Expression Manipulation

Symbolics.jl provides functionality for easily manipulating expressions. Most of the functionality comes by the expression objects obeying the standard mathematical semantics. For example, if one has A a matrix of symbolic expressions wrapped in Num, then A^2 calculates the expressions for the squared matrix. It is thus encouraged to use standard Julia for performing many of the manipulation on the IR. For example, calculating the sparse form of the matrix via sparse(A) is valid, legible, and easily understandable to all Julia programmers.

Functionality Inherited From SymbolicUtils.jl

The substitute and simplify functions are provided by SymbolicUtils and reexported by Symbolics. Documentation for rewriter can be found here, using the @rule macro or the @acrule macro from SymbolicUtils.jl.

Functionality Provided by SymPy.jl Integration

SymPy also includes solves as well, and the SymPy.jl extensions allow for automatically converting Symbolics expressions for use in its simplifier.

Symbolics.sympy_simplifyFunction
sympy_simplify(expr)

Simplifies a Symbolics expression using SymPy.

Arguments

  • expr: Symbolics expression.

Returns

Simplified Symbolics expression.

Example

@variables x
expr = x^2 + 2x^2
result = sympy_simplify(expr)
source

Additional Manipulation Functions

Other additional manipulation functions are given below.

SymbolicUtils.substituteFunction
substitute(expr, s; fold=Val(false))

Performs the substitution on expr according to rule(s) s. If fold=Val(true), expressions which can be fully evaluated will be evaluated to a number.

Does not penetrate `Differential`

As of Symbolics.jl v7 (SymbolicUtils.jl v4), substitute does not recurse into the arguments of Differential expressions. For example, substitute(D(x), Dict(x => y)) returns D(x), not D(y). Use substitute_in_deriv or substitute_in_deriv_and_depvar to substitute inside Differential applications.

Examples

julia> using Symbolics

julia> @variables t x y z(t)
4-element Vector{Num}:
    t
    x
    y
 z(t)

julia> ex = x + y + sin(z)
sin(z(t)) + x + y

julia> substitute(ex, Dict([x => z, sin(z) => z^2]))
y + z(t) + z(t)^2

julia> substitute(sqrt(2x), Dict([x => 1]))
sqrt(2)

julia> substitute(sqrt(2x), Dict([x => 1]); fold=Val(true))
1.4142135623730951
source
Symbolics.get_variablesFunction
get_variables(e, varlist = nothing; kw...)

Return a vector of variables appearing in e, optionally restricting to variables in varlist. Takes the same keyword arguments as SymbolicUtils.search_variables.

Note that the returned variables are not wrapped in the Num type.

Examples ≡≡≡≡≡≡≡≡

julia> @variables t x y z(t);

julia> Symbolics.get_variables(x + y + sin(z))
3-element Vector{SymbolicUtils.BasicSymbolic}:
 x
 y
 z(t)

julia> Symbolics.get_variables(x - y)
2-element Vector{SymbolicUtils.BasicSymbolic}:
 x
 y
source
Symbolics.tosymbolFunction
tosymbol(x::Union{Num,BasicSymbolic}; states=nothing, escape=true) -> Symbol

Convert x to a symbol. states are the states of a system, and escape means if the target has escapes like val"y(t)". If escape is false, then it will only output y instead of y(t).

Examples

julia> @variables t z(t)
2-element Vector{Num}:
    t
 z(t)

julia> Symbolics.tosymbol(z)
Symbol("z(t)")

julia> Symbolics.tosymbol(z; escape=false)
:z
source
Symbolics.diff2termFunction
diff2term(x) -> BasicSymbolic

Convert a differential variable to a Term. Note that it only takes a Term not a Num.

julia> using Symbolics

julia> vars = @variables x t u(x, t) z(t)[1:2]; length(vars)
4

julia> Dt = Differential(t)
Differential(t, 1)

julia> Dx = Differential(x)
Differential(x, 1)

julia> Symbolics.diff2term(Symbolics.value(Dx(Dt(u))))
uˍxt(x, t)

julia> Symbolics.diff2term(Symbolics.value(Dt(z[1])))
(zˍt(t))[1]
source
Symbolics.degreeFunction
degree(p, sym=nothing)

Extract the degree of p with respect to sym.

Examples

julia> @variables x;

julia> Symbolics.degree(x^0)
0

julia> Symbolics.degree(x)
1

julia> Symbolics.degree(x^2)
2
source
Symbolics.coeffFunction
coeff(p, sym=nothing)

Extract the coefficient of p with respect to sym. Note that p might need to be expanded and/or simplified with expand and/or simplify.

Examples

julia> @variables a x y;

julia> Symbolics.coeff(2a, x)
0

julia> Symbolics.coeff(3x + 2y, y)
2

julia> Symbolics.coeff(x^2 + y, x^2)
1

julia> Symbolics.coeff(2*x*y + y, x*y)
2
source
Symbolics.fixpoint_subFunction
fixpoint_sub(
    expr, dict, ::Type{OP} = Nothing;
    maxiters = 1000,
    warn_maxiters = true,
    filterer = SymbolicUtils.default_substitute_filter,
    fold = Val(false),
)

Recursively apply the substitutions in dict until expr no longer changes. Substitutions that depend on one another are fully expanded. Circular substitutions stop after maxiters applications.

Arguments

  • expr: symbolic expression, equation, inequality, or array to transform.
  • dict: substitution rules accepted by SymbolicUtils.Substituter.
  • OP: operator type whose contents should not be substituted. The default Nothing does not exclude an operator type.

