SINFONI Pipeline Reference Manual  2.5.2
sinfo_fft_base.c
1 /*
2  * This file is part of the ESO SINFONI Pipeline
3  * Copyright (C) 2004,2005 European Southern Observatory
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
18  */
19 /*---------------------------------------------------------------------------
20 
21  File name : sinfo_fft_base.c
22  Author : N. Devillard
23  Created on : October 1999
24  Description : base FFT routines
25 
26  *--------------------------------------------------------------------------*/
27 /*
28  $Id: sinfo_fft_base.c,v 1.7 2012-03-02 08:42:20 amodigli Exp $
29  $Author: amodigli $
30  $Date: 2012-03-02 08:42:20 $
31  $Revision: 1.7 $
32  */
33 #ifdef HAVE_CONFIG_H
34 # include <config.h>
35 #endif
36 /*---------------------------------------------------------------------------
37  Includes
38  ---------------------------------------------------------------------------*/
39 #include "sinfo_fft_base.h"
40 #include "sinfo_globals.h"
47 /*---------------------------------------------------------------------------
48  Function codes
49  ---------------------------------------------------------------------------*/
93 void
94 sinfo_fftn(
95  dcomplex data[],
96  unsigned nn[],
97  int ndim,
98  int isign)
99 {
100  int idim=0;
101  unsigned i1=0;
102  unsigned i2rev=0;
103  unsigned i3rev=0;
104  unsigned ibit=0;
105  unsigned ip2=0;
106  unsigned ifp1=0;
107  unsigned ifp2=0;
108  unsigned k2=0;
109  unsigned n=0;
110  unsigned nprev = 1;
111  unsigned ntot = 1;
112  register unsigned i2=0;
113  register unsigned i3=0;
114  double theta=0;
115  dcomplex w, wp;
116  double wtemp=0;
117  dcomplex temp, wt;
118  double t1=0;
119  double t2=0;
120 
121  /* Compute total number of complex values */
122  for (idim = 0; idim < ndim; ++idim) {
123  ntot *= nn[idim];
124  }
125 
126  for (idim = ndim - 1; idim >= 0; --idim) {
127  n = nn[idim];
128 
129  ip2 = nprev * n; /* Unit step for next dimension */
130  i2rev = 0; /* Bit reversed i2 */
131 
132  /* This is the bit reversal section of the routine */
133  /* Loop over current dimension */
134  for (i2 = 0; i2 < ip2; i2 += nprev) {
135  if (i2 < i2rev) {
136  /* Loop over lower dimensions */
137  for (i1 = i2; i1 < i2 + nprev; ++i1) {
138  /* Loop over higher dimensions */
139  for (i3 = i1; i3 < ntot; i3 += ip2) {
140  i3rev = i3 + i2rev - i2;
141  temp = data[i3];
142  data[i3] = data[i3rev];
143  data[i3rev] = temp;
144  }
145  }
146  }
147  ibit = ip2;
148  /* Increment from high end of i2rev to low */
149  do {
150  ibit >>= 1;
151  i2rev ^= ibit;
152  } while (ibit >= nprev && !(ibit & i2rev));
153  }
154 
155  /* Here begins the Danielson-Lanczos section of the routine */
156  /* Loop over step sizes */
157  for (ifp1 = nprev; ifp1 < ip2; ifp1 <<= 1) {
158  ifp2 = ifp1 << 1;
159  /* Initialize for the trig. recurrence */
160  theta = isign * 2.0 * PI_NUMB / (ifp2 / nprev);
161  wp.x = sin(0.5 * theta);
162  wp.x *= -2.0 * wp.x;
163  wp.y = sin(theta);
164  w.x = 1.0;
165  w.y = 0.0;
166 
167  /* Loop by unit step in current dimension */
168  for (i3 = 0; i3 < ifp1; i3 += nprev) {
169  /* Loop over lower dimensions */
170  for (i1 = i3; i1 < i3 + nprev; ++i1) {
171  /* Loop over higher dimensions */
172  for (i2 = i1; i2 < ntot; i2 += ifp2) {
173  /* Danielson-Lanczos formula */
174  k2 = i2 + ifp1;
175  wt = data[k2];
176 
177  /* Complex multiply using 3 real multiplies.
178  Should usually be faster. */
179  data[k2].x = data[i2].x - (temp.x =
180  (t1 = w.x * wt.x) - (t2 = w.y * wt.y));
181  data[k2].y = data[i2].y - (temp.y =
182  (w.x + w.y) * (wt.x + wt.y) - t1 - t2);
183  data[i2].x += temp.x;
184  data[i2].y += temp.y;
185  }
186  }
187  /* Trigonometric recurrence */
188  wtemp = w.x;
189  /* Complex multiply using 3 real multiplies. */
190  w.x += (t1 = w.x * wp.x) - (t2 = w.y * wp.y);
191  w.y += (wtemp + w.y) * (wp.x + wp.y) - t1 - t2;
192  }
193  }
194  nprev *= n;
195  }
196 
197  return ;
198 }
199 
200 
201 
202 
220 int
221 sinfo_is_power_of_2(int p)
222 {
223  float c ;
224  int power2 ;
225 
226  if (p == 0) { /* Yes, 0 is a power of 2 */
227  power2 = 1 ;
228  } else if (p<0) { /* No, negatives are no power of 2 (in R at least) */
229  power2 = -1 ;
230  } else { /* Compute log in base 2 */
231  c = (float)(log((double)p) / log(2.0)) ;
232  if (c == (float)((int)c)) {
233  power2 = (int)c ;
234  } else {
235  power2 = -1 ;
236  }
237  }
238 
239  return power2 ;
240 }
241