Symbolics.jl Jacobian

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