You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
jacobian(f, x) silently returns zeros if f is complex-valued #830
extract_jacobian! extracts with partials(T, ydual, i), which for a Complex{Dual} hits the partials(x, i...) = zero(x) fallback. derivative(f, x) is fine since it goes through extract_derivative, which handles Complex{<:Dual}.
extract_derivative cannot be reused directly because it hardcodes the partial index, while the Jacobian needs index i. But generalising it to an index is enough, and keeps the knowledge of how a complex number carries derivative information in one place:
@inlineextract_partial(::Type{T}, y::Real, i) where {T} =zero(y)
@inlineextract_partial(::Type{T}, y::Complex, i) where {T} =zero(y)
@inlineextract_partial(::Type{T}, y::Dual, i) where {T} =partials(T, y, i)
@inlineextract_partial(::Type{T}, y::Complex{<:Dual}, i) where {T} =complex(partials(T, real(y), i), partials(T, imag(y), i))
extract_jacobian!/extract_jacobian_chunk! then use extract_partial(T, ·, i) instead of partials(T, ·, i), and the scalar extract_derivative methods become the i = 1 case.
One more piece is needed for the result eltype, since jacobian allocates similar(ydual, valtype(T, eltype(ydual)), ...):
@inlinevaltype(::Type{T}, ::Type{Complex{D}}) where {T,D} = Complex{valtype(T, D)}
With those, vector mode, chunk mode and jacobian! all give the correct ComplexF64 Jacobian and the real paths are unchanged.
If we would rather not support complex-valued f here, it should at least throw rather than return zeros.
Activity