Hello everyone,
I’m doing inference on a system of ODEs solved with Rodas5
. To use Rodas5
while writing inplace to my du
, I check if one of u
or du
is a Dual
so there’s no typeassert
based errors. To use Turing
with the No U-Turns Sampler, I do the same with all of my inference parameters, checking one by one if they are Dual
s, and if they are, making sure that all of my calculations are propagated properly using the types of my inference parameters. This seems to be a robust method as I have not had type errors since implementing the code below, but it also seems potentially inefficient and just plain ugly.
if eltype(u) <: ForwardDiff.Dual
type_tester = u[1, 1]
elseif eltype(du) <: ForwardDiff.Dual
type_tester = du[1, 1]
elseif isnothing(inference_parameters) # If not doing inference
type_tester = 0.0
else
# Scans inference_parameters for Duals,
# returns the first or 0.0 if none are found.
use_default = true
for (type, parameter) in zip(
typeof.(inference_parameters),
inference_parameters)
if type <: ForwardDiff.Dual
type_tester = parameter
use_default = false
break
end
end
if use_default
type_tester = 0.0
end
end
# Used later in the function
current_eltype = eltype(type_tester)
F_total = get_tmp(F_total, type_tester)
What I would like to be able to write is:
values_to_test = (u[1, 1], d[1, 1], inference_parameters...)
if any(typeof.(values_to_test)) <: ForwardDiff.Dual
# Because I want a specific type of Dual I think?
type_tester = the_one_which_was_a_dual
else
type_tester = 0.0
end
But I’m not sure if that’s either the best way of doing this, or even a good way of doing this. Is there something obvious I’m missing?
As a side question, in my Turing
model if one of my inference parameters becomes a Dual
, does that always mean that the others are? That would imply that I don’t need to test all of the inference parameters and just one.