package com.isti.traceview.jnt.FFT; /** * Computes FFT's of real, double precision data when n is even, by computing * complex FFT. * * @author Bruce R. Miller bruce.miller@nist.gov * @author Derived from Numerical Methods. * @author Contribution of the National Institute of Standards and Technology, * @author not subject to copyright. */ public class RealDoubleFFT_Even extends RealDoubleFFT { ComplexDoubleFFT fft; /** Create an FFT for transforming n points of real, double precision data. */ public RealDoubleFFT_Even(int n) { super(n); if (n % 2 != 0) throw new IllegalArgumentException(n + " is not even"); fft = new ComplexDoubleFFT_Mixed(n / 2); } /** Compute the Fast Fourier Transform of data leaving the result in data. */ public void transform(double data[]) { fft.transform(data); shuffle(data, +1); } /** * Return data in wraparound order. i0 and stride are used to traverse data; * the new array is in packed (i0=0, stride=1) format. * * @see <a href="package-summary.html#wraparound">wraparound format</A> */ public double[] toWraparoundOrder(double data[]) { double newdata[] = new double[2 * n]; int nh = n / 2; newdata[0] = data[0]; newdata[1] = 0.0; newdata[n] = data[1]; newdata[n + 1] = 0.0; for (int i = 1; i < nh; i++) { newdata[2 * i] = data[2 * i]; newdata[2 * i + 1] = data[2 * i + 1]; newdata[2 * (n - i)] = data[2 * i]; newdata[2 * (n - i) + 1] = -data[2 * i + 1]; } return newdata; } /** * Return data in wraparound order. * * @see <a href="package-summary.html#wraparound">wraparound format</A> */ public double[] toWraparoundOrder(double data[], int i0, int stride) { throw new Error("Not Implemented!"); } /** Compute the (unnomalized) inverse FFT of data, leaving it in place. */ public void backtransform(double data[]) { shuffle(data, -1); fft.backtransform(data); } private void shuffle(double data[], int sign) { int nh = n / 2; int nq = n / 4; double c1 = 0.5, c2 = -0.5 * sign; double theta = sign * Math.PI / nh; double wtemp = Math.sin(0.5 * theta); double wpr = -2.0 * wtemp * wtemp; double wpi = -Math.sin(theta); double wr = 1.0 + wpr; double wi = wpi; for (int i = 1; i < nq; i++) { int i1 = 2 * i; int i3 = n - i1; double h1r = c1 * (data[i1] + data[i3]); double h1i = c1 * (data[i1 + 1] - data[i3 + 1]); double h2r = -c2 * (data[i1 + 1] + data[i3 + 1]); double h2i = c2 * (data[i1] - data[i3]); data[i1] = h1r + wr * h2r - wi * h2i; data[i1 + 1] = h1i + wr * h2i + wi * h2r; data[i3] = h1r - wr * h2r + wi * h2i; data[i3 + 1] = -h1i + wr * h2i + wi * h2r; wtemp = wr; wr += wtemp * wpr - wi * wpi; wi += wtemp * wpi + wi * wpr; } double d0 = data[0]; if (sign == 1) { data[0] = d0 + data[1]; data[1] = d0 - data[1]; } else { data[0] = c1 * (d0 + data[1]); data[1] = c1 * (d0 - data[1]); } if (n % 4 == 0) data[nh + 1] *= -1; } /** Compute the Fast Fourier Transform of data leaving the result in data. */ public void transform(double data[], int i0, int stride) { throw new Error("Not Implemented!"); } /** Compute the (unnomalized) inverse FFT of data, leaving it in place. */ public void backtransform(double data[], int i0, int stride) { throw new Error("Not Implemented!"); } /** Compute the (nomalized) inverse FFT of data, leaving it in place. */ public void inverse(double data[], int i0, int stride) { throw new Error("Not Implemented!"); } /** * Return the normalization factor. Multiply the elements of the * backtransform'ed data to get the normalized inverse. */ public double normalization() { return 2.0 / ((double) n); } /** Compute the (nomalized) inverse FFT of data, leaving it in place. */ public void inverse(double data[]) { backtransform(data); /* normalize inverse fft with 2/n */ double norm = normalization(); for (int i = 0; i < n; i++) data[i] *= norm; } }