Class MathExpr

  • All Implemented Interfaces:
    Serializable, Function<Double[],​Double>

    public final class MathExpr
    extends Object
    implements Function<Double[],​Double>, Serializable
    This class allows you to create a math operation tree from an expression string. The expression string may only contain functions/operations defined in MathOp.
    final MathExpr expr = MathExpr.parse("5 + 6*x + sin(x)^34 + (1 + sin(x*5)/4)/6"); final double result = expr.eval(4.32); assert result == 31.170600453465315; assert 12.0 == MathExpr.eval("3*4"); assert 24.0 == MathExpr.eval("3*4*x", 2); assert 28.0 == MathExpr.eval("3*4*x + y", 2, 4);
    Since:
    4.1
    Version:
    5.0
    See Also:
    MathOp, Serialized Form
    • Field Detail

      • CONST_REWRITER

        public static final TreeRewriter<Op<Double>> CONST_REWRITER
        This tree-rewriter rewrites constant expressions to its single value.
        final TreeNode<Op<Double>> tree = MathExpr.parseTree("1 + 2*(6 + 7)"); MathExpr.CONST_REWRITER.rewrite(tree); assertEquals(tree.getValue(), Const.of(27.0));
        Since:
        5.0
      • ARITHMETIC_REWRITER

        public static final TreeRewriter<Op<Double>> ARITHMETIC_REWRITER
        This rewriter implements some common arithmetic identities, in exactly this order.
         
             sub($x,$x) ->  0
             sub($x,0)  ->  $x
             add($x,0)  ->  $x
             add(0,$x)  ->  $x
             add($x,$x) ->  mul(2,$x)
             div($x,$x) ->  1
             div(0,$x)  ->  0
             mul($x,0)  ->  0
             mul(0,$x)  ->  0
             mul($x,1)  ->  $x
             mul(1,$x)  ->  $x
             mul($x,$x) ->  pow($x,2)
             pow($x,0)  ->  1
             pow(0,$x)  ->  0
             pow($x,1)  ->  $x
             pow(1,$x)  ->  1
         
        Since:
        5.0
    • Constructor Detail

      • MathExpr

        public MathExpr​(Tree<? extends Op<Double>,​?> tree)
        Create a new MathExpr object from the given operation tree.
        Parameters:
        tree - the underlying operation tree
        Throws:
        NullPointerException - if the given program is null
        IllegalArgumentException - if the given operation tree is invalid, which means there is at least one node where the operation arity and the node child count differ.
    • Method Detail

      • vars

        public ISeq<Var<Double>> vars()
        Return the variable list of this math expression.
        Returns:
        the variable list of this math expression
      • toTree

        public TreeNode<Op<Double>> toTree()
        Return the math expression as operation tree.
        Returns:
        a new expression tree
      • eval

        public double eval​(double... args)
        Convenient method, which lets you apply the program function without explicitly create a wrapper array.
        final double result = MathExpr.parse("2*z + 3*x - y").eval(3, 2, 1); assert result == 9.0;
        Parameters:
        args - the function arguments
        Returns:
        the evaluated value
        Throws:
        NullPointerException - if the given variable array is null
        IllegalArgumentException - if the length of the arguments array is smaller than the program arity
        See Also:
        apply(Double[]), eval(String, double...)
      • toString

        public String toString()
        Return the string representation of this MathExpr object. The string returned by this method can be parsed again and will result in the same expression object.
        final String expr = "5.0 + 6.0*x + sin(x)^34.0 + (1.0 + sin(x*5.0)/4.0) + 6.5"; final MathExpr tree = MathExpr.parse(expr); assert tree.toString().equals(expr);
        Overrides:
        toString in class Object
        Returns:
        the expression string
      • simplify

        public MathExpr simplify​(TreeRewriter<Op<Double>> rewriter,
                                 int limit)
        Simplifying this expression by applying the given rewriter and the given rewrite limit.
        Parameters:
        rewriter - the rewriter used for simplifying this expression
        limit - the rewrite limit
        Returns:
        a newly created math expression object
        Throws:
        NullPointerException - if the rewriter is null
        IllegalArgumentException - if the limit is smaller than zero
      • simplify

        public MathExpr simplify​(TreeRewriter<Op<Double>> rewriter)
        Simplifying this expression by applying the given rewriter.
        Parameters:
        rewriter - the rewriter used for simplifying this expression
        Returns:
        a newly created math expression object
        Throws:
        NullPointerException - if the rewriter is null
      • simplify

        public MathExpr simplify()
        Simplifies this expression by applying the default REWRITER.
        Returns:
        a newly created math expression object
      • format

        public static String format​(Tree<? extends Op<Double>,​?> tree)
        Return the string representation of the given tree object. The string returned by this method can be parsed again and will result in the same expression object.
        final String expr = "5.0 + 6.0*x + sin(x)^34.0 + (1.0 + sin(x*5.0)/4.0) + 6.5"; final MathExpr tree = MathExpr.parse(expr); assert MathExpr.format(tree.tree()).equals(expr);
        Parameters:
        tree - the tree object to convert to a string
        Returns:
        a new expression string
        Throws:
        NullPointerException - if the given tree is null
        Since:
        4.3
      • parse

        public static MathExpr parse​(String expression)
        Parses the given expression into a AST tree.
        Parameters:
        expression - the expression string
        Returns:
        the tree representation of the given expression
        Throws:
        NullPointerException - if the given expression is null
        IllegalArgumentException - if the given expression is invalid or can't be parsed.
      • parseTree

        public static TreeNode<Op<Double>> parseTree​(String expression)
        Parses the given mathematical expression string and returns the mathematical expression tree. The expression may contain all functions defined in MathOp.
        final Tree<? extends Op<Double>, ?> tree = MathExpr .parseTree("5 + 6*x + sin(x)^34 + (1 + sin(x*5)/4)/6");
        The example above will lead to the following tree:
         
          add
          ├── add
          │   ├── add
          │   │   ├── 5.0
          │   │   └── mul
          │   │       ├── 6.0
          │   │       └── x
          │   └── pow
          │       ├── sin
          │       │   └── x
          │       └── 34.0
          └── div
              ├── add
              │   ├── 1.0
              │   └── div
              │       ├── sin
              │       │   └── mul
              │       │       ├── x
              │       │       └── 5.0
              │       └── 4.0
              └── 6.0
         
        Parameters:
        expression - the expression string
        Returns:
        the parsed expression tree
        Throws:
        NullPointerException - if the given expression is null
        IllegalArgumentException - if the given expression is invalid or can't be parsed.
      • eval

        public static double eval​(String expression,
                                  double... args)
        Evaluates the given expression with the given arguments.
        final double result = MathExpr.eval("2*z + 3*x - y", 3, 2, 1); assert result == 9.0;
        Parameters:
        expression - the expression to evaluate
        args - the expression arguments, in alphabetical order
        Returns:
        the evaluation result
        Throws:
        NullPointerException - if the given expression is null
        IllegalArgumentException - if the given operation tree is invalid, which means there is at least one node where the operation arity and the node child count differ.
        See Also:
        apply(Double[]), eval(double...)
      • rewrite

        public static int rewrite​(TreeNode<Op<Double>> tree,
                                  int limit)
        Applies the REWRITER to the given (mutable) tree. The tree rewrite is done in place.
        Parameters:
        tree - the tree to be rewritten
        limit - the maximal number this rewrite rule is applied to the given tree. This guarantees the termination of the rewrite method.
        Returns:
        the number of rewrites applied to the input tree
        Throws:
        NullPointerException - if the given tree is null
        IllegalArgumentException - if the limit is smaller than one
        Since:
        5.0
        See Also:
        TreeRewriter.rewrite(TreeNode, int)