IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 16094


Ignore:
Timestamp:
Jan 15, 2008, 6:04:08 PM (18 years ago)
Author:
eugene
Message:

convert to Jones (creative commons) version of fft

Location:
trunk/Ohana/src/opihi
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/opihi/cmd.data/fft1d.c

    r7917 r16094  
    33int fft1d (int argc, char **argv) {
    44 
    5   int i, Npix, ZeroImaginary;
    6   float *t1, *t2, *temp;
     5  int Npix, Nbit, ZeroImaginary;
    76  Vector *Ire, *Iim, *Ore, *Oim;
    87
     
    1918  }   
    2019  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?)
    2422  Npix = Ire[0].Nelements;
    2523  if (!ZeroImaginary && (Npix != Iim[0].Nelements)) {
     
    2725    return (FALSE);
    2826  }
    29 
    30   if (!IsBinary (Npix)) {
     27  if (!IsBinary (Npix, &Nbit)) {
    3128    gprint (GP_ERR, "Npix is not a binary number!\n");
    3229    return (FALSE);
    3330  }
    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);
    5231
     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
    5337  Ore[0].Nelements = Npix;
    5438  Oim[0].Nelements = Npix;
     
    5640  REALLOCATE (Oim[0].elements, float, Npix);
    5741 
    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));
    6350  }   
    64  
    65   free (temp);
     51
     52  fft (Ore[0].elements, Oim[0].elements, Npix, Nbit);
    6653 
    6754  return (TRUE);
    6855}
    69 
    70  
  • trunk/Ohana/src/opihi/include/data.h

    r15274 r16094  
    8484
    8585/* in fft.c */
    86 void fft (float *Data, int N, int isign);
    87 void fftold (float *Data, int N, int isign);
     86void fft (float *dataRe, float *dataIm, int N, int Nbit);
    8887void fftN (float *data, int *nn, int ndim, int isign);
    8988int IsBinary (int N);
  • trunk/Ohana/src/opihi/lib.data/fft.c

    r2598 r16094  
    11# include "data.h"
    22
    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
     4void fftN (float *data, int *nn, int ndim, int isign) {
     5 
     6  fprintf (stderr, "broken\n");
     7  return;
    518}
    529
    53 void fftold (float *Data, int N, int isign) {
     10void fft (double *x, double *y, int n, int Nbit) {
    5411
    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}                         
    5864
    59   data = Data - 1;
    60   n = N << 1;
    61   j = 1;
     65int IsBinary (int N, int *nbin) {
    6266
    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;
    6775    }
    68     m = n >> 1;
    69     while (m >= 2 && j > m) {
    70       j -= m;
    71       m >>= 1;
    72     }
    73     j += m;
     76    N >>= 1;
    7477  }
    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);
    9980}
    10081
    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/**********************************************************/
    103101
    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 FSWAP
    169 
    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 with
    173    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/N
    178 
    179    no normalization is performed, so a signal of amplitude A sin (w_k * t) will be
    180       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)=tempr
    203 
    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.