From 1c2e476fa745d7323d77959d5fb88fd3587be187 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Mon, 30 Nov 2009 18:56:56 +0100 Subject: [PATCH 01/14] Initial commit for a modified ei_nested logic. --- Eigen/src/Core/util/XprHelper.h | 61 +++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index be4266f85..7f58797d7 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -171,6 +171,46 @@ template struct ei_plain_matrix_type_row_major template struct ei_must_nest_by_value { enum { ret = false }; }; template struct ei_must_nest_by_value > { enum { ret = true }; }; +/** +* Just a sanity check in order to verify that NestByValue is never +* used in combination with Matrix. Currently, I don't see a use case +* for nesting matrices by value. When an expression requires a temporary +* this should be handled through PlainMatrixType (i.e. arithmetic cost +* check + eval before nesting check). +* Note: If this were happening there were no harm but - if we are sure +* this does not happen, we can actually get rid of NestByValue! +**/ +template struct ei_is_nested_matrix { typedef int ok; }; +template +struct ei_is_nested_matrix< NestByValue< Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > > {}; + +/** +* The reference selector for template expressions. The idea is that we don't +* need to use references for expressions since they are light weight proxy +* objects which should generate no copying overhead. +**/ +template +struct ei_ref_selector +{ + typedef T type; +}; + +/** +* Matrices on the other hand side should only be copied, when it is sure +* we gain by copying (see arithmetic cost check and eval before nesting flag). +* Note: This is an optimization measure that comprises potential (though little) +* to create erroneous code. Any user, utilizing ei_nested outside of +* Eigen needs to take care that no references to temporaries are +* stored or that this potential danger is at least communicated +* to the user. +**/ +template +struct ei_ref_selector< Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > +{ + typedef typename Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> MatrixType; + typedef MatrixType const& type; +}; + /** \internal Determines how a given expression should be nested into another one. * For example, when you do a * (b+c), Eigen will determine how the expression b+c should be * nested into the bigger product expression. The choice is between nesting the expression b+c as-is, or @@ -195,15 +235,22 @@ template::ty CostEval = (n+1) * int(NumTraits::Scalar>::ReadCost), CostNoEval = (n-1) * int(ei_traits::CoeffReadCost) }; + + typedef typename ei_is_nested_matrix::ok is_ok; + typedef typename ei_meta_if< ei_must_nest_by_value::ret, - T, - typename ei_meta_if< - (int(ei_traits::Flags) & EvalBeforeNestingBit) - || ( int(CostEval) <= int(CostNoEval) ), - PlainMatrixType, - const T& - >::ret + T, + typename ei_meta_if< + ( int(ei_traits::Flags) & EvalBeforeNestingBit ) || + ( int(CostEval) <= int(CostNoEval) ), + PlainMatrixType, +#ifdef EIGEN_OLD_NESTED + const T& +#else + typename ei_ref_selector::type +#endif + >::ret >::ret type; }; From e6c560aedfff176cbc6df40eedd4c5cf343b0fa6 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Mon, 30 Nov 2009 19:06:07 +0100 Subject: [PATCH 02/14] Removed wrong typename. --- Eigen/src/Core/util/XprHelper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index 7f58797d7..d1250c009 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -207,7 +207,7 @@ struct ei_ref_selector template struct ei_ref_selector< Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > { - typedef typename Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> MatrixType; + typedef Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> MatrixType; typedef MatrixType const& type; }; From b2a5fb874f6b2d60d497180cf83e0f0ac6ae0cc8 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Tue, 1 Dec 2009 06:21:29 +0100 Subject: [PATCH 03/14] add specialization ei_ref_selector for sparse matrix types --- Eigen/src/Sparse/DynamicSparseMatrix.h | 7 +++++++ Eigen/src/Sparse/SparseDiagonalProduct.h | 3 +-- Eigen/src/Sparse/SparseMatrix.h | 7 +++++++ Eigen/src/Sparse/SparseVector.h | 7 +++++++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Eigen/src/Sparse/DynamicSparseMatrix.h b/Eigen/src/Sparse/DynamicSparseMatrix.h index 15135f9db..189a56bd0 100644 --- a/Eigen/src/Sparse/DynamicSparseMatrix.h +++ b/Eigen/src/Sparse/DynamicSparseMatrix.h @@ -57,6 +57,13 @@ struct ei_traits > }; }; +template +struct ei_ref_selector< DynamicSparseMatrix<_Scalar, _Options> > +{ + typedef DynamicSparseMatrix<_Scalar, _Options> MatrixType; + typedef MatrixType const& type; +}; + template class DynamicSparseMatrix : public SparseMatrixBase > diff --git a/Eigen/src/Sparse/SparseDiagonalProduct.h b/Eigen/src/Sparse/SparseDiagonalProduct.h index 5fb149a2c..f12ccb929 100644 --- a/Eigen/src/Sparse/SparseDiagonalProduct.h +++ b/Eigen/src/Sparse/SparseDiagonalProduct.h @@ -85,8 +85,7 @@ class SparseDiagonalProduct typedef ei_sparse_diagonal_product_inner_iterator_selector <_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator; - template - EIGEN_STRONG_INLINE SparseDiagonalProduct(const _Lhs& lhs, const _Rhs& rhs) + EIGEN_STRONG_INLINE SparseDiagonalProduct(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs) { ei_assert(lhs.cols() == rhs.rows() && "invalid sparse matrix * diagonal matrix product"); diff --git a/Eigen/src/Sparse/SparseMatrix.h b/Eigen/src/Sparse/SparseMatrix.h index 7010602b7..36fa123fb 100644 --- a/Eigen/src/Sparse/SparseMatrix.h +++ b/Eigen/src/Sparse/SparseMatrix.h @@ -56,6 +56,13 @@ struct ei_traits > }; }; +template +struct ei_ref_selector > +{ + typedef SparseMatrix<_Scalar, _Options> MatrixType; + typedef MatrixType const& type; +}; + template class SparseMatrix : public SparseMatrixBase > diff --git a/Eigen/src/Sparse/SparseVector.h b/Eigen/src/Sparse/SparseVector.h index 8c8728b87..1fa1980b2 100644 --- a/Eigen/src/Sparse/SparseVector.h +++ b/Eigen/src/Sparse/SparseVector.h @@ -51,6 +51,13 @@ struct ei_traits > }; }; +template +struct ei_ref_selector< SparseVector<_Scalar, _Options> > +{ + typedef SparseVector<_Scalar, _Options> MatrixType; + typedef MatrixType const& type; +}; + template class SparseVector : public SparseMatrixBase > From 7af1ee0b6c2bd3ef372ce1f8b6baa714227205f5 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Tue, 1 Dec 2009 07:53:09 +0100 Subject: [PATCH 04/14] Added the profiling test to unsupported. --- unsupported/test/CMakeLists.txt | 1 + unsupported/test/nesting_profiling.cpp | 199 +++++++++++++++++++++++++ 2 files changed, 200 insertions(+) create mode 100644 unsupported/test/nesting_profiling.cpp diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt index 58af79351..3f7211777 100644 --- a/unsupported/test/CMakeLists.txt +++ b/unsupported/test/CMakeLists.txt @@ -17,6 +17,7 @@ ei_add_test(BVH) ei_add_test(matrixExponential) ei_add_test(alignedvector3) ei_add_test(FFT) +ei_add_test(nesting_profiling) find_package(FFTW) if(FFTW_FOUND) diff --git a/unsupported/test/nesting_profiling.cpp b/unsupported/test/nesting_profiling.cpp new file mode 100644 index 000000000..c19081e5a --- /dev/null +++ b/unsupported/test/nesting_profiling.cpp @@ -0,0 +1,199 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Hauke Heibel +// +// 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" + +#define EIGEN_OLD_NESTED + +#include "Eigen/Core" +#include "Eigen/Array" +#include "Eigen/Geometry" + +#include "Bench/BenchTimer.h" + +using namespace Eigen; + +struct Transform2D +{ + static void run(int num_runs) + { + const Matrix2d T = Matrix2d::Random(); + const Vector2d t = Vector2d::Random(); + const Matrix2Xd pts = Matrix2Xd::Random(2,100); + + Matrix2Xd res; + for (int i=0; i(t); + } +}; + +struct ColwiseTransform2D +{ + static void run(int num_runs) + { + const Matrix2d T = Matrix2d::Random(); + const Vector2d t = Vector2d::Random(); + const Matrix2Xd pts = Matrix2Xd::Random(2,100); + + Matrix2Xd res; + for (int i=0; i(t); + } +}; + +struct LinearCombination +{ + typedef Eigen::Matrix Matrix2x4d; + + static void run(int num_runs) + { + const Matrix2Xd pts = Matrix2Xd::Random(2,100); + const Matrix2x4d coefs = Matrix2x4d::Random(); + + Matrix2x4d linear_combined = Matrix2x4d::Zero(); + for (int i=0; i(coefs.row(r)); + } +}; + +template +struct VectorAddition +{ + typedef VectorType ReturnType; + EIGEN_DONT_INLINE static VectorType run(int) + { + VectorType a,b,c,d; + return a+b+c+d; + } +}; + +template +struct MatrixProduct +{ + typedef MatrixType ReturnType; + EIGEN_DONT_INLINE static MatrixType run(int num_runs) + { + MatrixType a,b; + return a*b; + } +}; + +template +struct MatrixScaling +{ + typedef MatrixType ReturnType; + EIGEN_DONT_INLINE static MatrixType run(int num_runs) + { + ei_traits::Scalar s; + MatrixType a,b; + return s*a; + } +}; + +template +EIGEN_DONT_INLINE void run(int num_runs) +{ + for (int outer_runs=0; outer_runs<30; ++outer_runs) + { + //BenchTimer timer; + //const double start = timer.getTime(); + { + TestFunction::run(num_runs); + } + //const double stop = timer.getTime(); + //std::cout << (stop-start)*1000.0 << " ms" << std::endl; + } +} + +template +EIGEN_DONT_INLINE void run_direct(int num_runs = 1) +{ + for (int outer_runs=0; outer_runs<30; ++outer_runs) + { + // required to prevent that the compiler replaces the run-call by nop + typename TestFunction::ReturnType return_type; + for (int i=0; i(num_runs); + run(num_runs); + run(num_runs); + } + const double stop = timer.getTime(); + std::cout << (stop-start)*1000.0 << " ms" << std::endl; + + // leads to identical assembly + run_direct< MatrixProduct >(); + run_direct< MatrixProduct >(); + run_direct< MatrixProduct >(); + + // leads to identical assembly + run_direct< MatrixScaling >(); + run_direct< MatrixScaling >(); + run_direct< MatrixScaling >(); + + // leads to better assembly + run_direct< VectorAddition >(); + run_direct< VectorAddition >(); + run_direct< VectorAddition >(); +} From 1fc5fdea25212431f0029062b78da5c0cc1621b8 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Tue, 1 Dec 2009 09:20:05 +0100 Subject: [PATCH 05/14] Added missing typedef (will I ever learn it!?) Removed unsupported directories that do not provide CMakeList.txt (CMake 2.8 warning). The BenchTimer is now also working on Cygwin. --- bench/BenchTimer.h | 15 ++++++++------- unsupported/Eigen/src/CMakeLists.txt | 4 ++-- unsupported/test/nesting_profiling.cpp | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/bench/BenchTimer.h b/bench/BenchTimer.h index 70173427f..b2d0fc5f6 100644 --- a/bench/BenchTimer.h +++ b/bench/BenchTimer.h @@ -26,12 +26,13 @@ #ifndef EIGEN_BENCH_TIMER_H #define EIGEN_BENCH_TIMER_H -#ifndef WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) +#define NOMINMAX +#define WIN32_LEAN_AND_MEAN +#include +#else #include #include -#else -#define NOMINMAX -#include #endif #include @@ -53,7 +54,7 @@ public: BenchTimer() { -#ifdef WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); m_frequency = (double)freq.QuadPart; @@ -77,7 +78,7 @@ public: return m_best; } -#ifdef WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) inline double getTime(void) #else static inline double getTime(void) @@ -95,7 +96,7 @@ public: } protected: -#ifdef WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) double m_frequency; #endif double m_best, m_start; diff --git a/unsupported/Eigen/src/CMakeLists.txt b/unsupported/Eigen/src/CMakeLists.txt index 195808c59..a0870d3af 100644 --- a/unsupported/Eigen/src/CMakeLists.txt +++ b/unsupported/Eigen/src/CMakeLists.txt @@ -2,6 +2,6 @@ ADD_SUBDIRECTORY(IterativeSolvers) ADD_SUBDIRECTORY(BVH) ADD_SUBDIRECTORY(AutoDiff) ADD_SUBDIRECTORY(MoreVectorization) -ADD_SUBDIRECTORY(FFT) -ADD_SUBDIRECTORY(Skyline) +# ADD_SUBDIRECTORY(FFT) +# ADD_SUBDIRECTORY(Skyline) ADD_SUBDIRECTORY(MatrixFunctions) diff --git a/unsupported/test/nesting_profiling.cpp b/unsupported/test/nesting_profiling.cpp index c19081e5a..bee5b3c70 100644 --- a/unsupported/test/nesting_profiling.cpp +++ b/unsupported/test/nesting_profiling.cpp @@ -132,7 +132,7 @@ struct MatrixScaling typedef MatrixType ReturnType; EIGEN_DONT_INLINE static MatrixType run(int num_runs) { - ei_traits::Scalar s; + typename ei_traits::Scalar s; MatrixType a,b; return s*a; } From 82971a5dcda3dcb36465c0984f69a98a31baf7e7 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Tue, 1 Dec 2009 09:29:56 +0100 Subject: [PATCH 06/14] Adapted the number of test runs. --- unsupported/test/nesting_profiling.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unsupported/test/nesting_profiling.cpp b/unsupported/test/nesting_profiling.cpp index bee5b3c70..c0803bd46 100644 --- a/unsupported/test/nesting_profiling.cpp +++ b/unsupported/test/nesting_profiling.cpp @@ -169,7 +169,7 @@ EIGEN_DONT_INLINE void run_direct(int num_runs = 1) void test_nesting_profiling() { - const int num_runs = 100000; + const int num_runs = 10000; BenchTimer timer; const double start = timer.getTime(); From 88be82679171c3ef13c432949f4b635482b422e3 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Tue, 1 Dec 2009 09:49:15 +0100 Subject: [PATCH 07/14] Removed NestByValue dependency from MatrixBase::select(). --- Eigen/src/Array/Select.h | 8 ++++---- Eigen/src/Core/MatrixBase.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Eigen/src/Array/Select.h b/Eigen/src/Array/Select.h index 46c4a22ec..bc55147fd 100644 --- a/Eigen/src/Array/Select.h +++ b/Eigen/src/Array/Select.h @@ -131,11 +131,11 @@ MatrixBase::select(const MatrixBase& thenMatrix, */ template template -inline const Select > +inline const Select MatrixBase::select(const MatrixBase& thenMatrix, typename ThenDerived::Scalar elseScalar) const { - return Select >( + return Select( derived(), thenMatrix.derived(), ThenDerived::Constant(rows(),cols(),elseScalar)); } @@ -148,11 +148,11 @@ MatrixBase::select(const MatrixBase& thenMatrix, */ template template -inline const Select, ElseDerived > +inline const Select MatrixBase::select(typename ElseDerived::Scalar thenScalar, const MatrixBase& elseMatrix) const { - return Select,ElseDerived>( + return Select( derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived()); } diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 9f62ceb8f..1cee31936 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -694,11 +694,11 @@ template class MatrixBase const MatrixBase& elseMatrix) const; template - inline const Select > + inline const Select select(const MatrixBase& thenMatrix, typename ThenDerived::Scalar elseScalar) const; template - inline const Select, ElseDerived > + inline const Select select(typename ElseDerived::Scalar thenScalar, const MatrixBase& elseMatrix) const; template RealScalar lpNorm() const; From 7b3e205ebd4c8af6cd1ab65b538915a01c54bd35 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Tue, 1 Dec 2009 09:56:40 +0100 Subject: [PATCH 08/14] Removed NestByValue dependency from VectorwiseOp. --- Eigen/src/Array/VectorwiseOp.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Eigen/src/Array/VectorwiseOp.h b/Eigen/src/Array/VectorwiseOp.h index 7193e6f68..0a46f49fc 100644 --- a/Eigen/src/Array/VectorwiseOp.h +++ b/Eigen/src/Array/VectorwiseOp.h @@ -436,7 +436,7 @@ template class VectorwiseOp template CwiseBinaryOp, ExpressionType, - NestByValue::Type> > + typename ExtendedType::Type> operator+(const MatrixBase& other) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived); @@ -447,7 +447,7 @@ template class VectorwiseOp template CwiseBinaryOp, ExpressionType, - NestByValue::Type> > + typename ExtendedType::Type> operator-(const MatrixBase& other) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived); @@ -478,10 +478,10 @@ template class VectorwiseOp Direction==Horizontal ? 1 : int(ei_traits::ColsAtCompileTime)> HNormalized_Factors; typedef CwiseBinaryOp::Scalar>, - NestByValue, - NestByValue, + HNormalized_Block, + Replicate > > + Direction==Horizontal ? HNormalized_SizeMinusOne : 1> > HNormalizedReturnType; const HNormalizedReturnType hnormalized() const; From 3091be513421663f56f37d374212a365a73e84eb Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Tue, 1 Dec 2009 10:22:54 +0100 Subject: [PATCH 09/14] Removed NestByValue dependency from Cholesky, Eigenvalues, LU and QR. --- Eigen/src/Cholesky/LLT.h | 8 ++++---- Eigen/src/Eigenvalues/HessenbergDecomposition.h | 6 +++--- Eigen/src/Eigenvalues/Tridiagonalization.h | 13 ++++++------- Eigen/src/LU/FullPivLU.h | 4 ++-- Eigen/src/LU/PartialPivLU.h | 4 ++-- Eigen/src/QR/ColPivHouseholderQR.h | 4 ++-- Eigen/src/QR/FullPivHouseholderQR.h | 4 ++-- 7 files changed, 21 insertions(+), 22 deletions(-) diff --git a/Eigen/src/Cholesky/LLT.h b/Eigen/src/Cholesky/LLT.h index a1706e53e..ad737aaeb 100644 --- a/Eigen/src/Cholesky/LLT.h +++ b/Eigen/src/Cholesky/LLT.h @@ -224,18 +224,18 @@ template<> struct ei_llt_inplace template struct LLT_Traits { typedef TriangularView MatrixL; - typedef TriangularView, UpperTriangular> MatrixU; + typedef TriangularView MatrixU; inline static MatrixL getL(const MatrixType& m) { return m; } - inline static MatrixU getU(const MatrixType& m) { return m.adjoint().nestByValue(); } + inline static MatrixU getU(const MatrixType& m) { return m.adjoint(); } static bool inplace_decomposition(MatrixType& m) { return ei_llt_inplace::blocked(m); } }; template struct LLT_Traits { - typedef TriangularView, LowerTriangular> MatrixL; + typedef TriangularView MatrixL; typedef TriangularView MatrixU; - inline static MatrixL getL(const MatrixType& m) { return m.adjoint().nestByValue(); } + inline static MatrixL getL(const MatrixType& m) { return m.adjoint(); } inline static MatrixU getU(const MatrixType& m) { return m; } static bool inplace_decomposition(MatrixType& m) { return ei_llt_inplace::blocked(m); } diff --git a/Eigen/src/Eigenvalues/HessenbergDecomposition.h b/Eigen/src/Eigenvalues/HessenbergDecomposition.h index cce76b288..9f7df49bc 100644 --- a/Eigen/src/Eigenvalues/HessenbergDecomposition.h +++ b/Eigen/src/Eigenvalues/HessenbergDecomposition.h @@ -58,10 +58,10 @@ template class HessenbergDecomposition typedef Matrix DiagonalType; typedef Matrix SubDiagonalType; - typedef typename NestByValue >::RealReturnType DiagonalReturnType; + typedef typename Diagonal::RealReturnType DiagonalReturnType; - typedef typename NestByValue >,0 > >::RealReturnType SubDiagonalReturnType; + typedef typename Diagonal< + Block,0 >::RealReturnType SubDiagonalReturnType; /** This constructor initializes a HessenbergDecomposition object for * further use with HessenbergDecomposition::compute() diff --git a/Eigen/src/Eigenvalues/Tridiagonalization.h b/Eigen/src/Eigenvalues/Tridiagonalization.h index 04b9f72d7..d8dcfb047 100644 --- a/Eigen/src/Eigenvalues/Tridiagonalization.h +++ b/Eigen/src/Eigenvalues/Tridiagonalization.h @@ -61,15 +61,15 @@ template class Tridiagonalization typedef Matrix SubDiagonalType; typedef typename ei_meta_if::IsComplex, - typename NestByValue >::RealReturnType, + typename Diagonal::RealReturnType, Diagonal >::ret DiagonalReturnType; typedef typename ei_meta_if::IsComplex, - typename NestByValue >,0 > >::RealReturnType, + typename Diagonal< + Block,0 >::RealReturnType, Diagonal< - NestByValue >,0 > + Block,0 > >::ret SubDiagonalReturnType; /** This constructor initializes a Tridiagonalization object for @@ -144,7 +144,7 @@ template const typename Tridiagonalization::DiagonalReturnType Tridiagonalization::diagonal(void) const { - return m_matrix.diagonal().nestByValue(); + return m_matrix.diagonal(); } /** \returns an expression of the sub-diagonal vector */ @@ -153,8 +153,7 @@ const typename Tridiagonalization::SubDiagonalReturnType Tridiagonalization::subDiagonal(void) const { int n = m_matrix.rows(); - return Block(m_matrix, 1, 0, n-1,n-1) - .nestByValue().diagonal().nestByValue(); + return Block(m_matrix, 1, 0, n-1,n-1).diagonal(); } /** constructs and returns the tridiagonal matrix T. diff --git a/Eigen/src/LU/FullPivLU.h b/Eigen/src/LU/FullPivLU.h index 28dc0cd47..8d18e65f7 100644 --- a/Eigen/src/LU/FullPivLU.h +++ b/Eigen/src/LU/FullPivLU.h @@ -351,11 +351,11 @@ template class FullPivLU * * \sa MatrixBase::inverse() */ - inline const ei_solve_retval > inverse() const + inline const ei_solve_retval inverse() const { ei_assert(m_isInitialized && "LU is not initialized."); ei_assert(m_lu.rows() == m_lu.cols() && "You can't take the inverse of a non-square matrix!"); - return ei_solve_retval > + return ei_solve_retval (*this, MatrixType::Identity(m_lu.rows(), m_lu.cols()).nestByValue()); } diff --git a/Eigen/src/LU/PartialPivLU.h b/Eigen/src/LU/PartialPivLU.h index 975f79287..84bc165df 100644 --- a/Eigen/src/LU/PartialPivLU.h +++ b/Eigen/src/LU/PartialPivLU.h @@ -143,10 +143,10 @@ template class PartialPivLU * * \sa MatrixBase::inverse(), LU::inverse() */ - inline const ei_solve_retval > inverse() const + inline const ei_solve_retval inverse() const { ei_assert(m_isInitialized && "PartialPivLU is not initialized."); - return ei_solve_retval > + return ei_solve_retval (*this, MatrixType::Identity(m_lu.rows(), m_lu.cols()).nestByValue()); } diff --git a/Eigen/src/QR/ColPivHouseholderQR.h b/Eigen/src/QR/ColPivHouseholderQR.h index e59ecac66..614aa0295 100644 --- a/Eigen/src/QR/ColPivHouseholderQR.h +++ b/Eigen/src/QR/ColPivHouseholderQR.h @@ -214,11 +214,11 @@ template class ColPivHouseholderQR * Use isInvertible() to first determine whether this matrix is invertible. */ inline const - ei_solve_retval > + ei_solve_retval inverse() const { ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); - return ei_solve_retval > + return ei_solve_retval (*this, MatrixType::Identity(m_qr.rows(), m_qr.cols()).nestByValue()); } diff --git a/Eigen/src/QR/FullPivHouseholderQR.h b/Eigen/src/QR/FullPivHouseholderQR.h index ac0108046..db57ba088 100644 --- a/Eigen/src/QR/FullPivHouseholderQR.h +++ b/Eigen/src/QR/FullPivHouseholderQR.h @@ -216,11 +216,11 @@ template class FullPivHouseholderQR * \note If this matrix is not invertible, the returned matrix has undefined coefficients. * Use isInvertible() to first determine whether this matrix is invertible. */ inline const - ei_solve_retval > + ei_solve_retval inverse() const { ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); - return ei_solve_retval > + return ei_solve_retval (*this, MatrixType::Identity(m_qr.rows(), m_qr.cols()).nestByValue()); } From 2bf354da80d15a7a1e7ad9f58f375a21c6e721aa Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Tue, 1 Dec 2009 11:51:22 +0100 Subject: [PATCH 10/14] Much more NestByValue cleanup. --- Eigen/src/Array/VectorwiseOp.h | 4 ++-- Eigen/src/Core/BandMatrix.h | 2 +- Eigen/src/Core/Cwise.h | 2 +- Eigen/src/Core/MatrixBase.h | 10 +++++----- Eigen/src/Core/Transpose.h | 14 +++++++------- Eigen/src/Core/TriangularMatrix.h | 16 ++++++++-------- Eigen/src/Geometry/Homogeneous.h | 11 +++++------ Eigen/src/Geometry/Transform.h | 2 +- Eigen/src/Householder/HouseholderSequence.h | 2 +- Eigen/src/Sparse/SparseCwise.h | 2 +- blas/common.h | 8 ++++---- test/geo_quaternion.cpp | 2 +- 12 files changed, 37 insertions(+), 38 deletions(-) diff --git a/Eigen/src/Array/VectorwiseOp.h b/Eigen/src/Array/VectorwiseOp.h index 0a46f49fc..71b83eaad 100644 --- a/Eigen/src/Array/VectorwiseOp.h +++ b/Eigen/src/Array/VectorwiseOp.h @@ -440,7 +440,7 @@ template class VectorwiseOp operator+(const MatrixBase& other) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived); - return m_matrix + extendedTo(other).nestByValue(); + return m_matrix + extendedTo(other); } /** Returns the expression of the difference between each subvector of \c *this and the vector \a other */ @@ -451,7 +451,7 @@ template class VectorwiseOp operator-(const MatrixBase& other) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived); - return m_matrix - extendedTo(other).nestByValue(); + return m_matrix - extendedTo(other); } /////////// Geometry module /////////// diff --git a/Eigen/src/Core/BandMatrix.h b/Eigen/src/Core/BandMatrix.h index 85bd8dba7..7943e6280 100644 --- a/Eigen/src/Core/BandMatrix.h +++ b/Eigen/src/Core/BandMatrix.h @@ -141,7 +141,7 @@ class BandMatrix : public AnyMatrixBase BuildType; typedef typename ei_meta_if,NestByValue >, + CwiseUnaryOp,BuildType >, BuildType>::ret Type; }; diff --git a/Eigen/src/Core/Cwise.h b/Eigen/src/Core/Cwise.h index 4b143325e..80414782e 100644 --- a/Eigen/src/Core/Cwise.h +++ b/Eigen/src/Core/Cwise.h @@ -52,7 +52,7 @@ * convenient macro to defined the return type of a cwise comparison to a scalar */ #define EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(OP) \ CwiseBinaryOp::Scalar>, ExpressionType, \ - NestByValue > + typename ExpressionType::ConstantReturnType > /** \class Cwise * diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 1cee31936..f1cf4ef90 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -248,7 +248,7 @@ template class MatrixBase typedef CwiseUnaryView, Derived> NonConstImagReturnType; /** \internal the return type of MatrixBase::adjoint() */ typedef typename ei_meta_if::IsComplex, - CwiseUnaryOp, NestByValue > >, + CwiseUnaryOp, Eigen::Transpose >, Transpose >::ret AdjointReturnType; /** \internal the return type of MatrixBase::eigenvalues() */ @@ -445,11 +445,11 @@ template class MatrixBase Derived& lazyAssign(const CwiseBinaryOp,DerivedA,Transpose >& other); template - Derived& lazyAssign(const CwiseUnaryOp, NestByValue > >& other); + Derived& lazyAssign(const CwiseUnaryOp, Eigen::Transpose >& other); template - Derived& lazyAssign(const CwiseBinaryOp,CwiseUnaryOp, NestByValue > >,DerivedB>& other); + Derived& lazyAssign(const CwiseBinaryOp,CwiseUnaryOp, Eigen::Transpose >,DerivedB>& other); template - Derived& lazyAssign(const CwiseBinaryOp,DerivedA,CwiseUnaryOp, NestByValue > > >& other); + Derived& lazyAssign(const CwiseBinaryOp,DerivedA,CwiseUnaryOp, Eigen::Transpose > >& other); #endif RowXpr row(int i); @@ -766,7 +766,7 @@ template class MatrixBase ei_traits::ColsAtCompileTime==1 ? SizeMinusOne : 1, ei_traits::ColsAtCompileTime==1 ? 1 : SizeMinusOne> StartMinusOne; typedef CwiseUnaryOp::Scalar>, - NestByValue > HNormalizedReturnType; + StartMinusOne > HNormalizedReturnType; const HNormalizedReturnType hnormalized() const; typedef Homogeneous::ColsAtCompileTime==1?Vertical:Horizontal> HomogeneousReturnType; diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h index 990aa3807..79aef9fa7 100644 --- a/Eigen/src/Core/Transpose.h +++ b/Eigen/src/Core/Transpose.h @@ -186,7 +186,7 @@ template inline const typename MatrixBase::AdjointReturnType MatrixBase::adjoint() const { - return transpose().nestByValue(); + return transpose(); } /*************************************************************************** @@ -326,31 +326,31 @@ lazyAssign(const CwiseBinaryOp,DerivedA,Transpose template Derived& MatrixBase:: -lazyAssign(const CwiseUnaryOp, NestByValue > >& other) +lazyAssign(const CwiseUnaryOp, Eigen::Transpose >& other) { ei_assert(ei_extract_data(other) != ei_extract_data(derived()) && "aliasing detected during tranposition, please use adjointInPlace()"); - return lazyAssign(static_cast, NestByValue > > >& >(other)); + return lazyAssign(static_cast, Eigen::Transpose > >& >(other)); } template template Derived& MatrixBase:: -lazyAssign(const CwiseBinaryOp,CwiseUnaryOp, NestByValue > >,DerivedB>& other) +lazyAssign(const CwiseBinaryOp,CwiseUnaryOp, Eigen::Transpose >,DerivedB>& other) { ei_assert(ei_extract_data(derived()) != ei_extract_data(other.lhs()) && "aliasing detected during tranposition, please evaluate your expression"); - return lazyAssign(static_cast,CwiseUnaryOp, NestByValue > >,DerivedB> >& >(other)); + return lazyAssign(static_cast,CwiseUnaryOp, Eigen::Transpose >,DerivedB> >& >(other)); } template template Derived& MatrixBase:: -lazyAssign(const CwiseBinaryOp,DerivedA,CwiseUnaryOp, NestByValue > > >& other) +lazyAssign(const CwiseBinaryOp,DerivedA,CwiseUnaryOp, Eigen::Transpose > >& other) { ei_assert(ei_extract_data(derived()) != ei_extract_data(other.rhs()) && "aliasing detected during tranposition, please evaluate your expression"); - return lazyAssign(static_cast,DerivedA,CwiseUnaryOp, NestByValue > > > >& >(other)); + return lazyAssign(static_cast,DerivedA,CwiseUnaryOp, Eigen::Transpose > > >& >(other)); } #endif diff --git a/Eigen/src/Core/TriangularMatrix.h b/Eigen/src/Core/TriangularMatrix.h index e5d7367d8..aaf781d1f 100644 --- a/Eigen/src/Core/TriangularMatrix.h +++ b/Eigen/src/Core/TriangularMatrix.h @@ -222,18 +222,18 @@ template class TriangularView /** \sa MatrixBase::adjoint() */ - inline TriangularView,TransposeMode> adjoint() - { return m_matrix.adjoint().nestByValue(); } + inline TriangularView adjoint() + { return m_matrix.adjoint(); } /** \sa MatrixBase::adjoint() const */ - inline const TriangularView,TransposeMode> adjoint() const - { return m_matrix.adjoint().nestByValue(); } + inline const TriangularView adjoint() const + { return m_matrix.adjoint(); } /** \sa MatrixBase::transpose() */ - inline TriangularView >,TransposeMode> transpose() - { return m_matrix.transpose().nestByValue(); } + inline TriangularView,TransposeMode> transpose() + { return m_matrix.transpose(); } /** \sa MatrixBase::transpose() const */ - inline const TriangularView >,TransposeMode> transpose() const - { return m_matrix.transpose().nestByValue(); } + inline const TriangularView,TransposeMode> transpose() const + { return m_matrix.transpose(); } DenseMatrixType toDenseMatrix() const { diff --git a/Eigen/src/Geometry/Homogeneous.h b/Eigen/src/Geometry/Homogeneous.h index 035d213b7..ffa828f71 100644 --- a/Eigen/src/Geometry/Homogeneous.h +++ b/Eigen/src/Geometry/Homogeneous.h @@ -175,7 +175,7 @@ MatrixBase::hnormalized() const EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); return StartMinusOne(derived(),0,0, ColsAtCompileTime==1?size()-1:1, - ColsAtCompileTime==1?1:size()-1).nestByValue() / coeff(size()-1); + ColsAtCompileTime==1?1:size()-1) / coeff(size()-1); } /** \geometry_module @@ -192,18 +192,17 @@ VectorwiseOp::hnormalized() const { return HNormalized_Block(_expression(),0,0, Direction==Vertical ? _expression().rows()-1 : _expression().rows(), - Direction==Horizontal ? _expression().cols()-1 : _expression().cols()).nestByValue() - .cwise()/ - Replicate, + Direction==Horizontal ? _expression().cols()-1 : _expression().cols()).cwise()/ + Replicate (HNormalized_Factors(_expression(), Direction==Vertical ? _expression().rows()-1:0, Direction==Horizontal ? _expression().cols()-1:0, Direction==Vertical ? 1 : _expression().rows(), - Direction==Horizontal ? 1 : _expression().cols()).nestByValue(), + Direction==Horizontal ? 1 : _expression().cols()), Direction==Vertical ? _expression().rows()-1 : 1, - Direction==Horizontal ? _expression().cols()-1 : 1).nestByValue(); + Direction==Horizontal ? _expression().cols()-1 : 1); } template diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h index d478675bd..363fa9dc4 100644 --- a/Eigen/src/Geometry/Transform.h +++ b/Eigen/src/Geometry/Transform.h @@ -187,7 +187,7 @@ public: /** type of read/write reference to the affine part of the transformation */ typedef typename ei_meta_if > >::ret AffinePartNested; + Block >::ret AffinePartNested; /** type of a vector */ typedef Matrix VectorType; /** type of a read/write reference to the translation part of the rotation */ diff --git a/Eigen/src/Householder/HouseholderSequence.h b/Eigen/src/Householder/HouseholderSequence.h index 85aa90362..afeb758b3 100644 --- a/Eigen/src/Householder/HouseholderSequence.h +++ b/Eigen/src/Householder/HouseholderSequence.h @@ -69,7 +69,7 @@ template class HouseholderSequence typedef HouseholderSequence::IsComplex, - NestByValue::type >, + typename ei_cleantype::type, CoeffsType>::ret> ConjugateReturnType; HouseholderSequence(const VectorsType& v, const CoeffsType& h, bool trans = false) diff --git a/Eigen/src/Sparse/SparseCwise.h b/Eigen/src/Sparse/SparseCwise.h index dd745fe7c..bf8f2355c 100644 --- a/Eigen/src/Sparse/SparseCwise.h +++ b/Eigen/src/Sparse/SparseCwise.h @@ -52,7 +52,7 @@ * convenient macro to defined the return type of a cwise comparison to a scalar */ /*#define EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(OP) \ CwiseBinaryOp::Scalar>, ExpressionType, \ - NestByValue >*/ + typename ExpressionType::ConstantReturnType >*/ template class SparseCwise { diff --git a/blas/common.h b/blas/common.h index 74c3c9f11..4be530da2 100644 --- a/blas/common.h +++ b/blas/common.h @@ -76,14 +76,14 @@ extern "C" using namespace Eigen; template -Block > >, Dynamic, Dynamic> +Block >, Dynamic, Dynamic> matrix(T* data, int rows, int cols, int stride) { return Map >(data, stride, cols).nestByValue().block(0,0,rows,cols); } template -Block > >, Dynamic, 1> +Block >, Dynamic, 1> vector(T* data, int size, int incr) { return Map >(data, size, incr).nestByValue().col(0); @@ -106,8 +106,8 @@ enum Conj = IsComplex }; -typedef Block > >, Dynamic, Dynamic> MatrixType; -typedef Block > >, Dynamic, 1> StridedVectorType; +typedef Block >, Dynamic, Dynamic> MatrixType; +typedef Block >, Dynamic, 1> StridedVectorType; typedef Map > CompactVectorType; #define EIGEN_BLAS_FUNC(X) EIGEN_CAT(SCALAR_SUFFIX,X##_) diff --git a/test/geo_quaternion.cpp b/test/geo_quaternion.cpp index 2e97fe295..5a55138f9 100644 --- a/test/geo_quaternion.cpp +++ b/test/geo_quaternion.cpp @@ -43,7 +43,7 @@ template void quaternion(void) if (ei_is_same_type::ret) largeEps = 1e-3f; - Scalar eps = ei_random() * 1e-2; + Scalar eps = ei_random() * Scalar(1e-2); Vector3 v0 = Vector3::Random(), v1 = Vector3::Random(), From b08d5b2d2c73c095706cd2442878b960ef46df1f Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Tue, 1 Dec 2009 13:16:51 +0100 Subject: [PATCH 11/14] Even more NestByValue cleanup... --- Eigen/Sparse | 1 - Eigen/src/Core/ExpressionMaker.h | 6 -- Eigen/src/Core/util/BlasUtil.h | 14 ---- Eigen/src/LU/FullPivLU.h | 2 +- Eigen/src/LU/PartialPivLU.h | 2 +- Eigen/src/QR/ColPivHouseholderQR.h | 2 +- Eigen/src/QR/FullPivHouseholderQR.h | 2 +- Eigen/src/Sparse/SparseDiagonalProduct.h | 6 +- Eigen/src/Sparse/SparseExpressionMaker.h | 6 -- Eigen/src/Sparse/SparseMatrixBase.h | 11 +-- Eigen/src/Sparse/SparseNestByValue.h | 84 ------------------- Eigen/src/Sparse/SparseUtil.h | 3 - blas/common.h | 4 +- .../Eigen/src/AutoDiff/AutoDiffScalar.h | 24 +++--- .../Eigen/src/AutoDiff/AutoDiffVector.h | 10 +-- 15 files changed, 30 insertions(+), 147 deletions(-) delete mode 100644 Eigen/src/Sparse/SparseNestByValue.h diff --git a/Eigen/Sparse b/Eigen/Sparse index 96bd61419..a319405e6 100644 --- a/Eigen/Sparse +++ b/Eigen/Sparse @@ -84,7 +84,6 @@ namespace Eigen { #include "src/Sparse/SparseUtil.h" #include "src/Sparse/SparseMatrixBase.h" -#include "src/Sparse/SparseNestByValue.h" #include "src/Sparse/CompressedStorage.h" #include "src/Sparse/AmbiVector.h" #include "src/Sparse/RandomSetter.h" diff --git a/Eigen/src/Core/ExpressionMaker.h b/Eigen/src/Core/ExpressionMaker.h index 1d265b63c..7e2b81d4a 100644 --- a/Eigen/src/Core/ExpressionMaker.h +++ b/Eigen/src/Core/ExpressionMaker.h @@ -37,12 +37,6 @@ template struct ei_shape_of // matrix. Unless we change the overall design, here is a workaround. // There is an example in unsuported/Eigen/src/AutoDiff/AutoDiffScalar. -template::ret> -struct MakeNestByValue -{ - typedef NestByValue Type; -}; - template::ret> struct MakeCwiseUnaryOp { diff --git a/Eigen/src/Core/util/BlasUtil.h b/Eigen/src/Core/util/BlasUtil.h index 94154108c..a012a6e12 100644 --- a/Eigen/src/Core/util/BlasUtil.h +++ b/Eigen/src/Core/util/BlasUtil.h @@ -214,20 +214,6 @@ struct ei_blas_traits, NestedXpr> > { return - Base::extractScalarFactor(x._expression()); } }; -// pop NestByValue -template -struct ei_blas_traits > - : ei_blas_traits -{ - typedef typename NestedXpr::Scalar Scalar; - typedef ei_blas_traits Base; - typedef NestByValue XprType; - typedef typename Base::ExtractType ExtractType; - static inline ExtractType extract(const XprType& x) { return Base::extract(static_cast(x)); } - static inline Scalar extractScalarFactor(const XprType& x) - { return Base::extractScalarFactor(static_cast(x)); } -}; - // pop/push transpose template struct ei_blas_traits > diff --git a/Eigen/src/LU/FullPivLU.h b/Eigen/src/LU/FullPivLU.h index 8d18e65f7..974106509 100644 --- a/Eigen/src/LU/FullPivLU.h +++ b/Eigen/src/LU/FullPivLU.h @@ -356,7 +356,7 @@ template class FullPivLU ei_assert(m_isInitialized && "LU is not initialized."); ei_assert(m_lu.rows() == m_lu.cols() && "You can't take the inverse of a non-square matrix!"); return ei_solve_retval - (*this, MatrixType::Identity(m_lu.rows(), m_lu.cols()).nestByValue()); + (*this, MatrixType::Identity(m_lu.rows(), m_lu.cols())); } inline int rows() const { return m_lu.rows(); } diff --git a/Eigen/src/LU/PartialPivLU.h b/Eigen/src/LU/PartialPivLU.h index 84bc165df..577daa345 100644 --- a/Eigen/src/LU/PartialPivLU.h +++ b/Eigen/src/LU/PartialPivLU.h @@ -147,7 +147,7 @@ template class PartialPivLU { ei_assert(m_isInitialized && "PartialPivLU is not initialized."); return ei_solve_retval - (*this, MatrixType::Identity(m_lu.rows(), m_lu.cols()).nestByValue()); + (*this, MatrixType::Identity(m_lu.rows(), m_lu.cols())); } /** \returns the determinant of the matrix of which diff --git a/Eigen/src/QR/ColPivHouseholderQR.h b/Eigen/src/QR/ColPivHouseholderQR.h index 614aa0295..c4fc34f93 100644 --- a/Eigen/src/QR/ColPivHouseholderQR.h +++ b/Eigen/src/QR/ColPivHouseholderQR.h @@ -219,7 +219,7 @@ template class ColPivHouseholderQR { ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); return ei_solve_retval - (*this, MatrixType::Identity(m_qr.rows(), m_qr.cols()).nestByValue()); + (*this, MatrixType::Identity(m_qr.rows(), m_qr.cols())); } inline int rows() const { return m_qr.rows(); } diff --git a/Eigen/src/QR/FullPivHouseholderQR.h b/Eigen/src/QR/FullPivHouseholderQR.h index db57ba088..ae4e4aa4d 100644 --- a/Eigen/src/QR/FullPivHouseholderQR.h +++ b/Eigen/src/QR/FullPivHouseholderQR.h @@ -221,7 +221,7 @@ template class FullPivHouseholderQR { ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); return ei_solve_retval - (*this, MatrixType::Identity(m_qr.rows(), m_qr.cols()).nestByValue()); + (*this, MatrixType::Identity(m_qr.rows(), m_qr.cols())); } inline int rows() const { return m_qr.rows(); } diff --git a/Eigen/src/Sparse/SparseDiagonalProduct.h b/Eigen/src/Sparse/SparseDiagonalProduct.h index f12ccb929..e9ba47f70 100644 --- a/Eigen/src/Sparse/SparseDiagonalProduct.h +++ b/Eigen/src/Sparse/SparseDiagonalProduct.h @@ -154,16 +154,16 @@ class ei_sparse_diagonal_product_inner_iterator_selector : public SparseCwiseBinaryOp< ei_scalar_product_op, SparseInnerVectorSet, - NestByValue > >::InnerIterator + Transpose >::InnerIterator { typedef typename SparseCwiseBinaryOp< ei_scalar_product_op, SparseInnerVectorSet, - NestByValue > >::InnerIterator Base; + Transpose >::InnerIterator Base; public: inline ei_sparse_diagonal_product_inner_iterator_selector( const SparseDiagonalProductType& expr, int outer) - : Base(expr.lhs().innerVector(outer) .cwise()* expr.rhs().diagonal().transpose().nestByValue(), 0) + : Base(expr.lhs().innerVector(outer) .cwise()* expr.rhs().diagonal().transpose(), 0) {} }; diff --git a/Eigen/src/Sparse/SparseExpressionMaker.h b/Eigen/src/Sparse/SparseExpressionMaker.h index 1fdcbb1f2..8e31d55ef 100644 --- a/Eigen/src/Sparse/SparseExpressionMaker.h +++ b/Eigen/src/Sparse/SparseExpressionMaker.h @@ -25,12 +25,6 @@ #ifndef EIGEN_SPARSE_EXPRESSIONMAKER_H #define EIGEN_SPARSE_EXPRESSIONMAKER_H -template -struct MakeNestByValue -{ - typedef SparseNestByValue Type; -}; - template struct MakeCwiseUnaryOp { diff --git a/Eigen/src/Sparse/SparseMatrixBase.h b/Eigen/src/Sparse/SparseMatrixBase.h index 2fd314708..cbbaf6b8b 100644 --- a/Eigen/src/Sparse/SparseMatrixBase.h +++ b/Eigen/src/Sparse/SparseMatrixBase.h @@ -100,7 +100,7 @@ template class SparseMatrixBase : public AnyMatrixBase, Derived> ImagReturnType; /** \internal the return type of MatrixBase::adjoint() */ typedef typename ei_meta_if::IsComplex, - SparseCwiseUnaryOp, SparseNestByValue > >, + SparseCwiseUnaryOp, Eigen::SparseTranspose >, SparseTranspose >::ret AdjointReturnType; @@ -356,7 +356,7 @@ template class SparseMatrixBase : public AnyMatrixBase transpose() { return derived(); } const SparseTranspose transpose() const { return derived(); } // void transposeInPlace(); - const AdjointReturnType adjoint() const { return transpose().nestByValue(); } + const AdjointReturnType adjoint() const { return transpose(); } // sub-vector SparseInnerVectorSet row(int i); @@ -528,9 +528,6 @@ template class SparseMatrixBase : public AnyMatrixBase nestByValue() const; - - ConjugateReturnType conjugate() const; const RealReturnType real() const; const ImagReturnType imag() const; @@ -583,11 +580,11 @@ template class SparseMatrixBase : public AnyMatrixBase& elseMatrix) const; template - inline const Select > + inline const Select select(const MatrixBase& thenMatrix, typename ThenDerived::Scalar elseScalar) const; template - inline const Select, ElseDerived > + inline const Select select(typename ElseDerived::Scalar thenScalar, const MatrixBase& elseMatrix) const; template RealScalar lpNorm() const; diff --git a/Eigen/src/Sparse/SparseNestByValue.h b/Eigen/src/Sparse/SparseNestByValue.h deleted file mode 100644 index b48277232..000000000 --- a/Eigen/src/Sparse/SparseNestByValue.h +++ /dev/null @@ -1,84 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud -// Copyright (C) 2006-2008 Benoit Jacob -// -// 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_SPARSENESTBYVALUE_H -#define EIGEN_SPARSENESTBYVALUE_H - -/** \class SparseNestByValue - * - * \brief Expression which must be nested by value - * - * \param ExpressionType the type of the object of which we are requiring nesting-by-value - * - * This class is the return type of MatrixBase::nestByValue() - * and most of the time this is the only way it is used. - * - * \sa SparseMatrixBase::nestByValue(), class NestByValue - */ -template -struct ei_traits > : public ei_traits -{}; - -template class SparseNestByValue - : public SparseMatrixBase > -{ - public: - - typedef typename ExpressionType::InnerIterator InnerIterator; - - EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseNestByValue) - - inline SparseNestByValue(const ExpressionType& matrix) : m_expression(matrix) {} - - EIGEN_STRONG_INLINE int rows() const { return m_expression.rows(); } - EIGEN_STRONG_INLINE int cols() const { return m_expression.cols(); } - - operator const ExpressionType&() const { return m_expression; } - - protected: - const ExpressionType m_expression; -}; - -/** \returns an expression of the temporary version of *this. - */ -template -inline const SparseNestByValue -SparseMatrixBase::nestByValue() const -{ - return SparseNestByValue(derived()); -} - -// template -// class SparseNestByValue::InnerIterator : public MatrixType::InnerIterator -// { -// typedef typename MatrixType::InnerIterator Base; -// public: -// -// EIGEN_STRONG_INLINE InnerIterator(const SparseNestByValue& expr, int outer) -// : Base(expr.m_expression, outer) -// {} -// }; - -#endif // EIGEN_SPARSENESTBYVALUE_H diff --git a/Eigen/src/Sparse/SparseUtil.h b/Eigen/src/Sparse/SparseUtil.h index b5fc7c7b7..52781aa46 100644 --- a/Eigen/src/Sparse/SparseUtil.h +++ b/Eigen/src/Sparse/SparseUtil.h @@ -106,7 +106,6 @@ template class DynamicSparseMatrix; template class SparseVector; template class MappedSparseMatrix; -template class SparseNestByValue; template class SparseTranspose; template class SparseInnerVectorSet; template class SparseCwise; @@ -147,6 +146,4 @@ template class ei_eval typedef SparseMatrix<_Scalar, _Flags> type; }; -template struct ei_must_nest_by_value > { enum { ret = true }; }; - #endif // EIGEN_SPARSEUTIL_H diff --git a/blas/common.h b/blas/common.h index 4be530da2..e7bfda570 100644 --- a/blas/common.h +++ b/blas/common.h @@ -79,14 +79,14 @@ template Block >, Dynamic, Dynamic> matrix(T* data, int rows, int cols, int stride) { - return Map >(data, stride, cols).nestByValue().block(0,0,rows,cols); + return Map >(data, stride, cols).block(0,0,rows,cols); } template Block >, Dynamic, 1> vector(T* data, int size, int incr) { - return Map >(data, size, incr).nestByValue().col(0); + return Map >(data, size, incr).col(0); } template diff --git a/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h b/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h index c4607c2b8..795dd6b4d 100644 --- a/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h +++ b/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h @@ -212,33 +212,33 @@ class AutoDiffScalar template inline const AutoDiffScalar, - typename MakeNestByValue, - typename MakeNestByValue, DerType>::Type>::Type, - typename MakeNestByValue, typename ei_cleantype::type>::Type>::Type >::Type >::Type >::Type > + typename MakeCwiseBinaryOp, + typename MakeCwiseUnaryOp, DerType>::Type, + typename MakeCwiseUnaryOp, typename ei_cleantype::type>::Type>::Type >::Type > operator/(const AutoDiffScalar& other) const { ei_make_coherent(m_derivatives, other.derivatives()); return AutoDiffScalar, - typename MakeNestByValue, - typename MakeNestByValue, DerType>::Type>::Type, - typename MakeNestByValue, typename ei_cleantype::type>::Type>::Type >::Type >::Type >::Type >( + typename MakeCwiseBinaryOp, + typename MakeCwiseUnaryOp, DerType>::Type, + typename MakeCwiseUnaryOp, typename ei_cleantype::type>::Type>::Type >::Type >( m_value / other.value(), - ((m_derivatives * other.value()).nestByValue() - (m_value * other.derivatives()).nestByValue()).nestByValue() + ((m_derivatives * other.value()) - (m_value * other.derivatives())) * (Scalar(1)/(other.value()*other.value()))); } template inline const AutoDiffScalar, - typename MakeNestByValue, DerType>::Type>::Type, - typename MakeNestByValue, typename ei_cleantype::type>::Type>::Type >::Type > + typename MakeCwiseUnaryOp, DerType>::Type, + typename MakeCwiseUnaryOp, typename ei_cleantype::type>::Type>::Type > operator*(const AutoDiffScalar& other) const { ei_make_coherent(m_derivatives, other.derivatives()); return AutoDiffScalar, - typename MakeNestByValue, DerType>::Type>::Type, - typename MakeNestByValue, typename ei_cleantype::type>::Type>::Type >::Type >( + typename MakeCwiseUnaryOp, DerType>::Type, + typename MakeCwiseUnaryOp, typename ei_cleantype::type>::Type>::Type >( m_value * other.value(), - (m_derivatives * other.value()).nestByValue() + (m_value * other.derivatives()).nestByValue()); + (m_derivatives * other.value()) + (m_value * other.derivatives())); } inline AutoDiffScalar& operator*=(const Scalar& other) diff --git a/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h b/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h index 03c82b7e8..c0765d494 100644 --- a/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h +++ b/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h @@ -196,17 +196,17 @@ class AutoDiffVector // inline const AutoDiffVector< // CwiseBinaryOp, ValueType, OtherValueType> // CwiseBinaryOp, -// NestByValue, JacobianType> >, -// NestByValue, OtherJacobianType> > > > +// CwiseUnaryOp, JacobianType>, +// CwiseUnaryOp, OtherJacobianType> > > // operator*(const AutoDiffVector& other) const // { // return AutoDiffVector< // CwiseBinaryOp, ValueType, OtherValueType> // CwiseBinaryOp, -// NestByValue, JacobianType> >, -// NestByValue, OtherJacobianType> > > >( +// CwiseUnaryOp, JacobianType>, +// CwiseUnaryOp, OtherJacobianType> > >( // m_values.cwise() * other.values(), -// (m_jacobian * other.values()).nestByValue() + (m_values * other.jacobian()).nestByValue()); +// (m_jacobian * other.values()) + (m_values * other.jacobian())); // } inline AutoDiffVector& operator*=(const Scalar& other) From d3250cb38feaae3637ae2a9ab6266424a321674d Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Tue, 1 Dec 2009 13:29:08 +0100 Subject: [PATCH 12/14] That's it NestByValue and .nestByValue() are both gone! --- Eigen/Core | 1 - Eigen/src/Core/MatrixBase.h | 3 - Eigen/src/Core/NestByValue.h | 119 ---------------------- Eigen/src/Core/util/ForwardDeclarations.h | 1 - Eigen/src/Core/util/XprHelper.h | 35 ++----- 5 files changed, 6 insertions(+), 153 deletions(-) delete mode 100644 Eigen/src/Core/NestByValue.h diff --git a/Eigen/Core b/Eigen/Core index e095aee11..1accbfd09 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -162,7 +162,6 @@ namespace Eigen { #include "src/Core/util/BlasUtil.h" #include "src/Core/MatrixStorage.h" -#include "src/Core/NestByValue.h" #include "src/Core/ReturnByValue.h" #include "src/Core/Flagged.h" #include "src/Core/NoAlias.h" diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index f1cf4ef90..338395250 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -620,9 +620,6 @@ template class MatrixBase */ inline int stride(void) const { return derived().stride(); } - inline const NestByValue nestByValue() const; - - ConjugateReturnType conjugate() const; RealReturnType real() const; NonConstRealReturnType real(); diff --git a/Eigen/src/Core/NestByValue.h b/Eigen/src/Core/NestByValue.h deleted file mode 100644 index 94a8f8078..000000000 --- a/Eigen/src/Core/NestByValue.h +++ /dev/null @@ -1,119 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud -// Copyright (C) 2006-2008 Benoit Jacob -// -// 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_NESTBYVALUE_H -#define EIGEN_NESTBYVALUE_H - -/** \class NestByValue - * - * \brief Expression which must be nested by value - * - * \param ExpressionType the type of the object of which we are requiring nesting-by-value - * - * This class is the return type of MatrixBase::nestByValue() - * and most of the time this is the only way it is used. - * - * \sa MatrixBase::nestByValue() - */ -template -struct ei_traits > : public ei_traits -{}; - -template class NestByValue - : public MatrixBase > -{ - public: - - EIGEN_GENERIC_PUBLIC_INTERFACE(NestByValue) - - inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {} - - inline int rows() const { return m_expression.rows(); } - inline int cols() const { return m_expression.cols(); } - inline int stride() const { return m_expression.stride(); } - - inline const CoeffReturnType coeff(int row, int col) const - { - return m_expression.coeff(row, col); - } - - inline Scalar& coeffRef(int row, int col) - { - return m_expression.const_cast_derived().coeffRef(row, col); - } - - inline const CoeffReturnType coeff(int index) const - { - return m_expression.coeff(index); - } - - inline Scalar& coeffRef(int index) - { - return m_expression.const_cast_derived().coeffRef(index); - } - - template - inline const PacketScalar packet(int row, int col) const - { - return m_expression.template packet(row, col); - } - - template - inline void writePacket(int row, int col, const PacketScalar& x) - { - m_expression.const_cast_derived().template writePacket(row, col, x); - } - - template - inline const PacketScalar packet(int index) const - { - return m_expression.template packet(index); - } - - template - inline void writePacket(int index, const PacketScalar& x) - { - m_expression.const_cast_derived().template writePacket(index, x); - } - - operator const ExpressionType&() const { return m_expression; } - - protected: - const ExpressionType m_expression; - - private: - NestByValue& operator=(const NestByValue&); -}; - -/** \returns an expression of the temporary version of *this. - */ -template -inline const NestByValue -MatrixBase::nestByValue() const -{ - return NestByValue(derived()); -} - -#endif // EIGEN_NESTBYVALUE_H diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index 62e4bb31b..8670dccdb 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -36,7 +36,6 @@ template class Flagged; template class NoAlias; -template class NestByValue; template class SwapWrapper; template class Minor; template struct ei_plain_matrix_type_row_major > type; }; +// we should be able to get rid of this one too template struct ei_must_nest_by_value { enum { ret = false }; }; -template struct ei_must_nest_by_value > { enum { ret = true }; }; - -/** -* Just a sanity check in order to verify that NestByValue is never -* used in combination with Matrix. Currently, I don't see a use case -* for nesting matrices by value. When an expression requires a temporary -* this should be handled through PlainMatrixType (i.e. arithmetic cost -* check + eval before nesting check). -* Note: If this were happening there were no harm but - if we are sure -* this does not happen, we can actually get rid of NestByValue! -**/ -template struct ei_is_nested_matrix { typedef int ok; }; -template -struct ei_is_nested_matrix< NestByValue< Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > > {}; /** * The reference selector for template expressions. The idea is that we don't @@ -236,21 +223,11 @@ template::ty CostNoEval = (n-1) * int(ei_traits::CoeffReadCost) }; - typedef typename ei_is_nested_matrix::ok is_ok; - typedef typename ei_meta_if< - ei_must_nest_by_value::ret, - T, - typename ei_meta_if< - ( int(ei_traits::Flags) & EvalBeforeNestingBit ) || - ( int(CostEval) <= int(CostNoEval) ), - PlainMatrixType, -#ifdef EIGEN_OLD_NESTED - const T& -#else - typename ei_ref_selector::type -#endif - >::ret + ( int(ei_traits::Flags) & EvalBeforeNestingBit ) || + ( int(CostEval) <= int(CostNoEval) ), + PlainMatrixType, + typename ei_ref_selector::type >::ret type; }; @@ -303,7 +280,7 @@ template struct HNormalizedReturnType { ei_traits::ColsAtCompileTime==1 ? SizeMinusOne : 1, ei_traits::ColsAtCompileTime==1 ? 1 : SizeMinusOne> StartMinusOne; typedef CwiseUnaryOp::Scalar>, - NestByValue > Type; + StartMinusOne > Type; }; template struct ei_cast_return_type From e3612bc0b843302259d79e4ecb73dff25e891122 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Wed, 2 Dec 2009 09:11:24 +0100 Subject: [PATCH 13/14] Removed unnecessary code. --- Eigen/src/Core/ProductBase.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Eigen/src/Core/ProductBase.h b/Eigen/src/Core/ProductBase.h index 57183ac52..955e87feb 100644 --- a/Eigen/src/Core/ProductBase.h +++ b/Eigen/src/Core/ProductBase.h @@ -111,14 +111,6 @@ class ProductBase : public MatrixBase template inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { derived().scaleAndAddTo(dst,alpha); } - PlainMatrixType eval() const - { - PlainMatrixType res(rows(), cols()); - res.setZero(); - derived().evalTo(res); - return res; - } - EIGEN_DEPRECATED const Flagged lazy() const { return *this; } From 95861fbd6cbf9ec6634f2903d06f7ff5320a4f2a Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Wed, 2 Dec 2009 10:53:30 +0100 Subject: [PATCH 14/14] Added NestByValue and .nestByValue() again for the sake of backwards compatibility. --- Eigen/Core | 1 + Eigen/src/Core/MatrixBase.h | 2 + Eigen/src/Core/NestByValue.h | 119 ++++++++++++++++++++++ Eigen/src/Core/util/ForwardDeclarations.h | 1 + 4 files changed, 123 insertions(+) create mode 100644 Eigen/src/Core/NestByValue.h diff --git a/Eigen/Core b/Eigen/Core index 1accbfd09..e095aee11 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -162,6 +162,7 @@ namespace Eigen { #include "src/Core/util/BlasUtil.h" #include "src/Core/MatrixStorage.h" +#include "src/Core/NestByValue.h" #include "src/Core/ReturnByValue.h" #include "src/Core/Flagged.h" #include "src/Core/NoAlias.h" diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 338395250..03d8d5f55 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -620,6 +620,8 @@ template class MatrixBase */ inline int stride(void) const { return derived().stride(); } + inline const NestByValue nestByValue() const; + ConjugateReturnType conjugate() const; RealReturnType real() const; NonConstRealReturnType real(); diff --git a/Eigen/src/Core/NestByValue.h b/Eigen/src/Core/NestByValue.h new file mode 100644 index 000000000..94a8f8078 --- /dev/null +++ b/Eigen/src/Core/NestByValue.h @@ -0,0 +1,119 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008 Gael Guennebaud +// Copyright (C) 2006-2008 Benoit Jacob +// +// 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_NESTBYVALUE_H +#define EIGEN_NESTBYVALUE_H + +/** \class NestByValue + * + * \brief Expression which must be nested by value + * + * \param ExpressionType the type of the object of which we are requiring nesting-by-value + * + * This class is the return type of MatrixBase::nestByValue() + * and most of the time this is the only way it is used. + * + * \sa MatrixBase::nestByValue() + */ +template +struct ei_traits > : public ei_traits +{}; + +template class NestByValue + : public MatrixBase > +{ + public: + + EIGEN_GENERIC_PUBLIC_INTERFACE(NestByValue) + + inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {} + + inline int rows() const { return m_expression.rows(); } + inline int cols() const { return m_expression.cols(); } + inline int stride() const { return m_expression.stride(); } + + inline const CoeffReturnType coeff(int row, int col) const + { + return m_expression.coeff(row, col); + } + + inline Scalar& coeffRef(int row, int col) + { + return m_expression.const_cast_derived().coeffRef(row, col); + } + + inline const CoeffReturnType coeff(int index) const + { + return m_expression.coeff(index); + } + + inline Scalar& coeffRef(int index) + { + return m_expression.const_cast_derived().coeffRef(index); + } + + template + inline const PacketScalar packet(int row, int col) const + { + return m_expression.template packet(row, col); + } + + template + inline void writePacket(int row, int col, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket(row, col, x); + } + + template + inline const PacketScalar packet(int index) const + { + return m_expression.template packet(index); + } + + template + inline void writePacket(int index, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket(index, x); + } + + operator const ExpressionType&() const { return m_expression; } + + protected: + const ExpressionType m_expression; + + private: + NestByValue& operator=(const NestByValue&); +}; + +/** \returns an expression of the temporary version of *this. + */ +template +inline const NestByValue +MatrixBase::nestByValue() const +{ + return NestByValue(derived()); +} + +#endif // EIGEN_NESTBYVALUE_H diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index 8670dccdb..62e4bb31b 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -36,6 +36,7 @@ template class Flagged; template class NoAlias; +template class NestByValue; template class SwapWrapper; template class Minor; template