Changeset 16094
- Timestamp:
- Jan 15, 2008, 6:04:08 PM (18 years ago)
- Location:
- trunk/Ohana/src/opihi
- Files:
-
- 1 added
- 3 edited
-
cmd.data/fft1d.c (modified) (4 diffs)
-
include/data.h (modified) (1 diff)
-
lib.data/fft.c (modified) (1 diff)
-
lib.data/fftold.c (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Ohana/src/opihi/cmd.data/fft1d.c
r7917 r16094 3 3 int fft1d (int argc, char **argv) { 4 4 5 int i, Npix, ZeroImaginary; 6 float *t1, *t2, *temp; 5 int Npix, Nbit, ZeroImaginary; 7 6 Vector *Ire, *Iim, *Ore, *Oim; 8 7 … … 19 18 } 20 19 if ((Ire = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE); 21 if ((Ore = SelectVector (argv[4], ANYVECTOR, TRUE)) == NULL) return (FALSE); 22 if ((Oim = SelectVector (argv[5], ANYVECTOR, TRUE)) == NULL) return (FALSE); 23 20 21 // check the input data (match lengths? binary length?) 24 22 Npix = Ire[0].Nelements; 25 23 if (!ZeroImaginary && (Npix != Iim[0].Nelements)) { … … 27 25 return (FALSE); 28 26 } 29 30 if (!IsBinary (Npix)) { 27 if (!IsBinary (Npix, &Nbit)) { 31 28 gprint (GP_ERR, "Npix is not a binary number!\n"); 32 29 return (FALSE); 33 30 } 34 35 ALLOCATE (temp, float, 2*Npix);36 if (ZeroImaginary) {37 t1 = Ire[0].elements;38 for (i = 0; i < Npix; i++, t1++) {39 temp[2*i ] = *t1;40 temp[2*i+1] = 0;41 }42 } else {43 t1 = Ire[0].elements;44 t2 = Iim[0].elements;45 for (i = 0; i < Npix; i++, t1++, t2++) {46 temp[2*i ] = *t1;47 temp[2*i+1] = *t2;48 }49 }50 51 fft (temp, Npix, 1);52 31 32 // select or create the output vectors 33 if ((Ore = SelectVector (argv[4], ANYVECTOR, TRUE)) == NULL) return (FALSE); 34 if ((Oim = SelectVector (argv[5], ANYVECTOR, TRUE)) == NULL) return (FALSE); 35 36 // allocate sufficient output space 53 37 Ore[0].Nelements = Npix; 54 38 Oim[0].Nelements = Npix; … … 56 40 REALLOCATE (Oim[0].elements, float, Npix); 57 41 58 t1 = Ore[0].elements; 59 t2 = Oim[0].elements; 60 for (i = 0; i < Npix; i++, t1++, t2++) { 61 *t1 = temp[2*i ] / Npix; 62 *t2 = temp[2*i+1] / Npix; 42 // copy data to output vectors (fft is done in place) 43 memcpy (Ore[0].elements, Ire[0].elements, Npix*sizeof(float)); 44 45 // copy imaginary vector or create a zero vector 46 if (ZeroImaginary) { 47 memset (Oim[0].elements, 0, Npix*sizeof(float)); 48 } else { 49 memcpy (Oim[0].elements, Iim[0].elements, Npix*sizeof(float)); 63 50 } 64 65 f ree (temp);51 52 fft (Ore[0].elements, Oim[0].elements, Npix, Nbit); 66 53 67 54 return (TRUE); 68 55 } 69 70 -
trunk/Ohana/src/opihi/include/data.h
r15274 r16094 84 84 85 85 /* in fft.c */ 86 void fft (float *Data, int N, int isign); 87 void fftold (float *Data, int N, int isign); 86 void fft (float *dataRe, float *dataIm, int N, int Nbit); 88 87 void fftN (float *data, int *nn, int ndim, int isign); 89 88 int IsBinary (int N); -
trunk/Ohana/src/opihi/lib.data/fft.c
r2598 r16094 1 1 # include "data.h" 2 2 3 #define FSWAP(a,b) tempr=(a);(a)=(b);(b)=tempr 4 5 void fft (float *Data, int N, int isign) { 6 7 int n,mmax,m,j,istep,i; 8 double wtemp,wr,wpr,wpi,wi,theta; 9 float tempr,tempi, *data; 10 11 data = Data; 12 n = N << 1; 13 j = 0; 14 15 for (i = 0; i < n; i+=2) { 16 if (j > i) { 17 FSWAP (data[j], data[i]); 18 FSWAP (data[j+1], data[i+1]); 19 } 20 m = n >> 1; 21 while (m >= 2 && j >= m) { 22 j -= m; 23 m >>= 1; 24 } 25 j += m; 26 } 27 mmax = 2; 28 while (n > mmax) { 29 istep = 2*mmax; 30 theta = 6.28318530717959 / (isign*mmax); 31 wtemp = sin(0.5*theta); 32 wpr = -2.0*wtemp*wtemp; 33 wpi = sin(theta); 34 wr = 1.0; 35 wi = 0.0; 36 for (m = 0; m < mmax; m+=2) { 37 for (i = m; i < n; i+=istep) { 38 j = i + mmax; 39 tempr = wr*data[j] - wi*data[j+1]; 40 tempi = wr*data[j+1] + wi*data[j]; 41 data[j] = data[i] - tempr; 42 data[j+1] = data[i+1] - tempi; 43 data[i] += tempr; 44 data[i+1] += tempi; 45 } 46 wr = (wtemp = wr)*wpr - wi*wpi+wr; 47 wi = wi*wpr + wtemp*wpi + wi; 48 } 49 mmax = istep; 50 } 3 // fft based on code by Douglas L. Jones (see note at EOF). modified for Ohana C style 4 void fftN (float *data, int *nn, int ndim, int isign) { 5 6 fprintf (stderr, "broken\n"); 7 return; 51 8 } 52 9 53 void fft old (float *Data, int N, int isign) {10 void fft (double *x, double *y, int n, int Nbit) { 54 11 55 int n,mmax,m,j,istep,i; 56 double wtemp,wr,wpr,wpi,wi,theta; 57 float tempr,tempi, *data; 12 int i,j,k,n1,n2; 13 double c,s,e,a,t1,t2; 14 15 // bit-reverse 16 j = 0; 17 n2 = n/2; 18 for (i = 1; i < n - 1; i++) { 19 n1 = n2; 20 while ( j >= n1 ) { 21 j = j - n1; 22 n1 = n1/2; 23 } 24 j = j + n1; 25 26 if (i < j) { 27 t1 = x[i]; 28 x[i] = x[j]; 29 x[j] = t1; 30 t1 = y[i]; 31 y[i] = y[j]; 32 y[j] = t1; 33 } 34 } 35 36 37 n1 = 0; /* FFT */ 38 n2 = 1; 39 40 for (i=0; i < Nbit; i++) { 41 n1 = n2; 42 n2 = n2 + n2; 43 e = -6.283185307179586/n2; 44 a = 0.0; 45 46 for (j=0; j < n1; j++) { 47 c = cos(a); 48 s = sin(a); 49 a = a + e; 50 51 for (k=j; k < n; k=k+n2) { 52 t1 = c*x[k+n1] - s*y[k+n1]; 53 t2 = s*x[k+n1] + c*y[k+n1]; 54 x[k+n1] = x[k] - t1; 55 y[k+n1] = y[k] - t2; 56 x[k] = x[k] + t1; 57 y[k] = y[k] + t2; 58 } 59 } 60 } 61 62 return; 63 } 58 64 59 data = Data - 1; 60 n = N << 1; 61 j = 1; 65 int IsBinary (int N, int *nbin) { 62 66 63 for (i = 1; i < n; i+=2) { 64 if (j > i) { 65 FSWAP (data[j], data[i]); 66 FSWAP (data[j+1], data[i+1]); 67 // check that a number is binary (2^nbit) 68 69 Nbit = 0; 70 Nset = 0; 71 for (i = 0; i < 8*sizeof(int); i++) { 72 if (N & 0x01) { 73 Nset ++; 74 Nbin = i; 67 75 } 68 m = n >> 1; 69 while (m >= 2 && j > m) { 70 j -= m; 71 m >>= 1; 72 } 73 j += m; 76 N >>= 1; 74 77 } 75 mmax = 2; 76 while (n > mmax) { 77 istep = 2*mmax; 78 theta = 6.28318530717959 / (isign*mmax); 79 wtemp = sin(0.5*theta); 80 wpr = -2.0*wtemp*wtemp; 81 wpi = sin(theta); 82 wr = 1.0; 83 wi = 0.0; 84 for (m = 1; m < mmax; m+=2) { 85 for (i = m; i <= n; i+=istep) { 86 j = i + mmax; 87 tempr = wr*data[j] - wi*data[j+1]; 88 tempi = wr*data[j+1] + wi*data[j]; 89 data[j] = data[i] - tempr; 90 data[j+1] = data[i+1] - tempi; 91 data[i] += tempr; 92 data[i+1] += tempi; 93 } 94 wr = (wtemp = wr)*wpr - wi*wpi+wr; 95 wi = wi*wpr + wtemp*wpi + wi; 96 } 97 mmax = istep; 98 } 78 *nbin = Nbit; 79 if (Nset > 1) return (FALSE); 99 80 } 100 81 101 /* convert indices to zero reference */ 102 void fftN (float *data, int *nn, int ndim, int isign) { 82 /**********************************************************/ 83 /* fft.c */ 84 /* (c) Douglas L. Jones */ 85 /* University of Illinois at Urbana-Champaign */ 86 /* January 19, 1992 */ 87 /* */ 88 /* fft: in-place radix-2 DIT DFT of a complex input */ 89 /* */ 90 /* input: */ 91 /* n: length of FFT: must be a power of two */ 92 /* m: n = 2**m */ 93 /* input/output */ 94 /* x: double array of length n with real part of data */ 95 /* y: double array of length n with imag part of data */ 96 /* */ 97 /* Permission to copy and use this program is granted */ 98 /* under a Creative Commons "Attribution" license */ 99 /* http://creativecommons.org/licenses/by/1.0/ */ 100 /**********************************************************/ 103 101 104 int i1,i2,i3,i2rev,i3rev,ip1,ip2,ip3,ifp1,ifp2;105 int ibit,idim,k1,k2,n,nprev,nrem,ntot;106 float tempi,tempr;107 double theta,wi,wpi,wpr,wr,wtemp;108 109 ntot = 1;110 for (idim = 0; idim < ndim; idim++) ntot *= nn[idim];111 112 nprev = 1;113 for (idim = ndim - 1; idim >= 0; idim--) {114 n = nn[idim];115 nrem = ntot / (n*nprev);116 ip1 = nprev << 1;117 ip2 = ip1*n;118 ip3 = ip2*nrem;119 i2rev = 0;120 for (i2 = 0; i2 < ip2; i2+=ip1) {121 if (i2 < i2rev) {122 for (i1 = i2; i1 <= i2+ip1-2; i1+=2) {123 for (i3 = i1; i3 < ip3; i3+=ip2) {124 i3rev = i2rev+i3-i2;125 FSWAP(data[i3],data[i3rev]);126 FSWAP(data[i3+1],data[i3rev+1]);127 }128 }129 }130 ibit = ip2 >> 1;131 while (ibit >= ip1 && i2rev >= ibit) {132 i2rev -= ibit;133 ibit >>= 1;134 }135 i2rev += ibit;136 }137 ifp1 = ip1;138 while (ifp1 < ip2) {139 ifp2 = ifp1 << 1;140 theta = isign*6.28318530717959/(ifp2/ip1);141 wtemp = sin(0.5*theta);142 wpr = -2.0*wtemp*wtemp;143 wpi = sin(theta);144 wr = 1.0;145 wi = 0.0;146 for (i3 = 0; i3 < ifp1; i3+=ip1) {147 for (i1 = i3; i1 <= i3+ip1-2; i1+=2) {148 for (i2 = i1; i2 < ip3; i2+=ifp2) {149 k1 = i2;150 k2 = k1+ifp1;151 tempr = wr*data[k2]-wi*data[k2+1];152 tempi = wr*data[k2+1]+wi*data[k2];153 data[k2] = data[k1]-tempr;154 data[k2+1] = data[k1+1]-tempi;155 data[k1] += tempr;156 data[k1+1] += tempi;157 }158 }159 wr = (wtemp = wr)*wpr-wi*wpi+wr;160 wi = wi*wpr+wtemp*wpi+wi;161 }162 ifp1 = ifp2;163 }164 nprev *= n;165 }166 }167 168 #undef FSWAP169 170 /* based on the PRESS routine, this fft takes an array from data[0] to data[2N-1] */171 /* this function takes Data = h(t) and replaces it in situ with H(F) or vice versa.172 There are assumed to be 2*N input values with173 Data[0,2,4,...] the real and Data[1,3,5,...] the imaginary ones.174 the output is ordered the same.175 176 for h(t), values are in time sequence order.177 for H(F), values are in order F = 0, 1/N, ... 1/2 - 1/N, +/- 1/2, -1/2 + 1/N, ... -1/N178 179 no normalization is performed, so a signal of amplitude A sin (w_k * t) will be180 give an H(F) value of 0.5 * A * N, and the DC term will have H(0) = A * N.181 182 */183 184 int IsBinary (int N) {185 186 int i, nbit;187 188 /* check if number is a binary number */189 nbit = 0;190 for (i = 0; i < 8*sizeof(N); i++) {191 nbit += (N & 0x01);192 N = (N >> 1);193 }194 if (nbit == 1) {195 return (1);196 } else {197 return (0);198 }199 200 }201 202 #define FSWAP(a,b) tempr=(a);(a)=(b);(b)=tempr203 204 void fourn (float *data, int *nn, int ndim, int isign) {205 206 int i1,i2,i3,i2rev,i3rev,ip1,ip2,ip3,ifp1,ifp2;207 int ibit,idim,k1,k2,n,nprev,nrem,ntot;208 float tempi,tempr;209 double theta,wi,wpi,wpr,wr,wtemp;210 211 ntot = 1;212 for (idim = 1; idim <= ndim; idim++)213 ntot *= nn[idim];214 nprev = 1;215 for (idim = ndim; idim >= 1; idim--) {216 n = nn[idim];217 nrem = ntot/(n*nprev);218 ip1 = nprev << 1;219 ip2 = ip1*n;220 ip3 = ip2*nrem;221 i2rev = 1;222 for (i2 = 1; i2 <= ip2; i2+=ip1) {223 if (i2 < i2rev) {224 for (i1 = i2; i1 <= i2+ip1-2; i1+=2) {225 for (i3 = i1; i3 <= ip3;i3+=ip2) {226 i3rev = i2rev+i3-i2;227 FSWAP(data[i3],data[i3rev]);228 FSWAP(data[i3+1],data[i3rev+1]);229 }230 }231 }232 ibit = ip2 >> 1;233 while (ibit >= ip1 && i2rev > ibit) {234 i2rev -= ibit;235 ibit >>= 1;236 }237 i2rev += ibit;238 }239 ifp1 = ip1;240 while (ifp1 < ip2) {241 ifp2 = ifp1 << 1;242 theta = isign*6.28318530717959/(ifp2/ip1);243 wtemp = sin(0.5*theta);244 wpr = -2.0*wtemp*wtemp;245 wpi = sin(theta);246 wr = 1.0;247 wi = 0.0;248 for (i3 = 1;i3<=ifp1;i3+=ip1) {249 for (i1 = i3;i1<=i3+ip1-2;i1+=2) {250 for (i2 = i1;i2<=ip3;i2+=ifp2) {251 k1 = i2;252 k2 = k1+ifp1;253 tempr = wr*data[k2]-wi*data[k2+1];254 tempi = wr*data[k2+1]+wi*data[k2];255 data[k2] = data[k1]-tempr;256 data[k2+1] = data[k1+1]-tempi;257 data[k1] += tempr;258 data[k1+1] += tempi;259 }260 }261 wr = (wtemp = wr)*wpr-wi*wpi+wr;262 wi = wi*wpr+wtemp*wpi+wi;263 }264 ifp1 = ifp2;265 }266 nprev *= n;267 }268 }269 270 #undef FSWAP
Note:
See TracChangeset
for help on using the changeset viewer.
