# math_expressions #

A library for parsing and evaluating mathematical expressions.

• Performs evaluations in real, vector, and interval contexts.
• Supports expression simplification and differentiation.

## Features #

• Evaluation of expressions in various modes: Real, Vector and Interval.
• Parsing, simplification and differentiation of mathematical expressions.
• Supporting most basic math functions out of the box.
• Extensible through custom function definitions in code.
• Well documented and tested.

This package contains a very simple command-line interpreter for real numbers:

``````pub run math_expressions:interpreter
``````

### What's not working yet? #

• Some evaluations in vector and interval space (especially functions).
• N-dimensional vectors. Curently no more than four dimensions are supported.
• The parser only works for real numbers.
• Complex numbers.

Suggestions and pull requests are always welcome!

## Usage #

Below are two basic examples of how to use this library. There also is some additional example code available.

### 1. Expression creation and evaluation #

This example shows how to evaluate

$(x^2+cos(y))/3$

for $x=2,y=\pi$

#### 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

$x*1-(-5)$

• 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
``````

## Alternatives #

Here are some other Dart libraries that implement similar functionality to math_expression: parsing and evaluating mathematical expressions.

• expressions: an elegant and small library to parse and evaluate simple expressions.
• function_tree: a library for parsing, evaluating and plotting single- and multi-variables numerical functions.

To the author's knowledge math_expressions is currently the only library supporting interval arithmetics.

### 1.1.1 - 2019-04-16 #

• Package health and maintenance cleanups

### 1.1.0 - 2019-04-16 #

• Drop support for Dart SDK versions below 2.0.0
• Add arcsin, arccos, arctan functions
• Fix floor and ceil functions
• Update examples and documentation
• Switch to pendantic analysis options

### 1.0.0 - 2018-08-11 #

• Add support for Dart 2.0
• Drop support for Dart SDK versions below 1.24.0
• Depend on `vector_math` 2.0.0 or newer

### 0.4.0 - 2018-08-10 #

• Last release to only support Dart 1.x
• Prepare for Dart 2.0
• Enable strong mode
• Analyzer and linter fixes
• Drop support for Dart SDK versions below 1.21.0

### 0.3.0 - 2016-07-09 #

• Rename `Point3D` to `Point3`
• `Point3` now is a subtype of `Vector3`
• Add mod (%) operator and ceil, floor functions
• Fixing a few missed chain rules in `derive`

### 0.2.0+1 - 2015-12-30 #

• Depend on `vector_math` 1.4.4 or greater

### 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)
• 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
• 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/main.dart

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

/**
* This file contains three examples:
*  - Example 1: Expression creation and evaluation
*               (through the Parser and programmatically)
*  - Example 2: Expression simplification and differentiation
*  - Example 3: Custom function definition and use
*/
void main() {
_expression_creation_and_evaluation();
_expression_simplification_and_differentiation();
_custom_function_definition_and_use();
}

/**
* Example 1: Expression creation and evaluation
*
* How to create an expression (a) via the Parser, (b) programmatically,
* and how to evaluate an expression given a context.
*/
void _expression_creation_and_evaluation() {
print('\nExample 1: Expression creation and evaluation\n');

// You can either create an mathematical expression programmatically or parse
// a string.
// (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;

// Bind variables and evaluate the expression as real number.
// (2) Bind variables:
ContextModel cm = new ContextModel()
..bindVariable(x, new Number(2.0))
..bindVariable(y, new Number(math.pi));

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

print('Expression: \$exp');
print('Evaluated expression: \$eval\n  (with context: \$cm)'); // = 1
}

/**
* Example 2: Expression simplification and differentiation
*
* How to simplify an expression, and how to differentiate it with respect
* to a given variable.
*/
void _expression_simplification_and_differentiation() {
print('\nExample 2: Expression simplification and differentiation\n');

// (1) Parse expression:
Parser p = new Parser();
Expression exp = p.parse('x*1 - (-5)');

// (2) Simplify expression:
print('Expression: \$exp'); // = ((x * 1.0) - -(5.0))
print('Simplified expression: \${exp.simplify()}\n'); // = (x + 5.0)

// (2) Differentiate expression with respect to variable 'x':
Expression expDerived = exp.derive('x');

print(
'Differentiated expression: \$expDerived'); // = (((x * 0.0) + (1.0 * 1.0)) - -(0.0))
print(
'Simplified differentiated expression: \${expDerived.simplify()}'); // = 1.0
}

