Symbolic calculations in Julia
Symbolics.jl
is a computer Algebra System (CAS) for Julia. The symbols are number-like and follow Julia semantics so we can put them into a regular function to get a symbolic counterpart. Symbolics.jl is the backbone of ModelingToolkit.jl. Comparision to SymPy
Source:
Caveats about Symbolics.jl
Symbolics.jl
can only handle traceble, quasi-static expressions. However, some expressions are not quasi-static e.g. factorial. The number of operations depends on the input value.
Use @register_symbolic
to stop Symbolics.jl from digging further.
Some code paths is untraceable, such as conditional statements: if
…else
…end
.
You can use ifelse(cond, ex1, ex2)
or (cond) * (ex1) + (1 - cond) * (ex2)
to make it traceable.
Basic operations
latexify
derivative
gradient
jacobian
substitute
simplify
\[ \begin{equation}
x^{2} + y^{2}
\end{equation}
\]
You can use Latexify.latexify()
to see the LaTeX code.
\[\begin{split}\begin{equation}
\left[
\begin{array}{ccc}
y + x^{2} & 0 & 2 x \\
0 & 0 & 2 y \\
x + y^{2} & 0 & 0 \\
\end{array}
\right]
\end{equation}\end{split}\]
Derivative: Symbolics.derivative(expr, variable)
\[ \begin{equation}
2 x
\end{equation}
\]
Gradient: Symbolics.gradient(expr, [variables])
\[\begin{split} \begin{equation}
\left[
\begin{array}{c}
2 x \\
2 y \\
\end{array}
\right]
\end{equation}
\end{split}\]
Jacobian: Symbolics.jacobian([exprs], [variables])
\[\begin{split} \begin{equation}
\left[
\begin{array}{cc}
2 x & 2 y \\
0 & 2 y \\
\end{array}
\right]
\end{equation}
\end{split}\]
Substitute: Symbolics.substitute(expr, mapping)
\[ \begin{equation}
2 + \sin^{2}\left( y^{2} \right) + \cos^{2}\left( y^{2} \right)
\end{equation}
\]
\[ \begin{equation}
3
\end{equation}
\]
Simplify: Symbolics.simplify(expr)
\[ \begin{equation}
3
\end{equation}
\]
This expression gets automatically simplified because it’s always true
\[ \begin{equation}
x
\end{equation}
\]
You need to simplify the expressions.
\[ \begin{equation}
1
\end{equation}
\]
Symbolic integration: use SymbolicNumericIntegration.jl. The Youtube video by doggo dot jl
gives a concise example.
More number types
Complex number
\[\begin{split} \begin{equation}
\left[
\begin{array}{c}
\mathrm{real}\left( z \right) + \mathrm{imag}\left( z \right) \mathit{i} \\
\end{array}
\right]
\end{equation}
\end{split}\]
Array types with subscript
1-element Vector{Symbolics.Arr{Symbolics.Num, 1}}:
xs[1:20]
\[ \begin{equation}
\mathtt{xs}_{1}
\end{equation}
\]
Explicit vector form
\[\begin{split} \begin{equation}
\left[
\begin{array}{c}
\mathtt{xs}_{1} \\
\mathtt{xs}_{2} \\
\mathtt{xs}_{3} \\
\mathtt{xs}_{4} \\
\mathtt{xs}_{5} \\
\mathtt{xs}_{6} \\
\mathtt{xs}_{7} \\
\mathtt{xs}_{8} \\
\mathtt{xs}_{9} \\
\mathtt{xs}_{10} \\
\mathtt{xs}_{11} \\
\mathtt{xs}_{12} \\
\mathtt{xs}_{13} \\
\mathtt{xs}_{14} \\
\mathtt{xs}_{15} \\
\mathtt{xs}_{16} \\
\mathtt{xs}_{17} \\
\mathtt{xs}_{18} \\
\mathtt{xs}_{19} \\
\mathtt{xs}_{20} \\
\end{array}
\right]
\end{equation}
\end{split}\]
Operations on arrays are supported
\[ \begin{equation}
\mathtt{xs}_{1} + \mathtt{xs}_{10} + \mathtt{xs}_{11} + \mathtt{xs}_{12} + \mathtt{xs}_{13} + \mathtt{xs}_{14} + \mathtt{xs}_{15} + \mathtt{xs}_{16} + \mathtt{xs}_{17} + \mathtt{xs}_{18} + \mathtt{xs}_{19} + \mathtt{xs}_{2} + \mathtt{xs}_{20} + \mathtt{xs}_{3} + \mathtt{xs}_{4} + \mathtt{xs}_{5} + \mathtt{xs}_{6} + \mathtt{xs}_{7} + \mathtt{xs}_{8} + \mathtt{xs}_{9}
\end{equation}
\]
Example: Rosenbrock function
Wikipedia: https://en.wikipedia.org/wiki/Rosenbrock_function
We use the vector form of Rosenbrock function.
rosenbrock (generic function with 1 method)
The function is at minimum when xs are all one’s
Making a 20-element array
1-element Vector{Symbolics.Arr{Symbolics.Num, 1}}:
xs[1:20]
A full list of vector components
\[\begin{split} \begin{equation}
\left[
\begin{array}{c}
\mathtt{xs}_{1} \\
\mathtt{xs}_{2} \\
\mathtt{xs}_{3} \\
\mathtt{xs}_{4} \\
\mathtt{xs}_{5} \\
\mathtt{xs}_{6} \\
\mathtt{xs}_{7} \\
\mathtt{xs}_{8} \\
\mathtt{xs}_{9} \\
\mathtt{xs}_{10} \\
\mathtt{xs}_{11} \\
\mathtt{xs}_{12} \\
\mathtt{xs}_{13} \\
\mathtt{xs}_{14} \\
\mathtt{xs}_{15} \\
\mathtt{xs}_{16} \\
\mathtt{xs}_{17} \\
\mathtt{xs}_{18} \\
\mathtt{xs}_{19} \\
\mathtt{xs}_{20} \\
\end{array}
\right]
\end{equation}
\end{split}\]
\[ \begin{equation}
\left( 1 - \mathtt{xs}_{1} \right)^{2} + \left( 1 - \mathtt{xs}_{10} \right)^{2} + \left( 1 - \mathtt{xs}_{11} \right)^{2} + \left( 1 - \mathtt{xs}_{12} \right)^{2} + \left( 1 - \mathtt{xs}_{13} \right)^{2} + \left( 1 - \mathtt{xs}_{14} \right)^{2} + \left( 1 - \mathtt{xs}_{15} \right)^{2} + \left( 1 - \mathtt{xs}_{16} \right)^{2} + \left( 1 - \mathtt{xs}_{17} \right)^{2} + \left( 1 - \mathtt{xs}_{18} \right)^{2} + \left( 1 - \mathtt{xs}_{19} \right)^{2} + \left( 1 - \mathtt{xs}_{2} \right)^{2} + \left( 1 - \mathtt{xs}_{3} \right)^{2} + \left( 1 - \mathtt{xs}_{4} \right)^{2} + \left( 1 - \mathtt{xs}_{5} \right)^{2} + \left( 1 - \mathtt{xs}_{6} \right)^{2} + \left( 1 - \mathtt{xs}_{7} \right)^{2} + \left( 1 - \mathtt{xs}_{8} \right)^{2} + \left( 1 - \mathtt{xs}_{9} \right)^{2} + 100 \left( \mathtt{xs}_{2} - \left( \mathtt{xs}_{1} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{11} - \left( \mathtt{xs}_{10} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{12} - \left( \mathtt{xs}_{11} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{13} - \left( \mathtt{xs}_{12} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{14} - \left( \mathtt{xs}_{13} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{15} - \left( \mathtt{xs}_{14} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{16} - \left( \mathtt{xs}_{15} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{17} - \left( \mathtt{xs}_{16} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{18} - \left( \mathtt{xs}_{17} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{19} - \left( \mathtt{xs}_{18} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{20} - \left( \mathtt{xs}_{19} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{3} - \left( \mathtt{xs}_{2} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{4} - \left( \mathtt{xs}_{3} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{5} - \left( \mathtt{xs}_{4} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{6} - \left( \mathtt{xs}_{5} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{7} - \left( \mathtt{xs}_{6} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{8} - \left( \mathtt{xs}_{7} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{9} - \left( \mathtt{xs}_{8} \right)^{2} \right)^{2} + 100 \left( \mathtt{xs}_{10} - \left( \mathtt{xs}_{9} \right)^{2} \right)^{2}
\end{equation}
\]
Gradient
\[\begin{split} \begin{equation}
\left[
\begin{array}{c}
- 2 \left( 1 - \mathtt{xs}_{1} \right) - 400 \mathtt{xs}_{1} \left( \mathtt{xs}_{2} - \left( \mathtt{xs}_{1} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{2} \right) + 200 \left( \mathtt{xs}_{2} - \left( \mathtt{xs}_{1} \right)^{2} \right) - 400 \mathtt{xs}_{2} \left( \mathtt{xs}_{3} - \left( \mathtt{xs}_{2} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{3} \right) + 200 \left( \mathtt{xs}_{3} - \left( \mathtt{xs}_{2} \right)^{2} \right) - 400 \mathtt{xs}_{3} \left( \mathtt{xs}_{4} - \left( \mathtt{xs}_{3} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{4} \right) + 200 \left( \mathtt{xs}_{4} - \left( \mathtt{xs}_{3} \right)^{2} \right) - 400 \mathtt{xs}_{4} \left( \mathtt{xs}_{5} - \left( \mathtt{xs}_{4} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{5} \right) + 200 \left( \mathtt{xs}_{5} - \left( \mathtt{xs}_{4} \right)^{2} \right) - 400 \mathtt{xs}_{5} \left( \mathtt{xs}_{6} - \left( \mathtt{xs}_{5} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{6} \right) + 200 \left( \mathtt{xs}_{6} - \left( \mathtt{xs}_{5} \right)^{2} \right) - 400 \mathtt{xs}_{6} \left( \mathtt{xs}_{7} - \left( \mathtt{xs}_{6} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{7} \right) + 200 \left( \mathtt{xs}_{7} - \left( \mathtt{xs}_{6} \right)^{2} \right) - 400 \mathtt{xs}_{7} \left( \mathtt{xs}_{8} - \left( \mathtt{xs}_{7} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{8} \right) + 200 \left( \mathtt{xs}_{8} - \left( \mathtt{xs}_{7} \right)^{2} \right) - 400 \mathtt{xs}_{8} \left( \mathtt{xs}_{9} - \left( \mathtt{xs}_{8} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{9} \right) + 200 \left( \mathtt{xs}_{9} - \left( \mathtt{xs}_{8} \right)^{2} \right) - 400 \mathtt{xs}_{9} \left( \mathtt{xs}_{10} - \left( \mathtt{xs}_{9} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{10} \right) + 200 \left( \mathtt{xs}_{10} - \left( \mathtt{xs}_{9} \right)^{2} \right) - 400 \mathtt{xs}_{10} \left( \mathtt{xs}_{11} - \left( \mathtt{xs}_{10} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{11} \right) + 200 \left( \mathtt{xs}_{11} - \left( \mathtt{xs}_{10} \right)^{2} \right) - 400 \mathtt{xs}_{11} \left( \mathtt{xs}_{12} - \left( \mathtt{xs}_{11} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{12} \right) + 200 \left( \mathtt{xs}_{12} - \left( \mathtt{xs}_{11} \right)^{2} \right) - 400 \mathtt{xs}_{12} \left( \mathtt{xs}_{13} - \left( \mathtt{xs}_{12} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{13} \right) + 200 \left( \mathtt{xs}_{13} - \left( \mathtt{xs}_{12} \right)^{2} \right) - 400 \mathtt{xs}_{13} \left( \mathtt{xs}_{14} - \left( \mathtt{xs}_{13} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{14} \right) + 200 \left( \mathtt{xs}_{14} - \left( \mathtt{xs}_{13} \right)^{2} \right) - 400 \mathtt{xs}_{14} \left( \mathtt{xs}_{15} - \left( \mathtt{xs}_{14} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{15} \right) + 200 \left( \mathtt{xs}_{15} - \left( \mathtt{xs}_{14} \right)^{2} \right) - 400 \mathtt{xs}_{15} \left( \mathtt{xs}_{16} - \left( \mathtt{xs}_{15} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{16} \right) + 200 \left( \mathtt{xs}_{16} - \left( \mathtt{xs}_{15} \right)^{2} \right) - 400 \mathtt{xs}_{16} \left( \mathtt{xs}_{17} - \left( \mathtt{xs}_{16} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{17} \right) + 200 \left( \mathtt{xs}_{17} - \left( \mathtt{xs}_{16} \right)^{2} \right) - 400 \mathtt{xs}_{17} \left( \mathtt{xs}_{18} - \left( \mathtt{xs}_{17} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{18} \right) + 200 \left( \mathtt{xs}_{18} - \left( \mathtt{xs}_{17} \right)^{2} \right) - 400 \mathtt{xs}_{18} \left( \mathtt{xs}_{19} - \left( \mathtt{xs}_{18} \right)^{2} \right) \\
- 2 \left( 1 - \mathtt{xs}_{19} \right) + 200 \left( \mathtt{xs}_{19} - \left( \mathtt{xs}_{18} \right)^{2} \right) - 400 \mathtt{xs}_{19} \left( \mathtt{xs}_{20} - \left( \mathtt{xs}_{19} \right)^{2} \right) \\
200 \left( \mathtt{xs}_{20} - \left( \mathtt{xs}_{19} \right)^{2} \right) \\
\end{array}
\right]
\end{equation}
\end{split}\]
Hessian = Jacobian of gradient
\[\begin{split} \begin{equation}
\left[
\begin{array}{cccccccccccccccccccc}
2 + 800 \left( \mathtt{xs}_{1} \right)^{2} - 400 \left( \mathtt{xs}_{2} - \left( \mathtt{xs}_{1} \right)^{2} \right) & - 400 \mathtt{xs}_{1} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
- 400 \mathtt{xs}_{1} & 202 - 400 \left( \mathtt{xs}_{3} - \left( \mathtt{xs}_{2} \right)^{2} \right) + 800 \left( \mathtt{xs}_{2} \right)^{2} & - 400 \mathtt{xs}_{2} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & - 400 \mathtt{xs}_{2} & 202 + 800 \left( \mathtt{xs}_{3} \right)^{2} - 400 \left( \mathtt{xs}_{4} - \left( \mathtt{xs}_{3} \right)^{2} \right) & - 400 \mathtt{xs}_{3} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & - 400 \mathtt{xs}_{3} & 202 - 400 \left( \mathtt{xs}_{5} - \left( \mathtt{xs}_{4} \right)^{2} \right) + 800 \left( \mathtt{xs}_{4} \right)^{2} & - 400 \mathtt{xs}_{4} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & - 400 \mathtt{xs}_{4} & 202 + 800 \left( \mathtt{xs}_{5} \right)^{2} - 400 \left( \mathtt{xs}_{6} - \left( \mathtt{xs}_{5} \right)^{2} \right) & - 400 \mathtt{xs}_{5} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{5} & 202 - 400 \left( \mathtt{xs}_{7} - \left( \mathtt{xs}_{6} \right)^{2} \right) + 800 \left( \mathtt{xs}_{6} \right)^{2} & - 400 \mathtt{xs}_{6} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{6} & 202 + 800 \left( \mathtt{xs}_{7} \right)^{2} - 400 \left( \mathtt{xs}_{8} - \left( \mathtt{xs}_{7} \right)^{2} \right) & - 400 \mathtt{xs}_{7} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{7} & 202 + 800 \left( \mathtt{xs}_{8} \right)^{2} - 400 \left( \mathtt{xs}_{9} - \left( \mathtt{xs}_{8} \right)^{2} \right) & - 400 \mathtt{xs}_{8} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{8} & 202 + 800 \left( \mathtt{xs}_{9} \right)^{2} - 400 \left( \mathtt{xs}_{10} - \left( \mathtt{xs}_{9} \right)^{2} \right) & - 400 \mathtt{xs}_{9} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{9} & 202 - 400 \left( \mathtt{xs}_{11} - \left( \mathtt{xs}_{10} \right)^{2} \right) + 800 \left( \mathtt{xs}_{10} \right)^{2} & - 400 \mathtt{xs}_{10} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{10} & 202 + 800 \left( \mathtt{xs}_{11} \right)^{2} - 400 \left( \mathtt{xs}_{12} - \left( \mathtt{xs}_{11} \right)^{2} \right) & - 400 \mathtt{xs}_{11} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{11} & 202 - 400 \left( \mathtt{xs}_{13} - \left( \mathtt{xs}_{12} \right)^{2} \right) + 800 \left( \mathtt{xs}_{12} \right)^{2} & - 400 \mathtt{xs}_{12} & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{12} & 202 - 400 \left( \mathtt{xs}_{14} - \left( \mathtt{xs}_{13} \right)^{2} \right) + 800 \left( \mathtt{xs}_{13} \right)^{2} & - 400 \mathtt{xs}_{13} & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{13} & 202 - 400 \left( \mathtt{xs}_{15} - \left( \mathtt{xs}_{14} \right)^{2} \right) + 800 \left( \mathtt{xs}_{14} \right)^{2} & - 400 \mathtt{xs}_{14} & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{14} & 202 - 400 \left( \mathtt{xs}_{16} - \left( \mathtt{xs}_{15} \right)^{2} \right) + 800 \left( \mathtt{xs}_{15} \right)^{2} & - 400 \mathtt{xs}_{15} & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{15} & 202 - 400 \left( \mathtt{xs}_{17} - \left( \mathtt{xs}_{16} \right)^{2} \right) + 800 \left( \mathtt{xs}_{16} \right)^{2} & - 400 \mathtt{xs}_{16} & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{16} & 202 - 400 \left( \mathtt{xs}_{18} - \left( \mathtt{xs}_{17} \right)^{2} \right) + 800 \left( \mathtt{xs}_{17} \right)^{2} & - 400 \mathtt{xs}_{17} & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{17} & 202 + 800 \left( \mathtt{xs}_{18} \right)^{2} - 400 \left( \mathtt{xs}_{19} - \left( \mathtt{xs}_{18} \right)^{2} \right) & - 400 \mathtt{xs}_{18} & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{18} & 202 - 400 \left( \mathtt{xs}_{20} - \left( \mathtt{xs}_{19} \right)^{2} \right) + 800 \left( \mathtt{xs}_{19} \right)^{2} & - 400 \mathtt{xs}_{19} \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{19} & 200 \\
\end{array}
\right]
\end{equation}
\end{split}\]
call hessian()
directly
\[\begin{split} \begin{equation}
\left[
\begin{array}{cccccccccccccccccccc}
2 + 800 \left( \mathtt{xs}_{1} \right)^{2} - 400 \left( \mathtt{xs}_{2} - \left( \mathtt{xs}_{1} \right)^{2} \right) & - 400 \mathtt{xs}_{1} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
- 400 \mathtt{xs}_{1} & 202 - 400 \left( \mathtt{xs}_{3} - \left( \mathtt{xs}_{2} \right)^{2} \right) + 800 \left( \mathtt{xs}_{2} \right)^{2} & - 400 \mathtt{xs}_{2} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & - 400 \mathtt{xs}_{2} & 202 + 800 \left( \mathtt{xs}_{3} \right)^{2} - 400 \left( \mathtt{xs}_{4} - \left( \mathtt{xs}_{3} \right)^{2} \right) & - 400 \mathtt{xs}_{3} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & - 400 \mathtt{xs}_{3} & 202 - 400 \left( \mathtt{xs}_{5} - \left( \mathtt{xs}_{4} \right)^{2} \right) + 800 \left( \mathtt{xs}_{4} \right)^{2} & - 400 \mathtt{xs}_{4} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & - 400 \mathtt{xs}_{4} & 202 + 800 \left( \mathtt{xs}_{5} \right)^{2} - 400 \left( \mathtt{xs}_{6} - \left( \mathtt{xs}_{5} \right)^{2} \right) & - 400 \mathtt{xs}_{5} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{5} & 202 - 400 \left( \mathtt{xs}_{7} - \left( \mathtt{xs}_{6} \right)^{2} \right) + 800 \left( \mathtt{xs}_{6} \right)^{2} & - 400 \mathtt{xs}_{6} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{6} & 202 + 800 \left( \mathtt{xs}_{7} \right)^{2} - 400 \left( \mathtt{xs}_{8} - \left( \mathtt{xs}_{7} \right)^{2} \right) & - 400 \mathtt{xs}_{7} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{7} & 202 + 800 \left( \mathtt{xs}_{8} \right)^{2} - 400 \left( \mathtt{xs}_{9} - \left( \mathtt{xs}_{8} \right)^{2} \right) & - 400 \mathtt{xs}_{8} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{8} & 202 + 800 \left( \mathtt{xs}_{9} \right)^{2} - 400 \left( \mathtt{xs}_{10} - \left( \mathtt{xs}_{9} \right)^{2} \right) & - 400 \mathtt{xs}_{9} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{9} & 202 - 400 \left( \mathtt{xs}_{11} - \left( \mathtt{xs}_{10} \right)^{2} \right) + 800 \left( \mathtt{xs}_{10} \right)^{2} & - 400 \mathtt{xs}_{10} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{10} & 202 + 800 \left( \mathtt{xs}_{11} \right)^{2} - 400 \left( \mathtt{xs}_{12} - \left( \mathtt{xs}_{11} \right)^{2} \right) & - 400 \mathtt{xs}_{11} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{11} & 202 - 400 \left( \mathtt{xs}_{13} - \left( \mathtt{xs}_{12} \right)^{2} \right) + 800 \left( \mathtt{xs}_{12} \right)^{2} & - 400 \mathtt{xs}_{12} & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{12} & 202 - 400 \left( \mathtt{xs}_{14} - \left( \mathtt{xs}_{13} \right)^{2} \right) + 800 \left( \mathtt{xs}_{13} \right)^{2} & - 400 \mathtt{xs}_{13} & 0 & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{13} & 202 - 400 \left( \mathtt{xs}_{15} - \left( \mathtt{xs}_{14} \right)^{2} \right) + 800 \left( \mathtt{xs}_{14} \right)^{2} & - 400 \mathtt{xs}_{14} & 0 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{14} & 202 - 400 \left( \mathtt{xs}_{16} - \left( \mathtt{xs}_{15} \right)^{2} \right) + 800 \left( \mathtt{xs}_{15} \right)^{2} & - 400 \mathtt{xs}_{15} & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{15} & 202 - 400 \left( \mathtt{xs}_{17} - \left( \mathtt{xs}_{16} \right)^{2} \right) + 800 \left( \mathtt{xs}_{16} \right)^{2} & - 400 \mathtt{xs}_{16} & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{16} & 202 - 400 \left( \mathtt{xs}_{18} - \left( \mathtt{xs}_{17} \right)^{2} \right) + 800 \left( \mathtt{xs}_{17} \right)^{2} & - 400 \mathtt{xs}_{17} & 0 & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{17} & 202 + 800 \left( \mathtt{xs}_{18} \right)^{2} - 400 \left( \mathtt{xs}_{19} - \left( \mathtt{xs}_{18} \right)^{2} \right) & - 400 \mathtt{xs}_{18} & 0 \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{18} & 202 - 400 \left( \mathtt{xs}_{20} - \left( \mathtt{xs}_{19} \right)^{2} \right) + 800 \left( \mathtt{xs}_{19} \right)^{2} & - 400 \mathtt{xs}_{19} \\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - 400 \mathtt{xs}_{19} & 200 \\
\end{array}
\right]
\end{equation}
\end{split}\]
Sparse matrix
Sparse Hessian matrix of the Hessian matrix of the Rosenbrock function w.r.t. to vector components.
20×20 SparseArrays.SparseMatrixCSC{Bool, Int64} with 58 stored entries:
⎡⠻⣦⡀⠀⠀⠀⠀⠀⠀⠀⎤
⎢⠀⠈⠻⣦⡀⠀⠀⠀⠀⠀⎥
⎢⠀⠀⠀⠈⠻⣦⡀⠀⠀⠀⎥
⎢⠀⠀⠀⠀⠀⠈⠻⣦⡀⠀⎥
⎣⠀⠀⠀⠀⠀⠀⠀⠈⠻⣦⎦
Visualize the sparse matrix with Plots.spy()
Generate functions symbolically
https://docs.sciml.ai/Symbolics/stable/manual/build_function/
build_function(ex, args...)
generates out-of-place (oop) and in-place (ip) function expressions in a tuple pair.
build_function(ex, args..., parallel=Symbolics.MultithreadedForm())
generates a parallel, multithreaded algorithm.
build_function(ex, args..., target=Symbolics.CTarget())
generates a C function from Julia.
For example, we want to build a Julia function from grad
.
Get the Out-of-place f(input)
version
#3 (generic function with 1 method)
Get the In-place f!(out, in)
version
#5 (generic function with 1 method)
20-element Vector{Float64}:
157.35533084647494
-103.91378308259812
6.712704680676648
6.932609921943186
23.800540958336178
26.751210335685794
-35.595656272595036
39.0861293208317
37.559507028869405
-35.521117547121975
-39.48617284857703
111.2804937355183
-108.21815923481964
-1.2889368056793131
115.31848217997978
-52.68545296315378
95.14630577628606
-98.28547635929587
-6.5928820891437
88.64121296291844
To save the generated function for later use:
write("function.jl", string(fexprs[2]))
Load it back
g = include("function.jl")
Here, ForwardDiff.jl
checks if our gradient generated from Symbolics.jl
is correct.
Sparse Hessian matrix, only non-zero expressions are calculated.
20×20 SparseArrays.SparseMatrixCSC{Bool, Int64} with 58 stored entries:
⎡⠻⣦⡀⠀⠀⠀⠀⠀⠀⠀⎤
⎢⠀⠈⠻⣦⡀⠀⠀⠀⠀⠀⎥
⎢⠀⠀⠀⠈⠻⣦⡀⠀⠀⠀⎥
⎢⠀⠀⠀⠀⠀⠈⠻⣦⡀⠀⎥
⎣⠀⠀⠀⠀⠀⠀⠀⠈⠻⣦⎦
Solve equations symbolically
https://docs.sciml.ai/Symbolics/stable/manual/solver/
Use symbolic_solve(expr, x)
to get analytic solutions.
For single variable solving, the Nemo.jl
package is needed; for multiple variable solving, the Groebner.jl
package is needed.
This example solves the steady-state rate of a enzyme-catalyzed reaction of fumarate hydratase: https://bmcbioinformatics.biomedcentral.com/articles/10.1186/1471-2105-10-238. At steady-state, the rate of change of each state shoul be zero.
37.420144 seconds (123.44 M allocations: 5.187 GiB, 2.41% gc time, 83.18% compilation time: 14% of which was recompilation)
Dict{Symbolics.Num, Any} with 5 entries:
E4 => (k1*k2*k4*k6 + k1*k2*k4*km5 + k1*k2*k6*km3 + k1*k2*km3*km5 + k2*k3*k4*k…
E5 => (k1*k2*k6*km4 + k1*k2*km4*km5 + k2*k3*k5*k6 + k2*k3*k6*km4 + k2*k3*km4*…
E2 => (k1*k2*k4*k5 + k1*k2*k5*km3 + k2*k3*k4*k5 + k2*k4*k5*km6 + k2*k5*km3*km…
E1 => (k2*k4*k5*k6 + k2*k5*k6*km3 + k2*k6*km3*km4 + k2*km3*km4*km5 + k4*k5*k6…
E3 => (k1*k4*k5*k6 + k1*k4*k6*km2 + k1*k4*km2*km5 + k1*k5*k6*km3 + k1*k6*km2*…
The weight of the first enzyme state is
\[ \begin{equation}
\mathtt{k2} \mathtt{k4} \mathtt{k5} \mathtt{k6} + \mathtt{k2} \mathtt{k5} \mathtt{k6} \mathtt{km3} + \mathtt{k2} \mathtt{k6} \mathtt{km3} \mathtt{km4} + \mathtt{k2} \mathtt{km3} \mathtt{km4} \mathtt{km5} + \mathtt{k4} \mathtt{k5} \mathtt{k6} \mathtt{km1} + \mathtt{k4} \mathtt{k6} \mathtt{km1} \mathtt{km2} + \mathtt{k4} \mathtt{km1} \mathtt{km2} \mathtt{km5} + \mathtt{k5} \mathtt{k6} \mathtt{km1} \mathtt{km3} + \mathtt{k6} \mathtt{km1} \mathtt{km2} \mathtt{km3} + \mathtt{k6} \mathtt{km1} \mathtt{km3} \mathtt{km4} + \mathtt{km1} \mathtt{km2} \mathtt{km3} \mathtt{km5} + \mathtt{km1} \mathtt{km3} \mathtt{km4} \mathtt{km5}
\end{equation}
\]
This notebook was generated using Literate.jl.