package org.das2.qds.math.fft.jnt; import org.das2.qds.math.fft.ComplexArray; /** 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); if (true) throw new RuntimeException("Not verified--and it looks bad!"); } /** Compute the Fast Fourier Transform of data leaving the result in data. */ public void transform (ComplexArray.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 wraparound format */ public ComplexArray.Double toWraparoundOrder(ComplexArray.Double data){ ComplexArray.Double newdata = ComplexArray.newArray( new double[n], new double[n] ); int nh = n/2; newdata.setReal(0,data.getReal(0)); newdata.setReal(1,0.0); newdata.setReal(n,data.getReal(1)); newdata.setImag(n,0.0); for(int i=1; iwraparound format */ public double[] toWraparoundOrder(ComplexArray.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 (ComplexArray.Double data){ shuffle(data,-1); fft.backtransform(data); } private void shuffle(ComplexArray.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.getReal(i1 )+data.getReal(i3)); double h1i = c1*(data.getReal(i1+1)-data.getImag(i3)); double h2r = -c2*(data.getReal(i1+1)+data.getImag(i3)); double h2i = c2*(data.getReal(i1 )-data.getReal(i3)); data.setReal(i1 ,h1r+wr*h2r-wi*h2i); data.setImag(i1,h1i+wr*h2i+wi*h2r); data.setReal(i3 ,h1r-wr*h2r+wi*h2i); data.setImag(i3,-h1i+wr*h2i+wi*h2r); wtemp = wr; wr += wtemp*wpr-wi*wpi; wi += wtemp*wpi+wi*wpr; } double d0 = data.getReal(0); if (sign == 1){ data.setReal(0,d0+data.getReal(1)); data.setReal(1,d0-data.getReal(1)); } else { data.setReal(0,c1*(d0+data.getReal(1))); data.setReal(1,c1*(d0-data.getReal(1))); } if (n%4==0) data.setImag(nh, data.getImag(nh) * (-1) ); } /** Compute the Fast Fourier Transform of data leaving the result in data. */ public void transform (ComplexArray.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 (ComplexArray.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 (ComplexArray.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 (ComplexArray.Double data) { backtransform(data); /* normalize inverse fft with 2/n */ double norm = normalization(); for (int i = 0; i < n; i++) data.setReal( i, data.getReal(i) * norm ); } }