| 1 | |
1 | |
| 2 | loadMacros("MathObjects.pl"); |
2 | loadMacros("MathObjects.pl"); |
| 3 | |
3 | |
| 4 | sub _contextLimitedPolynomial_init {}; # don't load it again |
4 | sub _contextLimitedPolynomial_init {LimitedPolynomial::Init()}; # don't load it again |
| 5 | |
5 | |
| 6 | =head3 Context("LimitedPolynomial") |
6 | =head3 Context("LimitedPolynomial") |
| 7 | |
7 | |
| 8 | ########################################################## |
8 | ########################################################## |
| 9 | # |
9 | # |
| … | |
… | |
| 21 | # Context("LimitedPolynomial")->flags->set(singlePowers=>1); |
21 | # Context("LimitedPolynomial")->flags->set(singlePowers=>1); |
| 22 | # |
22 | # |
| 23 | |
23 | |
| 24 | =cut |
24 | =cut |
| 25 | |
25 | |
|
|
26 | ################################################## |
| 26 | # |
27 | # |
| 27 | # Handle common checking for BOPs |
28 | # Handle common checking for BOPs |
| 28 | # |
29 | # |
| 29 | package LimitedPolynomial::BOP; |
30 | package LimitedPolynomial::BOP; |
| 30 | |
31 | |
| … | |
… | |
| 84 | LimitedPolynomial::markPowers($r); |
85 | LimitedPolynomial::markPowers($r); |
| 85 | $self->{isPoly} = 1; |
86 | $self->{isPoly} = 1; |
| 86 | $self->{powers} = $l->{powers} || {}; delete $l->{powers}; |
87 | $self->{powers} = $l->{powers} || {}; delete $l->{powers}; |
| 87 | return 1 unless $r->{powers}; |
88 | return 1 unless $r->{powers}; |
| 88 | foreach my $n (keys(%{$r->{powers}})) { |
89 | foreach my $n (keys(%{$r->{powers}})) { |
| 89 | $self->Error("Polynomials can have at most one term of each degree") |
90 | $self->Error("Simplified polynomials can have at most one term of each degree") |
| 90 | if $self->{powers}{$n} && $single; |
91 | if $self->{powers}{$n} && $single; |
| 91 | $self->{powers}{$n} = 1; |
92 | $self->{powers}{$n} = 1; |
| 92 | } |
93 | } |
| 93 | delete $r->{powers}; |
94 | delete $r->{powers}; |
| 94 | return 1; |
95 | return 1; |
| 95 | } |
96 | } |
|
|
97 | |
|
|
98 | ################################################## |
| 96 | |
99 | |
| 97 | package LimitedPolynomial; |
100 | package LimitedPolynomial; |
| 98 | |
101 | |
| 99 | # |
102 | # |
| 100 | # Mark a variable as having power 1 |
103 | # Mark a variable as having power 1 |
| … | |
… | |
| 308 | our @ISA = qw(LimitedPolynomial::Function Parser::Function::hyperbolic); |
311 | our @ISA = qw(LimitedPolynomial::Function Parser::Function::hyperbolic); |
| 309 | |
312 | |
| 310 | ############################################## |
313 | ############################################## |
| 311 | ############################################## |
314 | ############################################## |
| 312 | |
315 | |
| 313 | package main; |
316 | package LimitedPolynomial; |
| 314 | |
317 | |
| 315 | # |
318 | sub Init { |
|
|
319 | # |
| 316 | # Now build the new context that calls the |
320 | # Build the new context that calls the |
| 317 | # above classes rather than the usual ones |
321 | # above classes rather than the usual ones |
| 318 | # |
322 | # |
| 319 | |
323 | |
| 320 | $context{LimitedPolynomial} = Parser::Context->getCopy("Numeric"); |
324 | my $context = $main::context{LimitedPolynomial} = Parser::Context->getCopy("Numeric"); |
| 321 | $context{LimitedPolynomial}->operators->set( |
325 | $context->operators->set( |
| 322 | '+' => {class => 'LimitedPolynomial::BOP::add'}, |
326 | '+' => {class => 'LimitedPolynomial::BOP::add'}, |
| 323 | '-' => {class => 'LimitedPolynomial::BOP::subtract'}, |
327 | '-' => {class => 'LimitedPolynomial::BOP::subtract'}, |
| 324 | '*' => {class => 'LimitedPolynomial::BOP::multiply'}, |
328 | '*' => {class => 'LimitedPolynomial::BOP::multiply'}, |
| 325 | '* ' => {class => 'LimitedPolynomial::BOP::multiply'}, |
329 | '* ' => {class => 'LimitedPolynomial::BOP::multiply'}, |
| 326 | ' *' => {class => 'LimitedPolynomial::BOP::multiply'}, |
330 | ' *' => {class => 'LimitedPolynomial::BOP::multiply'}, |
| 327 | ' ' => {class => 'LimitedPolynomial::BOP::multiply'}, |
331 | ' ' => {class => 'LimitedPolynomial::BOP::multiply'}, |
| 328 | '/' => {class => 'LimitedPolynomial::BOP::divide'}, |
332 | '/' => {class => 'LimitedPolynomial::BOP::divide'}, |
| 329 | ' /' => {class => 'LimitedPolynomial::BOP::divide'}, |
333 | ' /' => {class => 'LimitedPolynomial::BOP::divide'}, |
| 330 | '/ ' => {class => 'LimitedPolynomial::BOP::divide'}, |
334 | '/ ' => {class => 'LimitedPolynomial::BOP::divide'}, |
| 331 | '^' => {class => 'LimitedPolynomial::BOP::power'}, |
335 | '^' => {class => 'LimitedPolynomial::BOP::power'}, |
| 332 | '**' => {class => 'LimitedPolynomial::BOP::power'}, |
336 | '**' => {class => 'LimitedPolynomial::BOP::power'}, |
| 333 | 'u+' => {class => 'LimitedPolynomial::UOP::plus'}, |
337 | 'u+' => {class => 'LimitedPolynomial::UOP::plus'}, |
| 334 | 'u-' => {class => 'LimitedPolynomial::UOP::minus'}, |
338 | 'u-' => {class => 'LimitedPolynomial::UOP::minus'}, |
| 335 | ); |
|
|
| 336 | # |
|
|
| 337 | # Remove these operators and functions |
|
|
| 338 | # |
|
|
| 339 | $context{LimitedPolynomial}->lists->set( |
|
|
| 340 | AbsoluteValue => {class => 'LimitedPolynomial::List::AbsoluteValue'}, |
|
|
| 341 | ); |
|
|
| 342 | $context{LimitedPolynomial}->operators->undefine('_','!','U'); |
|
|
| 343 | $context{LimitedPolynomial}->functions->disable("atan2"); |
|
|
| 344 | # |
|
|
| 345 | # Hook into the numeric, trig, and hyperbolic functions |
|
|
| 346 | # |
|
|
| 347 | foreach ('ln','log','log10','exp','sqrt','abs','int','sgn') { |
|
|
| 348 | $context{LimitedPolynomial}->functions->set( |
|
|
| 349 | "$_"=>{class => 'LimitedPolynomial::Function::numeric'} |
|
|
| 350 | ); |
339 | ); |
| 351 | } |
340 | # |
| 352 | foreach ('sin','cos','tan','sec','csc','cot', |
341 | # Remove these operators and functions |
| 353 | 'asin','acos','atan','asec','acsc','acot') { |
342 | # |
| 354 | $context{LimitedPolynomial}->functions->set( |
343 | $context->lists->set( |
| 355 | "$_"=>{class => 'LimitedPolynomial::Function::trig'}, |
344 | AbsoluteValue => {class => 'LimitedPolynomial::List::AbsoluteValue'}, |
| 356 | "${_}h"=>{class => 'LimitedPolynomial::Function::hyperbolic'} |
|
|
| 357 | ); |
345 | ); |
| 358 | } |
346 | $context->operators->undefine('_','!','U'); |
|
|
347 | $context->functions->disable("atan2"); |
|
|
348 | # |
|
|
349 | # Hook into the numeric, trig, and hyperbolic functions |
|
|
350 | # |
|
|
351 | foreach ('ln','log','log10','exp','sqrt','abs','int','sgn') { |
|
|
352 | $context->functions->set( |
|
|
353 | "$_"=>{class => 'LimitedPolynomial::Function::numeric'} |
|
|
354 | ); |
|
|
355 | } |
|
|
356 | foreach ('sin','cos','tan','sec','csc','cot', |
|
|
357 | 'asin','acos','atan','asec','acsc','acot') { |
|
|
358 | $context->functions->set( |
|
|
359 | "$_"=>{class => 'LimitedPolynomial::Function::trig'}, |
|
|
360 | "${_}h"=>{class => 'LimitedPolynomial::Function::hyperbolic'} |
|
|
361 | ); |
|
|
362 | } |
| 359 | |
363 | |
| 360 | Context("LimitedPolynomial"); |
364 | main::Context("LimitedPolynomial"); ### FIXME: probably should require author to set this explicitly |
|
|
365 | } |
| 361 | |
366 | |
| 362 | 1; |
367 | 1; |