NEURON
fft.c
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 
3 /**************************************************************************
4 **
5 ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
6 **
7 ** Meschach Library
8 **
9 ** This Meschach Library is provided "as is" without any express
10 ** or implied warranty of any kind with respect to this software.
11 ** In particular the authors shall not be liable for any direct,
12 ** indirect, special, incidental or consequential damages arising
13 ** in any way from use of the software.
14 **
15 ** Everyone is granted permission to copy, modify and redistribute this
16 ** Meschach Library, provided:
17 ** 1. All copies contain this copyright notice.
18 ** 2. All modified copies shall carry a notice stating who
19 ** made the last modification and the date of such modification.
20 ** 3. No charge is made for this software or works derived from it.
21 ** This clause shall not be construed as constraining other software
22 ** distributed on the same medium as this software, nor is a
23 ** distribution fee considered a charge.
24 **
25 ***************************************************************************/
26 
27 
28 /*
29  Fast Fourier Transform routine
30  Loosely based on the Fortran routine in Rabiner & Gold's
31  "Digital Signal Processing"
32 */
33 
34 static char rcsid[] = "fft.c,v 1.1 1997/12/04 17:55:20 hines Exp";
35 
36 #include <stdio.h>
37 #include "matrix.h"
38 #include "matrix2.h"
39 #include <math.h>
40 
41 
42 /* fft -- d.i.t. fast Fourier transform
43  -- radix-2 FFT only
44  -- vector extended to a power of 2 */
45 void fft(x_re,x_im)
46 VEC *x_re, *x_im;
47 {
48  int i, ip, j, k, li, n, length;
49  Real *xr, *xi;
50  Real theta, pi = 3.1415926535897932384;
51  Real w_re, w_im, u_re, u_im, t_re, t_im;
52  Real tmp, tmpr, tmpi;
53 
54  if ( ! x_re || ! x_im )
55  error(E_NULL,"fft");
56  if ( x_re->dim != x_im->dim )
57  error(E_SIZES,"fft");
58 
59  n = 1;
60  while ( x_re->dim > n )
61  n *= 2;
62  x_re = v_resize(x_re,n);
63  x_im = v_resize(x_im,n);
64  printf("# fft: x_re =\n"); v_output(x_re);
65  printf("# fft: x_im =\n"); v_output(x_im);
66  xr = x_re->ve;
67  xi = x_im->ve;
68 
69  /* Decimation in time (DIT) algorithm */
70  j = 0;
71  for ( i = 0; i < n-1; i++ )
72  {
73  if ( i < j )
74  {
75  tmp = xr[i];
76  xr[i] = xr[j];
77  xr[j] = tmp;
78  tmp = xi[i];
79  xi[i] = xi[j];
80  xi[j] = tmp;
81  }
82  k = n / 2;
83  while ( k <= j )
84  {
85  j -= k;
86  k /= 2;
87  }
88  j += k;
89  }
90 
91  /* Actual FFT */
92  for ( li = 1; li < n; li *= 2 )
93  {
94  length = 2*li;
95  theta = pi/li;
96  u_re = 1.0;
97  u_im = 0.0;
98  if ( li == 1 )
99  {
100  w_re = -1.0;
101  w_im = 0.0;
102  }
103  else if ( li == 2 )
104  {
105  w_re = 0.0;
106  w_im = 1.0;
107  }
108  else
109  {
110  w_re = cos(theta);
111  w_im = sin(theta);
112  }
113  for ( j = 0; j < li; j++ )
114  {
115  for ( i = j; i < n; i += length )
116  {
117  ip = i + li;
118  /* step 1 */
119  t_re = xr[ip]*u_re - xi[ip]*u_im;
120  t_im = xr[ip]*u_im + xi[ip]*u_re;
121  /* step 2 */
122  xr[ip] = xr[i] - t_re;
123  xi[ip] = xi[i] - t_im;
124  /* step 3 */
125  xr[i] += t_re;
126  xi[i] += t_im;
127  }
128  tmpr = u_re*w_re - u_im*w_im;
129  tmpi = u_im*w_re + u_re*w_im;
130  u_re = tmpr;
131  u_im = tmpi;
132  }
133  }
134 }
135 
136 /* ifft -- inverse FFT using the same interface as fft() */
137 void ifft(x_re,x_im)
138 VEC *x_re, *x_im;
139 {
140  /* we just use complex conjugates */
141 
142  sv_mlt(-1.0,x_im,x_im);
143  fft(x_re,x_im);
144  sv_mlt( 1.0/((double)(x_re->dim)),x_re,x_re);
145 }
void ifft(VEC *x_re, VEC *x_im)
Definition: fft.c:137
#define Real
Definition: machine.h:189
static Object ** v_resize(void *v)
Definition: ivocvect.cpp:1297
cos
Definition: extdef.h:3
static philox4x32_key_t k
Definition: nrnran123.cpp:11
sin
Definition: extdef.h:3
Definition: matrix.h:67
#define E_SIZES
Definition: err.h:95
int const size_t const size_t n
Definition: nrngsl.h:12
#define printf
Definition: mwprefix.h:26
#define E_NULL
Definition: err.h:102
size_t j
VEC * sv_mlt(double, VEC *, VEC *)
static char rcsid[]
Definition: fft.c:34
#define i
Definition: md1redef.h:12
#define v_output(vec)
Definition: matrix.h:355
#define error(err_num, fn_name)
Definition: err.h:73
void fft(VEC *x_re, VEC *x_im)
Definition: fft.c:45