Hey,
I’d like to get derivatives for a linear least squares problem where the parameter appears in the right hand side:
using LinearAlgebra
using ForwardDiff
A = rand(10, 3)
b = rand(10)
qr_fact = qr(A)
function f(p)
res = b * p
v = qr_fact \ res
return v
end
g = ForwardDiff.derivative(f, 0.1)
However, this produces
ERROR: MethodError: no method matching ldiv!(::LinearAlgebra.QRCompactWY{ForwardDiff.Dual{ForwardDiff.Tag{typeof(f), Float64}, Float64, 1}, Matrix{ForwardDiff.Dual{ForwardDiff.Tag{typeof(f), Float64}, Float64, 1}}, Matrix{ForwardDiff.Dual{ForwardDiff.Tag{typeof(f), Float64}, Float64, 1}}}, ::Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(f), Float64}, Float64, 1}})
Closest candidates are:
ldiv!(::Bidiagonal, ::AbstractVecOrMat)
@ LinearAlgebra C:\Users\SomeUser\AppData\Local\Programs\Julia-1.9.2\share\julia\stdlib\v1.9\LinearAlgebra\src\bidiag.jl:729
ldiv!(::Cholesky, ::AbstractVecOrMat)
@ LinearAlgebra C:\Users\SomeUser\AppData\Local\Programs\Julia-1.9.2\share\julia\stdlib\v1.9\LinearAlgebra\src\cholesky.jl:579
ldiv!(::Diagonal, ::AbstractVecOrMat)
@ LinearAlgebra C:\Users\SomeUser\AppData\Local\Programs\Julia-1.9.2\share\julia\stdlib\v1.9\LinearAlgebra\src\diagonal.jl:415
...
Stacktrace:
[1] \(F::LinearAlgebra.QRCompactWY{Float64, Matrix{Float64}, Matrix{Float64}}, B::Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(f), Float64}, Float64, 1}})
@ LinearAlgebra C:\Users\SomeUser\AppData\Local\Programs\Julia-1.9.2\share\julia\stdlib\v1.9\LinearAlgebra\src\LinearAlgebra.jl:536
[2] f(p::ForwardDiff.Dual{ForwardDiff.Tag{typeof(f), Float64}, Float64, 1})
@ Main .\REPL[6]:3
[3] derivative(f::typeof(f), x::Float64)
@ ForwardDiff C:\Users\SomeUser\.julia\packages\ForwardDiff\PcZ48\src\derivative.jl:14
[4] top-level scope
@ REPL[8]:1
Applying the operations individually
function f2(p)
res = b * p
v = qr_fact.R \ (qr_fact.Q' * res)[1:3]
return v
end
g = ForwardDiff.derivative(f2, 0.1)
results in
ERROR: MethodError: no method matching lmul!(::Adjoint{ForwardDiff.Dual{ForwardDiff.Tag{typeof(f2), Float64}, Float64, 1}, LinearAlgebra.QRCompactWYQ{ForwardDiff.Dual{ForwardDiff.Tag{typeof(f2), Float64}, Float64, 1}, Matrix{ForwardDiff.Dual{ForwardDiff.Tag{typeof(f2), Float64}, Float64, 1}}, Matrix{ForwardDiff.Dual{ForwardDiff.Tag{typeof(f2), Float64}, Float64, 1}}}}, ::Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(f2), Float64}, Float64, 1}})
Closest candidates are:
lmul!(::SparseArrays.SPQR.QRSparseQ, ::StridedVecOrMat)
@ SparseArrays C:\Users\SomeUser\AppData\Local\Programs\Julia-1.9.2\share\julia\stdlib\v1.9\SparseArrays\src\solvers\spqr.jl:227
lmul!(::Diagonal, ::AbstractVecOrMat)
@ LinearAlgebra C:\Users\SomeUser\AppData\Local\Programs\Julia-1.9.2\share\julia\stdlib\v1.9\LinearAlgebra\src\diagonal.jl:253
lmul!(::UniformScaling, ::AbstractVecOrMat)
@ LinearAlgebra C:\Users\SomeUser\AppData\Local\Programs\Julia-1.9.2\share\julia\stdlib\v1.9\LinearAlgebra\src\uniformscaling.jl:305
...
Stacktrace:
[1] *(adjQ::Adjoint{Float64, LinearAlgebra.QRCompactWYQ{Float64, Matrix{Float64}, Matrix{Float64}}}, B::Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(f2), Float64}, Float64, 1}})
@ LinearAlgebra C:\Users\SomeUser\AppData\Local\Programs\Julia-1.9.2\share\julia\stdlib\v1.9\LinearAlgebra\src\qr.jl:727
[2] f2(p::ForwardDiff.Dual{ForwardDiff.Tag{typeof(f2), Float64}, Float64, 1})
@ Main .\REPL[10]:3
[3] derivative(f::typeof(f2), x::Float64)
@ ForwardDiff C:\Users\SomeUser\.julia\packages\ForwardDiff\PcZ48\src\derivative.jl:14
[4] top-level scope
@ REPL[11]:1
Since the derivatives are easy, it’s probably a problem with overloads / type system.
How can this be solved?
I’m using ForwardDiff v0.10.36
and Julia 1.9.2
.