edu.emory.mathcs.jtransforms.fft

## Class FloatFFT_3D

• ```public class FloatFFT_3D
extends Object```
Computes 3D Discrete Fourier Transform (DFT) of complex and real, single precision data. The sizes of all three dimensions can be arbitrary numbers. This is a parallel implementation of split-radix and mixed-radix algorithms optimized for SMP systems.

Part of the code is derived from General Purpose FFT Package written by Takuya Ooura (http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html)
Author:
Piotr Wendykier (piotr.wendykier@gmail.com)
• ### Constructor Summary

Constructors
Constructor and Description
```FloatFFT_3D(int slices, int rows, int columns)```
Creates new instance of FloatFFT_3D.
• ### Method Summary

All Methods
Modifier and Type Method and Description
`void` `complexForward(float[] a)`
Computes 3D forward DFT of complex data leaving the result in `a`.
`void` `complexForward(float[][][] a)`
Computes 3D forward DFT of complex data leaving the result in `a`.
`void` ```complexInverse(float[][][] a, boolean scale)```
Computes 3D inverse DFT of complex data leaving the result in `a`.
`void` ```complexInverse(float[] a, boolean scale)```
Computes 3D inverse DFT of complex data leaving the result in `a`.
`void` `realForward(float[] a)`
Computes 3D forward DFT of real data leaving the result in `a` .
`void` `realForward(float[][][] a)`
Computes 3D forward DFT of real data leaving the result in `a` .
`void` `realForwardFull(float[] a)`
Computes 3D forward DFT of real data leaving the result in `a` .
`void` `realForwardFull(float[][][] a)`
Computes 3D forward DFT of real data leaving the result in `a` .
`void` ```realInverse(float[][][] a, boolean scale)```
Computes 3D inverse DFT of real data leaving the result in `a` .
`void` ```realInverse(float[] a, boolean scale)```
Computes 3D inverse DFT of real data leaving the result in `a` .
`void` ```realInverseFull(float[][][] a, boolean scale)```
Computes 3D inverse DFT of real data leaving the result in `a` .
`void` ```realInverseFull(float[] a, boolean scale)```
Computes 3D inverse DFT of real data leaving the result in `a` .
• ### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`
• ### Constructor Detail

• #### FloatFFT_3D

```public FloatFFT_3D(int slices,
int rows,
int columns)```
Creates new instance of FloatFFT_3D.
Parameters:
`slices` - number of slices
`rows` - number of rows
`columns` - number of columns
• ### Method Detail

• #### complexForward

`public void complexForward(float[] a)`
Computes 3D forward DFT of complex data leaving the result in `a`. The data is stored in 1D array addressed in slice-major, then row-major, then column-major, in order of significance, i.e. element (i,j,k) of 3D array x[slices][rows][2*columns] is stored in a[i*sliceStride + j*rowStride + k], where sliceStride = rows * 2 * columns and rowStride = 2 * columns. Complex number is stored as two float values in sequence: the real and imaginary part, i.e. the input array must be of size slices*rows*2*columns. The physical layout of the input data is as follows:
``` a[k1*sliceStride + k2*rowStride + 2*k3] = Re[k1][k2][k3],
a[k1*sliceStride + k2*rowStride + 2*k3+1] = Im[k1][k2][k3], 0<=k1<slices, 0<=k2<rows, 0<=k3<columns,
```
Parameters:
`a` - data to transform
• #### complexForward

`public void complexForward(float[][][] a)`
Computes 3D forward DFT of complex data leaving the result in `a`. The data is stored in 3D array. Complex data is represented by 2 float values in sequence: the real and imaginary part, i.e. the input array must be of size slices by rows by 2*columns. The physical layout of the input data is as follows:
``` a[k1][k2][2*k3] = Re[k1][k2][k3],
a[k1][k2][2*k3+1] = Im[k1][k2][k3], 0<=k1<slices, 0<=k2<rows, 0<=k3<columns,
```
Parameters:
`a` - data to transform
• #### complexInverse

