I have searched far and wide and have no luck setting up a script to do a Jacobian calculation using Symbolics.jacobian.
Can someone shoot me example syntax for a vector of symbolics.
I get errors that look like this:
MethodError: no method matching similar(::Type{Matrix{Symbolics.Num}}, ::Tuple{Base.OneTo{Int64}, UnitRange{Int64}})
Closest candidates are:
similar(!Matched::AbstractArray{T, N} where N, ::Tuple) where T at abstractarray.jl:740
similar(::Type{A}, !Matched::Type{T}, !Matched::StaticArrays.Size{S}) where {A<:Array, T, S} at C:\Users\bakerar\.julia\packages\StaticArrays\0yhGP\src\abstractarray.jl:163
similar(::Type{T}, !Matched::Union{Integer, AbstractUnitRange}...) where T<:AbstractArray at abstractarray.jl:783
...
Code looks something like this:
using Symbolics
@variables v[1:4]
function conditionInputs(v)
[v[1]
v[2]
v[3]
cosd(v[4])
sind(v[4])
v[1]*v[2]
v[1]*v[3]
]
end
x=conditionInputs(v)
df=Symbolics.jacobian(x,v)
Sorry if this is a dumb question.
Best Regards,
Allan Baker
1 Like
The problem is that conditionInputs
returns a Matrix{Num}
instead of a Vector{Num}
. Try adding commas:
function conditionInputs(v)
[v[1],
v[2],
v[3],
cosd(v[4]),
sind(v[4]),
v[1]*v[2],
v[1]*v[3],
]
end
2 Likes
My bad, I didn’t give you the stack trace. The conditionInputs is going is a vector, the v[1:14] looks like it is an array, but the error seems to come from the similar command inside the jacobian call.
julia> df=Symbolics.jacobian(x,v)
ERROR: MethodError: no method matching similar(::Type{Matrix{Num}}, ::Tuple{Base.OneTo{Int64}, UnitRange{Int64}})
Closest candidates are:
similar(::AbstractArray{T, N} where N, ::Tuple) where T at abstractarray.jl:740
similar(::Type{A}, ::Type{T}, ::StaticArrays.Size{S}) where {A<:Array, T, S} at C:\Users\bakerar\.julia\packages\StaticArrays\0yhGP\src\abstractarray.jl:163
similar(::Type{T}, ::Union{Integer, AbstractUnitRange}...) where T<:AbstractArray at abstractarray.jl:783
...
Stacktrace:
[1] _array_for(#unused#::Type{Num}, itr::Base.Iterators.ProductIterator{Tuple{Vector{Num}, Symbolics.Arr{Num, 1}}}, #unused#::Base.HasShape{2})
@ Base .\array.jl:670
[2] jacobian(ops::Vector{Num}, vars::Symbolics.Arr{Num, 1}; simplify::Bool)
@ Symbolics C:\Users\bakerar\.julia\packages\Symbolics\CRJbI\src\diff.jl:357
[3] jacobian(ops::Vector{Num}, vars::Symbolics.Arr{Num, 1})
@ Symbolics C:\Users\bakerar\.julia\packages\Symbolics\CRJbI\src\diff.jl:357
[4] top-level scope
@ REPL[368]:1
The problem appears to be that I have V[1:4] defined in the @variables. Jacobian wants it to look like:
[v[1] v[2] v[3] v[4]].
Is there a quick way to make that expression, especially if I have a larger array?
julia> df=Symbolics.jacobian(x,[v[1], v[2], v[3], v[4] ])
7×4 Matrix{Num}:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 -0.0174533sind(v[4])
0 0 0 0.0174533cosd(v[4])
v[2] v[1] 0 0
v[3] 0 v[1] 0
Huh, I can’t reproduce that stack trace. I was wrong about conditionInputs
, the result is the same with or without the commas.
I get the same (successful, correct) output for Symbolics.jacobian(x,[v[1], v[2], v[3], v[4] ])
and Symbolics.jacobian(x, v)
What version of Symbolics do you have?
(jl_KGOypW) pkg> st
Status `/tmp/jl_KGOypW/Project.toml`
[0c5d862f] Symbolics v1.3.0
We’re still working on array symbolics. It should be able to compute a block Jacobian in the near-ish future.
2 Likes
Thank you, I got it to work by expanding it manually I think. I want to calculate the sensitivity for some pre-calculations prior to the first layer of a neural network. I’ve backed the sensitivities all the way to the neural network inputs, but now I want to back out to the real top level whose purpose was to expand a smaller set of inputs into easier to digest neural network inputs. So I thought I could use the Jacobian in the symbolics toolbox to be able to calculate the transformation of it, but I really need the inverse of the jacobian, but it isn’t square. I tried to use pinv, etc, but I get errors that may be that the Symbolics toolbox doesn’t quite handle calculating the inverse symbolically. Is this true, or should I be able to calculate the pseudo inverse?
pinv requires SVD IIRC, and so it cannot be done above 5x5
2 Likes