Производные и дифференциалы
Differential(op)
является частной производной по отношению к op
, которая затем может быть применена к некоторым другим операциям. Например, D=Differential(t)
обычно называют d/dt
и затем применяют к другим операциям с помощью вызова функции, так что D(x+y)
равнозначно d(x+y)/dt
.
По умолчанию производные остаются неразвернутыми, чтобы зафиксировать символическое представление дифференциального уравнения. Если пользователь хочет расширить все дифференциалы, функция expand_derivatives
сводит все дифференциалы к основным однопеременным выражениям.
#
Symbolics.Differential
— Type
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_derivatives
— Function
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.derivative
— Function
derivative(O, v; simplify)
Вспомогательная функция для вычисления производной выражения относительно var
.
#
Symbolics.jacobian
— Function
jacobian(ops, vars; simplify, scalarize)
Вспомогательная функция для вычисления якобиана массива выражений относительно массива выражений переменных.
#
Symbolics.sparsejacobian
— Function
sparsejacobian(ops, vars; simplify)
Вспомогательная функция для вычисления разреженного якобиана массива выражений относительно массива выражений переменных.
#
Symbolics.sparsejacobian_vals
— Function
sparsejacobian_vals(ops, vars, I, J; simplify)
Вспомогательная функция для вычисления значений разреженного якобиана массива выражений относительно массива выражений переменных с учетом структуры разреженности.
#
Symbolics.gradient
— Function
gradient(O, vars; simplify)
Вспомогательная функция для вычисления градиента выражения относительно массива выражений переменных.
#
Symbolics.hessian
— Function
hessian(O, vars; simplify)
Вспомогательная функция для вычисления гессиана выражения относительно массива выражений переменных.
#
Symbolics.sparsehessian
— Function
sparsehessian(op, vars; simplify, full)
Вспомогательная функция для вычисления разреженного гессиана выражения относительно массива выражений переменных.
#
Symbolics.sparsehessian_vals
— Function
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])