Unfortunately not all concrete types <:Real
are isbits
so I can’t reinterpret… and usually typejoin
doesn’t give concrete types.
I think promote_type
is what I was looking for, thanks @phg!
Here is my exploration if anyone is curious, or knows if I made an error somewhere. This minimal example uses the initial conditions, but I think the problem is similar with a cache variable.
using OrdinaryDiffEq
using Revise
using ForwardDiff
function f(du,u,p,t)
du .= -p[2]*p[1]*u
end
u_0 = [10.0]
params = (1.0,2.0)
prob = ODEProblem(f,u_0,(0.0,10.0),params)
solve(prob,Tsit5()) #make sure it works with no fancy stuff
using MonteCarloMeasurements
params = (1.0,Particles(10,Normal(1.0,2.0)))
prob = ODEProblem(f,u_0,(0.0,10.0),params)
#solve(prob,Tsit5()) #this does not work
u_0 = typeof(params[2])[10.0]
prob = ODEProblem(f,u_0,(0.0,10.0),params)
# solve(prob,Tsit5()) #this does work!
#how to do this for (most) general types T<:Real?
element_types = typeof.(params)
u_0_2 = promote_type(element_types...)[10.0]
prob2 = ODEProblem(f,u_0_2,(0.0,10.0),params)
solve(prob2,Tsit5()) #this works, but maybe it's slower?
using BenchmarkTools
@btime solve(prob,Tsit5())
@btime solve(prob2,Tsit5())
#seems to work?
# 252.864 ÎĽs (6876 allocations: 841.17 KiB)
# 253.666 ÎĽs (6876 allocations: 841.17 KiB)
I wanted this to cover not just like, Particles, but also ForwardDiff with respect to particles, so Dual{Particles}
and whatnot.