com.oregondsp.signalProcessing.fft
Class RDFT

java.lang.Object
  extended by com.oregondsp.signalProcessing.fft.RDFT

public class RDFT
extends java.lang.Object

Class to calculate the discrete Fourier transform of a real sequence using symmetries and a complex DFT of half the length.

This class is designed for efficient calculation of many discrete Fourier transforms of the same length. It is limited to transform lengths that are powers of two and are greater than or equal to 32. It uses the identity:

x[2n] + j*x[2n+1] <-> X[k] + X[k+N/2] + j*Wk*( X[k] - X[k+N/2] )

and the fact that, for real sequences x[n], the transform exhibits conjugate symmetry:

X[k] = conjg( X[N-k] )

to calculate a real DFT with a complex DFT of half the length.

Example of use:

int N     = 16384;
int log2N = 14;
float[] x = new float[N];
float[] X = new float[N];
RDFT Xfm = new RDFT( log2N );

// load data
for ( int i = 0; i < N; i++ ) {
  x[i] = ...
}

// evaluate transform of data
Xfm.evaluate( x, X );

The input sequence, x[n], is in natural order, and the output transform is in the packed form used by Sorensen et al. (1987) for conjugate symmetric transforms:

__0_____1_____2_____3_____..._______N/2-1______N/2_______N/2+1______N/2+2____...____N-1
Xr(0)_Xr(1)_Xr(2)_Xr(3)___..._____Xr(N/2-1)__Xr(N/2)___Xi(N/2-1)__Xi(N/2-2)__...___Xi(1)

where Xr is the real part of the transform and Xi is the imaginary part.

As long as the transform size does not change, the RDFT object does not need to be reinstantiated. Consequently, the data arrays can be reloaded and the evaluate method invoked to compute additional DFTs without incurring the cost of RDFT object instantiation.

The inverse DFT is calculated with a call to evaluateInverse():

Xfm.evaluateInverse( X, x );

The input transform, X, is in conjugate symmetric packed form and the output sequence, x, is in natural order.

This class also contains a convenience method to support convolution and correlation via the FFT.

See "Real-valued Fast Fourier Transform Algorithms", Sorensen, H. V., et al., IEEE TRANSACTIONS ON ACOUSTICS, SPEECH, AND SIGNAL PROCESSING, VOL. ASSP-35, NO. 6, JUNE 1987, pp. 849-863.

Author:
David B. Harris, Deschutes Signal Processing LLC

Constructor Summary
RDFT(int log2N)
           
 
Method Summary
static void dftProduct(float[] kernel, float[] transform, float sign)
          Calculates the product of two conjugate symmetric dfts of the same length and stores the result in the second dft.
 void evaluate(float[] x, float[] X)
          Evaluates the DFT of a real sequence x.
 void evaluateInverse(float[] X, float[] x)
          Evaluates the inverse DFT of a conjugate symmetric transform.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

RDFT

public RDFT(int log2N)
Method Detail

evaluate

public void evaluate(float[] x,
                     float[] X)
Evaluates the DFT of a real sequence x.

Parameters:
x - float[] containing the real sequence in natural order.
X - float[] containing the transform of the sequence in conjugate symmetric packed form.

evaluateInverse

public void evaluateInverse(float[] X,
                            float[] x)
Evaluates the inverse DFT of a conjugate symmetric transform.

Parameters:
X - float[] containing the input transform of the sequence in conjugate symmetric packed form.
x - float[] containing the output real sequence in natural order.

dftProduct

public static void dftProduct(float[] kernel,
                              float[] transform,
                              float sign)
Calculates the product of two conjugate symmetric dfts of the same length and stores the result in the second dft.

This is a convenience method to support convolution and correlation operations using the Fast Fourier Transform. Example of use to compute the convolution of two sequences:

int N     = 1024;
int log2N = 10;
float[] x = new float[N];
float[] y = new float[N];
float[] X = new float[N];
float[] Y = new float[N];
RDFT Xfm = new RDFT( log2N );

// load sequences
for ( int i = 0; i < N; i++ ) {
  x[i] = ...
  y[i] = ...
}

// evaluate transforms of sequences
Xfm.evaluate( x, X );
Xfm.evaluate( y, Y );

// product of transforms
RDFT.dftProduct( X, Y, 1 );

// inverse transform to obtain convolution
float[] xy = new float[1024];
RDFT.evaluateInverse( Y, xy );

Parameters:
kernel - first DFT
transform - second DFT before call, contains product after the call
sign - +1 if a convolution type product, -1 if a correlation type product