[system] / trunk / pg / lib / Parser / BOP / power.pm Repository:
ViewVC logotype

Annotation of /trunk/pg/lib/Parser/BOP/power.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6118 - (view) (download) (as text)

1 : sh002i 2558 #########################################################################
2 :     #
3 :     # Implements exponentiation
4 :     #
5 :     package Parser::BOP::power;
6 : dpvc 4994 use strict;
7 :     our @ISA = qw(Parser::BOP);
8 : sh002i 2558
9 :     #
10 :     # Check that operand types are OK.
11 :     # For non-numbers, promote to Matrix and check
12 :     # that the sizes are OK and that the exponents are numbers
13 :     sub _check {
14 :     my $self = shift;
15 : dpvc 5130 return if $self->checkStrings();
16 :     return if $self->checkLists();
17 :     return if $self->checkNumbers();
18 : sh002i 2558 my ($ltype,$rtype) = $self->promotePoints('Matrix');
19 :     if ($rtype->{name} eq 'Number') {
20 :     if ($ltype->{name} eq 'Matrix') {$self->checkMatrixSize($ltype,$ltype)}
21 : dpvc 5130 elsif ($self->context->flag("allowBadOperands")) {$self->{type} = $Value::Type{number}}
22 : sh002i 2558 else {$self->Error("You can only raise a Number to a power")}
23 : dpvc 5130 }
24 :     elsif ($self->context->flag("allowBadOperands")) {$self->{type} = $Value::Type{number}}
25 :     else {$self->Error("Exponents must be Numbers")}
26 : sh002i 2558 }
27 :    
28 :     #
29 :     # Do perl exponentiation
30 :     #
31 : dpvc 2908 sub _eval {
32 : dpvc 4994 my $self = $_[0];
33 : dpvc 2908 my $x = $_[1] ** $_[2];
34 :     return $x unless $x eq 'nan';
35 : dpvc 6118 $self->Error("Can't raise a negative number to a non-integer power")
36 : dpvc 4994 if Value::isNumber($_[1]) && Value::makeValue($_[1],context=>$self->context)->value < 0;
37 :     $self->Error("Result of exponentiation is not a number");
38 : dpvc 2908 }
39 : sh002i 2558
40 :     #
41 :     # Return 1 for power of zero or base of 1.
42 :     # Return base if power is 1.
43 :     # Return 1/base if power is -1.
44 :     #
45 :     sub _reduce {
46 : dpvc 2678 my $self = shift; my $equation = $self->{equation};
47 : dpvc 2796 my $reduce = $equation->{context}{reduction};
48 : dpvc 5001 return $self->Item("Number")->new($equation,1)
49 : dpvc 2796 if (($self->{rop}{isZero} && !$self->{lop}{isZero} && $reduce->{'x^0'}) ||
50 :     ($self->{lop}{isOne} && $reduce->{'1^x'}));
51 : dpvc 5331 return $self->{lop} if $self->{rop}{isOne} && $reduce->{'x^1'};
52 : dpvc 2796 if ($self->{rop}->isNeg && $self->{rop}->string eq '-1' && $reduce->{'x^(-1)'}) {
53 : dpvc 5001 $self = $self->Item("BOP")->new($equation,'/',$self->Item("Number")->new($equation,1),$self->{lop});
54 : sh002i 2558 $self = $self->reduce;
55 :     }
56 :     return $self;
57 :     }
58 :    
59 : dpvc 2796 $Parser::reduce->{'x^0'} = 1;
60 :     $Parser::reduce->{'1^x'} = 1;
61 :     $Parser::reduce->{'x^(-1)'} = 1;
62 : dpvc 5331 $Parser::reduce->{'x^1'} = 1;
63 : dpvc 2796
64 :    
65 : sh002i 2558 #
66 :     # Put exponent in braces for TeX
67 :     #
68 :     sub TeX {
69 : dpvc 2696 my ($self,$precedence,$showparens,$position,$outerRight) = @_;
70 : dpvc 3531 my $TeX; my $bop = $self->{def};
71 :     $position = '' unless defined($position);
72 :     $showparens = '' unless defined($showparens);
73 : dpvc 5132 my $extraParens = $self->context->flag('showExtraParens');
74 : dpvc 2696 my $addparens =
75 :     defined($precedence) &&
76 : dpvc 5132 (($showparens eq 'all' && $extraParens > 1) || $precedence > $bop->{precedence} ||
77 : dpvc 2696 ($precedence == $bop->{precedence} &&
78 : dpvc 5132 ($bop->{associativity} eq 'right' || ($showparens eq 'same' && $extraParens))));
79 : dpvc 3369 $outerRight = !$addparens && ($outerRight || $position eq 'right');
80 : dpvc 2696
81 : sh002i 2558 my $symbol = (defined($bop->{TeX}) ? $bop->{TeX} : $bop->{string});
82 : dpvc 2696 if ($self->{lop}->class eq 'Function' && $self->{rop}->class eq 'Number' &&
83 : dpvc 2701 $self->{lop}{def}{simplePowers} &&
84 : dpvc 2696 $self->{rop}{value} > 0 && int($self->{rop}{value}) == $self->{rop}{value}) {
85 :     $TeX = $self->{lop}->TeX($precedence,$showparens,$position,$outerRight,
86 :     $symbol.'{'.$self->{rop}->TeX.'}');
87 :     $addparens = 0;
88 :     } else {
89 :     $TeX = $self->{lop}->TeX($bop->{precedence},$bop->{leftparens},'left',$outerRight).
90 :     $symbol.'{'.$self->{rop}->TeX.'}';
91 :     }
92 :    
93 :     $TeX = '\left('.$TeX.'\right)' if $addparens;
94 :     return $TeX;
95 : sh002i 2558 }
96 :    
97 :     #########################################################################
98 :    
99 :     1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9