Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Derivative issue with DiffResults and nested arrays #725

Open
Technici4n opened this issue Nov 20, 2024 · 1 comment
Open

Derivative issue with DiffResults and nested arrays #725

Technici4n opened this issue Nov 20, 2024 · 1 comment

Comments

@Technici4n
Copy link

The following code works:

using ForwardDiff

g(x) = [[x^2, sqrt(x)]]
println(ForwardDiff.derivative(g, 2))

But this code:

using DiffResults
using ForwardDiff

g(x) = [[x^2, sqrt(x)]]
result = DiffResults.DiffResult(similar(g(2)), similar(g(2)))
result = ForwardDiff.derivative!(result, g, 2)
println(result)

Leads to a runtime error:

ERROR: LoadError: MethodError: no method matching Float64(::ForwardDiff.Dual{ForwardDiff.Tag{typeof(g), Int64}, Float64, 1})

Closest candidates are:
  (::Type{T})(::Real, ::RoundingMode) where T<:AbstractFloat
   @ Base rounding.jl:207
  (::Type{T})(::T) where T<:Number
   @ Core boot.jl:792
  Float64(::IrrationalConstants.Fourπ)
   @ IrrationalConstants C:\Users\bruno\.julia\packages\IrrationalConstants\vp5v4\src\macro.jl:112
  ...

Stacktrace:
  [1] convert(::Type{Float64}, x::ForwardDiff.Dual{ForwardDiff.Tag{typeof(g), Int64}, Float64, 1})
    @ Base .\number.jl:7
  [2] setindex!(A::Vector{Float64}, x::ForwardDiff.Dual{ForwardDiff.Tag{typeof(g), Int64}, Float64, 1}, i1::Int64)
    @ Base .\array.jl:1021
  [3] _unsafe_copyto!(dest::Vector{Float64}, doffs::Int64, src::Vector{ForwardDiff.Dual{…}}, soffs::Int64, n::Int64)
    @ Base .\array.jl:299
  [4] unsafe_copyto!
    @ .\array.jl:353 [inlined]
  [5] _copyto_impl!
    @ .\array.jl:376 [inlined]
  [6] copyto!
    @ .\array.jl:363 [inlined]
  [7] copyto!
    @ .\array.jl:385 [inlined]
  [8] copyto_axcheck!
    @ .\abstractarray.jl:1177 [inlined]
  [9] Vector{Float64}(x::Vector{ForwardDiff.Dual{ForwardDiff.Tag{typeof(g), Int64}, Float64, 1}})
    @ Base .\array.jl:673
 [10] convert
    @ .\array.jl:665 [inlined]
 [11] setindex!
    @ .\array.jl:1021 [inlined]
 [12] map!
    @ .\abstractarray.jl:3279 [inlined]
 [13] value!
    @ C:\Users\bruno\.julia\packages\DiffResults\YLo25\src\DiffResults.jl:167 [inlined]
 [14] extract_value!
    @ C:\Users\bruno\.julia\packages\ForwardDiff\UBbGT\src\apiutils.jl:5 [inlined]
 [15] derivative!(result::DiffResults.MutableDiffResult{1, Vector{Vector{…}}, Tuple{Vector{…}}}, f::typeof(g), x::Int64)
    @ ForwardDiff C:\Users\bruno\.julia\packages\ForwardDiff\UBbGT\src\derivative.jl:49

Adding the following line fixes this problem:

ForwardDiff.value(::Type{T}, x::AbstractArray) where T = map(d -> ForwardDiff.value(T, d), x)
@gdalle
Copy link
Member

gdalle commented Nov 20, 2024

To me the issue is bigger than one missing method: you are trying to use ForwardDiff in a setting where it is not meant to work. As the docstring of ForwardDiff.derivative clearly states,

This method assumes that isa(f(x), Union{Real,AbstractArray}).

Thus, even if you add this method, calling derivative with non-array outputs will be outside of the public API. It won't necessarily be tested, and it will be vulnerable to breaking even between patch versions. That is, unless the API is extended, but I'm not sure it's worth it to open such a can of worms?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants