Changeset 20936 for trunk/Ohana/src/opihi/lib.data/fft.c
- Timestamp:
- Dec 7, 2008, 3:31:01 PM (18 years ago)
- File:
-
- 1 edited
-
trunk/Ohana/src/opihi/lib.data/fft.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Ohana/src/opihi/lib.data/fft.c
r17902 r20936 133 133 } 134 134 135 // fft based on code by Douglas L. Jones (see note at EOF). modified for Ohana C style 136 void dfft1D (double *x, double *y, int n, int Nbit, int forward) { 137 138 int i,j,k,n1,n2; 139 double c,s,e,a,t1,t2; 140 double factor; 141 142 // bit-reverse 143 j = 0; 144 n2 = n/2; 145 for (i = 1; i < n - 1; i++) { 146 n1 = n2; 147 while ( j >= n1 ) { 148 j -= n1; 149 n1 /= 2; 150 } 151 j += n1; 152 153 if (i < j) { 154 t1 = x[i]; 155 x[i] = x[j]; 156 x[j] = t1; 157 t1 = y[i]; 158 y[i] = y[j]; 159 y[j] = t1; 160 } 161 } 162 163 n1 = 0; /* FFT */ 164 n2 = 1; 165 166 if (forward) { 167 factor = +2.0*M_PI; 168 } else { 169 factor = -2.0*M_PI; 170 } 171 172 for (i=0; i < Nbit; i++) { 173 n1 = n2; 174 n2 = n2 + n2; 175 e = factor/n2; 176 a = 0.0; 177 178 for (j=0; j < n1; j++) { 179 c = cos(a); 180 s = sin(a); 181 a = a + e; 182 183 for (k=j; k < n; k=k+n2) { 184 t1 = c*x[k+n1] - s*y[k+n1]; 185 t2 = s*x[k+n1] + c*y[k+n1]; 186 x[k+n1] = x[k] - t1; 187 y[k+n1] = y[k] - t2; 188 x[k] = x[k] + t1; 189 y[k] = y[k] + t2; 190 } 191 } 192 } 193 194 // re-normalize 195 for (i = 0; i < n; i++) { 196 x[i] /= n; 197 y[i] /= n; 198 } 199 200 return; 201 } 202 203 // This implementation uses the 1-D fft above for each of the vectors in each dimension. 204 // This requires 2(Nx*Ny*...) mem copies, but the fft operations are likely to happen in 205 // cache. 206 int dfftND (double *x, double *y, int Ndim, int *Nsize, int forward) { 207 208 int i, nIndex, minor, major, iDim; 209 int step, Nmajor, Nminor, Nmax, Ntotal; 210 int *Nbit; 211 double *tmpX, *tmpY; 212 213 ALLOCATE (Nbit, int, Ndim); 214 215 // find the longest axis and allocate storage for that length 216 Nmax = 0; 217 Ntotal = 1; 218 for (i = 0; i < Ndim; i++) { 219 Nmax = MAX(Nmax, Nsize[i]); 220 Ntotal *= Nsize[i]; 221 if (!IsBinary (Nsize[i], &Nbit[i])) { 222 free (Nbit); 223 return (FALSE); 224 } 225 } 226 ALLOCATE (tmpX, double, Nmax); 227 ALLOCATE (tmpY, double, Nmax); 228 229 step = 1; 230 Nminor = 1; 231 Nmajor = Ntotal; 232 for (iDim = 0; iDim < Ndim; iDim++) { 233 step *= Nsize[iDim]; 234 Nmajor /= Nsize[iDim]; 235 236 // we perform the FFT along all other dimensions 237 for (major = 0; major < Nmajor; major++) { 238 for (minor = 0; minor < Nminor; minor++) { 239 // nIndex = minor + i*Nminor + major*step; 240 // extract the data values to the temp vector 241 nIndex = minor + major*step; 242 for (i = 0; i < Nsize[iDim]; i++) { 243 tmpX[i] = x[nIndex]; 244 tmpY[i] = y[nIndex]; 245 nIndex += Nminor; 246 } 247 248 dfft1D (tmpX, tmpY, Nsize[iDim], Nbit[iDim], forward); 249 250 // replace the result vectors 251 nIndex = minor + major*step; 252 for (i = 0; i < Nsize[iDim]; i++) { 253 x[nIndex] = tmpX[i]; 254 y[nIndex] = tmpY[i]; 255 nIndex += Nminor; 256 } 257 } 258 } 259 Nminor *= Nsize[iDim]; 260 } 261 free (Nbit); 262 free (tmpX); 263 free (tmpY); 264 return (TRUE); 265 } 266 135 267 // check that a number is binary (2^Nbit). returns int(log_2(N)) in Nbit 136 268 int IsBinary (int N, int *Nbit) {
Note:
See TracChangeset
for help on using the changeset viewer.
