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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5331 - (download) (as text) (annotate)
Wed Aug 15 04:10:41 2007 UTC (12 years, 4 months ago) by dpvc
File size: 3442 byte(s)
Added a reduce flag for x^1 processing (it was not able to be
disabled before).

    1 #########################################################################
    2 #
    3 #  Implements exponentiation
    4 #
    5 package Parser::BOP::power;
    6 use strict;
    7 our @ISA = qw(Parser::BOP);
    8 
    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   return if $self->checkStrings();
   16   return if $self->checkLists();
   17   return if $self->checkNumbers();
   18   my ($ltype,$rtype) = $self->promotePoints('Matrix');
   19   if ($rtype->{name} eq 'Number') {
   20     if ($ltype->{name} eq 'Matrix') {$self->checkMatrixSize($ltype,$ltype)}
   21     elsif ($self->context->flag("allowBadOperands")) {$self->{type} = $Value::Type{number}}
   22     else {$self->Error("You can only raise a Number to a power")}
   23   }
   24   elsif ($self->context->flag("allowBadOperands")) {$self->{type} = $Value::Type{number}}
   25   else {$self->Error("Exponents must be Numbers")}
   26 }
   27 
   28 #
   29 #  Do perl exponentiation
   30 #
   31 sub _eval {
   32   my $self = $_[0];
   33   my $x = $_[1] ** $_[2];
   34   return $x unless $x eq 'nan';
   35   $self->Error("Can't raise a negative number to a power")
   36     if Value::isNumber($_[1]) && Value::makeValue($_[1],context=>$self->context)->value < 0;
   37   $self->Error("Result of exponentiation is not a number");
   38 }
   39 
   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   my $self = shift; my $equation = $self->{equation};
   47   my $reduce = $equation->{context}{reduction};
   48   return $self->Item("Number")->new($equation,1)
   49     if (($self->{rop}{isZero} && !$self->{lop}{isZero} && $reduce->{'x^0'}) ||
   50   ($self->{lop}{isOne} && $reduce->{'1^x'}));
   51   return $self->{lop} if $self->{rop}{isOne} && $reduce->{'x^1'};
   52   if ($self->{rop}->isNeg && $self->{rop}->string eq '-1' && $reduce->{'x^(-1)'}) {
   53     $self = $self->Item("BOP")->new($equation,'/',$self->Item("Number")->new($equation,1),$self->{lop});
   54     $self = $self->reduce;
   55   }
   56   return $self;
   57 }
   58 
   59 $Parser::reduce->{'x^0'} = 1;
   60 $Parser::reduce->{'1^x'} = 1;
   61 $Parser::reduce->{'x^(-1)'} = 1;
   62 $Parser::reduce->{'x^1'} = 1;
   63 
   64 
   65 #
   66 #  Put exponent in braces for TeX
   67 #
   68 sub TeX {
   69   my ($self,$precedence,$showparens,$position,$outerRight) = @_;
   70   my $TeX; my $bop = $self->{def};
   71   $position = '' unless defined($position);
   72   $showparens = '' unless defined($showparens);
   73   my $extraParens = $self->context->flag('showExtraParens');
   74   my $addparens =
   75       defined($precedence) &&
   76       (($showparens eq 'all' && $extraParens > 1) || $precedence > $bop->{precedence} ||
   77       ($precedence == $bop->{precedence} &&
   78         ($bop->{associativity} eq 'right' || ($showparens eq 'same' && $extraParens))));
   79   $outerRight = !$addparens && ($outerRight || $position eq 'right');
   80 
   81   my $symbol = (defined($bop->{TeX}) ? $bop->{TeX} : $bop->{string});
   82   if ($self->{lop}->class eq 'Function' && $self->{rop}->class eq 'Number' &&
   83       $self->{lop}{def}{simplePowers} &&
   84       $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 }
   96 
   97 #########################################################################
   98 
   99 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9