home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 22 gnu
/
22-gnu.zip
/
mesch12a.zip
/
fft.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-13
|
4KB
|
145 lines
/**************************************************************************
**
** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
**
** Meschach Library
**
** This Meschach Library is provided "as is" without any express
** or implied warranty of any kind with respect to this software.
** In particular the authors shall not be liable for any direct,
** indirect, special, incidental or consequential damages arising
** in any way from use of the software.
**
** Everyone is granted permission to copy, modify and redistribute this
** Meschach Library, provided:
** 1. All copies contain this copyright notice.
** 2. All modified copies shall carry a notice stating who
** made the last modification and the date of such modification.
** 3. No charge is made for this software or works derived from it.
** This clause shall not be construed as constraining other software
** distributed on the same medium as this software, nor is a
** distribution fee considered a charge.
**
***************************************************************************/
/*
Fast Fourier Transform routine
Loosely based on the Fortran routine in Rabiner & Gold's
"Digital Signal Processing"
*/
static char rcsid[] = "$Id: fft.c,v 1.3 1994/01/13 05:45:33 des Exp $";
#include <stdio.h>
#include <math.h>
#include "matrix.h"
#include "matrix2.h"
/* fft -- d.i.t. fast Fourier transform
-- radix-2 FFT only
-- vector extended to a power of 2 */
void fft(x_re,x_im)
VEC *x_re, *x_im;
{
int i, ip, j, k, li, n, length;
Real *xr, *xi;
Real theta, pi = 3.1415926535897932384;
Real w_re, w_im, u_re, u_im, t_re, t_im;
Real tmp, tmpr, tmpi;
if ( ! x_re || ! x_im )
error(E_NULL,"fft");
if ( x_re->dim != x_im->dim )
error(E_SIZES,"fft");
n = 1;
while ( x_re->dim > n )
n *= 2;
x_re = v_resize(x_re,n);
x_im = v_resize(x_im,n);
printf("# fft: x_re =\n"); v_output(x_re);
printf("# fft: x_im =\n"); v_output(x_im);
xr = x_re->ve;
xi = x_im->ve;
/* Decimation in time (DIT) algorithm */
j = 0;
for ( i = 0; i < n-1; i++ )
{
if ( i < j )
{
tmp = xr[i];
xr[i] = xr[j];
xr[j] = tmp;
tmp = xi[i];
xi[i] = xi[j];
xi[j] = tmp;
}
k = n / 2;
while ( k <= j )
{
j -= k;
k /= 2;
}
j += k;
}
/* Actual FFT */
for ( li = 1; li < n; li *= 2 )
{
length = 2*li;
theta = pi/li;
u_re = 1.0;
u_im = 0.0;
if ( li == 1 )
{
w_re = -1.0;
w_im = 0.0;
}
else if ( li == 2 )
{
w_re = 0.0;
w_im = 1.0;
}
else
{
w_re = cos(theta);
w_im = sin(theta);
}
for ( j = 0; j < li; j++ )
{
for ( i = j; i < n; i += length )
{
ip = i + li;
/* step 1 */
t_re = xr[ip]*u_re - xi[ip]*u_im;
t_im = xr[ip]*u_im + xi[ip]*u_re;
/* step 2 */
xr[ip] = xr[i] - t_re;
xi[ip] = xi[i] - t_im;
/* step 3 */
xr[i] += t_re;
xi[i] += t_im;
}
tmpr = u_re*w_re - u_im*w_im;
tmpi = u_im*w_re + u_re*w_im;
u_re = tmpr;
u_im = tmpi;
}
}
}
/* ifft -- inverse FFT using the same interface as fft() */
void ifft(x_re,x_im)
VEC *x_re, *x_im;
{
/* we just use complex conjugates */
sv_mlt(-1.0,x_im,x_im);
fft(x_re,x_im);
sv_mlt(-1.0/((double)(x_re->dim)),x_im,x_im);
}