sinfo_fft_base.c

00001 /*
00002  * This file is part of the ESO SINFONI Pipeline
00003  * Copyright (C) 2004,2005 European Southern Observatory
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00018  */
00019 /*---------------------------------------------------------------------------
00020    
00021    File name     :    sinfo_fft_base.c
00022    Author         :    N. Devillard
00023    Created on    :    October 1999
00024    Description    :    base FFT routines
00025 
00026  *--------------------------------------------------------------------------*/
00027 /*
00028     $Id: sinfo_fft_base.c,v 1.6 2007/06/06 07:10:45 amodigli Exp $
00029     $Author: amodigli $
00030     $Date: 2007/06/06 07:10:45 $
00031     $Revision: 1.6 $
00032 */
00033 #ifdef HAVE_CONFIG_H
00034 #  include <config.h>
00035 #endif
00036 /*---------------------------------------------------------------------------
00037                                    Includes
00038  ---------------------------------------------------------------------------*/
00039 #include "sinfo_fft_base.h"
00040 #include "sinfo_globals.h"
00047 /*---------------------------------------------------------------------------
00048                               Function codes
00049  ---------------------------------------------------------------------------*/
00093 void
00094 sinfo_fftn(
00095     dcomplex data[],
00096     unsigned nn[],
00097     int ndim, 
00098     int isign)
00099 {
00100   int        idim=0;
00101   unsigned   i1=0;
00102   unsigned   i2rev=0;
00103   unsigned   i3rev=0;
00104   unsigned   ibit=0;
00105   unsigned   ip2=0;
00106   unsigned   ifp1=0;
00107   unsigned   ifp2=0;
00108   unsigned   k2=0;
00109   unsigned   n=0;
00110   unsigned   nprev = 1;
00111   unsigned   ntot = 1;
00112   register   unsigned i2=0;
00113   register   unsigned i3=0;
00114   double        theta=0;
00115   dcomplex   w, wp;
00116   double        wtemp=0;
00117   dcomplex   temp, wt;
00118   double       t1=0;
00119   double     t2=0;
00120 
00121   /*      Compute total number of complex values  */
00122   for (idim = 0; idim < ndim; ++idim) {
00123     ntot *= nn[idim];
00124   }
00125 
00126   for (idim = ndim - 1; idim >= 0; --idim) {
00127     n = nn[idim];
00128 
00129     ip2 = nprev * n;        /*  Unit step for next dimension */
00130     i2rev = 0;              /*  Bit reversed i2 */
00131 
00132     /*      This is the bit reversal section of the routine */
00133     /*      Loop over current dimension     */
00134     for (i2 = 0; i2 < ip2; i2 += nprev) {
00135       if (i2 < i2rev) {
00136     /*      Loop over lower dimensions      */
00137     for (i1 = i2; i1 < i2 + nprev; ++i1) {
00138       /*      Loop over higher dimensions  */
00139       for (i3 = i1; i3 < ntot; i3 += ip2) {
00140         i3rev = i3 + i2rev - i2;
00141         temp = data[i3];
00142         data[i3] = data[i3rev];
00143         data[i3rev] = temp;
00144       }
00145     }
00146       }
00147       ibit = ip2;
00148       /*      Increment from high end of i2rev to low */
00149       do {
00150     ibit >>= 1;
00151     i2rev ^= ibit;
00152       } while (ibit >= nprev && !(ibit & i2rev));
00153     }
00154 
00155     /*      Here begins the Danielson-Lanczos section of the routine */
00156     /*      Loop over step sizes    */
00157     for (ifp1 = nprev; ifp1 < ip2; ifp1 <<= 1) {
00158       ifp2 = ifp1 << 1;
00159       /*  Initialize for the trig. recurrence */
00160       theta = isign * 2.0 * PI_NUMB / (ifp2 / nprev);
00161       wp.x = sin(0.5 * theta);
00162       wp.x *= -2.0 * wp.x;
00163       wp.y = sin(theta);
00164       w.x = 1.0;
00165       w.y = 0.0;
00166 
00167       /*  Loop by unit step in current dimension  */
00168       for (i3 = 0; i3 < ifp1; i3 += nprev) {
00169     /*      Loop over lower dimensions      */
00170     for (i1 = i3; i1 < i3 + nprev; ++i1) {
00171       /*  Loop over higher dimensions */
00172       for (i2 = i1; i2 < ntot; i2 += ifp2) {
00173         /*      Danielson-Lanczos formula */
00174         k2 = i2 + ifp1;
00175         wt = data[k2];
00176 
00177             /* Complex multiply using 3 real multiplies.  
00178                Should usually be faster.    */
00179         data[k2].x = data[i2].x - (temp.x =
00180                        (t1 = w.x * wt.x) - (t2 = w.y * wt.y));
00181         data[k2].y = data[i2].y - (temp.y =
00182                        (w.x + w.y) * (wt.x + wt.y) - t1 - t2);
00183         data[i2].x += temp.x;
00184         data[i2].y += temp.y;
00185       }
00186     }
00187     /*      Trigonometric recurrence        */
00188     wtemp = w.x;
00189         /*    Complex multiply using 3 real multiplies.    */
00190     w.x += (t1 = w.x * wp.x) - (t2 = w.y * wp.y);
00191     w.y += (wtemp + w.y) * (wp.x + wp.y) - t1 - t2;
00192       }
00193     }
00194     nprev *= n;
00195   }
00196     
00197   return ;
00198 }
00199 
00200 
00201 
00202 
00220 int
00221 sinfo_is_power_of_2(int p)
00222 {
00223     float    c ;
00224     int        power2 ;
00225 
00226     if (p == 0) { /* Yes, 0 is a power of 2    */
00227         power2 =  1 ;
00228     } else if (p<0) { /* No, negatives are no power of 2 (in R at least) */
00229         power2 = -1 ;
00230     } else { /* Compute log in base 2    */
00231         c = (float)(log((double)p) / log(2.0)) ;
00232         if (c == (float)((int)c)) {
00233             power2 = (int)c ;
00234         } else {
00235             power2 = -1 ;
00236         }
00237     }
00238     
00239     return power2 ;
00240 }
00241 

Generated on 8 Mar 2011 for SINFONI Pipeline Reference Manual by  doxygen 1.6.1