```public void complexInverse(float[] a,
boolean scale)```
Computes 3D inverse DFT of complex data leaving the result in `a`. The data is stored in a 1D array addressed in slice-major, then row-major, then column-major, in order of significance, i.e. element (i,j,k) of 3-d array x[slices][rows][2*columns] is stored in a[i*sliceStride + j*rowStride + k], where sliceStride = rows * 2 * columns and rowStride = 2 * columns. Complex number is stored as two float values in sequence: the real and imaginary part, i.e. the input array must be of size slices*rows*2*columns. The physical layout of the input data is as follows:
``` a[k1*sliceStride + k2*rowStride + 2*k3] = Re[k1][k2][k3],
a[k1*sliceStride + k2*rowStride + 2*k3+1] = Im[k1][k2][k3], 0<=k1<slices, 0<=k2<rows, 0<=k3<columns,
```
Parameters:
`a` - data to transform
`scale` - if true then scaling is performed
• #### complexInverse

```public void complexInverse(float[][][] a,
boolean scale)```
Computes 3D inverse DFT of complex data leaving the result in `a`. The data is stored in a 3D array. Complex data is represented by 2 float values in sequence: the real and imaginary part, i.e. the input array must be of size slices by rows by 2*columns. The physical layout of the input data is as follows:
``` a[k1][k2][2*k3] = Re[k1][k2][k3],
a[k1][k2][2*k3+1] = Im[k1][k2][k3], 0<=k1<slices, 0<=k2<rows, 0<=k3<columns,
```
Parameters:
`a` - data to transform
`scale` - if true then scaling is performed
• #### realForward

`public void realForward(float[] a)`
Computes 3D forward DFT of real data leaving the result in `a` . This method only works when the sizes of all three dimensions are power-of-two numbers. The data is stored in a 1D array addressed in slice-major, then row-major, then column-major, in order of significance, i.e. element (i,j,k) of 3-d array x[slices][rows][2*columns] is stored in a[i*sliceStride + j*rowStride + k], where sliceStride = rows * 2 * columns and rowStride = 2 * columns. The physical layout of the output data is as follows:
``` a[k1*sliceStride + k2*rowStride + 2*k3] = Re[k1][k2][k3]
= Re[(slices-k1)%slices][(rows-k2)%rows][columns-k3],
a[k1*sliceStride + k2*rowStride + 2*k3+1] = Im[k1][k2][k3]
= -Im[(slices-k1)%slices][(rows-k2)%rows][columns-k3],
0<=k1<slices, 0<=k2<rows, 0<k3<columns/2,
a[k1*sliceStride + k2*rowStride] = Re[k1][k2]
= Re[(slices-k1)%slices][rows-k2],
a[k1*sliceStride + k2*rowStride + 1] = Im[k1][k2]
= -Im[(slices-k1)%slices][rows-k2],
a[k1*sliceStride + (rows-k2)*rowStride + 1] = Re[(slices-k1)%slices][k2][columns/2]
= Re[k1][rows-k2][columns/2],
a[k1*sliceStride + (rows-k2)*rowStride] = -Im[(slices-k1)%slices][k2][columns/2]
= Im[k1][rows-k2][columns/2],
0<=k1<slices, 0<k2<rows/2,
a[k1*sliceStride] = Re[k1]
= Re[slices-k1],
a[k1*sliceStride + 1] = Im[k1]
= -Im[slices-k1],
a[k1*sliceStride + (rows/2)*rowStride] = Re[k1][rows/2]
= Re[slices-k1][rows/2],
a[k1*sliceStride + (rows/2)*rowStride + 1] = Im[k1][rows/2]
= -Im[slices-k1][rows/2],
a[(slices-k1)*sliceStride + 1] = Re[k1][columns/2]
= Re[slices-k1][columns/2],
a[(slices-k1)*sliceStride] = -Im[k1][columns/2]
= Im[slices-k1][columns/2],
a[(slices-k1)*sliceStride + (rows/2)*rowStride + 1] = Re[k1][rows/2][columns/2]
= Re[slices-k1][rows/2][columns/2],
a[(slices-k1)*sliceStride + (rows/2) * rowStride] = -Im[k1][rows/2][columns/2]
= Im[slices-k1][rows/2][columns/2],
0<k1<slices/2,
a = Re,
a = Re[columns/2],
a[(rows/2)*rowStride] = Re[rows/2],
a[(rows/2)*rowStride + 1] = Re[rows/2][columns/2],
a[(slices/2)*sliceStride] = Re[slices/2],
a[(slices/2)*sliceStride + 1] = Re[slices/2][columns/2],
a[(slices/2)*sliceStride + (rows/2)*rowStride] = Re[slices/2][rows/2],
a[(slices/2)*sliceStride + (rows/2)*rowStride + 1] = Re[slices/2][rows/2][columns/2]
```
This method computes only half of the elements of the real transform. The other half satisfies the symmetry condition. If you want the full real forward transform, use `realForwardFull`. To get back the original data, use `realInverse` on the output of this method.
Parameters:
`a` - data to transform
• #### realForward

