43.3 Real‑Valued FFT Optimizations
Real signals have conjugate‑symmetric spectra; exploit this to halve storage and computation.
43.3.1 Packing Real Data
Pack N real samples into N/2 complex samples, perform complex FFT, then unpack:
void realFFT(float[] real, float[] spectrum, int N) {
// pack: [r0, r1, r2, r3, ...] -> [r0, 0, r1, 0, ...] or pack two into one complex
// Simpler approach: zero-fill imaginary
float[] complex = new float[N*2];
for (int i = 0; i < N; i++) { complex[2*i] = real[i]; complex[2*i+1] = 0f; }
fftRadix2(complex, N);
// copy to spectrum (only first N/2+1 bins are unique for real input)
System.arraycopy(complex, 0, spectrum, 0, N+2);
}
43.3.2 Advanced Real FFT (Split‑Radix)
For production, use split‑radix or specialized real FFT libraries. The basic approach trades accuracy for simplicity.
43.3.3 Magnitude and Phase
float magnitude(float re, float im) { return (float)Math.sqrt(re*re + im*im); }
float phase(float re, float im) { return (float)Math.atan2(im, re); }