math_expressions 0.2.0

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 36

math_expressions

A math library for parsing and evaluating expressions in real, interval and vector contexts. Also supports simplification and differentiation.

It is partly inspired by mathExpr for Java.

Note: This library is still in an early state, the test coverage is not perfect, the performance is not optimized and some features are still unimplemented. Most REAL and basic INTERVAL and VECTOR evaluations should work though. Suggestions and pull requests are always welcome!

Build Status

Features

  • Parsing, simplification and differentiation of mathematical expressions.
  • Evaluation of expressions in various modes (Real, Vector, Interval).
  • Supporting most basic functions out of the box.
  • Well documented.

What's not working yet?

  • Some evaluations in vector and interval space (especially functions).
  • Parser only works for real numbers.
  • Complex numbers.

Documentation

See the DartDocs and the example code. For even more details, have a look into the unit tests.

Examples

1. Expression creation and evaluation

This example shows how to evaluate

Equation 1

for xy

Build the expression

You can either create an mathematical expression programmatically or parse a string.

  • Create the expression programmatically:
  Variable x = new Variable('x'), y = new Variable('y');
  Power xSquare = new Power(x, 2);
  Cos yCos = new Cos(y);
  Number three = new Number(3.0);
  Expression exp = (xSquare + yCos) / three;
  • Create the expression via the parser:
  Parser p = new Parser();
  Expression exp = p.parse("(x^2 + cos(y)) / 3");

Evaluate the expression

  • Bind variables and evaluate the expression as real number:
  // Bind variables:
  ContextModel cm = new ContextModel();
  cm.bindVariable(x, new Number(2.0));
  cm.bindVariable(y, new Number(Math.PI));
  
  // Evaluate expression:
  double eval = exp.evaluate(EvaluationType.REAL, cm);

  print(eval) // = 1.0

2. Expression simplification and differentiation

This example shows how to simplify and differentiate

Example 2

  • Expressions can be simplified and differentiated with respect to a given variable:
  Expression exp = p.parse("x*1 - (-5)");

  print(exp);            // = ((x * 1.0) - -(5.0))
  print(exp.simplify()); // = (x + 5.0)

  Expression expDerived = exp.derive('x');
  
  print(expDerived);            // = (((x * 0.0) + (1.0 * 1.0)) - -(0.0))
  print(expDerived.simplify()); // = 1.0

3. More Examples

For a simple CLI evaluator, see cli_evaluator.dart.
For more example code, see example.dart.

math_expressions is distributed under the MIT license as described in the LICENSE file.

0.2.0 - 2015-11-19

  • Add support for basic vector operations
  • Switch to using test instead of unittest package
  • Warning: Depends on git version of vector_math as latest pub release is severely outdated

0.1.0 - 2014-07-19

  • Add absolute value function (by markhats)
  • Add sign function
  • Improve test coverage
  • Adapt string representation of unary minus to standard syntax

0.0.9 - 2014-03-30

  • To create exponentials, use e(x) or e^x. Consequently, removed support for exp(x).
  • Improve test coverage
  • Update dependencies

0.0.8 - 2013-12-10

  • Bring back standard syntax for unary minus: -5 works now. (by markhats)
  • Add parser support for e^x additional to exp(x). (by markhats)

0.0.7 - 2013-11-09

  • Introduce nested context/naming scopes
  • Improve vector evaluation
  • Add some missing methods
  • Improve test coverage (custom and composite functions)
  • Remove boilerplate code

0.0.6 - 2013-11-07

  • Add compose operator for functions:
    Use & to conveniently create a CompositeFunction from two existing functions: expr = f & g;
  • Improve documentation and dartdoc generation

0.0.5 - 2013-11-06

  • Minor code cleanup
  • Prepare for Dart 1.0

0.0.4 - 2013-10-11

  • Fix handling of operator associativity
  • Add support for default functions to parser
  • Add support for unary minus to parser:
    Input with underscore. Instead of 2*-5 use 2*_5.

0.0.3 - 2013-10-09

  • Add cli evaluator to examples
  • Improve test coverage
  • Fix bug in differentiation of Sin and Cos
  • Remove support of unary minus in Parser

0.0.2 - 2013-10-07

  • Improve test coverage
  • Improve documentation
  • Fix bug in simplification of Minus
  • Fix bug in simplification of Times
  • Implement evaluation of nth root

0.0.1+1 - 2013-10-06

  • Improve documentation and examples

0.0.1 - 2013-10-04

  • Initial release of standalone version

example/example.dart

import 'package:math_expressions/math_expressions.dart';
import 'dart:math' as Math;

//TODO Documentation
void main() {
  //_expressionTest();
  //_evaluateTest();
  _example1();
  _example2();
  _example3();
}

