SymbolicUtils.jl
SymbolicUtils.jl copied to clipboard
`@register` does not work for arrays variables or arrays of variables
I cannot get @register to work with arrays of variables.
julia> foo(x) = 2x
foo (generic function with 1 method)
julia> @register foo(x)
julia> methods(foo)
# 3 methods for generic function "foo":
[1] foo(x::SymbolicUtils.Symbolic) in Main at /home/fredrikb/.julia/packages/Symbolics/LTmGT/src/register.jl:52
[2] foo(x::Num) in Main at /home/fredrikb/.julia/packages/Symbolics/LTmGT/src/register.jl:52
[3] foo(x) in Main at REPL[19]:1
julia> @register foo(x::Vector{Num})
julia> methods(foo)
# 3 methods for generic function "foo":
[1] foo(x::SymbolicUtils.Symbolic) in Main at /home/fredrikb/.julia/packages/Symbolics/LTmGT/src/register.jl:52
[2] foo
(x::Num) in Main at /home/fredrikb/.julia/packages/Symbolics/LTmGT/src/register.jl:52
[3] foo(x) in Main at REPL[19]:1
I have found one workaround, which is to define a wrapper function that accepts a symbolic dummy variable, like so
julia> bar(x, dummy) = foo(x)
bar (generic function with 1 method)
julia> @register bar(x::Vector{Num}, dummy)
julia> methods(bar)
# 3 methods for generic function "bar":
[1] bar(x::Vector{Num}, dummy::SymbolicUtils.Symbolic) in Main at /home/fredrikb/.julia/packages/Symbolics/LTmGT/src/register.jl:52
[2] bar(x::Vector{Num}, dummy::Num) in Main at /home/fredrikb/.julia/packages/Symbolics/LTmGT/src/register.jl:52
[3] bar(x, dummy) in Main at REPL[25]:1
but this is of course not optimal :)
Changing Vector{Num} to
julia> @variables x[1:2]
1-element Vector{Symbolics.Arr{Num, 1}}:
x[1:2]
doesn't change anything
ref https://github.com/JuliaSymbolics/Symbolics.jl/issues/292
@YingboMa would this issue be a suitable first step towards better array-variable register support? An example usecase could be a dynamics function on the form
function f(u, p, t)
# heavy computation
return du
end
where du is an array. To register this, I imagine that you'd like to say something about the type and size of the output, e.g.,
@register f(u::Vector, p, t::Real)::Vector
but with additional size information.
The intended effect of calling f on arrays with symbols or symbolic arrays would be to get a "symbolic function call" like
FunctionCall{typeof(f)}((u, p, t), arg_types, return_type)
that can later be extended with derivative/sparsity information etc.
FYI, there's https://github.com/JuliaSymbolics/Symbolics.jl/pull/457. But it seems to be slightly buggy.
julia> @register_symbolic oof(x::AbstractVector)
julia> @variables x[1:100]
1-element Vector{Symbolics.Arr{Num, 1}}:
x[1:100]
julia> oof(x)
ERROR: MethodError: no method matching oof(::Symbolics.Arr{Num, 1})
Closest candidates are:
oof(::SymbolicUtils.Symbolic{<:AbstractVector}) at ~/src/julia/Symbolics/src/register.jl:51
Stacktrace:
[1] top-level scope
@ REPL[313]:1
julia> oof(Symbolics.unwrap(x))
oof(x)
@shashi could you take a look?
https://github.com/JuliaSymbolics/Symbolics.jl/pull/557 fixes it.