Hey,
Basically, I want to extract the right hand side function f from the solution of a differential equation \dot{x} = f(x). For a minimum working example consider the following
julia> using DifferentialEquations
julia> myfunc(dx, x, u, t) = (dx .= -x)
myfunc (generic function with 1 method)
julia> prob = ODEProblem(myfunc, rand(1), (0.0, 1.0))
ODEProblem with uType Vector{Float64} and tType Float64. In-place: true
timespan: (0.0, 1.0)
u0: 1-element Vector{Float64}:
0.848128719065019
julia> sol = solve(prob)
retcode: Success
Interpolation: specialized 4th order "free" interpolation, specialized 2nd order "free" stiffness-aware interpolation
t: 5-element Vector{Float64}:
0.0
0.10002357021250141
0.34209643917644617
0.6554220498434524
1.0
u: 5-element Vector{Vector{Float64}}:
[0.848128719065019]
[0.7674005123680626]
[0.6024086282879929]
[0.4403679037389535]
[0.3120092483176733]
I remember that it was once possible to extract the function f from sol
as
f = sol.prob.f.f
(maybe wrong, not hundred percent sure!). However, for DifferentialEquations@v7.3.0
, the type of sol.prob.f.f
is
julia> typeof(sol.prob.f.f)
FunctionWrappersWrappers.FunctionWrappersWrapper{Tuple{FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{Float64}, Vector{Float64}, SciMLBase.NullParameters, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{Float64}, Vector{Float64}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{Float64}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{Float64}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, SciMLBase.NullParameters, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{Float64}, SciMLBase.NullParameters, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}}, false}
not typeof(myufunc)
as I expected. So, I defined the following function
extract_f(sol) = first(sol.prob.f.f.fw).obj[].f.f
to extract f from sol
.
julia> extract_f(sol) = first(sol.prob.f.f.fw).obj[].f.f
extract_f (generic function with 1 method)
julia> extract_f(sol)
myfunc (generic function with 1 method)
What I want to ask is this: Is there a simpler and maybe tidier way of getting f from sol
?