The x parameter is both input and output data. After the FFT, x * contains the transform coefficients used to construct n * complex FFT coefficients. * *
The real part of the first complex FFT coefficients is x[0]; * its imaginary part is 0. If n is even set m = n/2, if n is odd set * m = (n+1)/2, then for k = 1, ..., m-1: *
If n is even, the real of part of (n/2)-th complex FFT * coefficient is x[n - 1]; its imaginary part is 0. * *
The remaining complex FFT coefficients can be obtained by the
* symmetry relation: the (n-k)-th complex FFT coefficient is the
* conjugate of n-th complex FFT coefficient.
*
* @param x An array which contains the sequence to be
* transformed.
*/
public void ft(double[] x) {
if (x.length != ndim)
throw new IllegalArgumentException("The length of data can not match that of the wavetable");
rfftf(ndim, x, wavetable);
}
/**
* Forward real FFT transform. It computes the discrete transform of a real data sequence.
*
* @param x an array which contains the sequence to be transformed. After FFT,
* x contains the transform coeffients used to construct n complex FFT coeffients.
*
* @param y the first complex (n+1)/2 (when n is odd) or (n/2+1) (when
* n is even) FFT coefficients.
* The remaining complex FFT coefficients can be obtained by the symmetry relation:
* the (n-k)-th complex FFT coefficient is the conjugate of n-th complex FFT coeffient.
*
*/
public void ft(double x[], Complex1D y) {
if (x.length != ndim)
throw new IllegalArgumentException("The length of data can not match that of the wavetable");
rfftf(ndim, x, wavetable);
if(ndim%2 == 0)
{
y.x = new double[ndim/2 + 1];
y.y = new double[ndim/2 + 1];
}
else
{
y.x = new double[(ndim+1)/2];
y.y = new double[(ndim+1)/2];
}
y.x[0] = x[0];
y.y[0] = 0.0D;
for(int i=1; i<(ndim+1)/2; i++)
{
y.x[i] = x[2*i-1];
y.y[i] = x[2*i];
}
if(ndim%2 == 0)
{
y.x[ndim/2] = x[ndim-1];
y.y[ndim/2] = 0.0D;
}
}
/**
* Backward real FFT transform. It is the unnormalized inverse transform of ft(double[]).
*
* @param x an array which contains the sequence to be transformed. After FFT,
* x contains the transform coeffients. Also see the comments of ft(double[])
* for the relation between x and complex FFT coeffients.
*/
public void bt(double x[])
{
if(x.length != ndim)
throw new IllegalArgumentException("The length of data can not match that of the wavetable");
rfftb(ndim, x, wavetable);
}
/**
* Backward real FFT transform. It is the unnormalized inverse transform of ft(Complex1D, double[]).
*
* @param x an array which contains the sequence to be transformed. When n is odd, it contains the first
* (n+1)/2 complex data; when n is even, it contains (n/2+1) complex data.
* @param y the real FFT coeffients.
*
* Also see the comments of ft(double[]) for the relation
* between x and complex FFT coeffients.
*/
public void bt(Complex1D x, double y[])
{
if(ndim%2 == 0)
{
if(x.x.length != ndim/2+1)
throw new IllegalArgumentException("The length of data can not match that of the wavetable");
}
else
{
if(x.x.length != (ndim+1)/2)
throw new IllegalArgumentException("The length of data can not match that of the wavetable");
}
y[0] = x.x[0];
for(int i=1; i<(ndim+1)/2; i++)
{
y[2*i-1]=x.x[i];
y[2*i]=x.y[i];
}
if(ndim%2 == 0)
{
y[ndim-1]=x.x[ndim/2];
}
rfftb(ndim, y, wavetable);
}
/**
* norm_factor can be used to normalize this FFT transform. This is because
* a call of forward transform (ft) followed by a call of backward transform
* (bt) will multiply the input sequence by norm_factor.
*/
public double norm_factor;
private double wavetable[];
private int ndim;
}
package ca.uol.aig.fftpack;
/**
* cosine FFT transform of a real even sequence.
* @author Baoshe Zhang
* @author Astronomical Instrument Group of University of Lethbridge.
*/
public class RealDoubleFFT_Even extends RealDoubleFFT_Mixed
{
/**
* norm_factor can be used to normalize this FFT transform. This is because
* a call of forward transform (ft) followed by a call of backward transform
* (bt) will multiply the input sequence by norm_factor.
*/
public double norm_factor;
private double wavetable[];
private int ndim;
/**
* Construct a wavenumber table with size n.
* The sequences with the same size can share a wavenumber table. The prime
* factorization of n together with a tabulation of the trigonometric functions
* are computed and stored.
*
* @param n the size of a real data sequence. When (n-1) is a multiplication of small
* numbers (4, 2, 3, 5), this FFT transform is very efficient.
*/
public RealDoubleFFT_Even(int n)
{
ndim = n;
norm_factor = 2 * (n - 1);
if (wavetable == null || wavetable.length != (3 * ndim + 15))
wavetable = new double[3 * ndim + 15];
costi(ndim, wavetable);
}
/**
* Forward cosine FFT transform. It computes the discrete sine transform of
* an odd sequence.
*
* @param x an array which contains the sequence to be transformed. After FFT,
* x contains the transform coeffients.
*/
public void ft(double[] x) {
cost(ndim, x, wavetable);
}
/**
* Backward cosine FFT transform. It is the unnormalized inverse transform of ft.
*
* @param x an array which contains the sequence to be transformed. After FFT,
* x contains the transform coeffients.
*/
public void bt(double[] x) {
cost(ndim, x, wavetable);
}
/*-------------------------------------------------------------
cost: cosine FFT. Backward and forward cos-FFT are the same.
------------------------------------------------------------*/
void cost(int n, double x[], final double wtable[])
{
int modn, i, k;
double c1, t1, t2;
int kc;
double xi;
int nm1;
double x1h;
int ns2;
double tx2, x1p3, xim2;
nm1=n-1;
ns2=n / 2;
if(n-2<0) return;
else if(n==2)
{
x1h=x[0]+x[1];
x[1]=x[0]-x[1];
x[0]=x1h;
}
else if(n==3)
{
x1p3=x[0]+x[2];
tx2=x[1]+x[1];
x[1]=x[0]-x[2];
x[0]=x1p3+tx2;
x[2]=x1p3-tx2;
}
else
{
c1=x[0]-x[n-1];
x[0]+=x[n-1];
for(k=1; k