`public void realForward(float[][][] a)`
Computes 3D forward DFT of real data leaving the result in `a` . This method only works when the sizes of all three dimensions are power-of-two numbers. The data is stored in a 3D array. The physical layout of the output data is as follows:
``` a[k1][k2][2*k3] = Re[k1][k2][k3]
= Re[(slices-k1)%slices][(rows-k2)%rows][columns-k3],
a[k1][k2][2*k3+1] = Im[k1][k2][k3]
= -Im[(slices-k1)%slices][(rows-k2)%rows][columns-k3],
0<=k1<slices, 0<=k2<rows, 0<k3<columns/2,
a[k1][k2] = Re[k1][k2]
= Re[(slices-k1)%slices][rows-k2],
a[k1][k2] = Im[k1][k2]
= -Im[(slices-k1)%slices][rows-k2],
a[k1][rows-k2] = Re[(slices-k1)%slices][k2][columns/2]
= Re[k1][rows-k2][columns/2],
a[k1][rows-k2] = -Im[(slices-k1)%slices][k2][columns/2]
= Im[k1][rows-k2][columns/2],
0<=k1<slices, 0<k2<rows/2,
a[k1] = Re[k1]
= Re[slices-k1],
a[k1] = Im[k1]
= -Im[slices-k1],
a[k1][rows/2] = Re[k1][rows/2]
= Re[slices-k1][rows/2],
a[k1][rows/2] = Im[k1][rows/2]
= -Im[slices-k1][rows/2],
a[slices-k1] = Re[k1][columns/2]
= Re[slices-k1][columns/2],
a[slices-k1] = -Im[k1][columns/2]
= Im[slices-k1][columns/2],
a[slices-k1][rows/2] = Re[k1][rows/2][columns/2]
= Re[slices-k1][rows/2][columns/2],
a[slices-k1][rows/2] = -Im[k1][rows/2][columns/2]
= Im[slices-k1][rows/2][columns/2],
0<k1<slices/2,
a = Re,
a = Re[columns/2],
a[rows/2] = Re[rows/2],
a[rows/2] = Re[rows/2][columns/2],
a[slices/2] = Re[slices/2],
a[slices/2] = Re[slices/2][columns/2],
a[slices/2][rows/2] = Re[slices/2][rows/2],
a[slices/2][rows/2] = Re[slices/2][rows/2][columns/2]
```
This method computes only half of the elements of the real transform. The other half satisfies the symmetry condition. If you want the full real forward transform, use `realForwardFull`. To get back the original data, use `realInverse` on the output of this method.
Parameters:
`a` - data to transform
• #### realForwardFull

