You’ve constructed this to have a ComplexF64
eltype, but this is incompatible with operator-overloading automatic differentiation (AD) packages like ForwardDiff, ReverseDiff, and Tracker, which use a custom numeric type to compute gradients. Instead, try
uhat = zeros(complex(eltype(ξ)),2*N);
The next issue you’ll have is that not all AD packages support complex numbers. Zygote definitely does, but it doesn’t support mutation. But if you want to differentiate an FFT, I think Zygote is your only option. So here’s a non-mutating build_field
:
function build_field(ξ; α=one(eltype(ξ)))
N = length(ξ)
# construct the eigenvalues
πk = π * (1:N);
# NOTE we need to multiply by 2 *N for FFT scaling
c = 2N * sqrt(2)
umid = @. c * ξ / πk^α;
uhat = [0; umid; zeros(N - 1)]
# invert and get the relevant imaginary part
u = @views imag.(ifft(uhat)[N+2:end]);
return u
end
See https://turing.ml/dev/docs/using-turing/autodiff for details.
Also, from your simulated data, it seems γ
might be intended to be a standard deviation? Note that Normal
takes a standard deviation as a parameter, so perhaps you mean to use Normal(u[i], γ)
as your likelihood?