diff --git a/unsupported/Eigen/FFT.h b/unsupported/Eigen/FFT.h
new file mode 100644
index 000000000..03490d2c5
--- /dev/null
+++ b/unsupported/Eigen/FFT.h
@@ -0,0 +1,84 @@
+// 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 .
+
+#ifndef EIGEN_FFT_H
+#define EIGEN_FFT_H
+
+// simple_fft_traits: small, free, reasonably efficient default, derived from kissfft
+#include "src/FFT/simple_fft_traits.h"
+#define DEFAULT_FFT_TRAITS simple_fft_traits
+
+// FFTW: faster, GPL-not LGPL, bigger code size
+#ifdef FFTW_PATIENT // definition of FFTW_PATIENT indicates the caller has included fftw3.h, we can use FFTW routines
+// TODO
+// #include "src/FFT/fftw_traits.h"
+// #define DEFAULT_FFT_TRAITS fftw_traits
+#endif
+
+// intel Math Kernel Library: fastest, commerical
+#ifdef _MKL_DFTI_H_ // mkl_dfti.h has been included, we can use MKL FFT routines
+// TODO
+// #include "src/FFT/imkl_traits.h"
+// #define DEFAULT_FFT_TRAITS imkl_traits
+#endif
+
+namespace Eigen {
+
+template
+ >
+class FFT
+{
+ public:
+ typedef _Traits traits_type;
+ typedef typename traits_type::Scalar Scalar;
+ typedef typename traits_type::Complex Complex;
+
+ FFT(const traits_type & traits=traits_type() ) :m_traits(traits) { }
+
+ void fwd( Complex * dst, const Complex * src, int nfft)
+ {
+ m_traits.prepare(nfft,false,dst,src);
+ m_traits.exec(dst,src);
+ m_traits.postprocess(dst);
+ }
+
+ void inv( Complex * dst, const Complex * src, int nfft)
+ {
+ m_traits.prepare(nfft,true,dst,src);
+ m_traits.exec(dst,src);
+ m_traits.postprocess(dst);
+ }
+
+ // TODO: fwd,inv for Scalar
+ // TODO: multi-dimensional FFTs
+ // TODO: handle Eigen MatrixBase
+
+ traits_type & traits() {return m_traits;}
+ private:
+ traits_type m_traits;
+};
+#undef DEFAULT_FFT_TRAITS
+}
+#endif
diff --git a/unsupported/Eigen/src/FFT/simple_fft_traits.h b/unsupported/Eigen/src/FFT/simple_fft_traits.h
new file mode 100644
index 000000000..fe9d24b84
--- /dev/null
+++ b/unsupported/Eigen/src/FFT/simple_fft_traits.h
@@ -0,0 +1,296 @@
+// 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
+
+namespace Eigen {
+
+ template
+ struct simple_fft_traits
+ {
+ typedef _Scalar Scalar;
+ typedef std::complex Complex;
+ simple_fft_traits() : m_nfft(0) {}
+
+ void prepare(int nfft,bool inverse,Complex * dst,const Complex *src)
+ {
+ if (m_nfft == nfft) {
+ // reuse the twiddles, conjugate if necessary
+ if (inverse != m_inverse)
+ for (int i=0;in)
+ p=n;// no more factors
+ }
+ n /= p;
+ m_stageRadix.push_back(p);
+ m_stageRemainder.push_back(n);
+ }while(n>1);
+ }
+
+ void exec(Complex * dst, const Complex * src)
+ {
+ work(0, dst, src, 1,1);
+ }
+
+ void postprocess(Complex *dst)
+ {
+ if (m_inverse) {
+ Scalar scale = 1./m_nfft;
+ for (int k=0;kreal() - .5*scratch[3].real() , Fout->imag() - .5*scratch[3].imag() );
+
+ scratch[0] *= epi3.imag();
+
+ *Fout += scratch[3];
+
+ Fout[m2] = Complex( Fout[m].real() + scratch[0].imag() , Fout[m].imag() - scratch[0].real() );
+
+ Fout[m] += Complex( -scratch[0].imag(),scratch[0].real() );
+ ++Fout;
+ }while(--k);
+ }
+
+ void bfly5( Complex * Fout, const size_t fstride, const size_t m)
+ {
+ Complex *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
+ size_t u;
+ Complex scratch[13];
+ Complex * twiddles = &m_twiddles[0];
+ Complex *tw;
+ Complex ya,yb;
+ ya = twiddles[fstride*m];
+ yb = twiddles[fstride*2*m];
+
+ Fout0=Fout;
+ Fout1=Fout0+m;
+ Fout2=Fout0+2*m;
+ Fout3=Fout0+3*m;
+ Fout4=Fout0+4*m;
+
+ tw=twiddles;
+ for ( u=0; u=Norig) twidx-=Norig;
+ t=scratchbuf[q] * twiddles[twidx];
+ Fout[ k ] += t;
+ }
+ k += m;
+ }
+ }
+ }
+
+ int m_nfft;
+ bool m_inverse;
+ std::vector m_twiddles;
+ std::vector m_stageRadix;
+ std::vector m_stageRemainder;
+ };
+}
diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt
index abfbb0185..49de7dfb2 100644
--- a/unsupported/test/CMakeLists.txt
+++ b/unsupported/test/CMakeLists.txt
@@ -19,3 +19,4 @@ ei_add_test(autodiff)
ei_add_test(BVH)
ei_add_test(matrixExponential)
ei_add_test(alignedvector3)
+ei_add_test(FFT)
diff --git a/unsupported/test/FFT.cpp b/unsupported/test/FFT.cpp
new file mode 100644
index 000000000..b13a7810f
--- /dev/null
+++ b/unsupported/test/FFT.cpp
@@ -0,0 +1,85 @@
+// 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 "main.h"
+#include
+
+//#include
+//#include
+//#include
+
+using namespace std;
+
+template
+void test_fft(int nfft)
+{
+ typedef typename Eigen::FFT::Complex Complex;
+
+ //cout << "type:" << typeid(T).name() << " nfft:" << nfft;
+
+ FFT fft;
+
+ vector inbuf(nfft);
+ vector buf3(nfft);
+ vector outbuf(nfft);
+ for (int k=0;k acc = 0;
+ long double phinc = 2*k0* M_PIl / nfft;
+ for (int k1=0;k1 x(inbuf[k1].real(),inbuf[k1].imag());
+ acc += x * exp( complex(0,-k1*phinc) );
+ }
+ totalpower += norm(acc);
+ complex x(outbuf[k0].real(),outbuf[k0].imag());
+ complex dif = acc - x;
+ difpower += norm(dif);
+ }
+ long double rmse = sqrt(difpower/totalpower);
+ VERIFY( rmse < 1e-5 );// gross check
+
+ totalpower=0;
+ difpower=0;
+ for (int k=0;k(32) )); CALL_SUBTEST(( test_fft(32) )); CALL_SUBTEST(( test_fft(32) ));
+ CALL_SUBTEST(( test_fft(1024) )); CALL_SUBTEST(( test_fft(1024) )); CALL_SUBTEST(( test_fft(1024) ));
+ CALL_SUBTEST(( test_fft(2*3*4*5*7) )); CALL_SUBTEST(( test_fft(2*3*4*5*7) )); CALL_SUBTEST(( test_fft(2*3*4*5*7) ));
+}