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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2696 - (download) (as text) (annotate)
Sat Aug 28 12:34:56 2004 UTC (15 years, 3 months ago) by dpvc
File size: 3285 byte(s)
Improved TeX and string output in a number of situations.  Improved
use of parentheses to avoid things like x+-3.  Fixed wrong parentheses
in powers.  Display (sin(x))^2 as sin^2(x) in TeX output.

    1 #########################################################################
    2 #
    3 #  Implement multiplication.
    4 #
    5 package Parser::BOP::multiply;
    6 use strict; use vars qw(@ISA);
    7 @ISA = qw(Parser::BOP);
    8 
    9 #
   10 #  Check that operand types are compatible for multiplication.
   11 #
   12 sub _check {
   13   my $self = shift;
   14   return if ($self->checkStrings());
   15   return if ($self->checkLists());
   16   return if ($self->checkNumbers());
   17   my ($ltype,$rtype) = $self->promotePoints('Matrix');
   18   if ($ltype->{name} eq 'Number' && $rtype->{name} =~ m/Vector|Matrix/) {
   19     $self->{type} = {%{$rtype}};
   20   } elsif ($ltype->{name} =~ m/Vector|Matrix/ && $rtype->{name} eq 'Number') {
   21     $self->{type} = {%{$ltype}};
   22   } elsif ($ltype->{name} eq 'Matrix' && $rtype->{name} eq 'Vector') {
   23     $self->checkMatrixSize($ltype,transposeVectorType($rtype));
   24   } elsif ($ltype->{name} eq 'Vector' && $rtype->{name} eq 'Matrix') {
   25     $self->checkMatrixSize(Value::Type('Matrix',1,$ltype),$rtype);
   26   } elsif ($ltype->{name} eq 'Matrix' && $rtype->{name} eq 'Matrix') {
   27     $self->checkMatrixSize($ltype,$rtype);
   28   } else {$self->Error("Operands of '*' are not of compatible types")}
   29 }
   30 
   31 #
   32 #  Return the type of a vector as a column vector.
   33 #
   34 sub transposeVectorType {
   35   my $vtype = shift;
   36   Value::Type('Matrix',$vtype->{length},
   37      Value::Type('Matrix',1,$vtype->{entryType},formMatrix => 1),
   38      formMatrix =>1 );
   39 }
   40 
   41 #
   42 #  Do the multiplication.
   43 #
   44 sub _eval {$_[1] * $_[2]}
   45 
   46 #
   47 #  Remove multiplication by one.
   48 #  Reduce multiplication by zero to appropriately sized zero.
   49 #  Factor out negatives.
   50 #  Move a number from the right to the left.
   51 #  Move a function apply from the left to the right.
   52 #
   53 sub _reduce {
   54   my $self = shift;
   55   return $self->{rop} if ($self->{lop}{isOne});
   56   return $self->{lop} if ($self->{rop}{isOne});
   57   return $self->makeZero($self->{rop},$self->{lop}) if ($self->{lop}{isZero});
   58   return $self->makeZero($self->{lop},$self->{rop}) if ($self->{rop}{isZero});
   59   return $self->makeNeg($self->{lop}{op},$self->{rop}) if ($self->{lop}->isNeg);
   60   return $self->makeNeg($self->{lop},$self->{rop}{op}) if ($self->{rop}->isNeg);
   61   $self->swapOps
   62      if (($self->{rop}->class eq 'Number' && $self->{lop}->class ne 'Number') ||
   63         ($self->{lop}->class eq 'Function' && $self->{rop}->class ne 'Function'));
   64   return $self;
   65 }
   66 
   67 sub TeX {
   68   my ($self,$precedence,$showparens,$position,$outerRight) = @_;
   69   my $TeX; my $bop = $self->{def}; my $cdot;
   70   my $mult = (defined($bop->{TeX}) ? $bop->{TeX} : $bop->{string});
   71   ($mult,$cdot) = @{$mult} if ref($mult) eq 'ARRAY';
   72   $cdot = '\cdot ' unless $cdot;
   73 
   74   my $addparens =
   75       defined($precedence) &&
   76       ($showparens eq 'all' || $precedence > $bop->{precedence} ||
   77       ($precedence == $bop->{precedence} &&
   78         ($bop->{associativity} eq 'right' || $showparens eq 'same')));
   79   my $outerRight = !$addparens && ($outerRight || $position eq 'right');
   80 
   81   my $left  = $self->{lop}->TeX($bop->{precedence},$bop->{leftparens},'left',$outerRight);
   82   my $right = $self->{rop}->TeX($bop->{precedence},$bop->{rightparens},'right');
   83   $mult = $cdot if $left =~ m/\d$/ && $right =~ m/^\d/;
   84   $TeX = $left.$mult.$right;
   85 
   86   $TeX = '\left('.$TeX.'\right)' if $addparens;
   87   return $TeX;
   88 }
   89 
   90 #########################################################################
   91 
   92 1;
   93 

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9