Formula Evaluation In Perl

abez abez at abez.ca
Sat Sep 14 01:48:53 CDT 2002


Since can effectively evaluate perl code I thought wouldn't be neat to
evaluate formulas. Turns it's with regexes it is pretty easy. This also got me
thinking.. one could effectively do some symbolic math just by mucking around
with strings. Symbolic math is what I'll define as executing functions as
symbols rather than discrete values.

For instance dy/dx(x^4)=4*x**(4-1) which I "demo'd" poorly.

You can type in the following into this system and it will work well

sort(5,3,4,1)
x=2;y=3;x*y*x*log(x)
sin=1;sin(sin)
x=3.14;cos(x)*10

I hacked in the derivative function at the last second and it only works if 
it's the only outer function, it also only works for simple degrees of a symbol
x=2;y=4
derivative(x,x^y)
would produce 32, it would do a symbolic differentiation before evaluating tho.
.

None of this took very long either. It was pretty cool.

#!/usr/bin/perl
#Sad Sad "Symbolic Math"
my $in;
%hash = ();
while($in=<>) {
   chomp($in);
   if ($in =~ /^derivative\((.*)\)\s*$/) { # this is hack, more so a proof
                                           # of concept a better design would
                                           # be needed so we'd know symbolic
                                           # functions from normal functions
      $in = $1;
      $in = derivative(split(",",$in));
   }
   my @vars = ($in =~ /([a-zA-Z]+)\b(?!\()/g);
   my %symhash = ();
   foreach (@vars) {
      $symhash{$_} = 0;
   }
   my @syms = keys %symhash;
   my $str = $in;
   foreach (@syms) {
      if (!defined($hash{$_})) { $hash{$_} = 0 }
      $in =~ s/$_\b(?!\()/\$hash{$_}/g;
   }
   print join(",",eval $in.";"),"\n";
   warn $@ if $@;
   foreach my $key (sort keys %hash) {
      print "$key = ".$hash{$key}. " ";
   }
   print "\n";
}
#bad demo but shows some of the power of string manipulation
#for doing math..
sub derivative {
   my $symbol  = shift;
   my $formula = shift;
   #exponentiation
   #x**y == (y)*x**(y-1)
   $formula =~ s/$symbol\*\*([a-zA-Z]+\b)/$symbol\*\*($1-1)*$1/g;
   return $formula;
}


-- 
ABeZ------------ ------- ------ - ---------- -- ------------
http://www.indexdirect.com/abez/ Abram Hindle (abez at abez.ca)
---- ------- ----------- ----------- - - ------ --------ABeZ




More information about the Victoria-pm mailing list