Squashed 'third_party/eigen/' content from commit 61d72f6

Change-Id: Iccc90fa0b55ab44037f018046d2fcffd90d9d025
git-subtree-dir: third_party/eigen
git-subtree-split: 61d72f6383cfa842868c53e30e087b0258177257
diff --git a/bench/benchFFT.cpp b/bench/benchFFT.cpp
new file mode 100644
index 0000000..3eb1a1a
--- /dev/null
+++ b/bench/benchFFT.cpp
@@ -0,0 +1,115 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2009 Mark Borgerding mark a borgerding net
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <iostream>
+
+#include <bench/BenchUtil.h>
+#include <complex>
+#include <vector>
+#include <Eigen/Core>
+
+#include <unsupported/Eigen/FFT>
+
+using namespace Eigen;
+using namespace std;
+
+
+template <typename T>
+string nameof();
+
+template <> string nameof<float>() {return "float";}
+template <> string nameof<double>() {return "double";}
+template <> string nameof<long double>() {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 <typename T>
+void bench(int nfft,bool fwd,bool unscaled=false, bool halfspec=false)
+{
+    typedef typename NumTraits<T>::Real Scalar;
+    typedef typename std::complex<Scalar> Complex;
+    int nits = NDATA/nfft;
+    vector<T> inbuf(nfft);
+    vector<Complex > 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<Scalar>() << " ";
+    double mflops = 5.*nfft*log2((double)nfft) / (1e6 * timer.value() / (double)nits );
+    if ( NumTraits<T>::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<complex<float> >(NFFT,true);
+    bench<complex<float> >(NFFT,false);
+    bench<float>(NFFT,true);
+    bench<float>(NFFT,false);
+    bench<float>(NFFT,false,true);
+    bench<float>(NFFT,false,true,true);
+
+    bench<complex<double> >(NFFT,true);
+    bench<complex<double> >(NFFT,false);
+    bench<double>(NFFT,true);
+    bench<double>(NFFT,false);
+    bench<complex<long double> >(NFFT,true);
+    bench<complex<long double> >(NFFT,false);
+    bench<long double>(NFFT,true);
+    bench<long double>(NFFT,false);
+    return 0;
+}