You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Jacobians across an ODE (or DAE) solve, where the parameters are provided as a struct, work only if the struct is parametric and has a defined length.
Expected behavior
Though it is probably not good for performance, I would expect that a parameter struct without careful typing would at least execute. However, it instead errors.
Minimal Reproducible Example 👇
struct ExampleParams
a
b
end
pp =ExampleParams(1.0, -2.0)
functiondae1!(du, u, p, t)
du .= [-u[1]*p.b , u[1] - u[2], p.a, u[4]*p.a]
end
daef1! =ODEFunction(dae1!, mass_matrix=Diagonal([1, 0, 1, 1]))
exprob =ODEProblem(daef1!, [1.0, 0.0, 0.0, 1.0], (0.0, 1.0), pp)
exsol =solve(exprob, Rodas3())
ext =range(0, 1, length=40)
exy =exp.(ext*3)
plot(exsol)
scatter!(ext, exy)
functionobj_ex1(x,p)
lprob =remake(exprob, p=ExampleParams(x[1], x[2]))
@info"check1" lprob lprob.p
sol =solve(lprob, Rodas3())
[sum(abs2.(sol(ext, idxs=2) .- exy))]
end
ForwardDiff.jacobian(x->obj_ex1(x,nothing), [1.0, -2.0])
This produces a MethodError because it's trying to put a Dual in a Vector{Float64} somewhere in the initialization routine.
struct ExampleParamsType{T1, T2}
a::T1
b::T2end
Base.length(pp::ExampleParamsType) =2# Throws a MethodError if this is not definedfunctionobj_ex2(x,p)
lprob =remake(exprob, p=ExampleParamsType(x[1], x[2]))
@info"check1" lprob lprob.p
sol =solve(lprob, Rodas3())
[sum(abs2.(sol(ext, idxs=2) .- exy))]
end
ForwardDiff.jacobian(x->obj_ex1(x,nothing), [1.0, -2.0])
This way, however, it works. Very curiously, it does not seem to care about the return value of Base.length(::ExampleParamsType), so long as it is an Int: if I replace it with
Base.length(pp::ExampleParamsType) =100
then things return just fine, whereas I hit an InexactError if I replace 100 with, say, a NaN.
Error & Stacktrace ⚠️
For the case where the struct is not parametric, here is the error:
This is a limitation of ForwardDiff so I'm not sure it's going away. We could set it up with the SciMLStructures.jl interface to slightly generalize it in some cases though.
Describe the bug 🐞
Jacobians across an ODE (or DAE) solve, where the parameters are provided as a struct, work only if the struct is parametric and has a defined
length
.Expected behavior
Though it is probably not good for performance, I would expect that a parameter struct without careful typing would at least execute. However, it instead errors.
Minimal Reproducible Example 👇
This produces a MethodError because it's trying to put a
Dual
in aVector{Float64}
somewhere in the initialization routine.This way, however, it works. Very curiously, it does not seem to care about the return value of
Base.length(::ExampleParamsType)
, so long as it is an Int: if I replace it withthen things return just fine, whereas I hit an InexactError if I replace
100
with, say, aNaN
.Error & Stacktrace⚠️
For the case where the struct is not parametric, here is the error:
Environment (please complete the following information):
using Pkg; Pkg.status()
using Pkg; Pkg.status(; mode = PKGMODE_MANIFEST)
versioninfo()
The text was updated successfully, but these errors were encountered: