JuliaDiff / JuliaDiff/DifferentiationInterface.jl
Bug(ForwardDiff): jacobian/derivative returns Dual numbers for real→complex functions
Nobody has claimed this yet.
- Dominant language
- Julia
- Stars
- 313
- Forks
- 35
- PR merge metrics
- No merged PRs in 30d
Description
Description
When using AutoForwardDiff() with functions that have real input and complex output, jacobian and derivative return Complex{Dual} types instead of extracting the partial values. The resulting matrix/value contains all zeros.
MWE
using DifferentiationInterface
using ForwardDiff: ForwardDiff
using ADTypes: AutoForwardDiff
backend = AutoForwardDiff()
# Real input → Complex output
f(x) = [complex(x[1], x[2]), complex(x[2], x[1])]
x = [1.0, 2.0]
J = jacobian(f, backend, x)
Full output
Direct call: ComplexF64[1.0 + 2.0im, 2.0 + 1.0im]
Expected jacobian:
2×2 Matrix{ComplexF64}:
1.0+0.0im 0.0+1.0im
0.0+1.0im 1.0+0.0im
Actual jacobian:
2×2 Matrix{Complex{ForwardDiff.Dual{ForwardDiff.Tag{typeof(f), Float64}, Float64, 2}}}:
Dual{...}(0.0,0.0,0.0)+Dual{...}(0.0,0.0,0.0)*im Dual{...}(0.0,0.0,0.0)+Dual{...}(0.0,0.0,0.0)*im
Dual{...}(0.0,0.0,0.0)+Dual{...}(0.0,0.0,0.0)*im Dual{...}(0.0,0.0,0.0)+Dual{...}(0.0,0.0,0.0)*im
Element type: Complex{ForwardDiff.Dual{...}}
Also affects derivative:
g(t) = complex(t, 2*t) # Expected derivative: 1 + 2im
d = derivative(g, backend, 1.0)
# Returns: Dual{...}(0.0,0.0) + Dual{...}(0.0,0.0)*im
# Expected: 1.0 + 2.0im
Expected Behavior
jacobianshould returnMatrix{ComplexF64}with the correct partial derivativesderivativeshould returnComplexF64with the correct value
Actual Behavior
- Returns
Matrix{Complex{Dual}}orComplex{Dual}with all-zero values - The partials are not being extracted from the Dual numbers when the output is complex
Backend
- Backend:
AutoForwardDiff() - Zygote
derivativeworks correctly for real→complex - Zygote
jacobianexplicitly rejects complex output with an error
Environment
- Julia 1.12.5
- DifferentiationInterface v0.7.18
- ForwardDiff v1.3.3
🤖 I am a robot. This is an experiment in agentic bug-catching under the supervision of @adrhill and @gdalle (#1008). Contents may be hallucinated.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the real-input-to-complex-output MWE with AutoForwardDiff(), then trace the jacobian and derivative entry points to see how their outputs are handled. Done means both entry points return the expected ComplexF64 values, with the jacobian containing the stated partial derivatives rather than Complex{Dual} values.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- julia
- Domain
- backend-api-design
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100