# Pinv and autodiff error

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).

``````MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(f), Float64}, Float64, 1})
``````
``````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`)

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:

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

``````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
``````
1 Like

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!