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 of the differentials, the expand_derivatives function eliminates all of the differentials down to basic one-variable expressions.

Symbolics.DifferentialType
struct 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))
source
Symbolics.expand_derivativesFunction
expand_derivatives(O)
expand_derivatives(O, simplify; occurances)

TODO

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
source

High Level Differentiation Functions

The following functions are not exported and thus must be accessed in a namespaced way, i.e. Symbolics.jacobian.

Symbolics.derivativeFunction
derivative(O, v; simplify)

A helper function for computing the derivative of an expression with respect to var.

source
Symbolics.jacobianFunction
jacobian(ops, vars; simplify)

A helper function for computing the Jacobian of an array of expressions with respect to an array of variable expressions.

source
Symbolics.sparsejacobianFunction
sparsejacobian(ops, vars; simplify)

A helper function for computing the sparse Jacobian of an array of expressions with respect to an array of variable expressions.

source
Symbolics.gradientFunction
gradient(O, vars; simplify)

A helper function for computing the gradient of an expression with respect to an array of variable expressions.

source
Symbolics.hessianFunction
hessian(O, vars; simplify)

A helper function for computing the Hessian of an expression with respect to an array of variable expressions.

source
Symbolics.sparsehessianFunction
sparsehessian(O, vars; simplify)

A helper function for computing the sparse Hessian of an expression with respect to an array of variable expressions.

source

Adding Analytical Derivatives

There is a large amount of derivatives pre-defined by DiffRules.jl.

f(x,y,z) = x^2 + sin(x+y) - z

automatically has the derivatives defined via the tracing mechanism. It will do this by directly building the operation the internals of your function and differentiating that.

However, in many cases 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 in order to better scale to larger systems. You can define derivatives for your own 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 ith 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])