final protected static boolean verifyComplexToComplexfftDimensions( final int inputSize, final int outputSize) { if (FftComplex.nfftFast(inputSize) == outputSize || FftComplex.nfftSmall(inputSize) == outputSize) return true; return false; }
final protected static boolean verifyComplexToComplexfftDimensions( final int inputSize, final int outputSize ) { if ( FftComplex.nfftFast( inputSize ) == outputSize || FftComplex.nfftSmall( inputSize ) == outputSize ) return true; return false; } }
/** * Computes the supported dimensionality of an input dataset (of complex numbers) for a forward/inverse FFT of the entire dataset AS SMALL AS POSSIBLE * * @param inputDimensions - the dimensions of the input * @param paddedDimensions - the required dimensions of the input/output (computed) */ final static public void dimensionsComplexToComplexSmall( final Dimensions inputDimensions, final long[] paddedDimensions ) { for ( int d = 0; d < inputDimensions.numDimensions(); ++d ) paddedDimensions[ d ] = FftComplex.nfftSmall( (int)inputDimensions.dimension( d ) ); }
public static void main(String[] args) { for (int niter=0; niter<5; ++niter) { for (int nfft=1; nfft<=720720;) { int nfftSmall = FftComplex.nfftSmall(nfft); int nfftFast = FftComplex.nfftFast(nfft); double timeSmall = time(nfftSmall); if (nfftFast==nfftSmall) { System.out.printf("nsmall=%d tsmall=%.14f\n",nfftSmall,timeSmall); } else { double timeFast = (nfftFast>nfftSmall)?time(nfftFast):timeSmall; System.out.printf("nsmall=%d tsmall=%.14f tfast=%.14f\n", nfftSmall,timeSmall,timeFast); if (timeSmall<timeFast) System.out.println("*** WARNING: tsmall<tfast! ***"); } nfft = 1+nfftSmall; } } }
/** * Computes the supported dimensionality of an input dataset (of complex * numbers) for a forward/inverse FFT of the entire dataset AS SMALL AS * POSSIBLE * * @param inputDimensions - the dimensions of the input * @param paddedDimensions - the required dimensions of the input/output * (computed) */ final static public void dimensionsComplexToComplexSmall( final Dimensions inputDimensions, final long[] paddedDimensions) { for (int d = 0; d < inputDimensions.numDimensions(); ++d) paddedDimensions[d] = FftComplex.nfftSmall((int) inputDimensions.dimension(d)); }
protected int[] getZeroPaddingSize( final int[] imageSize, final FFTOptimization fftOptimization ) { final int[] fftSize = new int[ imageSize.length ]; // the first dimension is real to complex if ( fftOptimization == FFTOptimization.SPEED ) fftSize[ 0 ] = FftReal.nfftFast( imageSize[ 0 ] ); else fftSize[ 0 ] = FftReal.nfftSmall( imageSize[ 0 ] ); // all the other dimensions complex to complex for ( int d = 1; d < fftSize.length; ++d ) { if ( fftOptimization == FFTOptimization.SPEED ) fftSize[ d ] = FftComplex.nfftFast( imageSize[ d ] ); else fftSize[ d ] = FftComplex.nfftSmall( imageSize[ d ] ); } return fftSize; }
protected int[] getZeroPaddingSize( final int[] imageSize, final FFTOptimization fftOptimization ) { final int[] fftSize = new int[ imageSize.length ]; // the first dimension is real to complex if ( fftOptimization == FFTOptimization.SPEED ) fftSize[ 0 ] = FftReal.nfftFast( imageSize[ 0 ] ); else fftSize[ 0 ] = FftReal.nfftSmall( imageSize[ 0 ] ); // all the other dimensions complex to complex for ( int d = 1; d < fftSize.length; ++d ) { if ( fftOptimization == FFTOptimization.SPEED ) fftSize[ d ] = FftComplex.nfftFast( imageSize[ d ] ); else fftSize[ d ] = FftComplex.nfftSmall( imageSize[ d ] ); } return fftSize; }
/** * Computes the supported dimensionality of an input dataset (of real numbers) for a forward FFT of the entire dataset AS SMALL AS POSSIBLE * * @param inputDimensions - the dimensions of the real-valued input * @param paddedDimensions - the required dimensions of the real-valued input (computed) * @param fftDimensions - the dimensions of the complex-valued fft after the fast fourier transform (computed), i.e. which dimensions are required for the output */ final static public void dimensionsRealToComplexSmall( final Dimensions inputDimensions, final long[] paddedDimensions, final long[] fftDimensions ) { paddedDimensions[ 0 ] = FftReal.nfftSmall( (int)inputDimensions.dimension( 0 ) ); fftDimensions[ 0 ] = ( paddedDimensions[ 0 ] / 2 + 1 ); for ( int d = 1; d < inputDimensions.numDimensions(); ++d ) fftDimensions[ d ] = paddedDimensions[ d ] = FftComplex.nfftSmall( (int)inputDimensions.dimension( d ) ); }
/** * Computes the supported dimensionality of an input dataset (of complex numbers) for an inverse FFT of the entire dataset AS SMALL AS POSSIBLE * * @param inputDimensions - the dimensions of the complex-valued input * @param paddedDimensions - the required dimensions of the complex-valued input (computed) * @param realSize - the dimensions of the real-valued output after the inverse fast fourier transform (computed), i.e. which dimensions are required for the output */ final static public void dimensionsComplexToRealSmall( final Dimensions inputDimensions, final long[] paddedDimensions, final long[] realSize ) { // compute what the dimensionality corresponds to in real-valued pixels final int d0 = ( (int)inputDimensions.dimension( 0 ) - 1 ) * 2; // compute which dimensionality we could get from that paddedDimensions[ 0 ] = FftReal.nfftSmall( d0 ) / 2 + 1; // and which final dimensionality this will give in real space realSize[ 0 ] = ( paddedDimensions[ 0 ] - 1 ) * 2; for ( int d = 1; d < inputDimensions.numDimensions(); ++d ) realSize[ d ] = paddedDimensions[ d ] = FftComplex.nfftSmall( (int)inputDimensions.dimension( d ) ); }
/** * Computes the supported dimensionality of an input dataset (of real numbers) * for a forward FFT of the entire dataset AS SMALL AS POSSIBLE * * @param inputDimensions - the dimensions of the real-valued input * @param paddedDimensions - the required dimensions of the real-valued input * (computed) * @param fftDimensions - the dimensions of the complex-valued fft after the * fast fourier transform (computed), i.e. which dimensions are * required for the output */ final static public void dimensionsRealToComplexSmall( final Dimensions inputDimensions, final long[] paddedDimensions, final long[] fftDimensions) { paddedDimensions[0] = FftReal.nfftSmall((int) inputDimensions.dimension(0)); fftDimensions[0] = (paddedDimensions[0] / 2 + 1); for (int d = 1; d < inputDimensions.numDimensions(); ++d) fftDimensions[d] = paddedDimensions[d] = FftComplex.nfftSmall((int) inputDimensions.dimension(d)); }
private void updateSampling3() { if (_sx3==null) return; int nx = _sx3.getCount(); double dx = _sx3.getDelta(); int npad = nx+_padding3; int nfft = FftComplex.nfftSmall(npad); double dk = 1.0/(nfft*dx); double fk; int nk; if (_center3) { boolean even = nfft%2==0; nk = even?nfft+1:nfft; fk = even?-0.5/dx:-0.5/dx+0.5*dk; } else { nk = nfft; fk = 0.0; } if (_fft3==null || _nfft3!=nfft) { _fft3 = new FftComplex(nfft); _nfft3 = nfft; } _sk3 = new Sampling(nk,dk,fk); //trace("sk3: nfft="+nfft+" nk="+nk+" dk="+dk+" fk="+fk); }
/** * Computes the supported dimensionality of an input dataset (of complex * numbers) for an inverse FFT of the entire dataset AS SMALL AS POSSIBLE * * @param inputDimensions - the dimensions of the complex-valued input * @param paddedDimensions - the required dimensions of the complex-valued * input (computed) * @param realSize - the dimensions of the real-valued output after the * inverse fast fourier transform (computed), i.e. which dimensions * are required for the output */ final static public void dimensionsComplexToRealSmall( final Dimensions inputDimensions, final long[] paddedDimensions, final long[] realSize) { // compute what the dimensionality corresponds to in real-valued pixels final int d0 = ((int) inputDimensions.dimension(0) - 1) * 2; // compute which dimensionality we could get from that paddedDimensions[0] = FftReal.nfftSmall(d0) / 2 + 1; // and which final dimensionality this will give in real space realSize[0] = (paddedDimensions[0] - 1) * 2; for (int d = 1; d < inputDimensions.numDimensions(); ++d) realSize[d] = paddedDimensions[d] = FftComplex.nfftSmall((int) inputDimensions.dimension(d)); }
private void updateSampling2() { if (_sx2==null) return; int nx = _sx2.getCount(); double dx = _sx2.getDelta(); int npad = nx+_padding2; int nfft = FftComplex.nfftSmall(npad); double dk = 1.0/(nfft*dx); double fk; int nk; if (_center2) { boolean even = nfft%2==0; nk = even?nfft+1:nfft; fk = even?-0.5/dx:-0.5/dx+0.5*dk; } else { nk = nfft; fk = 0.0; } if (_fft2==null || _nfft2!=nfft) { _fft2 = new FftComplex(nfft); _nfft2 = nfft; } _sk2 = new Sampling(nk,dk,fk); //trace("sk2: nfft="+nfft+" nk="+nk+" dk="+dk+" fk="+fk); } private void updateSampling3() {
public void test3Random() { int n1 = 11; int n2 = 12; int n3 = 13; int n1fft = FftComplex.nfftSmall(n1); int n2fft = FftComplex.nfftSmall(n2); int n3fft = FftComplex.nfftSmall(n3); FftComplex fft1 = new FftComplex(n1fft); FftComplex fft2 = new FftComplex(n2fft); FftComplex fft3 = new FftComplex(n3fft); float[][][] cr = crandfloat(n1fft,n2fft,n3fft); float[][][] cx = ccopy(cr); fft1.complexToComplex1( 1,n2fft,n3fft,cx,cx); fft2.complexToComplex2( 1,n1fft,n3fft,cx,cx); fft3.complexToComplex3( 1,n1fft,n2fft,cx,cx); fft1.complexToComplex1(-1,n2fft,n3fft,cx,cx); fft2.complexToComplex2(-1,n1fft,n3fft,cx,cx); fft3.complexToComplex3(-1,n1fft,n2fft,cx,cx); fft1.scale(n1fft,n2fft,n3fft,cx); fft2.scale(n1fft,n2fft,n3fft,cx); fft3.scale(n1fft,n2fft,n3fft,cx); assertEqual(cr,cx); }
/** * Applies forward 2D Fourier transform. * @param level level number. * @param x input 2D image. * @return a 2D complex array, which is the forward 2D Fourier transform of * the input image. */ private float[][] ftForward(int level, float[][] x) { FftReal fft1; FftComplex fft2; int ny2 = x.length; int ny1 = x[0].length; int mpad = round(20.0f/(1.0f+(float)level)); int lfactor = (int)pow(2.0,(double)level); int nl2 = (n2-1)/lfactor+1; int nl1 = (n1-1)/lfactor+1; int nf1 = FftReal.nfftSmall(nl1+mpad*2); int nf1c = nf1/2+1; int nf2 = FftComplex.nfftSmall(nl2+mpad*2); float[][] xr = zerofloat(nf1,nf2); copy(ny1,ny2,0,0,x,mpad,mpad,xr); float[][] cx = czerofloat(nf1c,nf2); fft1 = new FftReal(nf1); fft2 = new FftComplex(nf2); fft1.realToComplex1(1,nf2,xr,cx); flipSign(2,cx); fft2.complexToComplex2(1,nf1c,cx,cx); return cx; }
public void test2Random() { int n1max = 26; int n2max = 26; for (int n2=2; n2<n2max; ++n2) { int n2fft = FftComplex.nfftSmall(n2); FftComplex fft2 = new FftComplex(n2fft); for (int n1=2; n1<n1max; ++n1) { int n1fft = FftComplex.nfftSmall(n1); FftComplex fft1 = new FftComplex(n1fft); float[][] cr = crandfloat(n1fft,n2fft); float[][] cx = ccopy(cr); float[][] cy = czerofloat(n1fft,n2fft); fft1.complexToComplex1( 1,n2fft,cx,cy); fft2.complexToComplex2( 1,n1fft,cy,cy); fft1.complexToComplex1(-1,n2fft,cy,cx); fft2.complexToComplex2(-1,n1fft,cx,cx); fft1.scale(n1fft,n2fft,cx); fft2.scale(n1fft,n2fft,cx); assertEqual(cr,cx); } } }
public void test1Random() { int nmax = 1000; for (int n=2; n<nmax; ++n) { int nfft = FftComplex.nfftSmall(n); FftComplex fft = new FftComplex(nfft); float[] cr = crandfloat(nfft); float[] cx = ccopy(cr); float[] cy = czerofloat(nfft); fft.complexToComplex( 1,cx,cy); fft.complexToComplex(-1,cy,cx); fft.scale(nfft,cx); assertEqual(cr,cx); } }
public void test1() { int nmax = 1000; for (int n=2; n<nmax; ++n) { int nfft = FftComplex.nfftSmall(n); FftComplex fft = new FftComplex(nfft); float[] c1 = czerofloat(nfft); c1[2] = 1.0f; float[] cx = ccopy(c1); fft.complexToComplex(1,cx,cx); float ra = 0.0f; float rb = 2.0f*FLT_PI/(float)nfft; float[] amp = fillfloat(1.0f,nfft); float[] phs = rampfloat(ra,rb,nfft); float[] cc = polar(amp,phs); assertEqual(cc,cx); fft.complexToComplex(-1,cx,cx); fft.scale(nfft,cx); assertEqual(c1,cx); } }
public void test12Random() { int n1max = 26; int n2max = 26; for (int n2=2; n2<n2max; ++n2) { int n2fft = FftComplex.nfftSmall(n2); FftComplex fft2 = new FftComplex(n2fft); for (int n1=2; n1<n1max; ++n1) { int n1fft = FftReal.nfftSmall(n1); FftReal fft1 = new FftReal(n1fft); int nw = n1fft/2+1; float[][] rr = randfloat(n1fft,n2); float[][] rx = copy(rr); float[][] cy = czerofloat(nw,n2fft); fft1.realToComplex1( 1,n2,rx,cy); fft2.complexToComplex2( 1,nw,cy,cy); fft2.complexToComplex2(-1,nw,cy,cy); fft2.scale(nw,n2,cy); fft1.complexToReal1(-1,n2,cy,rx); fft1.scale(n1,n2,rx); assertRealEqual(n1,n2,rr,rx); } } }
public void test21Random() { int n1max = 26; int n2max = 26; for (int n2=2; n2<n2max; ++n2) { int n2fft = FftReal.nfftSmall(n2); FftReal fft2 = new FftReal(n2fft); int nw = n2fft/2+1; for (int n1=2; n1<n1max; ++n1) { int n1fft = FftComplex.nfftSmall(n1); FftComplex fft1 = new FftComplex(n1fft); float[][] rr = randfloat(n1,n2fft); float[][] rx = copy(rr); float[][] cy = czerofloat(n1fft,nw); fft2.realToComplex2( 1,n1,rx,cy); fft1.complexToComplex1( 1,nw,cy,cy); fft1.complexToComplex1(-1,nw,cy,cy); fft1.scale(n1,nw,cy); fft2.complexToReal2(-1,n1,cy,rx); fft2.scale(n1,n2,rx); assertRealEqual(n1,n2,rr,rx); } } }