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
SymbolicUtils.substitute — Functionsubstitute(expr, s; fold=true)Performs the substitution on expr according to rule(s) s. If fold=false, expressions which can be evaluated won't be evaluated.
Examples
julia> @variables t x y z(t)
4-element Vector{Num}:
t
x
y
z(t)
julia> ex = x + y + sin(z)
(x + y) + sin(z(t))
julia> substitute(ex, Dict([x => z, sin(z) => z^2]))
(z(t) + y) + (z(t) ^ 2)
julia> substitute(sqrt(2x), Dict([x => 1]); fold=false)
sqrt(2)SymbolicUtils.simplify — Functionsimplify(x; expand=false,
threaded=false,
thread_subtree_cutoff=100,
rewriter=nothing)Simplify an expression (x) by applying rewriter until there are no changes. expand=true applies expand in the beginning of each fixpoint iteration.
By default, simplify will assume denominators are not zero and allow cancellation in fractions. Pass simplify_fractions=false to prevent this.
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_simplify — Functionsympy_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)Additional Manipulation Functions
Other additional manipulation functions are given below.
Symbolics.get_variables — Functionget_variables(e, varlist = nothing; sort::Bool = false)Return a vector of variables appearing in e, optionally restricting to variables in varlist.
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); sort = true)
3-element Vector{SymbolicUtils.BasicSymbolic}:
x
y
z(t)
julia> Symbolics.get_variables(x - y; sort = true)
2-element Vector{SymbolicUtils.BasicSymbolic}:
x
ySymbolics.tosymbol — Functiontosymbol(x::Union{Num,Symbolic}; states=nothing, escape=true) -> SymbolConvert 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)
:zSymbolics.diff2term — Functiondiff2term(x, x_metadata::Dict{Datatype, Any}) -> SymbolicConvert a differential variable to a Term. Note that it only takes a Term not a Num. Any upstream metadata can be passed via x_metadata
julia> @variables x t u(x, t) z(t)[1:2]; Dt = Differential(t); Dx = Differential(x);
julia> Symbolics.diff2term(Symbolics.value(Dx(Dt(u))))
uˍtx(x, t)
julia> Symbolics.diff2term(Symbolics.value(Dt(z[1])))
(zˍt(t))[1]Symbolics.degree — Functiondegree(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)
2Symbolics.coeff — Functioncoeff(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)
2Missing docstring for Symbolics.replace. Check Documenter's build log for details.
Base.occursin — Functionoccursin(needle::Symbolic, haystack::Symbolic)Determine whether the second argument contains the first argument. Note that this function doesn't handle associativity, commutativity, or distributivity.
Symbolics.filterchildren — Functionfilterchildren(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))]
Symbolics.fixpoint_sub — Functionfixpoint_sub(expr, dict; operator = Nothing, maxiters = 1000)Given a symbolic expression, equation or inequality expr perform the substitutions in dict recursively until the expression does not change. Substitutions that depend on one another will thus be recursively expanded. For example, fixpoint_sub(x, Dict(x => y, y => 3)) will return 3. The operator keyword can be specified to prevent substitution of expressions inside operators of the given type. The maxiters keyword is used to limit the number of times the substitution can occur to avoid infinite loops in cases where the substitutions in dict are circular (e.g. [x => y, y => x]).
See also: fast_substitute.
Symbolics.fast_substitute — Functionfast_substitute(expr, dict; operator = Nothing)Given a symbolic expression, equation or inequality expr perform the substitutions in dict. This only performs the substitutions once. For example, fast_substitute(x, Dict(x => y, y => 3)) will return y. The operator keyword can be specified to prevent substitution of expressions inside operators of the given type.
See also: fixpoint_sub.
Symbolics.evaluate — Functionevaluate(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))
falseSymbolics.symbolic_to_float — Functionsymbolic_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.175823272122517Symbolics.terms — Methodterms(x)Get the terms of the symbolic expression x.
Examples
julia> terms(-x + y - z)
3-element Vector{Num}:
-z
y
-xSymbolics.factors — Methodfactors(x)Get the factors of the symbolic expression x.
Examples
julia> factors(2 * x * y)
3-element Vector{Num}:
2
y
xBase.numerator — Methodnumerator(x)Return the numerator of the symbolic expression x.
Examples
julia> numerator(x/y)
xBase.denominator — Methoddenominator(x)Return the denominator of the symbolic expression x.
Examples
julia> denominator(x/y)
y