头文件:
/*
* Copyright (c) 2008-2011 Zhang Ming (M. Zhang), zmjerry@163.com
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 or any later version.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details. A copy of the GNU General Public License is available at:
* http://www.fsf.org/licensing/licenses
*/
/*****************************************************************************
* fft.h
*
* Some convenient interface for FFT algorithm. If signal length "N" is power
* of 2, then calls FFTR2 class to compute, else calls FFTPF class.
* Forward: Xk = fftr2c(xn); Xk = fftc2c(xn);
* Inverse: xn = fftc2r(Xk); xn = fftc2c(Xk);
*
* These routines don't need FFTW lib, but less efficiency than FFTW.
*
* Zhang Ming, 2010-09, Xi'an Jiaotong University.
*****************************************************************************/
#ifndef FFT_H
#define FFT_H
#include <fftmr.h>
#include <fftpf.h>
namespace splab
{
template<typename Type>
Vector< complex<Type> > fft( const Vector<Type>& );
template<typename Type>
Vector< complex<Type> > fft( const Vector< complex<Type> >& );
template<typename Type>
Vector< complex<Type> > ifft( const Vector< complex<Type> >& );
template<typename Type>
Vector< complex<Type> > fftr2c( const Vector<Type>& );
template<typename Type>
Vector< complex<Type> > fftc2c( const Vector< complex<Type> >& );
template<typename Type>
Vector<Type> ifftc2r( const Vector< complex<Type> >& );
template<typename Type>
Vector< complex<Type> > ifftc2c( const Vector< complex<Type> >& );
#include <fft-impl.h>
}
// namespace splab
#endif
// FFT_H
实现文件:
/*
* Copyright (c) 2008-2011 Zhang Ming (M. Zhang), zmjerry@163.com
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 2 or any later version.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details. A copy of the GNU General Public License is available at:
* http://www.fsf.org/licensing/licenses
*/
/*****************************************************************************
* fft-impl.h
*
* Implementation for FFT and IFFT interface.
*
* Zhang Ming, 2010-09, Xi'an Jiaotong University.
*****************************************************************************/
/**
* Forward FFT algorithm.
*/
template<typename Type>
inline Vector< complex<Type> > fft( const Vector<Type> &xn )
{
return fftr2c( xn );
}
template<typename Type>
inline Vector< complex<Type> > fft( const Vector< complex<Type> > &xn )
{
return fftc2c( xn );
}
/**
* Inverse FFT algorithm.
*/
template<typename Type>
inline Vector< complex<Type> > ifft( const Vector< complex<Type> > &Xk )
{
return ifftc2c( Xk );
}
/**
* Real to complex DFT of 1D signal.
*/
template<typename Type>
inline Vector< complex<Type> > fftr2c( const Vector<Type> &xn )
{
Vector< complex<Type> > Xk( xn.size() );
if( isPower2(xn.size()) )
{
FFTMR<Type> dft;
dft.fft( xn, Xk );
}
else
{
FFTPF<Type> dft;
dft.fft( xn, Xk );
}
return Xk;
}
/**
* Complex to complex DFT of 1D signal.
*/
template<typename Type>
inline Vector< complex<Type> > fftc2c( const Vector< complex<Type> > &xn )
{
Vector< complex<Type> > Xk( xn.size() );
if( isPower2(xn.size()) )
{
for( int i=0; i<xn.size(); ++i )
Xk[i] = xn[i];
FFTMR<Type> dft;
dft.fft( Xk );
}
else
{
FFTPF<Type> dft;
dft.fft( xn, Xk );
}
return Xk;
}
/**
* Complex to real IDFT of 1D signal.
*/
template<typename Type>
inline Vector<Type> ifftc2r( const Vector< complex<Type> > &Xk )
{
Vector<Type> xn( Xk.size() );
if( isPower2(xn.size()) )
{
Vector< complex<Type> > tmp( Xk );
FFTMR<Type> dft;
dft.ifft( tmp, xn );
}
else
{
FFTPF<Type> dft;
dft.ifft( Xk, xn );
}
return xn;
}
/**
* Complex to complex IDFT of 1D signal.
*/
template<typename Type>
inline Vector< complex<Type> > ifftc2c( const Vector< complex<Type> > &Xk )
{
Vector< complex<Type> > xn( Xk.size() );
if( isPower2(xn.size()) )
{
for( int i=0; i<xn.size(); ++i )
xn[i] = Xk[i];
FFTMR<Type> dft;
dft.ifft( xn );
}
else
{
FFTPF<Type> dft;
dft.ifft( Xk, xn );
}
return xn;
}
测试代码:
/*****************************************************************************
* fft_test.cpp
*
* FFT test.
*
* Zhang Ming, 2010-09, Xi'an Jiaotong University.
*****************************************************************************/
#include <iostream>
#include <cstdlib>
#include <vectormath.h>
#include <fft.h>
using namespace std;
using namespace splab;
typedef double Type;
const int MINLEN = 1;
const int MAXLEN = 1000;
const int STEP = 10;
int main()
{
Vector< complex<Type> > sn, Rk, Sk, xn;
Vector<Type> rn, tn;
cout << "forward transform: complex to complex." << endl;
cout << "inverse transform: complex to complex." << endl << endl;
cout << "signal length" << "\t" << "mean(abs((sn-xn))" << endl;
for( int len=MINLEN; len<MAXLEN; len+=STEP )
{
sn.resize(len);
for( int i=0; i<len; ++i )
sn[i] = complex<Type>( rand()%10, rand()%10 );
Sk = fftc2c( sn );
xn = ifftc2c( Sk );
// Sk = fft( sn );
// xn = ifft( Sk );
cout << " " << len << "\t\t" << " " << sum(abs(sn-xn))/len << endl;
}
cout << endl << endl;
cout << "forward transform: real to complex ." << endl;
cout << "inverse transform: complex to real." << endl << endl;
cout << "signal length" << "\t" << "mean(abs((rn-tn))" << endl;
for( int len=MINLEN; len<MAXLEN; len+=STEP )
{
rn.resize(len);
for( int i=0; i<len; ++i )
rn[i] = rand()%10;
Rk = fftr2c( rn );
tn = ifftc2r( Rk );
// Rk = fft( rn );
// tn = real( ifft(Rk) );
cout << " " << len << "\t\t" << " " << sum(abs(rn-tn))/len << endl;
}
cout << endl;
return 0;
}
运行结果:
forward transform: complex to complex.
inverse transform: complex to complex.
signal length mean(abs((sn-xn))
1 0
11 2.53071e-016
21 2.04167e-015
31 3.23943e-015
41 2.72403e-015
51 3.16559e-015
61 2.59734e-015
71 8.2923e-015
81 6.68263e-015
91 8.43078e-015
101 1.00071e-014
111 6.01269e-015
121 3.93451e-015
131 1.85043e-014
141 8.70367e-015
151 1.23613e-014
161 6.08565e-015
171 9.52577e-015
181 4.67904e-015
191 1.26907e-014
201 7.17336e-015
211 2.48636e-014
221 1.16938e-014
231 1.68039e-014
241 1.37351e-014
251 2.15957e-014
261 1.34044e-014
271 1.57957e-014
281 5.82583e-014
291 6.69909e-015
301 3.8242e-014
311 7.39088e-014
321 2.20706e-014
331 2.58994e-014
341 2.24836e-014
351 1.86775e-014
361 2.74814e-014
371 9.27838e-015
381 1.14252e-014
391 1.0008e-014
401 5.94498e-014
411 1.53057e-014
421 5.47408e-014
431 7.25253e-014
441 7.87218e-015
451 2.92309e-014
461 5.81937e-014
471 4.23726e-014
481 4.51822e-014
491 1.10778e-013
501 3.52489e-014
511 4.42759e-014
521 1.18393e-013
531 5.78823e-014
541 1.26566e-013
551 3.69879e-014
561 5.15765e-014
571 3.83505e-014
581 3.7811e-014
591 3.06472e-014
601 1.39216e-013
611 2.93462e-014
621 4.50018e-014
631 1.35626e-013
641 1.4146e-013
651 1.36433e-014
661 1.35491e-013
671 2.22196e-014
681 7.82905e-014
691 1.41573e-013
701 1.63199e-013
711 2.18095e-014
721 3.11044e-014
731 4.84485e-014
741 6.47117e-014
751 6.65676e-014
761 1.50277e-013
771 3.72186e-014
781 4.02716e-014
791 3.55064e-014
801 8.17425e-014
811 1.82512e-014
821 1.78106e-013
831 1.43936e-014
841 8.8678e-014
851 8.81647e-014
861 6.26873e-015
871 2.98626e-014
881 1.08503e-013
891 2.44492e-014
901 8.29867e-014
911 1.29968e-013
921 5.25883e-014
931 6.62704e-014
941 4.87279e-014
951 5.11132e-014
961 1.33708e-013
971 1.78372e-013
981 8.49343e-014
991 4.66578e-014
forward transform: real to complex .
inverse transform: complex to real.
signal length mean(abs((rn-tn))
1 0
11 1.41301e-016
21 1.11022e-015
31 1.96513e-015
41 1.3419e-015
51 2.13333e-015
61 1.88711e-015
71 5.01281e-015
81 4.06212e-015
91 4.96021e-015
101 6.08343e-015
111 3.27759e-015
121 2.21945e-015
131 1.2793e-014
141 4.77218e-015
151 8.30687e-015
161 3.41983e-015
171 5.91683e-015
181 3.50161e-015
191 8.77976e-015
201 4.62208e-015
211 1.66658e-014
221 7.22645e-015
231 1.01782e-014
241 9.79362e-015
251 1.55712e-014
261 7.40681e-015
271 1.01074e-014
281 3.81723e-014
291 3.8929e-015
301 2.22941e-014
311 4.76995e-014
321 1.36251e-014
331 1.78498e-014
341 1.3842e-014
351 1.16846e-014
361 1.50902e-014
371 4.81715e-015
381 7.45036e-015
391 5.79102e-015
401 3.68331e-014
411 8.45149e-015
421 3.5318e-014
431 4.64351e-014
441 4.5536e-015
451 1.82979e-014
461 4.11746e-014
471 2.67421e-014
481 2.76207e-014
491 7.49936e-014
501 2.24768e-014
511 2.8849e-014
521 7.29438e-014
531 3.92363e-014
541 8.14216e-014
551 2.2449e-014
561 3.26657e-014
571 2.44778e-014
581 2.23165e-014
591 1.95616e-014
601 8.50218e-014
611 1.81843e-014
621 2.89087e-014
631 8.84136e-014
641 9.02308e-014
651 8.84008e-015
661 8.58328e-014
671 1.31807e-014
681 4.8685e-014
691 8.97514e-014
701 1.07318e-013
711 1.35663e-014
721 1.82121e-014
731 2.86341e-014
741 4.07251e-014
751 4.35763e-014
761 9.37088e-014
771 2.29587e-014
781 2.29084e-014
791 1.99687e-014
801 5.27873e-014
811 1.21722e-014
821 1.06546e-013
831 9.23176e-015
841 5.27161e-014
851 5.19815e-014
861 3.93491e-015
871 1.86002e-014
881 7.19074e-014
891 1.38322e-014
901 4.85723e-014
911 8.17142e-014
921 3.32546e-014
931 3.87686e-014
941 3.16691e-014
951 2.93188e-014
961 8.21269e-014
971 1.16589e-013
981 5.44883e-014
991 2.98482e-014
Process returned 0 (0x0) execution time : 0.686 s
Press any key to continue.