Function simplify #
Simplify an expression tree.
A list of rules are applied to an expression, repeating over the list until no further changes are made. It’s possible to pass a custom set of rules to the function as second argument. A rule can be specified as an object, string, or function:
const rules = [
{ l: 'n1*n3 + n2*n3', r: '(n1+n2)*n3' },
'n1*n3 + n2*n3 -> (n1+n2)*n3',
function (node) {
// ... return a new node or return the node unchanged
return node
}
]
String and object rules consist of a left and right pattern. The left is used to match against the expression and the right determines what matches are replaced with. The main difference between a pattern and a normal expression is that variables starting with the following characters are interpreted as wildcards:
- ‘n’ - Matches any node [Node]
- ‘c’ - Matches a constant literal (5 or 3.2) [ConstantNode]
- ‘cl’ - Matches a constant literal; same as c [ConstantNode]
- ‘cd’ - Matches a decimal literal (5 or -3.2) [ConstantNode or unaryMinus wrapping a ConstantNode]
- ‘ce’ - Matches a constant expression (-5 or √3) [Expressions consisting of only ConstantNodes, functions, and operators]
- ‘v’ - Matches a variable; anything not matched by c (-5 or x) [Node that is not a ConstantNode]
- ‘vl’ - Matches a variable literal (x or y) [SymbolNode]
- ‘vd’ - Matches a non-decimal expression; anything not matched by cd (x or √3) [Node that is not a ConstantNode or unaryMinus that is wrapping a ConstantNode]
- ‘ve’ - Matches a variable expression; anything not matched by ce (x or 2x) [Expressions that contain a SymbolNode or other non-constant term]
The default list of rules is exposed on the function as simplify.rules
and can be used as a basis to built a set of custom rules. Note that since
the simplifyCore
function is in the default list of rules, by default
simplify will convert any function calls in the expression that have
operator equivalents to their operator forms.
To specify a rule as a string, separate the left and right pattern by ‘->’ When specifying a rule as an object, the following keys are meaningful:
- l - the left pattern
- r - the right pattern
- s - in lieu of l and r, the string form that is broken at -> to give them
- repeat - whether to repeat this rule until the expression stabilizes
- assuming - gives a context object, as in the ‘context’ option to simplify. Every property in the context object must match the current context in order, or else the rule will not be applied.
- imposeContext - gives a context object, as in the ‘context’ option to simplify. Any settings specified will override the incoming context for all matches of this rule.
For more details on the theory, see:
- Strategies for simplifying math expressions (Stackoverflow)
- Symbolic computation - Simplification (Wikipedia)
An optional options
argument can be passed as last argument of simplify
.
Currently available options (defaults in parentheses):
consoleDebug
(false): whether to write the expression being simplified and any changes to it, along with the rule responsible, to consolecontext
(simplify.defaultContext): an object giving properties of each operator, which determine what simplifications are allowed. The currently meaningful properties are commutative, associative, total (whether the operation is defined for all arguments), and trivial (whether the operation applied to a single argument leaves that argument unchanged). The default context is very permissive and allows almost all simplifications. Only properties differing from the default need to be specified; the default context is used as a fallback. Additional contextssimplify.realContext
andsimplify.positiveContext
are supplied to cause simplify to perform just simplifications guaranteed to preserve all values of the expression assuming all variables and subexpressions are real numbers or positive real numbers, respectively. (Note that these are in some cases more restrictive than the default context; for example, the default context will allowx/x
to simplify to 1, whereassimplify.realContext
will not, as0/0
is not equal to 1.)exactFractions
(true): whether to try to convert all constants to exact rational numbers.fractionsLimit
(10000): whenexactFractions
is true, constants will be expressed as fractions only when both numerator and denominator are smaller thanfractionsLimit
.
Syntax #
math.simplify(expr)
math.simplify(expr, rules)
math.simplify(expr, rules)
math.simplify(expr, rules, scope)
math.simplify(expr, rules, scope, options)
math.simplify(expr, scope)
math.simplify(expr, scope, options)
Parameters #
Parameter | Type | Description |
---|---|---|
expr |
Node | string | The expression to be simplified |
rules |
SimplifyRule[] | Optional list with custom rules |
scope |
Object | Optional scope with variables |
options |
SimplifyOptions | Optional configuration settings |
Returns #
Type | Description |
---|---|
Node | Returns the simplified form of expr |
Throws #
Type | Description —- | ———–
Examples #
math.simplify('2 * 1 * x ^ (2 - 1)') // Node "2 * x"
math.simplify('2 * 3 * x', {x: 4}) // Node "24"
const f = math.parse('2 * 1 * x ^ (2 - 1)')
math.simplify(f) // Node "2 * x"
math.simplify('0.4 * x', {}, {exactFractions: true}) // Node "x * 2 / 5"
math.simplify('0.4 * x', {}, {exactFractions: false}) // Node "0.4 * x"
See also #
simplifyCore, derivative, evaluate, parse, rationalize, resolve