######################################################################### # # Implement multiplication. # package Parser::BOP::multiply; use strict; use vars qw(@ISA); @ISA = qw(Parser::BOP); # # Check that operand types are compatible for multiplication. # sub _check { my $self = shift; return if ($self->checkStrings()); return if ($self->checkLists()); return if ($self->checkNumbers()); my ($ltype,$rtype) = $self->promotePoints('Matrix'); if ($ltype->{name} eq 'Number' && $rtype->{name} =~ m/Vector|Matrix/) {$self->{type} = {%{$rtype}}; } elsif ($ltype->{name} =~ m/Vector|Matrix/ && $rtype->{name} eq 'Number') {$self->{type} = {%{$ltype}}; } elsif ($ltype->{name} eq 'Matrix' && $rtype->{name} eq 'Vector') {$self->checkMatrixSize($ltype,transposeVectorType($rtype)); } elsif ($ltype->{name} eq 'Vector' &&$rtype->{name} eq 'Matrix') { $self->checkMatrixSize(Value::Type('Matrix',1,$ltype),$rtype); } elsif ($ltype->{name} eq 'Matrix' && $rtype->{name} eq 'Matrix') {$self->checkMatrixSize($ltype,$rtype); } else {$self->Error("Operands of '*' are not of compatible types")} } # # Return the type of a vector as a column vector. # sub transposeVectorType { my$vtype = shift; Value::Type('Matrix',$vtype->{length}, Value::Type('Matrix',1,$vtype->{entryType},formMatrix => 1), formMatrix =>1 ); } # # Do the multiplication. # sub _eval {$_[1] *$_[2]} # # Remove multiplication by one. # Reduce multiplication by zero to appropriately sized zero. # Factor out negatives. # Move a number from the right to the left. # Move a function apply from the left to the right. # sub _reduce { my $self = shift; return$self->{rop} if ($self->{lop}{isOne}); return$self->{lop} if ($self->{rop}{isOne}); return$self->makeZero($self->{rop},$self->{lop}) if ($self->{lop}{isZero}); return$self->makeZero($self->{lop},$self->{rop}) if ($self->{rop}{isZero}); return$self->makeNeg($self->{lop}{op},$self->{rop}) if ($self->{lop}->isNeg); return$self->makeNeg($self->{lop},$self->{rop}{op}) if ($self->{rop}->isNeg);$self->swapOps if (($self->{rop}->class eq 'Number' &&$self->{lop}->class ne 'Number') || ($self->{lop}->class eq 'Function' &&$self->{rop}->class ne 'Function')); return $self; } sub TeX { my ($self,$precedence,$showparens,$position,$outerRight) = @_; my $TeX; my$bop = $self->{def}; my$cdot; my $mult = (defined($bop->{TeX}) ? $bop->{TeX} :$bop->{string}); ($mult,$cdot) = @{$mult} if ref($mult) eq 'ARRAY'; $cdot = '\cdot ' unless$cdot; my $addparens = defined($precedence) && ($showparens eq 'all' ||$precedence > $bop->{precedence} || ($precedence == $bop->{precedence} && ($bop->{associativity} eq 'right' || $showparens eq 'same'))); my$outerRight = !$addparens && ($outerRight || $position eq 'right'); my$left = $self->{lop}->TeX($bop->{precedence},$bop->{leftparens},'left',$outerRight); my $right =$self->{rop}->TeX($bop->{precedence},$bop->{rightparens},'right'); $mult =$cdot if $left =~ m/\d$/ && $right =~ m/^\d/;$TeX = $left.$mult.$right;$TeX = '\left('.$TeX.'\right)' if$addparens; return \$TeX; } ######################################################################### 1;