I want to run sensitivity analysis w.r.t. the initial conditions:
using DifferentialEquations,
Optimization, OptimizationPolyalgorithms, SciMLSensitivity,
Zygote
function harm_osc_matrix(t::Real, p::Vector)
ω, ε = p # ε is not used but anyway
return [[0.0 1.0]
[-ω 0.0]]
end
function harm_osc!(du, u, p, t)
du .= harm_osc_matrix(t, p) * u
end
tspan = (0.0, pi)
tsteps = tspan[begin]:pi/5:tspan[end]
u0 = rand(2)
p = [1.0, 1.0]
h = pi / 5
prob_harm_osc = ODEProblem(harm_osc!, u0, tspan)
target = solve(prob_harm_osc, Euler(), p=p, dt=h).u[end]
function get_iv(target, tspan)
global p, h
function loss(x)
_prob = remake(prob_harm_osc, u0=x[1:2], tspan=tspan, p=p)
sol = solve(_prob, Euler(), dt=h, p=p)
loss = sum(abs2, sol.u[end] - target)
return loss, sol
end
adtype = Optimization.AutoZygote()
optf = Optimization.OptimizationFunction((x, p) -> loss(x), adtype)
optprob = Optimization.OptimizationProblem(optf, p)
result_ode = Optimization.solve(optprob, PolyOpt(), maxiters=100)
return result_ode.u
end
get_iv(target, tspan)
This code raises the error:
ERROR: MethodError: objects of type Float64 are not callable
Maybe you forgot to use an operator such as *, ^, %, / etc. ?
Stacktrace:
[1] (::var"#10#12")(x::Vector{Float64}, p::SciMLBase.NullParameters)
@ Main ~/Code/test/HarmonicOscillatorSensitivity.jl:33
[2] OptimizationFunction
@ ~/.julia/packages/SciMLBase/8XHkk/src/scimlfunctions.jl:3933 [inlined]
[3] #2
@ ~/.julia/packages/OptimizationPolyalgorithms/MOJAF/src/OptimizationPolyalgorithms.jl:14 [inlined]
[4] __solve(::OptimizationProblem{true, OptimizationFunction{true, AutoZygote, var"#10#12", Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, SciMLBase.NullParameters, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, ::PolyOpt; maxiters::Int64, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ OptimizationPolyalgorithms ~/.julia/packages/OptimizationPolyalgorithms/MOJAF/src/OptimizationPolyalgorithms.jl:15
[5] __solve
@ ~/.julia/packages/OptimizationPolyalgorithms/MOJAF/src/OptimizationPolyalgorithms.jl:9 [inlined]
[6] #solve#614
@ ~/.julia/packages/SciMLBase/8XHkk/src/solve.jl:97 [inlined]
[7] get_iv(target::Vector{Float64}, tspan::Tuple{Float64, Irrational{:π}})
@ Main ~/Code/test/HarmonicOscillatorSensitivity.jl:35
[8] top-level scope
@ ~/Code/test/HarmonicOscillatorSensitivity.jl:38
However, if I “unwrap” get_iv
function, putting its body to global scope, it works fine.
- How can I make
get_iv
work? - Is there a shorter way to analyze the system sensitivity w.r.t. the IVs?