Документация Engee

Производные и дифференциалы

Differential(op) является частной производной по отношению к op, которая затем может быть применена к некоторым другим операциям. Например, D=Differential(t) обычно называют d/dt и затем применяют к другим операциям с помощью вызова функции, так что D(x+y) равнозначно d(x+y)/dt.

По умолчанию производные остаются неразвернутыми, чтобы зафиксировать символическое представление дифференциального уравнения. Если пользователь хочет расширить все дифференциалы, функция expand_derivatives сводит все дифференциалы к основным однопеременным выражениям.

# Symbolics.DifferentialType

struct Differential <: Symbolics.Operator

Представляет дифференциальный оператор.

Поля

  • x: переменная или выражение, относительно которого нужно провести дифференцирование.

Примеры

julia> using Symbolics

julia> @variables x y;

julia> D = Differential(x)
(D'~x)

julia> D(y) # Дифференцировать y по x
(D'~x)(y)

julia> Dx = Differential(x) * Differential(y) # оператор d^2/dxy
(D'~x(t)) ∘ (D'~y(t))

julia> D3 = Differential(x)^3 # дифференциальный оператор 3-го порядка
(D'~x(t)) ∘ (D'~x(t)) ∘ (D'~x(t))

# Symbolics.expand_derivativesFunction

expand_derivatives(O)
expand_derivatives(O, simplify; occurrences)

TODO

Примеры

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) # Дифференцировать по 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

Функции дифференциации высокого уровня

Следующие функции не экспортируются, поэтому доступ к ним должен осуществляться в пространстве имен, т. e. Symbolics.jacobian.

# Symbolics.derivativeFunction

derivative(O, v; simplify)

Вспомогательная функция для вычисления производной выражения относительно var.

# Symbolics.jacobianFunction

jacobian(ops, vars; simplify, scalarize)

Вспомогательная функция для вычисления якобиана массива выражений относительно массива выражений переменных.

# Symbolics.sparsejacobianFunction

sparsejacobian(ops, vars; simplify)

Вспомогательная функция для вычисления разреженного якобиана массива выражений относительно массива выражений переменных.

# Symbolics.sparsejacobian_valsFunction

sparsejacobian_vals(ops, vars, I, J; simplify)

Вспомогательная функция для вычисления значений разреженного якобиана массива выражений относительно массива выражений переменных с учетом структуры разреженности.

# Symbolics.gradientFunction

gradient(O, vars; simplify)

Вспомогательная функция для вычисления градиента выражения относительно массива выражений переменных.

# Symbolics.hessianFunction

hessian(O, vars; simplify)

Вспомогательная функция для вычисления гессиана выражения относительно массива выражений переменных.

# Symbolics.sparsehessianFunction

sparsehessian(op, vars; simplify, full)

Вспомогательная функция для вычисления разреженного гессиана выражения относительно массива выражений переменных.

# Symbolics.sparsehessian_valsFunction

sparsehessian_vals(op, vars, I, J; simplify)

Вспомогательная функция для вычисления значений разреженного гессиана выражения относительно массива выражений переменных с учетом структуры разреженности.

Добавление аналитических производных

Существует множество производных, предварительно определенных в DiffRules.jl. Например,

using Symbolics
@variables x y z
f(x,y,z) = x^2 + sin(x+y) - z
f (generic function with 1 method)

f автоматически имеет производные, определенные через механизм трассировки. Для этого нужно напрямую построить внутренние компоненты функции и дифференцировать их.

Однако часто может потребоваться определить собственные производные, чтобы автоматические вычисления якобиана и проч. могли использовать эту информацию. В этом случае можно будет вычислять более краткие версии производных для масштабирования в большие системы. Вы можете определить производные для своей функции через диспетчеризацию:

# `N` аргументов принимаются соответствующим методом `my_function`
Symbolics.derivative(::typeof(my_function), args::NTuple{N,Any}, ::Val{i})

где i означает, что это производная по i-му аргументу. args — это массив аргументов, поэтому, например, если ваша функция имеет вид f(x,t), то args = [x,t]. Вы должны вернуть Term для производной функции.

Например, производная sin(t) (по t) дается следующим образом.

Symbolics.derivative(::typeof(sin), args::NTuple{1,Any}, ::Val{1}) = cos(args[1])