// This file is part of Eigen, a lightweight C++ template library // for linear algebra. Eigen itself is part of the KDE project. // // Copyright (C) 2009 Mark Borgerding mark a borgerding net // // Eigen is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 3 of the License, or (at your option) any later version. // // Alternatively, 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 of // the License, or (at your option) any later version. // // Eigen 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 Lesser General Public License or the // GNU General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License and a copy of the GNU General Public License along with // Eigen. If not, see . #include #include #include #include #include #include using namespace Eigen; using namespace std; template string nameof(); template <> string nameof() {return "float";} template <> string nameof() {return "double";} template <> string nameof() {return "long double";} #ifndef TYPE #define TYPE float #endif #ifndef NFFT #define NFFT 1024 #endif #ifndef NDATA #define NDATA 1000000 #endif using namespace Eigen; template void bench(int nfft,bool fwd,bool unscaled=false, bool halfspec=false) { typedef typename NumTraits::Real Scalar; typedef typename std::complex Complex; int nits = NDATA/nfft; vector inbuf(nfft); vector outbuf(nfft); FFT< Scalar > fft; if (unscaled) { fft.SetFlag(fft.Unscaled); cout << "unscaled "; } if (halfspec) { fft.SetFlag(fft.HalfSpectrum); cout << "halfspec "; } std::fill(inbuf.begin(),inbuf.end(),0); fft.fwd( outbuf , inbuf); BenchTimer timer; timer.reset(); for (int k=0;k<8;++k) { timer.start(); if (fwd) for(int i = 0; i < nits; i++) fft.fwd( outbuf , inbuf); else for(int i = 0; i < nits; i++) fft.inv(inbuf,outbuf); timer.stop(); } cout << nameof() << " "; double mflops = 5.*nfft*log2((double)nfft) / (1e6 * timer.value() / (double)nits ); if ( NumTraits::IsComplex ) { cout << "complex"; }else{ cout << "real "; mflops /= 2; } if (fwd) cout << " fwd"; else cout << " inv"; cout << " NFFT=" << nfft << " " << (double(1e-6*nfft*nits)/timer.value()) << " MS/s " << mflops << "MFLOPS\n"; } int main(int argc,char ** argv) { bench >(NFFT,true); bench >(NFFT,false); bench(NFFT,true); bench(NFFT,false); bench(NFFT,false,true); bench(NFFT,false,true,true); bench >(NFFT,true); bench >(NFFT,false); bench(NFFT,true); bench(NFFT,false); bench >(NFFT,true); bench >(NFFT,false); bench(NFFT,true); bench(NFFT,false); return 0; }