It looks like the code currently only keeps the 1:d slice in each dimension. Since standard FFT outputs place negative low-frequency modes at the end of the array, doesn’t this implementation drop those modes?
According to the FNO paper, we should keep the lowest modes from both ends (e.g., 1:k and (end-k+1):end). Is there a specific reason it’s implemented this way, or is this a bug?
I think the correct way to implement the truncation of higher frequency modes would be to apply fftshift, and then keep the center crop x[center-k:center+k].
After taking a closer look at the FourierNeuralOperator implementation in NeuralOperators.jl, I’m now convinced that the issue I described above is indeed a correctness bug.
More broadly, the current Fourier Neural Operator implementation in NeuralOperators.jl appears to be outdated. It follows the original FNO paper [1], whereas most modern implementations (for example, the PyTorch-based neuraloperator) are based on the follow-up work [2], which introduces a significantly improved FNO architecture.
To address this, I’ve implemented a modern FNO variant following [2] from scratch.
GitHub repo: FourierNeuralOperators.jl
If there is interest from the maintainers, I’d be happy to discuss integrating this implementation into NeuralOperators.jl.