`public void realForwardFull(float[] a)`
Computes 3D forward DFT of real data leaving the result in `a` . This method computes full real forward transform, i.e. you will get the same result as from `complexForward` called with all imaginary part equal 0. Because the result is stored in `a`, the input array must be of size slices*rows*2*columns, with only the first slices*rows*columns elements filled with real data. To get back the original data, use `complexInverse` on the output of this method.
Parameters:
`a` - data to transform
• #### realForwardFull

`public void realForwardFull(float[][][] a)`
Computes 3D forward DFT of real data leaving the result in `a` . This method computes full real forward transform, i.e. you will get the same result as from `complexForward` called with all imaginary part equal 0. Because the result is stored in `a`, the input array must be of size slices by rows by 2*columns, with only the first slices by rows by columns elements filled with real data. To get back the original data, use `complexInverse` on the output of this method.
Parameters:
`a` - data to transform
• #### realInverse

```public void realInverse(float[] a,
boolean scale)```
Computes 3D inverse DFT of real data leaving the result in `a` . This method only works when the sizes of all three dimensions are power-of-two numbers. The data is stored in a 1D array addressed in slice-major, then row-major, then column-major, in order of significance, i.e. element (i,j,k) of 3-d array x[slices][rows][2*columns] is stored in a[i*sliceStride + j*rowStride + k], where sliceStride = rows * 2 * columns and rowStride = 2 * columns. The physical layout of the input data has to be as follows:
``` a[k1*sliceStride + k2*rowStride + 2*k3] = Re[k1][k2][k3]
= Re[(slices-k1)%slices][(rows-k2)%rows][columns-k3],
a[k1*sliceStride + k2*rowStride + 2*k3+1] = Im[k1][k2][k3]
= -Im[(slices-k1)%slices][(rows-k2)%rows][columns-k3],
0<=k1<slices, 0<=k2<rows, 0<k3<columns/2,
a[k1*sliceStride + k2*rowStride] = Re[k1][k2]
= Re[(slices-k1)%slices][rows-k2],
a[k1*sliceStride + k2*rowStride + 1] = Im[k1][k2]
= -Im[(slices-k1)%slices][rows-k2],
a[k1*sliceStride + (rows-k2)*rowStride + 1] = Re[(slices-k1)%slices][k2][columns/2]
= Re[k1][rows-k2][columns/2],
a[k1*sliceStride + (rows-k2)*rowStride] = -Im[(slices-k1)%slices][k2][columns/2]
= Im[k1][rows-k2][columns/2],
0<=k1<slices, 0<k2<rows/2,
a[k1*sliceStride] = Re[k1]
= Re[slices-k1],
a[k1*sliceStride + 1] = Im[k1]
= -Im[slices-k1],
a[k1*sliceStride + (rows/2)*rowStride] = Re[k1][rows/2]
= Re[slices-k1][rows/2],
a[k1*sliceStride + (rows/2)*rowStride + 1] = Im[k1][rows/2]
= -Im[slices-k1][rows/2],
a[(slices-k1)*sliceStride + 1] = Re[k1][columns/2]
= Re[slices-k1][columns/2],
a[(slices-k1)*sliceStride] = -Im[k1][columns/2]
= Im[slices-k1][columns/2],
a[(slices-k1)*sliceStride + (rows/2)*rowStride + 1] = Re[k1][rows/2][columns/2]
= Re[slices-k1][rows/2][columns/2],
a[(slices-k1)*sliceStride + (rows/2) * rowStride] = -Im[k1][rows/2][columns/2]
= Im[slices-k1][rows/2][columns/2],
0<k1<slices/2,
a = Re,
a = Re[columns/2],
a[(rows/2)*rowStride] = Re[rows/2],
a[(rows/2)*rowStride + 1] = Re[rows/2][columns/2],
a[(slices/2)*sliceStride] = Re[slices/2],
a[(slices/2)*sliceStride + 1] = Re[slices/2][columns/2],
a[(slices/2)*sliceStride + (rows/2)*rowStride] = Re[slices/2][rows/2],
a[(slices/2)*sliceStride + (rows/2)*rowStride + 1] = Re[slices/2][rows/2][columns/2]
```
This method computes only half of the elements of the real transform. The other half satisfies the symmetry condition. If you want the full real inverse transform, use `realInverseFull`.
Parameters:
`a` - data to transform
`scale` - if true then scaling is performed
• #### realInverse

