diff options
author | Yifei Feng <yifeif@google.com> | 2016-09-19 13:42:50 -0700 |
---|---|---|
committer | Yifei Feng <yifeif@google.com> | 2016-09-19 13:42:50 -0700 |
commit | 2b74220466957e7fbc86ebe3da5ead9a0e4f5169 (patch) | |
tree | 31b70922125bcb69f52b15985247ad7b2a56d2dc /third_party/eigen3/unsupported | |
parent | 9b10d6e35be4c932426cc1dfda5686a5dc186773 (diff) |
Remove unused files.
Diffstat (limited to 'third_party/eigen3/unsupported')
8 files changed, 0 insertions, 1482 deletions
diff --git a/third_party/eigen3/unsupported/Eigen/CXX11/TensorSymmetry b/third_party/eigen3/unsupported/Eigen/CXX11/TensorSymmetry deleted file mode 100644 index 027c6087f9..0000000000 --- a/third_party/eigen3/unsupported/Eigen/CXX11/TensorSymmetry +++ /dev/null @@ -1,40 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2013 Christian Seiler <christian@iwakd.de> -// -// 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/. - -#ifndef EIGEN_CXX11_TENSORSYMMETRY_MODULE -#define EIGEN_CXX11_TENSORSYMMETRY_MODULE - -#include <Eigen/CXX11/Tensor> - -#include <Eigen/src/Core/util/DisableStupidWarnings.h> - -/** \defgroup CXX11_TensorSymmetry_Module Tensor Symmetry Module - * - * This module provides a classes that allow for the definition of - * symmetries w.r.t. tensor indices. - * - * Including this module will implicitly include the Tensor module. - * - * \code - * #include <Eigen/TensorSymmetry> - * \endcode - */ - -#include "src/TensorSymmetry/util/TemplateGroupTheory.h" -#include "src/TensorSymmetry/Symmetry.h" -#include "src/TensorSymmetry/StaticSymmetry.h" -#include "src/TensorSymmetry/DynamicSymmetry.h" - -#include <Eigen/src/Core/util/ReenableStupidWarnings.h> - -#endif // EIGEN_CXX11_TENSORSYMMETRY_MODULE - -/* - * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle; - */ diff --git a/third_party/eigen3/unsupported/Eigen/FFT b/third_party/eigen3/unsupported/Eigen/FFT deleted file mode 100644 index 2c45b3999e..0000000000 --- a/third_party/eigen3/unsupported/Eigen/FFT +++ /dev/null @@ -1,418 +0,0 @@ -// 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/. - -#ifndef EIGEN_FFT_H -#define EIGEN_FFT_H - -#include <complex> -#include <vector> -#include <map> -#include <Eigen/Core> - - -/** - * \defgroup FFT_Module Fast Fourier Transform module - * - * \code - * #include <unsupported/Eigen/FFT> - * \endcode - * - * This module provides Fast Fourier transformation, with a configurable backend - * implementation. - * - * The default implementation is based on kissfft. It is a small, free, and - * reasonably efficient default. - * - * There are currently two implementation backend: - * - * - fftw (http://www.fftw.org) : faster, GPL -- incompatible with Eigen in LGPL form, bigger code size. - * - MKL (http://en.wikipedia.org/wiki/Math_Kernel_Library) : fastest, commercial -- may be incompatible with Eigen in GPL form. - * - * \section FFTDesign Design - * - * The following design decisions were made concerning scaling and - * half-spectrum for real FFT. - * - * The intent is to facilitate generic programming and ease migrating code - * from Matlab/octave. - * We think the default behavior of Eigen/FFT should favor correctness and - * generality over speed. Of course, the caller should be able to "opt-out" from this - * behavior and get the speed increase if they want it. - * - * 1) %Scaling: - * Other libraries (FFTW,IMKL,KISSFFT) do not perform scaling, so there - * is a constant gain incurred after the forward&inverse transforms , so - * IFFT(FFT(x)) = Kx; this is done to avoid a vector-by-value multiply. - * The downside is that algorithms that worked correctly in Matlab/octave - * don't behave the same way once implemented in C++. - * - * How Eigen/FFT differs: invertible scaling is performed so IFFT( FFT(x) ) = x. - * - * 2) Real FFT half-spectrum - * Other libraries use only half the frequency spectrum (plus one extra - * sample for the Nyquist bin) for a real FFT, the other half is the - * conjugate-symmetric of the first half. This saves them a copy and some - * memory. The downside is the caller needs to have special logic for the - * number of bins in complex vs real. - * - * How Eigen/FFT differs: The full spectrum is returned from the forward - * transform. This facilitates generic template programming by obviating - * separate specializations for real vs complex. On the inverse - * transform, only half the spectrum is actually used if the output type is real. - */ - - -#ifdef EIGEN_FFTW_DEFAULT -// FFTW: faster, GPL -- incompatible with Eigen in LGPL form, bigger code size -# include <fftw3.h> -# include "src/FFT/ei_fftw_impl.h" - namespace Eigen { - //template <typename T> typedef struct internal::fftw_impl default_fft_impl; this does not work - template <typename T> struct default_fft_impl : public internal::fftw_impl<T> {}; - } -#elif defined EIGEN_MKL_DEFAULT -// TODO -// intel Math Kernel Library: fastest, commercial -- may be incompatible with Eigen in GPL form -# include "src/FFT/ei_imklfft_impl.h" - namespace Eigen { - template <typename T> struct default_fft_impl : public internal::imklfft_impl {}; - } -#else -// internal::kissfft_impl: small, free, reasonably efficient default, derived from kissfft -// -# include "src/FFT/ei_kissfft_impl.h" - namespace Eigen { - template <typename T> - struct default_fft_impl : public internal::kissfft_impl<T> {}; - } -#endif - -namespace Eigen { - - -// -template<typename T_SrcMat,typename T_FftIfc> struct fft_fwd_proxy; -template<typename T_SrcMat,typename T_FftIfc> struct fft_inv_proxy; - -namespace internal { -template<typename T_SrcMat,typename T_FftIfc> -struct traits< fft_fwd_proxy<T_SrcMat,T_FftIfc> > -{ - typedef typename T_SrcMat::PlainObject ReturnType; -}; -template<typename T_SrcMat,typename T_FftIfc> -struct traits< fft_inv_proxy<T_SrcMat,T_FftIfc> > -{ - typedef typename T_SrcMat::PlainObject ReturnType; -}; -} - -template<typename T_SrcMat,typename T_FftIfc> -struct fft_fwd_proxy - : public ReturnByValue<fft_fwd_proxy<T_SrcMat,T_FftIfc> > -{ - typedef DenseIndex Index; - - fft_fwd_proxy(const T_SrcMat& src,T_FftIfc & fft, Index nfft) : m_src(src),m_ifc(fft), m_nfft(nfft) {} - - template<typename T_DestMat> void evalTo(T_DestMat& dst) const; - - Index rows() const { return m_src.rows(); } - Index cols() const { return m_src.cols(); } -protected: - const T_SrcMat & m_src; - T_FftIfc & m_ifc; - Index m_nfft; -private: - fft_fwd_proxy& operator=(const fft_fwd_proxy&); -}; - -template<typename T_SrcMat,typename T_FftIfc> -struct fft_inv_proxy - : public ReturnByValue<fft_inv_proxy<T_SrcMat,T_FftIfc> > -{ - typedef DenseIndex Index; - - fft_inv_proxy(const T_SrcMat& src,T_FftIfc & fft, Index nfft) : m_src(src),m_ifc(fft), m_nfft(nfft) {} - - template<typename T_DestMat> void evalTo(T_DestMat& dst) const; - - Index rows() const { return m_src.rows(); } - Index cols() const { return m_src.cols(); } -protected: - const T_SrcMat & m_src; - T_FftIfc & m_ifc; - Index m_nfft; -private: - fft_inv_proxy& operator=(const fft_inv_proxy&); -}; - - -template <typename T_Scalar, - typename T_Impl=default_fft_impl<T_Scalar> > -class FFT -{ - public: - typedef T_Impl impl_type; - typedef DenseIndex Index; - typedef typename impl_type::Scalar Scalar; - typedef typename impl_type::Complex Complex; - - enum Flag { - Default=0, // goof proof - Unscaled=1, - HalfSpectrum=2, - // SomeOtherSpeedOptimization=4 - Speedy=32767 - }; - - FFT( const impl_type & impl=impl_type() , Flag flags=Default ) :m_impl(impl),m_flag(flags) { } - - inline - bool HasFlag(Flag f) const { return (m_flag & (int)f) == f;} - - inline - void SetFlag(Flag f) { m_flag |= (int)f;} - - inline - void ClearFlag(Flag f) { m_flag &= (~(int)f);} - - inline - void fwd( Complex * dst, const Scalar * src, Index nfft) - { - m_impl.fwd(dst,src,static_cast<int>(nfft)); - if ( HasFlag(HalfSpectrum) == false) - ReflectSpectrum(dst,nfft); - } - - inline - void fwd( Complex * dst, const Complex * src, Index nfft) - { - m_impl.fwd(dst,src,static_cast<int>(nfft)); - } - - /* - inline - void fwd2(Complex * dst, const Complex * src, int n0,int n1) - { - m_impl.fwd2(dst,src,n0,n1); - } - */ - - template <typename _Input> - inline - void fwd( std::vector<Complex> & dst, const std::vector<_Input> & src) - { - if ( NumTraits<_Input>::IsComplex == 0 && HasFlag(HalfSpectrum) ) - dst.resize( (src.size()>>1)+1); // half the bins + Nyquist bin - else - dst.resize(src.size()); - fwd(&dst[0],&src[0],src.size()); - } - - template<typename InputDerived, typename ComplexDerived> - inline - void fwd( MatrixBase<ComplexDerived> & dst, const MatrixBase<InputDerived> & src, Index nfft=-1) - { - typedef typename ComplexDerived::Scalar dst_type; - typedef typename InputDerived::Scalar src_type; - EIGEN_STATIC_ASSERT_VECTOR_ONLY(InputDerived) - EIGEN_STATIC_ASSERT_VECTOR_ONLY(ComplexDerived) - EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(ComplexDerived,InputDerived) // size at compile-time - EIGEN_STATIC_ASSERT((internal::is_same<dst_type, Complex>::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - EIGEN_STATIC_ASSERT(int(InputDerived::Flags)&int(ComplexDerived::Flags)&DirectAccessBit, - THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES) - - if (nfft<1) - nfft = src.size(); - - if ( NumTraits< src_type >::IsComplex == 0 && HasFlag(HalfSpectrum) ) - dst.derived().resize( (nfft>>1)+1); - else - dst.derived().resize(nfft); - - if ( src.innerStride() != 1 || src.size() < nfft ) { - Matrix<src_type,1,Dynamic> tmp; - if (src.size()<nfft) { - tmp.setZero(nfft); - tmp.block(0,0,src.size(),1 ) = src; - }else{ - tmp = src; - } - fwd( &dst[0],&tmp[0],nfft ); - }else{ - fwd( &dst[0],&src[0],nfft ); - } - } - - template<typename InputDerived> - inline - fft_fwd_proxy< MatrixBase<InputDerived>, FFT<T_Scalar,T_Impl> > - fwd( const MatrixBase<InputDerived> & src, Index nfft=-1) - { - return fft_fwd_proxy< MatrixBase<InputDerived> ,FFT<T_Scalar,T_Impl> >( src, *this,nfft ); - } - - template<typename InputDerived> - inline - fft_inv_proxy< MatrixBase<InputDerived>, FFT<T_Scalar,T_Impl> > - inv( const MatrixBase<InputDerived> & src, Index nfft=-1) - { - return fft_inv_proxy< MatrixBase<InputDerived> ,FFT<T_Scalar,T_Impl> >( src, *this,nfft ); - } - - inline - void inv( Complex * dst, const Complex * src, Index nfft) - { - m_impl.inv( dst,src,static_cast<int>(nfft) ); - if ( HasFlag( Unscaled ) == false) - scale(dst,Scalar(1./nfft),nfft); // scale the time series - } - - inline - void inv( Scalar * dst, const Complex * src, Index nfft) - { - m_impl.inv( dst,src,static_cast<int>(nfft) ); - if ( HasFlag( Unscaled ) == false) - scale(dst,Scalar(1./nfft),nfft); // scale the time series - } - - template<typename OutputDerived, typename ComplexDerived> - inline - void inv( MatrixBase<OutputDerived> & dst, const MatrixBase<ComplexDerived> & src, Index nfft=-1) - { - typedef typename ComplexDerived::Scalar src_type; - typedef typename OutputDerived::Scalar dst_type; - const bool realfft= (NumTraits<dst_type>::IsComplex == 0); - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OutputDerived) - EIGEN_STATIC_ASSERT_VECTOR_ONLY(ComplexDerived) - EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(ComplexDerived,OutputDerived) // size at compile-time - EIGEN_STATIC_ASSERT((internal::is_same<src_type, Complex>::value), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - EIGEN_STATIC_ASSERT(int(OutputDerived::Flags)&int(ComplexDerived::Flags)&DirectAccessBit, - THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES) - - if (nfft<1) { //automatic FFT size determination - if ( realfft && HasFlag(HalfSpectrum) ) - nfft = 2*(src.size()-1); //assume even fft size - else - nfft = src.size(); - } - dst.derived().resize( nfft ); - - // check for nfft that does not fit the input data size - Index resize_input= ( realfft && HasFlag(HalfSpectrum) ) - ? ( (nfft/2+1) - src.size() ) - : ( nfft - src.size() ); - - if ( src.innerStride() != 1 || resize_input ) { - // if the vector is strided, then we need to copy it to a packed temporary - Matrix<src_type,1,Dynamic> tmp; - if ( resize_input ) { - size_t ncopy = (std::min)(src.size(),src.size() + resize_input); - tmp.setZero(src.size() + resize_input); - if ( realfft && HasFlag(HalfSpectrum) ) { - // pad at the Nyquist bin - tmp.head(ncopy) = src.head(ncopy); - tmp(ncopy-1) = real(tmp(ncopy-1)); // enforce real-only Nyquist bin - }else{ - size_t nhead,ntail; - nhead = 1+ncopy/2-1; // range [0:pi) - ntail = ncopy/2-1; // range (-pi:0) - tmp.head(nhead) = src.head(nhead); - tmp.tail(ntail) = src.tail(ntail); - if (resize_input<0) { //shrinking -- create the Nyquist bin as the average of the two bins that fold into it - tmp(nhead) = ( src(nfft/2) + src( src.size() - nfft/2 ) )*src_type(.5); - }else{ // expanding -- split the old Nyquist bin into two halves - tmp(nhead) = src(nhead) * src_type(.5); - tmp(tmp.size()-nhead) = tmp(nhead); - } - } - }else{ - tmp = src; - } - inv( &dst[0],&tmp[0], nfft); - }else{ - inv( &dst[0],&src[0], nfft); - } - } - - template <typename _Output> - inline - void inv( std::vector<_Output> & dst, const std::vector<Complex> & src,Index nfft=-1) - { - if (nfft<1) - nfft = ( NumTraits<_Output>::IsComplex == 0 && HasFlag(HalfSpectrum) ) ? 2*(src.size()-1) : src.size(); - dst.resize( nfft ); - inv( &dst[0],&src[0],nfft); - } - - - /* - // TODO: multi-dimensional FFTs - inline - void inv2(Complex * dst, const Complex * src, int n0,int n1) - { - m_impl.inv2(dst,src,n0,n1); - if ( HasFlag( Unscaled ) == false) - scale(dst,1./(n0*n1),n0*n1); - } - */ - - inline - impl_type & impl() {return m_impl;} - private: - - template <typename T_Data> - inline - void scale(T_Data * x,Scalar s,Index nx) - { -#if 1 - for (int k=0;k<nx;++k) - *x++ *= s; -#else - if ( ((ptrdiff_t)x) & 15 ) - Matrix<T_Data, Dynamic, 1>::Map(x,nx) *= s; - else - Matrix<T_Data, Dynamic, 1>::MapAligned(x,nx) *= s; - //Matrix<T_Data, Dynamic, Dynamic>::Map(x,nx) * s; -#endif - } - - inline - void ReflectSpectrum(Complex * freq, Index nfft) - { - // create the implicit right-half spectrum (conjugate-mirror of the left-half) - Index nhbins=(nfft>>1)+1; - for (Index k=nhbins;k < nfft; ++k ) - freq[k] = conj(freq[nfft-k]); - } - - impl_type m_impl; - int m_flag; -}; - -template<typename T_SrcMat,typename T_FftIfc> -template<typename T_DestMat> inline -void fft_fwd_proxy<T_SrcMat,T_FftIfc>::evalTo(T_DestMat& dst) const -{ - m_ifc.fwd( dst, m_src, m_nfft); -} - -template<typename T_SrcMat,typename T_FftIfc> -template<typename T_DestMat> inline -void fft_inv_proxy<T_SrcMat,T_FftIfc>::evalTo(T_DestMat& dst) const -{ - m_ifc.inv( dst, m_src, m_nfft); -} - -} -#endif -/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/third_party/eigen3/unsupported/Eigen/KroneckerProduct b/third_party/eigen3/unsupported/Eigen/KroneckerProduct deleted file mode 100644 index c932c06a6d..0000000000 --- a/third_party/eigen3/unsupported/Eigen/KroneckerProduct +++ /dev/null @@ -1,34 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// -// 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/. - -#ifndef EIGEN_KRONECKER_PRODUCT_MODULE_H -#define EIGEN_KRONECKER_PRODUCT_MODULE_H - -#include "../../Eigen/Core" - -#include "../../Eigen/src/Core/util/DisableStupidWarnings.h" - -namespace Eigen { - -/** - * \defgroup KroneckerProduct_Module KroneckerProduct module - * - * This module contains an experimental Kronecker product implementation. - * - * \code - * #include <Eigen/KroneckerProduct> - * \endcode - */ - -} // namespace Eigen - -#include "src/KroneckerProduct/KroneckerTensorProduct.h" - -#include "../../Eigen/src/Core/util/ReenableStupidWarnings.h" - -#endif // EIGEN_KRONECKER_PRODUCT_MODULE_H diff --git a/third_party/eigen3/unsupported/Eigen/src/FFT/CMakeLists.txt b/third_party/eigen3/unsupported/Eigen/src/FFT/CMakeLists.txt deleted file mode 100644 index edcffcb189..0000000000 --- a/third_party/eigen3/unsupported/Eigen/src/FFT/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -FILE(GLOB Eigen_FFT_SRCS "*.h") - -INSTALL(FILES - ${Eigen_FFT_SRCS} - DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/FFT COMPONENT Devel - ) diff --git a/third_party/eigen3/unsupported/Eigen/src/FFT/ei_fftw_impl.h b/third_party/eigen3/unsupported/Eigen/src/FFT/ei_fftw_impl.h deleted file mode 100644 index d49aa17f51..0000000000 --- a/third_party/eigen3/unsupported/Eigen/src/FFT/ei_fftw_impl.h +++ /dev/null @@ -1,261 +0,0 @@ -// 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/. - -namespace Eigen { - -namespace internal { - - // FFTW uses non-const arguments - // so we must use ugly const_cast calls for all the args it uses - // - // This should be safe as long as - // 1. we use FFTW_ESTIMATE for all our planning - // see the FFTW docs section 4.3.2 "Planner Flags" - // 2. fftw_complex is compatible with std::complex - // This assumes std::complex<T> layout is array of size 2 with real,imag - template <typename T> - inline - T * fftw_cast(const T* p) - { - return const_cast<T*>( p); - } - - inline - fftw_complex * fftw_cast( const std::complex<double> * p) - { - return const_cast<fftw_complex*>( reinterpret_cast<const fftw_complex*>(p) ); - } - - inline - fftwf_complex * fftw_cast( const std::complex<float> * p) - { - return const_cast<fftwf_complex*>( reinterpret_cast<const fftwf_complex*>(p) ); - } - - inline - fftwl_complex * fftw_cast( const std::complex<long double> * p) - { - return const_cast<fftwl_complex*>( reinterpret_cast<const fftwl_complex*>(p) ); - } - - template <typename T> - struct fftw_plan {}; - - template <> - struct fftw_plan<float> - { - typedef float scalar_type; - typedef fftwf_complex complex_type; - fftwf_plan m_plan; - fftw_plan() :m_plan(NULL) {} - ~fftw_plan() {if (m_plan) fftwf_destroy_plan(m_plan);} - - inline - void fwd(complex_type * dst,complex_type * src,int nfft) { - if (m_plan==NULL) m_plan = fftwf_plan_dft_1d(nfft,src,dst, FFTW_FORWARD, FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftwf_execute_dft( m_plan, src,dst); - } - inline - void inv(complex_type * dst,complex_type * src,int nfft) { - if (m_plan==NULL) m_plan = fftwf_plan_dft_1d(nfft,src,dst, FFTW_BACKWARD , FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftwf_execute_dft( m_plan, src,dst); - } - inline - void fwd(complex_type * dst,scalar_type * src,int nfft) { - if (m_plan==NULL) m_plan = fftwf_plan_dft_r2c_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftwf_execute_dft_r2c( m_plan,src,dst); - } - inline - void inv(scalar_type * dst,complex_type * src,int nfft) { - if (m_plan==NULL) - m_plan = fftwf_plan_dft_c2r_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftwf_execute_dft_c2r( m_plan, src,dst); - } - - inline - void fwd2( complex_type * dst,complex_type * src,int n0,int n1) { - if (m_plan==NULL) m_plan = fftwf_plan_dft_2d(n0,n1,src,dst,FFTW_FORWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftwf_execute_dft( m_plan, src,dst); - } - inline - void inv2( complex_type * dst,complex_type * src,int n0,int n1) { - if (m_plan==NULL) m_plan = fftwf_plan_dft_2d(n0,n1,src,dst,FFTW_BACKWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftwf_execute_dft( m_plan, src,dst); - } - - }; - template <> - struct fftw_plan<double> - { - typedef double scalar_type; - typedef fftw_complex complex_type; - ::fftw_plan m_plan; - fftw_plan() :m_plan(NULL) {} - ~fftw_plan() {if (m_plan) fftw_destroy_plan(m_plan);} - - inline - void fwd(complex_type * dst,complex_type * src,int nfft) { - if (m_plan==NULL) m_plan = fftw_plan_dft_1d(nfft,src,dst, FFTW_FORWARD, FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftw_execute_dft( m_plan, src,dst); - } - inline - void inv(complex_type * dst,complex_type * src,int nfft) { - if (m_plan==NULL) m_plan = fftw_plan_dft_1d(nfft,src,dst, FFTW_BACKWARD , FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftw_execute_dft( m_plan, src,dst); - } - inline - void fwd(complex_type * dst,scalar_type * src,int nfft) { - if (m_plan==NULL) m_plan = fftw_plan_dft_r2c_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftw_execute_dft_r2c( m_plan,src,dst); - } - inline - void inv(scalar_type * dst,complex_type * src,int nfft) { - if (m_plan==NULL) - m_plan = fftw_plan_dft_c2r_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftw_execute_dft_c2r( m_plan, src,dst); - } - inline - void fwd2( complex_type * dst,complex_type * src,int n0,int n1) { - if (m_plan==NULL) m_plan = fftw_plan_dft_2d(n0,n1,src,dst,FFTW_FORWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftw_execute_dft( m_plan, src,dst); - } - inline - void inv2( complex_type * dst,complex_type * src,int n0,int n1) { - if (m_plan==NULL) m_plan = fftw_plan_dft_2d(n0,n1,src,dst,FFTW_BACKWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftw_execute_dft( m_plan, src,dst); - } - }; - template <> - struct fftw_plan<long double> - { - typedef long double scalar_type; - typedef fftwl_complex complex_type; - fftwl_plan m_plan; - fftw_plan() :m_plan(NULL) {} - ~fftw_plan() {if (m_plan) fftwl_destroy_plan(m_plan);} - - inline - void fwd(complex_type * dst,complex_type * src,int nfft) { - if (m_plan==NULL) m_plan = fftwl_plan_dft_1d(nfft,src,dst, FFTW_FORWARD, FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftwl_execute_dft( m_plan, src,dst); - } - inline - void inv(complex_type * dst,complex_type * src,int nfft) { - if (m_plan==NULL) m_plan = fftwl_plan_dft_1d(nfft,src,dst, FFTW_BACKWARD , FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftwl_execute_dft( m_plan, src,dst); - } - inline - void fwd(complex_type * dst,scalar_type * src,int nfft) { - if (m_plan==NULL) m_plan = fftwl_plan_dft_r2c_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftwl_execute_dft_r2c( m_plan,src,dst); - } - inline - void inv(scalar_type * dst,complex_type * src,int nfft) { - if (m_plan==NULL) - m_plan = fftwl_plan_dft_c2r_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftwl_execute_dft_c2r( m_plan, src,dst); - } - inline - void fwd2( complex_type * dst,complex_type * src,int n0,int n1) { - if (m_plan==NULL) m_plan = fftwl_plan_dft_2d(n0,n1,src,dst,FFTW_FORWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftwl_execute_dft( m_plan, src,dst); - } - inline - void inv2( complex_type * dst,complex_type * src,int n0,int n1) { - if (m_plan==NULL) m_plan = fftwl_plan_dft_2d(n0,n1,src,dst,FFTW_BACKWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT); - fftwl_execute_dft( m_plan, src,dst); - } - }; - - template <typename _Scalar> - struct fftw_impl - { - typedef _Scalar Scalar; - typedef std::complex<Scalar> Complex; - - inline - void clear() - { - m_plans.clear(); - } - - // complex-to-complex forward FFT - inline - void fwd( Complex * dst,const Complex *src,int nfft) - { - get_plan(nfft,false,dst,src).fwd(fftw_cast(dst), fftw_cast(src),nfft ); - } - - // real-to-complex forward FFT - inline - void fwd( Complex * dst,const Scalar * src,int nfft) - { - get_plan(nfft,false,dst,src).fwd(fftw_cast(dst), fftw_cast(src) ,nfft); - } - - // 2-d complex-to-complex - inline - void fwd2(Complex * dst, const Complex * src, int n0,int n1) - { - get_plan(n0,n1,false,dst,src).fwd2(fftw_cast(dst), fftw_cast(src) ,n0,n1); - } - - // inverse complex-to-complex - inline - void inv(Complex * dst,const Complex *src,int nfft) - { - get_plan(nfft,true,dst,src).inv(fftw_cast(dst), fftw_cast(src),nfft ); - } - - // half-complex to scalar - inline - void inv( Scalar * dst,const Complex * src,int nfft) - { - get_plan(nfft,true,dst,src).inv(fftw_cast(dst), fftw_cast(src),nfft ); - } - - // 2-d complex-to-complex - inline - void inv2(Complex * dst, const Complex * src, int n0,int n1) - { - get_plan(n0,n1,true,dst,src).inv2(fftw_cast(dst), fftw_cast(src) ,n0,n1); - } - - - protected: - typedef fftw_plan<Scalar> PlanData; - - typedef std::map<int64_t,PlanData> PlanMap; - - PlanMap m_plans; - - inline - PlanData & get_plan(int nfft,bool inverse,void * dst,const void * src) - { - bool inplace = (dst==src); - bool aligned = ( (reinterpret_cast<size_t>(src)&15) | (reinterpret_cast<size_t>(dst)&15) ) == 0; - int64_t key = ( (nfft<<3 ) | (inverse<<2) | (inplace<<1) | aligned ) << 1; - return m_plans[key]; - } - - inline - PlanData & get_plan(int n0,int n1,bool inverse,void * dst,const void * src) - { - bool inplace = (dst==src); - bool aligned = ( (reinterpret_cast<size_t>(src)&15) | (reinterpret_cast<size_t>(dst)&15) ) == 0; - int64_t key = ( ( (((int64_t)n0) << 30)|(n1<<3 ) | (inverse<<2) | (inplace<<1) | aligned ) << 1 ) + 1; - return m_plans[key]; - } - }; - -} // end namespace internal - -} // end namespace Eigen - -/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/third_party/eigen3/unsupported/Eigen/src/FFT/ei_kissfft_impl.h b/third_party/eigen3/unsupported/Eigen/src/FFT/ei_kissfft_impl.h deleted file mode 100644 index be51b4e6fe..0000000000 --- a/third_party/eigen3/unsupported/Eigen/src/FFT/ei_kissfft_impl.h +++ /dev/null @@ -1,420 +0,0 @@ -// 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/. - -namespace Eigen { - -namespace internal { - - // This FFT implementation was derived from kissfft http:sourceforge.net/projects/kissfft - // Copyright 2003-2009 Mark Borgerding - -template <typename _Scalar> -struct kiss_cpx_fft -{ - typedef _Scalar Scalar; - typedef std::complex<Scalar> Complex; - std::vector<Complex> m_twiddles; - std::vector<int> m_stageRadix; - std::vector<int> m_stageRemainder; - std::vector<Complex> m_scratchBuf; - bool m_inverse; - - inline - void make_twiddles(int nfft,bool inverse) - { - using std::acos; - m_inverse = inverse; - m_twiddles.resize(nfft); - Scalar phinc = (inverse?2:-2)* acos( (Scalar) -1) / nfft; - for (int i=0;i<nfft;++i) - m_twiddles[i] = exp( Complex(0,i*phinc) ); - } - - void factorize(int nfft) - { - //start factoring out 4's, then 2's, then 3,5,7,9,... - int n= nfft; - int p=4; - do { - while (n % p) { - switch (p) { - case 4: p = 2; break; - case 2: p = 3; break; - default: p += 2; break; - } - if (p*p>n) - p=n;// impossible to have a factor > sqrt(n) - } - n /= p; - m_stageRadix.push_back(p); - m_stageRemainder.push_back(n); - if ( p > 5 ) - m_scratchBuf.resize(p); // scratchbuf will be needed in bfly_generic - }while(n>1); - } - - template <typename _Src> - inline - void work( int stage,Complex * xout, const _Src * xin, size_t fstride,size_t in_stride) - { - int p = m_stageRadix[stage]; - int m = m_stageRemainder[stage]; - Complex * Fout_beg = xout; - Complex * Fout_end = xout + p*m; - - if (m>1) { - do{ - // recursive call: - // DFT of size m*p performed by doing - // p instances of smaller DFTs of size m, - // each one takes a decimated version of the input - work(stage+1, xout , xin, fstride*p,in_stride); - xin += fstride*in_stride; - }while( (xout += m) != Fout_end ); - }else{ - do{ - *xout = *xin; - xin += fstride*in_stride; - }while(++xout != Fout_end ); - } - xout=Fout_beg; - - // recombine the p smaller DFTs - switch (p) { - case 2: bfly2(xout,fstride,m); break; - case 3: bfly3(xout,fstride,m); break; - case 4: bfly4(xout,fstride,m); break; - case 5: bfly5(xout,fstride,m); break; - default: bfly_generic(xout,fstride,m,p); break; - } - } - - inline - void bfly2( Complex * Fout, const size_t fstride, int m) - { - for (int k=0;k<m;++k) { - Complex t = Fout[m+k] * m_twiddles[k*fstride]; - Fout[m+k] = Fout[k] - t; - Fout[k] += t; - } - } - - inline - void bfly4( Complex * Fout, const size_t fstride, const size_t m) - { - Complex scratch[6]; - int negative_if_inverse = m_inverse * -2 +1; - for (size_t k=0;k<m;++k) { - scratch[0] = Fout[k+m] * m_twiddles[k*fstride]; - scratch[1] = Fout[k+2*m] * m_twiddles[k*fstride*2]; - scratch[2] = Fout[k+3*m] * m_twiddles[k*fstride*3]; - scratch[5] = Fout[k] - scratch[1]; - - Fout[k] += scratch[1]; - scratch[3] = scratch[0] + scratch[2]; - scratch[4] = scratch[0] - scratch[2]; - scratch[4] = Complex( scratch[4].imag()*negative_if_inverse , -scratch[4].real()* negative_if_inverse ); - - Fout[k+2*m] = Fout[k] - scratch[3]; - Fout[k] += scratch[3]; - Fout[k+m] = scratch[5] + scratch[4]; - Fout[k+3*m] = scratch[5] - scratch[4]; - } - } - - inline - void bfly3( Complex * Fout, const size_t fstride, const size_t m) - { - size_t k=m; - const size_t m2 = 2*m; - Complex *tw1,*tw2; - Complex scratch[5]; - Complex epi3; - epi3 = m_twiddles[fstride*m]; - - tw1=tw2=&m_twiddles[0]; - - do{ - scratch[1]=Fout[m] * *tw1; - scratch[2]=Fout[m2] * *tw2; - - scratch[3]=scratch[1]+scratch[2]; - scratch[0]=scratch[1]-scratch[2]; - tw1 += fstride; - tw2 += fstride*2; - Fout[m] = Complex( Fout->real() - Scalar(.5)*scratch[3].real() , Fout->imag() - Scalar(.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); - } - - inline - 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<m; ++u ) { - scratch[0] = *Fout0; - - scratch[1] = *Fout1 * tw[u*fstride]; - scratch[2] = *Fout2 * tw[2*u*fstride]; - scratch[3] = *Fout3 * tw[3*u*fstride]; - scratch[4] = *Fout4 * tw[4*u*fstride]; - - scratch[7] = scratch[1] + scratch[4]; - scratch[10] = scratch[1] - scratch[4]; - scratch[8] = scratch[2] + scratch[3]; - scratch[9] = scratch[2] - scratch[3]; - - *Fout0 += scratch[7]; - *Fout0 += scratch[8]; - - scratch[5] = scratch[0] + Complex( - (scratch[7].real()*ya.real() ) + (scratch[8].real() *yb.real() ), - (scratch[7].imag()*ya.real()) + (scratch[8].imag()*yb.real()) - ); - - scratch[6] = Complex( - (scratch[10].imag()*ya.imag()) + (scratch[9].imag()*yb.imag()), - -(scratch[10].real()*ya.imag()) - (scratch[9].real()*yb.imag()) - ); - - *Fout1 = scratch[5] - scratch[6]; - *Fout4 = scratch[5] + scratch[6]; - - scratch[11] = scratch[0] + - Complex( - (scratch[7].real()*yb.real()) + (scratch[8].real()*ya.real()), - (scratch[7].imag()*yb.real()) + (scratch[8].imag()*ya.real()) - ); - - scratch[12] = Complex( - -(scratch[10].imag()*yb.imag()) + (scratch[9].imag()*ya.imag()), - (scratch[10].real()*yb.imag()) - (scratch[9].real()*ya.imag()) - ); - - *Fout2=scratch[11]+scratch[12]; - *Fout3=scratch[11]-scratch[12]; - - ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; - } - } - - /* perform the butterfly for one stage of a mixed radix FFT */ - inline - void bfly_generic( - Complex * Fout, - const size_t fstride, - int m, - int p - ) - { - int u,k,q1,q; - Complex * twiddles = &m_twiddles[0]; - Complex t; - int Norig = static_cast<int>(m_twiddles.size()); - Complex * scratchbuf = &m_scratchBuf[0]; - - for ( u=0; u<m; ++u ) { - k=u; - for ( q1=0 ; q1<p ; ++q1 ) { - scratchbuf[q1] = Fout[ k ]; - k += m; - } - - k=u; - for ( q1=0 ; q1<p ; ++q1 ) { - int twidx=0; - Fout[ k ] = scratchbuf[0]; - for (q=1;q<p;++q ) { - twidx += static_cast<int>(fstride) * k; - if (twidx>=Norig) twidx-=Norig; - t=scratchbuf[q] * twiddles[twidx]; - Fout[ k ] += t; - } - k += m; - } - } - } -}; - -template <typename _Scalar> -struct kissfft_impl -{ - typedef _Scalar Scalar; - typedef std::complex<Scalar> Complex; - - void clear() - { - m_plans.clear(); - m_realTwiddles.clear(); - } - - inline - void fwd( Complex * dst,const Complex *src,int nfft) - { - get_plan(nfft,false).work(0, dst, src, 1,1); - } - - inline - void fwd2( Complex * dst,const Complex *src,int n0,int n1) - { - EIGEN_UNUSED_VARIABLE(dst); - EIGEN_UNUSED_VARIABLE(src); - EIGEN_UNUSED_VARIABLE(n0); - EIGEN_UNUSED_VARIABLE(n1); - } - - inline - void inv2( Complex * dst,const Complex *src,int n0,int n1) - { - EIGEN_UNUSED_VARIABLE(dst); - EIGEN_UNUSED_VARIABLE(src); - EIGEN_UNUSED_VARIABLE(n0); - EIGEN_UNUSED_VARIABLE(n1); - } - - // real-to-complex forward FFT - // perform two FFTs of src even and src odd - // then twiddle to recombine them into the half-spectrum format - // then fill in the conjugate symmetric half - inline - void fwd( Complex * dst,const Scalar * src,int nfft) - { - if ( nfft&3 ) { - // use generic mode for odd - m_tmpBuf1.resize(nfft); - get_plan(nfft,false).work(0, &m_tmpBuf1[0], src, 1,1); - std::copy(m_tmpBuf1.begin(),m_tmpBuf1.begin()+(nfft>>1)+1,dst ); - }else{ - int ncfft = nfft>>1; - int ncfft2 = nfft>>2; - Complex * rtw = real_twiddles(ncfft2); - - // use optimized mode for even real - fwd( dst, reinterpret_cast<const Complex*> (src), ncfft); - Complex dc = dst[0].real() + dst[0].imag(); - Complex nyquist = dst[0].real() - dst[0].imag(); - int k; - for ( k=1;k <= ncfft2 ; ++k ) { - Complex fpk = dst[k]; - Complex fpnk = conj(dst[ncfft-k]); - Complex f1k = fpk + fpnk; - Complex f2k = fpk - fpnk; - Complex tw= f2k * rtw[k-1]; - dst[k] = (f1k + tw) * Scalar(.5); - dst[ncfft-k] = conj(f1k -tw)*Scalar(.5); - } - dst[0] = dc; - dst[ncfft] = nyquist; - } - } - - // inverse complex-to-complex - inline - void inv(Complex * dst,const Complex *src,int nfft) - { - get_plan(nfft,true).work(0, dst, src, 1,1); - } - - // half-complex to scalar - inline - void inv( Scalar * dst,const Complex * src,int nfft) - { - if (nfft&3) { - m_tmpBuf1.resize(nfft); - m_tmpBuf2.resize(nfft); - std::copy(src,src+(nfft>>1)+1,m_tmpBuf1.begin() ); - for (int k=1;k<(nfft>>1)+1;++k) - m_tmpBuf1[nfft-k] = conj(m_tmpBuf1[k]); - inv(&m_tmpBuf2[0],&m_tmpBuf1[0],nfft); - for (int k=0;k<nfft;++k) - dst[k] = m_tmpBuf2[k].real(); - }else{ - // optimized version for multiple of 4 - int ncfft = nfft>>1; - int ncfft2 = nfft>>2; - Complex * rtw = real_twiddles(ncfft2); - m_tmpBuf1.resize(ncfft); - m_tmpBuf1[0] = Complex( src[0].real() + src[ncfft].real(), src[0].real() - src[ncfft].real() ); - for (int k = 1; k <= ncfft / 2; ++k) { - Complex fk = src[k]; - Complex fnkc = conj(src[ncfft-k]); - Complex fek = fk + fnkc; - Complex tmp = fk - fnkc; - Complex fok = tmp * conj(rtw[k-1]); - m_tmpBuf1[k] = fek + fok; - m_tmpBuf1[ncfft-k] = conj(fek - fok); - } - get_plan(ncfft,true).work(0, reinterpret_cast<Complex*>(dst), &m_tmpBuf1[0], 1,1); - } - } - - protected: - typedef kiss_cpx_fft<Scalar> PlanData; - typedef std::map<int,PlanData> PlanMap; - - PlanMap m_plans; - std::map<int, std::vector<Complex> > m_realTwiddles; - std::vector<Complex> m_tmpBuf1; - std::vector<Complex> m_tmpBuf2; - - inline - int PlanKey(int nfft, bool isinverse) const { return (nfft<<1) | int(isinverse); } - - inline - PlanData & get_plan(int nfft, bool inverse) - { - // TODO look for PlanKey(nfft, ! inverse) and conjugate the twiddles - PlanData & pd = m_plans[ PlanKey(nfft,inverse) ]; - if ( pd.m_twiddles.size() == 0 ) { - pd.make_twiddles(nfft,inverse); - pd.factorize(nfft); - } - return pd; - } - - inline - Complex * real_twiddles(int ncfft2) - { - using std::acos; - std::vector<Complex> & twidref = m_realTwiddles[ncfft2];// creates new if not there - if ( (int)twidref.size() != ncfft2 ) { - twidref.resize(ncfft2); - int ncfft= ncfft2<<1; - Scalar pi = acos( Scalar(-1) ); - for (int k=1;k<=ncfft2;++k) - twidref[k-1] = exp( Complex(0,-pi * (Scalar(k) / ncfft + Scalar(.5)) ) ); - } - return &twidref[0]; - } -}; - -} // end namespace internal - -} // end namespace Eigen - -/* vim: set filetype=cpp et sw=2 ts=2 ai: */ diff --git a/third_party/eigen3/unsupported/Eigen/src/KroneckerProduct/CMakeLists.txt b/third_party/eigen3/unsupported/Eigen/src/KroneckerProduct/CMakeLists.txt deleted file mode 100644 index 4daefebee6..0000000000 --- a/third_party/eigen3/unsupported/Eigen/src/KroneckerProduct/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -FILE(GLOB Eigen_KroneckerProduct_SRCS "*.h") - -INSTALL(FILES - ${Eigen_KroneckerProduct_SRCS} - DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/KroneckerProduct COMPONENT Devel - ) diff --git a/third_party/eigen3/unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h b/third_party/eigen3/unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h deleted file mode 100644 index b8f2cba173..0000000000 --- a/third_party/eigen3/unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h +++ /dev/null @@ -1,297 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2011 Kolja Brix <brix@igpm.rwth-aachen.de> -// Copyright (C) 2011 Andreas Platen <andiplaten@gmx.de> -// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.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/. - -#ifndef KRONECKER_TENSOR_PRODUCT_H -#define KRONECKER_TENSOR_PRODUCT_H - -namespace Eigen { - -/*! - * \ingroup KroneckerProduct_Module - * - * \brief The base class of dense and sparse Kronecker product. - * - * \tparam Derived is the derived type. - */ -template<typename Derived> -class KroneckerProductBase : public ReturnByValue<Derived> -{ - private: - typedef typename internal::traits<Derived> Traits; - typedef typename Traits::Scalar Scalar; - - protected: - typedef typename Traits::Lhs Lhs; - typedef typename Traits::Rhs Rhs; - typedef typename Traits::Index Index; - - public: - /*! \brief Constructor. */ - KroneckerProductBase(const Lhs& A, const Rhs& B) - : m_A(A), m_B(B) - {} - - inline Index rows() const { return m_A.rows() * m_B.rows(); } - inline Index cols() const { return m_A.cols() * m_B.cols(); } - - /*! - * This overrides ReturnByValue::coeff because this function is - * efficient enough. - */ - Scalar coeff(Index row, Index col) const - { - return m_A.coeff(row / m_B.rows(), col / m_B.cols()) * - m_B.coeff(row % m_B.rows(), col % m_B.cols()); - } - - /*! - * This overrides ReturnByValue::coeff because this function is - * efficient enough. - */ - Scalar coeff(Index i) const - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); - return m_A.coeff(i / m_A.size()) * m_B.coeff(i % m_A.size()); - } - - protected: - typename Lhs::Nested m_A; - typename Rhs::Nested m_B; -}; - -/*! - * \ingroup KroneckerProduct_Module - * - * \brief Kronecker tensor product helper class for dense matrices - * - * This class is the return value of kroneckerProduct(MatrixBase, - * MatrixBase). Use the function rather than construct this class - * directly to avoid specifying template prarameters. - * - * \tparam Lhs Type of the left-hand side, a matrix expression. - * \tparam Rhs Type of the rignt-hand side, a matrix expression. - */ -template<typename Lhs, typename Rhs> -class KroneckerProduct : public KroneckerProductBase<KroneckerProduct<Lhs,Rhs> > -{ - private: - typedef KroneckerProductBase<KroneckerProduct> Base; - using Base::m_A; - using Base::m_B; - - public: - /*! \brief Constructor. */ - KroneckerProduct(const Lhs& A, const Rhs& B) - : Base(A, B) - {} - - /*! \brief Evaluate the Kronecker tensor product. */ - template<typename Dest> void evalTo(Dest& dst) const; -}; - -/*! - * \ingroup KroneckerProduct_Module - * - * \brief Kronecker tensor product helper class for sparse matrices - * - * If at least one of the operands is a sparse matrix expression, - * then this class is returned and evaluates into a sparse matrix. - * - * This class is the return value of kroneckerProduct(EigenBase, - * EigenBase). Use the function rather than construct this class - * directly to avoid specifying template prarameters. - * - * \tparam Lhs Type of the left-hand side, a matrix expression. - * \tparam Rhs Type of the rignt-hand side, a matrix expression. - */ -template<typename Lhs, typename Rhs> -class KroneckerProductSparse : public KroneckerProductBase<KroneckerProductSparse<Lhs,Rhs> > -{ - private: - typedef KroneckerProductBase<KroneckerProductSparse> Base; - using Base::m_A; - using Base::m_B; - - public: - /*! \brief Constructor. */ - KroneckerProductSparse(const Lhs& A, const Rhs& B) - : Base(A, B) - {} - - /*! \brief Evaluate the Kronecker tensor product. */ - template<typename Dest> void evalTo(Dest& dst) const; -}; - -template<typename Lhs, typename Rhs> -template<typename Dest> -void KroneckerProduct<Lhs,Rhs>::evalTo(Dest& dst) const -{ - typedef typename Base::Index Index; - const int BlockRows = Rhs::RowsAtCompileTime, - BlockCols = Rhs::ColsAtCompileTime; - const Index Br = m_B.rows(), - Bc = m_B.cols(); - for (Index i=0; i < m_A.rows(); ++i) - for (Index j=0; j < m_A.cols(); ++j) - Block<Dest,BlockRows,BlockCols>(dst,i*Br,j*Bc,Br,Bc) = m_A.coeff(i,j) * m_B; -} - -template<typename Lhs, typename Rhs> -template<typename Dest> -void KroneckerProductSparse<Lhs,Rhs>::evalTo(Dest& dst) const -{ - typedef typename Base::Index Index; - const Index Br = m_B.rows(), - Bc = m_B.cols(); - dst.resize(this->rows(), this->cols()); - dst.resizeNonZeros(0); - - // compute number of non-zeros per innervectors of dst - { - VectorXi nnzA = VectorXi::Zero(Dest::IsRowMajor ? m_A.rows() : m_A.cols()); - for (Index kA=0; kA < m_A.outerSize(); ++kA) - for (typename Lhs::InnerIterator itA(m_A,kA); itA; ++itA) - nnzA(Dest::IsRowMajor ? itA.row() : itA.col())++; - - VectorXi nnzB = VectorXi::Zero(Dest::IsRowMajor ? m_B.rows() : m_B.cols()); - for (Index kB=0; kB < m_B.outerSize(); ++kB) - for (typename Rhs::InnerIterator itB(m_B,kB); itB; ++itB) - nnzB(Dest::IsRowMajor ? itB.row() : itB.col())++; - - Matrix<int,Dynamic,Dynamic,ColMajor> nnzAB = nnzB * nnzA.transpose(); - dst.reserve(VectorXi::Map(nnzAB.data(), nnzAB.size())); - } - - for (Index kA=0; kA < m_A.outerSize(); ++kA) - { - for (Index kB=0; kB < m_B.outerSize(); ++kB) - { - for (typename Lhs::InnerIterator itA(m_A,kA); itA; ++itA) - { - for (typename Rhs::InnerIterator itB(m_B,kB); itB; ++itB) - { - const Index i = itA.row() * Br + itB.row(), - j = itA.col() * Bc + itB.col(); - dst.insert(i,j) = itA.value() * itB.value(); - } - } - } - } -} - -namespace internal { - -template<typename _Lhs, typename _Rhs> -struct traits<KroneckerProduct<_Lhs,_Rhs> > -{ - typedef typename remove_all<_Lhs>::type Lhs; - typedef typename remove_all<_Rhs>::type Rhs; - typedef typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar; - typedef typename promote_index_type<typename Lhs::Index, typename Rhs::Index>::type Index; - - enum { - Rows = size_at_compile_time<traits<Lhs>::RowsAtCompileTime, traits<Rhs>::RowsAtCompileTime>::ret, - Cols = size_at_compile_time<traits<Lhs>::ColsAtCompileTime, traits<Rhs>::ColsAtCompileTime>::ret, - MaxRows = size_at_compile_time<traits<Lhs>::MaxRowsAtCompileTime, traits<Rhs>::MaxRowsAtCompileTime>::ret, - MaxCols = size_at_compile_time<traits<Lhs>::MaxColsAtCompileTime, traits<Rhs>::MaxColsAtCompileTime>::ret, - CoeffReadCost = Lhs::CoeffReadCost + Rhs::CoeffReadCost + NumTraits<Scalar>::MulCost - }; - - typedef Matrix<Scalar,Rows,Cols> ReturnType; -}; - -template<typename _Lhs, typename _Rhs> -struct traits<KroneckerProductSparse<_Lhs,_Rhs> > -{ - typedef MatrixXpr XprKind; - typedef typename remove_all<_Lhs>::type Lhs; - typedef typename remove_all<_Rhs>::type Rhs; - typedef typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar; - typedef typename promote_storage_type<typename traits<Lhs>::StorageKind, typename traits<Rhs>::StorageKind>::ret StorageKind; - typedef typename promote_index_type<typename Lhs::Index, typename Rhs::Index>::type Index; - - enum { - LhsFlags = Lhs::Flags, - RhsFlags = Rhs::Flags, - - RowsAtCompileTime = size_at_compile_time<traits<Lhs>::RowsAtCompileTime, traits<Rhs>::RowsAtCompileTime>::ret, - ColsAtCompileTime = size_at_compile_time<traits<Lhs>::ColsAtCompileTime, traits<Rhs>::ColsAtCompileTime>::ret, - MaxRowsAtCompileTime = size_at_compile_time<traits<Lhs>::MaxRowsAtCompileTime, traits<Rhs>::MaxRowsAtCompileTime>::ret, - MaxColsAtCompileTime = size_at_compile_time<traits<Lhs>::MaxColsAtCompileTime, traits<Rhs>::MaxColsAtCompileTime>::ret, - - EvalToRowMajor = (LhsFlags & RhsFlags & RowMajorBit), - RemovedBits = ~(EvalToRowMajor ? 0 : RowMajorBit), - - Flags = ((LhsFlags | RhsFlags) & HereditaryBits & RemovedBits) - | EvalBeforeNestingBit | EvalBeforeAssigningBit, - CoeffReadCost = Dynamic - }; - - typedef SparseMatrix<Scalar> ReturnType; -}; - -} // end namespace internal - -/*! - * \ingroup KroneckerProduct_Module - * - * Computes Kronecker tensor product of two dense matrices - * - * \warning If you want to replace a matrix by its Kronecker product - * with some matrix, do \b NOT do this: - * \code - * A = kroneckerProduct(A,B); // bug!!! caused by aliasing effect - * \endcode - * instead, use eval() to work around this: - * \code - * A = kroneckerProduct(A,B).eval(); - * \endcode - * - * \param a Dense matrix a - * \param b Dense matrix b - * \return Kronecker tensor product of a and b - */ -template<typename A, typename B> -KroneckerProduct<A,B> kroneckerProduct(const MatrixBase<A>& a, const MatrixBase<B>& b) -{ - return KroneckerProduct<A, B>(a.derived(), b.derived()); -} - -/*! - * \ingroup KroneckerProduct_Module - * - * Computes Kronecker tensor product of two matrices, at least one of - * which is sparse - * - * \warning If you want to replace a matrix by its Kronecker product - * with some matrix, do \b NOT do this: - * \code - * A = kroneckerProduct(A,B); // bug!!! caused by aliasing effect - * \endcode - * instead, use eval() to work around this: - * \code - * A = kroneckerProduct(A,B).eval(); - * \endcode - * - * \param a Dense/sparse matrix a - * \param b Dense/sparse matrix b - * \return Kronecker tensor product of a and b, stored in a sparse - * matrix - */ -template<typename A, typename B> -KroneckerProductSparse<A,B> kroneckerProduct(const EigenBase<A>& a, const EigenBase<B>& b) -{ - return KroneckerProductSparse<A,B>(a.derived(), b.derived()); -} - -} // end namespace Eigen - -#endif // KRONECKER_TENSOR_PRODUCT_H |