# Pinv and autodiff error

**URL:** <https://discourse.julialang.org/t/pinv-and-autodiff-error/118636>\
**Category:** New to Julia\
**Created:** [August 26, 2024, 5:26pm UTC](https://discourse.julialang.org/t/pinv-and-autodiff-error/118636 "2024-08-26T17:26:54Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![JADekker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jadekker/32/210281_2.png) [@JADekker](https://discourse.julialang.org/u/JADekker)\
**Post date:** [August 26, 2024, 5:26pm UTC](https://discourse.julialang.org/t/pinv-and-autodiff-error/118636/1 "2024-08-26T17:26:54Z")

</div>

Hi, I’m getting the following error in the following MWE:

(I’m aware that I could implement Moore-Penrose by hand to circumvent the issue; I’d rather not do this, as I’m trying to understand why exactly I get this error here).

```julia
MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(f), Float64}, Float64, 1})

```

```julia
using Optim, LinearAlgebra

function f(x::AbstractVector{T}) where T <: Real
    n = length(x)
    KXX = Matrix{Real}(undef, n, n)
    for i = 1:n
        for j = i:n
            KXX[i, j] = x[i] * x[j]
            KXX[j, i] = KXX[i, j]
        end
    end
    return sum(pinv(KXX)) + sum(x .^2)
end

x_opt_NM = optimize(f, [0.])
display(x_opt_NM)

x_opt = optimize(f, [0.], Newton(); autodiff = :forward)
display(x_opt)

```

I’m failing to see where it tries to make something into a Float. (Note that the problem persists for higher dimensional problems, just replace [0.] by `zeros(d)` for some choice `d`)

---

<div class="post-metadata">

**Author:** ![contradict](https://avatars.discourse-cdn.com/v4/letter/c/ac91a4/32.png) [@contradict](https://discourse.julialang.org/u/contradict)\
**Post date:** [August 26, 2024, 5:36pm UTC](https://discourse.julialang.org/t/pinv-and-autodiff-error/118636/2 "2024-08-26T17:36:49Z")

</div>

I’m not sure I see why this doesn’t work either, but I suspect it has something to do with `Real` not being a concrete type and a broadcast inside `pinv` making a concrete array. Using the actual type of the argument does work:

```julia
function f(x::AbstractVector{T}) where T <: Real
    n = length(x)
    KXX = Matrix{T}(undef, n, n) # Use the actual type here
    for i = 1:n
        for j = i:n
            KXX[i, j] = x[i] * x[j]
            KXX[j, i] = KXX[i, j]
        end
    end
    return sum(pinv(KXX)) + sum(x .^2)
end

```

Or, even less restrictive:

```julia
function f2(x)
    n = length(x)
    KXX = similar(x, (n,n))
    for i = 1:n
        for j = i:n
            KXX[i, j] = x[i] * x[j]
            KXX[j, i] = KXX[i, j]
        end
    end
    return sum(pinv(KXX)) + sum(x .^2)
end

```

---

<div class="post-metadata">

**Author:** ![JADekker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jadekker/32/210281_2.png) [@JADekker](https://discourse.julialang.org/u/JADekker)\
**Post date:** [August 26, 2024, 6:27pm UTC](https://discourse.julialang.org/t/pinv-and-autodiff-error/118636/3 "2024-08-26T18:27:12Z")

</div>

Thank you for pointing that out! There’s probably a good reason why this is the case, but it is certainly a bit counterintuitive to me at present! I’ll make the necessary changes to my code then!
