# Problem using ForwardDiff with backslash "\\" matrix solver

**URL:** https://discourse.julialang.org/t/problem-using-forwarddiff-with-backslash-matrix-solver/74498
**Category:** Numerics
**Tags:** forwarddiff
**Created:** [January 12, 2022, 4:23pm UTC](https://discourse.julialang.org/t/problem-using-forwarddiff-with-backslash-matrix-solver/74498 "2022-01-12T16:23:57Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![gaodifan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gaodifan/32/32715_2.png) [@gaodifan](https://discourse.julialang.org/u/gaodifan)
#### Post date: [January 12, 2022, 4:23pm UTC](https://discourse.julialang.org/t/problem-using-forwarddiff-with-backslash-matrix-solver/74498/1 "2022-01-12T16:23:57Z")

</div>

Hello, I’m trying to use the ForwardDiff.jl package for automatic differentiation of my function, which includes using the backslash `\` operator for a matrix solve. ForwardDiff [requires Arrays to be of the more general type Real](https://juliadiff.org/ForwardDiff.jl/stable/user/limitations/) (instead of Float64). However, the `\` solver always outputs an Array{Float64}.

Example code:

```julia
# input v
v = [1. 2. 3.]

# true X (would be the target in an optimization)
Xtrue = [1.1, 1.9, 0.8]

function f(v)
    # in A*X = B, solve for X

    # A is #3x3 square matrix, with values depending on input v
    A = Matrix{Real}([1. 2. v[1]; 6. v[2] 4.; 8. 7. v[3]]) 
    
    B = Vector{Real}([5., 13., 23.]) #3x1 matrix

    # solve for X using backslash operator
    X = A \ B #3x1 vector

    # difference between calculated X and true X is the cost
    cost = sum((X - Xtrue).^2) 

    return cost
end

using ForwardDiff
ForwardDiff.gradient(f, v)

```

ForwardDiff.gradient gives this error:  
`MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(f), Float64}, Float64, 3})`

I think it’s because A \ B outputs an Array{Float64} to X.

Is there a way to make this work?

---

<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: [January 12, 2022, 7:03pm UTC](https://discourse.julialang.org/t/problem-using-forwarddiff-with-backslash-matrix-solver/74498/2 "2022-01-12T19:03:37Z")

</div>

You’re way overthinking it. Julia will promote the types when you put them in an array. The simplest code works:

```julia
using ForwardDiff
# input v
v = [1. 2. 3.]

# true X (would be the target in an optimization)
Xtrue = [1.1, 1.9, 0.8]

function f(v)
    # in A*X = B, solve for X

    # A is #3x3 square matrix, with values depending on input v
    A = [1. 2. v[1]; 6. v[2] 4.; 8. 7. v[3]]

    B = [5., 13., 23.] #3x1 matrix

    # solve for X using backslash operator
    X = A \ B #3x1 vector

    # difference between calculated X and true X is the cost
    cost = sum((X - Xtrue).^2)

    return cost
end

using ForwardDiff
ForwardDiff.gradient(f, v)

```

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [January 12, 2022, 9:06pm UTC](https://discourse.julialang.org/t/problem-using-forwarddiff-with-backslash-matrix-solver/74498/3 "2022-01-12T21:06:12Z")

</div>

> [@gaodifan](#):
>
> ForwardDiff [requires Arrays to be of the more general type Real](https://juliadiff.org/ForwardDiff.jl/stable/user/limitations/) (instead of Float64).

No, this is not quite right. ForwardDiff requires you to _support_ arbitrary `Real` types as input. This means that, like any type-generic code, you want to work with _whatever number type is passed_ in the arguments and construct your arrays accordingly. It does _not_ mean to use `Matrix{Real}`.

(You still want to end up working with arrays of concrete types, which is [crucial for performance](https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-abstract-container) in Julia, but you have to support ForwardDiff passing in a weird “[dual number](https://en.wikipedia.org/wiki/Dual_number)” type as the input vector.)

For example, this works:

```julia
function f(v, xtrue)
    A = [1. 2. v[1]; 6. v[2] 4.; 8. 7. v[3]] # promotes based on type of v
    b = [5., 13., 23.]
    x = A \ b
    return sum(abs2, x - xtrue) # better yet, use norm(x - xtrue) from LinearAlgebra
end

v = [1. 2. 3.]
xtrue = [1.1, 1.9, 0.8]

import ForwardDiff
ForwardDiff.gradient(v -> f(v, xtrue), v)

```

(Note also that I edited `f` to no longer use a global variable `Xtrue`, which is good to avoid on general software-engineering principles but also [particularly in Julia](https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-global-variables).)

---

<div class="post-metadata">

### Author: ![gaodifan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gaodifan/32/32715_2.png) [@gaodifan](https://discourse.julialang.org/u/gaodifan)
#### Post date: [January 13, 2022, 2:08pm UTC](https://discourse.julialang.org/t/problem-using-forwarddiff-with-backslash-matrix-solver/74498/5 "2022-01-13T14:08:16Z")

</div>

Thanks for your help. Unfortunately, it turns out that I asked a bad question any that my example didn’t get to the crux of my problem -\_-

In reality, I need to build matrices A and B line-by-line in a loop, and thus need to pre-allocate them, which I believe forces me to define their type.

```julia
function f(v, xtrue)
    A = Matrix{Float64}(undef, 3, 3)

    # A values assigned row-by-row
    for i in 1:size(A, 1)
        if i % 2 == 0 # is even
            A[i, :] = [v[i] 1. 2.]
        else
            A[i, :] = [5. 6. v[i]]
        end
    end

    b = [5., 13., 23.]
    x = A \ b
    return sum(abs2, x - xtrue)
end

v = [1. 2. 3.]
xtrue = [1.1, 1.9, 0.8]

import ForwardDiff
ForwardDiff.gradient(v -> f(v, xtrue), v)

```

I just wrote a silly example of loop assignment here – in reality the conditional is on another variable, not whether i is odd and even.

I then get error from FowardDiff, `MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{var"#13#14", Float64}, Float64, 3})` .

It’s as if pre-allocating A forces x into Float64 and prevents its promotion? Is there an easy way around this?

---

<div class="post-metadata">

### Author: ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)
#### Post date: [January 13, 2022, 3:02pm UTC](https://discourse.julialang.org/t/problem-using-forwarddiff-with-backslash-matrix-solver/74498/6 "2022-01-13T15:02:09Z")

</div>

You need to allocate `A` in such a way that it can hold elements of `typeof(v)`, for example something like this

```julia
function f(v::AbstractVector{T}, xtrue) where T
    A = Matrix{T}(undef, 3, 3)
    # ...
end

```
