Регистрация и трассировка функций
Прямая трассировка
Поскольку в выражениях Symbolics соблюдается семантика Julia, одним из способов создания символьных выражений является простой ввод переменных Symbolics в качестве входных данных в существующий код Julia. Например, ниже используется стандартная функция Julia для уравнений Лоренца, чтобы сгенерировать символьное выражение для уравнений Лоренца.
using Symbolics
function lorenz(du,u,p,t)
du[1] = 10.0(u[2]-u[1])
du[2] = u[1]*(28.0-u[3]) - u[2]
du[3] = u[1]*u[2] - (8/3)*u[3]
end
@variables t p[1:3] u(t)[1:3]
du = Array{Any}(undef, 3)
lorenz(du,u,p,t)
du
3-element Vector{Any}:
10.0(-(u(t))[1] + (u(t))[2])
-(u(t))[2] + (u(t))[1]*(28.0 - (u(t))[3])
-2.6666666666666665(u(t))[3] + (u(t))[1]*(u(t))[2]
Или аналогично:
@variables t x(t) y(t) z(t) dx(t) dy(t) dz(t) σ ρ β
du = [dx,dy,dz]
u = [x,y,z]
p = [σ,ρ,β]
lorenz(du,u,p,t)
du
3-element Vector{Num}:
10.0(-x(t) + y(t))
-y(t) + x(t)*(28.0 - z(t))
-2.6666666666666665z(t) + x(t)*y(t)
Регистрация функций
Граф Symbolics допускает только зарегистрированные функции Julia в пределах своего типа. Все остальные функции автоматически отслеживаются до зарегистрированных функций. По умолчанию Symbolics.jl предварительно регистрирует общие функции, используемые в SymbolicUtils.jl, и предварительно определяет их производные. Однако пользователь может использовать макрос @register_symbolic
, чтобы добавить свою функцию к разрешенным функциям вычислительного графа.
#
Symbolics.@register_symbolic
— Macro
@register_symbolic(expr, define_promotion = true, Ts = [Real])
Перегружает соответствующие методы, чтобы Symbolics мог прекратить трассировку в зарегистрированную функцию. Если define_promotion
имеет значение true, метод продвижения в виде
SymbolicUtils.promote_symtype(::typeof(f_registered), args...) = Real # или аннотированный возвращаемый тип
определяется для функции регистрации. Обратите внимание, что при определении нескольких перегрузок регистрации для одной функции для всех остальных функций регистрации, кроме первой, необходимо задать define_promotion
равным false
, чтобы избежать перезаписи метода.
Примеры
@register_symbolic foo(x, y)
@register_symbolic foo(x, y::Bool) false # не перегружать повторяющееся правило продвижения
@register_symbolic goo(x, y::Int) # `y` не перегружается, чтобы принимать символьные объекты
@register_symbolic hoo(x, y)::Int # `hoo` возвращает `Int`