类似Matlab中FFT函数调用形式的C++实现

头文件:

/*
 * Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected]
 *
 * 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), [email protected]
 *
 * 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.

你可能感兴趣的:(类似Matlab中FFT函数调用形式的C++实现)