The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Math::Expression::Evaluator - parses and evaluates mathematic expressions

SYNOPSIS

use Math::Expression::Evaluator;
my $m = new Math::Expression::Evaluator;

print $m->parse("a = 12; a*3")->val(), "\n";
# prints 36
print $m->parse("2^(a/3)")->val(), "\n";
# prints 8 (ie 2**3)
print $m->parse("a / b")->val({ b => 6 }), "\n";
# prints 36
print $m->parse("log2(16)")->val(), "\n";
# prints 4

DESCRIPTION

Math::Expression::Evaluator is a simple, recursive descending parser for mathematical expressions. It can handle normal arithmetics (includings powers ^), builtin functions like sin() and variables.

Multiple exressions can be seperated by whitespaces or by semicolons ';'. In case of multiple expressions the value of the last expression is returned.

Variables can be assigned with a single '=' sign, their name has to start with a alphabetic character or underscore [a-zA-Z_], and may contain alphabetic characters, digits and underscores.

Values for variables can also be provided as a hash ref as a parameter to val(). In case of collision the explicitly provided value is used:

$m->parse("a = 2; a")->val({a => 1}); 

will return 1, not 2.

The following builtin functions are supported atm:

  • trignometric functions: sin, cos, tan

  • inverse trigonomic functions: asin, acos, atan

  • Square root: sqrt

  • exponentials: exp, sinh, cosh

  • logarithms: log, log2, log10

  • constants: pi() (you need the parenthesis to distinguish it from the variable pi)

  • other: theta (theta(x) = 1 for x > 0, theta(x) = 0 for x < 0)

METHODS

new

generates a new MathExpr object. accepts an optional argument, a hash ref that contains configurations. If this hash sets force_semicolon to true, expressions have to be separated by a semicolon ';'.

parse

Takes a string as argument, and generates an AST that is stored internally.

Returns a reference to the object, so that method calls can be chained:

print MathExpr->new->parse("1+2")->val;

Parse failures cause this method to die with a stack trace.

val

Executes the AST generated by parse(), and returns the number that the expression is evaluated to. It accepts an optional hash reference that contain values for variables:

my $m = new MathExpr;
$m->parse("(x - 1) / (x + 1)");
foreach (0 .. 10) {
    print $_, "\t", $m->val({x => $_}), "\n";
}
optimize

Optimizes the AST generated by parse(), that is evaluates any subexpression that only depends on numerical constants, e.g.

a + 3 * 4

becomes

a + 12

Please note that the optimization by itself is rather costly compared to the evaluation by val(), so only do this if you plan to evaluate the expression multiple times, and be sure to benchmark it to know if you do the right thing.

If you don't know how the expression looks like (e.g. user supplied input) you should call optimize() if you evaluate the expression at least 20 times.

LICENSE

This module is free software. You may use, redistribute and modify it under the same terms as perl itself.

AUTHOR

Moritz Lenz, http://moritz.faui2k3.org/, moritz@faui2k3.org

DEVELOPMENT

You can obtain the latest development version via subversion:

svn co https://casella.verplant.org/svn/moritz/cpan/Math-Expression-Evaluator/