/**
 * Example 1: Expression creation and evaluation
 */
void _example1() {
  // (1a) Parse expression:
  Parser p = new Parser();
  Expression exp = p.parse("(x^2 + cos(y)) / 3");

  // (1b) Build expression: (x^2 + cos(y)) / 3
  Variable x = new Variable('x'), y = new Variable('y');
  Power xSquare = new Power(x, 2);
  Cos yCos = new Cos(y);
  Number three = new Number(3.0);
  exp = (xSquare + yCos) / three;

  // (2) Bind variables:
  ContextModel cm = new ContextModel();
  cm.bindVariable(x, new Number(2.0));
  cm.bindVariable(y, new Number(Math.PI));

  // (3) Evaluate expression:
  double eval = exp.evaluate(EvaluationType.REAL, cm);

  print(eval); // = 1
}

/**
 * Example 2: Expression simplification and derivation
 */
void _example2() {
  Parser p = new Parser();
  Expression exp = p.parse("x*1 - (_5)");

  print(exp);            // = ((x * 1.0) - -(5.0))
  print(exp.simplify()); // = (x + 5.0)

  Expression expDerived = exp.derive('x');

  print(expDerived);            // = (((x * 0.0) + (1.0 * 1.0)) - -(0.0))
  print(expDerived.simplify()); // = 1.0
}

void _example3() {
  //TODO move to functional tests.
  Parser p = new Parser();
  Expression exp = p.parse("x * 2^2.5 * log(10,100)");

  print(exp);

  ContextModel cm = new ContextModel();
  cm.bindVariableName('x', new Number(1.0));

  double eval = exp.evaluate(EvaluationType.REAL, cm);
  print(eval);
}

void _expressionTest() {
  Expression x = new Variable('x'), a = new Variable('a'), b = new Variable('b'), c = new Variable('c');
  //Expression pow = new Power(x, new Number(2));
  //Expression e = a+b;
  //Expression e = a*pow+b*x+c;
  //Expression e = a*x*x+b*x+c;
  //print(e);
  //print(e.derive('x'));

  Expression exp = new Power('x', 2);
  Expression mul = new Times('x', 'x');


  print('exp: ${exp.toString()}');
  print('expD: ${exp.derive('x').toString()}');
  print('expDSimp: ${exp.derive('x').simplify().toString()}');
  print('expDSimpDSimp: ${exp.derive('x').simplify().derive('x').simplify().toString()}');
  print('expDD: ${exp.derive('x').derive('x').toString()}');
  print('expDDSimp: ${exp.derive('x').derive('x').simplify().toString()}');

  print('mul: ${mul.toString()}');
  print('mulD: ${mul.derive('x').toString()}');
  print('mulDSimp: ${mul.derive('x').simplify().toString()}');

  Expression div = new Divide(exp, 'x');
  print('div: ${div.toString()}');
  print('divD: ${div.derive('x').toString()}');
  print('divDSimp: ${div.derive('x').simplify().toString()}');


  Expression log = new Log(new Number(10), exp);
  print('log: ${log.toString()}');
  print('logD: ${log.derive('x').toString()}');
  print('logDSimp: ${log.derive('x').simplify().toString()}');


  Expression expXY = x^a;
  print('expXY: ${expXY.toString()}');
  print('expXYD: ${expXY.derive('x').toString()}');
  print('expXYDsimp: ${expXY.derive('x').simplify().toString()}');

  Expression sqrt = new Sqrt(exp);
  print('sqrt: ${sqrt.toString()}');
  print('sqrtD: ${sqrt.derive('x').toString()}');
  print('sqrtDsimpl: ${sqrt.derive('x').simplify().toString()}');

  Expression root = new Root(5, exp);
  print('root: ${root.toString()}');
  print('rootD: ${root.derive('x').toString()}');
  print('rootDsimpl: ${root.derive('x').simplify().toString()}');

  Expression negate = -exp;
  print(negate);

  Expression vector = new Vector([x*new Number(1), div, exp]);
  print('vector: ${vector}');
  print('vectorS: ${vector.simplify()}');
  print('vectorSD: ${vector.simplify().derive('x')}');

  Expression logVar = new Log(new Number(11), new Variable('x'));
  print('logVar: ${logVar.toString()}');
  print('logVarD: ${logVar.derive('x').toString()}');

  Expression composite = new CompositeFunction(logVar, sqrt);
  print('composite: ${composite.toString()}');
  print('compositeD: ${composite.derive('x').toString()}');
  print('compositeDS: ${composite.derive('x').simplify().toString()}');

  Expression fExpr = new Vector([x, new Plus(x,1), new Minus(x,1)]); // Transforms x to 3-dimensional vector
  MathFunction f = new CustomFunction('f', [x], fExpr);     // R -> R^3
  Expression gExpr = x + a + b;
  MathFunction g = new CustomFunction('g', [x, a, b], gExpr);      // R^3 -> R
  composite = new CompositeFunction(f, g); // R -> R

  print('composite2: ${composite.toString()}');
}