```public void realInverse(float[][][] a,
boolean scale)```
Computes 3D inverse DFT of real data leaving the result in `a` . This method only works when the sizes of all three dimensions are power-of-two numbers. The data is stored in a 3D array. The physical layout of the input data has to be as follows:
``` a[k1][k2][2*k3] = Re[k1][k2][k3]
= Re[(slices-k1)%slices][(rows-k2)%rows][columns-k3],
a[k1][k2][2*k3+1] = Im[k1][k2][k3]
= -Im[(slices-k1)%slices][(rows-k2)%rows][columns-k3],
0<=k1<slices, 0<=k2<rows, 0<k3<columns/2,
a[k1][k2] = Re[k1][k2]
= Re[(slices-k1)%slices][rows-k2],
a[k1][k2] = Im[k1][k2]
= -Im[(slices-k1)%slices][rows-k2],
a[k1][rows-k2] = Re[(slices-k1)%slices][k2][columns/2]
= Re[k1][rows-k2][columns/2],
a[k1][rows-k2] = -Im[(slices-k1)%slices][k2][columns/2]
= Im[k1][rows-k2][columns/2],
0<=k1<slices, 0<k2<rows/2,
a[k1] = Re[k1]
= Re[slices-k1],
a[k1] = Im[k1]
= -Im[slices-k1],
a[k1][rows/2] = Re[k1][rows/2]
= Re[slices-k1][rows/2],
a[k1][rows/2] = Im[k1][rows/2]
= -Im[slices-k1][rows/2],
a[slices-k1] = Re[k1][columns/2]
= Re[slices-k1][columns/2],
a[slices-k1] = -Im[k1][columns/2]
= Im[slices-k1][columns/2],
a[slices-k1][rows/2] = Re[k1][rows/2][columns/2]
= Re[slices-k1][rows/2][columns/2],
a[slices-k1][rows/2] = -Im[k1][rows/2][columns/2]
= Im[slices-k1][rows/2][columns/2],
0<k1<slices/2,
a = Re,
a = Re[columns/2],
a[rows/2] = Re[rows/2],
a[rows/2] = Re[rows/2][columns/2],
a[slices/2] = Re[slices/2],
a[slices/2] = Re[slices/2][columns/2],
a[slices/2][rows/2] = Re[slices/2][rows/2],
a[slices/2][rows/2] = Re[slices/2][rows/2][columns/2]
```
This method computes only half of the elements of the real transform. The other half satisfies the symmetry condition. If you want the full real inverse transform, use `realInverseFull`.
Parameters:
`a` - data to transform
`scale` - if true then scaling is performed
• #### realInverseFull

```public void realInverseFull(float[] a,
boolean scale)```
Computes 3D inverse DFT of real data leaving the result in `a` . This method computes full real inverse transform, i.e. you will get the same result as from `complexInverse` called with all imaginary part equal 0. Because the result is stored in `a`, the input array must be of size slices*rows*2*columns, with only the first slices*rows*columns elements filled with real data.
Parameters:
`a` - data to transform
`scale` - if true then scaling is performed
• #### realInverseFull

```public void realInverseFull(float[][][] a,
boolean scale)```
Computes 3D inverse DFT of real data leaving the result in `a` . This method computes full real inverse transform, i.e. you will get the same result as from `complexInverse` called with all imaginary part equal 0. Because the result is stored in `a`, the input array must be of size slices by rows by 2*columns, with only the first slices by rows by columns elements filled with real data.
Parameters:
`a` - data to transform
`scale` - if true then scaling is performed