Keywords

  • maxiters::Integer = 1000: maximum number of repeated substitutions.
  • warn_maxiters::Bool = true: emit a warning when the iteration limit is reached.
  • filterer = SymbolicUtils.default_substitute_filter: predicate controlling which expression nodes may be substituted.
  • fold::Val = Val(false): whether to constant-fold while substituting.

Returns

The transformed value after reaching a fixpoint or the iteration limit.

Examples

julia> using Symbolics

julia> @variables x y;

julia> Symbolics.fixpoint_sub(x, Dict(x => y, y => 3))
3

See also: FixpointSubstituter.

source
Symbolics.evaluateFunction
evaluate(eq::Equation, subs)
evaluate(ineq::Inequality, subs)

Evaluate the equation eq or inequality ineq. subs is a dictionary of variable to numerical value substitutions. If both sides of the equation or inequality are numeric, then the result is a boolean.

Examples

julia> @variables x y
julia> eq = x ~ y
julia> evaluate(eq, Dict(x => 1, y => 1))
true

julia> ltr = x ≲ y
julia> evaluate(ltr, Dict(x => 1, y => 2))
true

julia> gtr = x ≳ y
julia> evaluate(gtr, Dict(x => 1, y => 2))
false
source
Symbolics.symbolic_to_floatFunction
symbolic_to_float(x::Union{Num, BasicSymbolic})::Union{AbstractFloat, BasicSymbolic}

If the symbolic value is exactly equal to a number, converts the symbolic value to a floating point number. Otherwise retains the symbolic value.

Examples

symbolic_to_float((1//2 * x)/x) # 0.5
symbolic_to_float((1/2 * x)/x) # 0.5
symbolic_to_float((1//2)*√(279//4)) # 4.175823272122517
source
Symbolics.termsMethod
terms(x)

Get the terms of the symbolic expression x.

Examples

julia> terms(-x + y - z)
3-element Vector{Num}:
 -z
  y
 -x
source
Symbolics.factorsMethod
factors(x)

Get the factors of the symbolic expression x.

Examples

julia> factors(2 * x * y)
3-element Vector{Num}:
 2
 y
 x
source
Base.numeratorMethod
numerator(x)

Return the numerator of the symbolic expression x.

Examples

julia> numerator(x/y)
x
source
Base.denominatorMethod
denominator(x)

Return the denominator of the symbolic expression x.

Examples

julia> denominator(x/y)
y
source
TermInterface.argumentsFunction
arguments(x, op::Function)

Get the arguments of the symbolic expression x with respect to the operation or function op.

source
Symbolics.hasnodeFunction
hasnode(c, x)

Returns true if any part of x fulfills the condition given in c. c can be a function or an expression. If it is a function, returns true if x is true for any part of x. If c is an expression, returns true if x contains c.

Examples:

@syms x y
hasnode(x, log(x) + x + 1) # returns `true`.
hasnode(x, log(y) + y + 1) # returns `false`.
@variables t X(t)
D = Differential(t)
hasnode(Symbolics.is_derivative, X + D(X) + D(X^2)) # returns `true`.
source
Symbolics.filterchildrenFunction
filterchildren(c, x)

Returns all parts of x that fulfills the condition given in c. c can be a function or an expression. If it is a function, returns everything for which the function is true. If c is an expression, returns all expressions that matches it.

Examples:

@syms x
Symbolics.filterchildren(x, log(x) + x + 1)

returns [x, x]

@variables t X(t)
D = Differential(t)
Symbolics.filterchildren(Symbolics.is_derivative, X + D(X) + D(X^2))

returns [Differential(t)(X(t)^2), Differential(t)(X(t))]

source
Symbolics.replacenodeFunction
replacenode(expr::BasicSymbolic, rules...)

Walk the expression and replacenode subexpressions according to rules. rules could be rules constructed with @rule, a function, or a pair where the left hand side is matched with equality (using isequal) and is replacenoded by the right hand side.

Rules will be applied left-to-right simultaneously, so only one pattern will be applied to any subexpression, and the patterns will only be applied to the input text, not the replacenodements.

Set fixpoint = true to repeatedly apply rules until no change to the expression remains to be made.

source
Symbolics.gather_factorFunction
gather_factor(expr, sym)
gather_factor(expr, syms::AbstractArray)

Collect the additive terms of expr by grouping them according to the powers of sym that they contain. Equivalent to SymPy's collect.

Operates directly on the dict-based representation of the Add / Mul IR nodes for efficiency.

For multiple symbols, collection is applied sequentially left-to-right.

Examples

julia> @variables a b x;

julia> gather_factor(a*b*x + a*b + b*x, x)
a*b + (b + a*b)*x

julia> gather_factor(a*b*x + a*b + b*x, b)
(a + x + a*x)*b

julia> gather_factor(x^2 + 2x + 1, x)
1 + 2x + x^2
source
gather_factor(expr, syms::AbstractArray)

Apply gather_factor sequentially for each element of syms.

source
Symbolics.FixpointSubstituterType
FixpointSubstituter{Fold, #= ... =# } <: SymbolicUtils.Substituter{Fold}

A substituter which repeatedly substitutes an expression until a fixpoint is reached, or a maximum number of substitutions in case of circular rules. For example, the rules [x => y, y => x] will lead to hitting the maximum iterations. This follows the same caching rules as SymbolicUtils.Substituter.

See also: fixpoint_sub.

source
Symbolics.sympy_pythoncall_simplifyFunction
sympy_pythoncall_simplify(expr)

Simplifies symbolic expressions using SymPyPythonCall.

Arguments

  • expr: Symbolics expression to simplify.

Returns

Simplified Symbolics expression.

Example

@variables x
expr = (x^2 - 1)/(x - 1)
result = sympy_pythoncall_simplify(expr)
source