# Turing type error: expected Float64, got ForwardDiff.Dual

**URL:** https://discourse.julialang.org/t/turing-type-error-expected-float64-got-forwarddiff-dual/47670
**Category:** Probabilistic Programming
**Tags:** question, type, turing
**Created:** [October 2, 2020, 11:41pm UTC](https://discourse.julialang.org/t/turing-type-error-expected-float64-got-forwarddiff-dual/47670 "2020-10-02T23:41:52Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![mangulo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mangulo/32/14076_2.png) [@mangulo](https://discourse.julialang.org/u/mangulo)
#### Post date: [October 2, 2020, 11:41pm UTC](https://discourse.julialang.org/t/turing-type-error-expected-float64-got-forwarddiff-dual/47670/1 "2020-10-02T23:41:52Z")

</div>

Hi All,

I’m trying to do a multivariable linear regression y = \Phi(A, x) using Turing, where y \in \mathbb R^N, x \in \mathbb R^N, and the function \Phi is linear in the unknown parameters A \in \mathbb R^{N \times N}. For my particular problem, the function \Phi = (\phi\_1, \cdots, \phi\_n)^T needs to be constructed row-by-row.

It’s straightforward to build a Turing model to infer the unknown matrix A from a dataset containing the inputs x and outputs y. However, when I run the sampler, I find the following error:

> ERROR: TypeError: in typeassert, expected Float64, got ForwardDiff.Dual{Nothing,Float64,9}

Below is a minimal example to reproduce this error. I also found that the error does not occur if all the rows of \Phi are constructed in a single step.

I checked [this related previous post](https://github.com/TuringLang/Turing.jl/issues/716), but the solutions there do not seem to solve the problem.

**Does anybody have a suggestion about how to fix this issue?**

Thanks!

```julia
using Distributions
using LinearAlgebra
using StatsBase

using Turing

function Φ(A, x)
    N = size(x,1)
    temp = zeros(N)

    for i = 1:N
        temp[i] = dot(A[i, :], x)
    end

    return temp
end

N = 5
number_of_samples = 100

# Generate data
A = rand(Normal(), N,N) + I(N)
xdata = rand(LogNormal(0,1), (N, number_of_samples) )
ydata = hcat([Φ(A, x) for x in eachcol(xdata)]...)

# Build model
@model function regression(x, y)
    N = size(x, 1)
    number_of_samples = size(x, 2)

    # Priors
    σ ~ truncated(Normal(0, 100), 0, Inf)
    A ~ filldist(Normal(0,1), N, N)

    # Equations
    for k = 1: number_of_samples
        # mu = A*x[:, k]
         mu = Φ(A, x[:, k])
        y[:, k] ~ MvNormal(mu, sqrt(σ))
    end
end

# Inference
model = regression(xdata, ydata)
chain = sample(model, NUTS(0.65), 300)

```

---

<div class="post-metadata">

### Author: ![mchitre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mchitre/32/13756_2.png) [@mchitre](https://discourse.julialang.org/u/mchitre)
#### Post date: [October 3, 2020, 4:41am UTC](https://discourse.julialang.org/t/turing-type-error-expected-float64-got-forwarddiff-dual/47670/2 "2020-10-03T04:41:49Z")

</div>

This line:

> [@mangulo](#):
>
> `temp = zeros(N)`

will create an array that is of type `Float64`, and I suspect that `x` contains dual number because `NUTS` needs derivatives with respect to it. Doing `temp = zeros(eltype(x), N)` might fix the problem.

An even easier option might be to replace the loop with a comprehension, which will take care of types for you:

```julia
temp = [dot(A[i, :], x) for i in 1:N]

```

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [October 3, 2020, 5:05am UTC](https://discourse.julialang.org/t/turing-type-error-expected-float64-got-forwarddiff-dual/47670/3 "2020-10-03T05:05:34Z")

</div>

Why not just write

```julia
temp = A * x

```

?  
That’s both simpler, clearer, and potentially _much_ faster.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [October 3, 2020, 5:21am UTC](https://discourse.julialang.org/t/turing-type-error-expected-float64-got-forwarddiff-dual/47670/4 "2020-10-03T05:21:39Z")

</div>

> [@mangulo](#):
>
> `ydata = hcat([Φ(A, x) for x in eachcol(xdata)]...)`

This, too, will be slow. Why not just

```julia
ydata = Φ(A, xdata) 

```

?

---

<div class="post-metadata">

### Author: ![mangulo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mangulo/32/14076_2.png) [@mangulo](https://discourse.julialang.org/u/mangulo)
#### Post date: [October 3, 2020, 4:52pm UTC](https://discourse.julialang.org/t/turing-type-error-expected-float64-got-forwarddiff-dual/47670/5 "2020-10-03T16:52:14Z")

</div>

Unfortunately, your first suggestion `temp = zeros(eltype(x), N)` does not work (do you understand why?)  
The second suggestion `temp = [dot(A[i, :], x) for i in 1:N]` solves the problem.  
Thanks!

---

<div class="post-metadata">

### Author: ![mangulo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mangulo/32/14076_2.png) [@mangulo](https://discourse.julialang.org/u/mangulo)
#### Post date: [October 3, 2020, 4:53pm UTC](https://discourse.julialang.org/t/turing-type-error-expected-float64-got-forwarddiff-dual/47670/6 "2020-10-03T16:53:58Z")

</div>

For my particular problem, I cannot write the model as a multiplication of a matrix and a vector.  
Note the code I pasted is only a minimal case that reproduces the error I was finding.  
Thanks for answering.

---

<div class="post-metadata">

### Author: ![mangulo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mangulo/32/14076_2.png) [@mangulo](https://discourse.julialang.org/u/mangulo)
#### Post date: [October 3, 2020, 4:55pm UTC](https://discourse.julialang.org/t/turing-type-error-expected-float64-got-forwarddiff-dual/47670/7 "2020-10-03T16:55:02Z")

</div>

This does not work because the inner product in `Φ` will not correctly broadcast.

---

<div class="post-metadata">

### Author: ![mchitre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mchitre/32/13756_2.png) [@mchitre](https://discourse.julialang.org/u/mchitre)
#### Post date: [October 3, 2020, 5:09pm UTC](https://discourse.julialang.org/t/turing-type-error-expected-float64-got-forwarddiff-dual/47670/8 "2020-10-03T17:09:00Z")

</div>

> [@mangulo](#):
>
> Unfortunately, your first suggestion temp = zeros(eltype(x), N) does not work (do you understand why?)

Yes, I just tried it. It’s because `NUTS` also wants the gradient with respect to A, and so A can contain dual numbers. This fixes it:

```julia
temp = zeros(promote_type(eltype(x), eltype(A)), N)

```

Of course, the list comprehension is an easier option when possible to use.

---

<div class="post-metadata">

### Author: ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)
#### Post date: [October 3, 2020, 5:12pm UTC](https://discourse.julialang.org/t/turing-type-error-expected-float64-got-forwarddiff-dual/47670/9 "2020-10-03T17:12:43Z")

</div>

> [@mchitre](#):
>
> This fixes it:
> 
> ```julia
> temp = zeros(promote_type(eltype(x), eltype(A)), N)
> 
> ```

Or you can use the super secret special function `Base.promote_eltype` 🤫

```julia
julia> Base.promote_eltype(rand(Float64, 3), rand(Int, 3))
Float64

```

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [October 3, 2020, 5:14pm UTC](https://discourse.julialang.org/t/turing-type-error-expected-float64-got-forwarddiff-dual/47670/10 "2020-10-03T17:14:26Z")

</div>

That’s the thing with minimal reproducible examples, they can be difficult to make.

But, I think that in order for something to be a minimal example, it shouldn’t be possible to look at it and then dramatically simplify it further.
