With accurate trigonometric constants, a good FFT algorithm should have $O(\log n)$ error bounds and $O(\sqrt{\log n})$ root-mean-square error, similar to pairwise summation. See also the commentary and references posted with the FFTW accuracy benchmarks.
However, the accuracy of FFTA seems to be much worse, nearly $O(n)$ error growth, presumably because (like many naive textbook presentations) it is constructing the trigonometric constants by a recurrence relation. Here is a plot of the single-precision accuracy on random data (using the double-precision result as the "exact" value for comparison) with both FFTW and FFTA:
via the code:
using LinearAlgebra
relerr(approx, exact) = norm(approx - exact) / norm(exact)
n = 2 .^ (4:20)
err_fft = Float64[]
for n in n
x = randn(ComplexF32, n)
push!(err_fft, relerr(fft(x), fft(ComplexF64.(x))))
end
@show err_fft;
Recommendation: the only reasonably efficient way to get accurate trigonometric constants is to precompute them by calling cis (or cispi) and storing the table in the "plan" data structure.
With accurate trigonometric constants, a good FFT algorithm should have$O(\log n)$ error bounds and $O(\sqrt{\log n})$ root-mean-square error, similar to pairwise summation. See also the commentary and references posted with the FFTW accuracy benchmarks.
However, the accuracy of FFTA seems to be much worse, nearly$O(n)$ error growth, presumably because (like many naive textbook presentations) it is constructing the trigonometric constants by a recurrence relation. Here is a plot of the single-precision accuracy on random data (using the double-precision result as the "exact" value for comparison) with both FFTW and FFTA:
via the code:
Recommendation: the only reasonably efficient way to get accurate trigonometric constants is to precompute them by calling
cis(orcispi) and storing the table in the "plan" data structure.