# Handling Dual types in my Turing model in a more elegant way

**URL:** https://discourse.julialang.org/t/handling-dual-types-in-my-turing-model-in-a-more-elegant-way/76365
**Category:** Probabilistic Programming
**Tags:** diffeq, turing
**Created:** [February 13, 2022, 6:46pm UTC](https://discourse.julialang.org/t/handling-dual-types-in-my-turing-model-in-a-more-elegant-way/76365 "2022-02-13T18:46:18Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![jacobusmmsmit](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jacobusmmsmit/32/217669_2.png) [@jacobusmmsmit](https://discourse.julialang.org/u/jacobusmmsmit)
#### Post date: [February 13, 2022, 6:46pm UTC](https://discourse.julialang.org/t/handling-dual-types-in-my-turing-model-in-a-more-elegant-way/76365/1 "2022-02-13T18:46:18Z")

</div>

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.

```julia
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:

```julia
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.

---

<div class="post-metadata">

### Author: ![trahflow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/trahflow/32/30585_2.png) [@trahflow](https://discourse.julialang.org/u/trahflow)
#### Post date: [February 13, 2022, 8:09pm UTC](https://discourse.julialang.org/t/handling-dual-types-in-my-turing-model-in-a-more-elegant-way/76365/2 "2022-02-13T20:09:44Z")

</div>

Hi @jacobusmmsmit

a good way to avoid such conditional statements on types is to use parametric types instead.  
As an example, if you write a function with one arument that is an abstract array of a parametric type like this:

```julia
function model(u::AbstractArray{T}) where T
   @show T
   nothing
end

```

then `T` is the eltype of `u` inside your function:

```julia
julia> model([1., 2., 3.])
T = Float64

julia> model([1, 2, 3])
T = Int64

```

and you could work with `T` inside your function, instead of defining conditions for every possible eltype.

However for your task it might be better to write type-generic code in the first place, if possible.  
For example to create a new array that has the same type (and size…) as another array, you can use `u2 = similar(u)`.

For a more specific answer, could you maybe provide your original approach that leads to `ForwardDiff.Dual`-related type errors?

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [February 14, 2022, 12:22am UTC](https://discourse.julialang.org/t/handling-dual-types-in-my-turing-model-in-a-more-elegant-way/76365/3 "2022-02-14T00:22:36Z")

</div>

Share code. This shouldn’t be required.

---

<div class="post-metadata">

### Author: ![jacobusmmsmit](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jacobusmmsmit/32/217669_2.png) [@jacobusmmsmit](https://discourse.julialang.org/u/jacobusmmsmit)
#### Post date: [February 14, 2022, 2:17pm UTC](https://discourse.julialang.org/t/handling-dual-types-in-my-turing-model-in-a-more-elegant-way/76365/4 "2022-02-14T14:17:56Z")

</div>

I tried to reproduce the error myself but it seems that there must have been a non-type-generic part of my code before which has now been replaced. I’m not able to reproduce the error.

Apologies for not doing this test before posting, it was just something on my long “bugs and gripes” list that I decided needed getting squared away and I thought it highly unlikely that removing an entire block of code and replacing it with `type_tester = u` would work first try.
