///|
/// The length of the transform that an interleaved array holds.
///
/// The array holds `(real, imaginary)` pairs, so its length is `2 * n`, `n`
/// has to be a valid transform length and the name of the caller goes into
/// the message of the failure.
fn complex_length(x : Array[Float], caller : String) -> Int32 {
let len = x.length()
if len % 2 != 0 {
abort(
caller +
": the array holds " +
len.to_string() +
" floats, which is not a whole number of (real, imaginary) pairs",
)
}
let n = len / 2
if !nfft_valid(n) {
abort(
caller +
": " +
n.to_string() +
" is not a valid transform length, the nearest one is " +
nfft_small(n).to_string() +
", see nfft_valid",
)
}
n
}
///|
/// The forward discrete Fourier transform of a sequence of complex points.
///
/// This is the `fft` of FFTW.jl: unscaled, `X[k] = sum_j x[j] *
/// exp(-2*pi*i*j*k/n)`. `x` holds `n` interleaved `(real, imaginary)` pairs,
/// so it is `2 * n` floats long, and `n` has to be a valid transform length,
/// see *Transform sizes*; the nearest valid length to a given length is
/// `nfft_small(n)`. The result is a new array of the same length, and `x` is
/// left untouched.
///
/// The inverse is `ifft`, which is scaled so that the two undo each other.
pub fn fft(x : Array[Float]) -> Array[Float] {
let n = complex_length(x, "fft")
let y = zerosf(x.length())
FftComplex::new(n).complex_to_complex(-1, x, y)
y
}
///|
/// The inverse discrete Fourier transform of a sequence of complex points,
/// scaled by `1 / n` so that it undoes `fft`.
///
/// This is the `ifft` of FFTW.jl: the transform of the opposite direction
/// divided by the length. The unscaled inverse - the `bfft` of FFTW.jl - is
/// what `complex_to_complex(1, ...)` of `FftComplex` computes, and it is the
/// only inverse of the Java original, which never scales. `x` holds `n`
/// interleaved pairs and `n` has to be a valid transform length, as in `fft`.
pub fn ifft(x : Array[Float]) -> Array[Float] {
let n = complex_length(x, "ifft")
let y = zerosf(x.length())
FftComplex::new(n).ifft(x, y)
y
}