void _evaluateTest() {
  EvaluationType type = EvaluationType.REAL;
  ContextModel context = new ContextModel();

  Expression x = new Variable('x');
  Expression exp = new Power('x', 2);

  Expression mul = new Number(10) * new Number(5);
  _print('mul',mul);
  _print('mul =',mul.evaluate(type, context));

  context.bindVariable(x, new Number(2));
  Expression sqrt = new Sqrt(exp);
  print('sqrt: ${sqrt.toString()}');
  print('sqrtD: ${sqrt.derive('x').toString()}');
  print('sqrtDsimpl: ${sqrt.derive('x').simplify().toString()}');
  print('sqrtDEval: ${sqrt.derive('x').simplify().evaluate(type, context).toString()}');
  print('sqrtEval: ${sqrt.evaluate(type, context).toString()}');

  Expression negate = -exp;
  print(negate.evaluate(type, context));

  Expression vector = new Vector([x*new Number(1), x, exp]);
  print('vector: ${vector}');
  print('vectorS: ${vector.simplify()}');
  print('vectorSD: ${vector.simplify().derive('x')}');
  print('vectorS: ${vector.simplify().evaluate(EvaluationType.VECTOR, context)}');

  Expression interval1 = new IntervalLiteral(new Number(-1), new Number(4));
  Expression interval2 = new IntervalLiteral(new Number(5), new Number(10));

  Expression intAdd = (interval1 + interval2);
  Expression intMul = (interval1 * interval2);
  Expression intDiv = (interval2 / interval1);
  print('intAdd: ${intAdd}');
  print('intAdd: ${intAdd.simplify().evaluate(EvaluationType.INTERVAL, context)}');
  print('intMul: ${intMul}');
  print('intMul: ${intMul.simplify().evaluate(EvaluationType.INTERVAL, context)}');
  print('intDiv: ${intDiv}');
  try {
    // This should throw an exception (divide by 0)
    print('intDiv: ${intDiv.simplify().evaluate(EvaluationType.INTERVAL, context)}');
  } catch (e) {
    // expected
  }
}

void _print(prefix, stuff) => print('$prefix: $stuff');

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  math_expressions: ^0.2.0

2. Install it

You can install packages from the command line:

with pub:


$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:math_expressions/math_expressions.dart';
  
Version Uploaded Documentation Archive
1.0.0 Aug 10, 2018 Go to the documentation of math_expressions 1.0.0 Download math_expressions 1.0.0 archive
0.4.0 Aug 10, 2018 Go to the documentation of math_expressions 0.4.0 Download math_expressions 0.4.0 archive
0.3.0 Jul 9, 2016 Go to the documentation of math_expressions 0.3.0 Download math_expressions 0.3.0 archive
0.2.0+1 Dec 30, 2015 Go to the documentation of math_expressions 0.2.0+1 Download math_expressions 0.2.0+1 archive
0.2.0 Nov 19, 2015 Go to the documentation of math_expressions 0.2.0 Download math_expressions 0.2.0 archive
0.1.0 Jul 19, 2014 Go to the documentation of math_expressions 0.1.0 Download math_expressions 0.1.0 archive
0.0.9 Mar 30, 2014 Go to the documentation of math_expressions 0.0.9 Download math_expressions 0.0.9 archive
0.0.8 Dec 10, 2013 Go to the documentation of math_expressions 0.0.8 Download math_expressions 0.0.8 archive
0.0.7 Nov 9, 2013 Go to the documentation of math_expressions 0.0.7 Download math_expressions 0.0.7 archive
0.0.6 Nov 7, 2013 Go to the documentation of math_expressions 0.0.6 Download math_expressions 0.0.6 archive

All 16 versions...

Popularity:
Describes how popular the package is relative to other packages. [more]
71
Health:
Code health derived from static analysis. [more]
--
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
--
Overall:
Weighted score of the above. [more]
36
Learn more about scoring.

This package version is not analyzed, because it is more than two years old. Check the latest stable version for its analysis.

The package version is not analyzed, because it does not support Dart 2. Until this is resolved, the package will receive a health and maintenance score of 0.

Maintenance issues and suggestions

Running dartdoc failed. (-10 points)

Make sure dartdoc runs without any issues.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=0.8.10+6 <2.0.0