Closed
Description
I'm trying to calculate complex derivatives of analytic functions, using a trick by @tpapp:
using ForwardDiff
∂(f, x::Real) = ForwardDiff.derivative(f, x)
function ∂(f, z::Complex)
# https://discourse.julialang.org/t/automatic-differentiation-of-complex-valued-functions/30263/3
ff = ((x,y),) -> begin
fz = f(complex(x,y))
[real(fz), imag(fz)]
end
J = ForwardDiff.jacobian(ff, [real(z), imag(z)])
# Complex derivative for an analytic function
# f(x + im*y) = u(x,y) + im*v(x,y)
# is given by
# f′(x + im*y) = uₓ + im*vₓ = v_y - im*u_y
J[1,1] + im*J[2,1]
end
This works for some simple functions:
julia> ∂(sin, 0.1), ∂(sin, 0.1+0im), ∂(sin, 0.1+0.3im)
(0.9950041652780258, 0.9950041652780258 + 0.0im, 1.0401161756837587 - 0.030401301333122962im)
julia> ∂(t -> exp(-t), 0.1+0.3im)
-0.8644242021759518 + 0.26739774077289963im
But fails for functions involving powers:
julia> f = z -> z^2
#4019 (generic function with 1 method)
julia> ∂(f, 0.1)
0.2
julia> ∂(f, 0.1+0.0im)
ERROR: MethodError: no method matching Int64(::ForwardDiff.Dual{ForwardDiff.Tag{var"#4015#4016"{var"#4019#4020"}, Float64}, Float64, 2})
Closest candidates are:
(::Type{T})(::T) where T<:Number at boot.jl:760
(::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number} at char.jl:50
(::Type{T})(::BigInt) where T<:Union{Int128, Int16, Int32, Int64, Int8} at gmp.jl:356
...
Stacktrace:
[1] convert(#unused#::Type{Int64}, x::ForwardDiff.Dual{ForwardDiff.Tag{var"#4015#4016"{var"#4019#4020"}, Float64}, Float64, 2})
@ Base ./number.jl:7
[2] _cpow(z::Complex{ForwardDiff.Dual{ForwardDiff.Tag{var"#4015#4016"{var"#4019#4020"}, Float64}, Float64, 2}}, p::Complex{ForwardDiff.Dual{ForwardDiff.Tag{var"#4015#4016"{var"#4019#4020"}, Float64}, Float64, 2}})
@ Base ./complex.jl:740
[3] ^
@ ./complex.jl:808 [inlined]
[4] ^
@ ./promotion.jl:355 [inlined]
[5] ^
@ ./complex.jl:813 [inlined]
[6] macro expansion
@ ./none:0 [inlined]
[7] literal_pow
@ ./none:0 [inlined]
[8] #4019
@ ./REPL[124]:1 [inlined]
[9] (::var"#4015#4016"{var"#4019#4020"})(::Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#4015#4016"{var"#4019#4020"}, Float64}, Float64, 2}})
@ Main /tmp/test.jl:6
[10] vector_mode_dual_eval
@ ~/.julia/packages/ForwardDiff/sqhTO/src/apiutils.jl:37 [inlined]
[11] vector_mode_jacobian(f::var"#4015#4016"{var"#4019#4020"}, x::Vector{Float64}, cfg::ForwardDiff.JacobianConfig{ForwardDiff.Tag{var"#4015#4016"{var"#4019#4020"}, Float64}, Float64, 2, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#4015#4016"{var"#4019#4020"}, Float64}, Float64, 2}}})
@ ForwardDiff ~/.julia/packages/ForwardDiff/sqhTO/src/jacobian.jl:147
[12] jacobian(f::Function, x::Vector{Float64}, cfg::ForwardDiff.JacobianConfig{ForwardDiff.Tag{var"#4015#4016"{var"#4019#4020"}, Float64}, Float64, 2, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#4015#4016"{var"#4019#4020"}, Float64}, Float64, 2}}}, ::Val{true})
@ ForwardDiff ~/.julia/packages/ForwardDiff/sqhTO/src/jacobian.jl:21
[13] jacobian(f::Function, x::Vector{Float64}, cfg::ForwardDiff.JacobianConfig{ForwardDiff.Tag{var"#4015#4016"{var"#4019#4020"}, Float64}, Float64, 2, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#4015#4016"{var"#4019#4020"}, Float64}, Float64, 2}}}) (repeats 2 times)
@ ForwardDiff ~/.julia/packages/ForwardDiff/sqhTO/src/jacobian.jl:19
[14] ∂(f::var"#4019#4020", z::ComplexF64)
Other failing examples: t -> exp(-t^2)
, z -> cospi(z)^2
.
Unsure if related to #486
Metadata
Metadata
Assignees
Labels
No labels