IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Dec 7, 2008, 3:31:01 PM (18 years ago)
Author:
eugene
Message:

big update from eam_branch_20081124 with updates to Opihi math

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/opihi/lib.data/fft.c

    r17902 r20936  
    133133}
    134134
     135// fft based on code by Douglas L. Jones (see note at EOF). modified for Ohana C style
     136void 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.
     206int 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
    135267// check that a number is binary (2^Nbit).  returns int(log_2(N)) in Nbit
    136268int IsBinary (int N, int *Nbit) {
Note: See TracChangeset for help on using the changeset viewer.