/**
* Example 3: Custom function definition and use
*
* How to create an arbitrary custom function expression and evaluate it.
*/
void _custom_function_definition_and_use() {
print('\nExample 3: Custom function definition and use\n');

// (1) Create and evaluate custom function: DOUBLEUP (R -> R)
ContextModel cm = ContextModel();
Variable x = Variable('x');
CustomFunction doubleup = CustomFunction('doubleup', [x], x * new Number(2));

cm.bindVariable(x, Number(0.5));

print('\$doubleup = \${doubleup.expression}');
print(
'doubleup(\${cm.getExpression('x')}) = \${doubleup.evaluate(EvaluationType.REAL, cm)}\n');

// (1) Create and evaluate custom function: LEFTSHIFT (R² -> R)
// Shifting to the left makes the number larger, effectively multiplying the
// number by pow(2, shiftIndex). Custom implementation of x << i.
Variable shiftIndex = Variable('i');
CustomFunction leftshift = new CustomFunction(
'leftshift', [x, shiftIndex], x * new Power(2, shiftIndex));

cm.bindVariable(x, Number(250));
cm.bindVariable(shiftIndex, Number(8));

print('\$leftshift = \${leftshift.expression}');
print(
'leftshift(\${cm.getExpression('x')}, \${cm.getExpression('i')}) = \${leftshift.evaluate(EvaluationType.REAL, cm)}');
}
``````

## Use this package as a library

### 1. Depend on it

``````
dependencies:
math_expressions: ^1.1.1

``````

### 2. Install it

You can install packages from the command line:

with pub:

``````
\$ pub get

``````

with Flutter:

``````
\$ flutter pub get

``````

Alternatively, your editor might support `pub get` or `flutter 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';
``````
 Popularity: Describes how popular the package is relative to other packages. [more] 91 Health: Code health derived from static analysis. [more] 75 Maintenance: Reflects how tidy and up-to-date the package is. [more] 100 Overall: Weighted score of the above. [more] 88

We analyzed this package on Feb 27, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

• Dart: 2.7.1
• pana: 0.13.5

#### Health suggestions

Fix `lib/src/functions.dart`. (-25 points)

Analysis of `lib/src/functions.dart` reported 76 hints, including:

line 24 col 46: Unnecessary new keyword.

line 98 col 13: Unnecessary new keyword.

line 104 col 12: Unnecessary new keyword.

line 113 col 12: Unnecessary new keyword.

line 173 col 11: Unnecessary new keyword.

Fix `lib/src/parser.dart`. (-25 points)

Analysis of `lib/src/parser.dart` reported 62 hints, including:

line 16 col 20: Unnecessary new keyword.

line 24 col 13: Unnecessary new keyword.

line 35 col 22: Unnecessary new keyword.

line 38 col 22: Unnecessary new keyword.

line 74 col 22: Unnecessary new keyword.

Fix `lib/src/expression.dart`. (-24.10 points)

Analysis of `lib/src/expression.dart` reported 55 hints, including:

line 32 col 44: Unnecessary new keyword.

line 35 col 44: Unnecessary new keyword.

line 38 col 44: Unnecessary new keyword.

line 41 col 44: Unnecessary new keyword.

line 44 col 44: Unnecessary new keyword.

Fix additional 3 files with analysis or formatting issues. (-23.40 points)

Additional issues in the following files:

• `lib/src/algebra.dart` (36 hints)
• `lib/src/evaluator.dart` (8 hints)
• `bin/interpreter.dart` (6 hints)

#### Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0 <3.0.0
vector_math ^2.0.0 2.0.8
Dev dependencies
pedantic ^1.4.0
test ^1.3.0