jnt.FFT.RealFloat2DFFT_Even Maven / Gradle / Ivy
Show all versions of sspace Show documentation
package jnt.FFT;
/** EXPERIMENTAL! (till I think of something better):
* Computes the FFT of 2 dimensional real, single precision data.
* The data is stored in a 1-dimensional array in almost Row-Major order.
* The number of columns MUST be even, and there must be two extra elements per row!
* The physical layout in the real input data array, of the mathematical data d[i,j] is
* as follows:
*
* d[i,j]) = data[i*rowspan+j]
*
* where rowspan >= ncols+2.
*WARNING! Note that rowspan must be greater than the number of columns,
* and the next 2 values, as well as the data itself, are overwritten in
* order to store enough of the complex transformation in place.
* (In fact, it can be done completely in place, but where one has to look for various
* real and imaginary parts is quite complicated).
*
* The physical layout in the transformed (complex) array data, of the
* mathematical data D[i,j] is as follows:
*
* Re(D[i,j]) = data[2*(i*rowspan+j)]
* Im(D[i,j]) = data[2*(i*rowspan+j)+1]
*
*
* The transformed data in each row is complex for frequencies from
* 0, 1/(n delta), ... 1/(2 delta), where delta is the time difference between
* the column values.
*
* The transformed data for columns is in `wrap-around' order; that is from
* 0, 1/(n delta)... +/- 1/(2 delta) ... -1/(n delta)
* @author Bruce R. Miller [email protected]
* @author Contribution of the National Institute of Standards and Technology,
* @author not subject to copyright.
*/
public class RealFloat2DFFT_Even {
int nrows;
int ncols;
int rowspan;
ComplexFloatFFT rowFFT, colFFT;
/** Create an FFT for transforming nrows*ncols points of Complex, double precision
* data. */
public RealFloat2DFFT_Even(int nrows, int ncols) {
this.nrows = nrows;
this.ncols = ncols;
rowspan = ncols+2;
if (ncols%2 != 0)
throw new Error("The number of columns must be even!");
rowFFT = new ComplexFloatFFT_Mixed(ncols/2);
colFFT = (nrows == (ncols/2) ? rowFFT : new ComplexFloatFFT_Mixed(nrows));
}
protected void checkData(float data[], int rowspan){
if (rowspan < ncols+2)
throw new IllegalArgumentException("The row span "+rowspan+
"is not long enough for ncols="+ncols);
if (nrows*rowspan > data.length)
throw new IllegalArgumentException("The data array is too small for "+
nrows+"x"+rowspan+" data.length="+data.length);}
/** Compute the Fast Fourier Transform of data leaving the result in data. */
public void transform(float data[]) {
transform(data,ncols+2); }
/** Compute the Fast Fourier Transform of data leaving the result in data. */
public void transform(float data[], int rowspan) {
checkData(data,rowspan);
for(int i=0; iwraparound format */
public float[] toWraparoundOrder(float data[], int rowspan){
float newdata[] = new float[2*nrows*ncols];
int nc = ncols/2;
for(int i=0; i