/** * Scales n1*n2 complex numbers in the specified array by 1/nfft. * The inverse of a complex-to-complex FFT is a complex-to-complex * FFT (with opposite sign) followed by this scaling. * @param n1 the 1st dimension of the array cx. * @param n2 the 2nd dimension of the array cx. * @param cx the input/output array[n2][2*n1]. */ public void scale(int n1, int n2, float[][] cx) { for (int i2=0; i2<n2; ++i2) scale(n1,cx[i2]); }
/** * Scales n1*n2*n3 complex numbers in the specified array by 1/nfft. * The inverse of a complex-to-complex FFT is a complex-to-complex * FFT (with opposite sign) followed by this scaling. * @param n1 the 1st dimension of the array cx. * @param n2 the 2nd dimension of the array cx. * @param n3 the 3rd dimension of the array cx. * @param cx the input/output array[n3][n2][2*n1]. */ public void scale(int n1, int n2, int n3, float[][][] cx) { for (int i3=0; i3<n3; ++i3) scale(n1,n2,cx[i3]); }
if (_complex) { _fft3.complexToComplex3(-_sign3,_nfft1,_nfft2,gpad,gpad); _fft3.scale(_nfft1,_nfft2,nx3,gpad); _fft2.complexToComplex2(-_sign2,_nfft1,nx3,gpad,gpad); _fft2.scale(_nfft1,nx2,nx3,gpad); _fft1c.complexToComplex1(-_sign1,nx2,nx3,gpad,gpad); _fft1c.scale(nx1,nx2,nx3,gpad); return ccopy(nx1,nx2,nx3,gpad); } else { _fft3.complexToComplex3(-_sign3,_nfft1/2+1,_nfft2,gpad,gpad); _fft3.scale(_nfft1/2+1,_nfft2,nx3,gpad); _fft2.complexToComplex2(-_sign2,_nfft1/2+1,nx3,gpad,gpad); _fft2.scale(_nfft1/2+1,nx2,nx3,gpad); _fft1r.complexToReal1(-_sign1,nx2,nx3,gpad,gpad); _fft1r.scale(nx1,nx2,nx3,gpad);
/** * Applies an inverse frequency-to-space transform of a 2D array. * @param g the array to be transformed, a sampled function of frequency. * @return the transformed array, a sampled function of space. */ public float[][] applyInverse(float[][] g) { ensureSamplingK2(g); float[][] gpad = (_overwrite)?g:copy(g); int nx1 = _sx1.getCount(); int nx2 = _sx2.getCount(); uncenter(gpad); unphase(gpad); if (_complex) { _fft2.complexToComplex2(-_sign2,_nfft1,gpad,gpad); _fft2.scale(_nfft1,nx2,gpad); _fft1c.complexToComplex1(-_sign1,nx2,gpad,gpad); _fft1c.scale(nx1,nx2,gpad); return ccopy(nx1,nx2,gpad); } else { _fft2.complexToComplex2(-_sign2,_nfft1/2+1,gpad,gpad); _fft2.scale(_nfft1/2+1,nx2,gpad); _fft1r.complexToReal1(-_sign1,nx2,gpad,gpad); _fft1r.scale(nx1,nx2,gpad); return copy(nx1,nx2,gpad); } }
private static double time(int nfft) { double maxtime = 2.0; FftComplex fft = new FftComplex(nfft); float[] cx = crandfloat(nfft); int count; Stopwatch sw = new Stopwatch(); sw.start(); for (count=0; sw.time()<maxtime; ++count) { fft.complexToComplex(-1,cx,cx); fft.complexToComplex( 1,cx,cx); fft.scale(nfft,cx); } sw.stop(); double time = sw.time()/(float)count; return time; } }
/** * Applies an inverse frequency-to-space transform of a 1D array. * @param g the array to be transformed, a sampled function of frequency. * @return the transformed array, a sampled function of space. */ public float[] applyInverse(float[] g) { ensureSamplingK1(g); int nx1 = _sx1.getCount(); float[] gpad = (_overwrite)?g:copy(g); uncenter(gpad); unphase(gpad); if (_complex) { _fft1c.complexToComplex(-_sign1,gpad,gpad); _fft1c.scale(nx1,gpad); return ccopy(nx1,gpad); } else { _fft1r.complexToReal(-_sign1,gpad,gpad); _fft1r.scale(nx1,gpad); return copy(nx1,gpad); } }
/** * Applies inverse 2D Fourier transform to an input wavenumber-domain image. * The output space-domain image is written to the appropriate part of the * steerable pyramid array. * @param lev level number. * @param dir basis filter orientation index for the input image. * @param cf input image in wavenumber domain (complex array). * @param spyr input/output 2D steerable pyramid. */ private void ftInverse(int lev,int dir, float[][] cf,float spyr[][][][]) { FftReal fft1; FftComplex fft2; int nf2 = cf.length; int nf1c = cf[0].length/2; int nf1 = (nf1c-1)*2; int mpad = round(20.0f/(1.0f+(float)lev)); int lfactor = (int)pow(2.0,(double)lev); int nl2 = (n2-1)/lfactor+1; int nl1 = (n1-1)/lfactor+1; fft1 = new FftReal(nf1); fft2 = new FftComplex(nf2); fft2.complexToComplex2(-1,nf1c,cf,cf); flipSign(2,cf); fft2.scale(nf1c,nf2,cf); fft1.complexToReal1(-1,nf2,cf,cf); fft1.scale(nf1,nf2,cf); copy(nl1,nl2,mpad,mpad,1,1,cf,0,0,1,1,spyr[lev][dir]); }
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); }
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 test2() { 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[][] c1 = czerofloat(n1fft,n2fft); c1[1][2] = 1.0f; float[][] cx = ccopy(c1); fft1.complexToComplex1(1,n2fft,cx,cx); fft2.complexToComplex2(1,n1fft,cx,cx); float ra = 0.0f; float rb1 = 2.0f*FLT_PI/(float)n1fft; float rb2 = 2.0f*FLT_PI/(float)n2fft; float[][] amp = fillfloat(1.0f,n1fft,n2fft); float[][] phs = rampfloat(ra,rb1,rb2,n1fft,n2fft); float[][] cc = polar(amp,phs); assertEqual(cc,cx); fft1.complexToComplex1(-1,n2fft,cx,cx); fft2.complexToComplex2(-1,n1fft,cx,cx); fft1.scale(n1fft,n2fft,cx); fft2.scale(n1fft,n2fft,cx); assertEqual(c1,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); } } }
assertComplexEqual(n1fft,nw,cc,cx); fft1.complexToComplex1(-1,nw,cx,cx); fft1.scale(n1,nw,cx); fft2.complexToReal2(-1,n1,cx,rx); fft2.scale(n1,n2,rx);
assertComplexEqual(nw,n2fft,cc,cx); fft2.complexToComplex2(-1,nw,cx,cx); fft2.scale(nw,n2,cx); fft1.complexToReal1(-1,n2,cx,rx); fft1.scale(n1,n2,rx);