Hello,
I have a very basic question, but I haven’t found any solution. I want to differentiate a holomorphic complex function.
My function is
f(z) = [z^3 + exp(im*z), exp(im*z^2) + 1]
And I differentiate it using DifferentiationInferface.jl
f2(z) = f(z[1])
_, j1 = DifferentiationInterface.value_and_jacobian(f2, AutoFiniteDiff(), [1.0+2.0im])
j1
_, j2 = DifferentiationInterface.value_and_jacobian(f2, AutoForwardDiff(), [1.0+2.0im])
j2
But ForwardDiff.jl returns the error
ERROR: ArgumentError: Cannot create a dual over scalar type ComplexF64. If the type behaves as a scalar, define ForwardDiff.can_dual(::Type{ComplexF64}) = true.
What does it do if I set can_dual
? Why isn’t it already set? If I do it I then get
ERROR: ArgumentError: Cannot create a dual over scalar type Any. If the type behaves as a scalar, define ForwardDiff.can_dual(::Type{Any}) = true.
If I also set this, I get
ERROR: MethodError: no method matching signbit(::ComplexF64)
The function `signbit` exists, but no method is defined for this combination of argument types.
Closest candidates are:
signbit(::Float32)
@ Base floatfuncs.jl:16
signbit(::Bool)
@ Base bool.jl:151
signbit(::Float16)
@ Base floatfuncs.jl:17
Using Zygote
It works using Zygote.js
function wirtinger(f, x)
y, back = Zygote.pullback(f, x)
du = [back([i == j ? 1 : 0 for i in 1:length(y)])[1] for j in 1:length(y)]
dv = [back([i == j ? im : 0 for i in 1:length(y)])[1] for j in 1:length(y)]
(conj.(du) + im*conj.(dv))/2, (du + im*dv)/2
end
wirtinger(f, 1+2im)[1]