Derivatives and Differentials
A Differential(op)
is a partial derivative with respect to op
, which can then be applied to some other operations. For example, D=Differential(t)
is what would commonly be referred to as d/dt
, which can then be applied to other operations using its function call, so D(x+y)
is d(x+y)/dt
.
By default, the derivatives are left unexpanded to capture the symbolic representation of the differential equation. If the user would like to expand out all the differentials, the expand_derivatives
function eliminates all the differentials down to basic one-variable expressions.
Symbolics.Differential
— Typestruct Differential <: Symbolics.Operator
Represents a differential operator.
Fields
x
: The variable or expression to differentiate with respect to.
Examples
julia> using Symbolics
julia> @variables x y;
julia> D = Differential(x)
(D'~x)
julia> D(y) # Differentiate y wrt. x
(D'~x)(y)
julia> Dx = Differential(x) * Differential(y) # d^2/dxy operator
(D'~x(t)) ∘ (D'~y(t))
julia> D3 = Differential(x)^3 # 3rd order differential operator
(D'~x(t)) ∘ (D'~x(t)) ∘ (D'~x(t))
Symbolics.expand_derivatives
— Functionexpand_derivatives(O; ...)
expand_derivatives(O, simplify; occurrences)
Expands derivatives within a symbolic expression O
.
This function recursively traverses a symbolic expression, applying the chain rule and other derivative rules to expand any derivatives it encounters.
Arguments
O::Symbolic
: The symbolic expression to expand.simplify::Bool=false
: Whether to simplify the resulting expression usingSymbolicUtils.simplify
.occurrences=nothing
: Information about the occurrences of the independent variable in the argument of the derivative. This is used internally for optimization purposes.
Examples
julia> @variables x y z k;
julia> f=k*(abs(x-y)/y-z)^2
k*((abs(x - y) / y - z)^2)
julia> Dx=Differential(x) # Differentiate wrt x
(::Differential) (generic function with 2 methods)
julia> dfx=expand_derivatives(Dx(f))
(k*((2abs(x - y)) / y - 2z)*IfElse.ifelse(signbit(x - y), -1, 1)) / y
Missing docstring for is_derivative
. Check Documenter's build log for details.
For symbolic differentiation, all registered functions in the symbolic expression need a registered derivative. For more information, see the function registration page.
High-Level Differentiation Functions
The following functions are not exported and thus must be accessed in a namespaced way, i.e. Symbolics.jacobian
.
Symbolics.derivative
— Functionderivative(O, var; simplify)
A helper function for computing the derivative of the expression O
with respect to var
.
Symbolics.jacobian
— Functionjacobian(ops, vars; simplify, scalarize)
A helper function for computing the Jacobian of an array of expressions with respect to an array of variable expressions.
Symbolics.sparsejacobian
— Functionsparsejacobian(ops, vars; simplify)
A helper function for computing the sparse Jacobian of an array of expressions with respect to an array of variable expressions.
Symbolics.sparsejacobian_vals
— Functionsparsejacobian_vals(ops, vars, I, J; simplify)
A helper function for computing the values of the sparse Jacobian of an array of expressions with respect to an array of variable expressions given the sparsity structure.
Symbolics.gradient
— Functiongradient(O, vars; simplify)
A helper function for computing the gradient of the expression O
with respect to an array of variable expressions.
Symbolics.hessian
— Functionhessian(O, vars; simplify)
A helper function for computing the Hessian of the expression O
with respect to an array of variable expressions.
Symbolics.sparsehessian
— Functionsparsehessian(op, vars; simplify, full)
A helper function for computing the sparse Hessian of an expression with respect to an array of variable expressions.
Symbolics.sparsehessian_vals
— Functionsparsehessian_vals(op, vars, I, J; simplify)
A helper function for computing the values of the sparse Hessian of an expression with respect to an array of variable expressions given the sparsity structure.
Adding Analytical Derivatives
There are many derivatives pre-defined by DiffRules.jl. For example,
using Symbolics
@variables x y z
f(x,y,z) = x^2 + sin(x+y) - z
f (generic function with 1 method)
f
automatically has the derivatives defined via the tracing mechanism. It will do this by directly building the internals of your function and differentiating that.
However, often you may want to define your own derivatives so that way automatic Jacobian etc. calculations can utilize this information. This can allow for more succinct versions of the derivatives to be calculated to scale to larger systems. You can define derivatives for your function via the dispatch:
# `N` arguments are accepted by the relevant method of `my_function`
Symbolics.derivative(::typeof(my_function), args::NTuple{N,Any}, ::Val{i})
where i
means that it's the derivative with respect to the i
th argument. args
is the array of arguments, so, for example, if your function is f(x,t)
, then args = [x,t]
. You should return an Term
for the derivative of your function.
For example, sin(t)
's derivative (by t
) is given by the following:
Symbolics.derivative(::typeof(sin), args::NTuple{1,Any}, ::Val{1}) = cos(args[1])