From e09768e3bc8ff60972cc7cbf49e4a12e2b1c9235 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 16 Nov 2009 09:38:44 -0500 Subject: handle make errors ---> exit, don't run ctest --- scripts/check.in | 4 +--- test/buildtests.in | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/check.in b/scripts/check.in index 3aa9501bb..2a862fd80 100755 --- a/scripts/check.in +++ b/scripts/check.in @@ -8,7 +8,5 @@ then exit 0 fi -./buildtests $* - # TODO when ctest 2.8 comes out, honor the jobs parameter -ctest -R $1 \ No newline at end of file +./buildtests $* && ctest -R $1 \ No newline at end of file diff --git a/test/buildtests.in b/test/buildtests.in index 52cc66281..c24234930 100755 --- a/test/buildtests.in +++ b/test/buildtests.in @@ -13,9 +13,11 @@ targets_to_make=`echo "$TESTSLIST" | grep "$1" | sed s/^/test_/g | xargs echo` if [ $# == 1 ] then make $targets_to_make + exit $? fi if [ $# == 2 ] then make -j $2 $targets_to_make + exit $? fi -- cgit v1.2.3 From b25eb5fdaade6c20457a411fd08e17acc54f3349 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 16 Nov 2009 09:39:07 -0500 Subject: PermutationMatrix: add inverse() and product of permutations --- Eigen/src/Core/PermutationMatrix.h | 30 +++++++++++++++++++++++++++--- test/permutationmatrices.cpp | 9 +++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/Eigen/src/Core/PermutationMatrix.h b/Eigen/src/Core/PermutationMatrix.h index aaccb4e7b..1c66cde8e 100644 --- a/Eigen/src/Core/PermutationMatrix.h +++ b/Eigen/src/Core/PermutationMatrix.h @@ -105,10 +105,10 @@ class PermutationMatrix : public AnyMatrixBase @@ -126,7 +126,31 @@ class PermutationMatrix : public AnyMatrixBase + inline PermutationMatrix operator*(const PermutationMatrix& other) const + { return PermutationMatrix(Product, *this, other); } + protected: IndicesType m_indices; diff --git a/test/permutationmatrices.cpp b/test/permutationmatrices.cpp index 13b01cd83..ec3a8541c 100644 --- a/test/permutationmatrices.cpp +++ b/test/permutationmatrices.cpp @@ -72,6 +72,15 @@ template void permutationmatrices(const MatrixType& m) Matrix rm(rp); VERIFY_IS_APPROX(m_permuted, lm*m_original*rm); + + VERIFY_IS_APPROX(lp.inverse()*m_permuted*rp.inverse(), m_original); + VERIFY((lp*lp.inverse()).toDenseMatrix().isIdentity()); + + LeftPermutationVectorType lv2; + randomPermutationVector(lv2, rows); + LeftPermutationType lp2(lv2); + Matrix lm2(lp2); + VERIFY_IS_APPROX((lp*lp2).toDenseMatrix().template cast(), lm2*lm); } void test_permutationmatrices() -- cgit v1.2.3 From 8a1bada43d64820f5e973d1692cc51eaf865bf76 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 16 Nov 2009 13:45:06 -0500 Subject: initialize-by-zero: remember that when the newsize==oldsize, resize() must remain a NOP --- Eigen/src/Core/Matrix.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h index 11d73f0c4..290247978 100644 --- a/Eigen/src/Core/Matrix.h +++ b/Eigen/src/Core/Matrix.h @@ -259,8 +259,14 @@ class Matrix && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) && (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols) && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)); - m_storage.resize(rows * cols, rows, cols); - EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO + int size = rows*cols; + bool size_changed = size != this->size(); + m_storage.resize(size, rows, cols); + if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + #else + m_storage.resize(rows*cols, rows, cols); + #endif } /** Resizes \c *this to a vector of length \a size @@ -278,11 +284,16 @@ class Matrix { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix) ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size); + #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO + bool size_changed = size != this->size(); + #endif if(RowsAtCompileTime == 1) m_storage.resize(size, 1, size); else m_storage.resize(size, size, 1); - EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO + if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + #endif } /** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange -- cgit v1.2.3 From e8d0dbf82e224fa57f0741bef58c3f57ec9f7895 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 16 Nov 2009 15:07:33 -0500 Subject: PermutationMatrix: * make multiplication order not be reversed * release-quality documentation --- Eigen/src/Core/PermutationMatrix.h | 72 ++++++++++++++++++++++++++++++-------- doc/Doxyfile.in | 3 +- test/permutationmatrices.cpp | 4 +-- 3 files changed, 61 insertions(+), 18 deletions(-) diff --git a/Eigen/src/Core/PermutationMatrix.h b/Eigen/src/Core/PermutationMatrix.h index 1c66cde8e..f2bde0e71 100644 --- a/Eigen/src/Core/PermutationMatrix.h +++ b/Eigen/src/Core/PermutationMatrix.h @@ -25,18 +25,24 @@ #ifndef EIGEN_PERMUTATIONMATRIX_H #define EIGEN_PERMUTATIONMATRIX_H -/** \nonstableyet - * \class PermutationMatrix +/** \class PermutationMatrix * * \brief Permutation matrix * * \param SizeAtCompileTime the number of rows/cols, or Dynamic - * \param MaxSizeAtCompileTime the maximum number of rows/cols, or Dynamic. This optional parameter defaults to SizeAtCompileTime. + * \param MaxSizeAtCompileTime the maximum number of rows/cols, or Dynamic. This optional parameter defaults to SizeAtCompileTime. Most of the time, you should not have to specify it. * * This class represents a permutation matrix, internally stored as a vector of integers. - * The convention followed here is the same as on Wikipedia, - * namely: the matrix of permutation \a p is the matrix such that on each row \a i, the only nonzero coefficient is - * in column p(i). + * The convention followed here is that if \f$ \sigma \f$ is a permutation, the corresponding permutation matrix + * \f$ P_\sigma \f$ is such that if \f$ (e_1,\ldots,e_p) \f$ is the canonical basis, we have: + * \f[ P_\sigma(e_i) = e_{\sigma(i)}. \f] + * This convention ensures that for any two permutations \f$ \sigma, \tau \f$, we have: + * \f[ P_{\sigma\circ\tau} = P_\sigma P_\tau. \f] + * + * Permutation matrices are square and invertible. + * + * Notice that in addition to the member functions and operators listed here, there also are non-member + * operator* to multiply a PermutationMatrix with any kind of matrix expression (MatrixBase) on either side. * * \sa class DiagonalMatrix */ @@ -53,6 +59,7 @@ class PermutationMatrix : public AnyMatrixBase Traits; typedef Matrix DenseMatrixType; @@ -65,25 +72,37 @@ class PermutationMatrix : public AnyMatrixBase IndicesType; + typedef Matrix IndicesType; inline PermutationMatrix() { } + /** Copy constructor. */ template inline PermutationMatrix(const PermutationMatrix& other) : m_indices(other.indices()) {} - /** copy constructor. prevent a default copy constructor from hiding the other templated constructor */ + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** Standard copy constructor. Defined only to prevent a default copy constructor + * from hiding the other templated constructor */ inline PermutationMatrix(const PermutationMatrix& other) : m_indices(other.indices()) {} - - /** generic constructor from expression of the indices */ + #endif + + /** Generic constructor from expression of the indices. The indices + * array has the meaning that the permutations sends each integer i to indices[i]. + * + * \warning It is your responsibility to check that the indices array that you passes actually + * describes a permutation, \ie each value between 0 and n-1 occurs exactly once, where n is the + * array's size. + */ template - explicit inline PermutationMatrix(const MatrixBase& other) : m_indices(other) + explicit inline PermutationMatrix(const MatrixBase& indices) : m_indices(indices) {} + /** Copies the other permutation into *this */ template PermutationMatrix& operator=(const PermutationMatrix& other) { @@ -91,6 +110,7 @@ class PermutationMatrix : public AnyMatrixBase void evalTo(MatrixBase& other) const { other.setZero(); for (int i=0; i inline PermutationMatrix operator*(const PermutationMatrix& other) const { return PermutationMatrix(Product, *this, other); } @@ -209,7 +251,7 @@ struct ei_permut_matrix_product_retval Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime - >(dst, Side==OnTheRight ? m_permutation.indices().coeff(i) : i) + >(dst, Side==OnTheLeft ? m_permutation.indices().coeff(i) : i) = @@ -217,7 +259,7 @@ struct ei_permut_matrix_product_retval MatrixTypeNestedCleaned, Side==OnTheLeft ? 1 : MatrixType::RowsAtCompileTime, Side==OnTheRight ? 1 : MatrixType::ColsAtCompileTime - >(m_matrix, Side==OnTheLeft ? m_permutation.indices().coeff(i) : i); + >(m_matrix, Side==OnTheRight ? m_permutation.indices().coeff(i) : i); } } diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index da99d3592..82ebf6aa0 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -218,7 +218,8 @@ ALIASES = "only_for_vectors=This is only for vectors (either row- "nonstableyet=\warning This is not considered to be part of the stable public API yet. Changes may happen in future releases. See \ref Experimental \"Experimental parts of Eigen\"" \ "note_about_arbitrary_choice_of_solution=If there exists more than one solution, this method will arbitrarily choose one." \ "note_about_using_kernel_to_study_multiple_solutions=If you need a complete analysis of the space of solutions, take the one solution obtained by this method and add to it elements of the kernel, as determined by kernel()." \ - "note_about_checking_solutions=This method just tries to find as good a solution as possible. If you want to check whether a solution exists or if it is accurate, just call this function to get a result and then compute the error of this result, or use MatrixBase::isApprox() directly, for instance like this: \code bool a_solution_exists = (A*result).isApprox(b, precision); \endcode This method avoids dividing by zero, so that the non-existence of a solution doesn't by itself mean that you'll get \c inf or \c nan values." + "note_about_checking_solutions=This method just tries to find as good a solution as possible. If you want to check whether a solution exists or if it is accurate, just call this function to get a result and then compute the error of this result, or use MatrixBase::isApprox() directly, for instance like this: \code bool a_solution_exists = (A*result).isApprox(b, precision); \endcode This method avoids dividing by zero, so that the non-existence of a solution doesn't by itself mean that you'll get \c inf or \c nan values." \ + "note_try_to_help_rvo=This function returns the result by value. In order to make that efficient, it is implemented as just a return statement using a special constructor, hopefully allowing the compiler to perform a RVO (return value optimization)." # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. diff --git a/test/permutationmatrices.cpp b/test/permutationmatrices.cpp index ec3a8541c..c4affc795 100644 --- a/test/permutationmatrices.cpp +++ b/test/permutationmatrices.cpp @@ -66,7 +66,7 @@ template void permutationmatrices(const MatrixType& m) for (int i=0; i lm(lp); Matrix rm(rp); @@ -80,7 +80,7 @@ template void permutationmatrices(const MatrixType& m) randomPermutationVector(lv2, rows); LeftPermutationType lp2(lv2); Matrix lm2(lp2); - VERIFY_IS_APPROX((lp*lp2).toDenseMatrix().template cast(), lm2*lm); + VERIFY_IS_APPROX((lp*lp2).toDenseMatrix().template cast(), lm*lm2); } void test_permutationmatrices() -- cgit v1.2.3 From eb6df28c6cab95c98c34898a3a0aa92d406493f6 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 16 Nov 2009 15:25:58 -0500 Subject: DiagonalMatrix: release-quality documentation BandMatrix: rename toDense() ---> toDenseMatrix() for consistency --- Eigen/src/Core/BandMatrix.h | 2 +- Eigen/src/Core/DiagonalMatrix.h | 47 ++++++++++++++++++++++++++++------------- test/bandmatrix.cpp | 4 ++-- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/Eigen/src/Core/BandMatrix.h b/Eigen/src/Core/BandMatrix.h index 841d1786a..b67f60691 100644 --- a/Eigen/src/Core/BandMatrix.h +++ b/Eigen/src/Core/BandMatrix.h @@ -171,7 +171,7 @@ class BandMatrix : public AnyMatrixBase(m_data, supers()-i, std::max(0,i), 1, diagonalLength(i)); } - PlainMatrixType toDense() const + PlainMatrixType toDenseMatrix() const { PlainMatrixType res(rows(),cols()); res.setZero(); diff --git a/Eigen/src/Core/DiagonalMatrix.h b/Eigen/src/Core/DiagonalMatrix.h index 1dec82229..e3e2120ea 100644 --- a/Eigen/src/Core/DiagonalMatrix.h +++ b/Eigen/src/Core/DiagonalMatrix.h @@ -26,6 +26,7 @@ #ifndef EIGEN_DIAGONALMATRIX_H #define EIGEN_DIAGONALMATRIX_H +#ifndef EIGEN_PARSED_BY_DOXYGEN template class DiagonalBase : public AnyMatrixBase { @@ -44,10 +45,8 @@ class DiagonalBase : public AnyMatrixBase typedef Matrix DenseMatrixType; - #ifndef EIGEN_PARSED_BY_DOXYGEN inline const Derived& derived() const { return *static_cast(this); } inline Derived& derived() { return *static_cast(this); } - #endif // not EIGEN_PARSED_BY_DOXYGEN DenseMatrixType toDenseMatrix() const { return derived(); } template @@ -77,16 +76,18 @@ void DiagonalBase::evalTo(MatrixBase &other) const other.setZero(); other.diagonal() = diagonal(); } +#endif /** \class DiagonalMatrix - * \nonstableyet * * \brief Represents a diagonal matrix with its storage * * \param _Scalar the type of coefficients - * \param _Size the dimension of the matrix, or Dynamic + * \param SizeAtCompileTime the dimension of the matrix, or Dynamic + * \param MaxSizeAtCompileTime the dimension of the matrix, or Dynamic. This parameter is optional and defaults + * to SizeAtCompileTime. Most of the time, you do not need to specify it. * - * \sa class Matrix + * \sa class DiagonalWrapper */ template struct ei_traits > @@ -100,10 +101,11 @@ class DiagonalMatrix : public DiagonalBase > { public: - + #ifndef EIGEN_PARSED_BY_DOXYGEN typedef typename ei_traits::DiagonalVectorType DiagonalVectorType; typedef const DiagonalMatrix& Nested; typedef _Scalar Scalar; + #endif protected: @@ -111,7 +113,9 @@ class DiagonalMatrix public: + /** const version of diagonal(). */ inline const DiagonalVectorType& diagonal() const { return m_diagonal; } + /** \returns a reference to the stored vector of diagonal coefficients. */ inline DiagonalVectorType& diagonal() { return m_diagonal; } /** Default constructor without initialization */ @@ -120,23 +124,27 @@ class DiagonalMatrix /** Constructs a diagonal matrix with given dimension */ inline DiagonalMatrix(int dim) : m_diagonal(dim) {} - /** 2D only */ + /** 2D constructor. */ inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {} - /** 3D only */ + /** 3D constructor. */ inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {} + /** Copy constructor. */ template inline DiagonalMatrix(const DiagonalBase& other) : m_diagonal(other.diagonal()) {} + #ifndef EIGEN_PARSED_BY_DOXYGEN /** copy constructor. prevent a default copy constructor from hiding the other templated constructor */ inline DiagonalMatrix(const DiagonalMatrix& other) : m_diagonal(other.diagonal()) {} + #endif /** generic constructor from expression of the diagonal coefficients */ template explicit inline DiagonalMatrix(const MatrixBase& other) : m_diagonal(other) {} + /** Copy operator. */ template DiagonalMatrix& operator=(const DiagonalBase& other) { @@ -144,6 +152,7 @@ class DiagonalMatrix return *this; } + #ifndef EIGEN_PARSED_BY_DOXYGEN /** This is a special case of the templated operator=. Its purpose is to * prevent a default operator= from hiding the templated operator=. */ @@ -152,23 +161,28 @@ class DiagonalMatrix m_diagonal = other.m_diagonal(); return *this; } + #endif + /** Resizes to given size. */ inline void resize(int size) { m_diagonal.resize(size); } + /** Sets all coefficients to zero. */ inline void setZero() { m_diagonal.setZero(); } + /** Resizes and sets all coefficients to zero. */ inline void setZero(int size) { m_diagonal.setZero(size); } + /** Sets this matrix to be the identity matrix of the current size. */ inline void setIdentity() { m_diagonal.setOnes(); } + /** Sets this matrix to be the identity matrix of the given size. */ inline void setIdentity(int size) { m_diagonal.setOnes(size); } }; /** \class DiagonalWrapper - * \nonstableyet * * \brief Expression of a diagonal matrix * * \param _DiagonalVectorType the type of the vector of diagonal coefficients * - * This class is an expression of a diagonal matrix with given vector of diagonal - * coefficients. It is the return type of MatrixBase::asDiagonal() + * This class is an expression of a diagonal matrix, but not storing its own vector of diagonal coefficients, + * instead wrapping an existing vector expression. It is the return type of MatrixBase::asDiagonal() * and most of the time this is the only way that it is used. * * \sa class DiagonalMatrix, class DiagonalBase, MatrixBase::asDiagonal() @@ -192,18 +206,22 @@ class DiagonalWrapper : public DiagonalBase >, ei_no_assignment_operator { public: + #ifndef EIGEN_PARSED_BY_DOXYGEN typedef _DiagonalVectorType DiagonalVectorType; typedef DiagonalWrapper Nested; + #endif + /** Constructor from expression of diagonal coefficients to wrap. */ inline DiagonalWrapper(const DiagonalVectorType& diagonal) : m_diagonal(diagonal) {} + + /** \returns a const reference to the wrapped expression of diagonal coefficients. */ const DiagonalVectorType& diagonal() const { return m_diagonal; } protected: const typename DiagonalVectorType::Nested m_diagonal; }; -/** \nonstableyet - * \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients +/** \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients * * \only_for_vectors * @@ -219,8 +237,7 @@ MatrixBase::asDiagonal() const return derived(); } -/** \nonstableyet - * \returns true if *this is approximately equal to a diagonal matrix, +/** \returns true if *this is approximately equal to a diagonal matrix, * within the precision given by \a prec. * * Example: \include MatrixBase_isDiagonal.cpp diff --git a/test/bandmatrix.cpp b/test/bandmatrix.cpp index ecb7304db..e243dffe5 100644 --- a/test/bandmatrix.cpp +++ b/test/bandmatrix.cpp @@ -53,7 +53,7 @@ template void bandmatrix(const MatrixType& _m) dm1.diagonal(-i).setConstant(-static_cast(i)); } //std::cerr << m.m_data << "\n\n" << m.toDense() << "\n\n" << dm1 << "\n\n\n\n"; - VERIFY_IS_APPROX(dm1,m.toDense()); + VERIFY_IS_APPROX(dm1,m.toDenseMatrix()); for (int i=0; i void bandmatrix(const MatrixType& _m) dm1.block(subs+1,0,rows-subs-1-b,rows-subs-1-b).template triangularView().setZero(); if(b>0) dm1.block(d+subs,0,b,cols).setZero(); //std::cerr << m.m_data << "\n\n" << m.toDense() << "\n\n" << dm1 << "\n\n"; - VERIFY_IS_APPROX(dm1,m.toDense()); + VERIFY_IS_APPROX(dm1,m.toDenseMatrix()); } -- cgit v1.2.3 From 76c614f9bd8e80a530a4aa685f1ae7506b64b8dd Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 16 Nov 2009 15:36:07 -0500 Subject: PartialPivLU: port to PermutationMatrix PermutationMatrix: add resize() --- Eigen/src/Core/PermutationMatrix.h | 3 +++ Eigen/src/LU/PartialPivLU.h | 18 ++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Eigen/src/Core/PermutationMatrix.h b/Eigen/src/Core/PermutationMatrix.h index f2bde0e71..b2acdb50d 100644 --- a/Eigen/src/Core/PermutationMatrix.h +++ b/Eigen/src/Core/PermutationMatrix.h @@ -159,6 +159,9 @@ class PermutationMatrix : public AnyMatrixBase class PartialPivLU typedef _MatrixType MatrixType; typedef typename MatrixType::Scalar Scalar; typedef typename NumTraits::Real RealScalar; - typedef Matrix IntRowVectorType; - typedef Matrix IntColVectorType; - typedef Matrix RowVectorType; - typedef Matrix ColVectorType; + typedef Matrix PermutationVectorType; + typedef PermutationMatrix PermutationType; enum { MaxSmallDimAtCompileTime = EIGEN_ENUM_MIN( MatrixType::MaxColsAtCompileTime, @@ -109,7 +107,7 @@ template class PartialPivLU * representing the P permutation i.e. the permutation of the rows. For its precise meaning, * see the examples given in the documentation of class FullPivLU. */ - inline const IntColVectorType& permutationP() const + inline const PermutationType& permutationP() const { ei_assert(m_isInitialized && "PartialPivLU is not initialized."); return m_p; @@ -174,7 +172,7 @@ template class PartialPivLU protected: MatrixType m_lu; - IntColVectorType m_p; + PermutationType m_p; int m_det_p; bool m_isInitialized; }; @@ -384,15 +382,15 @@ PartialPivLU& PartialPivLU::compute(const MatrixType& ma ei_assert(matrix.rows() == matrix.cols() && "PartialPivLU is only for square (and moreover invertible) matrices"); const int size = matrix.rows(); - IntColVectorType rows_transpositions(size); + PermutationVectorType rows_transpositions(size); int nb_transpositions; ei_partial_lu_inplace(m_lu, rows_transpositions, nb_transpositions); m_det_p = (nb_transpositions%2) ? -1 : 1; - for(int k = 0; k < size; ++k) m_p.coeffRef(k) = k; + for(int k = 0; k < size; ++k) m_p.indices().coeffRef(k) = k; for(int k = size-1; k >= 0; --k) - std::swap(m_p.coeffRef(k), m_p.coeffRef(rows_transpositions.coeff(k))); + std::swap(m_p.indices().coeffRef(k), m_p.indices().coeffRef(rows_transpositions.coeff(k))); m_isInitialized = true; return *this; @@ -428,7 +426,7 @@ struct ei_solve_retval, Rhs> dst.resize(size, rhs().cols()); // Step 1 - for(int i = 0; i < size; ++i) dst.row(dec().permutationP().coeff(i)) = rhs().row(i); + dst = dec().permutationP() * rhs(); // Step 2 dec().matrixLU().template triangularView().solveInPlace(dst); -- cgit v1.2.3 From b90744dc053d176f3ae00f67fbaac7f3b083b55e Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 16 Nov 2009 17:05:12 -0500 Subject: Port FullPivLU to PermutationMatrix --- Eigen/src/LU/FullPivLU.h | 45 ++++++++++++++++++---------------------- Eigen/src/LU/PartialPivLU.h | 4 +--- doc/snippets/class_FullPivLU.cpp | 6 +----- test/lu.cpp | 17 ++++++++++++++- 4 files changed, 38 insertions(+), 34 deletions(-) diff --git a/Eigen/src/LU/FullPivLU.h b/Eigen/src/LU/FullPivLU.h index d8975b0b6..62bdfba56 100644 --- a/Eigen/src/LU/FullPivLU.h +++ b/Eigen/src/LU/FullPivLU.h @@ -63,8 +63,8 @@ template class FullPivLU typedef typename NumTraits::Real RealScalar; typedef Matrix IntRowVectorType; typedef Matrix IntColVectorType; - typedef Matrix RowVectorType; - typedef Matrix ColVectorType; + typedef PermutationMatrix PermutationQType; + typedef PermutationMatrix PermutationPType; /** * \brief Default Constructor. @@ -120,25 +120,21 @@ template class FullPivLU */ RealScalar maxPivot() const { return m_maxpivot; } - /** \returns a vector of integers, whose size is the number of rows of the matrix being decomposed, - * representing the P permutation i.e. the permutation of the rows. For its precise meaning, - * see the examples given in the documentation of class FullPivLU. + /** \returns the permutation matrix P * * \sa permutationQ() */ - inline const IntColVectorType& permutationP() const + inline const PermutationPType& permutationP() const { ei_assert(m_isInitialized && "LU is not initialized."); return m_p; } - /** \returns a vector of integers, whose size is the number of columns of the matrix being - * decomposed, representing the Q permutation i.e. the permutation of the columns. - * For its precise meaning, see the examples given in the documentation of class FullPivLU. + /** \returns the permutation matrix Q * * \sa permutationP() */ - inline const IntRowVectorType& permutationQ() const + inline const PermutationQType& permutationQ() const { ei_assert(m_isInitialized && "LU is not initialized."); return m_q; @@ -368,8 +364,8 @@ template class FullPivLU protected: MatrixType m_lu; - IntColVectorType m_p; - IntRowVectorType m_q; + PermutationPType m_p; + PermutationQType m_q; int m_det_pq, m_nonzero_pivots; RealScalar m_maxpivot, m_prescribedThreshold; bool m_isInitialized, m_usePrescribedThreshold; @@ -463,13 +459,13 @@ FullPivLU& FullPivLU::compute(const MatrixType& matrix) // the main loop is over, we still have to accumulate the transpositions to find the // permutations P and Q - for(int k = 0; k < matrix.rows(); ++k) m_p.coeffRef(k) = k; + for(int k = 0; k < matrix.rows(); ++k) m_p.indices().coeffRef(k) = k; for(int k = size-1; k >= 0; --k) - std::swap(m_p.coeffRef(k), m_p.coeffRef(rows_transpositions.coeff(k))); + std::swap(m_p.indices().coeffRef(k), m_p.indices().coeffRef(rows_transpositions.coeff(k))); - for(int k = 0; k < matrix.cols(); ++k) m_q.coeffRef(k) = k; + for(int k = 0; k < matrix.cols(); ++k) m_q.indices().coeffRef(k) = k; for(int k = 0; k < size; ++k) - std::swap(m_q.coeffRef(k), m_q.coeffRef(cols_transpositions.coeff(k))); + std::swap(m_q.indices().coeffRef(k), m_q.indices().coeffRef(cols_transpositions.coeff(k))); m_det_pq = (number_of_transpositions%2) ? -1 : 1; return *this; @@ -562,9 +558,9 @@ struct ei_kernel_retval > m.col(i).swap(m.col(pivots.coeff(i))); // see the negative sign in the next line, that's what we were talking about above. - for(int i = 0; i < rank(); ++i) dst.row(dec().permutationQ().coeff(i)) = -m.row(i).end(dimker); - for(int i = rank(); i < cols; ++i) dst.row(dec().permutationQ().coeff(i)).setZero(); - for(int k = 0; k < dimker; ++k) dst.coeffRef(dec().permutationQ().coeff(rank()+k), k) = Scalar(1); + for(int i = 0; i < rank(); ++i) dst.row(dec().permutationQ().indices().coeff(i)) = -m.row(i).end(dimker); + for(int i = rank(); i < cols; ++i) dst.row(dec().permutationQ().indices().coeff(i)).setZero(); + for(int k = 0; k < dimker; ++k) dst.coeffRef(dec().permutationQ().indices().coeff(rank()+k), k) = Scalar(1); } }; @@ -599,9 +595,8 @@ struct ei_image_retval > if(ei_abs(dec().matrixLU().coeff(i,i)) > premultiplied_threshold) pivots.coeffRef(p++) = i; ei_internal_assert(p == rank()); - - for(int i = 0; i < rank(); ++i) - dst.col(i) = originalMatrix().col(dec().permutationQ().coeff(pivots.coeff(i))); + + dst.block(0,0,dst.rows(),rank()) = (originalMatrix()*dec().permutationQ()).block(0,0,dst.rows(),rank()); } }; @@ -638,7 +633,7 @@ struct ei_solve_retval, Rhs> // Step 1 for(int i = 0; i < rows; ++i) - c.row(dec().permutationP().coeff(i)) = rhs().row(i); + c.row(dec().permutationP().indices().coeff(i)) = rhs().row(i); // Step 2 dec().matrixLU() @@ -660,9 +655,9 @@ struct ei_solve_retval, Rhs> // Step 4 for(int i = 0; i < nonzero_pivots; ++i) - dst.row(dec().permutationQ().coeff(i)) = c.row(i); + dst.row(dec().permutationQ().indices().coeff(i)) = c.row(i); for(int i = nonzero_pivots; i < dec().matrixLU().cols(); ++i) - dst.row(dec().permutationQ().coeff(i)).setZero(); + dst.row(dec().permutationQ().indices().coeff(i)).setZero(); } }; diff --git a/Eigen/src/LU/PartialPivLU.h b/Eigen/src/LU/PartialPivLU.h index 847c895d7..4eb1162c1 100644 --- a/Eigen/src/LU/PartialPivLU.h +++ b/Eigen/src/LU/PartialPivLU.h @@ -103,9 +103,7 @@ template class PartialPivLU return m_lu; } - /** \returns a vector of integers, whose size is the number of rows of the matrix being decomposed, - * representing the P permutation i.e. the permutation of the rows. For its precise meaning, - * see the examples given in the documentation of class FullPivLU. + /** \returns the permutation matrix P. */ inline const PermutationType& permutationP() const { diff --git a/doc/snippets/class_FullPivLU.cpp b/doc/snippets/class_FullPivLU.cpp index 40d76e8e6..855782d15 100644 --- a/doc/snippets/class_FullPivLU.cpp +++ b/doc/snippets/class_FullPivLU.cpp @@ -13,8 +13,4 @@ cout << "Here is the U part:" << endl; Matrix5x3 u = lu.matrixLU().part(); cout << u << endl; cout << "Let us now reconstruct the original matrix m:" << endl; -Matrix5x3 x = l * u; -Matrix5x3 y; -for(int i = 0; i < 5; i++) for(int j = 0; j < 3; j++) - y(i, lu.permutationQ()[j]) = x(lu.permutationP()[i], j); -cout << y << endl; // should be equal to the original matrix m +cout << lu.permutationP().inverse() * l * u * lu.permutationQ().inverse() << endl; diff --git a/test/lu.cpp b/test/lu.cpp index 9dcebbeaa..c2237febf 100644 --- a/test/lu.cpp +++ b/test/lu.cpp @@ -24,9 +24,11 @@ #include "main.h" #include +using namespace std; template void lu_non_invertible() { + typedef typename MatrixType::Scalar Scalar; /* this test covers the following files: LU.h */ @@ -65,7 +67,20 @@ template void lu_non_invertible() createRandomMatrixOfRank(rank, rows, cols, m1); FullPivLU lu(m1); - std::cout << lu.kernel().rows() << " " << lu.kernel().cols() << std::endl; + // FIXME need better way to construct trapezoid matrices. extend triangularView to support rectangular. + DynamicMatrixType u(rows,cols); + for(int i = 0; i < rows; i++) + for(int j = 0; j < cols; j++) + u(i,j) = i>j ? Scalar(0) : lu.matrixLU()(i,j); + DynamicMatrixType l(rows,rows); + for(int i = 0; i < rows; i++) + for(int j = 0; j < rows; j++) + l(i,j) = (i=cols) ? Scalar(0) + : i==j ? Scalar(1) + : lu.matrixLU()(i,j); + + VERIFY_IS_APPROX(lu.permutationP() * m1 * lu.permutationQ(), l*u); + KernelMatrixType m1kernel = lu.kernel(); ImageMatrixType m1image = lu.image(m1); -- cgit v1.2.3 From 07412b2075a0d2924ae302f4af7ca54c923c9115 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 16 Nov 2009 21:28:26 -0500 Subject: PermutationMatrix: add setIdentity and transpositions methods LU: make use of that --- Eigen/src/Core/PermutationMatrix.h | 69 +++++++++++++++++++++++++++++++++----- Eigen/src/LU/FullPivLU.h | 10 +++--- Eigen/src/LU/PartialPivLU.h | 5 ++- test/permutationmatrices.cpp | 24 +++++++++++++ 4 files changed, 90 insertions(+), 18 deletions(-) diff --git a/Eigen/src/Core/PermutationMatrix.h b/Eigen/src/Core/PermutationMatrix.h index b2acdb50d..147c48734 100644 --- a/Eigen/src/Core/PermutationMatrix.h +++ b/Eigen/src/Core/PermutationMatrix.h @@ -116,18 +116,15 @@ class PermutationMatrix : public AnyMatrixBase=0 && j>=0 && i=0 && j>=0 && i& FullPivLU::compute(const MatrixType& matrix) { m_isInitialized = true; m_lu = matrix; - m_p.resize(matrix.rows()); - m_q.resize(matrix.cols()); const int size = matrix.diagonalSize(); const int rows = matrix.rows(); @@ -459,13 +457,13 @@ FullPivLU& FullPivLU::compute(const MatrixType& matrix) // the main loop is over, we still have to accumulate the transpositions to find the // permutations P and Q - for(int k = 0; k < matrix.rows(); ++k) m_p.indices().coeffRef(k) = k; + m_p.setIdentity(rows); for(int k = size-1; k >= 0; --k) - std::swap(m_p.indices().coeffRef(k), m_p.indices().coeffRef(rows_transpositions.coeff(k))); + m_p.applyTranspositionOnTheRight(k, rows_transpositions.coeff(k)); - for(int k = 0; k < matrix.cols(); ++k) m_q.indices().coeffRef(k) = k; + m_q.setIdentity(cols); for(int k = 0; k < size; ++k) - std::swap(m_q.indices().coeffRef(k), m_q.indices().coeffRef(cols_transpositions.coeff(k))); + m_q.applyTranspositionOnTheRight(k, cols_transpositions.coeff(k)); m_det_pq = (number_of_transpositions%2) ? -1 : 1; return *this; diff --git a/Eigen/src/LU/PartialPivLU.h b/Eigen/src/LU/PartialPivLU.h index 4eb1162c1..975f79287 100644 --- a/Eigen/src/LU/PartialPivLU.h +++ b/Eigen/src/LU/PartialPivLU.h @@ -375,7 +375,6 @@ template PartialPivLU& PartialPivLU::compute(const MatrixType& matrix) { m_lu = matrix; - m_p.resize(matrix.rows()); ei_assert(matrix.rows() == matrix.cols() && "PartialPivLU is only for square (and moreover invertible) matrices"); const int size = matrix.rows(); @@ -386,9 +385,9 @@ PartialPivLU& PartialPivLU::compute(const MatrixType& ma ei_partial_lu_inplace(m_lu, rows_transpositions, nb_transpositions); m_det_p = (nb_transpositions%2) ? -1 : 1; - for(int k = 0; k < size; ++k) m_p.indices().coeffRef(k) = k; + m_p.setIdentity(size); for(int k = size-1; k >= 0; --k) - std::swap(m_p.indices().coeffRef(k), m_p.indices().coeffRef(rows_transpositions.coeff(k))); + m_p.applyTranspositionOnTheRight(k, rows_transpositions.coeff(k)); m_isInitialized = true; return *this; diff --git a/test/permutationmatrices.cpp b/test/permutationmatrices.cpp index c4affc795..0ef0a371a 100644 --- a/test/permutationmatrices.cpp +++ b/test/permutationmatrices.cpp @@ -81,6 +81,30 @@ template void permutationmatrices(const MatrixType& m) LeftPermutationType lp2(lv2); Matrix lm2(lp2); VERIFY_IS_APPROX((lp*lp2).toDenseMatrix().template cast(), lm*lm2); + + LeftPermutationType identityp; + identityp.setIdentity(rows); + VERIFY_IS_APPROX(m_original, identityp*m_original); + + if(rows>1 && cols>1) + { + lp2 = lp; + int i = ei_random(0, rows-1); + int j; + do j = ei_random(0, rows-1); while(j==i); + lp2.applyTranspositionOnTheLeft(i, j); + lm = lp; + lm.row(i).swap(lm.row(j)); + VERIFY_IS_APPROX(lm, lp2.toDenseMatrix().template cast()); + + RightPermutationType rp2 = rp; + i = ei_random(0, cols-1); + do j = ei_random(0, cols-1); while(j==i); + rp2.applyTranspositionOnTheRight(i, j); + rm = rp; + rm.col(i).swap(rm.col(j)); + VERIFY_IS_APPROX(rm, rp2.toDenseMatrix().template cast()); + } } void test_permutationmatrices() -- cgit v1.2.3 From 984c00077878382a5b49c0cbbe150e488a801940 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 16 Nov 2009 21:33:41 -0500 Subject: addToDense ---> addTo subToDense ---> subTo --- Eigen/src/Core/AnyMatrixBase.h | 8 ++++---- Eigen/src/Core/DiagonalMatrix.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Eigen/src/Core/AnyMatrixBase.h b/Eigen/src/Core/AnyMatrixBase.h index 58b425740..eddf2d232 100644 --- a/Eigen/src/Core/AnyMatrixBase.h +++ b/Eigen/src/Core/AnyMatrixBase.h @@ -52,7 +52,7 @@ template struct AnyMatrixBase { derived().evalTo(dst); } /** \internal Don't use it, but do the equivalent: \code dst += *this; \endcode */ - template inline void addToDense(Dest& dst) const + template inline void addTo(Dest& dst) const { // This is the default implementation, // derived class can reimplement it in a more optimized way. @@ -62,7 +62,7 @@ template struct AnyMatrixBase } /** \internal Don't use it, but do the equivalent: \code dst -= *this; \endcode */ - template inline void subToDense(Dest& dst) const + template inline void subTo(Dest& dst) const { // This is the default implementation, // derived class can reimplement it in a more optimized way. @@ -109,7 +109,7 @@ template template Derived& MatrixBase::operator+=(const AnyMatrixBase &other) { - other.derived().addToDense(derived()); + other.derived().addTo(derived()); return derived(); } @@ -117,7 +117,7 @@ template template Derived& MatrixBase::operator-=(const AnyMatrixBase &other) { - other.derived().subToDense(derived()); + other.derived().subTo(derived()); return derived(); } diff --git a/Eigen/src/Core/DiagonalMatrix.h b/Eigen/src/Core/DiagonalMatrix.h index e3e2120ea..360f03dd2 100644 --- a/Eigen/src/Core/DiagonalMatrix.h +++ b/Eigen/src/Core/DiagonalMatrix.h @@ -52,10 +52,10 @@ class DiagonalBase : public AnyMatrixBase template void evalTo(MatrixBase &other) const; template - void addToDense(MatrixBase &other) const + void addTo(MatrixBase &other) const { other.diagonal() += diagonal(); } template - void subToDense(MatrixBase &other) const + void subTo(MatrixBase &other) const { other.diagonal() -= diagonal(); } inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); } -- cgit v1.2.3 From ac00902f8448156b85e29d8a9351b3f0ab700ae2 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 16 Nov 2009 21:43:15 -0500 Subject: for consistency: PlainMatrixType ---> DenseMatrixType --- Eigen/src/Core/BandMatrix.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Eigen/src/Core/BandMatrix.h b/Eigen/src/Core/BandMatrix.h index b67f60691..320981fa6 100644 --- a/Eigen/src/Core/BandMatrix.h +++ b/Eigen/src/Core/BandMatrix.h @@ -70,7 +70,7 @@ class BandMatrix : public AnyMatrixBase::MaxColsAtCompileTime }; typedef typename ei_traits::Scalar Scalar; - typedef Matrix PlainMatrixType; + typedef Matrix DenseMatrixType; protected: enum { @@ -171,9 +171,9 @@ class BandMatrix : public AnyMatrixBase(m_data, supers()-i, std::max(0,i), 1, diagonalLength(i)); } - PlainMatrixType toDenseMatrix() const + DenseMatrixType toDenseMatrix() const { - PlainMatrixType res(rows(),cols()); + DenseMatrixType res(rows(),cols()); res.setZero(); res.diagonal() = diagonal(); for (int i=1; i<=supers();++i) -- cgit v1.2.3 From 30b610a10f764529c7f93b6b7cd3cbf86a36e73d Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 16 Nov 2009 21:45:01 -0500 Subject: vade retro --- Eigen/src/Core/BandMatrix.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Eigen/src/Core/BandMatrix.h b/Eigen/src/Core/BandMatrix.h index 320981fa6..85bd8dba7 100644 --- a/Eigen/src/Core/BandMatrix.h +++ b/Eigen/src/Core/BandMatrix.h @@ -87,7 +87,7 @@ class BandMatrix : public AnyMatrixBase Date: Tue, 17 Nov 2009 08:14:54 -0500 Subject: port the QR module to PermutationMatrix --- Eigen/src/LU/FullPivLU.h | 6 +++--- Eigen/src/QR/ColPivHouseholderQR.h | 15 ++++++--------- Eigen/src/QR/FullPivHouseholderQR.h | 14 +++++++------- test/qr_fullpivoting.cpp | 5 +---- 4 files changed, 17 insertions(+), 23 deletions(-) diff --git a/Eigen/src/LU/FullPivLU.h b/Eigen/src/LU/FullPivLU.h index 607fe261f..28dc0cd47 100644 --- a/Eigen/src/LU/FullPivLU.h +++ b/Eigen/src/LU/FullPivLU.h @@ -594,7 +594,8 @@ struct ei_image_retval > pivots.coeffRef(p++) = i; ei_internal_assert(p == rank()); - dst.block(0,0,dst.rows(),rank()) = (originalMatrix()*dec().permutationQ()).block(0,0,dst.rows(),rank()); + for(int i = 0; i < rank(); ++i) + dst.col(i) = originalMatrix().col(dec().permutationQ().indices().coeff(pivots.coeff(i))); } }; @@ -630,8 +631,7 @@ struct ei_solve_retval, Rhs> typename Rhs::PlainMatrixType c(rhs().rows(), rhs().cols()); // Step 1 - for(int i = 0; i < rows; ++i) - c.row(dec().permutationP().indices().coeff(i)) = rhs().row(i); + c = dec().permutationP() * rhs(); // Step 2 dec().matrixLU() diff --git a/Eigen/src/QR/ColPivHouseholderQR.h b/Eigen/src/QR/ColPivHouseholderQR.h index d3c6b4c7c..e764af529 100644 --- a/Eigen/src/QR/ColPivHouseholderQR.h +++ b/Eigen/src/QR/ColPivHouseholderQR.h @@ -57,10 +57,9 @@ template class ColPivHouseholderQR typedef typename MatrixType::RealScalar RealScalar; typedef Matrix MatrixQType; typedef Matrix HCoeffsType; + typedef PermutationMatrix PermutationType; typedef Matrix IntRowVectorType; - typedef Matrix IntColVectorType; typedef Matrix RowVectorType; - typedef Matrix ColVectorType; typedef Matrix RealRowVectorType; typedef typename HouseholderSequence::ConjugateReturnType HouseholderSequenceType; @@ -117,7 +116,7 @@ template class ColPivHouseholderQR ColPivHouseholderQR& compute(const MatrixType& matrix); - const IntRowVectorType& colsPermutation() const + const PermutationType& colsPermutation() const { ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); return m_cols_permutation; @@ -230,7 +229,7 @@ template class ColPivHouseholderQR protected: MatrixType m_qr; HCoeffsType m_hCoeffs; - IntRowVectorType m_cols_permutation; + PermutationType m_cols_permutation; bool m_isInitialized; RealScalar m_precision; int m_rank; @@ -271,7 +270,6 @@ ColPivHouseholderQR& ColPivHouseholderQR::compute(const m_precision = epsilon() * size; IntRowVectorType cols_transpositions(matrix.cols()); - m_cols_permutation.resize(matrix.cols()); int number_of_transpositions = 0; RealRowVectorType colSqNorms(cols); @@ -314,9 +312,9 @@ ColPivHouseholderQR& ColPivHouseholderQR::compute(const colSqNorms.end(cols-k-1) -= m_qr.row(k).end(cols-k-1).cwise().abs2(); } - for(int k = 0; k < matrix.cols(); ++k) m_cols_permutation.coeffRef(k) = k; + m_cols_permutation.setIdentity(cols); for(int k = 0; k < size; ++k) - std::swap(m_cols_permutation.coeffRef(k), m_cols_permutation.coeffRef(cols_transpositions.coeff(k))); + m_cols_permutation.applyTranspositionOnTheLeft(k, cols_transpositions.coeff(k)); m_det_pq = (number_of_transpositions%2) ? -1 : 1; m_isInitialized = true; @@ -368,8 +366,7 @@ struct ei_solve_retval, Rhs> .template triangularView() .solveInPlace(c.corner(TopLeft, dec().rank(), c.cols())); - for(int i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().coeff(i)) = c.row(i); - for(int i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().coeff(i)).setZero(); + dst = dec().colsPermutation() * c; } }; diff --git a/Eigen/src/QR/FullPivHouseholderQR.h b/Eigen/src/QR/FullPivHouseholderQR.h index 07df5ed6b..ac0108046 100644 --- a/Eigen/src/QR/FullPivHouseholderQR.h +++ b/Eigen/src/QR/FullPivHouseholderQR.h @@ -58,6 +58,7 @@ template class FullPivHouseholderQR typedef Matrix MatrixQType; typedef Matrix HCoeffsType; typedef Matrix IntRowVectorType; + typedef PermutationMatrix PermutationType; typedef Matrix IntColVectorType; typedef Matrix RowVectorType; typedef Matrix ColVectorType; @@ -112,7 +113,7 @@ template class FullPivHouseholderQR FullPivHouseholderQR& compute(const MatrixType& matrix); - const IntRowVectorType& colsPermutation() const + const PermutationType& colsPermutation() const { ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); return m_cols_permutation; @@ -231,7 +232,7 @@ template class FullPivHouseholderQR MatrixType m_qr; HCoeffsType m_hCoeffs; IntColVectorType m_rows_transpositions; - IntRowVectorType m_cols_permutation; + PermutationType m_cols_permutation; bool m_isInitialized; RealScalar m_precision; int m_rank; @@ -273,7 +274,6 @@ FullPivHouseholderQR& FullPivHouseholderQR::compute(cons m_rows_transpositions.resize(matrix.rows()); IntRowVectorType cols_transpositions(matrix.cols()); - m_cols_permutation.resize(matrix.cols()); int number_of_transpositions = 0; RealScalar biggest(0); @@ -322,9 +322,9 @@ FullPivHouseholderQR& FullPivHouseholderQR::compute(cons .applyHouseholderOnTheLeft(m_qr.col(k).end(rows-k-1), m_hCoeffs.coeffRef(k), &temp.coeffRef(k+1)); } - for(int k = 0; k < matrix.cols(); ++k) m_cols_permutation.coeffRef(k) = k; + m_cols_permutation.setIdentity(cols); for(int k = 0; k < size; ++k) - std::swap(m_cols_permutation.coeffRef(k), m_cols_permutation.coeffRef(cols_transpositions.coeff(k))); + m_cols_permutation.applyTranspositionOnTheRight(k, cols_transpositions.coeff(k)); m_det_pq = (number_of_transpositions%2) ? -1 : 1; m_isInitialized = true; @@ -379,8 +379,8 @@ struct ei_solve_retval, Rhs> .template triangularView() .solveInPlace(c.corner(TopLeft, dec().rank(), c.cols())); - for(int i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().coeff(i)) = c.row(i); - for(int i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().coeff(i)).setZero(); + for(int i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i); + for(int i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero(); } }; diff --git a/test/qr_fullpivoting.cpp b/test/qr_fullpivoting.cpp index 65d9a071f..c82ba4c7e 100644 --- a/test/qr_fullpivoting.cpp +++ b/test/qr_fullpivoting.cpp @@ -51,11 +51,8 @@ template void qr() // FIXME need better way to construct trapezoid for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) if(i>j) r(i,j) = Scalar(0); - MatrixType b = qr.matrixQ() * r; + MatrixType c = qr.matrixQ() * r * qr.colsPermutation().inverse(); - MatrixType c = MatrixType::Zero(rows,cols); - - for(int i = 0; i < cols; ++i) c.col(qr.colsPermutation().coeff(i)) = b.col(i); VERIFY_IS_APPROX(m1, c); MatrixType m2 = MatrixType::Random(cols,cols2); -- cgit v1.2.3 From 94c706d04fe74cfc6917f6ac057e0c3ca98796c7 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 18 Nov 2009 11:57:07 -0500 Subject: Assign.h: add LinearTraversal (non-vectorized index-based traversal) Rename some constants to make names match more closely what they mean. --- Eigen/src/Core/Assign.h | 143 ++++++++++++++++++++---------- Eigen/src/Core/Dot.h | 26 +++--- Eigen/src/Core/Redux.h | 28 +++--- Eigen/src/Core/products/GeneralUnrolled.h | 28 +++--- Eigen/src/Core/util/Constants.h | 11 ++- test/vectorization_logic.cpp | 55 +++++++----- 6 files changed, 176 insertions(+), 115 deletions(-) diff --git a/Eigen/src/Core/Assign.h b/Eigen/src/Core/Assign.h index 8dc015715..86ba45481 100644 --- a/Eigen/src/Core/Assign.h +++ b/Eigen/src/Core/Assign.h @@ -57,40 +57,46 @@ private: && ((int(Derived::Flags)&RowMajorBit)==(int(OtherDerived::Flags)&RowMajorBit)), MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0 && int(DstIsAligned) && int(SrcIsAligned), - MayLinearVectorize = MightVectorize && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit) - && (DstIsAligned || InnerMaxSize == Dynamic),/* If the destination isn't aligned, - we have to do runtime checks and we don't unroll, so it's only good for large enough sizes. See remark below - about InnerMaxSize. */ - MaySliceVectorize = MightVectorize && int(InnerMaxSize)>=3*PacketSize /* slice vectorization can be slow, so we only - want it if the slices are big, which is indicated by InnerMaxSize rather than InnerSize, think of the case - of a dynamic block in a fixed-size matrix */ + MayLinearize = (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit), + MayLinearVectorize = MightVectorize && MayLinearize + && (DstIsAligned || InnerMaxSize == Dynamic), + /* If the destination isn't aligned, we have to do runtime checks and we don't unroll, + so it's only good for large enough sizes. See remark below about InnerMaxSize. */ + MaySliceVectorize = MightVectorize && int(InnerMaxSize)>=3*PacketSize + /* slice vectorization can be slow, so we only want it if the slices are big, which is + indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block + in a fixed-size matrix */ }; public: enum { - Vectorization = int(MayInnerVectorize) ? int(InnerVectorization) - : int(MayLinearVectorize) ? int(LinearVectorization) - : int(MaySliceVectorize) ? int(SliceVectorization) - : int(NoVectorization) + Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal) + : int(MayLinearVectorize) ? int(LinearVectorizedTraversal) + : int(MaySliceVectorize) ? int(SliceVectorizedTraversal) + : int(MayLinearize) ? int(LinearTraversal) + : int(DefaultTraversal), + Vectorized = int(Traversal) != LinearTraversal && int(Traversal) == DefaultTraversal }; private: enum { - UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize)), + UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? 1 : int(PacketSize)), MayUnrollCompletely = int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit), MayUnrollInner = int(InnerSize * OtherDerived::CoeffReadCost) <= int(UnrollingLimit) }; public: enum { - Unrolling = (int(Vectorization) == int(InnerVectorization) || int(Vectorization) == int(NoVectorization)) - ? ( - int(MayUnrollCompletely) ? int(CompleteUnrolling) - : int(MayUnrollInner) ? int(InnerUnrolling) - : int(NoUnrolling) - ) - : int(Vectorization) == int(LinearVectorization) - ? ( int(MayUnrollCompletely) && int(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) ) + Unrolling = (int(Traversal) == int(InnerVectorizedTraversal) || int(Traversal) == int(DefaultTraversal)) + ? ( + int(MayUnrollCompletely) ? int(CompleteUnrolling) + : int(MayUnrollInner) ? int(InnerUnrolling) + : int(NoUnrolling) + ) + : int(Traversal) == int(LinearVectorizedTraversal) + ? ( int(MayUnrollCompletely) && int(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) ) + : int(Traversal) == int(LinearTraversal) + ? ( int(MayUnrollCompletely) ? int(CompleteUnrolling) : int(NoUnrolling) ) : int(NoUnrolling) }; @@ -106,7 +112,7 @@ public: EIGEN_DEBUG_VAR(MayInnerVectorize) EIGEN_DEBUG_VAR(MayLinearVectorize) EIGEN_DEBUG_VAR(MaySliceVectorize) - EIGEN_DEBUG_VAR(Vectorization) + EIGEN_DEBUG_VAR(Traversal) EIGEN_DEBUG_VAR(UnrollingLimit) EIGEN_DEBUG_VAR(MayUnrollCompletely) EIGEN_DEBUG_VAR(MayUnrollInner) @@ -118,12 +124,12 @@ public: * Part 2 : meta-unrollers ***************************************************************************/ -/*********************** -*** No vectorization *** -***********************/ +/************************ +*** Default traversal *** +************************/ template -struct ei_assign_novec_CompleteUnrolling +struct ei_assign_DefaultTraversal_CompleteUnrolling { enum { row = int(Derived1::Flags)&RowMajorBit @@ -137,18 +143,18 @@ struct ei_assign_novec_CompleteUnrolling EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) { dst.copyCoeff(row, col, src); - ei_assign_novec_CompleteUnrolling::run(dst, src); + ei_assign_DefaultTraversal_CompleteUnrolling::run(dst, src); } }; template -struct ei_assign_novec_CompleteUnrolling +struct ei_assign_DefaultTraversal_CompleteUnrolling { EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {} }; template -struct ei_assign_novec_InnerUnrolling +struct ei_assign_DefaultTraversal_InnerUnrolling { EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int row_or_col) { @@ -156,16 +162,36 @@ struct ei_assign_novec_InnerUnrolling const int row = rowMajor ? row_or_col : Index; const int col = rowMajor ? Index : row_or_col; dst.copyCoeff(row, col, src); - ei_assign_novec_InnerUnrolling::run(dst, src, row_or_col); + ei_assign_DefaultTraversal_InnerUnrolling::run(dst, src, row_or_col); } }; template -struct ei_assign_novec_InnerUnrolling +struct ei_assign_DefaultTraversal_InnerUnrolling { EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {} }; +/*********************** +*** Linear traversal *** +***********************/ + +template +struct ei_assign_LinearTraversal_CompleteUnrolling +{ + EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + { + dst.copyCoeff(Index, src); + ei_assign_LinearTraversal_CompleteUnrolling::run(dst, src); + } +}; + +template +struct ei_assign_LinearTraversal_CompleteUnrolling +{ + EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {} +}; + /************************** *** Inner vectorization *** **************************/ @@ -221,16 +247,16 @@ struct ei_assign_innervec_InnerUnrolling ***************************************************************************/ template::Vectorization, + int Traversal = ei_assign_traits::Traversal, int Unrolling = ei_assign_traits::Unrolling> struct ei_assign_impl; -/*********************** -*** No vectorization *** -***********************/ +/************************ +*** Default traversal *** +************************/ template -struct ei_assign_impl +struct ei_assign_impl { inline static void run(Derived1 &dst, const Derived2 &src) { @@ -248,17 +274,17 @@ struct ei_assign_impl }; template -struct ei_assign_impl +struct ei_assign_impl { EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) { - ei_assign_novec_CompleteUnrolling + ei_assign_DefaultTraversal_CompleteUnrolling ::run(dst, src); } }; template -struct ei_assign_impl +struct ei_assign_impl { EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) { @@ -266,17 +292,42 @@ struct ei_assign_impl const int innerSize = rowMajor ? Derived1::ColsAtCompileTime : Derived1::RowsAtCompileTime; const int outerSize = dst.outerSize(); for(int j = 0; j < outerSize; ++j) - ei_assign_novec_InnerUnrolling + ei_assign_DefaultTraversal_InnerUnrolling ::run(dst, src, j); } }; +/*********************** +*** Linear traversal *** +***********************/ + +template +struct ei_assign_impl +{ + inline static void run(Derived1 &dst, const Derived2 &src) + { + const int size = dst.size(); + for(int i = 0; i < size; ++i) + dst.copyCoeff(i, src); + } +}; + +template +struct ei_assign_impl +{ + EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + { + ei_assign_LinearTraversal_CompleteUnrolling + ::run(dst, src); + } +}; + /************************** *** Inner vectorization *** **************************/ template -struct ei_assign_impl +struct ei_assign_impl { inline static void run(Derived1 &dst, const Derived2 &src) { @@ -295,7 +346,7 @@ struct ei_assign_impl }; template -struct ei_assign_impl +struct ei_assign_impl { EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) { @@ -305,7 +356,7 @@ struct ei_assign_impl }; template -struct ei_assign_impl +struct ei_assign_impl { EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) { @@ -323,7 +374,7 @@ struct ei_assign_impl ***************************/ template -struct ei_assign_impl +struct ei_assign_impl { inline static void run(Derived1 &dst, const Derived2 &src) { @@ -347,7 +398,7 @@ struct ei_assign_impl }; template -struct ei_assign_impl +struct ei_assign_impl { EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) { @@ -356,7 +407,7 @@ struct ei_assign_impl::run(dst, src); - ei_assign_novec_CompleteUnrolling::run(dst, src); + ei_assign_DefaultTraversal_CompleteUnrolling::run(dst, src); } }; @@ -365,7 +416,7 @@ struct ei_assign_impl -struct ei_assign_impl +struct ei_assign_impl { inline static void run(Derived1 &dst, const Derived2 &src) { diff --git a/Eigen/src/Core/Dot.h b/Eigen/src/Core/Dot.h index 631124f2b..a8983d4ce 100644 --- a/Eigen/src/Core/Dot.h +++ b/Eigen/src/Core/Dot.h @@ -34,10 +34,10 @@ struct ei_dot_traits { public: enum { - Vectorization = (int(Derived1::Flags)&int(Derived2::Flags)&ActualPacketAccessBit) + Traversal = (int(Derived1::Flags)&int(Derived2::Flags)&ActualPacketAccessBit) && (int(Derived1::Flags)&int(Derived2::Flags)&LinearAccessBit) - ? LinearVectorization - : NoVectorization + ? LinearVectorizedTraversal + : DefaultTraversal }; private: @@ -46,7 +46,7 @@ private: PacketSize = ei_packet_traits::size, Cost = Derived1::SizeAtCompileTime * (Derived1::CoeffReadCost + Derived2::CoeffReadCost + NumTraits::MulCost) + (Derived1::SizeAtCompileTime-1) * NumTraits::AddCost, - UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize)) + UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize)) }; public: @@ -142,13 +142,13 @@ struct ei_dot_vec_unroller ***************************************************************************/ template::Vectorization, + int Traversal = ei_dot_traits::Traversal, int Unrolling = ei_dot_traits::Unrolling > struct ei_dot_impl; template -struct ei_dot_impl +struct ei_dot_impl { typedef typename Derived1::Scalar Scalar; static Scalar run(const Derived1& v1, const Derived2& v2) @@ -163,12 +163,12 @@ struct ei_dot_impl }; template -struct ei_dot_impl +struct ei_dot_impl : public ei_dot_novec_unroller {}; template -struct ei_dot_impl +struct ei_dot_impl { typedef typename Derived1::Scalar Scalar; typedef typename ei_packet_traits::type PacketScalar; @@ -221,20 +221,20 @@ struct ei_dot_impl }; template -struct ei_dot_impl +struct ei_dot_impl { typedef typename Derived1::Scalar Scalar; typedef typename ei_packet_traits::type PacketScalar; enum { PacketSize = ei_packet_traits::size, Size = Derived1::SizeAtCompileTime, - VectorizationSize = (Size / PacketSize) * PacketSize + VectorizedSize = (Size / PacketSize) * PacketSize }; static Scalar run(const Derived1& v1, const Derived2& v2) { - Scalar res = ei_predux(ei_dot_vec_unroller::run(v1, v2)); - if (VectorizationSize != Size) - res += ei_dot_novec_unroller::run(v1, v2); + Scalar res = ei_predux(ei_dot_vec_unroller::run(v1, v2)); + if (VectorizedSize != Size) + res += ei_dot_novec_unroller::run(v1, v2); return res; } }; diff --git a/Eigen/src/Core/Redux.h b/Eigen/src/Core/Redux.h index 9f796157a..171f6dcf5 100644 --- a/Eigen/src/Core/Redux.h +++ b/Eigen/src/Core/Redux.h @@ -54,16 +54,16 @@ private: public: enum { - Vectorization = int(MayLinearVectorize) ? int(LinearVectorization) - : int(MaySliceVectorize) ? int(SliceVectorization) - : int(NoVectorization) + Traversal = int(MayLinearVectorize) ? int(LinearVectorizedTraversal) + : int(MaySliceVectorize) ? int(SliceVectorizedTraversal) + : int(DefaultTraversal) }; private: enum { Cost = Derived::SizeAtCompileTime * Derived::CoeffReadCost + (Derived::SizeAtCompileTime-1) * NumTraits::AddCost, - UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize)) + UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize)) }; public: @@ -171,13 +171,13 @@ struct ei_redux_vec_unroller ***************************************************************************/ template::Vectorization, + int Traversal = ei_redux_traits::Traversal, int Unrolling = ei_redux_traits::Unrolling > struct ei_redux_impl; template -struct ei_redux_impl +struct ei_redux_impl { typedef typename Derived::Scalar Scalar; static Scalar run(const Derived& mat, const Func& func) @@ -195,12 +195,12 @@ struct ei_redux_impl }; template -struct ei_redux_impl +struct ei_redux_impl : public ei_redux_novec_unroller {}; template -struct ei_redux_impl +struct ei_redux_impl { typedef typename Derived::Scalar Scalar; typedef typename ei_packet_traits::type PacketScalar; @@ -246,7 +246,7 @@ struct ei_redux_impl }; template -struct ei_redux_impl +struct ei_redux_impl { typedef typename Derived::Scalar Scalar; typedef typename ei_packet_traits::type PacketScalar; @@ -277,7 +277,7 @@ struct ei_redux_impl else // too small to vectorize anything. // since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize. { - res = ei_redux_impl::run(mat, func); + res = ei_redux_impl::run(mat, func); } return res; @@ -285,20 +285,20 @@ struct ei_redux_impl }; template -struct ei_redux_impl +struct ei_redux_impl { typedef typename Derived::Scalar Scalar; typedef typename ei_packet_traits::type PacketScalar; enum { PacketSize = ei_packet_traits::size, Size = Derived::SizeAtCompileTime, - VectorizationSize = (Size / PacketSize) * PacketSize + VectorizedSize = (Size / PacketSize) * PacketSize }; EIGEN_STRONG_INLINE static Scalar run(const Derived& mat, const Func& func) { Scalar res = func.predux(ei_redux_vec_unroller::run(mat,func)); - if (VectorizationSize != Size) - res = func(res,ei_redux_novec_unroller::run(mat,func)); + if (VectorizedSize != Size) + res = func(res,ei_redux_novec_unroller::run(mat,func)); return res; } }; diff --git a/Eigen/src/Core/products/GeneralUnrolled.h b/Eigen/src/Core/products/GeneralUnrolled.h index 7241976a8..e8fb760ae 100644 --- a/Eigen/src/Core/products/GeneralUnrolled.h +++ b/Eigen/src/Core/products/GeneralUnrolled.h @@ -36,7 +36,7 @@ * Note that here the inner-loops should always be unrolled. */ -template +template struct ei_product_coeff_impl; template @@ -115,7 +115,7 @@ template class GeneralProduct::CanVectorizeInner }; - typedef ei_product_coeff_impl ScalarCoeffImpl; @@ -182,17 +182,17 @@ template class GeneralProduct -struct ei_product_coeff_impl +struct ei_product_coeff_impl { EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { - ei_product_coeff_impl::run(row, col, lhs, rhs, res); + ei_product_coeff_impl::run(row, col, lhs, rhs, res); res += lhs.coeff(row, Index) * rhs.coeff(Index, col); } }; template -struct ei_product_coeff_impl +struct ei_product_coeff_impl { EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { @@ -201,7 +201,7 @@ struct ei_product_coeff_impl }; template -struct ei_product_coeff_impl +struct ei_product_coeff_impl { EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar& res) { @@ -214,7 +214,7 @@ struct ei_product_coeff_impl // prevent buggy user code from causing an infinite recursion template -struct ei_product_coeff_impl +struct ei_product_coeff_impl { EIGEN_STRONG_INLINE static void run(int, int, const Lhs&, const Rhs&, RetScalar&) {} }; @@ -244,7 +244,7 @@ struct ei_product_coeff_vectorized_unroller<0, Lhs, Rhs, PacketScalar> }; template -struct ei_product_coeff_impl +struct ei_product_coeff_impl { typedef typename Lhs::PacketScalar PacketScalar; enum { PacketSize = ei_packet_traits::size }; @@ -252,7 +252,7 @@ struct ei_product_coeff_impl { PacketScalar pres; ei_product_coeff_vectorized_unroller::run(row, col, lhs, rhs, pres); - ei_product_coeff_impl::run(row, col, lhs, rhs, res); + ei_product_coeff_impl::run(row, col, lhs, rhs, res); res = ei_predux(pres); } }; @@ -265,7 +265,7 @@ struct ei_product_coeff_vectorized_dyn_selector res = ei_dot_impl< Block::ColsAtCompileTime>, Block::RowsAtCompileTime, 1>, - LinearVectorization, NoUnrolling>::run(lhs.row(row), rhs.col(col)); + LinearVectorizedTraversal, NoUnrolling>::run(lhs.row(row), rhs.col(col)); } }; @@ -279,7 +279,7 @@ struct ei_product_coeff_vectorized_dyn_selector res = ei_dot_impl< Lhs, Block::RowsAtCompileTime, 1>, - LinearVectorization, NoUnrolling>::run(lhs, rhs.col(col)); + LinearVectorizedTraversal, NoUnrolling>::run(lhs, rhs.col(col)); } }; @@ -291,7 +291,7 @@ struct ei_product_coeff_vectorized_dyn_selector res = ei_dot_impl< Block::ColsAtCompileTime>, Rhs, - LinearVectorization, NoUnrolling>::run(lhs.row(row), rhs); + LinearVectorizedTraversal, NoUnrolling>::run(lhs.row(row), rhs); } }; @@ -303,12 +303,12 @@ struct ei_product_coeff_vectorized_dyn_selector res = ei_dot_impl< Lhs, Rhs, - LinearVectorization, NoUnrolling>::run(lhs, rhs); + LinearVectorizedTraversal, NoUnrolling>::run(lhs, rhs); } }; template -struct ei_product_coeff_impl +struct ei_product_coeff_impl { EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) { diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h index 487425f88..5489d063a 100644 --- a/Eigen/src/Core/util/Constants.h +++ b/Eigen/src/Core/util/Constants.h @@ -202,16 +202,19 @@ enum DirectionType { Vertical, Horizontal, BothDirections }; enum ProductEvaluationMode { NormalProduct, CacheFriendlyProduct, SparseTimeSparseProduct, SparseTimeDenseProduct, DenseTimeSparseProduct }; enum { + /** \internal Default traversal, no vectorization, no index-based access */ + DefaultTraversal, + /** \internal No vectorization, use index-based access to have only one for loop instead of 2 nested loops */ + LinearTraversal, /** \internal Equivalent to a slice vectorization for fixed-size matrices having good alignment * and good size */ - InnerVectorization, + InnerVectorizedTraversal, /** \internal Vectorization path using a single loop plus scalar loops for the * unaligned boundaries */ - LinearVectorization, + LinearVectorizedTraversal, /** \internal Generic vectorization path using one vectorized loop per row/column with some * scalar loops to handle the unaligned boundaries */ - SliceVectorization, - NoVectorization + SliceVectorizedTraversal }; enum { diff --git a/test/vectorization_logic.cpp b/test/vectorization_logic.cpp index 680adeb45..3772bf13d 100644 --- a/test/vectorization_logic.cpp +++ b/test/vectorization_logic.cpp @@ -26,17 +26,18 @@ #include template -bool test_assign(const Dst&, const Src&, int vectorization, int unrolling) +bool test_assign(const Dst&, const Src&, int traversal, int unrolling) { - return ei_assign_traits::Vectorization==vectorization + ei_assign_traits::debug(); + return ei_assign_traits::Traversal==traversal && ei_assign_traits::Unrolling==unrolling; } template -bool test_redux(const Xpr&, int vectorization, int unrolling) +bool test_redux(const Xpr&, int traversal, int unrolling) { typedef ei_redux_traits,Xpr> traits; - return traits::Vectorization==vectorization && traits::Unrolling==unrolling; + return traits::Traversal==traversal && traits::Unrolling==unrolling; } void test_vectorization_logic() @@ -45,61 +46,67 @@ void test_vectorization_logic() #ifdef EIGEN_VECTORIZE VERIFY(test_assign(Vector4f(),Vector4f(), - InnerVectorization,CompleteUnrolling)); + InnerVectorizedTraversal,CompleteUnrolling)); VERIFY(test_assign(Vector4f(),Vector4f()+Vector4f(), - InnerVectorization,CompleteUnrolling)); + InnerVectorizedTraversal,CompleteUnrolling)); VERIFY(test_assign(Vector4f(),Vector4f().cwise() * Vector4f(), - InnerVectorization,CompleteUnrolling)); + InnerVectorizedTraversal,CompleteUnrolling)); VERIFY(test_assign(Vector4f(),Vector4f().cast(), - InnerVectorization,CompleteUnrolling)); + InnerVectorizedTraversal,CompleteUnrolling)); VERIFY(test_assign(Matrix4f(),Matrix4f(), - InnerVectorization,CompleteUnrolling)); + InnerVectorizedTraversal,CompleteUnrolling)); VERIFY(test_assign(Matrix4f(),Matrix4f()+Matrix4f(), - InnerVectorization,CompleteUnrolling)); + InnerVectorizedTraversal,CompleteUnrolling)); VERIFY(test_assign(Matrix4f(),Matrix4f().cwise() * Matrix4f(), - InnerVectorization,CompleteUnrolling)); + InnerVectorizedTraversal,CompleteUnrolling)); VERIFY(test_assign(Matrix(),Matrix()+Matrix(), - InnerVectorization,InnerUnrolling)); + InnerVectorizedTraversal,InnerUnrolling)); VERIFY(test_assign(Matrix(),Matrix()+Matrix(), - NoVectorization,InnerUnrolling)); + LinearTraversal,NoUnrolling)); + + VERIFY(test_assign(Matrix(),Matrix()+Matrix(), + LinearTraversal,CompleteUnrolling)); VERIFY(test_assign(Matrix(),Matrix().cwise() / Matrix(), - LinearVectorization,CompleteUnrolling)); + LinearVectorizedTraversal,CompleteUnrolling)); VERIFY(test_assign(Matrix(),Matrix()+Matrix(), - NoVectorization,InnerUnrolling)); + LinearTraversal,NoUnrolling)); + + VERIFY(test_assign(Matrix(),Matrix()+Matrix(), + LinearTraversal,CompleteUnrolling)); VERIFY(test_assign(Matrix(),Matrix().block<4,4>(2,3)+Matrix().block<4,4>(10,4), - NoVectorization,CompleteUnrolling)); + DefaultTraversal,CompleteUnrolling)); VERIFY(test_assign(MatrixXf(10,10),MatrixXf(20,20).block(10,10,2,3), - SliceVectorization,NoUnrolling)); + SliceVectorizedTraversal,NoUnrolling)); VERIFY(test_redux(VectorXf(10), - LinearVectorization,NoUnrolling)); + LinearVectorizedTraversal,NoUnrolling)); VERIFY(test_redux(Matrix(), - NoVectorization,CompleteUnrolling)); + DefaultTraversal,CompleteUnrolling)); VERIFY(test_redux(Matrix(), - LinearVectorization,CompleteUnrolling)); + LinearVectorizedTraversal,CompleteUnrolling)); VERIFY(test_redux(Matrix(), - LinearVectorization,NoUnrolling)); + LinearVectorizedTraversal,NoUnrolling)); VERIFY(test_redux(Matrix().block<4,4>(1,2), - NoVectorization,CompleteUnrolling)); + DefaultTraversal,CompleteUnrolling)); VERIFY(test_redux(Matrix().block<8,1>(1,2), - LinearVectorization,CompleteUnrolling)); + LinearVectorizedTraversal,CompleteUnrolling)); VERIFY(test_redux(Matrix(), - NoVectorization,CompleteUnrolling)); + DefaultTraversal,CompleteUnrolling)); #endif // EIGEN_VECTORIZE -- cgit v1.2.3 From 8860203e6a29d7cc5f19097ca57aa458ee449777 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 18 Nov 2009 12:41:24 -0500 Subject: fix stuff after the PermutationMatrix changes. I still have JacobiSVD errors when cols>rows --- Eigen/src/QR/ColPivHouseholderQR.h | 2 +- Eigen/src/SVD/JacobiSVD.h | 9 +++------ test/jacobisvd.cpp | 3 +++ test/qr_colpivoting.cpp | 9 ++++++--- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Eigen/src/QR/ColPivHouseholderQR.h b/Eigen/src/QR/ColPivHouseholderQR.h index e764af529..4e983684f 100644 --- a/Eigen/src/QR/ColPivHouseholderQR.h +++ b/Eigen/src/QR/ColPivHouseholderQR.h @@ -314,7 +314,7 @@ ColPivHouseholderQR& ColPivHouseholderQR::compute(const m_cols_permutation.setIdentity(cols); for(int k = 0; k < size; ++k) - m_cols_permutation.applyTranspositionOnTheLeft(k, cols_transpositions.coeff(k)); + m_cols_permutation.applyTranspositionOnTheRight(k, cols_transpositions.coeff(k)); m_det_pq = (number_of_transpositions%2) ? -1 : 1; m_isInitialized = true; diff --git a/Eigen/src/SVD/JacobiSVD.h b/Eigen/src/SVD/JacobiSVD.h index 927ef6591..2f7ebb160 100644 --- a/Eigen/src/SVD/JacobiSVD.h +++ b/Eigen/src/SVD/JacobiSVD.h @@ -236,9 +236,8 @@ struct ei_svd_precondition_if_more_rows_than_cols FullPivHouseholderQR qr(matrix); work_matrix = qr.matrixQR().block(0,0,diagSize,diagSize).template triangularView(); if(ComputeU) svd.m_matrixU = qr.matrixQ(); - if(ComputeV) - for(int i = 0; i < cols; i++) - svd.m_matrixV.coeffRef(qr.colsPermutation().coeff(i),i) = Scalar(1); + if(ComputeV) svd.m_matrixV = qr.colsPermutation(); + return true; } else return false; @@ -281,9 +280,7 @@ struct ei_svd_precondition_if_more_cols_than_rows FullPivHouseholderQR qr(matrix.adjoint()); work_matrix = qr.matrixQR().block(0,0,diagSize,diagSize).template triangularView().adjoint(); if(ComputeV) svd.m_matrixV = qr.matrixQ(); - if(ComputeU) - for(int i = 0; i < rows; i++) - svd.m_matrixU.coeffRef(qr.colsPermutation().coeff(i),i) = Scalar(1); + if(ComputeU) svd.m_matrixU = qr.colsPermutation(); return true; } else return false; diff --git a/test/jacobisvd.cpp b/test/jacobisvd.cpp index f3a143e3c..587bc7572 100644 --- a/test/jacobisvd.cpp +++ b/test/jacobisvd.cpp @@ -54,6 +54,9 @@ template void svd(const MatrixType& m MatrixUType u = svd.matrixU(); MatrixVType v = svd.matrixV(); + std::cout << "a\n" << a << std::endl; + std::cout << "b\n" << u * sigma * v.adjoint() << std::endl; + VERIFY_IS_APPROX(a, u * sigma * v.adjoint()); VERIFY_IS_UNITARY(u); VERIFY_IS_UNITARY(v); diff --git a/test/qr_colpivoting.cpp b/test/qr_colpivoting.cpp index 763c12067..bdf273926 100644 --- a/test/qr_colpivoting.cpp +++ b/test/qr_colpivoting.cpp @@ -28,7 +28,8 @@ template void qr() { - int rows = ei_random(20,200), cols = ei_random(20,200), cols2 = ei_random(20,200); +// int rows = ei_random(20,200), cols = ei_random(20,200), cols2 = ei_random(20,200); + int rows=3, cols=3, cols2=3; int rank = ei_random(1, std::min(rows, cols)-1); typedef typename MatrixType::Scalar Scalar; @@ -55,7 +56,9 @@ template void qr() MatrixType c = MatrixType::Zero(rows,cols); - for(int i = 0; i < cols; ++i) c.col(qr.colsPermutation().coeff(i)) = b.col(i); + for(int i = 0; i < cols; ++i) c.col(qr.colsPermutation().indices().coeff(i)) = b.col(i); + std::cout << "m1:\n" << m1 << std::endl; + std::cout << "c:\n" << c << std::endl; VERIFY_IS_APPROX(m1, c); MatrixType m2 = MatrixType::Random(cols,cols2); @@ -87,7 +90,7 @@ template void qr_fixedsize() Matrix c = MatrixType::Zero(Rows,Cols); - for(int i = 0; i < Cols; ++i) c.col(qr.colsPermutation().coeff(i)) = b.col(i); + for(int i = 0; i < Cols; ++i) c.col(qr.colsPermutation().indices().coeff(i)) = b.col(i); VERIFY_IS_APPROX(m1, c); Matrix m2 = Matrix::Random(Cols,Cols2); -- cgit v1.2.3 From 11fa2ae2c602a9771fadee6f5162e82d5d29cd85 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 18 Nov 2009 16:31:14 -0500 Subject: temporarily disable linear traversal. Actually I don't think it's buggy. But it probably triggers existing bugs, I suspect that some xprs have LinearAccessBit and shouldn't have it. Also this fixes the "bugs" with JacobiSVD ---> now it works again --- Eigen/src/Core/Assign.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Eigen/src/Core/Assign.h b/Eigen/src/Core/Assign.h index 86ba45481..32f9623e8 100644 --- a/Eigen/src/Core/Assign.h +++ b/Eigen/src/Core/Assign.h @@ -73,16 +73,18 @@ public: Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal) : int(MayLinearVectorize) ? int(LinearVectorizedTraversal) : int(MaySliceVectorize) ? int(SliceVectorizedTraversal) - : int(MayLinearize) ? int(LinearTraversal) +// : int(MayLinearize) ? int(LinearTraversal) : int(DefaultTraversal), - Vectorized = int(Traversal) != LinearTraversal && int(Traversal) == DefaultTraversal + Vectorized = int(Traversal) == InnerVectorizedTraversal + || int(Traversal) == LinearVectorizedTraversal + || int(Traversal) == SliceVectorizedTraversal }; private: enum { - UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? 1 : int(PacketSize)), + UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1), MayUnrollCompletely = int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit), - MayUnrollInner = int(InnerSize * OtherDerived::CoeffReadCost) <= int(UnrollingLimit) + MayUnrollInner = int(InnerSize) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit) }; public: @@ -91,7 +93,7 @@ public: ? ( int(MayUnrollCompletely) ? int(CompleteUnrolling) : int(MayUnrollInner) ? int(InnerUnrolling) - : int(NoUnrolling) + : int(NoUnrolling) ) : int(Traversal) == int(LinearVectorizedTraversal) ? ( int(MayUnrollCompletely) && int(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) ) -- cgit v1.2.3 From 40865fa28cab9473959458ec890d68b9df398dc9 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 18 Nov 2009 17:20:39 -0500 Subject: fix bugs, old and new: * old bug: in CwiseBinaryOp: only set the LinearAccessBit if both sides have the same storage order. * new bug: in Assign.h, only consider linear traversal if both sides have the same storage order. --- Eigen/src/Core/Assign.h | 12 +++++++----- Eigen/src/Core/CwiseBinaryOp.h | 11 ++++++++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Eigen/src/Core/Assign.h b/Eigen/src/Core/Assign.h index 32f9623e8..00febdc5d 100644 --- a/Eigen/src/Core/Assign.h +++ b/Eigen/src/Core/Assign.h @@ -28,7 +28,7 @@ #define EIGEN_ASSIGN_H /*************************************************************************** -* Part 1 : the logic deciding a strategy for vectorization and unrolling +* Part 1 : the logic deciding a strategy for traversal and unrolling * ***************************************************************************/ template @@ -53,11 +53,12 @@ private: }; enum { - MightVectorize = (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit) - && ((int(Derived::Flags)&RowMajorBit)==(int(OtherDerived::Flags)&RowMajorBit)), + StorageOrdersAgree = (int(Derived::Flags)&RowMajorBit)==(int(OtherDerived::Flags)&RowMajorBit), + MightVectorize = StorageOrdersAgree + && (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit), MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0 && int(DstIsAligned) && int(SrcIsAligned), - MayLinearize = (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit), + MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit), MayLinearVectorize = MightVectorize && MayLinearize && (DstIsAligned || InnerMaxSize == Dynamic), /* If the destination isn't aligned, we have to do runtime checks and we don't unroll, @@ -73,7 +74,7 @@ public: Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal) : int(MayLinearVectorize) ? int(LinearVectorizedTraversal) : int(MaySliceVectorize) ? int(SliceVectorizedTraversal) -// : int(MayLinearize) ? int(LinearTraversal) + : int(MayLinearize) ? int(LinearTraversal) : int(DefaultTraversal), Vectorized = int(Traversal) == InnerVectorizedTraversal || int(Traversal) == LinearVectorizedTraversal @@ -110,6 +111,7 @@ public: EIGEN_DEBUG_VAR(InnerSize) EIGEN_DEBUG_VAR(InnerMaxSize) EIGEN_DEBUG_VAR(PacketSize) + EIGEN_DEBUG_VAR(StorageOrdersAgree) EIGEN_DEBUG_VAR(MightVectorize) EIGEN_DEBUG_VAR(MayInnerVectorize) EIGEN_DEBUG_VAR(MayLinearVectorize) diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h index 875bc9aa5..4bea0425f 100644 --- a/Eigen/src/Core/CwiseBinaryOp.h +++ b/Eigen/src/Core/CwiseBinaryOp.h @@ -67,11 +67,16 @@ struct ei_traits > ColsAtCompileTime = Lhs::ColsAtCompileTime, MaxRowsAtCompileTime = Lhs::MaxRowsAtCompileTime, MaxColsAtCompileTime = Lhs::MaxColsAtCompileTime, + StorageOrdersAgree = (int(Lhs::Flags)&RowMajorBit)==(int(Rhs::Flags)&RowMajorBit), Flags = (int(LhsFlags) | int(RhsFlags)) & ( HereditaryBits - | (int(LhsFlags) & int(RhsFlags) & (LinearAccessBit | AlignedBit)) - | (ei_functor_traits::PacketAccess && ((int(LhsFlags) & RowMajorBit)==(int(RhsFlags) & RowMajorBit)) - ? (int(LhsFlags) & int(RhsFlags) & PacketAccessBit) : 0)), + | (int(LhsFlags) & int(RhsFlags) & + ( AlignedBit + | (StorageOrdersAgree ? LinearAccessBit : 0) + | (ei_functor_traits::PacketAccess && StorageOrdersAgree ? PacketAccessBit : 0) + ) + ) + ), CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + ei_functor_traits::Cost }; }; -- cgit v1.2.3 From 126a8e6a69fb3bb21e3971fa04d71433bfba8b3d Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 18 Nov 2009 17:40:45 -0500 Subject: fix remaining bug in ColPivHouseholderQR, so now all tests pass again --- Eigen/src/QR/ColPivHouseholderQR.h | 3 ++- test/qr_colpivoting.cpp | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Eigen/src/QR/ColPivHouseholderQR.h b/Eigen/src/QR/ColPivHouseholderQR.h index 4e983684f..e59ecac66 100644 --- a/Eigen/src/QR/ColPivHouseholderQR.h +++ b/Eigen/src/QR/ColPivHouseholderQR.h @@ -366,7 +366,8 @@ struct ei_solve_retval, Rhs> .template triangularView() .solveInPlace(c.corner(TopLeft, dec().rank(), c.cols())); - dst = dec().colsPermutation() * c; + for(int i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i); + for(int i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero(); } }; diff --git a/test/qr_colpivoting.cpp b/test/qr_colpivoting.cpp index bdf273926..600a94133 100644 --- a/test/qr_colpivoting.cpp +++ b/test/qr_colpivoting.cpp @@ -57,8 +57,6 @@ template void qr() MatrixType c = MatrixType::Zero(rows,cols); for(int i = 0; i < cols; ++i) c.col(qr.colsPermutation().indices().coeff(i)) = b.col(i); - std::cout << "m1:\n" << m1 << std::endl; - std::cout << "c:\n" << c << std::endl; VERIFY_IS_APPROX(m1, c); MatrixType m2 = MatrixType::Random(cols,cols2); -- cgit v1.2.3 From abb2a1bb1568bf0ab1b49c20ead8548bbb2b186e Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 18 Nov 2009 17:44:20 -0500 Subject: simplification --- Eigen/src/SVD/JacobiSVD.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Eigen/src/SVD/JacobiSVD.h b/Eigen/src/SVD/JacobiSVD.h index 2f7ebb160..5792c5767 100644 --- a/Eigen/src/SVD/JacobiSVD.h +++ b/Eigen/src/SVD/JacobiSVD.h @@ -294,8 +294,6 @@ JacobiSVD& JacobiSVD::compute(const Ma int rows = matrix.rows(); int cols = matrix.cols(); int diagSize = std::min(rows, cols); - if(ComputeU) m_matrixU = MatrixUType::Zero(rows,rows); - if(ComputeV) m_matrixV = MatrixVType::Zero(cols,cols); m_singularValues.resize(diagSize); const RealScalar precision = 2 * epsilon(); @@ -303,8 +301,8 @@ JacobiSVD& JacobiSVD::compute(const Ma && !ei_svd_precondition_if_more_cols_than_rows::run(matrix, work_matrix, *this)) { work_matrix = matrix.block(0,0,diagSize,diagSize); - if(ComputeU) m_matrixU.diagonal().setOnes(); - if(ComputeV) m_matrixV.diagonal().setOnes(); + if(ComputeU) m_matrixU.setIdentity(rows,rows); + if(ComputeV) m_matrixV.setIdentity(cols,cols); } bool finished = false; -- cgit v1.2.3 From b5f4636d42eb8b8e2383c0fbe357dca8fa1d357e Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Thu, 19 Nov 2009 12:09:04 -0500 Subject: * eigen2->eigen3 * bump version to 2.91.0 * add FindEigen3.cmake --- CMakeLists.txt | 22 +++++------ Eigen/src/Core/util/Macros.h | 4 +- cmake/FindEigen3.cmake | 80 ++++++++++++++++++++++++++++++++++++++++ doc/C01_QuickStartGuide.dox | 2 +- doc/D11_UnalignedArrayAssert.dox | 2 +- doc/Doxyfile.in | 8 ---- doc/I00_CustomizingEigen.dox | 2 +- eigen2.pc.in | 7 ---- eigen3.pc.in | 6 +++ scripts/eigen_gen_credits | 4 +- test/testsuite.cmake | 8 ++-- unsupported/README.txt | 2 +- unsupported/doc/Doxyfile.in | 8 ---- 13 files changed, 109 insertions(+), 46 deletions(-) create mode 100644 cmake/FindEigen3.cmake delete mode 100644 eigen2.pc.in create mode 100644 eigen3.pc.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a23479d7..62d292c02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,14 +7,14 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) endif() # automatically parse the version number -file(READ "${CMAKE_SOURCE_DIR}/Eigen/src/Core/util/Macros.h" _eigen2_version_header) -string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen2_world_version_match "${_eigen2_version_header}") -set(EIGEN2_WORLD_VERSION "${CMAKE_MATCH_1}") -string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen2_major_version_match "${_eigen2_version_header}") -set(EIGEN2_MAJOR_VERSION "${CMAKE_MATCH_1}") -string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen2_minor_version_match "${_eigen2_version_header}") -set(EIGEN2_MINOR_VERSION "${CMAKE_MATCH_1}") -set(EIGEN_VERSION_NUMBER ${EIGEN2_WORLD_VERSION}.${EIGEN2_MAJOR_VERSION}.${EIGEN2_MINOR_VERSION}) +file(READ "${CMAKE_SOURCE_DIR}/Eigen/src/Core/util/Macros.h" _eigen_version_header) +string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen_world_version_match "${_eigen_version_header}") +set(EIGEN_WORLD_VERSION "${CMAKE_MATCH_1}") +string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen_major_version_match "${_eigen_version_header}") +set(EIGEN_MAJOR_VERSION "${CMAKE_MATCH_1}") +string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen_minor_version_match "${_eigen_version_header}") +set(EIGEN_MINOR_VERSION "${CMAKE_MATCH_1}") +set(EIGEN_VERSION_NUMBER ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION}) # if the mercurial program is absent, this will leave the EIGEN_HG_CHANGESET string empty, # but won't stop CMake. @@ -117,14 +117,14 @@ option(EIGEN_TEST_RVALUE_REF_SUPPORT "Enable rvalue references for unit tests." include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) set(INCLUDE_INSTALL_DIR - "${CMAKE_INSTALL_PREFIX}/include/eigen2" + "${CMAKE_INSTALL_PREFIX}/include/eigen3" CACHE PATH "The directory where we install the header files" ) if(EIGEN_BUILD_PKGCONFIG) - configure_file(eigen2.pc.in eigen2.pc) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eigen2.pc + configure_file(eigen3.pc.in eigen3.pc) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eigen3.pc DESTINATION share/pkgconfig ) endif(EIGEN_BUILD_PKGCONFIG) diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h index a94300de3..a51b46f02 100644 --- a/Eigen/src/Core/util/Macros.h +++ b/Eigen/src/Core/util/Macros.h @@ -29,8 +29,8 @@ #undef minor #define EIGEN_WORLD_VERSION 2 -#define EIGEN_MAJOR_VERSION 90 -#define EIGEN_MINOR_VERSION 1 +#define EIGEN_MAJOR_VERSION 91 +#define EIGEN_MINOR_VERSION 0 #define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \ (EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \ diff --git a/cmake/FindEigen3.cmake b/cmake/FindEigen3.cmake new file mode 100644 index 000000000..610df8023 --- /dev/null +++ b/cmake/FindEigen3.cmake @@ -0,0 +1,80 @@ +# - Try to find Eigen3 lib +# +# This module supports requiring a minimum version, e.g. you can do +# find_package(Eigen3 3.1.2) +# to require version 3.1.2 or newer of Eigen3. +# +# Once done this will define +# +# EIGEN3_FOUND - system has eigen lib with correct version +# EIGEN3_INCLUDE_DIR - the eigen include directory +# EIGEN3_VERSION - eigen version + +# Copyright (c) 2006, 2007 Montel Laurent, +# Copyright (c) 2008, 2009 Gael Guennebaud, +# Redistribution and use is allowed according to the terms of the BSD license. + +if(NOT Eigen3_FIND_VERSION) + if(NOT Eigen3_FIND_VERSION_MAJOR) + set(Eigen3_FIND_VERSION_MAJOR 2) + endif(NOT Eigen3_FIND_VERSION_MAJOR) + if(NOT Eigen3_FIND_VERSION_MINOR) + set(Eigen3_FIND_VERSION_MINOR 91) + endif(NOT Eigen3_FIND_VERSION_MINOR) + if(NOT Eigen3_FIND_VERSION_PATCH) + set(Eigen3_FIND_VERSION_PATCH 0) + endif(NOT Eigen3_FIND_VERSION_PATCH) + + set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}") +endif(NOT Eigen3_FIND_VERSION) + +macro(_eigen3_check_version) + file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header LIMIT 5000 OFFSET 1000) + + string(REGEX MATCH "define *EIGEN_WORLD_VERSION ([0-9]*)" _eigen3_world_version_match "${_eigen3_version_header}") + set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define *EIGEN_MAJOR_VERSION ([0-9]*)" _eigen3_major_version_match "${_eigen3_version_header}") + set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define *EIGEN_MINOR_VERSION ([0-9]*)" _eigen3_minor_version_match "${_eigen3_version_header}") + set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}") + + set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION}) + if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + set(EIGEN3_VERSION_OK FALSE) + else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + set(EIGEN3_VERSION_OK TRUE) + endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + + if(NOT EIGEN3_VERSION_OK) + + message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, " + "but at least version ${Eigen3_FIND_VERSION} is required") + endif(NOT EIGEN3_VERSION_OK) +endmacro(_eigen3_check_version) + +if (EIGEN3_INCLUDE_DIR) + + # in cache already + _eigen3_check_version() + set(EIGEN3_FOUND ${EIGEN3_VERSION_OK}) + +else (EIGEN3_INCLUDE_DIR) + + find_path(EIGEN3_INCLUDE_DIR NAMES Eigen/Core + PATHS + ${INCLUDE_INSTALL_DIR} + ${KDE4_INCLUDE_DIR} + PATH_SUFFIXES eigen3 + ) + + if(EIGEN3_INCLUDE_DIR) + _eigen3_check_version() + endif(EIGEN3_INCLUDE_DIR) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK) + + mark_as_advanced(EIGEN3_INCLUDE_DIR) + +endif(EIGEN3_INCLUDE_DIR) + diff --git a/doc/C01_QuickStartGuide.dox b/doc/C01_QuickStartGuide.dox index 06b2595e7..0c545f735 100644 --- a/doc/C01_QuickStartGuide.dox +++ b/doc/C01_QuickStartGuide.dox @@ -36,7 +36,7 @@ In order to use Eigen, you just need to download and extract Eigen's source code Here are some quick compilation instructions with GCC. To quickly test an example program, just do -\code g++ -I /path/to/eigen2/ my_program.cpp -o my_program \endcode +\code g++ -I /path/to/eigen/ my_program.cpp -o my_program \endcode There is no library to link to. For good performance, add the \c -O2 compile-flag. Note however that this makes it impossible to debug inside Eigen code, as many functions get inlined. In some cases, performance can be further improved by disabling Eigen assertions: use \c -DEIGEN_NO_DEBUG or \c -DNDEBUG to disable them. diff --git a/doc/D11_UnalignedArrayAssert.dox b/doc/D11_UnalignedArrayAssert.dox index 226b20452..f4da15236 100644 --- a/doc/D11_UnalignedArrayAssert.dox +++ b/doc/D11_UnalignedArrayAssert.dox @@ -4,7 +4,7 @@ namespace Eigen { Hello! You are seeing this webpage because your program terminated on an assertion failure like this one:
-my_program: path/to/eigen2/Eigen/src/Core/MatrixStorage.h:44:
+my_program: path/to/eigen/Eigen/src/Core/MatrixStorage.h:44:
 Eigen::ei_matrix_array::ei_matrix_array()
 [with T = double, int Size = 2, int MatrixOptions = 2, bool Align = true]:
 Assertion `(reinterpret_cast(array) & 0xf) == 0 && "this assertion
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index 82ebf6aa0..7f5b26a61 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -1,11 +1,3 @@
-################################################################################
-##                                                                            ##
-##                                  WARNING                                   ##
-##                                                                            ##
-##  all modifications in this file must be reported in eigen2/Mainpage.dox    ##
-##                                                                            ##
-################################################################################
-
 # This file describes the settings to be used by the documentation system
 # doxygen (www.doxygen.org) for a project
 #
diff --git a/doc/I00_CustomizingEigen.dox b/doc/I00_CustomizingEigen.dox
index 7c8ba9b75..ede6f23b7 100644
--- a/doc/I00_CustomizingEigen.dox
+++ b/doc/I00_CustomizingEigen.dox
@@ -2,7 +2,7 @@ namespace Eigen {
 
 /** \page CustomizingEigen Advanced - Customizing/Extending Eigen
 
-Eigen2 can be extended in several ways, for instance, by defining global methods, \ref ExtendingMatrixBase "by adding custom methods to MatrixBase", adding support to \ref CustomScalarType "custom types" etc.
+Eigen can be extended in several ways, for instance, by defining global methods, \ref ExtendingMatrixBase "by adding custom methods to MatrixBase", adding support to \ref CustomScalarType "custom types" etc.
 
 \b Table \b of \b contents
   - \ref ExtendingMatrixBase
diff --git a/eigen2.pc.in b/eigen2.pc.in
deleted file mode 100644
index b508a58d3..000000000
--- a/eigen2.pc.in
+++ /dev/null
@@ -1,7 +0,0 @@
-
-Name: Eigen2
-Description: A C++ template library for linear algebra: vectors, matrices, and related algorithms
-Requires:
-Version: ${EIGEN_VERSION_NUMBER}
-Libs:
-Cflags: -I${INCLUDE_INSTALL_DIR}
diff --git a/eigen3.pc.in b/eigen3.pc.in
new file mode 100644
index 000000000..c5855de33
--- /dev/null
+++ b/eigen3.pc.in
@@ -0,0 +1,6 @@
+Name: Eigen3
+Description: A C++ template library for linear algebra: vectors, matrices, and related algorithms
+Requires:
+Version: ${EIGEN_VERSION_NUMBER}
+Libs:
+Cflags: -I${INCLUDE_INSTALL_DIR}
diff --git a/scripts/eigen_gen_credits b/scripts/eigen_gen_credits
index c67416784..83ca8da12 100755
--- a/scripts/eigen_gen_credits
+++ b/scripts/eigen_gen_credits
@@ -1,10 +1,10 @@
 #!/bin/sh
 
-# this script must be run from the eigen2/ directory.
+# this script must be run from the eigen/ directory.
 # when running hg churn from the scripts/ subdir, i hit a divide-by-zero error.
 #
 # like this:
-#   cd eigen2
+#   cd eigen
 #   USER=yourtuxfamilyuser scripts/eigen_gen_credits
 
 rm -f eigen_gen_credits.log
diff --git a/test/testsuite.cmake b/test/testsuite.cmake
index 9c38e48b1..90edf2853 100644
--- a/test/testsuite.cmake
+++ b/test/testsuite.cmake
@@ -4,7 +4,7 @@
 # Usage:
 #  - create a new folder, let's call it cdash
 #  - in that folder, do:
-#    ctest -S path/to/eigen2/test/testsuite.cmake[,option1=value1[,option2=value2]]
+#    ctest -S path/to/eigen/test/testsuite.cmake[,option1=value1[,option2=value2]]
 #
 # Options:
 #  - EIGEN_CXX: compiler, eg.: g++-4.2
@@ -44,9 +44,9 @@
 # ARCH=`uname -m`
 # SITE=`hostname`
 # VERSION=opensuse-11.1
-# WORK_DIR=/home/gael/Coding/eigen2/cdash
+# WORK_DIR=/home/gael/Coding/eigen/cdash
 # # get the last version of the script
-# wget http://bitbucket.org/eigen/eigen2/raw/tip/test/testsuite.cmake -o $WORK_DIR/testsuite.cmake
+# wget http://bitbucket.org/eigen/eigen/raw/tip/test/testsuite.cmake -o $WORK_DIR/testsuite.cmake
 # COMMON="ctest -S $WORK_DIR/testsuite.cmake,EIGEN_WORK_DIR=$WORK_DIR,EIGEN_SITE=$SITE,EIGEN_MODE=$1,EIGEN_BUILD_STRING=$OS_VERSION-$ARCH"
 # $COMMON-gcc-3.4.6,EIGEN_CXX=g++-3.4
 # $COMMON-gcc-4.0.1,EIGEN_CXX=g++-4.0.1
@@ -141,7 +141,7 @@ endif(NOT EIGEN_MODE)
 
 if(NOT EIGEN_NO_UPDATE)
   SET (CTEST_CVS_COMMAND "hg")
-  SET (CTEST_CVS_CHECKOUT "${CTEST_CVS_COMMAND} clone http://bitbucket.org/eigen/eigen2 \"${CTEST_SOURCE_DIRECTORY}\"")
+  SET (CTEST_CVS_CHECKOUT "${CTEST_CVS_COMMAND} clone http://bitbucket.org/eigen/eigen \"${CTEST_SOURCE_DIRECTORY}\"")
   SET(CTEST_BACKUP_AND_RESTORE TRUE) # the backup is CVS related ...
 endif(NOT EIGEN_NO_UPDATE)
 
diff --git a/unsupported/README.txt b/unsupported/README.txt
index ed1341426..83479ff0b 100644
--- a/unsupported/README.txt
+++ b/unsupported/README.txt
@@ -4,7 +4,7 @@ most of them are subject to be included in Eigen in the future.
 
 In order to use an unsupported module you have to do either:
 
- - add the path_to_eigen2/unsupported directory to your include path and do:
+ - add the path_to_eigen/unsupported directory to your include path and do:
    #include 
 
  - or directly do:
diff --git a/unsupported/doc/Doxyfile.in b/unsupported/doc/Doxyfile.in
index 269595820..a9c7d6004 100644
--- a/unsupported/doc/Doxyfile.in
+++ b/unsupported/doc/Doxyfile.in
@@ -1,11 +1,3 @@
-################################################################################
-##                                                                            ##
-##                                  WARNING                                   ##
-##                                                                            ##
-##  all modifications in this file must be reported in eigen2/Mainpage.dox    ##
-##                                                                            ##
-################################################################################
-
 # This file describes the settings to be used by the documentation system
 # doxygen (www.doxygen.org) for a project
 #
-- 
cgit v1.2.3


From bbf0eb35a769b3b644ac62d65601f7b3044baacd Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Thu, 19 Nov 2009 12:31:11 -0500
Subject: * in Eigen/CMakeLists.txt, finally do a globbing to we no longer will
 have problems with "oops forgot to install new module". * add a file
 Eigen/signature_of_eigen3_matrix_library, use it to make FindEigen3.cmake
 more solid: able to find Eigen in either eigen3/ or eigen/ and not mix it up
 with Eigen2.

---
 Eigen/CMakeLists.txt                     | 9 +++++++--
 Eigen/signature_of_eigen3_matrix_library | 1 +
 cmake/FindEigen3.cmake                   | 6 +++---
 3 files changed, 11 insertions(+), 5 deletions(-)
 create mode 100644 Eigen/signature_of_eigen3_matrix_library

diff --git a/Eigen/CMakeLists.txt b/Eigen/CMakeLists.txt
index e0eb837a5..321b2978e 100644
--- a/Eigen/CMakeLists.txt
+++ b/Eigen/CMakeLists.txt
@@ -1,7 +1,12 @@
-set(Eigen_HEADERS Core LU Cholesky QR Geometry Sparse Array SVD LeastSquares QtAlignedMalloc StdVector Householder Jacobi Eigenvalues)
+file(GLOB Eigen_directory_files "*")
+foreach(f ${Eigen_directory_files})
+  if(NOT(f MATCHES ".txt") AND NOT (f MATCHES "src"))
+    list(APPEND Eigen_directory_files_to_install ${f})
+  endif()
+endforeach(f ${Eigen_directory_files})
 
 install(FILES
-  ${Eigen_HEADERS}
+  ${Eigen_directory_files_to_install}
   DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen COMPONENT Devel
   )
 
diff --git a/Eigen/signature_of_eigen3_matrix_library b/Eigen/signature_of_eigen3_matrix_library
new file mode 100644
index 000000000..477732ef4
--- /dev/null
+++ b/Eigen/signature_of_eigen3_matrix_library
@@ -0,0 +1 @@
+This file is just there as a signature to help identify directories containing Eigen3. When writing for a script looking for Eigen3, just look for this file. This is especially useful to help disambiguate with Eigen2...
diff --git a/cmake/FindEigen3.cmake b/cmake/FindEigen3.cmake
index 610df8023..1d7dbb43d 100644
--- a/cmake/FindEigen3.cmake
+++ b/cmake/FindEigen3.cmake
@@ -60,11 +60,11 @@ if (EIGEN3_INCLUDE_DIR)
 
 else (EIGEN3_INCLUDE_DIR)
 
-  find_path(EIGEN3_INCLUDE_DIR NAMES Eigen/Core
+  find_path(EIGEN3_INCLUDE_DIR NAMES Eigen/signature_of_eigen3_matrix_library
       PATHS
-      ${INCLUDE_INSTALL_DIR}
+      ${CMAKE_INSTALL_PREFIX}/include
       ${KDE4_INCLUDE_DIR}
-      PATH_SUFFIXES eigen3
+      PATH_SUFFIXES eigen3 eigen
     )
 
   if(EIGEN3_INCLUDE_DIR)
-- 
cgit v1.2.3


From 2275f98d7bd90c12a4bd324ada21a15ec0ffec69 Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Thu, 19 Nov 2009 12:41:28 -0500
Subject: move signature file to root directory, where it belongs

---
 CMakeLists.txt                           | 5 +++++
 Eigen/signature_of_eigen3_matrix_library | 1 -
 cmake/FindEigen3.cmake                   | 2 +-
 signature_of_eigen3_matrix_library       | 1 +
 4 files changed, 7 insertions(+), 2 deletions(-)
 delete mode 100644 Eigen/signature_of_eigen3_matrix_library
 create mode 100644 signature_of_eigen3_matrix_library

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 62d292c02..8932fff2a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -122,6 +122,11 @@ set(INCLUDE_INSTALL_DIR
     "The directory where we install the header files"
 )
 
+install(FILES
+  signature_of_eigen3_matrix_library
+  DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel
+  )
+
 if(EIGEN_BUILD_PKGCONFIG)
     configure_file(eigen3.pc.in eigen3.pc)
     install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eigen3.pc
diff --git a/Eigen/signature_of_eigen3_matrix_library b/Eigen/signature_of_eigen3_matrix_library
deleted file mode 100644
index 477732ef4..000000000
--- a/Eigen/signature_of_eigen3_matrix_library
+++ /dev/null
@@ -1 +0,0 @@
-This file is just there as a signature to help identify directories containing Eigen3. When writing for a script looking for Eigen3, just look for this file. This is especially useful to help disambiguate with Eigen2...
diff --git a/cmake/FindEigen3.cmake b/cmake/FindEigen3.cmake
index 1d7dbb43d..2c4bb0462 100644
--- a/cmake/FindEigen3.cmake
+++ b/cmake/FindEigen3.cmake
@@ -60,7 +60,7 @@ if (EIGEN3_INCLUDE_DIR)
 
 else (EIGEN3_INCLUDE_DIR)
 
-  find_path(EIGEN3_INCLUDE_DIR NAMES Eigen/signature_of_eigen3_matrix_library
+  find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library
       PATHS
       ${CMAKE_INSTALL_PREFIX}/include
       ${KDE4_INCLUDE_DIR}
diff --git a/signature_of_eigen3_matrix_library b/signature_of_eigen3_matrix_library
new file mode 100644
index 000000000..477732ef4
--- /dev/null
+++ b/signature_of_eigen3_matrix_library
@@ -0,0 +1 @@
+This file is just there as a signature to help identify directories containing Eigen3. When writing for a script looking for Eigen3, just look for this file. This is especially useful to help disambiguate with Eigen2...
-- 
cgit v1.2.3


From a20a744adc5414f9a79ae0637de9c3227c3dd420 Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Thu, 19 Nov 2009 17:07:55 -0500
Subject: TriangularMatrix: extend to rectangular matrices

---
 Eigen/src/Core/TriangularMatrix.h |  93 ++++++++++---------
 test/triangular.cpp               | 183 +++++++++++++++++++++++++++++---------
 2 files changed, 193 insertions(+), 83 deletions(-)

diff --git a/Eigen/src/Core/TriangularMatrix.h b/Eigen/src/Core/TriangularMatrix.h
index e60d57e70..ed26683ea 100644
--- a/Eigen/src/Core/TriangularMatrix.h
+++ b/Eigen/src/Core/TriangularMatrix.h
@@ -26,22 +26,11 @@
 #ifndef EIGEN_TRIANGULARMATRIX_H
 #define EIGEN_TRIANGULARMATRIX_H
 
-/** \nonstableyet
-  * \class TriangularBase
-  *
-  * \brief Expression of a triangular matrix extracted from a given matrix
-  *
-  * \param MatrixType the type of the object in which we are taking the triangular part
-  * \param Mode the kind of triangular matrix expression to construct. Can be UpperTriangular,
-  *             LowerTriangular, UpperSelfadjoint, or LowerSelfadjoint. This is in fact a bit field;
-  *             it must have either UpperBit or LowerBit, and additionnaly it may have either
-  *             TraingularBit or SelfadjointBit.
+/** \internal
   *
-  * This class represents an expression of the upper or lower triangular part of
-  * a square matrix, possibly with a further assumption on the diagonal. It is the return type
-  * of MatrixBase::part() and most of the time this is the only way it is used.
+  * \class TriangularBase
   *
-  * \sa MatrixBase::part()
+  * \brief Base class for triangular part in a matrix
   */
 template class TriangularBase : public AnyMatrixBase
 {
@@ -115,19 +104,21 @@ template class TriangularBase : public AnyMatrixBase
 
 };
 
-
 /** \class TriangularView
-  * \nonstableyet
   *
-  * \brief Expression of a triangular part of a dense matrix
+  * \brief Base class for triangular part in a matrix
   *
-  * \param MatrixType the type of the dense matrix storing the coefficients
+  * \param MatrixType the type of the object in which we are taking the triangular part
+  * \param Mode the kind of triangular matrix expression to construct. Can be UpperTriangular,
+  *             LowerTriangular, UpperSelfadjoint, or LowerSelfadjoint. This is in fact a bit field;
+  *             it must have either UpperBit or LowerBit, and additionnaly it may have either
+  *             TraingularBit or SelfadjointBit.
   *
-  * This class is an expression of a triangular part of a matrix with given dense
-  * storage of the coefficients. It is the return type of MatrixBase::triangularPart()
-  * and most of the time this is the only way that it is used.
+  * This class represents a triangular part of a matrix, not necessarily square. Strictly speaking, for rectangular
+  * matrices one should speak ok "trapezoid" parts. This class is the return type
+  * of MatrixBase::triangularView() and most of the time this is the only way it is used.
   *
-  * \sa class TriangularBase, MatrixBase::triangularPart(), class DiagonalWrapper
+  * \sa MatrixBase::triangularView()
   */
 template
 struct ei_traits > : ei_traits
@@ -155,7 +146,7 @@ template class TriangularView
     typedef TriangularBase Base;
     typedef typename ei_traits::Scalar Scalar;
     typedef _MatrixType MatrixType;
-    typedef typename MatrixType::PlainMatrixType PlainMatrixType;
+    typedef typename MatrixType::PlainMatrixType DenseMatrixType;
     typedef typename MatrixType::Nested MatrixTypeNested;
     typedef typename ei_cleantype::type _MatrixTypeNested;
 
@@ -244,9 +235,9 @@ template class TriangularView
     inline const TriangularView >,TransposeMode> transpose() const
     { return m_matrix.transpose().nestByValue(); }
 
-    PlainMatrixType toDense() const
+    DenseMatrixType toDenseMatrix() const
     {
-      PlainMatrixType res(rows(), cols());
+      DenseMatrixType res(rows(), cols());
       res = *this;
       return res;
     }
@@ -351,6 +342,7 @@ struct ei_triangular_assignment_selector
     }
   }
 };
+
 template
 struct ei_triangular_assignment_selector
 {
@@ -365,6 +357,7 @@ struct ei_triangular_assignment_selector
 struct ei_triangular_assignment_selector
@@ -379,14 +372,16 @@ struct ei_triangular_assignment_selector
 struct ei_triangular_assignment_selector
 {
@@ -396,8 +391,9 @@ struct ei_triangular_assignment_selector
 struct ei_triangular_assignment_selector
 {
@@ -427,8 +425,9 @@ struct ei_triangular_assignment_selector::operator=(const TriangularBase&
   ei_assert(Mode == OtherDerived::Mode);
   if(ei_traits::Flags & EvalBeforeAssigningBit)
   {
-    typename OtherDerived::PlainMatrixType other_evaluated(other.rows(), other.cols());
+    typename OtherDerived::DenseMatrixType other_evaluated(other.rows(), other.cols());
     other_evaluated.template triangularView().lazyAssign(other.derived());
     lazyAssign(other_evaluated);
   }
@@ -633,17 +634,20 @@ const TriangularView MatrixBase::triangularView() const
 template
 bool MatrixBase::isUpperTriangular(RealScalar prec) const
 {
-  if(cols() != rows()) return false;
   RealScalar maxAbsOnUpperTriangularPart = static_cast(-1);
   for(int j = 0; j < cols(); ++j)
-    for(int i = 0; i <= j; ++i)
+  {
+    int maxi = std::min(j, rows()-1);
+    for(int i = 0; i <= maxi; ++i)
     {
       RealScalar absValue = ei_abs(coeff(i,j));
       if(absValue > maxAbsOnUpperTriangularPart) maxAbsOnUpperTriangularPart = absValue;
     }
-  for(int j = 0; j < cols()-1; ++j)
+  }
+  RealScalar threshold = maxAbsOnUpperTriangularPart * prec;
+  for(int j = 0; j < cols(); ++j)
     for(int i = j+1; i < rows(); ++i)
-      if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnUpperTriangularPart, prec)) return false;
+      if(ei_abs(coeff(i, j)) > threshold) return false;
   return true;
 }
 
@@ -655,7 +659,6 @@ bool MatrixBase::isUpperTriangular(RealScalar prec) const
 template
 bool MatrixBase::isLowerTriangular(RealScalar prec) const
 {
-  if(cols() != rows()) return false;
   RealScalar maxAbsOnLowerTriangularPart = static_cast(-1);
   for(int j = 0; j < cols(); ++j)
     for(int i = j; i < rows(); ++i)
@@ -663,9 +666,13 @@ bool MatrixBase::isLowerTriangular(RealScalar prec) const
       RealScalar absValue = ei_abs(coeff(i,j));
       if(absValue > maxAbsOnLowerTriangularPart) maxAbsOnLowerTriangularPart = absValue;
     }
+  RealScalar threshold = maxAbsOnLowerTriangularPart * prec;
   for(int j = 1; j < cols(); ++j)
-    for(int i = 0; i < j; ++i)
-      if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnLowerTriangularPart, prec)) return false;
+  {
+    int maxi = std::min(j, rows()-1);
+    for(int i = 0; i < maxi; ++i)
+      if(ei_abs(coeff(i, j)) > threshold) return false;
+  }
   return true;
 }
 
diff --git a/test/triangular.cpp b/test/triangular.cpp
index ee02c0022..3c89a8abb 100644
--- a/test/triangular.cpp
+++ b/test/triangular.cpp
@@ -24,7 +24,9 @@
 
 #include "main.h"
 
-template void triangular(const MatrixType& m)
+
+
+template void triangular_square(const MatrixType& m)
 {
   typedef typename MatrixType::Scalar Scalar;
   typedef typename NumTraits::Real RealScalar;
@@ -51,8 +53,8 @@ template void triangular(const MatrixType& m)
              v2 = VectorType::Random(rows),
              vzero = VectorType::Zero(rows);
 
-  MatrixType m1up = m1.template triangularView();
-  MatrixType m2up = m2.template triangularView();
+  MatrixType m1up = m1.template triangularView();
+  MatrixType m2up = m2.template triangularView();
 
   if (rows*cols>1)
   {
@@ -66,20 +68,20 @@ template void triangular(const MatrixType& m)
   // test overloaded operator+=
   r1.setZero();
   r2.setZero();
-  r1.template triangularView() +=  m1;
+  r1.template triangularView() +=  m1;
   r2 += m1up;
   VERIFY_IS_APPROX(r1,r2);
 
   // test overloaded operator=
   m1.setZero();
-  m1.template triangularView() = m2.transpose() + m2;
+  m1.template triangularView() = m2.transpose() + m2;
   m3 = m2.transpose() + m2;
-  VERIFY_IS_APPROX(m3.template triangularView().transpose().toDense(), m1);
+  VERIFY_IS_APPROX(m3.template triangularView().transpose().toDenseMatrix(), m1);
 
   // test overloaded operator=
   m1.setZero();
-  m1.template triangularView() = m2.transpose() + m2;
-  VERIFY_IS_APPROX(m3.template triangularView().toDense(), m1);
+  m1.template triangularView() = m2.transpose() + m2;
+  VERIFY_IS_APPROX(m3.template triangularView().toDenseMatrix(), m1);
 
   m1 = MatrixType::Random(rows, cols);
   for (int i=0; i void triangular(const MatrixType& m)
 
   Transpose trm4(m4);
   // test back and forward subsitution with a vector as the rhs
-  m3 = m1.template triangularView();
-  VERIFY(v2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView().solve(v2)), largerEps));
-  m3 = m1.template triangularView();
-  VERIFY(v2.isApprox(m3.transpose() * (m1.transpose().template triangularView().solve(v2)), largerEps));
-  m3 = m1.template triangularView();
-  VERIFY(v2.isApprox(m3 * (m1.template triangularView().solve(v2)), largerEps));
-  m3 = m1.template triangularView();
-  VERIFY(v2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView().solve(v2)), largerEps));
+  m3 = m1.template triangularView();
+  VERIFY(v2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView().solve(v2)), largerEps));
+  m3 = m1.template triangularView();
+  VERIFY(v2.isApprox(m3.transpose() * (m1.transpose().template triangularView().solve(v2)), largerEps));
+  m3 = m1.template triangularView();
+  VERIFY(v2.isApprox(m3 * (m1.template triangularView().solve(v2)), largerEps));
+  m3 = m1.template triangularView();
+  VERIFY(v2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView().solve(v2)), largerEps));
 
   // test back and forward subsitution with a matrix as the rhs
-  m3 = m1.template triangularView();
-  VERIFY(m2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView().solve(m2)), largerEps));
-  m3 = m1.template triangularView();
-  VERIFY(m2.isApprox(m3.transpose() * (m1.transpose().template triangularView().solve(m2)), largerEps));
-  m3 = m1.template triangularView();
-  VERIFY(m2.isApprox(m3 * (m1.template triangularView().solve(m2)), largerEps));
-  m3 = m1.template triangularView();
-  VERIFY(m2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView().solve(m2)), largerEps));
+  m3 = m1.template triangularView();
+  VERIFY(m2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView().solve(m2)), largerEps));
+  m3 = m1.template triangularView();
+  VERIFY(m2.isApprox(m3.transpose() * (m1.transpose().template triangularView().solve(m2)), largerEps));
+  m3 = m1.template triangularView();
+  VERIFY(m2.isApprox(m3 * (m1.template triangularView().solve(m2)), largerEps));
+  m3 = m1.template triangularView();
+  VERIFY(m2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView().solve(m2)), largerEps));
 
   // check M * inv(L) using in place API
   m4 = m3;
-  m3.transpose().template triangularView().solveInPlace(trm4);
+  m3.transpose().template triangularView().solveInPlace(trm4);
   VERIFY(m4.cwise().abs().isIdentity(test_precision()));
 
   // check M * inv(U) using in place API
-  m3 = m1.template triangularView();
+  m3 = m1.template triangularView();
   m4 = m3;
-  m3.transpose().template triangularView().solveInPlace(trm4);
+  m3.transpose().template triangularView().solveInPlace(trm4);
   VERIFY(m4.cwise().abs().isIdentity(test_precision()));
 
   // check solve with unit diagonal
-  m3 = m1.template triangularView();
-  VERIFY(m2.isApprox(m3 * (m1.template triangularView().solve(m2)), largerEps));
+  m3 = m1.template triangularView();
+  VERIFY(m2.isApprox(m3 * (m1.template triangularView().solve(m2)), largerEps));
+
+//   VERIFY((  m1.template triangularView()
+//           * m2.template triangularView()).isUpperTriangular());
+
+  // test swap
+  m1.setOnes();
+  m2.setZero();
+  m2.template triangularView().swap(m1);
+  m3.setZero();
+  m3.template triangularView().setOnes();
+  VERIFY_IS_APPROX(m2,m3);
+
+}
+
+
+template void triangular_rect(const MatrixType& m)
+{
+  typedef typename MatrixType::Scalar Scalar;
+  typedef typename NumTraits::Real RealScalar;
+  typedef Matrix VectorType;
+
+  int rows = m.rows();
+  int cols = m.cols();
+
+  MatrixType m1 = MatrixType::Random(rows, cols),
+             m2 = MatrixType::Random(rows, cols),
+             m3(rows, cols),
+             m4(rows, cols),
+             r1(rows, cols),
+             r2(rows, cols),
+             mzero = MatrixType::Zero(rows, cols),
+             mones = MatrixType::Ones(rows, cols),
+             identity = Matrix
+                              ::Identity(rows, rows),
+             square = Matrix
+                              ::Random(rows, rows);
+  VectorType v1 = VectorType::Random(rows),
+             v2 = VectorType::Random(rows),
+             vzero = VectorType::Zero(rows);
+
+  MatrixType m1up = m1.template triangularView();
+  MatrixType m2up = m2.template triangularView();
+
+  if (rows*cols>1)
+  {
+    VERIFY(m1up.isUpperTriangular());
+    VERIFY(m2up.transpose().isLowerTriangular());
+    VERIFY(!m2.isLowerTriangular());
+  }
+
+//   VERIFY_IS_APPROX(m1up.transpose() * m2, m1.upper().transpose().lower() * m2);
 
-//   VERIFY((  m1.template triangularView()
-//           * m2.template triangularView()).isUpperTriangular());
+  // test overloaded operator+=
+  r1.setZero();
+  r2.setZero();
+  r1.template triangularView() +=  m1;
+  r2 += m1up;
+  VERIFY_IS_APPROX(r1,r2);
 
+  // test overloaded operator=
+  m1.setZero();
+  m1.template triangularView() = 3 * m2;
+  m3 = 3 * m2;
+  VERIFY_IS_APPROX(m3.template triangularView().toDenseMatrix(), m1);
+
+  m1.setZero();
+  m1.template triangularView() = 3 * m2;
+  VERIFY_IS_APPROX(m3.template triangularView().toDenseMatrix(), m1);
+
+  m1.setZero();
+  m1.template triangularView() = 3 * m2;
+  VERIFY_IS_APPROX(m3.template triangularView().toDenseMatrix(), m1);
+
+  m1.setZero();
+  m1.template triangularView() = 3 * m2;
+  VERIFY_IS_APPROX(m3.template triangularView().toDenseMatrix(), m1);
+
+  m1.setRandom();
+  m2 = m1.template triangularView();
+  VERIFY(m2.isUpperTriangular());
+  VERIFY(!m2.isLowerTriangular());
+  m2 = m1.template triangularView();
+  VERIFY(m2.isUpperTriangular());
+  VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
+  m2 = m1.template triangularView();
+  VERIFY(m2.isUpperTriangular());
+  m2.diagonal().cwise() -= Scalar(1);
+  VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
+  m2 = m1.template triangularView();
+  VERIFY(m2.isLowerTriangular());
+  VERIFY(!m2.isUpperTriangular());
+  m2 = m1.template triangularView();
+  VERIFY(m2.isLowerTriangular());
+  VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
+  m2 = m1.template triangularView();
+  VERIFY(m2.isLowerTriangular());
+  m2.diagonal().cwise() -= Scalar(1);
+  VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));
   // test swap
   m1.setOnes();
   m2.setZero();
-  m2.template triangularView().swap(m1);
+  m2.template triangularView().swap(m1);
   m3.setZero();
-  m3.template triangularView().setOnes();
+  m3.template triangularView().setOnes();
   VERIFY_IS_APPROX(m2,m3);
 
 }
@@ -137,12 +233,19 @@ template void triangular(const MatrixType& m)
 void test_triangular()
 {
   for(int i = 0; i < g_repeat ; i++) {
-    CALL_SUBTEST_1( triangular(Matrix()) );
-    CALL_SUBTEST_2( triangular(Matrix()) );
-    CALL_SUBTEST_3( triangular(Matrix3d()) );
-    CALL_SUBTEST_4( triangular(MatrixXcf(4, 4)) );
-    CALL_SUBTEST_5( triangular(Matrix,8, 8>()) );
-    CALL_SUBTEST_6( triangular(MatrixXcd(17,17)) );
-    CALL_SUBTEST_7( triangular(Matrix(5, 5)) );
+    CALL_SUBTEST_1( triangular_square(Matrix()) );
+    CALL_SUBTEST_2( triangular_square(Matrix()) );
+    CALL_SUBTEST_3( triangular_square(Matrix3d()) );
+    CALL_SUBTEST_4( triangular_square(MatrixXcf(4, 4)) );
+    CALL_SUBTEST_5( triangular_square(Matrix,8, 8>()) );
+    CALL_SUBTEST_6( triangular_square(MatrixXcd(17,17)) );
+    CALL_SUBTEST_7( triangular_square(Matrix(5, 5)) );
+
+    CALL_SUBTEST_8( triangular_rect(Matrix()) );
+    CALL_SUBTEST_9( triangular_rect(Matrix()) );
+    CALL_SUBTEST_4( triangular_rect(MatrixXcf(4, 10)) );
+    CALL_SUBTEST_6( triangular_rect(MatrixXcd(11, 3)) );
+    CALL_SUBTEST_7( triangular_rect(Matrix(7, 6)) );
+
   }
 }
-- 
cgit v1.2.3


From 88b551e89bd34367c12f0ba540ee1134c6897ba1 Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Thu, 19 Nov 2009 19:20:19 -0500
Subject: * fix compilation of unit-tests (sorry, had tested only 1 channel) *
 remove buggy (superfluous?) specialization in the meta-unroller

---
 Eigen/src/Core/TriangularMatrix.h | 15 ---------------
 test/triangular.cpp               | 28 +++++++++++++++++-----------
 2 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/Eigen/src/Core/TriangularMatrix.h b/Eigen/src/Core/TriangularMatrix.h
index ed26683ea..34b029421 100644
--- a/Eigen/src/Core/TriangularMatrix.h
+++ b/Eigen/src/Core/TriangularMatrix.h
@@ -343,21 +343,6 @@ struct ei_triangular_assignment_selector
   }
 };
 
-template
-struct ei_triangular_assignment_selector
-{
-  inline static void run(Derived1 &dst, const Derived2 &src)
-  {
-    if(Mode&UnitDiagBit)
-    {
-      if(ClearOpposite)
-        dst.coeffRef(0, 0) = 1;
-    }
-    else if(!(Mode & ZeroDiagBit))
-      dst.copyCoeff(0, 0, src);
-  }
-};
-
 // prevent buggy user code from causing an infinite recursion
 template
 struct ei_triangular_assignment_selector
diff --git a/test/triangular.cpp b/test/triangular.cpp
index 3c89a8abb..a10b457a7 100644
--- a/test/triangular.cpp
+++ b/test/triangular.cpp
@@ -141,7 +141,10 @@ template void triangular_rect(const MatrixType& m)
 {
   typedef typename MatrixType::Scalar Scalar;
   typedef typename NumTraits::Real RealScalar;
-  typedef Matrix VectorType;
+  enum { Rows =  MatrixType::RowsAtCompileTime, Cols =  MatrixType::ColsAtCompileTime };
+  typedef Matrix VectorType;
+  typedef Matrix RMatrixType;
+  
 
   int rows = m.rows();
   int cols = m.cols();
@@ -153,10 +156,10 @@ template void triangular_rect(const MatrixType& m)
              r1(rows, cols),
              r2(rows, cols),
              mzero = MatrixType::Zero(rows, cols),
-             mones = MatrixType::Ones(rows, cols),
-             identity = Matrix
+             mones = MatrixType::Ones(rows, cols);
+  RMatrixType identity = Matrix
                               ::Identity(rows, rows),
-             square = Matrix
+              square = Matrix
                               ::Random(rows, rows);
   VectorType v1 = VectorType::Random(rows),
              v2 = VectorType::Random(rows),
@@ -172,8 +175,6 @@ template void triangular_rect(const MatrixType& m)
     VERIFY(!m2.isLowerTriangular());
   }
 
-//   VERIFY_IS_APPROX(m1up.transpose() * m2, m1.upper().transpose().lower() * m2);
-
   // test overloaded operator+=
   r1.setZero();
   r2.setZero();
@@ -227,25 +228,30 @@ template void triangular_rect(const MatrixType& m)
   m3.setZero();
   m3.template triangularView().setOnes();
   VERIFY_IS_APPROX(m2,m3);
-
 }
 
 void test_triangular()
 {
-  for(int i = 0; i < g_repeat ; i++) {
+  for(int i = 0; i < g_repeat ; i++)
+  {
+
+#ifdef EIGEN_TEST_PART_7
+    int r = ei_random(2,20);
+    int c = ei_random(2,20);
+#endif
+
     CALL_SUBTEST_1( triangular_square(Matrix()) );
     CALL_SUBTEST_2( triangular_square(Matrix()) );
     CALL_SUBTEST_3( triangular_square(Matrix3d()) );
     CALL_SUBTEST_4( triangular_square(MatrixXcf(4, 4)) );
     CALL_SUBTEST_5( triangular_square(Matrix,8, 8>()) );
     CALL_SUBTEST_6( triangular_square(MatrixXcd(17,17)) );
-    CALL_SUBTEST_7( triangular_square(Matrix(5, 5)) );
+    CALL_SUBTEST_7( triangular_square(Matrix(r, r)) );
 
     CALL_SUBTEST_8( triangular_rect(Matrix()) );
     CALL_SUBTEST_9( triangular_rect(Matrix()) );
     CALL_SUBTEST_4( triangular_rect(MatrixXcf(4, 10)) );
     CALL_SUBTEST_6( triangular_rect(MatrixXcd(11, 3)) );
-    CALL_SUBTEST_7( triangular_rect(Matrix(7, 6)) );
-
+    CALL_SUBTEST_7( triangular_rect(Matrix(r, c)) );
   }
 }
-- 
cgit v1.2.3


From eac3232095baf7c69e8ff7a6b636ffcf03db156b Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Thu, 19 Nov 2009 20:50:50 -0500
Subject: minor improvements in triangular stuff

---
 Eigen/src/Core/TriangularMatrix.h | 2 +-
 test/triangular.cpp               | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Eigen/src/Core/TriangularMatrix.h b/Eigen/src/Core/TriangularMatrix.h
index 34b029421..1286bf6a6 100644
--- a/Eigen/src/Core/TriangularMatrix.h
+++ b/Eigen/src/Core/TriangularMatrix.h
@@ -238,7 +238,7 @@ template class TriangularView
     DenseMatrixType toDenseMatrix() const
     {
       DenseMatrixType res(rows(), cols());
-      res = *this;
+      evalToLazy(res);
       return res;
     }
 
diff --git a/test/triangular.cpp b/test/triangular.cpp
index a10b457a7..379f586c4 100644
--- a/test/triangular.cpp
+++ b/test/triangular.cpp
@@ -85,7 +85,7 @@ template void triangular_square(const MatrixType& m)
 
   m1 = MatrixType::Random(rows, cols);
   for (int i=0; i();
+    while (ei_abs2(m1(i,i))<1e-1) m1(i,i) = ei_random();
 
   Transpose trm4(m4);
   // test back and forward subsitution with a vector as the rhs
-- 
cgit v1.2.3


From 6cbf662f14d8fd0606d9e9c6f7052e5dcc52b2ae Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Thu, 19 Nov 2009 22:01:13 -0500
Subject: * don't laugh, but these bugs took me forever to fix. * expand unit
 tests to make sure to catch them: they nearly escaped the existing tests as
 these memory violations were highly dependent on the numbers of rows and
 cols.

---
 Eigen/src/Core/TriangularMatrix.h |  6 +++---
 test/triangular.cpp               | 29 +++++++++++++----------------
 2 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/Eigen/src/Core/TriangularMatrix.h b/Eigen/src/Core/TriangularMatrix.h
index 1286bf6a6..1a8f6493d 100644
--- a/Eigen/src/Core/TriangularMatrix.h
+++ b/Eigen/src/Core/TriangularMatrix.h
@@ -410,7 +410,7 @@ struct ei_triangular_assignment_selector
@@ -451,9 +451,9 @@ struct ei_triangular_assignment_selector void triangular_rect(const MatrixType& m)
   m3 = 3 * m2;
   VERIFY_IS_APPROX(m3.template triangularView().toDenseMatrix(), m1);
 
+
   m1.setZero();
   m1.template triangularView() = 3 * m2;
   VERIFY_IS_APPROX(m3.template triangularView().toDenseMatrix(), m1);
@@ -196,10 +197,10 @@ template void triangular_rect(const MatrixType& m)
   m1.template triangularView() = 3 * m2;
   VERIFY_IS_APPROX(m3.template triangularView().toDenseMatrix(), m1);
 
+
   m1.setZero();
   m1.template triangularView() = 3 * m2;
   VERIFY_IS_APPROX(m3.template triangularView().toDenseMatrix(), m1);
-
   m1.setRandom();
   m2 = m1.template triangularView();
   VERIFY(m2.isUpperTriangular());
@@ -234,24 +235,20 @@ void test_triangular()
 {
   for(int i = 0; i < g_repeat ; i++)
   {
-
-#ifdef EIGEN_TEST_PART_7
-    int r = ei_random(2,20);
-    int c = ei_random(2,20);
-#endif
+    EIGEN_UNUSED int r = ei_random(2,20);
+    EIGEN_UNUSED int c = ei_random(2,20);
 
     CALL_SUBTEST_1( triangular_square(Matrix()) );
     CALL_SUBTEST_2( triangular_square(Matrix()) );
     CALL_SUBTEST_3( triangular_square(Matrix3d()) );
-    CALL_SUBTEST_4( triangular_square(MatrixXcf(4, 4)) );
-    CALL_SUBTEST_5( triangular_square(Matrix,8, 8>()) );
-    CALL_SUBTEST_6( triangular_square(MatrixXcd(17,17)) );
-    CALL_SUBTEST_7( triangular_square(Matrix(r, r)) );
-
-    CALL_SUBTEST_8( triangular_rect(Matrix()) );
-    CALL_SUBTEST_9( triangular_rect(Matrix()) );
-    CALL_SUBTEST_4( triangular_rect(MatrixXcf(4, 10)) );
-    CALL_SUBTEST_6( triangular_rect(MatrixXcd(11, 3)) );
-    CALL_SUBTEST_7( triangular_rect(Matrix(r, c)) );
+    CALL_SUBTEST_4( triangular_square(Matrix,8, 8>()) );
+    CALL_SUBTEST_5( triangular_square(MatrixXcd(r,r)) );
+    CALL_SUBTEST_6( triangular_square(Matrix(r, r)) );
+
+    CALL_SUBTEST_7( triangular_rect(Matrix()) );
+    CALL_SUBTEST_8( triangular_rect(Matrix()) );
+    CALL_SUBTEST_9( triangular_rect(MatrixXcf(r, c)) );
+    CALL_SUBTEST_5( triangular_rect(MatrixXcd(r, c)) );
+    CALL_SUBTEST_6( triangular_rect(Matrix(r, c)) );
   }
 }
-- 
cgit v1.2.3


From b0baf43114d3e8fa0bff957636912e93ec8a4e6a Mon Sep 17 00:00:00 2001
From: Jitse Niesen 
Date: Fri, 20 Nov 2009 11:26:26 +0000
Subject: Eigen/CMakeLists.txt: remove parens from if. Only CMake 2.6.3 and
 later recognize this syntax, and at the moment we require 2.6.2. CMake uses
 the right precendence, per its man page, so the parentheses are not
 necessary.

---
 Eigen/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Eigen/CMakeLists.txt b/Eigen/CMakeLists.txt
index 321b2978e..af90db2fe 100644
--- a/Eigen/CMakeLists.txt
+++ b/Eigen/CMakeLists.txt
@@ -1,6 +1,6 @@
 file(GLOB Eigen_directory_files "*")
 foreach(f ${Eigen_directory_files})
-  if(NOT(f MATCHES ".txt") AND NOT (f MATCHES "src"))
+  if(NOT f MATCHES ".txt" AND NOT f MATCHES "src")
     list(APPEND Eigen_directory_files_to_install ${f})
   endif()
 endforeach(f ${Eigen_directory_files})
-- 
cgit v1.2.3


From 34be9d45376193cf1d1cdbcb6d96fbc4f0af73b9 Mon Sep 17 00:00:00 2001
From: Jitse Niesen 
Date: Fri, 20 Nov 2009 12:22:46 +0000
Subject: Replace toDense() by toDenseMatrix() in tests.

---
 test/cholesky.cpp            |  4 ++--
 test/product_selfadjoint.cpp |  8 ++++----
 test/product_syrk.cpp        | 12 ++++++------
 test/product_trsm.cpp        |  2 +-
 4 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/test/cholesky.cpp b/test/cholesky.cpp
index c3ef96752..c658b902c 100644
--- a/test/cholesky.cpp
+++ b/test/cholesky.cpp
@@ -95,7 +95,7 @@ template void cholesky(const MatrixType& m)
 
   {
     LLT chollo(symmLo);
-    VERIFY_IS_APPROX(symm, chollo.matrixL().toDense() * chollo.matrixL().adjoint().toDense());
+    VERIFY_IS_APPROX(symm, chollo.matrixL().toDenseMatrix() * chollo.matrixL().adjoint().toDenseMatrix());
     vecX = chollo.solve(vecB);
     VERIFY_IS_APPROX(symm * vecX, vecB);
     matX = chollo.solve(matB);
@@ -103,7 +103,7 @@ template void cholesky(const MatrixType& m)
 
     // test the upper mode
     LLT cholup(symmUp);
-    VERIFY_IS_APPROX(symm, cholup.matrixL().toDense() * cholup.matrixL().adjoint().toDense());
+    VERIFY_IS_APPROX(symm, cholup.matrixL().toDenseMatrix() * cholup.matrixL().adjoint().toDenseMatrix());
     vecX = cholup.solve(vecB);
     VERIFY_IS_APPROX(symm * vecX, vecB);
     matX = cholup.solve(matB);
diff --git a/test/product_selfadjoint.cpp b/test/product_selfadjoint.cpp
index aa8da37bd..2e9f8be80 100644
--- a/test/product_selfadjoint.cpp
+++ b/test/product_selfadjoint.cpp
@@ -55,15 +55,15 @@ template void product_selfadjoint(const MatrixType& m)
   // rank2 update
   m2 = m1.template triangularView();
   m2.template selfadjointView().rankUpdate(v1,v2);
-  VERIFY_IS_APPROX(m2, (m1 + v1 * v2.adjoint()+ v2 * v1.adjoint()).template triangularView().toDense());
+  VERIFY_IS_APPROX(m2, (m1 + v1 * v2.adjoint()+ v2 * v1.adjoint()).template triangularView().toDenseMatrix());
 
   m2 = m1.template triangularView();
   m2.template selfadjointView().rankUpdate(-v1,s2*v2,s3);
-  VERIFY_IS_APPROX(m2, (m1 + (-s2*s3) * (v1 * v2.adjoint()+ v2 * v1.adjoint())).template triangularView().toDense());
+  VERIFY_IS_APPROX(m2, (m1 + (-s2*s3) * (v1 * v2.adjoint()+ v2 * v1.adjoint())).template triangularView().toDenseMatrix());
 
   m2 = m1.template triangularView();
   m2.template selfadjointView().rankUpdate(-r1.adjoint(),r2.adjoint()*s3,s1);
-  VERIFY_IS_APPROX(m2, (m1 + (-s3*s1) * (r1.adjoint() * r2 + r2.adjoint() * r1)).template triangularView().toDense());
+  VERIFY_IS_APPROX(m2, (m1 + (-s3*s1) * (r1.adjoint() * r2 + r2.adjoint() * r1)).template triangularView().toDenseMatrix());
 
   if (rows>1)
   {
@@ -71,7 +71,7 @@ template void product_selfadjoint(const MatrixType& m)
     m2.block(1,1,rows-1,cols-1).template selfadjointView().rankUpdate(v1.end(rows-1),v2.start(cols-1));
     m3 = m1;
     m3.block(1,1,rows-1,cols-1) += v1.end(rows-1) * v2.start(cols-1).adjoint()+ v2.start(cols-1) * v1.end(rows-1).adjoint();
-    VERIFY_IS_APPROX(m2, m3.template triangularView().toDense());
+    VERIFY_IS_APPROX(m2, m3.template triangularView().toDenseMatrix());
   }
 }
 
diff --git a/test/product_syrk.cpp b/test/product_syrk.cpp
index 37d54bf16..9f6aec0e2 100644
--- a/test/product_syrk.cpp
+++ b/test/product_syrk.cpp
@@ -46,27 +46,27 @@ template void syrk(const MatrixType& m)
 
   m2.setZero();
   VERIFY_IS_APPROX((m2.template selfadjointView().rankUpdate(rhs2,s1)._expression()),
-                   ((s1 * rhs2 * rhs2.adjoint()).eval().template triangularView().toDense()));
+                   ((s1 * rhs2 * rhs2.adjoint()).eval().template triangularView().toDenseMatrix()));
 
   m2.setZero();
   VERIFY_IS_APPROX(m2.template selfadjointView().rankUpdate(rhs2,s1)._expression(),
-                   (s1 * rhs2 * rhs2.adjoint()).eval().template triangularView().toDense());
+                   (s1 * rhs2 * rhs2.adjoint()).eval().template triangularView().toDenseMatrix());
 
   m2.setZero();
   VERIFY_IS_APPROX(m2.template selfadjointView().rankUpdate(rhs1.adjoint(),s1)._expression(),
-                   (s1 * rhs1.adjoint() * rhs1).eval().template triangularView().toDense());
+                   (s1 * rhs1.adjoint() * rhs1).eval().template triangularView().toDenseMatrix());
 
   m2.setZero();
   VERIFY_IS_APPROX(m2.template selfadjointView().rankUpdate(rhs1.adjoint(),s1)._expression(),
-                   (s1 * rhs1.adjoint() * rhs1).eval().template triangularView().toDense());
+                   (s1 * rhs1.adjoint() * rhs1).eval().template triangularView().toDenseMatrix());
 
   m2.setZero();
   VERIFY_IS_APPROX(m2.template selfadjointView().rankUpdate(rhs3.adjoint(),s1)._expression(),
-                   (s1 * rhs3.adjoint() * rhs3).eval().template triangularView().toDense());
+                   (s1 * rhs3.adjoint() * rhs3).eval().template triangularView().toDenseMatrix());
 
   m2.setZero();
   VERIFY_IS_APPROX(m2.template selfadjointView().rankUpdate(rhs3.adjoint(),s1)._expression(),
-                   (s1 * rhs3.adjoint() * rhs3).eval().template triangularView().toDense());
+                   (s1 * rhs3.adjoint() * rhs3).eval().template triangularView().toDenseMatrix());
 }
 
 void test_product_syrk()
diff --git a/test/product_trsm.cpp b/test/product_trsm.cpp
index f850e031a..5f224d1a9 100644
--- a/test/product_trsm.cpp
+++ b/test/product_trsm.cpp
@@ -27,7 +27,7 @@
 #define VERIFY_TRSM(TRI,XB) { \
     (XB).setRandom(); ref = (XB); \
     (TRI).solveInPlace(XB); \
-    VERIFY_IS_APPROX((TRI).toDense() * (XB), ref); \
+    VERIFY_IS_APPROX((TRI).toDenseMatrix() * (XB), ref); \
   }
 
 template void trsm(int size,int cols)
-- 
cgit v1.2.3


From 3c5e32f0daa3a73394f9b770ef6cba82c47f033e Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Fri, 20 Nov 2009 10:17:59 -0500
Subject: improvements in FindEigen*.cmake, ported from changes in
 CMakeLists.txt:  - better regular expression  - grep the whole file, not
 expensive anyway, more robust

---
 cmake/FindEigen2.cmake | 8 ++++----
 cmake/FindEigen3.cmake | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/cmake/FindEigen2.cmake b/cmake/FindEigen2.cmake
index ee054b0da..da95bb0f5 100644
--- a/cmake/FindEigen2.cmake
+++ b/cmake/FindEigen2.cmake
@@ -29,13 +29,13 @@ if(NOT Eigen2_FIND_VERSION)
 endif(NOT Eigen2_FIND_VERSION)
 
 macro(_eigen2_check_version)
-  file(READ "${EIGEN2_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen2_version_header LIMIT 5000 OFFSET 1000)
+  file(READ "${EIGEN2_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen2_version_header)
 
-  string(REGEX MATCH "define *EIGEN_WORLD_VERSION ([0-9]*)" _eigen2_world_version_match "${_eigen2_version_header}")
+  string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen2_world_version_match "${_eigen2_version_header}")
   set(EIGEN2_WORLD_VERSION "${CMAKE_MATCH_1}")
-  string(REGEX MATCH "define *EIGEN_MAJOR_VERSION ([0-9]*)" _eigen2_major_version_match "${_eigen2_version_header}")
+  string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen2_major_version_match "${_eigen2_version_header}")
   set(EIGEN2_MAJOR_VERSION "${CMAKE_MATCH_1}")
-  string(REGEX MATCH "define *EIGEN_MINOR_VERSION ([0-9]*)" _eigen2_minor_version_match "${_eigen2_version_header}")
+  string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen2_minor_version_match "${_eigen2_version_header}")
   set(EIGEN2_MINOR_VERSION "${CMAKE_MATCH_1}")
 
   set(EIGEN2_VERSION ${EIGEN2_WORLD_VERSION}.${EIGEN2_MAJOR_VERSION}.${EIGEN2_MINOR_VERSION})
diff --git a/cmake/FindEigen3.cmake b/cmake/FindEigen3.cmake
index 2c4bb0462..b87ebff4b 100644
--- a/cmake/FindEigen3.cmake
+++ b/cmake/FindEigen3.cmake
@@ -29,13 +29,13 @@ if(NOT Eigen3_FIND_VERSION)
 endif(NOT Eigen3_FIND_VERSION)
 
 macro(_eigen3_check_version)
-  file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header LIMIT 5000 OFFSET 1000)
+  file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header)
 
-  string(REGEX MATCH "define *EIGEN_WORLD_VERSION ([0-9]*)" _eigen3_world_version_match "${_eigen3_version_header}")
+  string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}")
   set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}")
-  string(REGEX MATCH "define *EIGEN_MAJOR_VERSION ([0-9]*)" _eigen3_major_version_match "${_eigen3_version_header}")
+  string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}")
   set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}")
-  string(REGEX MATCH "define *EIGEN_MINOR_VERSION ([0-9]*)" _eigen3_minor_version_match "${_eigen3_version_header}")
+  string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}")
   set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}")
 
   set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION})
-- 
cgit v1.2.3


From 06f11f337951982f240c161933229812c391e979 Mon Sep 17 00:00:00 2001
From: Thomas Capricelli 
Date: Sat, 21 Nov 2009 02:00:47 +0100
Subject: fix important typo

---
 unsupported/Eigen/NonLinearOptimization | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/unsupported/Eigen/NonLinearOptimization b/unsupported/Eigen/NonLinearOptimization
index 601b1abc7..5e64bc585 100644
--- a/unsupported/Eigen/NonLinearOptimization
+++ b/unsupported/Eigen/NonLinearOptimization
@@ -43,7 +43,7 @@ namespace Eigen {
   * actually linear. But if this is so, you should probably better use other
   * methods more fitted to this special case.
   *
-  * One algorithm allows to find the extremum of such a system (Levenberg
+  * One algorithm allows to find an extremum of such a system (Levenberg
   * Marquardt algorithm) and the second one is used to find 
   * a zero for the system (Powell hybrid "dogleg" method).
   *
-- 
cgit v1.2.3


From 44d0d667cd629a18e29b9c248633891c1b04f75c Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Mon, 23 Nov 2009 10:13:21 -0500
Subject: 4x4 inverse: * change block selection threshold from 1e-2 to 1e-1 *
 add rigorous precision test

---
 Eigen/src/LU/Inverse.h    |  7 ++--
 test/CMakeLists.txt       |  2 ++
 test/inverse.cpp          |  8 -----
 test/main.h               | 13 +++++---
 test/prec_inverse_4x4.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 100 insertions(+), 14 deletions(-)
 create mode 100644 test/prec_inverse_4x4.cpp

diff --git a/Eigen/src/LU/Inverse.h b/Eigen/src/LU/Inverse.h
index 306b5f60a..9d5e86845 100644
--- a/Eigen/src/LU/Inverse.h
+++ b/Eigen/src/LU/Inverse.h
@@ -235,8 +235,11 @@ struct ei_compute_inverse
     int good_row0, good_row1, good_i;
     Matrix absdet;
 
-    // any 2x2 block with determinant above this threshold will be considered good enough
-    RealScalar d = (matrix.col(0).squaredNorm()+matrix.col(1).squaredNorm()) * RealScalar(1e-2);
+    // any 2x2 block with determinant above this threshold will be considered good enough.
+    // The magic value 1e-1 here comes from experimentation. The bigger it is, the higher the precision,
+    // the slower the computation. This value 1e-1 gives precision almost as good as the brutal cofactors
+    // algorithm, both in average and in worst-case precision.
+    RealScalar d = (matrix.col(0).squaredNorm()+matrix.col(1).squaredNorm()) * RealScalar(1e-1);
     #define ei_inv_size4_helper_macro(i,row0,row1) \
     absdet[i] = ei_abs(matrix.coeff(row0,0)*matrix.coeff(row1,1) \
                                  - matrix.coeff(row0,1)*matrix.coeff(row1,0)); \
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 30668a2aa..c91ec328b 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -160,6 +160,8 @@ ei_add_test(swap)
 ei_add_test(conservative_resize)
 ei_add_test(permutationmatrices)
 
+ei_add_test(prec_inverse_4x4)
+
 ei_add_property(EIGEN_TESTING_SUMMARY "CXX:               ${CMAKE_CXX_COMPILER}\n")
 if(CMAKE_COMPILER_IS_GNUCXX)
   execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version COMMAND head -n 1 OUTPUT_VARIABLE EIGEN_CXX_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE)
diff --git a/test/inverse.cpp b/test/inverse.cpp
index 3ed61d356..59b791507 100644
--- a/test/inverse.cpp
+++ b/test/inverse.cpp
@@ -104,12 +104,4 @@ void test_inverse()
     s = ei_random(25,100);
     CALL_SUBTEST_6( inverse(MatrixXcd(s,s)) );
   }
-
-#ifdef EIGEN_TEST_PART_4
-  // test some tricky cases for 4x4 matrices
-  VERIFY_IS_APPROX((Matrix4f() << 0,0,1,0, 1,0,0,0, 0,1,0,0, 0,0,0,1).finished().inverse(),
-                   (Matrix4f() << 0,1,0,0, 0,0,1,0, 1,0,0,0, 0,0,0,1).finished());
-  VERIFY_IS_APPROX((Matrix4f() << 1,0,0,0, 0,0,1,0, 0,0,0,1, 0,1,0,0).finished().inverse(),
-                   (Matrix4f() << 1,0,0,0, 0,0,0,1, 0,1,0,0, 0,0,1,0).finished());
-#endif
 }
diff --git a/test/main.h b/test/main.h
index 0b9b0bc4c..3ae573c1e 100644
--- a/test/main.h
+++ b/test/main.h
@@ -372,6 +372,14 @@ template<> struct GetDifferentType { typedef float type; };
 template struct GetDifferentType >
 { typedef std::complex::type> type; };
 
+template std::string type_name() { return "other"; }
+template<> std::string type_name() { return "float"; }
+template<> std::string type_name() { return "double"; }
+template<> std::string type_name() { return "int"; }
+template<> std::string type_name >() { return "complex"; }
+template<> std::string type_name >() { return "complex"; }
+template<> std::string type_name >() { return "complex"; }
+
 // forward declaration of the main test function
 void EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
 
@@ -444,7 +452,4 @@ int main(int argc, char *argv[])
 
     EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
     return 0;
-}
-
-
-
+}
\ No newline at end of file
diff --git a/test/prec_inverse_4x4.cpp b/test/prec_inverse_4x4.cpp
new file mode 100644
index 000000000..77763f830
--- /dev/null
+++ b/test/prec_inverse_4x4.cpp
@@ -0,0 +1,84 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2009 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 .
+
+#include "main.h"
+#include 
+#include 
+
+template void inverse_permutation_4x4()
+{
+  typedef typename MatrixType::Scalar Scalar;
+  typedef typename MatrixType::RealScalar RealScalar;
+  double error_max = 0.;
+  Vector4i indices(0,1,2,3);
+  for(int i = 0; i < 24; ++i)
+  {
+    MatrixType m = PermutationMatrix<4>(indices);
+    MatrixType inv = m.inverse();
+    double error = double( (m*inv-MatrixType::Identity()).norm() / epsilon() );
+    error_max = std::max(error_max, error);
+    std::next_permutation(indices.data(),indices.data()+4);
+  }
+  std::cerr << "inverse_permutation_4x4, Scalar = " << type_name() << std::endl;
+  EIGEN_DEBUG_VAR(error_max);
+  VERIFY(error_max < (NumTraits::IsComplex ? 150.0 : 60.) );
+}
+
+template void inverse_general_4x4(int repeat)
+{
+  typedef typename MatrixType::Scalar Scalar;
+  typedef typename MatrixType::RealScalar RealScalar;
+  double error_sum = 0., error_max = 0.;
+  for(int i = 0; i < repeat; ++i)
+  {
+    MatrixType m;
+    RealScalar absdet;
+    do {
+      m = MatrixType::Random();
+      absdet = ei_abs(m.determinant());
+    } while(absdet == RealScalar(0));
+    MatrixType inv = m.inverse();
+    double error = double( (m*inv-MatrixType::Identity()).norm() * absdet / epsilon() );
+    error_sum += error;
+    error_max = std::max(error_max, error);
+  }
+  std::cerr << "inverse_general_4x4, Scalar = " << type_name() << std::endl;
+  double error_avg = error_sum / repeat;
+  EIGEN_DEBUG_VAR(error_avg);
+  EIGEN_DEBUG_VAR(error_max);
+  VERIFY(error_avg < (NumTraits::IsComplex ? 8.4 : 1.4) );
+  VERIFY(error_max < (NumTraits::IsComplex ? 150.0 : 60.) );
+}
+
+void test_prec_inverse_4x4()
+{
+  CALL_SUBTEST_1((inverse_permutation_4x4()));
+  CALL_SUBTEST_1(( inverse_general_4x4(200000 * g_repeat) ));
+
+  CALL_SUBTEST_2((inverse_permutation_4x4 >()));
+  CALL_SUBTEST_2(( inverse_general_4x4 >(200000 * g_repeat) ));
+
+  CALL_SUBTEST_3((inverse_permutation_4x4()));
+  CALL_SUBTEST_3((inverse_general_4x4(50000 * g_repeat)));
+}
-- 
cgit v1.2.3


From e6ea9e401c6933c102a534d853eb2b59cdd6be3b Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Mon, 23 Nov 2009 11:24:06 -0500
Subject: improve precision test

---
 test/prec_inverse_4x4.cpp | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/test/prec_inverse_4x4.cpp b/test/prec_inverse_4x4.cpp
index 77763f830..c5c7af5d2 100644
--- a/test/prec_inverse_4x4.cpp
+++ b/test/prec_inverse_4x4.cpp
@@ -26,6 +26,28 @@
 #include 
 #include 
 
+Matrix4f inverse(const Matrix4f& m)
+{
+  Matrix4f r;
+  r(0,0) = m.minor(0,0).determinant();
+  r(1,0) = -m.minor(0,1).determinant();
+  r(2,0) = m.minor(0,2).determinant();
+  r(3,0) = -m.minor(0,3).determinant();
+  r(0,2) = m.minor(2,0).determinant();
+  r(1,2) = -m.minor(2,1).determinant();
+  r(2,2) = m.minor(2,2).determinant();
+  r(3,2) = -m.minor(2,3).determinant();
+  r(0,1) = -m.minor(1,0).determinant();
+  r(1,1) = m.minor(1,1).determinant();
+  r(2,1) = -m.minor(1,2).determinant();
+  r(3,1) = m.minor(1,3).determinant();
+  r(0,3) = -m.minor(3,0).determinant();
+  r(1,3) = m.minor(3,1).determinant();
+  r(2,3) = -m.minor(3,2).determinant();
+  r(3,3) = m.minor(3,3).determinant();
+  return r / (m(0,0)*r(0,0) + m(1,0)*r(0,1) + m(2,0)*r(0,2) + m(3,0)*r(0,3));
+}
+
 template void inverse_permutation_4x4()
 {
   typedef typename MatrixType::Scalar Scalar;
@@ -42,7 +64,7 @@ template void inverse_permutation_4x4()
   }
   std::cerr << "inverse_permutation_4x4, Scalar = " << type_name() << std::endl;
   EIGEN_DEBUG_VAR(error_max);
-  VERIFY(error_max < (NumTraits::IsComplex ? 150.0 : 60.) );
+  VERIFY(error_max < 1. );
 }
 
 template void inverse_general_4x4(int repeat)
@@ -57,7 +79,7 @@ template void inverse_general_4x4(int repeat)
     do {
       m = MatrixType::Random();
       absdet = ei_abs(m.determinant());
-    } while(absdet == RealScalar(0));
+    } while(absdet < 2*epsilon() );
     MatrixType inv = m.inverse();
     double error = double( (m*inv-MatrixType::Identity()).norm() * absdet / epsilon() );
     error_sum += error;
@@ -68,7 +90,7 @@ template void inverse_general_4x4(int repeat)
   EIGEN_DEBUG_VAR(error_avg);
   EIGEN_DEBUG_VAR(error_max);
   VERIFY(error_avg < (NumTraits::IsComplex ? 8.4 : 1.4) );
-  VERIFY(error_max < (NumTraits::IsComplex ? 150.0 : 60.) );
+  VERIFY(error_max < (NumTraits::IsComplex ? 150.0 : 75.) );
 }
 
 void test_prec_inverse_4x4()
-- 
cgit v1.2.3


From abdb2a2bd55661d09db7a6b5ae7f603fc61db815 Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Tue, 24 Nov 2009 12:14:40 -0500
Subject: fix assert and handle Unit shapes

---
 Eigen/src/Core/TriangularMatrix.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Eigen/src/Core/TriangularMatrix.h b/Eigen/src/Core/TriangularMatrix.h
index 1a8f6493d..e5d7367d8 100644
--- a/Eigen/src/Core/TriangularMatrix.h
+++ b/Eigen/src/Core/TriangularMatrix.h
@@ -88,11 +88,11 @@ template class TriangularBase : public AnyMatrixBase
 
     void check_coordinates(int row, int col)
     {
-      ei_assert(col>0 && col0 && row=0 && col=0 && row=row)
                 || (Mode==LowerTriangular && col<=row)
-                || (Mode==StrictlyUpperTriangular && col>row)
-                || (Mode==StrictlyLowerTriangular && colrow)
+                || ((Mode==StrictlyLowerTriangular || Mode==UnitLowerTriangular) && col
Date: Tue, 24 Nov 2009 15:12:43 -0500
Subject: add SSE4 support, start with integer multiplication

---
 CMakeLists.txt                       | 22 +++++++++++++++++-----
 Eigen/Core                           |  6 ++++++
 Eigen/src/Core/arch/SSE/PacketMath.h |  4 ++++
 cmake/EigenTesting.cmake             | 32 ++++++++++++++++++++++----------
 4 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8932fff2a..33e7584c4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,31 +63,43 @@ if(CMAKE_COMPILER_IS_GNUCXX)
 
     if(NOT EIGEN_TEST_LIB)
       set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
-    endif(NOT EIGEN_TEST_LIB)
+    endif()
 
     option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
     if(EIGEN_TEST_SSE2)
       set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2")
       message("Enabling SSE2 in tests/examples")
-    endif(EIGEN_TEST_SSE2)
+    endif()
 
     option(EIGEN_TEST_SSE3 "Enable/Disable SSE3 in tests/examples" OFF)
     if(EIGEN_TEST_SSE3)
       set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse3")
       message("Enabling SSE3 in tests/examples")
-    endif(EIGEN_TEST_SSE3)
+    endif()
 
     option(EIGEN_TEST_SSSE3 "Enable/Disable SSSE3 in tests/examples" OFF)
     if(EIGEN_TEST_SSSE3)
       set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mssse3")
       message("Enabling SSSE3 in tests/examples")
-    endif(EIGEN_TEST_SSSE3)
+    endif()
+
+    option(EIGEN_TEST_SSE4_1 "Enable/Disable SSE4.1 in tests/examples" OFF)
+    if(EIGEN_TEST_SSE4_1)
+      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
+      message("Enabling SSE4.1 in tests/examples")
+    endif()
+
+    option(EIGEN_TEST_SSE4_2 "Enable/Disable SSE4.2 in tests/examples" OFF)
+    if(EIGEN_TEST_SSE4_2)
+      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2")
+      message("Enabling SSE4.2 in tests/examples")
+    endif()
 
     option(EIGEN_TEST_ALTIVEC "Enable/Disable altivec in tests/examples" OFF)
     if(EIGEN_TEST_ALTIVEC)
       set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec -mabi=altivec")
       message("Enabling AltiVec in tests/examples")
-    endif(EIGEN_TEST_ALTIVEC)
+    endif()
 
   endif(CMAKE_SYSTEM_NAME MATCHES Linux)
 endif(CMAKE_COMPILER_IS_GNUCXX)
diff --git a/Eigen/Core b/Eigen/Core
index 2968e36c6..e095aee11 100644
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -67,6 +67,12 @@
     #ifdef __SSSE3__
       #include 
     #endif
+    #ifdef __SSE4_1__
+      #include 
+    #endif
+    #ifdef __SSE4_2__
+      #include 
+    #endif
   #elif defined __ALTIVEC__
     #define EIGEN_VECTORIZE
     #define EIGEN_VECTORIZE_ALTIVEC
diff --git a/Eigen/src/Core/arch/SSE/PacketMath.h b/Eigen/src/Core/arch/SSE/PacketMath.h
index 60ccadc21..69f6979bd 100644
--- a/Eigen/src/Core/arch/SSE/PacketMath.h
+++ b/Eigen/src/Core/arch/SSE/PacketMath.h
@@ -118,6 +118,9 @@ template<> EIGEN_STRONG_INLINE Packet4f ei_pmul(const Packet4f& a, con
 template<> EIGEN_STRONG_INLINE Packet2d ei_pmul(const Packet2d& a, const Packet2d& b) { return _mm_mul_pd(a,b); }
 template<> EIGEN_STRONG_INLINE Packet4i ei_pmul(const Packet4i& a, const Packet4i& b)
 {
+#ifdef __SSE4_1__
+  return _mm_mullo_epi32(a,b);
+#else
   // this version is slightly faster than 4 scalar products
   return ei_vec4i_swizzle1(
             ei_vec4i_swizzle2(
@@ -126,6 +129,7 @@ template<> EIGEN_STRONG_INLINE Packet4i ei_pmul(const Packet4i& a, con
                             ei_vec4i_swizzle1(b,1,0,3,2)),
               0,2,0,2),
             0,2,1,3);
+#endif
 }
 
 template<> EIGEN_STRONG_INLINE Packet4f ei_pdiv(const Packet4f& a, const Packet4f& b) { return _mm_div_ps(a,b); }
diff --git a/cmake/EigenTesting.cmake b/cmake/EigenTesting.cmake
index 42f7454f4..43ae53cc1 100644
--- a/cmake/EigenTesting.cmake
+++ b/cmake/EigenTesting.cmake
@@ -147,33 +147,45 @@ macro(ei_testing_print_summary)
 
   if(EIGEN_TEST_SSE2)
     message("SSE2:              ON")
-  else(EIGEN_TEST_SSE2)
+  else()
     message("SSE2:              Using architecture defaults")
-  endif(EIGEN_TEST_SSE2)
+  endif()
 
   if(EIGEN_TEST_SSE3)
     message("SSE3:              ON")
-  else(EIGEN_TEST_SSE3)
+  else()
     message("SSE3:              Using architecture defaults")
-  endif(EIGEN_TEST_SSE3)
+  endif()
 
   if(EIGEN_TEST_SSSE3)
     message("SSSE3:             ON")
-  else(EIGEN_TEST_SSSE3)
+  else()
     message("SSSE3:             Using architecture defaults")
-  endif(EIGEN_TEST_SSSE3)
+  endif()
+
+  if(EIGEN_TEST_SSE4_1)
+    message("SSE4.1:            ON")
+  else()
+    message("SSE4.1:            Using architecture defaults")
+  endif()
+
+  if(EIGEN_TEST_SSE4_2)
+    message("SSE4.2:            ON")
+  else()
+    message("SSE4.2:            Using architecture defaults")
+  endif()
 
   if(EIGEN_TEST_ALTIVEC)
     message("Altivec:           Using architecture defaults")
-  else(EIGEN_TEST_ALTIVEC)
+  else()
     message("Altivec:           Using architecture defaults")
-  endif(EIGEN_TEST_ALTIVEC)
+  endif()
 
   if(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
     message("Explicit vec:      OFF")
-  else(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
+  else()
     message("Explicit vec:      Using architecture defaults")
-  endif(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
+  endif()
 
   message("\n${EIGEN_TESTING_SUMMARY}")
   #   message("CXX:               ${CMAKE_CXX_COMPILER}")
-- 
cgit v1.2.3


From 1e2bcba5e4b481c72a9d4b2db563f711d13865e5 Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Wed, 25 Nov 2009 09:08:03 -0500
Subject: forward port slight changes in the 4x4 inverse test

---
 test/prec_inverse_4x4.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/prec_inverse_4x4.cpp b/test/prec_inverse_4x4.cpp
index c5c7af5d2..613535346 100644
--- a/test/prec_inverse_4x4.cpp
+++ b/test/prec_inverse_4x4.cpp
@@ -79,7 +79,7 @@ template void inverse_general_4x4(int repeat)
     do {
       m = MatrixType::Random();
       absdet = ei_abs(m.determinant());
-    } while(absdet < 2*epsilon() );
+    } while(absdet < 10 * epsilon());
     MatrixType inv = m.inverse();
     double error = double( (m*inv-MatrixType::Identity()).norm() * absdet / epsilon() );
     error_sum += error;
@@ -90,7 +90,7 @@ template void inverse_general_4x4(int repeat)
   EIGEN_DEBUG_VAR(error_avg);
   EIGEN_DEBUG_VAR(error_max);
   VERIFY(error_avg < (NumTraits::IsComplex ? 8.4 : 1.4) );
-  VERIFY(error_max < (NumTraits::IsComplex ? 150.0 : 75.) );
+  VERIFY(error_max < (NumTraits::IsComplex ? 160.0 : 75.) );
 }
 
 void test_prec_inverse_4x4()
-- 
cgit v1.2.3

-- 
cgit v1.2.3


From a6380ae272f5c1ae706b0b3c4c3fd658e2f99c62 Mon Sep 17 00:00:00 2001
From: Thomas Capricelli 
Date: Wed, 25 Nov 2009 23:08:39 +0100
Subject: silent warnings

---
 unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h b/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h
index ef91da2da..a06072a54 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h
@@ -8,7 +8,7 @@ void ei_r1mpyq(int m, int n, Scalar *a, int
 
     /* Local variables */
     int i, j, nm1, nmj;
-    Scalar cos__, sin__, temp;
+    Scalar cos__=0., sin__=0., temp;
 
     /* Parameter adjustments */
     --w;
-- 
cgit v1.2.3


From dca80b5f229cfb455a6beebbdaf2f6743beb71ed Mon Sep 17 00:00:00 2001
From: Thomas Capricelli 
Date: Wed, 25 Nov 2009 23:08:46 +0100
Subject: use typedef

---
 .../NonLinearOptimization/HybridNonLinearSolver.h  | 43 +++++++++----------
 .../src/NonLinearOptimization/LevenbergMarquardt.h | 50 +++++++++++-----------
 2 files changed, 47 insertions(+), 46 deletions(-)

diff --git a/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h b/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
index e944f0e1b..6269a3d89 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
@@ -71,50 +71,49 @@ public:
         int nb_of_superdiagonals;
         Scalar epsfcn;
     };
+    typedef Matrix< Scalar, Dynamic, 1 > FVectorType;
+    typedef Matrix< Scalar, Dynamic, Dynamic > JacobianType;
 
     Status hybrj1(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType  &x,
             const Scalar tol = ei_sqrt(epsilon())
             );
 
     Status solveInit(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType  &x,
             const int mode=1
             );
     Status solveOneStep(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType  &x,
             const int mode=1
             );
     Status solve(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType  &x,
             const int mode=1
             );
 
     Status hybrd1(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType  &x,
             const Scalar tol = ei_sqrt(epsilon())
             );
 
     Status solveNumericalDiffInit(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType  &x,
             const int mode=1
             );
     Status solveNumericalDiffOneStep(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType  &x,
             const int mode=1
             );
     Status solveNumericalDiff(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType  &x,
             const int mode=1
             );
 
     void resetParameters(void) { parameters = Parameters(); }
     Parameters parameters;
-    Matrix< Scalar, Dynamic, 1 >  fvec;
-    Matrix< Scalar, Dynamic, Dynamic > fjac;
-    Matrix< Scalar, Dynamic, 1 >  R;
-    Matrix< Scalar, Dynamic, 1 >  qtf;
-    Matrix< Scalar, Dynamic, 1 >  diag;
+    FVectorType  fvec, R, qtf, diag;
+    JacobianType fjac;
     int nfev;
     int njev;
     int iter;
@@ -133,7 +132,7 @@ private:
     int nslow1, nslow2;
     int ncfail;
     Scalar actred, prered;
-    Matrix< Scalar, Dynamic, 1 > wa1, wa2, wa3, wa4;
+    FVectorType wa1, wa2, wa3, wa4;
 };
 
 
@@ -141,7 +140,7 @@ private:
 template
 typename HybridNonLinearSolver::Status
 HybridNonLinearSolver::hybrj1(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const Scalar tol
         )
 {
@@ -164,7 +163,7 @@ HybridNonLinearSolver::hybrj1(
 template
 typename HybridNonLinearSolver::Status
 HybridNonLinearSolver::solveInit(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const int mode
         )
 {
@@ -214,7 +213,7 @@ HybridNonLinearSolver::solveInit(
 template
 typename HybridNonLinearSolver::Status
 HybridNonLinearSolver::solveOneStep(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const int mode
         )
 {
@@ -435,7 +434,7 @@ HybridNonLinearSolver::solveOneStep(
 template
 typename HybridNonLinearSolver::Status
 HybridNonLinearSolver::solve(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const int mode
         )
 {
@@ -450,7 +449,7 @@ HybridNonLinearSolver::solve(
 template
 typename HybridNonLinearSolver::Status
 HybridNonLinearSolver::hybrd1(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const Scalar tol
         )
 {
@@ -474,7 +473,7 @@ HybridNonLinearSolver::hybrd1(
 template
 typename HybridNonLinearSolver::Status
 HybridNonLinearSolver::solveNumericalDiffInit(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const int mode
         )
 {
@@ -529,7 +528,7 @@ HybridNonLinearSolver::solveNumericalDiffInit(
 template
 typename HybridNonLinearSolver::Status
 HybridNonLinearSolver::solveNumericalDiffOneStep(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const int mode
         )
 {
@@ -752,7 +751,7 @@ HybridNonLinearSolver::solveNumericalDiffOneStep(
 template
 typename HybridNonLinearSolver::Status
 HybridNonLinearSolver::solveNumericalDiff(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const int mode
         )
 {
diff --git a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
index 9e982a078..1a2a69561 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
@@ -72,56 +72,58 @@ public:
         Scalar epsfcn;
     };
 
+    typedef Matrix< Scalar, Dynamic, 1 > FVectorType;
+    typedef Matrix< Scalar, Dynamic, Dynamic > JacobianType;
+
     Status lmder1(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType &x,
             const Scalar tol = ei_sqrt(epsilon())
             );
 
     Status minimize(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType &x,
             const int mode=1
             );
     Status minimizeInit(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType &x,
             const int mode=1
             );
     Status minimizeOneStep(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType &x,
             const int mode=1
             );
 
     static Status lmdif1(
             FunctorType &functor,
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType &x,
             int *nfev,
             const Scalar tol = ei_sqrt(epsilon())
             );
 
     Status lmstr1(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType  &x,
             const Scalar tol = ei_sqrt(epsilon())
             );
 
     Status minimizeOptimumStorage(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType  &x,
             const int mode=1
             );
     Status minimizeOptimumStorageInit(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType  &x,
             const int mode=1
             );
     Status minimizeOptimumStorageOneStep(
-            Matrix< Scalar, Dynamic, 1 >  &x,
+            FVectorType  &x,
             const int mode=1
             );
 
     void resetParameters(void) { parameters = Parameters(); }
+
     Parameters parameters;
-    Matrix< Scalar, Dynamic, 1 >  fvec;
-    Matrix< Scalar, Dynamic, Dynamic > fjac;
+    FVectorType  fvec, qtf, diag;
+    JacobianType fjac;
     VectorXi ipvt;
-    Matrix< Scalar, Dynamic, 1 >  qtf;
-    Matrix< Scalar, Dynamic, 1 >  diag;
     int nfev;
     int njev;
     int iter;
@@ -130,7 +132,7 @@ private:
     FunctorType &functor;
     int n;
     int m;
-    Matrix< Scalar, Dynamic, 1 > wa1, wa2, wa3, wa4;
+    FVectorType wa1, wa2, wa3, wa4;
 
     Scalar par, sum;
     Scalar temp, temp1, temp2;
@@ -142,7 +144,7 @@ private:
 template
 typename LevenbergMarquardt::Status
 LevenbergMarquardt::lmder1(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const Scalar tol
         )
 {
@@ -165,7 +167,7 @@ LevenbergMarquardt::lmder1(
 template
 typename LevenbergMarquardt::Status
 LevenbergMarquardt::minimize(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const int mode
         )
 {
@@ -178,7 +180,7 @@ LevenbergMarquardt::minimize(
 template
 typename LevenbergMarquardt::Status
 LevenbergMarquardt::minimizeInit(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const int mode
         )
 {
@@ -228,7 +230,7 @@ LevenbergMarquardt::minimizeInit(
 template
 typename LevenbergMarquardt::Status
 LevenbergMarquardt::minimizeOneStep(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const int mode
         )
 {
@@ -424,13 +426,13 @@ LevenbergMarquardt::minimizeOneStep(
 template
 typename LevenbergMarquardt::Status
 LevenbergMarquardt::lmstr1(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const Scalar tol
         )
 {
     n = x.size();
     m = functor.values();
-    Matrix< Scalar, Dynamic, Dynamic > fjac(m, n);
+    JacobianType fjac(m, n);
     VectorXi ipvt;
 
     /* check the input parameters for errors. */
@@ -448,7 +450,7 @@ LevenbergMarquardt::lmstr1(
 template
 typename LevenbergMarquardt::Status
 LevenbergMarquardt::minimizeOptimumStorageInit(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const int mode
         )
 {
@@ -499,7 +501,7 @@ LevenbergMarquardt::minimizeOptimumStorageInit(
 template
 typename LevenbergMarquardt::Status
 LevenbergMarquardt::minimizeOptimumStorageOneStep(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const int mode
         )
 {
@@ -708,7 +710,7 @@ LevenbergMarquardt::minimizeOptimumStorageOneStep(
 template
 typename LevenbergMarquardt::Status
 LevenbergMarquardt::minimizeOptimumStorage(
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         const int mode
         )
 {
@@ -722,7 +724,7 @@ template
 typename LevenbergMarquardt::Status
 LevenbergMarquardt::lmdif1(
         FunctorType &functor,
-        Matrix< Scalar, Dynamic, 1 >  &x,
+        FVectorType  &x,
         int *nfev,
         const Scalar tol
         )
-- 
cgit v1.2.3


From f795681da0fec9cd8a56f6987c903ec9a530d509 Mon Sep 17 00:00:00 2001
From: Thomas Capricelli 
Date: Thu, 26 Nov 2009 02:28:13 +0100
Subject: export stableNorm(), blueNorm() and hypotNorm() to colwise() and
 rowwise() + rudimentary test

---
 Eigen/src/Array/VectorwiseOp.h | 30 ++++++++++++++++++++++++++++++
 test/stable_norm.cpp           |  8 ++++++++
 2 files changed, 38 insertions(+)

diff --git a/Eigen/src/Array/VectorwiseOp.h b/Eigen/src/Array/VectorwiseOp.h
index 880567212..7193e6f68 100644
--- a/Eigen/src/Array/VectorwiseOp.h
+++ b/Eigen/src/Array/VectorwiseOp.h
@@ -121,6 +121,9 @@ class PartialReduxExpr : ei_no_assignment_operator,
 
 EIGEN_MEMBER_FUNCTOR(squaredNorm, Size * NumTraits::MulCost + (Size-1)*NumTraits::AddCost);
 EIGEN_MEMBER_FUNCTOR(norm, (Size+5) * NumTraits::MulCost + (Size-1)*NumTraits::AddCost);
+EIGEN_MEMBER_FUNCTOR(stableNorm, (Size+5) * NumTraits::MulCost + (Size-1)*NumTraits::AddCost);
+EIGEN_MEMBER_FUNCTOR(blueNorm, (Size+5) * NumTraits::MulCost + (Size-1)*NumTraits::AddCost);
+EIGEN_MEMBER_FUNCTOR(hypotNorm, (Size-1) * ei_functor_traits >::Cost );
 EIGEN_MEMBER_FUNCTOR(sum, (Size-1)*NumTraits::AddCost);
 EIGEN_MEMBER_FUNCTOR(mean, (Size-1)*NumTraits::AddCost + NumTraits::MulCost);
 EIGEN_MEMBER_FUNCTOR(minCoeff, (Size-1)*NumTraits::AddCost);
@@ -288,6 +291,33 @@ template class VectorwiseOp
     const typename ReturnType::Type norm() const
     { return _expression(); }
 
+
+    /** \returns a row (or column) vector expression of the norm
+      * of each column (or row) of the referenced expression, using
+      * blue's algorithm.
+      *
+      * \sa MatrixBase::blueNorm() */
+    const typename ReturnType::Type blueNorm() const
+    { return _expression(); }
+
+
+    /** \returns a row (or column) vector expression of the norm
+      * of each column (or row) of the referenced expression, avoiding
+      * underflow and overflow.
+      *
+      * \sa MatrixBase::stableNorm() */
+    const typename ReturnType::Type stableNorm() const
+    { return _expression(); }
+
+
+    /** \returns a row (or column) vector expression of the norm
+      * of each column (or row) of the referenced expression, avoiding
+      * underflow and overflow using a concatenation of hypot() calls.
+      *
+      * \sa MatrixBase::hypotNorm() */
+    const typename ReturnType::Type hypotNorm() const
+    { return _expression(); }
+
     /** \returns a row (or column) vector expression of the sum
       * of each column (or row) of the referenced expression.
       *
diff --git a/test/stable_norm.cpp b/test/stable_norm.cpp
index 7661fc893..10531dc5d 100644
--- a/test/stable_norm.cpp
+++ b/test/stable_norm.cpp
@@ -79,6 +79,14 @@ template void stable_norm(const MatrixType& m)
   VERIFY_IS_APPROX(static_cast(vsmall.stableNorm()), ei_sqrt(size)*small);
   VERIFY_IS_APPROX(static_cast(vsmall.blueNorm()),   ei_sqrt(size)*small);
   VERIFY_IS_APPROX(static_cast(vsmall.hypotNorm()),  ei_sqrt(size)*small);
+
+// Test compilation of cwise() version
+  VERIFY_IS_APPROX(vrand.colwise().stableNorm(),      vrand.colwise().norm());
+  VERIFY_IS_APPROX(vrand.colwise().blueNorm(),        vrand.colwise().norm());
+  VERIFY_IS_APPROX(vrand.colwise().hypotNorm(),       vrand.colwise().norm());
+  VERIFY_IS_APPROX(vrand.rowwise().stableNorm(),      vrand.rowwise().norm());
+  VERIFY_IS_APPROX(vrand.rowwise().blueNorm(),        vrand.rowwise().norm());
+  VERIFY_IS_APPROX(vrand.rowwise().hypotNorm(),       vrand.rowwise().norm());
 }
 
 void test_stable_norm()
-- 
cgit v1.2.3


From 9cbfdbad220ccb1d1a9a49d70474336ece971e67 Mon Sep 17 00:00:00 2001
From: Thomas Capricelli 
Date: Thu, 26 Nov 2009 02:42:27 +0100
Subject: cleaning

---
 .../Eigen/src/NonLinearOptimization/r1mpyq.h       | 37 +++-------------------
 1 file changed, 5 insertions(+), 32 deletions(-)

diff --git a/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h b/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h
index a06072a54..70a6d30c3 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h
@@ -18,28 +18,18 @@ void ei_r1mpyq(int m, int n, Scalar *a, int
     a -= a_offset;
 
     /* Function Body */
-
-    /*     apply the first set of givens rotations to a. */
-
     nm1 = n - 1;
-    if (nm1 < 1) {
-        /* goto L50; */
+    if (nm1 < 1)
         return;
-    }
+
+    /*     apply the first set of givens rotations to a. */
     for (nmj = 1; nmj <= nm1; ++nmj) {
         j = n - nmj;
         if (ei_abs(v[j]) > 1.) {
             cos__ = 1. / v[j];
-        }
-        if (ei_abs(v[j]) > 1.) {
-            /* Computing 2nd power */
             sin__ = ei_sqrt(1. - ei_abs2(cos__));
-        }
-        if (ei_abs(v[j]) <= 1.) {
+        } else  {
             sin__ = v[j];
-        }
-        if (ei_abs(v[j]) <= 1.) {
-            /* Computing 2nd power */
             cos__ = ei_sqrt(1. - ei_abs2(sin__));
         }
         for (i = 1; i <= m; ++i) {
@@ -47,26 +37,15 @@ void ei_r1mpyq(int m, int n, Scalar *a, int
             a[i + n * a_dim1] = sin__ * a[i + j * a_dim1] + cos__ * a[
                 i + n * a_dim1];
             a[i + j * a_dim1] = temp;
-            /* L10: */
         }
-        /* L20: */
     }
-
     /*     apply the second set of givens rotations to a. */
-
     for (j = 1; j <= nm1; ++j) {
         if (ei_abs(w[j]) > 1.) {
             cos__ = 1. / w[j];
-        }
-        if (ei_abs(w[j]) > 1.) {
-            /* Computing 2nd power */
             sin__ = ei_sqrt(1. - ei_abs2(cos__));
-        }
-        if (ei_abs(w[j]) <= 1.) {
+        } else  {
             sin__ = w[j];
-        }
-        if (ei_abs(w[j]) <= 1.) {
-            /* Computing 2nd power */
             cos__ = ei_sqrt(1. - ei_abs2(sin__));
         }
         for (i = 1; i <= m; ++i) {
@@ -74,14 +53,8 @@ void ei_r1mpyq(int m, int n, Scalar *a, int
             a[i + n * a_dim1] = -sin__ * a[i + j * a_dim1] + cos__ * a[
                 i + n * a_dim1];
             a[i + j * a_dim1] = temp;
-            /* L30: */
         }
-        /* L40: */
     }
-    /* L50: */
     return;
-
-    /*     last card of subroutine r1mpyq. */
-
 } /* r1mpyq_ */
 
-- 
cgit v1.2.3


From 746c787a763ed8be1bbba1e42310d8b968feacd0 Mon Sep 17 00:00:00 2001
From: Thomas Capricelli 
Date: Thu, 26 Nov 2009 02:53:58 +0100
Subject: computes column norms outside of ei_qrfac()

---
 .../NonLinearOptimization/HybridNonLinearSolver.h  | 42 ++++++++++------------
 .../src/NonLinearOptimization/LevenbergMarquardt.h | 10 +++---
 .../Eigen/src/NonLinearOptimization/qrfac.h        | 11 ++----
 3 files changed, 27 insertions(+), 36 deletions(-)

diff --git a/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h b/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
index 6269a3d89..b2e297741 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
@@ -226,15 +226,11 @@ HybridNonLinearSolver::solveOneStep(
         return UserAksed;
     ++njev;
 
-    /* compute the qr factorization of the jacobian. */
-
-    ei_qrfac(n, n, fjac.data(), fjac.rows(), false, iwa, wa1.data(), wa2.data());
-
+    wa2 = fjac.colwise().blueNorm();
 
+    /* on the first iteration and if mode is 1, scale according */
+    /* to the norms of the columns of the initial jacobian. */
     if (iter == 1) {
-
-        /* on the first iteration and if mode is 1, scale according */
-        /* to the norms of the columns of the initial jacobian. */
         if (mode != 2)
             for (j = 0; j < n; ++j) {
                 diag[j] = wa2[j];
@@ -251,6 +247,9 @@ HybridNonLinearSolver::solveOneStep(
             delta = parameters.factor;
     }
 
+    /* compute the qr factorization of the jacobian. */
+    ei_qrfac(n, n, fjac.data(), fjac.rows(), false, iwa, wa1.data());
+
     /* form (q transpose)*fvec and store in qtf. */
 
     qtf = fvec;
@@ -269,18 +268,16 @@ HybridNonLinearSolver::solveOneStep(
     sing = false;
     for (j = 0; j < n; ++j) {
         l = j;
-        if (j)
-            for (i = 0; i < j; ++i) {
-                R[l] = fjac(i,j);
-                l = l + n - i -1;
-            }
+        for (i = 0; i < j; ++i) {
+            R[l] = fjac(i,j);
+            l = l + n - i -1;
+        }
         R[l] = wa1[j];
         if (wa1[j] == 0.)
             sing = true;
     }
 
     /* accumulate the orthogonal factor in fjac. */
-
     ei_qform(n, n, fjac.data(), fjac.rows(), wa1.data());
 
     /* rescale if necessary. */
@@ -543,13 +540,10 @@ HybridNonLinearSolver::solveNumericalDiffOneStep(
         return UserAksed;
     nfev += std::min(parameters.nb_of_subdiagonals+parameters.nb_of_superdiagonals+ 1, n);
 
-    /* compute the qr factorization of the jacobian. */
-
-    ei_qrfac(n, n, fjac.data(), fjac.rows(), false, iwa, wa1.data(), wa2.data());
+    wa2 = fjac.colwise().blueNorm();
 
     /* on the first iteration and if mode is 1, scale according */
     /* to the norms of the columns of the initial jacobian. */
-
     if (iter == 1) {
         if (mode != 2)
             for (j = 0; j < n; ++j) {
@@ -560,7 +554,6 @@ HybridNonLinearSolver::solveNumericalDiffOneStep(
 
         /* on the first iteration, calculate the norm of the scaled x */
         /* and initialize the step bound delta. */
-
         wa3 = diag.cwise() * x;
         xnorm = wa3.stableNorm();
         delta = parameters.factor * xnorm;
@@ -568,6 +561,9 @@ HybridNonLinearSolver::solveNumericalDiffOneStep(
             delta = parameters.factor;
     }
 
+    /* compute the qr factorization of the jacobian. */
+    ei_qrfac(n, n, fjac.data(), fjac.rows(), false, iwa, wa1.data());
+
     /* form (q transpose)*fvec and store in qtf. */
 
     qtf = fvec;
@@ -586,18 +582,16 @@ HybridNonLinearSolver::solveNumericalDiffOneStep(
     sing = false;
     for (j = 0; j < n; ++j) {
         l = j;
-        if (j)
-            for (i = 0; i < j; ++i) {
-                R[l] = fjac(i,j);
-                l = l + n - i -1;
-            }
+        for (i = 0; i < j; ++i) {
+            R[l] = fjac(i,j);
+            l = l + n - i -1;
+        }
         R[l] = wa1[j];
         if (wa1[j] == 0.)
             sing = true;
     }
 
     /* accumulate the orthogonal factor in fjac. */
-
     ei_qform(n, n, fjac.data(), fjac.rows(), wa1.data());
 
     /* rescale if necessary. */
diff --git a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
index 1a2a69561..c611ec595 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
@@ -248,8 +248,9 @@ LevenbergMarquardt::minimizeOneStep(
 
     /* compute the qr factorization of the jacobian. */
 
-    ei_qrfac(m, n, fjac.data(), fjac.rows(), true, ipvt.data(), wa1.data(), wa2.data());
-    ipvt.cwise()-=1; // qrfac() creates ipvt with fortran convetion (1->n), convert it to c (0->n-1)
+    wa2 = fjac.colwise().blueNorm();
+    ei_qrfac(m, n, fjac.data(), fjac.rows(), true, ipvt.data(), wa1.data());
+    ipvt.cwise()-=1; // qrfac() creates ipvt with fortran convention (1->n), convert it to c (0->n-1)
 
     /* on the first iteration and if mode is 1, scale according */
     /* to the norms of the columns of the initial jacobian. */
@@ -537,8 +538,9 @@ LevenbergMarquardt::minimizeOptimumStorageOneStep(
     }
     if (sing) {
         ipvt.cwise()+=1;
-        ei_qrfac(n, n, fjac.data(), fjac.rows(), true, ipvt.data(), wa1.data(), wa2.data());
-        ipvt.cwise()-=1; // qrfac() creates ipvt with fortran convetion (1->n), convert it to c (0->n-1)
+        wa2 = fjac.colwise().blueNorm();
+        ei_qrfac(n, n, fjac.data(), fjac.rows(), true, ipvt.data(), wa1.data());
+        ipvt.cwise()-=1; // qrfac() creates ipvt with fortran convention (1->n), convert it to c (0->n-1)
         for (j = 0; j < n; ++j) {
             if (fjac(j,j) != 0.) {
                 sum = 0.;
diff --git a/unsupported/Eigen/src/NonLinearOptimization/qrfac.h b/unsupported/Eigen/src/NonLinearOptimization/qrfac.h
index 481fe57d8..0c1ecf394 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/qrfac.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/qrfac.h
@@ -1,8 +1,7 @@
 
 template 
 void ei_qrfac(int m, int n, Scalar *a, int
-        lda, int pivot, int *ipvt, Scalar *rdiag,
-        Scalar *acnorm)
+        lda, int pivot, int *ipvt, Scalar *rdiag)
 {
     /* System generated locals */
     int a_dim1, a_offset;
@@ -18,7 +17,6 @@ void ei_qrfac(int m, int n, Scalar *a, int
     Matrix< Scalar, Dynamic, 1 > wa(n+1);
 
     /* Parameter adjustments */
-    --acnorm;
     --rdiag;
     a_dim1 = lda;
     a_offset = 1 + a_dim1 * 1;
@@ -31,13 +29,10 @@ void ei_qrfac(int m, int n, Scalar *a, int
     /*     compute the initial column norms and initialize several arrays. */
 
     for (j = 1; j <= n; ++j) {
-        acnorm[j] = Map< Matrix< Scalar, Dynamic, 1 > >(&a[j * a_dim1 + 1],m).blueNorm();
-        rdiag[j] = acnorm[j];
+        rdiag[j] = Map< Matrix< Scalar, Dynamic, 1 > >(&a[j * a_dim1 + 1],m).blueNorm();
         wa[j] = rdiag[j];
-        if (pivot) {
+        if (pivot)
             ipvt[j] = j;
-        }
-        /* L10: */
     }
 
     /*     reduce a to r with householder transformations. */
-- 
cgit v1.2.3


From 5923bcb1b94cd5a79dfc57f2ffe6271d999ea67d Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Wed, 25 Nov 2009 21:26:37 -0500
Subject: improve the scripts for building unit tests: * support unsupported/ *
 use egrep instead of grep, properly escape special chars.

---
 CMakeLists.txt                     |  4 ++++
 cmake/EigenTesting.cmake           |  7 ++++++-
 scripts/CMakeLists.txt             |  3 +++
 scripts/buildtests.in              | 24 ++++++++++++++++++++++++
 scripts/check.in                   |  4 ++--
 signature_of_eigen3_matrix_library |  2 +-
 test/CMakeLists.txt                |  6 ------
 test/buildtests.in                 | 23 -----------------------
 unsupported/test/CMakeLists.txt    |  5 -----
 9 files changed, 40 insertions(+), 38 deletions(-)
 create mode 100755 scripts/buildtests.in
 delete mode 100755 test/buildtests.in

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 33e7584c4..10c72ab38 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -152,6 +152,9 @@ add_subdirectory(doc EXCLUDE_FROM_ALL)
 
 include(CTest)
 enable_testing() # must be called from the root CMakeLists, see man page
+include(EigenTesting)
+ei_init_testing()
+
 if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)
   add_subdirectory(test) # can't do EXCLUDE_FROM_ALL here, breaks CTest
 else()
@@ -164,6 +167,7 @@ add_subdirectory(demos EXCLUDE_FROM_ALL)
 
 add_subdirectory(blas EXCLUDE_FROM_ALL)
 
+# must be after test and unsupported, for configuring buildtests.in
 add_subdirectory(scripts EXCLUDE_FROM_ALL)
 
 # TODO: consider also replacing EIGEN_BUILD_BTL by a custom target "make btl"?
diff --git a/cmake/EigenTesting.cmake b/cmake/EigenTesting.cmake
index 43ae53cc1..ce567abc3 100644
--- a/cmake/EigenTesting.cmake
+++ b/cmake/EigenTesting.cmake
@@ -107,7 +107,10 @@ endmacro(ei_add_test_internal)
 #
 # Again, ctest -R allows to run all matching tests.
 macro(ei_add_test testname)
-  set(cmake_tests_list "${cmake_tests_list}${testname}\n")
+  get_property(EIGEN_TESTS_LIST GLOBAL PROPERTY EIGEN_TESTS_LIST)
+  set(EIGEN_TESTS_LIST "${EIGEN_TESTS_LIST}${testname}\n")
+  set_property(GLOBAL PROPERTY EIGEN_TESTS_LIST "${EIGEN_TESTS_LIST}")
+
   file(READ "${testname}.cpp" test_source)
   set(parts 0)
   string(REGEX MATCHALL "CALL_SUBTEST_[0-9]+|EIGEN_TEST_PART_[0-9]+"
@@ -204,10 +207,12 @@ macro(ei_init_testing)
   define_property(GLOBAL PROPERTY EIGEN_TESTED_BACKENDS BRIEF_DOCS " " FULL_DOCS " ")
   define_property(GLOBAL PROPERTY EIGEN_MISSING_BACKENDS BRIEF_DOCS " " FULL_DOCS " ")
   define_property(GLOBAL PROPERTY EIGEN_TESTING_SUMMARY BRIEF_DOCS " " FULL_DOCS " ")
+  define_property(GLOBAL PROPERTY EIGEN_TESTS_LIST BRIEF_DOCS " " FULL_DOCS " ")
 
   set_property(GLOBAL PROPERTY EIGEN_TESTED_BACKENDS "")
   set_property(GLOBAL PROPERTY EIGEN_MISSING_BACKENDS "")
   set_property(GLOBAL PROPERTY EIGEN_TESTING_SUMMARY "")
+  set_property(GLOBAL PROPERTY EIGEN_TESTS_LIST "")
 endmacro(ei_init_testing)
 
 if(CMAKE_COMPILER_IS_GNUCXX)
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
index b75e99d5e..acf3bb6e9 100644
--- a/scripts/CMakeLists.txt
+++ b/scripts/CMakeLists.txt
@@ -1,3 +1,6 @@
+get_property(EIGEN_TESTS_LIST GLOBAL PROPERTY EIGEN_TESTS_LIST)
+configure_file(buildtests.in ${CMAKE_BINARY_DIR}/buildtests)
+
 configure_file(check.in ${CMAKE_BINARY_DIR}/check)
 configure_file(debug.in ${CMAKE_BINARY_DIR}/debug)
 configure_file(release.in ${CMAKE_BINARY_DIR}/release)
diff --git a/scripts/buildtests.in b/scripts/buildtests.in
new file mode 100755
index 000000000..1cc8e956f
--- /dev/null
+++ b/scripts/buildtests.in
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+if [ $# == 0 -o $# -ge 3 ]
+then
+  echo "usage: ./buildtests regexp [jobs]"
+  echo "  makes tests matching the regexp, with [jobs] concurrent make jobs"
+  exit 0
+fi
+
+TESTSLIST="${EIGEN_TESTS_LIST}"
+
+targets_to_make=`echo "$TESTSLIST" | egrep "$1" | sed s/^/test_/g | xargs echo`
+
+if [ $# == 1 ]
+then
+  make $targets_to_make
+  exit $?
+fi
+
+if [ $# == 2 ]
+then
+  make -j $2 $targets_to_make
+  exit $?
+fi
diff --git a/scripts/check.in b/scripts/check.in
index 2a862fd80..ff3c96441 100755
--- a/scripts/check.in
+++ b/scripts/check.in
@@ -4,9 +4,9 @@
 if [ $# == 0 -o $# -ge 3 ]
 then
   echo "usage: ./check regexp [jobs]"
-  echo "  makes and runs tests matching the regexp, with  concurrent make jobs"
+  echo "  makes and runs tests matching the regexp, with [jobs] concurrent make jobs"
   exit 0
 fi
 
 # TODO when ctest 2.8 comes out, honor the jobs parameter
-./buildtests $* && ctest -R $1
\ No newline at end of file
+./buildtests "$1" "$2" && ctest -R "$1"
diff --git a/signature_of_eigen3_matrix_library b/signature_of_eigen3_matrix_library
index 477732ef4..80aaf4621 100644
--- a/signature_of_eigen3_matrix_library
+++ b/signature_of_eigen3_matrix_library
@@ -1 +1 @@
-This file is just there as a signature to help identify directories containing Eigen3. When writing for a script looking for Eigen3, just look for this file. This is especially useful to help disambiguate with Eigen2...
+This file is just there as a signature to help identify directories containing Eigen3. When writing a script looking for Eigen3, just look for this file. This is especially useful to help disambiguate with Eigen2...
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index c91ec328b..ffe89915a 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -3,10 +3,6 @@ add_custom_target(buildtests)
 add_custom_target(check COMMAND "ctest")
 add_dependencies(check buildtests)
 
-
-include(EigenTesting)
-ei_init_testing()
-
 option(EIGEN_SPLIT_LARGE_TESTS "Split large tests into smaller executables" ON)
 
 find_package(GSL)
@@ -169,5 +165,3 @@ if(CMAKE_COMPILER_IS_GNUCXX)
 endif(CMAKE_COMPILER_IS_GNUCXX)
 ei_add_property(EIGEN_TESTING_SUMMARY "CXX_FLAGS:         ${CMAKE_CXX_FLAGS}\n")
 ei_add_property(EIGEN_TESTING_SUMMARY "Sparse lib flags:  ${SPARSE_LIBS}\n")
-
-configure_file(buildtests.in ${CMAKE_BINARY_DIR}/buildtests)
diff --git a/test/buildtests.in b/test/buildtests.in
deleted file mode 100755
index c24234930..000000000
--- a/test/buildtests.in
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-
-if [ $# == 0 -o $# -ge 3 ]
-then
-  echo "usage: ./buildtests regexp [jobs]"
-  echo "  makes tests matching the regexp, with  concurrent make jobs"
-  exit 0
-fi
-
-TESTSLIST="${cmake_tests_list}"
-targets_to_make=`echo "$TESTSLIST" | grep "$1" | sed s/^/test_/g | xargs echo`
-
-if [ $# == 1 ]
-then
-  make $targets_to_make
-  exit $?
-fi
-
-if [ $# == 2 ]
-then
-  make -j $2 $targets_to_make
-  exit $?
-fi
diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt
index 057c2026e..58af79351 100644
--- a/unsupported/test/CMakeLists.txt
+++ b/unsupported/test/CMakeLists.txt
@@ -1,8 +1,3 @@
-
-include(EigenTesting)
-
-enable_testing()
-
 find_package(Adolc)
 
 include_directories(../../test)
-- 
cgit v1.2.3


From e95f736402958e9fef27977d35389ef134f7e73d Mon Sep 17 00:00:00 2001
From: Thomas Capricelli 
Date: Thu, 26 Nov 2009 03:26:41 +0100
Subject: reduce ei_qrsolv() signature, wa is actually a 'working array'

---
 unsupported/Eigen/src/NonLinearOptimization/lmpar.h  | 2 +-
 unsupported/Eigen/src/NonLinearOptimization/qrsolv.h | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/unsupported/Eigen/src/NonLinearOptimization/lmpar.h b/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
index c62881c81..ef1b64083 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
@@ -123,7 +123,7 @@ void ei_lmpar(
         wa1 = temp * diag;
 
         ipvt.cwise()+=1; // qrsolv() expects the fortran convention (as qrfac provides)
-        ei_qrsolv(n, r.data(), r.rows(), ipvt.data(), wa1.data(), qtb.data(), x.data(), sdiag.data(), wa2.data());
+        ei_qrsolv(n, r.data(), r.rows(), ipvt.data(), wa1.data(), qtb.data(), x.data(), sdiag.data());
         ipvt.cwise()-=1;
 
         wa2 = diag.cwise() * x;
diff --git a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
index 57884870c..cbb45107a 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
@@ -1,8 +1,8 @@
 
-    template 
+template 
 void ei_qrsolv(int n, Scalar *r__, int ldr, 
         const int *ipvt, const Scalar *diag, const Scalar *qtb, Scalar *x, 
-        Scalar *sdiag, Scalar *wa)
+        Scalar *sdiag)
 {
     /* System generated locals */
     int r_dim1, r_offset;
@@ -12,9 +12,9 @@ void ei_qrsolv(int n, Scalar *r__, int ldr,
     Scalar tan__, cos__, sin__, sum, temp, cotan;
     int nsing;
     Scalar qtbpj;
+    Matrix< Scalar, Dynamic, 1 >  wa(n+1);
 
     /* Parameter adjustments */
-    --wa;
     --sdiag;
     --x;
     --qtb;
-- 
cgit v1.2.3


From e18caf7a01db6b856f8ad4a798fb886bfcbefc32 Mon Sep 17 00:00:00 2001
From: Thomas Capricelli 
Date: Thu, 26 Nov 2009 04:06:40 +0100
Subject: clean qrsolv

---
 .../Eigen/src/NonLinearOptimization/qrsolv.h       | 100 ++++++---------------
 1 file changed, 29 insertions(+), 71 deletions(-)

diff --git a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
index cbb45107a..77786636c 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
@@ -8,7 +8,7 @@ void ei_qrsolv(int n, Scalar *r__, int ldr,
     int r_dim1, r_offset;
 
     /* Local variables */
-    int i, j, k, l, jp1, kp1;
+    int i, j, k, l;
     Scalar tan__, cos__, sin__, sum, temp, cotan;
     int nsing;
     Scalar qtbpj;
@@ -30,13 +30,10 @@ void ei_qrsolv(int n, Scalar *r__, int ldr,
     /*     in particular, save the diagonal elements of r in x. */
 
     for (j = 1; j <= n; ++j) {
-        for (i = j; i <= n; ++i) {
+        for (i = j; i <= n; ++i)
             r__[i + j * r_dim1] = r__[j + i * r_dim1];
-            /* L10: */
-        }
         x[j] = r__[j + j * r_dim1];
         wa[j] = qtb[j];
-        /* L20: */
     }
 
     /*     eliminate the diagonal matrix d using a givens rotation. */
@@ -47,13 +44,10 @@ void ei_qrsolv(int n, Scalar *r__, int ldr,
         /*        diagonal element using p from the qr factorization. */
 
         l = ipvt[j];
-        if (diag[l] == 0.) {
+        if (diag[l] == 0.)
             goto L90;
-        }
-        for (k = j; k <= n; ++k) {
+        for (k = j; k <= n; ++k)
             sdiag[k] = 0.;
-            /* L30: */
-        }
         sdiag[j] = diag[l];
 
         /*        the transformations to eliminate the row of d */
@@ -62,25 +56,21 @@ void ei_qrsolv(int n, Scalar *r__, int ldr,
 
         qtbpj = 0.;
         for (k = j; k <= n; ++k) {
-
             /*           determine a givens rotation which eliminates the */
             /*           appropriate element in the current row of d. */
-
             if (sdiag[k] == 0.)
-                goto L70;
-            if ( ei_abs(r__[k + k * r_dim1]) >= ei_abs(sdiag[k]))
-                goto L40;
-            cotan = r__[k + k * r_dim1] / sdiag[k];
-            /* Computing 2nd power */
-            sin__ = Scalar(.5) / ei_sqrt(Scalar(0.25) + Scalar(0.25) * ei_abs2(cotan));
-            cos__ = sin__ * cotan;
-            goto L50;
-L40:
-            tan__ = sdiag[k] / r__[k + k * r_dim1];
-            /* Computing 2nd power */
-            cos__ = Scalar(.5) / ei_sqrt(Scalar(0.25) + Scalar(0.25) * ei_abs2(tan__));
-            sin__ = cos__ * tan__;
-L50:
+                continue;
+            if ( ei_abs(r__[k + k * r_dim1]) < ei_abs(sdiag[k])) {
+                cotan = r__[k + k * r_dim1] / sdiag[k];
+                /* Computing 2nd power */
+                sin__ = Scalar(.5) / ei_sqrt(Scalar(0.25) + Scalar(0.25) * ei_abs2(cotan));
+                cos__ = sin__ * cotan;
+            } else {
+                tan__ = sdiag[k] / r__[k + k * r_dim1];
+                /* Computing 2nd power */
+                cos__ = Scalar(.5) / ei_sqrt(Scalar(0.25) + Scalar(0.25) * ei_abs2(tan__));
+                sin__ = cos__ * tan__;
+            }
 
             /*           compute the modified diagonal element of r and */
             /*           the modified element of ((q transpose)*b,0). */
@@ -92,21 +82,11 @@ L50:
             wa[k] = temp;
 
             /*           accumulate the tranformation in the row of s. */
-
-            kp1 = k + 1;
-            if (n < kp1) {
-                goto L70;
-            }
-            for (i = kp1; i <= n; ++i) {
+            for (i = k+1; i <= n; ++i) {
                 temp = cos__ * r__[i + k * r_dim1] + sin__ * sdiag[i];
-                sdiag[i] = -sin__ * r__[i + k * r_dim1] + cos__ * sdiag[
-                    i];
+                sdiag[i] = -sin__ * r__[i + k * r_dim1] + cos__ * sdiag[i];
                 r__[i + k * r_dim1] = temp;
-                /* L60: */
             }
-L70:
-            /* L80: */
-            ;
         }
 L90:
 
@@ -115,7 +95,6 @@ L90:
 
         sdiag[j] = r__[j + j * r_dim1];
         r__[j + j * r_dim1] = x[j];
-        /* L100: */
     }
 
     /*     solve the triangular system for z. if the system is */
@@ -123,44 +102,23 @@ L90:
 
     nsing = n;
     for (j = 1; j <= n; ++j) {
-        if (sdiag[j] == 0. && nsing == n) {
-            nsing = j - 1;
-        }
-        if (nsing < n) {
-            wa[j] = 0.;
-        }
-        /* L110: */
+        if (sdiag[j] == 0. && nsing == n) nsing = j - 1;
+        if (nsing < n) wa[j] = 0.;
     }
-    if (nsing < 1) {
-        goto L150;
-    }
-    for (k = 1; k <= nsing; ++k) {
-        j = nsing - k + 1;
-        sum = 0.;
-        jp1 = j + 1;
-        if (nsing < jp1) {
-            goto L130;
-        }
-        for (i = jp1; i <= nsing; ++i) {
-            sum += r__[i + j * r_dim1] * wa[i];
-            /* L120: */
+    if (nsing >= 1)
+        for (k = 1; k <= nsing; ++k) {
+            j = nsing - k + 1;
+            sum = 0.;
+            if (nsing>j)
+                for (i = j+1; i <= nsing; ++i)
+                    sum += r__[i + j * r_dim1] * wa[i];
+            wa[j] = (wa[j] - sum) / sdiag[j];
         }
-L130:
-        wa[j] = (wa[j] - sum) / sdiag[j];
-        /* L140: */
-    }
-L150:
 
     /*     permute the components of z back to components of x. */
-
     for (j = 1; j <= n; ++j) {
         l = ipvt[j];
         x[l] = wa[j];
-        /* L160: */
     }
-    return;
-
-    /*     last card of subroutine qrsolv. */
-
-} /* qrsolv_ */
+}
 
-- 
cgit v1.2.3


From 905aecf803341a88046861e6596fc8de8220aacc Mon Sep 17 00:00:00 2001
From: Thomas Capricelli 
Date: Thu, 26 Nov 2009 04:29:51 +0100
Subject: make qrsolv use eigen types

---
 .../Eigen/src/NonLinearOptimization/lmpar.h        |  4 +-
 .../Eigen/src/NonLinearOptimization/qrsolv.h       | 94 +++++++++++-----------
 2 files changed, 46 insertions(+), 52 deletions(-)

diff --git a/unsupported/Eigen/src/NonLinearOptimization/lmpar.h b/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
index ef1b64083..c1ab2626c 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
@@ -122,9 +122,7 @@ void ei_lmpar(
         temp = ei_sqrt(par);
         wa1 = temp * diag;
 
-        ipvt.cwise()+=1; // qrsolv() expects the fortran convention (as qrfac provides)
-        ei_qrsolv(n, r.data(), r.rows(), ipvt.data(), wa1.data(), qtb.data(), x.data(), sdiag.data());
-        ipvt.cwise()-=1;
+        ei_qrsolv(r, ipvt, wa1, qtb, x, sdiag);
 
         wa2 = diag.cwise() * x;
         dxnorm = wa2.blueNorm();
diff --git a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
index 77786636c..adfa2be50 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
@@ -1,44 +1,43 @@
 
-template 
-void ei_qrsolv(int n, Scalar *r__, int ldr, 
+#if 0
+        int n, Scalar *r__, int ldr, 
         const int *ipvt, const Scalar *diag, const Scalar *qtb, Scalar *x, 
         Scalar *sdiag)
-{
-    /* System generated locals */
-    int r_dim1, r_offset;
+#endif
+
+
+template 
+void ei_qrsolv(
+        Matrix< Scalar, Dynamic, Dynamic > &r,
+        VectorXi &ipvt, // TODO : const once ipvt mess fixed
+        const Matrix< Scalar, Dynamic, 1 >  &diag,
+        const Matrix< Scalar, Dynamic, 1 >  &qtb,
+        Matrix< Scalar, Dynamic, 1 >  &x,
+        Matrix< Scalar, Dynamic, 1 >  &sdiag)
 
+{
     /* Local variables */
     int i, j, k, l;
     Scalar tan__, cos__, sin__, sum, temp, cotan;
     int nsing;
     Scalar qtbpj;
-    Matrix< Scalar, Dynamic, 1 >  wa(n+1);
-
-    /* Parameter adjustments */
-    --sdiag;
-    --x;
-    --qtb;
-    --diag;
-    --ipvt;
-    r_dim1 = ldr;
-    r_offset = 1 + r_dim1 * 1;
-    r__ -= r_offset;
+    int n = r.cols();
+    Matrix< Scalar, Dynamic, 1 >  wa(n);
 
     /* Function Body */
 
     /*     copy r and (q transpose)*b to preserve input and initialize s. */
     /*     in particular, save the diagonal elements of r in x. */
 
-    for (j = 1; j <= n; ++j) {
-        for (i = j; i <= n; ++i)
-            r__[i + j * r_dim1] = r__[j + i * r_dim1];
-        x[j] = r__[j + j * r_dim1];
+    for (j = 0; j < n; ++j) {
+        for (i = j; i < n; ++i)
+            r(i,j) = r(j,i);
+        x[j] = r(j,j);
         wa[j] = qtb[j];
     }
 
     /*     eliminate the diagonal matrix d using a givens rotation. */
-
-    for (j = 1; j <= n; ++j) {
+    for (j = 0; j < n; ++j) {
 
         /*        prepare the row of d to be eliminated, locating the */
         /*        diagonal element using p from the qr factorization. */
@@ -46,7 +45,7 @@ void ei_qrsolv(int n, Scalar *r__, int ldr,
         l = ipvt[j];
         if (diag[l] == 0.)
             goto L90;
-        for (k = j; k <= n; ++k)
+        for (k = j; k < n; ++k)
             sdiag[k] = 0.;
         sdiag[j] = diag[l];
 
@@ -55,18 +54,18 @@ void ei_qrsolv(int n, Scalar *r__, int ldr,
         /*        beyond the first n, which is initially zero. */
 
         qtbpj = 0.;
-        for (k = j; k <= n; ++k) {
+        for (k = j; k < n; ++k) {
             /*           determine a givens rotation which eliminates the */
             /*           appropriate element in the current row of d. */
             if (sdiag[k] == 0.)
                 continue;
-            if ( ei_abs(r__[k + k * r_dim1]) < ei_abs(sdiag[k])) {
-                cotan = r__[k + k * r_dim1] / sdiag[k];
+            if ( ei_abs(r(k,k)) < ei_abs(sdiag[k])) {
+                cotan = r(k,k) / sdiag[k];
                 /* Computing 2nd power */
                 sin__ = Scalar(.5) / ei_sqrt(Scalar(0.25) + Scalar(0.25) * ei_abs2(cotan));
                 cos__ = sin__ * cotan;
             } else {
-                tan__ = sdiag[k] / r__[k + k * r_dim1];
+                tan__ = sdiag[k] / r(k,k);
                 /* Computing 2nd power */
                 cos__ = Scalar(.5) / ei_sqrt(Scalar(0.25) + Scalar(0.25) * ei_abs2(tan__));
                 sin__ = cos__ * tan__;
@@ -75,17 +74,16 @@ void ei_qrsolv(int n, Scalar *r__, int ldr,
             /*           compute the modified diagonal element of r and */
             /*           the modified element of ((q transpose)*b,0). */
 
-            r__[k + k * r_dim1] = cos__ * r__[k + k * r_dim1] + sin__ * sdiag[
-                k];
+            r(k,k) = cos__ * r(k,k) + sin__ * sdiag[k];
             temp = cos__ * wa[k] + sin__ * qtbpj;
             qtbpj = -sin__ * wa[k] + cos__ * qtbpj;
             wa[k] = temp;
 
             /*           accumulate the tranformation in the row of s. */
-            for (i = k+1; i <= n; ++i) {
-                temp = cos__ * r__[i + k * r_dim1] + sin__ * sdiag[i];
-                sdiag[i] = -sin__ * r__[i + k * r_dim1] + cos__ * sdiag[i];
-                r__[i + k * r_dim1] = temp;
+            for (i = k+1; i= 1)
-        for (k = 1; k <= nsing; ++k) {
-            j = nsing - k + 1;
-            sum = 0.;
-            if (nsing>j)
-                for (i = j+1; i <= nsing; ++i)
-                    sum += r__[i + j * r_dim1] * wa[i];
-            wa[j] = (wa[j] - sum) / sdiag[j];
-        }
 
     /*     permute the components of z back to components of x. */
-    for (j = 1; j <= n; ++j) {
+    for (j = 0; j < n; ++j) {
         l = ipvt[j];
         x[l] = wa[j];
     }
-- 
cgit v1.2.3


From db39f892a36b1a754abfdf70ea8d5402b295492d Mon Sep 17 00:00:00 2001
From: Thomas Capricelli 
Date: Thu, 26 Nov 2009 05:48:38 +0100
Subject: kill yet another un-needed parameter

---
 unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h | 6 ++----
 unsupported/Eigen/src/NonLinearOptimization/lmpar.h              | 4 ++--
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
index c611ec595..5895fb578 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
@@ -320,7 +320,7 @@ LevenbergMarquardt::minimizeOneStep(
 
         /* determine the levenberg-marquardt parameter. */
 
-        ei_lmpar(fjac, ipvt, diag, qtf, delta, par, wa1, wa2);
+        ei_lmpar(fjac, ipvt, diag, qtf, delta, par, wa1);
 
         /* store the direction p and x + p. calculate the norm of p. */
 
@@ -433,8 +433,6 @@ LevenbergMarquardt::lmstr1(
 {
     n = x.size();
     m = functor.values();
-    JacobianType fjac(m, n);
-    VectorXi ipvt;
 
     /* check the input parameters for errors. */
     if (n <= 0 || m < n || tol < 0.)
@@ -605,7 +603,7 @@ LevenbergMarquardt::minimizeOptimumStorageOneStep(
 
         /* determine the levenberg-marquardt parameter. */
 
-        ei_lmpar(fjac, ipvt, diag, qtf, delta, par, wa1, wa2);
+        ei_lmpar(fjac, ipvt, diag, qtf, delta, par, wa1);
 
         /* store the direction p and x + p. calculate the norm of p. */
 
diff --git a/unsupported/Eigen/src/NonLinearOptimization/lmpar.h b/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
index c1ab2626c..77c07a8db 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
@@ -7,8 +7,7 @@ void ei_lmpar(
         const Matrix< Scalar, Dynamic, 1 >  &qtb,
         Scalar delta,
         Scalar &par,
-        Matrix< Scalar, Dynamic, 1 >  &x,
-        Matrix< Scalar, Dynamic, 1 >  &sdiag)
+        Matrix< Scalar, Dynamic, 1 >  &x)
 {
     /* Local variables */
     int i, j, k, l;
@@ -122,6 +121,7 @@ void ei_lmpar(
         temp = ei_sqrt(par);
         wa1 = temp * diag;
 
+        Matrix< Scalar, Dynamic, 1 > sdiag(n);
         ei_qrsolv(r, ipvt, wa1, qtb, x, sdiag);
 
         wa2 = diag.cwise() * x;
-- 
cgit v1.2.3


From f948df5a7289185088034a5ff2023cfd414a4807 Mon Sep 17 00:00:00 2001
From: Thomas Capricelli 
Date: Thu, 26 Nov 2009 07:37:37 +0100
Subject: cleaning

---
 .../Eigen/src/NonLinearOptimization/qrsolv.h       | 72 ++++++++--------------
 1 file changed, 26 insertions(+), 46 deletions(-)

diff --git a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
index adfa2be50..db44585d1 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
@@ -18,8 +18,7 @@ void ei_qrsolv(
 {
     /* Local variables */
     int i, j, k, l;
-    Scalar tan__, cos__, sin__, sum, temp, cotan;
-    int nsing;
+    Scalar sum, temp;
     Scalar qtbpj;
     int n = r.cols();
     Matrix< Scalar, Dynamic, 1 >  wa(n);
@@ -29,12 +28,12 @@ void ei_qrsolv(
     /*     copy r and (q transpose)*b to preserve input and initialize s. */
     /*     in particular, save the diagonal elements of r in x. */
 
-    for (j = 0; j < n; ++j) {
-        for (i = j; i < n; ++i)
+    x = r.diagonal();
+    wa = qtb;
+
+    for (j = 0; j < n; ++j)
+        for (i = j+1; i < n; ++i)
             r(i,j) = r(j,i);
-        x[j] = r(j,j);
-        wa[j] = qtb[j];
-    }
 
     /*     eliminate the diagonal matrix d using a givens rotation. */
     for (j = 0; j < n; ++j) {
@@ -44,9 +43,8 @@ void ei_qrsolv(
 
         l = ipvt[j];
         if (diag[l] == 0.)
-            goto L90;
-        for (k = j; k < n; ++k)
-            sdiag[k] = 0.;
+            break;
+        sdiag.segment(j,n-j).setZero();
         sdiag[j] = diag[l];
 
         /*        the transformations to eliminate the row of d */
@@ -57,54 +55,39 @@ void ei_qrsolv(
         for (k = j; k < n; ++k) {
             /*           determine a givens rotation which eliminates the */
             /*           appropriate element in the current row of d. */
-            if (sdiag[k] == 0.)
-                continue;
-            if ( ei_abs(r(k,k)) < ei_abs(sdiag[k])) {
-                cotan = r(k,k) / sdiag[k];
-                /* Computing 2nd power */
-                sin__ = Scalar(.5) / ei_sqrt(Scalar(0.25) + Scalar(0.25) * ei_abs2(cotan));
-                cos__ = sin__ * cotan;
-            } else {
-                tan__ = sdiag[k] / r(k,k);
-                /* Computing 2nd power */
-                cos__ = Scalar(.5) / ei_sqrt(Scalar(0.25) + Scalar(0.25) * ei_abs2(tan__));
-                sin__ = cos__ * tan__;
-            }
+            PlanarRotation givens;
+            givens.makeGivens(-r(k,k), sdiag[k]);
 
             /*           compute the modified diagonal element of r and */
             /*           the modified element of ((q transpose)*b,0). */
 
-            r(k,k) = cos__ * r(k,k) + sin__ * sdiag[k];
-            temp = cos__ * wa[k] + sin__ * qtbpj;
-            qtbpj = -sin__ * wa[k] + cos__ * qtbpj;
+            r(k,k) = givens.c() * r(k,k) + givens.s() * sdiag[k];
+            temp = givens.c() * wa[k] + givens.s() * qtbpj;
+            qtbpj = -givens.s() * wa[k] + givens.c() * qtbpj;
             wa[k] = temp;
 
             /*           accumulate the tranformation in the row of s. */
             for (i = k+1; i=0; j--) {
         sum = 0.;
         for (i = j+1; i <= nsing; ++i)
             sum += r(i,j) * wa[i];
@@ -112,9 +95,6 @@ L90:
     }
 
     /*     permute the components of z back to components of x. */
-    for (j = 0; j < n; ++j) {
-        l = ipvt[j];
-        x[l] = wa[j];
-    }
+    for (j = 0; j < n; ++j) x[ipvt[j]] = wa[j];
 }
 
-- 
cgit v1.2.3


From c245054aa8eb91bff82ac799e3ea740c03fa7678 Mon Sep 17 00:00:00 2001
From: Thomas Capricelli 
Date: Thu, 26 Nov 2009 08:30:38 +0100
Subject: cleaning

---
 .../Eigen/src/NonLinearOptimization/lmpar.h        | 38 +++++++++-------------
 .../Eigen/src/NonLinearOptimization/qrsolv.h       | 10 +-----
 2 files changed, 16 insertions(+), 32 deletions(-)

diff --git a/unsupported/Eigen/src/NonLinearOptimization/lmpar.h b/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
index 77c07a8db..b723a7e0a 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/lmpar.h
@@ -10,12 +10,11 @@ void ei_lmpar(
         Matrix< Scalar, Dynamic, 1 >  &x)
 {
     /* Local variables */
-    int i, j, k, l;
+    int i, j, l;
     Scalar fp;
-    Scalar sum, parc, parl;
+    Scalar parc, parl;
     int iter;
     Scalar temp, paru;
-    int nsing;
     Scalar gnorm;
     Scalar dxnorm;
 
@@ -27,31 +26,28 @@ void ei_lmpar(
     assert(n==qtb.size());
     assert(n==x.size());
 
-    Matrix< Scalar, Dynamic, 1 >  wa1(n), wa2(n);
+    Matrix< Scalar, Dynamic, 1 >  wa1, wa2;
 
     /* compute and store in x the gauss-newton direction. if the */
     /* jacobian is rank-deficient, obtain a least squares solution. */
 
-    nsing = n-1;
+    int nsing = n-1;
+    wa1 = qtb;
     for (j = 0; j < n; ++j) {
-        wa1[j] = qtb[j];
         if (r(j,j) == 0. && nsing == n-1)
             nsing = j - 1;
         if (nsing < n-1) 
             wa1[j] = 0.;
     }
-    for (k = 0; k <= nsing; ++k) {
-        j = nsing - k;
+    for (j = nsing; j>=0; --j) {
         wa1[j] /= r(j,j);
         temp = wa1[j];
         for (i = 0; i < j ; ++i)
             wa1[i] -= r(i,j) * temp;
     }
 
-    for (j = 0; j < n; ++j) {
-        l = ipvt[j];
-        x[l] = wa1[j];
-    }
+    for (j = 0; j < n; ++j)
+        x[ipvt[j]] = wa1[j];
 
     /* initialize the iteration counter. */
     /* evaluate the function at the origin, and test */
@@ -76,8 +72,10 @@ void ei_lmpar(
             l = ipvt[j];
             wa1[j] = diag[l] * (wa2[l] / dxnorm);
         }
+        // it's actually a triangularView.solveInplace(), though in a weird
+        // way:
         for (j = 0; j < n; ++j) {
-            sum = 0.;
+            Scalar sum = 0.;
             for (i = 0; i < j; ++i) 
                 sum += r(i,j) * wa1[i];
             wa1[j] = (wa1[j] - sum) / r(j,j);
@@ -88,13 +86,9 @@ void ei_lmpar(
 
     /* calculate an upper bound, paru, for the zero of the function. */
 
-    for (j = 0; j < n; ++j) {
-        sum = 0.;
-        for (i = 0; i <= j; ++i)
-            sum += r(i,j) * qtb[i];
-        l = ipvt[j];
-        wa1[j] = sum / diag[l];
-    }
+    for (j = 0; j < n; ++j)
+        wa1[j] = r.col(j).start(j+1).dot(qtb.start(j+1)) / diag[ipvt[j]];
+
     gnorm = wa1.stableNorm();
     paru = gnorm / delta;
     if (paru == 0.)
@@ -118,8 +112,7 @@ void ei_lmpar(
         if (par == 0.)
             par = std::max(dwarf,Scalar(.001) * paru); /* Computing MAX */
 
-        temp = ei_sqrt(par);
-        wa1 = temp * diag;
+        wa1 = ei_sqrt(par)* diag;
 
         Matrix< Scalar, Dynamic, 1 > sdiag(n);
         ei_qrsolv(r, ipvt, wa1, qtb, x, sdiag);
@@ -141,7 +134,6 @@ void ei_lmpar(
         for (j = 0; j < n; ++j) {
             l = ipvt[j];
             wa1[j] = diag[l] * (wa2[l] / dxnorm);
-            /* L180: */
         }
         for (j = 0; j < n; ++j) {
             wa1[j] /= sdiag[j];
diff --git a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
index db44585d1..1ee21d5ed 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h
@@ -1,11 +1,4 @@
 
-#if 0
-        int n, Scalar *r__, int ldr, 
-        const int *ipvt, const Scalar *diag, const Scalar *qtb, Scalar *x, 
-        Scalar *sdiag)
-#endif
-
-
 template 
 void ei_qrsolv(
         Matrix< Scalar, Dynamic, Dynamic > &r,
@@ -19,7 +12,6 @@ void ei_qrsolv(
     /* Local variables */
     int i, j, k, l;
     Scalar sum, temp;
-    Scalar qtbpj;
     int n = r.cols();
     Matrix< Scalar, Dynamic, 1 >  wa(n);
 
@@ -51,7 +43,7 @@ void ei_qrsolv(
         /*        modify only a single element of (q transpose)*b */
         /*        beyond the first n, which is initially zero. */
 
-        qtbpj = 0.;
+        Scalar qtbpj = 0.;
         for (k = j; k < n; ++k) {
             /*           determine a givens rotation which eliminates the */
             /*           appropriate element in the current row of d. */
-- 
cgit v1.2.3


From 4b1aca2288ebf549791def6287b2886759dec2f4 Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Thu, 26 Nov 2009 22:05:02 -0500
Subject: precision  --->  dummy_precision

---
 Eigen/src/Core/MathFunctions.h                   | 58 ++++++++++++------------
 Eigen/src/Core/MatrixBase.h                      | 30 ++++++------
 Eigen/src/Geometry/AlignedBox.h                  |  2 +-
 Eigen/src/Geometry/AngleAxis.h                   |  4 +-
 Eigen/src/Geometry/EulerAngles.h                 |  2 +-
 Eigen/src/Geometry/Hyperplane.h                  |  2 +-
 Eigen/src/Geometry/ParametrizedLine.h            |  2 +-
 Eigen/src/Geometry/Quaternion.h                  |  6 +--
 Eigen/src/Geometry/Rotation2D.h                  |  2 +-
 Eigen/src/Geometry/Scaling.h                     |  2 +-
 Eigen/src/Geometry/Transform.h                   |  2 +-
 Eigen/src/Geometry/Translation.h                 |  2 +-
 Eigen/src/SVD/SVD.h                              |  2 +-
 Eigen/src/Sparse/AmbiVector.h                    |  2 +-
 Eigen/src/Sparse/CompressedStorage.h             |  2 +-
 Eigen/src/Sparse/DynamicSparseMatrix.h           |  2 +-
 Eigen/src/Sparse/SparseLDLT.h                    |  4 +-
 Eigen/src/Sparse/SparseLLT.h                     |  4 +-
 Eigen/src/Sparse/SparseLU.h                      |  4 +-
 Eigen/src/Sparse/SparseMatrix.h                  |  2 +-
 Eigen/src/Sparse/SparseMatrixBase.h              | 26 +++++------
 Eigen/src/Sparse/SparseVector.h                  |  2 +-
 test/product.h                                   |  2 +-
 unsupported/Eigen/AlignedVector3                 |  2 +-
 unsupported/Eigen/src/Skyline/SkylineInplaceLU.h |  2 +-
 unsupported/Eigen/src/Skyline/SkylineMatrix.h    |  2 +-
 unsupported/Eigen/src/Skyline/SkylineStorage.h   |  2 +-
 27 files changed, 87 insertions(+), 87 deletions(-)

diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h
index 05469b340..7ffddcbf8 100644
--- a/Eigen/src/Core/MathFunctions.h
+++ b/Eigen/src/Core/MathFunctions.h
@@ -30,7 +30,7 @@ template inline typename NumTraits::Real epsilon()
  return std::numeric_limits::Real>::epsilon();
 }
 
-template inline typename NumTraits::Real precision();
+template inline typename NumTraits::Real dummy_precision();
 
 template inline T ei_random(T a, T b);
 template inline T ei_random();
@@ -55,7 +55,7 @@ template inline typename NumTraits::Real ei_hypot(T x, T y)
 ***   int   ***
 **************/
 
-template<> inline int precision() { return 0; }
+template<> inline int dummy_precision() { return 0; }
 inline int ei_real(int x)  { return x; }
 inline int& ei_real_ref(int& x)  { return x; }
 inline int ei_imag(int)    { return 0; }
@@ -92,15 +92,15 @@ template<> inline int ei_random()
 {
   return ei_random(-ei_random_amplitude(), ei_random_amplitude());
 }
-inline bool ei_isMuchSmallerThan(int a, int, int = precision())
+inline bool ei_isMuchSmallerThan(int a, int, int = dummy_precision())
 {
   return a == 0;
 }
-inline bool ei_isApprox(int a, int b, int = precision())
+inline bool ei_isApprox(int a, int b, int = dummy_precision())
 {
   return a == b;
 }
-inline bool ei_isApproxOrLessThan(int a, int b, int = precision())
+inline bool ei_isApproxOrLessThan(int a, int b, int = dummy_precision())
 {
   return a <= b;
 }
@@ -109,7 +109,7 @@ inline bool ei_isApproxOrLessThan(int a, int b, int = precision())
 *** float   ***
 **************/
 
-template<> inline float precision() { return 1e-5f; }
+template<> inline float dummy_precision() { return 1e-5f; }
 inline float ei_real(float x)  { return x; }
 inline float& ei_real_ref(float& x)  { return x; }
 inline float ei_imag(float)    { return 0.f; }
@@ -140,15 +140,15 @@ template<> inline float ei_random()
 {
   return ei_random(-ei_random_amplitude(), ei_random_amplitude());
 }
-inline bool ei_isMuchSmallerThan(float a, float b, float prec = precision())
+inline bool ei_isMuchSmallerThan(float a, float b, float prec = dummy_precision())
 {
   return ei_abs(a) <= ei_abs(b) * prec;
 }
-inline bool ei_isApprox(float a, float b, float prec = precision())
+inline bool ei_isApprox(float a, float b, float prec = dummy_precision())
 {
   return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
 }
-inline bool ei_isApproxOrLessThan(float a, float b, float prec = precision())
+inline bool ei_isApproxOrLessThan(float a, float b, float prec = dummy_precision())
 {
   return a <= b || ei_isApprox(a, b, prec);
 }
@@ -157,7 +157,7 @@ inline bool ei_isApproxOrLessThan(float a, float b, float prec = precision inline double precision() { return 1e-12; }
+template<> inline double dummy_precision() { return 1e-12; }
 
 inline double ei_real(double x)  { return x; }
 inline double& ei_real_ref(double& x)  { return x; }
@@ -189,15 +189,15 @@ template<> inline double ei_random()
 {
   return ei_random(-ei_random_amplitude(), ei_random_amplitude());
 }
-inline bool ei_isMuchSmallerThan(double a, double b, double prec = precision())
+inline bool ei_isMuchSmallerThan(double a, double b, double prec = dummy_precision())
 {
   return ei_abs(a) <= ei_abs(b) * prec;
 }
-inline bool ei_isApprox(double a, double b, double prec = precision())
+inline bool ei_isApprox(double a, double b, double prec = dummy_precision())
 {
   return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
 }
-inline bool ei_isApproxOrLessThan(double a, double b, double prec = precision())
+inline bool ei_isApproxOrLessThan(double a, double b, double prec = dummy_precision())
 {
   return a <= b || ei_isApprox(a, b, prec);
 }
@@ -206,7 +206,7 @@ inline bool ei_isApproxOrLessThan(double a, double b, double prec = precision ***
 *********************/
 
-template<> inline float precision >() { return precision(); }
+template<> inline float dummy_precision >() { return dummy_precision(); }
 inline float ei_real(const std::complex& x) { return std::real(x); }
 inline float ei_imag(const std::complex& x) { return std::imag(x); }
 inline float& ei_real_ref(std::complex& x) { return reinterpret_cast(&x)[0]; }
@@ -224,15 +224,15 @@ template<> inline std::complex ei_random()
 {
   return std::complex(ei_random(), ei_random());
 }
-inline bool ei_isMuchSmallerThan(const std::complex& a, const std::complex& b, float prec = precision())
+inline bool ei_isMuchSmallerThan(const std::complex& a, const std::complex& b, float prec = dummy_precision())
 {
   return ei_abs2(a) <= ei_abs2(b) * prec * prec;
 }
-inline bool ei_isMuchSmallerThan(const std::complex& a, float b, float prec = precision())
+inline bool ei_isMuchSmallerThan(const std::complex& a, float b, float prec = dummy_precision())
 {
   return ei_abs2(a) <= ei_abs2(b) * prec * prec;
 }
-inline bool ei_isApprox(const std::complex& a, const std::complex& b, float prec = precision())
+inline bool ei_isApprox(const std::complex& a, const std::complex& b, float prec = dummy_precision())
 {
   return ei_isApprox(ei_real(a), ei_real(b), prec)
       && ei_isApprox(ei_imag(a), ei_imag(b), prec);
@@ -243,7 +243,7 @@ inline bool ei_isApprox(const std::complex& a, const std::complex&
 *** complex ***
 **********************/
 
-template<> inline double precision >() { return precision(); }
+template<> inline double dummy_precision >() { return dummy_precision(); }
 inline double ei_real(const std::complex& x) { return std::real(x); }
 inline double ei_imag(const std::complex& x) { return std::imag(x); }
 inline double& ei_real_ref(std::complex& x) { return reinterpret_cast(&x)[0]; }
@@ -261,15 +261,15 @@ template<> inline std::complex ei_random()
 {
   return std::complex(ei_random(), ei_random());
 }
-inline bool ei_isMuchSmallerThan(const std::complex& a, const std::complex& b, double prec = precision())
+inline bool ei_isMuchSmallerThan(const std::complex& a, const std::complex& b, double prec = dummy_precision())
 {
   return ei_abs2(a) <= ei_abs2(b) * prec * prec;
 }
-inline bool ei_isMuchSmallerThan(const std::complex& a, double b, double prec = precision())
+inline bool ei_isMuchSmallerThan(const std::complex& a, double b, double prec = dummy_precision())
 {
   return ei_abs2(a) <= ei_abs2(b) * prec * prec;
 }
-inline bool ei_isApprox(const std::complex& a, const std::complex& b, double prec = precision())
+inline bool ei_isApprox(const std::complex& a, const std::complex& b, double prec = dummy_precision())
 {
   return ei_isApprox(ei_real(a), ei_real(b), prec)
       && ei_isApprox(ei_imag(a), ei_imag(b), prec);
@@ -281,7 +281,7 @@ inline bool ei_isApprox(const std::complex& a, const std::complex inline long double precision() { return precision(); }
+template<> inline long double dummy_precision() { return dummy_precision(); }
 inline long double ei_real(long double x)  { return x; }
 inline long double& ei_real_ref(long double& x)  { return x; }
 inline long double ei_imag(long double)    { return 0.; }
@@ -304,15 +304,15 @@ template<> inline long double ei_random()
 {
   return ei_random(-ei_random_amplitude(), ei_random_amplitude());
 }
-inline bool ei_isMuchSmallerThan(long double a, long double b, long double prec = precision())
+inline bool ei_isMuchSmallerThan(long double a, long double b, long double prec = dummy_precision())
 {
   return ei_abs(a) <= ei_abs(b) * prec;
 }
-inline bool ei_isApprox(long double a, long double b, long double prec = precision())
+inline bool ei_isApprox(long double a, long double b, long double prec = dummy_precision())
 {
   return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
 }
-inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec = precision())
+inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec = dummy_precision())
 {
   return a <= b || ei_isApprox(a, b, prec);
 }
@@ -321,7 +321,7 @@ inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec
 ***  bool  ***
 **************/
 
-template<> inline bool precision() { return 0; }
+template<> inline bool dummy_precision() { return 0; }
 inline bool ei_real(bool x)  { return x; }
 inline bool& ei_real_ref(bool& x)  { return x; }
 inline bool ei_imag(bool)    { return 0; }
@@ -334,15 +334,15 @@ template<> inline bool ei_random()
 {
   return (ei_random(0,1) == 1);
 }
-inline bool ei_isMuchSmallerThan(bool a, bool, bool = precision())
+inline bool ei_isMuchSmallerThan(bool a, bool, bool = dummy_precision())
 {
   return !a;
 }
-inline bool ei_isApprox(bool a, bool b, bool = precision())
+inline bool ei_isApprox(bool a, bool b, bool = dummy_precision())
 {
   return a == b;
 }
-inline bool ei_isApproxOrLessThan(bool a, bool b, bool = precision())
+inline bool ei_isApproxOrLessThan(bool a, bool b, bool = dummy_precision())
 {
   return int(a) <= int(b);
 }
diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h
index 8078b75b0..9f62ceb8f 100644
--- a/Eigen/src/Core/MatrixBase.h
+++ b/Eigen/src/Core/MatrixBase.h
@@ -558,27 +558,27 @@ template class MatrixBase
 
     template
     bool isApprox(const MatrixBase& other,
-                  RealScalar prec = precision()) const;
+                  RealScalar prec = dummy_precision()) const;
     bool isMuchSmallerThan(const RealScalar& other,
-                           RealScalar prec = precision()) const;
+                           RealScalar prec = dummy_precision()) const;
     template
     bool isMuchSmallerThan(const MatrixBase& other,
-                           RealScalar prec = precision()) const;
+                           RealScalar prec = dummy_precision()) const;
 
-    bool isApproxToConstant(const Scalar& value, RealScalar prec = precision()) const;
-    bool isConstant(const Scalar& value, RealScalar prec = precision()) const;
-    bool isZero(RealScalar prec = precision()) const;
-    bool isOnes(RealScalar prec = precision()) const;
-    bool isIdentity(RealScalar prec = precision()) const;
-    bool isDiagonal(RealScalar prec = precision()) const;
+    bool isApproxToConstant(const Scalar& value, RealScalar prec = dummy_precision()) const;
+    bool isConstant(const Scalar& value, RealScalar prec = dummy_precision()) const;
+    bool isZero(RealScalar prec = dummy_precision()) const;
+    bool isOnes(RealScalar prec = dummy_precision()) const;
+    bool isIdentity(RealScalar prec = dummy_precision()) const;
+    bool isDiagonal(RealScalar prec = dummy_precision()) const;
 
-    bool isUpperTriangular(RealScalar prec = precision()) const;
-    bool isLowerTriangular(RealScalar prec = precision()) const;
+    bool isUpperTriangular(RealScalar prec = dummy_precision()) const;
+    bool isLowerTriangular(RealScalar prec = dummy_precision()) const;
 
     template
     bool isOrthogonal(const MatrixBase& other,
-                      RealScalar prec = precision()) const;
-    bool isUnitary(RealScalar prec = precision()) const;
+                      RealScalar prec = dummy_precision()) const;
+    bool isUnitary(RealScalar prec = dummy_precision()) const;
 
     template
     inline bool operator==(const MatrixBase& other) const
@@ -722,13 +722,13 @@ template class MatrixBase
       ResultType& inverse,
       typename ResultType::Scalar& determinant,
       bool& invertible,
-      const RealScalar& absDeterminantThreshold = precision()
+      const RealScalar& absDeterminantThreshold = dummy_precision()
     ) const;
     template
     void computeInverseWithCheck(
       ResultType& inverse,
       bool& invertible,
-      const RealScalar& absDeterminantThreshold = precision()
+      const RealScalar& absDeterminantThreshold = dummy_precision()
     ) const;
     Scalar determinant() const;
 
diff --git a/Eigen/src/Geometry/AlignedBox.h b/Eigen/src/Geometry/AlignedBox.h
index 94edc5561..0a716cf31 100644
--- a/Eigen/src/Geometry/AlignedBox.h
+++ b/Eigen/src/Geometry/AlignedBox.h
@@ -171,7 +171,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
     * determined by \a prec.
     *
     * \sa MatrixBase::isApprox() */
-  bool isApprox(const AlignedBox& other, typename NumTraits::Real prec = precision()) const
+  bool isApprox(const AlignedBox& other, typename NumTraits::Real prec = dummy_precision()) const
   { return m_min.isApprox(other.m_min, prec) && m_max.isApprox(other.m_max, prec); }
 
 protected:
diff --git a/Eigen/src/Geometry/AngleAxis.h b/Eigen/src/Geometry/AngleAxis.h
index ef86eb20d..2486df0e6 100644
--- a/Eigen/src/Geometry/AngleAxis.h
+++ b/Eigen/src/Geometry/AngleAxis.h
@@ -146,7 +146,7 @@ public:
     * determined by \a prec.
     *
     * \sa MatrixBase::isApprox() */
-  bool isApprox(const AngleAxis& other, typename NumTraits::Real prec = precision()) const
+  bool isApprox(const AngleAxis& other, typename NumTraits::Real prec = dummy_precision()) const
   { return m_axis.isApprox(other.m_axis, prec) && ei_isApprox(m_angle,other.m_angle, prec); }
 };
 
@@ -165,7 +165,7 @@ template
 AngleAxis& AngleAxis::operator=(const QuaternionBase& q)
 {
   Scalar n2 = q.vec().squaredNorm();
-  if (n2 < precision()*precision())
+  if (n2 < dummy_precision()*dummy_precision())
   {
     m_angle = 0;
     m_axis << 1, 0, 0;
diff --git a/Eigen/src/Geometry/EulerAngles.h b/Eigen/src/Geometry/EulerAngles.h
index dbcc7ae89..b6dbf8ae9 100644
--- a/Eigen/src/Geometry/EulerAngles.h
+++ b/Eigen/src/Geometry/EulerAngles.h
@@ -50,7 +50,7 @@ MatrixBase::eulerAngles(int a0, int a1, int a2) const
 
   Matrix res;
   typedef Matrix Vector2;
-  const Scalar epsilon = precision();
+  const Scalar epsilon = dummy_precision();
 
   const int odd = ((a0+1)%3 == a1) ? 0 : 1;
   const int i = a0;
diff --git a/Eigen/src/Geometry/Hyperplane.h b/Eigen/src/Geometry/Hyperplane.h
index ab65ca2ae..49a9ac7bb 100644
--- a/Eigen/src/Geometry/Hyperplane.h
+++ b/Eigen/src/Geometry/Hyperplane.h
@@ -257,7 +257,7 @@ public:
     * determined by \a prec.
     *
     * \sa MatrixBase::isApprox() */
-  bool isApprox(const Hyperplane& other, typename NumTraits::Real prec = precision()) const
+  bool isApprox(const Hyperplane& other, typename NumTraits::Real prec = dummy_precision()) const
   { return m_coeffs.isApprox(other.m_coeffs, prec); }
 
 protected:
diff --git a/Eigen/src/Geometry/ParametrizedLine.h b/Eigen/src/Geometry/ParametrizedLine.h
index 6a4fcb1c5..21a5595b9 100644
--- a/Eigen/src/Geometry/ParametrizedLine.h
+++ b/Eigen/src/Geometry/ParametrizedLine.h
@@ -123,7 +123,7 @@ public:
     * determined by \a prec.
     *
     * \sa MatrixBase::isApprox() */
-  bool isApprox(const ParametrizedLine& other, typename NumTraits::Real prec = precision()) const
+  bool isApprox(const ParametrizedLine& other, typename NumTraits::Real prec = dummy_precision()) const
   { return m_origin.isApprox(other.m_origin, prec) && m_direction.isApprox(other.m_direction, prec); }
 
 protected:
diff --git a/Eigen/src/Geometry/Quaternion.h b/Eigen/src/Geometry/Quaternion.h
index 660e10d1e..a6bdb2408 100644
--- a/Eigen/src/Geometry/Quaternion.h
+++ b/Eigen/src/Geometry/Quaternion.h
@@ -163,7 +163,7 @@ public:
     *
     * \sa MatrixBase::isApprox() */
   template
-  bool isApprox(const QuaternionBase& other, RealScalar prec = precision()) const
+  bool isApprox(const QuaternionBase& other, RealScalar prec = dummy_precision()) const
   { return coeffs().isApprox(other.coeffs(), prec); }
 
 	/** return the result vector of \a v through the rotation*/
@@ -514,7 +514,7 @@ inline Derived& QuaternionBase::setFromTwoVectors(const MatrixBase())
+  if (c < Scalar(-1)+dummy_precision())
   {
     c = std::max(c,-1);
     Matrix m; m << v0.transpose(), v1.transpose();
@@ -590,7 +590,7 @@ template 
 Quaternion::Scalar>
 QuaternionBase::slerp(Scalar t, const QuaternionBase& other) const
 {
-  static const Scalar one = Scalar(1) - precision();
+  static const Scalar one = Scalar(1) - dummy_precision();
   Scalar d = this->dot(other);
   Scalar absD = ei_abs(d);
   if (absD>=one)
diff --git a/Eigen/src/Geometry/Rotation2D.h b/Eigen/src/Geometry/Rotation2D.h
index b80fcace0..7f24a3eae 100644
--- a/Eigen/src/Geometry/Rotation2D.h
+++ b/Eigen/src/Geometry/Rotation2D.h
@@ -121,7 +121,7 @@ public:
     * determined by \a prec.
     *
     * \sa MatrixBase::isApprox() */
-  bool isApprox(const Rotation2D& other, typename NumTraits::Real prec = precision()) const
+  bool isApprox(const Rotation2D& other, typename NumTraits::Real prec = dummy_precision()) const
   { return ei_isApprox(m_angle,other.m_angle, prec); }
 };
 
diff --git a/Eigen/src/Geometry/Scaling.h b/Eigen/src/Geometry/Scaling.h
index ce191b5da..4695914fd 100644
--- a/Eigen/src/Geometry/Scaling.h
+++ b/Eigen/src/Geometry/Scaling.h
@@ -107,7 +107,7 @@ public:
     * determined by \a prec.
     *
     * \sa MatrixBase::isApprox() */
-  bool isApprox(const UniformScaling& other, typename NumTraits::Real prec = precision()) const
+  bool isApprox(const UniformScaling& other, typename NumTraits::Real prec = dummy_precision()) const
   { return ei_isApprox(m_factor, other.factor(), prec); }
 
 };
diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h
index 4ee036140..d478675bd 100644
--- a/Eigen/src/Geometry/Transform.h
+++ b/Eigen/src/Geometry/Transform.h
@@ -424,7 +424,7 @@ public:
     * determined by \a prec.
     *
     * \sa MatrixBase::isApprox() */
-  bool isApprox(const Transform& other, typename NumTraits::Real prec = precision()) const
+  bool isApprox(const Transform& other, typename NumTraits::Real prec = dummy_precision()) const
   { return m_matrix.isApprox(other.m_matrix, prec); }
 
   /** Sets the last row to [0 ... 0 1]
diff --git a/Eigen/src/Geometry/Translation.h b/Eigen/src/Geometry/Translation.h
index 1fff03810..b7477df9f 100644
--- a/Eigen/src/Geometry/Translation.h
+++ b/Eigen/src/Geometry/Translation.h
@@ -154,7 +154,7 @@ public:
     * determined by \a prec.
     *
     * \sa MatrixBase::isApprox() */
-  bool isApprox(const Translation& other, typename NumTraits::Real prec = precision()) const
+  bool isApprox(const Translation& other, typename NumTraits::Real prec = dummy_precision()) const
   { return m_coeffs.isApprox(other.m_coeffs, prec); }
 
 };
diff --git a/Eigen/src/SVD/SVD.h b/Eigen/src/SVD/SVD.h
index 254885873..3c7aaf322 100644
--- a/Eigen/src/SVD/SVD.h
+++ b/Eigen/src/SVD/SVD.h
@@ -193,7 +193,7 @@ SVD& SVD::compute(const MatrixType& matrix)
   int i,its,j,k,l,nm;
   Scalar anorm, c, f, g, h, s, scale, x, y, z;
   bool convergence = true;
-  Scalar eps = precision();
+  Scalar eps = dummy_precision();
 
   Matrix rv1(n);
   g = scale = anorm = 0;
diff --git a/Eigen/src/Sparse/AmbiVector.h b/Eigen/src/Sparse/AmbiVector.h
index 474626848..5e75bd6e7 100644
--- a/Eigen/src/Sparse/AmbiVector.h
+++ b/Eigen/src/Sparse/AmbiVector.h
@@ -300,7 +300,7 @@ class AmbiVector<_Scalar>::Iterator
       * In practice, all coefficients having a magnitude smaller than \a epsilon
       * are skipped.
       */
-    Iterator(const AmbiVector& vec, RealScalar epsilon = RealScalar(0.1)*precision())
+    Iterator(const AmbiVector& vec, RealScalar epsilon = RealScalar(0.1)*dummy_precision())
       : m_vector(vec)
     {
       m_epsilon = epsilon;
diff --git a/Eigen/src/Sparse/CompressedStorage.h b/Eigen/src/Sparse/CompressedStorage.h
index abf42914f..fcf5c7bfe 100644
--- a/Eigen/src/Sparse/CompressedStorage.h
+++ b/Eigen/src/Sparse/CompressedStorage.h
@@ -185,7 +185,7 @@ class CompressedStorage
       return m_values[id];
     }
     
-    void prune(Scalar reference, RealScalar epsilon = precision())
+    void prune(Scalar reference, RealScalar epsilon = dummy_precision())
     {
       size_t k = 0;
       size_t n = size();
diff --git a/Eigen/src/Sparse/DynamicSparseMatrix.h b/Eigen/src/Sparse/DynamicSparseMatrix.h
index 6a5cd070e..15135f9db 100644
--- a/Eigen/src/Sparse/DynamicSparseMatrix.h
+++ b/Eigen/src/Sparse/DynamicSparseMatrix.h
@@ -208,7 +208,7 @@ class DynamicSparseMatrix
 
     inline void finalize() {}
 
-    void prune(Scalar reference, RealScalar epsilon = precision())
+    void prune(Scalar reference, RealScalar epsilon = dummy_precision())
     {
       for (int j=0; j();
+      m_precision = RealScalar(0.1) * Eigen::dummy_precision();
     }
 
     /** Creates a LDLT object and compute the respective factorization of \a matrix using
@@ -103,7 +103,7 @@ class SparseLDLT
       : m_matrix(matrix.rows(), matrix.cols()), m_flags(flags), m_status(0)
     {
       ei_assert((MatrixType::Flags&RowMajorBit)==0);
-      m_precision = RealScalar(0.1) * Eigen::precision();
+      m_precision = RealScalar(0.1) * Eigen::dummy_precision();
       compute(matrix);
     }
 
diff --git a/Eigen/src/Sparse/SparseLLT.h b/Eigen/src/Sparse/SparseLLT.h
index b2f65b944..4b73dd205 100644
--- a/Eigen/src/Sparse/SparseLLT.h
+++ b/Eigen/src/Sparse/SparseLLT.h
@@ -54,7 +54,7 @@ class SparseLLT
     SparseLLT(int flags = 0)
       : m_flags(flags), m_status(0)
     {
-      m_precision = RealScalar(0.1) * Eigen::precision();
+      m_precision = RealScalar(0.1) * Eigen::dummy_precision();
     }
 
     /** Creates a LLT object and compute the respective factorization of \a matrix using
@@ -62,7 +62,7 @@ class SparseLLT
     SparseLLT(const MatrixType& matrix, int flags = 0)
       : m_matrix(matrix.rows(), matrix.cols()), m_flags(flags), m_status(0)
     {
-      m_precision = RealScalar(0.1) * Eigen::precision();
+      m_precision = RealScalar(0.1) * Eigen::dummy_precision();
       compute(matrix);
     }
 
diff --git a/Eigen/src/Sparse/SparseLU.h b/Eigen/src/Sparse/SparseLU.h
index 3f8d0f8db..2ec6d0e74 100644
--- a/Eigen/src/Sparse/SparseLU.h
+++ b/Eigen/src/Sparse/SparseLU.h
@@ -59,7 +59,7 @@ class SparseLU
     SparseLU(int flags = 0)
       : m_flags(flags), m_status(0)
     {
-      m_precision = RealScalar(0.1) * Eigen::precision();
+      m_precision = RealScalar(0.1) * Eigen::dummy_precision();
     }
 
     /** Creates a LU object and compute the respective factorization of \a matrix using
@@ -67,7 +67,7 @@ class SparseLU
     SparseLU(const MatrixType& matrix, int flags = 0)
       : /*m_matrix(matrix.rows(), matrix.cols()),*/ m_flags(flags), m_status(0)
     {
-      m_precision = RealScalar(0.1) * Eigen::precision();
+      m_precision = RealScalar(0.1) * Eigen::dummy_precision();
       compute(matrix);
     }
 
diff --git a/Eigen/src/Sparse/SparseMatrix.h b/Eigen/src/Sparse/SparseMatrix.h
index af3b5e5eb..7010602b7 100644
--- a/Eigen/src/Sparse/SparseMatrix.h
+++ b/Eigen/src/Sparse/SparseMatrix.h
@@ -341,7 +341,7 @@ class SparseMatrix
       }
     }
 
-    void prune(Scalar reference, RealScalar epsilon = precision())
+    void prune(Scalar reference, RealScalar epsilon = dummy_precision())
     {
       int k = 0;
       for (int j=0; j class SparseMatrixBase : public AnyMatrixBase
     bool isApprox(const SparseMatrixBase& other,
-                  RealScalar prec = precision()) const
+                  RealScalar prec = dummy_precision()) const
     { return toDense().isApprox(other.toDense(),prec); }
 
     template
     bool isApprox(const MatrixBase& other,
-                  RealScalar prec = precision()) const
+                  RealScalar prec = dummy_precision()) const
     { return toDense().isApprox(other,prec); }
 //     bool isMuchSmallerThan(const RealScalar& other,
-//                            RealScalar prec = precision()) const;
+//                            RealScalar prec = dummy_precision()) const;
 //     template
 //     bool isMuchSmallerThan(const MatrixBase& other,
-//                            RealScalar prec = precision()) const;
+//                            RealScalar prec = dummy_precision()) const;
 
-//     bool isApproxToConstant(const Scalar& value, RealScalar prec = precision()) const;
-//     bool isZero(RealScalar prec = precision()) const;
-//     bool isOnes(RealScalar prec = precision()) const;
-//     bool isIdentity(RealScalar prec = precision()) const;
-//     bool isDiagonal(RealScalar prec = precision()) const;
+//     bool isApproxToConstant(const Scalar& value, RealScalar prec = dummy_precision()) const;
+//     bool isZero(RealScalar prec = dummy_precision()) const;
+//     bool isOnes(RealScalar prec = dummy_precision()) const;
+//     bool isIdentity(RealScalar prec = dummy_precision()) const;
+//     bool isDiagonal(RealScalar prec = dummy_precision()) const;
 
-//     bool isUpperTriangular(RealScalar prec = precision()) const;
-//     bool isLowerTriangular(RealScalar prec = precision()) const;
+//     bool isUpperTriangular(RealScalar prec = dummy_precision()) const;
+//     bool isLowerTriangular(RealScalar prec = dummy_precision()) const;
 
 //     template
 //     bool isOrthogonal(const MatrixBase& other,
-//                       RealScalar prec = precision()) const;
-//     bool isUnitary(RealScalar prec = precision()) const;
+//                       RealScalar prec = dummy_precision()) const;
+//     bool isUnitary(RealScalar prec = dummy_precision()) const;
 
 //     template
 //     inline bool operator==(const MatrixBase& other) const
diff --git a/Eigen/src/Sparse/SparseVector.h b/Eigen/src/Sparse/SparseVector.h
index 122b1888e..8c8728b87 100644
--- a/Eigen/src/Sparse/SparseVector.h
+++ b/Eigen/src/Sparse/SparseVector.h
@@ -201,7 +201,7 @@ class SparseVector
     EIGEN_DEPRECATED void endFill() {}
     inline void finalize() {}
 
-    void prune(Scalar reference, RealScalar epsilon = precision())
+    void prune(Scalar reference, RealScalar epsilon = dummy_precision())
     {
       m_data.prune(reference,epsilon);
     }
diff --git a/test/product.h b/test/product.h
index 40773ad90..c1413cc2c 100644
--- a/test/product.h
+++ b/test/product.h
@@ -27,7 +27,7 @@
 #include 
 
 template
-bool areNotApprox(const MatrixBase& m1, const MatrixBase& m2, typename Derived1::RealScalar epsilon = precision())
+bool areNotApprox(const MatrixBase& m1, const MatrixBase& m2, typename Derived1::RealScalar epsilon = dummy_precision())
 {
   return !((m1-m2).cwise().abs2().maxCoeff() < epsilon * epsilon
                           * std::max(m1.cwise().abs2().maxCoeff(), m2.cwise().abs2().maxCoeff()));
diff --git a/unsupported/Eigen/AlignedVector3 b/unsupported/Eigen/AlignedVector3
index f20fad6d1..a1510f19d 100644
--- a/unsupported/Eigen/AlignedVector3
+++ b/unsupported/Eigen/AlignedVector3
@@ -188,7 +188,7 @@ template class AlignedVector3
     }
 
     template
-    inline bool isApprox(const MatrixBase& other, RealScalar eps=precision()) const
+    inline bool isApprox(const MatrixBase& other, RealScalar eps=dummy_precision()) const
     {
       return m_coeffs.template start<3>().isApprox(other,eps);
     }
diff --git a/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h b/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h
index feed564c5..c8c5f7575 100644
--- a/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h
+++ b/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h
@@ -46,7 +46,7 @@ public:
      * flags \a flags. */
     SkylineInplaceLU(MatrixType& matrix, int flags = 0)
     : /*m_matrix(matrix.rows(), matrix.cols()),*/ m_flags(flags), m_status(0), m_lu(matrix) {
-        m_precision = RealScalar(0.1) * Eigen::precision ();
+        m_precision = RealScalar(0.1) * Eigen::dummy_precision ();
         m_lu.IsRowMajor ? computeRowMajor() : compute();
     }
 
diff --git a/unsupported/Eigen/src/Skyline/SkylineMatrix.h b/unsupported/Eigen/src/Skyline/SkylineMatrix.h
index 5d47d970f..6dd4f1736 100644
--- a/unsupported/Eigen/src/Skyline/SkylineMatrix.h
+++ b/unsupported/Eigen/src/Skyline/SkylineMatrix.h
@@ -589,7 +589,7 @@ public:
         m_data.squeeze();
     }
 
-    void prune(Scalar reference, RealScalar epsilon = precision ()) {
+    void prune(Scalar reference, RealScalar epsilon = dummy_precision ()) {
         //TODO
     }
 
diff --git a/unsupported/Eigen/src/Skyline/SkylineStorage.h b/unsupported/Eigen/src/Skyline/SkylineStorage.h
index f725da0bf..641508f75 100644
--- a/unsupported/Eigen/src/Skyline/SkylineStorage.h
+++ b/unsupported/Eigen/src/Skyline/SkylineStorage.h
@@ -206,7 +206,7 @@ public:
         memset(m_lowerProfile, 0, m_diagSize * sizeof (int));
     }
 
-    void prune(Scalar reference, RealScalar epsilon = precision()) {
+    void prune(Scalar reference, RealScalar epsilon = dummy_precision()) {
         //TODO
     }
 
-- 
cgit v1.2.3


From a255336e4fa3e01f71db96b72f5ced4c200c341c Mon Sep 17 00:00:00 2001
From: Thomas Capricelli 
Date: Sat, 28 Nov 2009 02:42:05 +0100
Subject: fix doc

---
 blas/README.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/blas/README.txt b/blas/README.txt
index 466a6751c..07a8bd92a 100644
--- a/blas/README.txt
+++ b/blas/README.txt
@@ -4,4 +4,6 @@ This directory contains a BLAS library built on top of Eigen.
 This is currently a work in progress which is far to be ready for use,
 but feel free to contribute to it if you wish.
 
-If you want to compile it, set the cmake variable EIGEN_BUILD_BLAS to "on".
+This module is not built by default. In order to compile it, you need to
+type 'make blas' from within your build dir.
+
-- 
cgit v1.2.3


From 21ff296652c1be066e93c1196e9d7b8e868683f1 Mon Sep 17 00:00:00 2001
From: Thomas Capricelli 
Date: Mon, 30 Nov 2009 16:21:21 +0100
Subject: Adapted a mail from Mark about some design and add it as
 documentation for the FFT module.

---
 unsupported/Eigen/FFT | 35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/unsupported/Eigen/FFT b/unsupported/Eigen/FFT
index c8521bbf0..fc2efc1d6 100644
--- a/unsupported/Eigen/FFT
+++ b/unsupported/Eigen/FFT
@@ -44,11 +44,42 @@
   * The build-in implementation is based on kissfft. It is a small, free, and
   * reasonably efficient default.
   *
-  * Frontends are
+  * There are currently two frontends:
   *
   * - fftw (http://www.fftw.org) : faster, GPL -- incompatible with Eigen in LGPL form, bigger code size.
-  * - MLK (http://en.wikipedia.org/wiki/Math_Kernel_Library) : fastest, commercial -- may be incompatible with Eigen in GPL form
+  * - MLK (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.
   */
  
 
-- 
cgit v1.2.3


From 66534b782c243f8a9a6c392674fa6e1706e7e822 Mon Sep 17 00:00:00 2001
From: Hauke Heibel 
Date: Mon, 30 Nov 2009 16:54:04 +0100
Subject: Some of our unit tests require mathematical constants and thus we
 rely on non-ansi code. It seems as if the new standard removed pow(T,int).
 M_PIL is only defined when _GNU_SOURCE is defined.

---
 cmake/EigenTesting.cmake                                  | 2 +-
 unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h | 4 ++--
 unsupported/test/FFT.cpp                                  | 4 ++++
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/cmake/EigenTesting.cmake b/cmake/EigenTesting.cmake
index ce567abc3..c1fd49e20 100644
--- a/cmake/EigenTesting.cmake
+++ b/cmake/EigenTesting.cmake
@@ -223,7 +223,7 @@ if(CMAKE_COMPILER_IS_GNUCXX)
     set(COVERAGE_FLAGS "")
   endif(EIGEN_COVERAGE_TESTING)
   if(EIGEN_TEST_RVALUE_REF_SUPPORT OR EIGEN_TEST_C++0x)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
   endif(EIGEN_TEST_RVALUE_REF_SUPPORT OR EIGEN_TEST_C++0x)
   if(CMAKE_SYSTEM_NAME MATCHES Linux)
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_FLAGS} -g2")
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
index 636f37655..6510b6814 100644
--- a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
+++ b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
@@ -272,7 +272,7 @@ void MatrixExponential::computeUV(float)
   } else {
     const float maxnorm = 3.925724783138660f;
     m_squarings = std::max(0, (int)ceil(log2(m_l1norm / maxnorm)));
-    MatrixType A = *m_M / std::pow(Scalar(2), m_squarings);
+    MatrixType A = *m_M / std::pow(Scalar(2), Scalar(m_squarings));
     pade7(A);
   }
 }
@@ -291,7 +291,7 @@ void MatrixExponential::computeUV(double)
   } else {
     const double maxnorm = 5.371920351148152;
     m_squarings = std::max(0, (int)ceil(log2(m_l1norm / maxnorm)));
-    MatrixType A = *m_M / std::pow(Scalar(2), m_squarings);
+    MatrixType A = *m_M / std::pow(Scalar(2), Scalar(m_squarings));
     pade13(A);
   }
 }
diff --git a/unsupported/test/FFT.cpp b/unsupported/test/FFT.cpp
index ad0d426e4..861677174 100644
--- a/unsupported/test/FFT.cpp
+++ b/unsupported/test/FFT.cpp
@@ -47,7 +47,11 @@ complex  promote(long double x) { return complex( x);
         cerr <<"idx\ttruth\t\tvalue\t|dif|=\n";
         for (size_t k0=0;k0 acc = 0;
+#ifdef _GNU_SOURCE
             long double phinc = -2.*k0* M_PIl / timebuf.size();
+#else
+            long double phinc = -2.*k0* M_PI / timebuf.size();
+#endif
             for (size_t k1=0;k1(0,k1*phinc) );
             }
-- 
cgit v1.2.3


From 1c2e476fa745d7323d77959d5fb88fd3587be187 Mon Sep 17 00:00:00 2001
From: Hauke Heibel 
Date: Mon, 30 Nov 2009 18:56:56 +0100
Subject: 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;
 };
 
-- 
cgit v1.2.3


From e6c560aedfff176cbc6df40eedd4c5cf343b0fa6 Mon Sep 17 00:00:00 2001
From: Hauke Heibel 
Date: Mon, 30 Nov 2009 19:06:07 +0100
Subject: 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;
 };
 
-- 
cgit v1.2.3


From 120882c4f1ee4c029d91818f59a5fdbda19b40a5 Mon Sep 17 00:00:00 2001
From: Thomas Capricelli 
Date: Mon, 30 Nov 2009 19:42:00 +0100
Subject: fix another 'duplicated content in doxygen pages' bug : exclude
 *.orig files

---
 doc/Doxyfile.in             | 1 +
 unsupported/doc/Doxyfile.in | 1 +
 2 files changed, 2 insertions(+)

diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index 7f5b26a61..497f7ab6c 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -607,6 +607,7 @@ EXCLUDE_SYMLINKS       = NO
 EXCLUDE_PATTERNS       = CMake* \
                          *.txt \
                          *.sh \
+                         *.orig \
                          *.diff \
                          diff
                          *~
diff --git a/unsupported/doc/Doxyfile.in b/unsupported/doc/Doxyfile.in
index a9c7d6004..e55d53f7e 100644
--- a/unsupported/doc/Doxyfile.in
+++ b/unsupported/doc/Doxyfile.in
@@ -601,6 +601,7 @@ EXCLUDE_PATTERNS       = CMake* \
                          *.txt \
                          *.sh \
                          *.diff \
+                         *.orig \
                          diff
                          *~
 
-- 
cgit v1.2.3


From b2a5fb874f6b2d60d497180cf83e0f0ac6ae0cc8 Mon Sep 17 00:00:00 2001
From: Gael Guennebaud 
Date: Tue, 1 Dec 2009 06:21:29 +0100
Subject: 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 >
-- 
cgit v1.2.3


From 7af1ee0b6c2bd3ef372ce1f8b6baa714227205f5 Mon Sep 17 00:00:00 2001
From: Hauke Heibel 
Date: Tue, 1 Dec 2009 07:53:09 +0100
Subject: 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 >();
+}
-- 
cgit v1.2.3


From 1fc5fdea25212431f0029062b78da5c0cc1621b8 Mon Sep 17 00:00:00 2001
From: Hauke Heibel 
Date: Tue, 1 Dec 2009 09:20:05 +0100
Subject: 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
-#include 
-#include 
-#else
+#if defined(_WIN32) || defined(__CYGWIN__)
 #define NOMINMAX
+#define WIN32_LEAN_AND_MEAN
 #include 
+#else
+#include 
+#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;
   }
-- 
cgit v1.2.3


From 82971a5dcda3dcb36465c0984f69a98a31baf7e7 Mon Sep 17 00:00:00 2001
From: Hauke Heibel 
Date: Tue, 1 Dec 2009 09:29:56 +0100
Subject: 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();
-- 
cgit v1.2.3


From 88be82679171c3ef13c432949f4b635482b422e3 Mon Sep 17 00:00:00 2001
From: Hauke Heibel 
Date: Tue, 1 Dec 2009 09:49:15 +0100
Subject: 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;
-- 
cgit v1.2.3


From 7b3e205ebd4c8af6cd1ab65b538915a01c54bd35 Mon Sep 17 00:00:00 2001
From: Hauke Heibel 
Date: Tue, 1 Dec 2009 09:56:40 +0100
Subject: 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;
-- 
cgit v1.2.3


From 3091be513421663f56f37d374212a365a73e84eb Mon Sep 17 00:00:00 2001
From: Hauke Heibel 
Date: Tue, 1 Dec 2009 10:22:54 +0100
Subject: 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());
     }
 
-- 
cgit v1.2.3


From 2bf354da80d15a7a1e7ad9f58f375a21c6e721aa Mon Sep 17 00:00:00 2001
From: Hauke Heibel 
Date: Tue, 1 Dec 2009 11:51:22 +0100
Subject: 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(),
-- 
cgit v1.2.3


From b08d5b2d2c73c095706cd2442878b960ef46df1f Mon Sep 17 00:00:00 2001
From: Hauke Heibel 
Date: Tue, 1 Dec 2009 13:16:51 +0100
Subject: 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 +-
 unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h | 24 +++----
 unsupported/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)
-- 
cgit v1.2.3


From d3250cb38feaae3637ae2a9ab6266424a321674d Mon Sep 17 00:00:00 2001
From: Hauke Heibel 
Date: Tue, 1 Dec 2009 13:29:08 +0100
Subject: 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
-- 
cgit v1.2.3


From 49c0986d861822f2ef3bb588ae446307aac19f2f Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Tue, 1 Dec 2009 13:22:14 -0500
Subject: minor cleanup

---
 Eigen/src/LU/FullPivLU.h | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/Eigen/src/LU/FullPivLU.h b/Eigen/src/LU/FullPivLU.h
index 28dc0cd47..e79e3ad23 100644
--- a/Eigen/src/LU/FullPivLU.h
+++ b/Eigen/src/LU/FullPivLU.h
@@ -234,8 +234,9 @@ template class FullPivLU
       * who need to determine when pivots are to be considered nonzero. This is not used for the
       * LU decomposition itself.
       *
-      * When it needs to get the threshold value, Eigen calls threshold(). By default, this calls
-      * defaultThreshold(). Once you have called the present method setThreshold(const RealScalar&),
+      * When it needs to get the threshold value, Eigen calls threshold(). By default, this
+      * uses a formula to automatically determine a reasonable threshold.
+      * Once you have called the present method setThreshold(const RealScalar&),
       * your value is used instead.
       *
       * \param threshold The new value to use as the threshold.
@@ -303,7 +304,7 @@ template class FullPivLU
     inline int dimensionOfKernel() const
     {
       ei_assert(m_isInitialized && "LU is not initialized.");
-      return m_lu.cols() - rank();
+      return cols() - rank();
     }
 
     /** \returns true if the matrix of which *this is the LU decomposition represents an injective
@@ -316,7 +317,7 @@ template class FullPivLU
     inline bool isInjective() const
     {
       ei_assert(m_isInitialized && "LU is not initialized.");
-      return rank() == m_lu.cols();
+      return rank() == cols();
     }
 
     /** \returns true if the matrix of which *this is the LU decomposition represents a surjective
@@ -329,7 +330,7 @@ template class FullPivLU
     inline bool isSurjective() const
     {
       ei_assert(m_isInitialized && "LU is not initialized.");
-      return rank() == m_lu.rows();
+      return rank() == rows();
     }
 
     /** \returns true if the matrix of which *this is the LU decomposition is invertible.
@@ -402,6 +403,7 @@ FullPivLU& FullPivLU::compute(const MatrixType& matrix)
 
   m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
   m_maxpivot = RealScalar(0);
+
   for(int k = 0; k < size; ++k)
   {
     // First, we need to find the pivot.
@@ -418,10 +420,10 @@ FullPivLU& FullPivLU::compute(const MatrixType& matrix)
     // if the pivot (hence the corner) is exactly zero, terminate to avoid generating nan/inf values
     if(biggest_in_corner == RealScalar(0))
     {
-      // before exiting, make sure to initialize the still uninitialized row_transpositions
+      // before exiting, make sure to initialize the still uninitialized transpositions
       // in a sane state without destroying what we already have.
       m_nonzero_pivots = k;
-      for(int i = k; i < size; i++)
+      for(int i = k; i < size; ++i)
       {
         rows_transpositions.coeffRef(i) = i;
         cols_transpositions.coeffRef(i) = i;
@@ -617,7 +619,7 @@ struct ei_solve_retval, Rhs>
      * Step 4: result = Q * c;
      */
 
-    const int rows = dec().matrixLU().rows(), cols = dec().matrixLU().cols(),
+    const int rows = dec().rows(), cols = dec().cols(),
               nonzero_pivots = dec().nonzeroPivots();
     ei_assert(rhs().rows() == rows);
     const int smalldim = std::min(rows, cols);
-- 
cgit v1.2.3


From 95d88e1327d6654df00323bf6c1cfd356401fa7f Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Tue, 1 Dec 2009 13:26:29 -0500
Subject: Big reworking of ColPivQR and its unit test, which now passes even
 with thousands of repetitions and correctly tests matrices of all sizes.
 Several surprises along the way: for example, a major cause of trouble was
 the optimized "table of column squared norms" where the accumulation of
 imprecision was a serious issue; another surprise is that tests like "x!=0"
 before dividing by x really benefit from being replaced by fuzzy tests, as i
 hit real cases where i got wrong results in 1/epsilon.

---
 Eigen/src/QR/ColPivHouseholderQR.h | 222 ++++++++++++++++++++++++++-----------
 test/qr_colpivoting.cpp            |  31 ++----
 2 files changed, 166 insertions(+), 87 deletions(-)

diff --git a/Eigen/src/QR/ColPivHouseholderQR.h b/Eigen/src/QR/ColPivHouseholderQR.h
index e59ecac66..1865417d4 100644
--- a/Eigen/src/QR/ColPivHouseholderQR.h
+++ b/Eigen/src/QR/ColPivHouseholderQR.h
@@ -74,7 +74,8 @@ template class ColPivHouseholderQR
     ColPivHouseholderQR(const MatrixType& matrix)
       : m_qr(matrix.rows(), matrix.cols()),
         m_hCoeffs(std::min(matrix.rows(),matrix.cols())),
-        m_isInitialized(false)
+        m_isInitialized(false),
+        m_usePrescribedThreshold(false)
     {
       compute(matrix);
     }
@@ -153,54 +154,63 @@ template class ColPivHouseholderQR
 
     /** \returns the rank of the matrix of which *this is the QR decomposition.
       *
-      * \note This is computed at the time of the construction of the QR decomposition. This
-      *       method does not perform any further computation.
+      * \note This method has to determine which pivots should be considered nonzero.
+      *       For that, it uses the threshold value that you can control by calling
+      *       setThreshold(const RealScalar&).
       */
     inline int rank() const
     {
       ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-      return m_rank;
+      RealScalar premultiplied_threshold = ei_abs(m_maxpivot) * threshold();
+      int result = 0;
+      for(int i = 0; i < m_nonzero_pivots; ++i)
+        result += (ei_abs(m_qr.coeff(i,i)) > premultiplied_threshold);
+      return result;
     }
 
     /** \returns the dimension of the kernel of the matrix of which *this is the QR decomposition.
       *
-      * \note Since the rank is computed at the time of the construction of the QR decomposition, this
-      *       method almost does not perform any further computation.
+      * \note This method has to determine which pivots should be considered nonzero.
+      *       For that, it uses the threshold value that you can control by calling
+      *       setThreshold(const RealScalar&).
       */
     inline int dimensionOfKernel() const
     {
       ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-      return m_qr.cols() - m_rank;
+      return cols() - rank();
     }
 
     /** \returns true if the matrix of which *this is the QR decomposition represents an injective
       *          linear map, i.e. has trivial kernel; false otherwise.
       *
-      * \note Since the rank is computed at the time of the construction of the QR decomposition, this
-      *       method almost does not perform any further computation.
+      * \note This method has to determine which pivots should be considered nonzero.
+      *       For that, it uses the threshold value that you can control by calling
+      *       setThreshold(const RealScalar&).
       */
     inline bool isInjective() const
     {
       ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-      return m_rank == m_qr.cols();
+      return rank() == cols();
     }
 
     /** \returns true if the matrix of which *this is the QR decomposition represents a surjective
       *          linear map; false otherwise.
       *
-      * \note Since the rank is computed at the time of the construction of the QR decomposition, this
-      *       method almost does not perform any further computation.
+      * \note This method has to determine which pivots should be considered nonzero.
+      *       For that, it uses the threshold value that you can control by calling
+      *       setThreshold(const RealScalar&).
       */
     inline bool isSurjective() const
     {
       ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-      return m_rank == m_qr.rows();
+      return rank() == rows();
     }
 
     /** \returns true if the matrix of which *this is the QR decomposition is invertible.
       *
-      * \note Since the rank is computed at the time of the construction of the QR decomposition, this
-      *       method almost does not perform any further computation.
+      * \note This method has to determine which pivots should be considered nonzero.
+      *       For that, it uses the threshold value that you can control by calling
+      *       setThreshold(const RealScalar&).
       */
     inline bool isInvertible() const
     {
@@ -226,13 +236,80 @@ template class ColPivHouseholderQR
     inline int cols() const { return m_qr.cols(); }
     const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
 
+    /** Allows to prescribe a threshold to be used by certain methods, such as rank(),
+      * who need to determine when pivots are to be considered nonzero. This is not used for the
+      * QR decomposition itself.
+      *
+      * When it needs to get the threshold value, Eigen calls threshold(). By default, this
+      * uses a formula to automatically determine a reasonable threshold.
+      * Once you have called the present method setThreshold(const RealScalar&),
+      * your value is used instead.
+      *
+      * \param threshold The new value to use as the threshold.
+      *
+      * A pivot will be considered nonzero if its absolute value is strictly greater than
+      *  \f$ \vert pivot \vert \leqslant threshold \times \vert maxpivot \vert \f$
+      * where maxpivot is the biggest pivot.
+      *
+      * If you want to come back to the default behavior, call setThreshold(Default_t)
+      */
+    ColPivHouseholderQR& setThreshold(const RealScalar& threshold)
+    {
+      m_usePrescribedThreshold = true;
+      m_prescribedThreshold = threshold;
+    }
+
+    /** Allows to come back to the default behavior, letting Eigen use its default formula for
+      * determining the threshold.
+      *
+      * You should pass the special object Eigen::Default as parameter here.
+      * \code qr.setThreshold(Eigen::Default); \endcode
+      *
+      * See the documentation of setThreshold(const RealScalar&).
+      */
+    ColPivHouseholderQR& setThreshold(Default_t)
+    {
+      m_usePrescribedThreshold = false;
+    }
+
+    /** Returns the threshold that will be used by certain methods such as rank().
+      *
+      * See the documentation of setThreshold(const RealScalar&).
+      */
+    RealScalar threshold() const
+    {
+      ei_assert(m_isInitialized || m_usePrescribedThreshold);
+      return m_usePrescribedThreshold ? m_prescribedThreshold
+      // this formula comes from experimenting (see "LU precision tuning" thread on the list)
+      // and turns out to be identical to Higham's formula used already in LDLt.
+                                      : epsilon() * m_qr.diagonalSize();
+    }
+
+    /** \returns the number of nonzero pivots in the QR decomposition.
+      * Here nonzero is meant in the exact sense, not in a fuzzy sense.
+      * So that notion isn't really intrinsically interesting, but it is
+      * still useful when implementing algorithms.
+      *
+      * \sa rank()
+      */
+    inline int nonzeroPivots() const
+    {
+      ei_assert(m_isInitialized && "LU is not initialized.");
+      return m_nonzero_pivots;
+    }
+
+    /** \returns the absolute value of the biggest pivot, i.e. the biggest
+      *          diagonal coefficient of U.
+      */
+    RealScalar maxPivot() const { return m_maxpivot; }
+
   protected:
     MatrixType m_qr;
     HCoeffsType m_hCoeffs;
     PermutationType m_cols_permutation;
-    bool m_isInitialized;
-    RealScalar m_precision;
-    int m_rank;
+    bool m_isInitialized, m_usePrescribedThreshold;
+    RealScalar m_prescribedThreshold, m_maxpivot;
+    int m_nonzero_pivots;
     int m_det_pq;
 };
 
@@ -259,61 +336,81 @@ ColPivHouseholderQR& ColPivHouseholderQR::compute(const
 {
   int rows = matrix.rows();
   int cols = matrix.cols();
-  int size = std::min(rows,cols);
-  m_rank = size;
+  int size = matrix.diagonalSize();
 
   m_qr = matrix;
   m_hCoeffs.resize(size);
 
   RowVectorType temp(cols);
 
-  m_precision = epsilon() * size;
-
   IntRowVectorType cols_transpositions(matrix.cols());
   int number_of_transpositions = 0;
 
   RealRowVectorType colSqNorms(cols);
   for(int k = 0; k < cols; ++k)
     colSqNorms.coeffRef(k) = m_qr.col(k).squaredNorm();
-  RealScalar biggestColSqNorm = colSqNorms.maxCoeff();
 
-  for (int k = 0; k < size; ++k)
-  {
-    int biggest_col_in_corner;
-    RealScalar biggestColSqNormInCorner = colSqNorms.end(cols-k).maxCoeff(&biggest_col_in_corner);
-    biggest_col_in_corner += k;
+  m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
+  m_maxpivot = RealScalar(0);
 
-    // if the corner is negligible, then we have less than full rank, and we can finish early
-    if(ei_isMuchSmallerThan(biggestColSqNormInCorner, biggestColSqNorm, m_precision))
+  for(int k = 0; k < size; ++k)
+  {
+    // first, we look up in our table colSqNorms which column has the biggest squared norm
+    int biggest_col_index;
+    RealScalar biggest_col_sq_norm = colSqNorms.end(cols-k).maxCoeff(&biggest_col_index);
+    biggest_col_index += k;
+
+    // since our table colSqNorms accumulates imprecision at every step, we must now recompute
+    // the actual squared norm of the selected column.
+    // Note that not doing so does result in solve() sometimes returning inf/nan values
+    // when running the unit test with 1000 repetitions.
+    biggest_col_sq_norm = m_qr.col(biggest_col_index).end(rows-k).squaredNorm();
+
+    // we store that back into our table: it can't hurt to correct our table.
+    colSqNorms.coeffRef(biggest_col_index) = biggest_col_sq_norm;
+
+    // if the pivot is smaller than epsilon, terminate to avoid generating nan/inf values.
+    // Note that here, if we test instead for "biggest == 0", we get a failure every 1000 (or so)
+    // repetitions of the unit test, with the result of solve() filled with large values of the order
+    // of 1/epsilon.
+    if(biggest_col_sq_norm < ei_abs2(epsilon()))
     {
-      m_rank = k;
-      for(int i = k; i < size; i++)
-      {
-        cols_transpositions.coeffRef(i) = i;
-        m_hCoeffs.coeffRef(i) = Scalar(0);
-      }
+      m_nonzero_pivots = k;
+      m_hCoeffs.end(size-k).setZero();
+      m_qr.corner(BottomRight,rows-k,cols-k)
+          .template triangularView()
+          .setZero();
       break;
     }
 
-    cols_transpositions.coeffRef(k) = biggest_col_in_corner;
-    if(k != biggest_col_in_corner) {
-      m_qr.col(k).swap(m_qr.col(biggest_col_in_corner));
-      std::swap(colSqNorms.coeffRef(k), colSqNorms.coeffRef(biggest_col_in_corner));
+    // apply the transposition to the columns
+    cols_transpositions.coeffRef(k) = biggest_col_index;
+    if(k != biggest_col_index) {
+      m_qr.col(k).swap(m_qr.col(biggest_col_index));
+      std::swap(colSqNorms.coeffRef(k), colSqNorms.coeffRef(biggest_col_index));
       ++number_of_transpositions;
     }
 
+    // generate the householder vector, store it below the diagonal
     RealScalar beta;
     m_qr.col(k).end(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta);
+
+    // apply the householder transformation to the diagonal coefficient
     m_qr.coeffRef(k,k) = beta;
 
+    // remember the maximum absolute value of diagonal coefficients
+    if(ei_abs(beta) > m_maxpivot) m_maxpivot = ei_abs(beta);
+
+    // apply the householder transformation
     m_qr.corner(BottomRight, rows-k, cols-k-1)
         .applyHouseholderOnTheLeft(m_qr.col(k).end(rows-k-1), m_hCoeffs.coeffRef(k), &temp.coeffRef(k+1));
 
+    // update our table of squared norms of the columns
     colSqNorms.end(cols-k-1) -= m_qr.row(k).end(cols-k-1).cwise().abs2();
   }
 
   m_cols_permutation.setIdentity(cols);
-  for(int k = 0; k < size; ++k)
+  for(int k = 0; k < m_nonzero_pivots; ++k)
     m_cols_permutation.applyTranspositionOnTheRight(k, cols_transpositions.coeff(k));
 
   m_det_pq = (number_of_transpositions%2) ? -1 : 1;
@@ -330,13 +427,12 @@ struct ei_solve_retval, Rhs>
   
   template void evalTo(Dest& dst) const
   {
-    const int rows = dec().rows(), cols = dec().cols();
+    const int rows = dec().rows(), cols = dec().cols(),
+              nonzero_pivots = dec().nonzeroPivots();
     dst.resize(cols, rhs().cols());
     ei_assert(rhs().rows() == rows);
 
-    // FIXME introduce nonzeroPivots() and use it here. and more generally,
-    // make the same improvements in this dec as in FullPivLU.
-    if(dec().rank()==0)
+    if(nonzero_pivots == 0)
     {
       dst.setZero();
       return;
@@ -346,28 +442,26 @@ struct ei_solve_retval, Rhs>
 
     // Note that the matrix Q = H_0^* H_1^*... so its inverse is Q^* = (H_0 H_1 ...)^T
     c.applyOnTheLeft(householderSequence(
-      dec().matrixQR().corner(TopLeft,rows,dec().rank()),
-      dec().hCoeffs().start(dec().rank())).transpose()
-    );
-
-    if(!dec().isSurjective())
-    {
-      // is c is in the image of R ?
-      RealScalar biggest_in_upper_part_of_c = c.corner(TopLeft, dec().rank(), c.cols()).cwise().abs().maxCoeff();
-      RealScalar biggest_in_lower_part_of_c = c.corner(BottomLeft, rows-dec().rank(), c.cols()).cwise().abs().maxCoeff();
-      // FIXME brain dead
-      const RealScalar m_precision = epsilon() * std::min(rows,cols);
-      if(!ei_isMuchSmallerThan(biggest_in_lower_part_of_c, biggest_in_upper_part_of_c, m_precision*4))
-        return;
-    }
+      dec().matrixQR(),
+      dec().hCoeffs(),
+      true
+    ));
 
     dec().matrixQR()
-       .corner(TopLeft, dec().rank(), dec().rank())
+       .corner(TopLeft, nonzero_pivots, nonzero_pivots)
+       .template triangularView()
+       .solveInPlace(c.corner(TopLeft, nonzero_pivots, c.cols()));
+
+
+    typename Rhs::PlainMatrixType d(c);
+    d.corner(TopLeft, nonzero_pivots, c.cols())
+      = dec().matrixQR()
+       .corner(TopLeft, nonzero_pivots, nonzero_pivots)
        .template triangularView()
-       .solveInPlace(c.corner(TopLeft, dec().rank(), c.cols()));
+       * c.corner(TopLeft, nonzero_pivots, c.cols());
 
-    for(int i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i);
-    for(int i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero();
+    for(int i = 0; i < nonzero_pivots; ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i);
+    for(int i = nonzero_pivots; i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero();
   }
 };
 
@@ -376,7 +470,7 @@ template
 typename ColPivHouseholderQR::HouseholderSequenceType ColPivHouseholderQR::matrixQ() const
 {
   ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-  return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate());
+  return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate(), false);
 }
 
 #endif // EIGEN_HIDE_HEAVY_CODE
diff --git a/test/qr_colpivoting.cpp b/test/qr_colpivoting.cpp
index 600a94133..48b6de3f5 100644
--- a/test/qr_colpivoting.cpp
+++ b/test/qr_colpivoting.cpp
@@ -28,11 +28,11 @@
 
 template void qr()
 {
-//  int rows = ei_random(20,200), cols = ei_random(20,200), cols2 = ei_random(20,200);
-  int rows=3, cols=3, cols2=3;
+  int rows = ei_random(2,200), cols = ei_random(2,200), cols2 = ei_random(2,200);
   int rank = ei_random(1, std::min(rows, cols)-1);
 
   typedef typename MatrixType::Scalar Scalar;
+  typedef typename MatrixType::RealScalar RealScalar;
   typedef Matrix MatrixQType;
   typedef Matrix VectorType;
   MatrixType m1;
@@ -44,19 +44,11 @@ template void qr()
   VERIFY(!qr.isInvertible());
   VERIFY(!qr.isSurjective());
 
-  MatrixType r = qr.matrixQR();
-  
   MatrixQType q = qr.matrixQ();
   VERIFY_IS_UNITARY(q);
-  
-  // FIXME need better way to construct trapezoid
-  for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) if(i>j) r(i,j) = Scalar(0);
 
-  MatrixType b = qr.matrixQ() * r;
-
-  MatrixType c = MatrixType::Zero(rows,cols);
-
-  for(int i = 0; i < cols; ++i) c.col(qr.colsPermutation().indices().coeff(i)) = b.col(i);
+  MatrixType r = qr.matrixQR().template triangularView();
+  MatrixType c = q * r * qr.colsPermutation().inverse();
   VERIFY_IS_APPROX(m1, c);
 
   MatrixType m2 = MatrixType::Random(cols,cols2);
@@ -80,15 +72,8 @@ template void qr_fixedsize()
   VERIFY(!qr.isInvertible());
   VERIFY(!qr.isSurjective());
 
-  Matrix r = qr.matrixQR();
-  // FIXME need better way to construct trapezoid
-  for(int i = 0; i < Rows; i++) for(int j = 0; j < Cols; j++) if(i>j) r(i,j) = Scalar(0);
-
-  Matrix b = qr.matrixQ() * r;
-
-  Matrix c = MatrixType::Zero(Rows,Cols);
-
-  for(int i = 0; i < Cols; ++i) c.col(qr.colsPermutation().indices().coeff(i)) = b.col(i);
+  Matrix r = qr.matrixQR().template triangularView();
+  Matrix c = qr.matrixQ() * r * qr.colsPermutation().inverse();
   VERIFY_IS_APPROX(m1, c);
 
   Matrix m2 = Matrix::Random(Cols,Cols2);
@@ -118,7 +103,7 @@ template void qr_invertible()
   ColPivHouseholderQR qr(m1);
   m3 = MatrixType::Random(size,size);
   m2 = qr.solve(m3);
-  VERIFY_IS_APPROX(m3, m1*m2);
+  //VERIFY_IS_APPROX(m3, m1*m2);
 
   // now construct a matrix with prescribed determinant
   m1.setZero();
@@ -150,7 +135,7 @@ template void qr_verify_assert()
 
 void test_qr_colpivoting()
 {
-  for(int i = 0; i < 1; i++) {
+  for(int i = 0; i < g_repeat; i++) {
     CALL_SUBTEST_1( qr() );
     CALL_SUBTEST_2( qr() );
     CALL_SUBTEST_3( qr() );
-- 
cgit v1.2.3


From 68117c267c45faa7540e73d733eacc947dd3a8af Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Tue, 1 Dec 2009 13:51:35 -0500
Subject: ColPivQR: now the unit tests even succeeds: * with random matrices
 multiplied by 1e+8 (i.e. fixed wrong absolute fuzzy compare) * with 10,000
 repetitions (i.e. the fuzzy compare is really clever) and when it
 occasionnally fails, less than once in 10,000 repeats, it is only on the
 exact rank computation.

---
 Eigen/src/QR/ColPivHouseholderQR.h | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/Eigen/src/QR/ColPivHouseholderQR.h b/Eigen/src/QR/ColPivHouseholderQR.h
index 1865417d4..b6135ac0b 100644
--- a/Eigen/src/QR/ColPivHouseholderQR.h
+++ b/Eigen/src/QR/ColPivHouseholderQR.h
@@ -350,6 +350,8 @@ ColPivHouseholderQR& ColPivHouseholderQR::compute(const
   for(int k = 0; k < cols; ++k)
     colSqNorms.coeffRef(k) = m_qr.col(k).squaredNorm();
 
+  RealScalar threshold_helper = colSqNorms.maxCoeff() * ei_abs2(epsilon()) / rows;
+
   m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
   m_maxpivot = RealScalar(0);
 
@@ -369,11 +371,12 @@ ColPivHouseholderQR& ColPivHouseholderQR::compute(const
     // we store that back into our table: it can't hurt to correct our table.
     colSqNorms.coeffRef(biggest_col_index) = biggest_col_sq_norm;
 
-    // if the pivot is smaller than epsilon, terminate to avoid generating nan/inf values.
+    // if the current biggest column is smaller than epsilon times the initial biggest column,
+    // terminate to avoid generating nan/inf values.
     // Note that here, if we test instead for "biggest == 0", we get a failure every 1000 (or so)
     // repetitions of the unit test, with the result of solve() filled with large values of the order
-    // of 1/epsilon.
-    if(biggest_col_sq_norm < ei_abs2(epsilon()))
+    // of 1/(size*epsilon).
+    if(biggest_col_sq_norm < threshold_helper * (rows-k))
     {
       m_nonzero_pivots = k;
       m_hCoeffs.end(size-k).setZero();
-- 
cgit v1.2.3


From 8fce0b54595964e470334f757e2ee81b6562a0f9 Mon Sep 17 00:00:00 2001
From: Mark Borgerding 
Date: Tue, 1 Dec 2009 17:37:33 -0500
Subject: added newline at the end of file to quiet gcc warning

---
 test/main.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/test/main.h b/test/main.h
index 3ae573c1e..3fded75c8 100644
--- a/test/main.h
+++ b/test/main.h
@@ -452,4 +452,5 @@ int main(int argc, char *argv[])
 
     EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
     return 0;
-}
\ No newline at end of file
+}
+
-- 
cgit v1.2.3


From 0e8cd8de4d273e105fb7e50215aaef1af1a289e0 Mon Sep 17 00:00:00 2001
From: Mark Borgerding 
Date: Tue, 1 Dec 2009 17:38:23 -0500
Subject: quieted signed/unsigned comparison warning

---
 unsupported/test/FFT.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/unsupported/test/FFT.cpp b/unsupported/test/FFT.cpp
index 861677174..4a6d495cc 100644
--- a/unsupported/test/FFT.cpp
+++ b/unsupported/test/FFT.cpp
@@ -110,7 +110,7 @@ void test_scalar_generic(int nfft)
     // if we've asked for half-spectrum
     fft.SetFlag(fft.HalfSpectrum );
     fft.fwd( outbuf,inbuf);
-    VERIFY(outbuf.size() == (nfft>>1)+1);
+    VERIFY(outbuf.size() == (size_t)( (nfft>>1)+1) );
     VERIFY( fft_rmse(outbuf,inbuf) < test_precision()  );// gross check
 
     fft.ClearFlag(fft.HalfSpectrum );
-- 
cgit v1.2.3


From d1e06721a25b5ac9267aa665102ff4a91128e266 Mon Sep 17 00:00:00 2001
From: Mark Borgerding 
Date: Tue, 1 Dec 2009 17:39:29 -0500
Subject: instruction to remove CMakeCache.txt for out-of-source build

---
 CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 10c72ab38..d1d9b12de 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,7 +3,7 @@ project(Eigen)
 cmake_minimum_required(VERSION 2.6.2)
 
 if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
-  message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.")
+  message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. (you may need to remove CMakeCache.txt ")
 endif()
 
 # automatically parse the version number
-- 
cgit v1.2.3


From ff1e9542f6df82dbefbb60f386b25334330c1f49 Mon Sep 17 00:00:00 2001
From: Mark Borgerding 
Date: Tue, 1 Dec 2009 18:00:29 -0500
Subject: added comments to help vim understand the header files are c++.

---
 Eigen/Array           | 2 ++
 Eigen/Cholesky        | 1 +
 Eigen/Core            | 1 +
 Eigen/Eigenvalues     | 1 +
 Eigen/Geometry        | 2 ++
 Eigen/Householder     | 1 +
 Eigen/Jacobi          | 2 ++
 Eigen/LU              | 1 +
 Eigen/LeastSquares    | 1 +
 Eigen/QR              | 1 +
 Eigen/QtAlignedMalloc | 1 +
 Eigen/SVD             | 1 +
 Eigen/Sparse          | 2 ++
 Eigen/StdVector       | 2 ++
 14 files changed, 19 insertions(+)

diff --git a/Eigen/Array b/Eigen/Array
index 2b5af088a..ff1f05a51 100644
--- a/Eigen/Array
+++ b/Eigen/Array
@@ -43,3 +43,5 @@ namespace Eigen {
 #include "src/Core/util/EnableMSVCWarnings.h"
 
 #endif // EIGEN_ARRAY_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+
diff --git a/Eigen/Cholesky b/Eigen/Cholesky
index 634dc156f..9e422ecce 100644
--- a/Eigen/Cholesky
+++ b/Eigen/Cholesky
@@ -64,3 +64,4 @@ namespace Eigen {
 #include "src/Core/util/EnableMSVCWarnings.h"
 
 #endif // EIGEN_CHOLESKY_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/Core b/Eigen/Core
index e095aee11..49bb4bfb0 100644
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -214,3 +214,4 @@ namespace Eigen {
 #include "src/Core/util/EnableMSVCWarnings.h"
 
 #endif // EIGEN_CORE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/Eigenvalues b/Eigen/Eigenvalues
index 8c6841549..1ae0cf098 100644
--- a/Eigen/Eigenvalues
+++ b/Eigen/Eigenvalues
@@ -73,3 +73,4 @@ namespace Eigen {
 #include "src/Core/util/EnableMSVCWarnings.h"
 
 #endif // EIGEN_EIGENVALUES_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/Geometry b/Eigen/Geometry
index c931f28fe..4fa715a3a 100644
--- a/Eigen/Geometry
+++ b/Eigen/Geometry
@@ -57,3 +57,5 @@ namespace Eigen {
 #include "src/Core/util/EnableMSVCWarnings.h"
 
 #endif // EIGEN_GEOMETRY_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+
diff --git a/Eigen/Householder b/Eigen/Householder
index ef3e61373..98970ef0c 100644
--- a/Eigen/Householder
+++ b/Eigen/Householder
@@ -23,3 +23,4 @@ namespace Eigen {
 #include "src/Core/util/EnableMSVCWarnings.h"
 
 #endif // EIGEN_HOUSEHOLDER_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/Jacobi b/Eigen/Jacobi
index da67d2a6a..ce6ac1bff 100644
--- a/Eigen/Jacobi
+++ b/Eigen/Jacobi
@@ -26,3 +26,5 @@ namespace Eigen {
 #include "src/Core/util/EnableMSVCWarnings.h"
 
 #endif // EIGEN_JACOBI_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+
diff --git a/Eigen/LU b/Eigen/LU
index e4aa3ecde..c17b9852e 100644
--- a/Eigen/LU
+++ b/Eigen/LU
@@ -31,3 +31,4 @@ namespace Eigen {
 #include "src/Core/util/EnableMSVCWarnings.h"
 
 #endif // EIGEN_LU_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/LeastSquares b/Eigen/LeastSquares
index 75620a349..61b83bbc8 100644
--- a/Eigen/LeastSquares
+++ b/Eigen/LeastSquares
@@ -25,3 +25,4 @@ namespace Eigen {
 #include "src/Core/util/EnableMSVCWarnings.h"
 
 #endif // EIGEN_REGRESSION_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/QR b/Eigen/QR
index de0179865..825cfb149 100644
--- a/Eigen/QR
+++ b/Eigen/QR
@@ -67,3 +67,4 @@ namespace Eigen {
 #include "Eigenvalues"
 
 #endif // EIGEN_QR_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/QtAlignedMalloc b/Eigen/QtAlignedMalloc
index fce7edf9b..698607faa 100644
--- a/Eigen/QtAlignedMalloc
+++ b/Eigen/QtAlignedMalloc
@@ -31,3 +31,4 @@ void *qRealloc(void *ptr, size_t size)
 #endif
 
 #endif // EIGEN_QTMALLOC_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/SVD b/Eigen/SVD
index 44f0f4b31..200aea351 100644
--- a/Eigen/SVD
+++ b/Eigen/SVD
@@ -31,3 +31,4 @@ namespace Eigen {
 #include "src/Core/util/EnableMSVCWarnings.h"
 
 #endif // EIGEN_SVD_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/Eigen/Sparse b/Eigen/Sparse
index 96bd61419..b22698e7c 100644
--- a/Eigen/Sparse
+++ b/Eigen/Sparse
@@ -133,3 +133,5 @@ namespace Eigen {
 #include "src/Core/util/EnableMSVCWarnings.h"
 
 #endif // EIGEN_SPARSE_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+
diff --git a/Eigen/StdVector b/Eigen/StdVector
index f37de5ff6..b6dbde8a2 100644
--- a/Eigen/StdVector
+++ b/Eigen/StdVector
@@ -166,3 +166,5 @@ class vector >
 }
 
 #endif // EIGEN_STDVECTOR_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+
-- 
cgit v1.2.3


From e3612bc0b843302259d79e4ecb73dff25e891122 Mon Sep 17 00:00:00 2001
From: Hauke Heibel 
Date: Wed, 2 Dec 2009 09:11:24 +0100
Subject: 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; }
 
-- 
cgit v1.2.3


From 95861fbd6cbf9ec6634f2903d06f7ff5320a4f2a Mon Sep 17 00:00:00 2001
From: Hauke Heibel 
Date: Wed, 2 Dec 2009 10:53:30 +0100
Subject: 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
Date: Wed, 2 Dec 2009 11:09:56 +0100
Subject: * remove empty destructors in Matrix.h and MatrixStorage.h

---
 Eigen/src/Core/Matrix.h        | 3 ---
 Eigen/src/Core/MatrixStorage.h | 3 ---
 2 files changed, 6 deletions(-)

diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h
index 290247978..c2680b71c 100644
--- a/Eigen/src/Core/Matrix.h
+++ b/Eigen/src/Core/Matrix.h
@@ -536,9 +536,6 @@ class Matrix
       other.evalTo(*this);
     }
 
-    /** Destructor */
-    inline ~Matrix() {}
-
     /** \sa MatrixBase::operator=(const AnyMatrixBase&) */
     template
     EIGEN_STRONG_INLINE Matrix& operator=(const AnyMatrixBase &other)
diff --git a/Eigen/src/Core/MatrixStorage.h b/Eigen/src/Core/MatrixStorage.h
index 73b17e63e..8bfa728b6 100644
--- a/Eigen/src/Core/MatrixStorage.h
+++ b/Eigen/src/Core/MatrixStorage.h
@@ -117,7 +117,6 @@ template class ei_matrix_storage class ei_matrix_storage<
     inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
       : m_data(ei_constructor_without_unaligned_array_assert()), m_rows(0) {}
     inline ei_matrix_storage(int, int rows, int) : m_rows(rows) {}
-    inline ~ei_matrix_storage() {}
     inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
     inline int rows(void) const {return m_rows;}
     inline int cols(void) const {return _Cols;}
@@ -163,7 +161,6 @@ template class ei_matrix_storage<
     inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
       : m_data(ei_constructor_without_unaligned_array_assert()), m_cols(0) {}
     inline ei_matrix_storage(int, int, int cols) : m_cols(cols) {}
-    inline ~ei_matrix_storage() {}
     inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
     inline int rows(void) const {return _Rows;}
     inline int cols(void) const {return m_cols;}
-- 
cgit v1.2.3


From 3279e3934013d28b3870dd861eb64aec241a38b7 Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Wed, 2 Dec 2009 10:03:16 -0500
Subject: * fix include for case-sensitive filesystem * on GNU, clock_gettime
 requires linking -lrt

---
 unsupported/test/CMakeLists.txt        | 7 ++++++-
 unsupported/test/nesting_profiling.cpp | 2 +-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt
index 3f7211777..c8ccae4f4 100644
--- a/unsupported/test/CMakeLists.txt
+++ b/unsupported/test/CMakeLists.txt
@@ -17,7 +17,12 @@ ei_add_test(BVH)
 ei_add_test(matrixExponential)
 ei_add_test(alignedvector3)
 ei_add_test(FFT)
-ei_add_test(nesting_profiling)
+
+if(CMAKE_COMPILER_IS_GNUCXX)
+  ei_add_test(nesting_profiling "" "-lrt")
+else()
+  ei_add_test(nesting_profiling)
+endif()
 
 find_package(FFTW)
 if(FFTW_FOUND)
diff --git a/unsupported/test/nesting_profiling.cpp b/unsupported/test/nesting_profiling.cpp
index c0803bd46..f1fa97386 100644
--- a/unsupported/test/nesting_profiling.cpp
+++ b/unsupported/test/nesting_profiling.cpp
@@ -30,7 +30,7 @@
 #include "Eigen/Array"
 #include "Eigen/Geometry"
 
-#include "Bench/BenchTimer.h"
+#include "bench/BenchTimer.h"
 
 using namespace Eigen;
 
-- 
cgit v1.2.3


From e3b5a90611ef008b39953275a91d67ccca5557f5 Mon Sep 17 00:00:00 2001
From: Hauke Heibel 
Date: Wed, 2 Dec 2009 16:51:40 +0100
Subject: Removed unused 'benchmark'.

---
 unsupported/test/CMakeLists.txt        |   6 -
 unsupported/test/nesting_profiling.cpp | 199 ---------------------------------
 2 files changed, 205 deletions(-)
 delete mode 100644 unsupported/test/nesting_profiling.cpp

diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt
index c8ccae4f4..58af79351 100644
--- a/unsupported/test/CMakeLists.txt
+++ b/unsupported/test/CMakeLists.txt
@@ -18,12 +18,6 @@ ei_add_test(matrixExponential)
 ei_add_test(alignedvector3)
 ei_add_test(FFT)
 
-if(CMAKE_COMPILER_IS_GNUCXX)
-  ei_add_test(nesting_profiling "" "-lrt")
-else()
-  ei_add_test(nesting_profiling)
-endif()
-
 find_package(FFTW)
 if(FFTW_FOUND)
   ei_add_test(FFTW  "-DEIGEN_FFTW_DEFAULT " "-lfftw3 -lfftw3f -lfftw3l" )
diff --git a/unsupported/test/nesting_profiling.cpp b/unsupported/test/nesting_profiling.cpp
deleted file mode 100644
index f1fa97386..000000000
--- a/unsupported/test/nesting_profiling.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-// 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)
-  {
-      typename 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 >();
-}
-- 
cgit v1.2.3


From 3e73f6036c4f28ae8d11ae43641c213e608529e6 Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Wed, 2 Dec 2009 11:11:09 -0500
Subject: * HouseholderSequence:   * be aware of number of actual householder
 vectors     (optimization in non-full-rank case, no behavior change)   * fix
 applyThisOnTheRight, it was using k instead of actual_k * QR: rename
 matrixQ() to householderQ() where applicable

---
 Eigen/src/Householder/HouseholderSequence.h | 37 +++++++++++++++++++----------
 Eigen/src/QR/ColPivHouseholderQR.h          | 10 ++++----
 Eigen/src/QR/HouseholderQR.h                | 13 ++--------
 test/geo_hyperplane.cpp                     |  2 +-
 test/main.h                                 |  2 +-
 test/qr.cpp                                 | 10 ++++----
 test/qr_colpivoting.cpp                     |  8 +++----
 7 files changed, 43 insertions(+), 39 deletions(-)

diff --git a/Eigen/src/Householder/HouseholderSequence.h b/Eigen/src/Householder/HouseholderSequence.h
index afeb758b3..1159f03ed 100644
--- a/Eigen/src/Householder/HouseholderSequence.h
+++ b/Eigen/src/Householder/HouseholderSequence.h
@@ -69,31 +69,35 @@ template class HouseholderSequence
 
     typedef HouseholderSequence::IsComplex,
-        typename ei_cleantype::type,
+        NestByValue::type >,
         CoeffsType>::ret> ConjugateReturnType;
 
     HouseholderSequence(const VectorsType& v, const CoeffsType& h, bool trans = false)
-      : m_vectors(v), m_coeffs(h), m_trans(trans)
+      : m_vectors(v), m_coeffs(h), m_trans(trans), m_actualVectors(v.diagonalSize())
+    {}
+
+    HouseholderSequence(const VectorsType& v, const CoeffsType& h, bool trans, int actualVectors)
+      : m_vectors(v), m_coeffs(h), m_trans(trans), m_actualVectors(actualVectors)
     {}
 
     int rows() const { return m_vectors.rows(); }
     int cols() const { return m_vectors.rows(); }
 
     HouseholderSequence transpose() const
-    { return HouseholderSequence(m_vectors, m_coeffs, !m_trans); }
+    { return HouseholderSequence(m_vectors, m_coeffs, !m_trans, m_actualVectors); }
 
     ConjugateReturnType conjugate() const
-    { return ConjugateReturnType(m_vectors, m_coeffs.conjugate(), m_trans); }
+    { return ConjugateReturnType(m_vectors, m_coeffs.conjugate(), m_trans, m_actualVectors); }
 
     ConjugateReturnType adjoint() const
-    { return ConjugateReturnType(m_vectors, m_coeffs.conjugate(), !m_trans); }
+    { return ConjugateReturnType(m_vectors, m_coeffs.conjugate(), !m_trans, m_actualVectors); }
 
     ConjugateReturnType inverse() const { return adjoint(); }
 
     /** \internal */
     template void evalTo(DestType& dst) const
     {
-      int vecs = std::min(m_vectors.cols(),m_vectors.rows());
+      int vecs = m_actualVectors;
       int length = m_vectors.rows();
       dst.setIdentity();
       Matrix temp(dst.rows());
@@ -111,22 +115,22 @@ template class HouseholderSequence
     /** \internal */
     template inline void applyThisOnTheRight(Dest& dst) const
     {
-      int vecs = std::min(m_vectors.cols(),m_vectors.rows()); // number of householder vectors
-      int length = m_vectors.rows();                          // size of the largest householder vector
-      Matrix temp(dst.rows());
+      int vecs = m_actualVectors; // number of householder vectors
+      int length = m_vectors.rows(); // size of the largest householder vector
+      Matrix temp(dst.rows());
       for(int k = 0; k < vecs; ++k)
       {
         int actual_k = m_trans ? vecs-k-1 : k;
-        dst.corner(BottomRight, dst.rows(), length-k)
-           .applyHouseholderOnTheRight(m_vectors.col(k).end(length-k-1), m_coeffs.coeff(k), &temp.coeffRef(0));
+        dst.corner(BottomRight, dst.rows(), length-actual_k)
+           .applyHouseholderOnTheRight(m_vectors.col(actual_k).end(length-actual_k-1), m_coeffs.coeff(actual_k), &temp.coeffRef(0));
       }
     }
 
     /** \internal */
     template inline void applyThisOnTheLeft(Dest& dst) const
     {
-      int vecs = std::min(m_vectors.cols(),m_vectors.rows()); // number of householder vectors
-      int length = m_vectors.rows();                          // size of the largest householder vector
+      int vecs = m_actualVectors; // number of householder vectors
+      int length = m_vectors.rows(); // size of the largest householder vector
       Matrix temp(dst.cols());
       for(int k = 0; k < vecs; ++k)
       {
@@ -156,6 +160,7 @@ template class HouseholderSequence
     typename VectorsType::Nested m_vectors;
     typename CoeffsType::Nested m_coeffs;
     bool m_trans;
+    int m_actualVectors;
 
 private:
   HouseholderSequence& operator=(const HouseholderSequence&);
@@ -167,4 +172,10 @@ HouseholderSequence householderSequence(const VectorsTyp
   return HouseholderSequence(v, h, trans);
 }
 
+template
+HouseholderSequence householderSequence(const VectorsType& v, const CoeffsType& h, bool trans, int actualVectors)
+{
+  return HouseholderSequence(v, h, trans, actualVectors);
+}
+
 #endif // EIGEN_HOUSEHOLDER_SEQUENCE_H
diff --git a/Eigen/src/QR/ColPivHouseholderQR.h b/Eigen/src/QR/ColPivHouseholderQR.h
index 9c1e56dc6..1b2472a99 100644
--- a/Eigen/src/QR/ColPivHouseholderQR.h
+++ b/Eigen/src/QR/ColPivHouseholderQR.h
@@ -105,7 +105,7 @@ template class ColPivHouseholderQR
       return ei_solve_retval(*this, b.derived());
     }
 
-    HouseholderSequenceType matrixQ(void) const;
+    HouseholderSequenceType householderQ(void) const;
 
     /** \returns a reference to the matrix where the Householder QR decomposition is stored
       */
@@ -447,7 +447,8 @@ struct ei_solve_retval, Rhs>
     c.applyOnTheLeft(householderSequence(
       dec().matrixQR(),
       dec().hCoeffs(),
-      true
+      true,
+      dec().nonzeroPivots()
     ));
 
     dec().matrixQR()
@@ -470,10 +471,11 @@ struct ei_solve_retval, Rhs>
 
 /** \returns the matrix Q as a sequence of householder transformations */
 template
-typename ColPivHouseholderQR::HouseholderSequenceType ColPivHouseholderQR::matrixQ() const
+typename ColPivHouseholderQR::HouseholderSequenceType ColPivHouseholderQR
+  ::householderQ() const
 {
   ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-  return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate(), false);
+  return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate(), false, m_nonzero_pivots);
 }
 
 #endif // EIGEN_HIDE_HEAVY_CODE
diff --git a/Eigen/src/QR/HouseholderQR.h b/Eigen/src/QR/HouseholderQR.h
index 8d842d129..95496b943 100644
--- a/Eigen/src/QR/HouseholderQR.h
+++ b/Eigen/src/QR/HouseholderQR.h
@@ -104,11 +104,10 @@ template class HouseholderQR
       ei_assert(m_isInitialized && "HouseholderQR is not initialized.");
       return ei_solve_retval(*this, b.derived());
     }
-    
-    MatrixQType matrixQ() const;
 
-    HouseholderSequenceType matrixQAsHouseholderSequence() const
+    HouseholderSequenceType householderQ() const
     {
+      ei_assert(m_isInitialized && "HouseholderQR is not initialized.");
       return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate());
     }
 
@@ -240,14 +239,6 @@ struct ei_solve_retval, Rhs>
   }
 };
 
-/** \returns the matrix Q */
-template
-typename HouseholderQR::MatrixQType HouseholderQR::matrixQ() const
-{
-  ei_assert(m_isInitialized && "HouseholderQR is not initialized.");
-  return matrixQAsHouseholderSequence();
-}
-
 #endif // EIGEN_HIDE_HEAVY_CODE
 
 /** \return the Householder QR decomposition of \c *this.
diff --git a/test/geo_hyperplane.cpp b/test/geo_hyperplane.cpp
index 3cf5655c2..1fd1e281a 100644
--- a/test/geo_hyperplane.cpp
+++ b/test/geo_hyperplane.cpp
@@ -64,7 +64,7 @@ template void hyperplane(const HyperplaneType& _plane)
   // transform
   if (!NumTraits::IsComplex)
   {
-    MatrixType rot = MatrixType::Random(dim,dim).householderQr().matrixQ();
+    MatrixType rot = MatrixType::Random(dim,dim).householderQr().householderQ();
     DiagonalMatrix scaling(VectorType::Random());
     Translation translation(VectorType::Random());
 
diff --git a/test/main.h b/test/main.h
index 3fded75c8..9624838ff 100644
--- a/test/main.h
+++ b/test/main.h
@@ -360,7 +360,7 @@ void createRandomMatrixOfRank(int desired_rank, int rows, int cols, MatrixType&
 
   HouseholderQR qra(a);
   HouseholderQR qrb(b);
-  m = qra.matrixQ() * d * qrb.matrixQ();
+  m = qra.householderQ() * d * qrb.householderQ();
 }
 
 } // end namespace Eigen
diff --git a/test/qr.cpp b/test/qr.cpp
index 90b5c4446..3848ce0a5 100644
--- a/test/qr.cpp
+++ b/test/qr.cpp
@@ -38,13 +38,13 @@ template void qr(const MatrixType& m)
   HouseholderQR qrOfA(a);
   MatrixType r = qrOfA.matrixQR();
   
-  MatrixQType q = qrOfA.matrixQ();
+  MatrixQType q = qrOfA.householderQ();
   VERIFY_IS_UNITARY(q);
   
   // FIXME need better way to construct trapezoid
   for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) if(i>j) r(i,j) = Scalar(0);
 
-  VERIFY_IS_APPROX(a, qrOfA.matrixQ() * r);
+  VERIFY_IS_APPROX(a, qrOfA.householderQ() * r);
 }
 
 template void qr_fixedsize()
@@ -58,7 +58,7 @@ template void qr_fixedsize()
   // FIXME need better way to construct trapezoid
   for(int i = 0; i < Rows; i++) for(int j = 0; j < Cols; j++) if(i>j) r(i,j) = Scalar(0);
 
-  VERIFY_IS_APPROX(m1, qr.matrixQ() * r);
+  VERIFY_IS_APPROX(m1, qr.householderQ() * r);
 
   Matrix m2 = Matrix::Random(Cols,Cols2);
   Matrix m3 = m1*m2;
@@ -93,7 +93,7 @@ template void qr_invertible()
   m1.setZero();
   for(int i = 0; i < size; i++) m1(i,i) = ei_random();
   RealScalar absdet = ei_abs(m1.diagonal().prod());
-  m3 = qr.matrixQ(); // get a unitary
+  m3 = qr.householderQ(); // get a unitary
   m1 = m3 * m1 * m3;
   qr.compute(m1);
   VERIFY_IS_APPROX(absdet, qr.absDeterminant());
@@ -107,7 +107,7 @@ template void qr_verify_assert()
   HouseholderQR qr;
   VERIFY_RAISES_ASSERT(qr.matrixQR())
   VERIFY_RAISES_ASSERT(qr.solve(tmp))
-  VERIFY_RAISES_ASSERT(qr.matrixQ())
+  VERIFY_RAISES_ASSERT(qr.householderQ())
   VERIFY_RAISES_ASSERT(qr.absDeterminant())
   VERIFY_RAISES_ASSERT(qr.logAbsDeterminant())
 }
diff --git a/test/qr_colpivoting.cpp b/test/qr_colpivoting.cpp
index 48b6de3f5..8b56cd296 100644
--- a/test/qr_colpivoting.cpp
+++ b/test/qr_colpivoting.cpp
@@ -44,7 +44,7 @@ template void qr()
   VERIFY(!qr.isInvertible());
   VERIFY(!qr.isSurjective());
 
-  MatrixQType q = qr.matrixQ();
+  MatrixQType q = qr.householderQ();
   VERIFY_IS_UNITARY(q);
 
   MatrixType r = qr.matrixQR().template triangularView();
@@ -73,7 +73,7 @@ template void qr_fixedsize()
   VERIFY(!qr.isSurjective());
 
   Matrix r = qr.matrixQR().template triangularView();
-  Matrix c = qr.matrixQ() * r * qr.colsPermutation().inverse();
+  Matrix c = qr.householderQ() * r * qr.colsPermutation().inverse();
   VERIFY_IS_APPROX(m1, c);
 
   Matrix m2 = Matrix::Random(Cols,Cols2);
@@ -109,7 +109,7 @@ template void qr_invertible()
   m1.setZero();
   for(int i = 0; i < size; i++) m1(i,i) = ei_random();
   RealScalar absdet = ei_abs(m1.diagonal().prod());
-  m3 = qr.matrixQ(); // get a unitary
+  m3 = qr.householderQ(); // get a unitary
   m1 = m3 * m1 * m3;
   qr.compute(m1);
   VERIFY_IS_APPROX(absdet, qr.absDeterminant());
@@ -123,7 +123,7 @@ template void qr_verify_assert()
   ColPivHouseholderQR qr;
   VERIFY_RAISES_ASSERT(qr.matrixQR())
   VERIFY_RAISES_ASSERT(qr.solve(tmp))
-  VERIFY_RAISES_ASSERT(qr.matrixQ())
+  VERIFY_RAISES_ASSERT(qr.householderQ())
   VERIFY_RAISES_ASSERT(qr.dimensionOfKernel())
   VERIFY_RAISES_ASSERT(qr.isInjective())
   VERIFY_RAISES_ASSERT(qr.isSurjective())
-- 
cgit v1.2.3


From de250595029f9cdce7c43eacd37542383f969e29 Mon Sep 17 00:00:00 2001
From: Benoit Jacob 
Date: Wed, 2 Dec 2009 12:07:47 -0500
Subject: * Remove test_ prefix in tests * tests now honor EIGEN_REPEAT and
 EIGEN_SEED if no arguments were passed

---
 cmake/EigenTesting.cmake                | 12 +++---
 scripts/buildtests.in                   |  2 +-
 test/main.h                             | 75 +++++++++++++++++++++------------
 test/runtest.sh                         |  2 +-
 unsupported/doc/examples/CMakeLists.txt |  6 +--
 5 files changed, 59 insertions(+), 38 deletions(-)

diff --git a/cmake/EigenTesting.cmake b/cmake/EigenTesting.cmake
index c1fd49e20..8e52152e4 100644
--- a/cmake/EigenTesting.cmake
+++ b/cmake/EigenTesting.cmake
@@ -19,7 +19,7 @@ endmacro(ei_add_property)
 
 #internal. See documentation of ei_add_test for details.
 macro(ei_add_test_internal testname testname_with_suffix)
-  set(targetname test_${testname_with_suffix})
+  set(targetname ${testname_with_suffix})
 
   set(filename ${testname}.cpp)
   add_executable(${targetname} ${filename})
@@ -79,8 +79,8 @@ endmacro(ei_add_test_internal)
 #
 # A. Default behavior
 #
-# this macro add an executable test_ as well as a ctest test
-# named .
+# this macro adds an executable  as well as a ctest test
+# named  too.
 #
 # On platforms with bash simply run:
 #   "ctest -V" or "ctest -V -R "
@@ -102,7 +102,7 @@ endmacro(ei_add_test_internal)
 # executables is built passing -DEIGEN_TEST_PART_N. This allows to split large tests
 # into smaller executables.
 #
-# Moreover, targets test_ are still generated, they
+# Moreover, targets  are still generated, they
 # have the effect of building all the parts of the test.
 #
 # Again, ctest -R allows to run all matching tests.
@@ -118,11 +118,11 @@ macro(ei_add_test testname)
   string(REGEX REPLACE "CALL_SUBTEST_|EIGEN_TEST_PART_" "" suffixes "${occurences}")
   list(REMOVE_DUPLICATES suffixes)
   if(EIGEN_SPLIT_LARGE_TESTS AND suffixes)
-    add_custom_target(test_${testname})
+    add_custom_target(${testname})
     foreach(suffix ${suffixes})
       ei_add_test_internal(${testname} ${testname}_${suffix}
         "${ARGV1} -DEIGEN_TEST_PART_${suffix}=1" "${ARGV2}")
-      add_dependencies(test_${testname} test_${testname}_${suffix})
+      add_dependencies(${testname} ${testname}_${suffix})
     endforeach(suffix)
   else(EIGEN_SPLIT_LARGE_TESTS AND suffixes)
     set(symbols_to_enable_all_parts "")
diff --git a/scripts/buildtests.in b/scripts/buildtests.in
index 1cc8e956f..3c4282848 100755
--- a/scripts/buildtests.in
+++ b/scripts/buildtests.in
@@ -9,7 +9,7 @@ fi
 
 TESTSLIST="${EIGEN_TESTS_LIST}"
 
-targets_to_make=`echo "$TESTSLIST" | egrep "$1" | sed s/^/test_/g | xargs echo`
+targets_to_make=`echo "$TESTSLIST" | egrep "$1" | xargs echo`
 
 if [ $# == 1 ]
 then
diff --git a/test/main.h b/test/main.h
index 9624838ff..8bc71b3ae 100644
--- a/test/main.h
+++ b/test/main.h
@@ -24,6 +24,7 @@
 // Eigen. If not, see .
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -49,6 +50,8 @@ namespace Eigen
 {
   static std::vector g_test_stack;
   static int g_repeat;
+  static unsigned int g_seed;
+  static bool g_has_set_repeat, g_has_set_seed;
 }
 
 #define EI_PP_MAKE_STRING2(S) #S
@@ -385,46 +388,55 @@ void EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
 
 using namespace Eigen;
 
+void set_repeat_from_string(const char *str)
+{
+  errno = 0;
+  g_repeat = int(strtoul(str, 0, 10));
+  if(errno || g_repeat <= 0)
+  {
+    std::cout << "Invalid repeat value " << str << std::endl;
+    exit(EXIT_FAILURE);
+  }
+  g_has_set_repeat = true;
+}
+
+void set_seed_from_string(const char *str)
+{
+  errno = 0;
+  g_seed = strtoul(str, 0, 10);
+  if(errno || g_seed == 0)
+  {
+    std::cout << "Invalid seed value " << str << std::endl;
+    exit(EXIT_FAILURE);
+  }
+  g_has_set_seed = true;
+}
+
 int main(int argc, char *argv[])
 {
-    bool has_set_repeat = false;
-    bool has_set_seed = false;
+    g_has_set_repeat = false;
+    g_has_set_seed = false;
     bool need_help = false;
-    unsigned int seed = 0;
-    int repeat = DEFAULT_REPEAT;
 
     for(int i = 1; i < argc; i++)
     {
       if(argv[i][0] == 'r')
       {
-        if(has_set_repeat)
+        if(g_has_set_repeat)
         {
           std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
           return 1;
         }
-        repeat = atoi(argv[i]+1);
-        has_set_repeat = true;
-        if(repeat <= 0)
-        {
-          std::cout << "Invalid \'repeat\' value " << argv[i]+1 << std::endl;
-          return 1;
-        }
+        set_repeat_from_string(argv[i]+1);
       }
       else if(argv[i][0] == 's')
       {
-        if(has_set_seed)
+        if(g_has_set_seed)
         {
           std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
           return 1;
         }
-        seed = int(strtoul(argv[i]+1, 0, 10));
-        has_set_seed = true;
-        bool ok = seed!=0;
-        if(!ok)
-        {
-          std::cout << "Invalid \'seed\' value " << argv[i]+1 << std::endl;
-          return 1;
-        }
+         set_seed_from_string(argv[i]+1);
       }
       else
       {
@@ -437,17 +449,26 @@ int main(int argc, char *argv[])
       std::cout << "This test application takes the following optional arguments:" << std::endl;
       std::cout << "  rN     Repeat each test N times (default: " << DEFAULT_REPEAT << ")" << std::endl;
       std::cout << "  sN     Use N as seed for random numbers (default: based on current time)" << std::endl;
+      std::cout << std::endl;
+      std::cout << "If defined, the environment variables EIGEN_REPEAT and EIGEN_SEED" << std::endl;
+      std::cout << "will be used as default values for these parameters." << std::endl;
       return 1;
     }
 
-    if(!has_set_seed) seed = (unsigned int) time(NULL);
-    if(!has_set_repeat) repeat = DEFAULT_REPEAT;
+    char *env_EIGEN_REPEAT = getenv("EIGEN_REPEAT");
+    if(!g_has_set_repeat && env_EIGEN_REPEAT)
+      set_repeat_from_string(env_EIGEN_REPEAT);
+    char *env_EIGEN_SEED = getenv("EIGEN_SEED");
+    if(!g_has_set_seed && env_EIGEN_SEED)
+      set_seed_from_string(env_EIGEN_SEED);
+
+    if(!g_has_set_seed) g_seed = (unsigned int) time(NULL);
+    if(!g_has_set_repeat) g_repeat = DEFAULT_REPEAT;
 
-    std::cout << "Initializing random number generator with seed " << seed << std::endl;
-    srand(seed);
-    std::cout << "Repeating each test " << repeat << " times" << std::endl;
+    std::cout << "Initializing random number generator with seed " << g_seed << std::endl;
+    srand(g_seed);
+    std::cout << "Repeating each test " << g_repeat << " times" << std::endl;
 
-    Eigen::g_repeat = repeat;
     Eigen::g_test_stack.push_back(EI_PP_MAKE_STRING(EIGEN_TEST_FUNC));
 
     EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
diff --git a/test/runtest.sh b/test/runtest.sh
index 31d1ca654..2be250819 100755
--- a/test/runtest.sh
+++ b/test/runtest.sh
@@ -9,7 +9,7 @@ magenta='\E[35m'
 cyan='\E[36m'
 white='\E[37m'
 
-if ! ./test_$1 > /dev/null 2> .runtest.log ; then
+if ! ./$1 > /dev/null 2> .runtest.log ; then
   echo -e  $red Test $1 failed: $black
   echo -e $blue
   cat .runtest.log
diff --git a/unsupported/doc/examples/CMakeLists.txt b/unsupported/doc/examples/CMakeLists.txt
index af4de4b0d..d78af13a9 100644
--- a/unsupported/doc/examples/CMakeLists.txt
+++ b/unsupported/doc/examples/CMakeLists.txt
@@ -4,14 +4,14 @@ ADD_CUSTOM_TARGET(unsupported_examples)
 
 FOREACH(example_src ${examples_SRCS})
 GET_FILENAME_COMPONENT(example ${example_src} NAME_WE)
-ADD_EXECUTABLE(${example} ${example_src})
+ADD_EXECUTABLE(example_${example} ${example_src})
 GET_TARGET_PROPERTY(example_executable
                     ${example} LOCATION)
 ADD_CUSTOM_COMMAND(
-  TARGET ${example}
+  TARGET example_${example}
   POST_BUILD
   COMMAND ${example_executable}
   ARGS >${CMAKE_CURRENT_BINARY_DIR}/${example}.out
 )
-ADD_DEPENDENCIES(unsupported_examples ${example})
+ADD_DEPENDENCIES(unsupported_examples example_${example})
 ENDFOREACH(example_src)
-- 
cgit v1.2.3


From e12f5adbdeee6281af8a534652c3d82638630419 Mon Sep 17 00:00:00 2001
From: Gael Guennebaud 
Date: Wed, 2 Dec 2009 19:32:54 +0100
Subject: fix MSVC10 compilation

---
 Eigen/src/Core/Block.h          | 2 +-
 Eigen/src/Core/util/XprHelper.h | 4 ++--
 Eigen/src/Geometry/Hyperplane.h | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/Eigen/src/Core/Block.h b/Eigen/src/Core/Block.h
index 5fffdcb01..f9bbf473d 100644
--- a/Eigen/src/Core/Block.h
+++ b/Eigen/src/Core/Block.h
@@ -228,7 +228,7 @@ class Block
 
     class InnerIterator;
     typedef typename ei_traits::AlignedDerivedType AlignedDerivedType;
-    friend class Block;
+    friend class Block;
 
     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
 
diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h
index 659b3d7d1..5f3b6286c 100644
--- a/Eigen/src/Core/util/XprHelper.h
+++ b/Eigen/src/Core/util/XprHelper.h
@@ -192,7 +192,7 @@ struct ei_ref_selector
 *       to the user.
 **/
 template
-struct ei_ref_selector< Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > 
+struct ei_ref_selector< Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
 {
   typedef Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> MatrixType;
   typedef MatrixType const& type;
@@ -224,7 +224,7 @@ template::ty
   };
 
   typedef typename ei_meta_if<
-    ( int(ei_traits::Flags) & EvalBeforeNestingBit ) || 
+    ( int(ei_traits::Flags) & EvalBeforeNestingBit ) ||
     ( int(CostEval) <= int(CostNoEval) ),
       PlainMatrixType,
       typename ei_ref_selector::type
diff --git a/Eigen/src/Geometry/Hyperplane.h b/Eigen/src/Geometry/Hyperplane.h
index 49a9ac7bb..aab3d5b35 100644
--- a/Eigen/src/Geometry/Hyperplane.h
+++ b/Eigen/src/Geometry/Hyperplane.h
@@ -52,9 +52,9 @@ public:
   typedef _Scalar Scalar;
   typedef typename NumTraits::Real RealScalar;
   typedef Matrix VectorType;
-  typedef Matrix Coefficients;
+                        : int(AmbientDimAtCompileTime)+1,1> Coefficients;
   typedef Block NormalReturnType;
 
   /** Default constructor without initialization */
-- 
cgit v1.2.3


From e5c91b4e9553401392c0cb39e9a479e11cc582df Mon Sep 17 00:00:00 2001
From: Mark Borgerding 
Date: Wed, 2 Dec 2009 17:23:09 -0500
Subject: removed troublesome M_PI and M_PIl constants

---
 unsupported/test/FFT.cpp  | 7 ++-----
 unsupported/test/FFTW.cpp | 3 ++-
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/unsupported/test/FFT.cpp b/unsupported/test/FFT.cpp
index 4a6d495cc..3e4126522 100644
--- a/unsupported/test/FFT.cpp
+++ b/unsupported/test/FFT.cpp
@@ -45,13 +45,10 @@ complex  promote(long double x) { return complex( x);
         long double totalpower=0;
         long double difpower=0;
         cerr <<"idx\ttruth\t\tvalue\t|dif|=\n";
+        long double pi = acos(-1);
         for (size_t k0=0;k0 acc = 0;
-#ifdef _GNU_SOURCE
-            long double phinc = -2.*k0* M_PIl / timebuf.size();
-#else
-            long double phinc = -2.*k0* M_PI / timebuf.size();
-#endif
+            long double phinc = -2.*k0* pi / timebuf.size();
             for (size_t k1=0;k1(0,k1*phinc) );
             }
diff --git a/unsupported/test/FFTW.cpp b/unsupported/test/FFTW.cpp
index cf7be75aa..fdb41f2e0 100644
--- a/unsupported/test/FFTW.cpp
+++ b/unsupported/test/FFTW.cpp
@@ -45,10 +45,11 @@ complex  promote(long double x) { return complex( x);
     {
         long double totalpower=0;
         long double difpower=0;
+        long double pi = acos(-1);
         cerr <<"idx\ttruth\t\tvalue\t|dif|=\n";
         for (size_t k0=0;k0 acc = 0;
-            long double phinc = -2.*k0* M_PIl / timebuf.size();
+            long double phinc = -2.*k0* pi / timebuf.size();
             for (size_t k1=0;k1(0,k1*phinc) );
             }
-- 
cgit v1.2.3


From 012cd62c81af01c6089d57871d492636b843e4a5 Mon Sep 17 00:00:00 2001
From: Mark Borgerding 
Date: Wed, 2 Dec 2009 22:58:34 -0500
Subject: explicitly cast to use the acos(long double)

---
 unsupported/test/FFT.cpp  | 2 +-
 unsupported/test/FFTW.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/unsupported/test/FFT.cpp b/unsupported/test/FFT.cpp
index 3e4126522..b029ba655 100644
--- a/unsupported/test/FFT.cpp
+++ b/unsupported/test/FFT.cpp
@@ -45,7 +45,7 @@ complex  promote(long double x) { return complex( x);
         long double totalpower=0;
         long double difpower=0;
         cerr <<"idx\ttruth\t\tvalue\t|dif|=\n";
-        long double pi = acos(-1);
+        long double pi = acos((long double)-1);
         for (size_t k0=0;k0 acc = 0;
             long double phinc = -2.*k0* pi / timebuf.size();
diff --git a/unsupported/test/FFTW.cpp b/unsupported/test/FFTW.cpp
index fdb41f2e0..c182cab9d 100644
--- a/unsupported/test/FFTW.cpp
+++ b/unsupported/test/FFTW.cpp
@@ -45,7 +45,7 @@ complex  promote(long double x) { return complex( x);
     {
         long double totalpower=0;
         long double difpower=0;
-        long double pi = acos(-1);
+        long double pi = acos((long double)-1 );
         cerr <<"idx\ttruth\t\tvalue\t|dif|=\n";
         for (size_t k0=0;k0 acc = 0;
-- 
cgit v1.2.3


From af17770680f23fe3d858cb461b4983795f7e8810 Mon Sep 17 00:00:00 2001
From: bjornpiltz 
Date: Thu, 3 Dec 2009 09:27:15 +0100
Subject: Fix compilation for MSVC.

---
 unsupported/Eigen/src/NumericalDiff/NumericalDiff.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h b/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h
index 98872e0bc..db6f791df 100644
--- a/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h
+++ b/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h
@@ -45,10 +45,11 @@ enum NumericalDiffMode {
   *
   * Currently only "Forward" and "Central" scheme are implemented.
   */
-template
-class NumericalDiff : public Functor
+template
+class NumericalDiff : public _Functor
 {
 public:
+    typedef _Functor Functor;
     typedef typename Functor::Scalar Scalar;
     typedef typename Functor::InputType InputType;
     typedef typename Functor::ValueType ValueType;
-- 
cgit v1.2.3


From ffaea19a70d22657008645e97a0b9efe2fcc9451 Mon Sep 17 00:00:00 2001
From: Marton Danoczy 
Date: Thu, 3 Dec 2009 14:01:34 +0100
Subject: Fixed compilation warnings in MSVC with Scalar==float

---
 unsupported/Eigen/src/FFT/ei_kissfft_impl.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/unsupported/Eigen/src/FFT/ei_kissfft_impl.h b/unsupported/Eigen/src/FFT/ei_kissfft_impl.h
index 5c958d1ec..2dff2bd00 100644
--- a/unsupported/Eigen/src/FFT/ei_kissfft_impl.h
+++ b/unsupported/Eigen/src/FFT/ei_kissfft_impl.h
@@ -160,7 +160,7 @@ struct ei_kiss_cpx_fft
         scratch[0]=scratch[1]-scratch[2];
         tw1 += fstride;
         tw2 += fstride*2;
-        Fout[m] = Complex( Fout->real() - .5*scratch[3].real() , Fout->imag() - .5*scratch[3].imag() );
+        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() );
@@ -377,10 +377,10 @@ struct ei_kissfft_impl
   std::vector m_tmpBuf2;
 
   inline
-    int PlanKey(int nfft,bool isinverse) const { return (nfft<<1) | isinverse; }
+    int PlanKey(int nfft, bool isinverse) const { return (nfft<<1) | int(isinverse); }
 
   inline
-    PlanData & get_plan(int nfft,bool inverse)
+    PlanData & get_plan(int nfft, bool inverse)
     {
       // TODO look for PlanKey(nfft, ! inverse) and conjugate the twiddles
       PlanData & pd = m_plans[ PlanKey(nfft,inverse) ];
@@ -400,7 +400,7 @@ struct ei_kissfft_impl
         int ncfft= ncfft2<<1;
         Scalar pi =  acos( Scalar(-1) );
         for (int k=1;k<=ncfft2;++k) 
-          twidref[k-1] = exp( Complex(0,-pi * ((double) (k) / ncfft + .5) ) );
+          twidref[k-1] = exp( Complex(0,-pi * (Scalar(k) / ncfft + Scalar(.5)) ) );
       }
       return &twidref[0];
     }
-- 
cgit v1.2.3


From 7aad4341609260356845b16057fd581302c5072f Mon Sep 17 00:00:00 2001
From: Gael Guennebaud 
Date: Fri, 4 Dec 2009 12:26:56 +0100
Subject: fix compilation and clean a bit Map

---
 Eigen/src/Geometry/Quaternion.h | 21 +++++++--------------
 1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/Eigen/src/Geometry/Quaternion.h b/Eigen/src/Geometry/Quaternion.h
index a6bdb2408..7f102c942 100644
--- a/Eigen/src/Geometry/Quaternion.h
+++ b/Eigen/src/Geometry/Quaternion.h
@@ -152,9 +152,9 @@ public:
 	/** \returns the conjugated quaternion */
   Quaternion conjugate() const;
 
-	/** \returns an interpolation for a constant motion between \a other and \c *this 
+	/** \returns an interpolation for a constant motion between \a other and \c *this
 		* \a t in [0;1]
-		* see http://en.wikipedia.org/wiki/Slerp		
+		* see http://en.wikipedia.org/wiki/Slerp
 	*/
   template Quaternion slerp(Scalar t, const QuaternionBase& other) const;
 
@@ -221,7 +221,7 @@ struct ei_traits >
 template
 class Quaternion : public QuaternionBase >{
   typedef QuaternionBase > Base;
-public: 
+public:
   typedef _Scalar Scalar;
 
   EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Quaternion)
@@ -304,21 +304,14 @@ template
 class Map, PacketAccess >
   : public QuaternionBase, PacketAccess> >
 {
-	public:
-    typedef _Scalar Scalar;
-		typedef Map, PacketAccess > MapQuat;
-		
-	private:
- 		Map, PacketAccess >();
- 		Map, PacketAccess >(const Map, PacketAccess>&);
-
     typedef QuaternionBase, PacketAccess> > Base;
+
   public:
-  	EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(MapQuat)
+    typedef _Scalar Scalar;
+    typedef typename ei_traits::Coefficients Coefficients;
+    EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Map)
     using Base::operator*=;
 
-    typedef typename ei_traits, PacketAccess> >::Coefficients Coefficients;
-
     /** Constructs a Mapped Quaternion object from the pointer \a coeffs
       *
       * The pointer \a coeffs must reference the four coeffecients of Quaternion in the following order:
-- 
cgit v1.2.3


From c68c695b87b1e72bae6eb09e6ebcc35551c22044 Mon Sep 17 00:00:00 2001
From: Gael Guennebaud 
Date: Fri, 4 Dec 2009 15:01:17 +0100
Subject: Fix poor Quaternion::slerp snapping

---
 Eigen/src/Geometry/Quaternion.h | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/Eigen/src/Geometry/Quaternion.h b/Eigen/src/Geometry/Quaternion.h
index 5578ce9f4..b6eb74d66 100644
--- a/Eigen/src/Geometry/Quaternion.h
+++ b/Eigen/src/Geometry/Quaternion.h
@@ -583,20 +583,29 @@ template 
 Quaternion::Scalar>
 QuaternionBase::slerp(Scalar t, const QuaternionBase& other) const
 {
-  static const Scalar one = Scalar(1) - dummy_precision();
+  static const Scalar one = Scalar(1) - epsilon();
   Scalar d = this->dot(other);
   Scalar absD = ei_abs(d);
-  if (absD>=one)
-    return Quaternion(derived());
 
-  // theta is the angle between the 2 quaternions
-  Scalar theta = std::acos(absD);
-  Scalar sinTheta = ei_sin(theta);
+  Scalar scale0;
+  Scalar scale1;
 
-  Scalar scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
-  Scalar scale1 = ei_sin( ( t * theta) ) / sinTheta;
-  if (d<0)
-    scale1 = -scale1;
+  if (absD>=one)
+  {
+    scale0 = Scalar(1) - t;
+    scale1 = t;
+  }
+  else
+  {
+    // theta is the angle between the 2 quaternions
+    Scalar theta = std::acos(absD);
+    Scalar sinTheta = ei_sin(theta);
+
+    scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
+    scale1 = ei_sin( ( t * theta) ) / sinTheta;
+    if (d<0)
+      scale1 = -scale1;
+  }
 
   return Quaternion(scale0 * coeffs() + scale1 * other.coeffs());
 }
-- 
cgit v1.2.3


From 36969cc2a5c2d0d3a52510b68c203b920eb4d3de Mon Sep 17 00:00:00 2001
From: Gael Guennebaud 
Date: Fri, 4 Dec 2009 15:02:38 +0100
Subject: add a slerp benchmark (for accuracy and speed))

---
 bench/quat_slerp.cpp | 245 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 245 insertions(+)
 create mode 100644 bench/quat_slerp.cpp

diff --git a/bench/quat_slerp.cpp b/bench/quat_slerp.cpp
new file mode 100644
index 000000000..029443704
--- /dev/null
+++ b/bench/quat_slerp.cpp
@@ -0,0 +1,245 @@
+
+#include 
+#include 
+using namespace Eigen;
+using namespace std;
+
+
+
+template
+EIGEN_DONT_INLINE Q nlerp(const Q& a, const Q& b, typename Q::Scalar t)
+{
+  return Q((a.coeffs() * (1.0-t) + b.coeffs() * t).normalized());
+}
+
+template
+EIGEN_DONT_INLINE Q slerp_eigen(const Q& a, const Q& b, typename Q::Scalar t)
+{
+  return a.slerp(t,b);
+}
+
+template
+EIGEN_DONT_INLINE Q slerp_legacy(const Q& a, const Q& b, typename Q::Scalar t)
+{
+  typedef typename Q::Scalar Scalar;
+  static const Scalar one = Scalar(1) - dummy_precision();
+  Scalar d = a.dot(b);
+  Scalar absD = ei_abs(d);
+  if (absD>=one)
+    return a;
+
+  // theta is the angle between the 2 quaternions
+  Scalar theta = std::acos(absD);
+  Scalar sinTheta = ei_sin(theta);
+
+  Scalar scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
+  Scalar scale1 = ei_sin( ( t * theta) ) / sinTheta;
+  if (d<0)
+    scale1 = -scale1;
+
+  return Q(scale0 * a.coeffs() + scale1 * b.coeffs());
+}
+
+template
+EIGEN_DONT_INLINE Q slerp_legacy_nlerp(const Q& a, const Q& b, typename Q::Scalar t)
+{
+  typedef typename Q::Scalar Scalar;
+  static const Scalar one = Scalar(1) - epsilon();
+  Scalar d = a.dot(b);
+  Scalar absD = ei_abs(d);
+  
+  Scalar scale0;
+  Scalar scale1;
+  
+  if (absD>=one)
+  {
+    scale0 = Scalar(1) - t;
+    scale1 = t;
+  }
+  else
+  {
+    // theta is the angle between the 2 quaternions
+    Scalar theta = std::acos(absD);
+    Scalar sinTheta = ei_sin(theta);
+
+    scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
+    scale1 = ei_sin( ( t * theta) ) / sinTheta;
+    if (d<0)
+      scale1 = -scale1;
+  }
+
+  return Q(scale0 * a.coeffs() + scale1 * b.coeffs());
+}
+
+template
+inline T sin_over_x(T x)
+{
+  if (T(1) + x*x == T(1))
+    return T(1);
+  else
+    return std::sin(x)/x;
+}
+
+template
+EIGEN_DONT_INLINE Q slerp_rw(const Q& a, const Q& b, typename Q::Scalar t)
+{
+  typedef typename Q::Scalar Scalar;
+  
+  Scalar d = a.dot(b);
+  Scalar theta;
+  if (d<0.0)
+    theta = /*M_PI -*/ Scalar(2)*std::asin( (a.coeffs()+b.coeffs()).norm()/2 );
+  else
+    theta = Scalar(2)*std::asin( (a.coeffs()-b.coeffs()).norm()/2 );
+  
+  // theta is the angle between the 2 quaternions
+//   Scalar theta = std::acos(absD);
+  Scalar sinOverTheta = sin_over_x(theta);
+
+  Scalar scale0 = (Scalar(1)-t)*sin_over_x( ( Scalar(1) - t ) * theta) / sinOverTheta;
+  Scalar scale1 = t * sin_over_x( ( t * theta) ) / sinOverTheta;
+  if (d<0)
+    scale1 = -scale1;
+
+  return Quaternion(scale0 * a.coeffs() + scale1 * b.coeffs());
+}
+
+template
+EIGEN_DONT_INLINE Q slerp_gael(const Q& a, const Q& b, typename Q::Scalar t)
+{
+  typedef typename Q::Scalar Scalar;
+  
+  Scalar d = a.dot(b);
+  Scalar theta;
+//   theta = Scalar(2) * atan2((a.coeffs()-b.coeffs()).norm(),(a.coeffs()+b.coeffs()).norm());
+//   if (d<0.0)
+//     theta = M_PI-theta;
+  
+  if (d<0.0)
+    theta = /*M_PI -*/ Scalar(2)*std::asin( (-a.coeffs()-b.coeffs()).norm()/2 );
+  else
+    theta = Scalar(2)*std::asin( (a.coeffs()-b.coeffs()).norm()/2 );
+  
+  
+  Scalar scale0;
+  Scalar scale1;
+  if(theta*theta-Scalar(6)==-Scalar(6))
+  {
+    scale0 = Scalar(1) - t;
+    scale1 = t;
+  }
+  else
+  {
+    Scalar sinTheta = std::sin(theta);
+    scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
+    scale1 = ei_sin( ( t * theta) ) / sinTheta;
+    if (d<0)
+      scale1 = -scale1;
+  }
+
+  return Quaternion(scale0 * a.coeffs() + scale1 * b.coeffs());
+}
+
+int main()
+{
+  typedef double RefScalar;
+  typedef float TestScalar;
+  
+  typedef Quaternion  Qd;
+  typedef Quaternion Qf;
+  
+  unsigned int g_seed = (unsigned int) time(NULL);
+  std::cout << g_seed << "\n";
+//   g_seed = 1259932496;
+  srand(g_seed);
+  
+  Matrix maxerr(7);
+  maxerr.setZero();
+  
+  Matrix avgerr(7);
+  avgerr.setZero();
+  
+  cout << "double=>float=>double       nlerp        eigen        legacy(snap)         legacy(nlerp)        rightway         gael's criteria\n";
+  
+  int rep = 100;
+  int iters = 40;
+  for (int w=0; w());
+    Qd br(b.cast());
+    Qd cr;
+    
+    
+    
+    cout.precision(8);
+    cout << std::scientific;
+    for (int i=0; i();
+      c[0] = nlerp(a,b,t);
+      c[1] = slerp_eigen(a,b,t);
+      c[2] = slerp_legacy(a,b,t);
+      c[3] = slerp_legacy_nlerp(a,b,t);
+      c[4] = slerp_rw(a,b,t);
+      c[5] = slerp_gael(a,b,t);
+      
+      VectorXd err(7);
+      err[0] = (cr.coeffs()-refc.cast().coeffs()).norm();
+//       std::cout << err[0] << "    ";
+      for (int k=0; k<6; ++k)
+      {
+        err[k+1] = (c[k].coeffs()-refc.coeffs()).norm();
+//         std::cout << err[k+1] << "    ";
+      }
+      maxerr = maxerr.cwise().max(err);
+      avgerr += err;
+//       std::cout << "\n";
+      b = cr.cast();
+      br = cr;
+    }
+//     std::cout << "\n";
+  }
+  avgerr /= RefScalar(rep*iters);
+  cout << "\n\nAccuracy:\n"
+       << "  max: " << maxerr.transpose() << "\n";
+  cout << "  avg: " << avgerr.transpose() << "\n";
+  
+  // perf bench
+  Quaternionf a,b;
+  a.coeffs().setRandom();
+  a.normalize();
+  b.coeffs().setRandom();
+  b.normalize();
+  //b = a;
+  float s = 0.65;
+    
+  #define BENCH(FUNC) {\
+    BenchTimer t; \
+    for(int k=0; k<2; ++k) {\
+      t.start(); \
+      for(int i=0; i<1000000; ++i) \
+        FUNC(a,b,s); \
+      t.stop(); \
+    } \
+    cout << "  " << #FUNC << " => \t " << t.value() << "s\n"; \
+  }
+  
+  cout << "\nSpeed:\n" << std::fixed;
+  BENCH(nlerp);
+  BENCH(slerp_eigen);
+  BENCH(slerp_legacy);
+  BENCH(slerp_legacy_nlerp);
+  BENCH(slerp_rw);
+  BENCH(slerp_gael);
+}
\ No newline at end of file
-- 
cgit v1.2.3


From 39ceba409b4b0295f0c70872cf2592503b54eba2 Mon Sep 17 00:00:00 2001
From: Jitse Niesen 
Date: Mon, 7 Dec 2009 19:10:11 +0000
Subject: Various improvements to the docs for unsupported. * Enable
 compilation of examples for unsupported. * Fix use of std::vector in BVH
 example. * Add an example for the matrix exponential. * Bug fixes in
 unsupported/doc/{examples,snippets}/CMakeLists.txt .

---
 doc/CMakeLists.txt                                     |  2 +-
 .../Eigen/src/MatrixFunctions/MatrixExponential.h      | 16 ++++++++++++++++
 unsupported/doc/CMakeLists.txt                         |  2 ++
 unsupported/doc/examples/BVH_Example.cpp               |  4 +++-
 unsupported/doc/examples/CMakeLists.txt                |  2 +-
 unsupported/doc/examples/MatrixExponential.cpp         | 18 ++++++++++++++++++
 unsupported/doc/snippets/CMakeLists.txt                |  2 +-
 7 files changed, 42 insertions(+), 4 deletions(-)
 create mode 100644 unsupported/doc/examples/MatrixExponential.cpp

diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 1d20a6075..af756a516 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -63,7 +63,7 @@ add_custom_target(
 )
 
 add_dependencies(doc-eigen-prerequisites all_snippets all_examples)
-# add_dependencies(doc-unsupported-prerequisites unsupported_snippets unsupported_examples)
+add_dependencies(doc-unsupported-prerequisites unsupported_snippets unsupported_examples)
 add_custom_target(doc ALL
   COMMAND doxygen Doxyfile-unsupported
   COMMAND doxygen
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
index 6510b6814..bb4706c35 100644
--- a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
+++ b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
@@ -58,6 +58,22 @@
  * SIAM J. %Matrix Anal. Applic., 26:1179–1193,
  * 2005. 
  *
+ * Example: The following program checks that
+ * \f[ \exp \left[ \begin{array}{ccc} 
+ *       0 & \frac14\pi & 0 \\ 
+ *       -\frac14\pi & 0 & 0 \\
+ *       0 & 0 & 0 
+ *     \end{array} \right] = \left[ \begin{array}{ccc}
+ *       \frac12\sqrt2 & -\frac12\sqrt2 & 0 \\
+ *       \frac12\sqrt2 & \frac12\sqrt2 & 0 \\
+ *       0 & 0 & 1
+ *     \end{array} \right]. \f]
+ * This corresponds to a rotation of \f$ \frac14\pi \f$ radians around
+ * the z-axis.
+
+ * \include MatrixExponential.cpp
+ * Output: \verbinclude MatrixExponential.out
+ *
  * \note \p M has to be a matrix of \c float, \c double, 
  * \c complex or \c complex .
  */
diff --git a/unsupported/doc/CMakeLists.txt b/unsupported/doc/CMakeLists.txt
index 2cff2510f..a50d07798 100644
--- a/unsupported/doc/CMakeLists.txt
+++ b/unsupported/doc/CMakeLists.txt
@@ -1,6 +1,8 @@
 
 set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL TRUE)
 
+
 if(NOT MSVC)
   add_subdirectory(examples)
+  add_subdirectory(snippets)
 endif(NOT MSVC)
diff --git a/unsupported/doc/examples/BVH_Example.cpp b/unsupported/doc/examples/BVH_Example.cpp
index 890eb535b..0fbab5fdb 100644
--- a/unsupported/doc/examples/BVH_Example.cpp
+++ b/unsupported/doc/examples/BVH_Example.cpp
@@ -1,3 +1,4 @@
+#include 
 #include 
 
 using namespace Eigen;
@@ -20,7 +21,8 @@ struct PointPointMinimizer //how to compute squared distances between points and
 
 int main()
 {
-  std::vector redPoints, bluePoints;
+  typedef std::vector > StdVectorOfVector2d;
+  StdVectorOfVector2d redPoints, bluePoints;
   for(int i = 0; i < 100; ++i) { //initialize random set of red points and blue points
     redPoints.push_back(Vector2d::Random());
     bluePoints.push_back(Vector2d::Random());
diff --git a/unsupported/doc/examples/CMakeLists.txt b/unsupported/doc/examples/CMakeLists.txt
index d78af13a9..cb42b2ab9 100644
--- a/unsupported/doc/examples/CMakeLists.txt
+++ b/unsupported/doc/examples/CMakeLists.txt
@@ -6,7 +6,7 @@ FOREACH(example_src ${examples_SRCS})
 GET_FILENAME_COMPONENT(example ${example_src} NAME_WE)
 ADD_EXECUTABLE(example_${example} ${example_src})
 GET_TARGET_PROPERTY(example_executable
-                    ${example} LOCATION)
+                    example_${example} LOCATION)
 ADD_CUSTOM_COMMAND(
   TARGET example_${example}
   POST_BUILD
diff --git a/unsupported/doc/examples/MatrixExponential.cpp b/unsupported/doc/examples/MatrixExponential.cpp
new file mode 100644
index 000000000..86062e3a6
--- /dev/null
+++ b/unsupported/doc/examples/MatrixExponential.cpp
@@ -0,0 +1,18 @@
+#include 
+
+using namespace Eigen;
+
+int main()
+{
+  const double pi = std::acos(-1);
+
+  MatrixXd A(3,3);
+  A << 0,    -pi/4, 0,
+       pi/4, 0,     0,
+       0,    0,     0;
+  std::cout << "The matrix A is:\n" << A << "\n\n";
+
+  MatrixXd B;
+  ei_matrix_exponential(A, &B);
+  std::cout << "The matrix exponential of A is:\n" << B << "\n\n";
+}
diff --git a/unsupported/doc/snippets/CMakeLists.txt b/unsupported/doc/snippets/CMakeLists.txt
index fa529d139..19e9b1a1f 100644
--- a/unsupported/doc/snippets/CMakeLists.txt
+++ b/unsupported/doc/snippets/CMakeLists.txt
@@ -7,7 +7,7 @@ FOREACH(snippet_src ${snippets_SRCS})
   SET(compile_snippet_target compile_${snippet})
   SET(compile_snippet_src ${compile_snippet_target}.cpp)
   FILE(READ ${snippet_src} snippet_source_code)
-  CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/compile_snippet.cpp.in
+  CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/snippets/compile_snippet.cpp.in
                  ${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src})
   ADD_EXECUTABLE(${compile_snippet_target}
                  ${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src})
-- 
cgit v1.2.3


From a682a0eeb1246725a0f6bbbe02eeedf81d26b22b Mon Sep 17 00:00:00 2001
From: Jitse Niesen 
Date: Tue, 8 Dec 2009 11:08:04 +0000
Subject: C05_TutorialLinearAlgebra.dox: Correct file name

---
 doc/C05_TutorialLinearAlgebra.dox | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/C05_TutorialLinearAlgebra.dox b/doc/C05_TutorialLinearAlgebra.dox
index c50e9c6bc..5bae00b7e 100644
--- a/doc/C05_TutorialLinearAlgebra.dox
+++ b/doc/C05_TutorialLinearAlgebra.dox
@@ -69,9 +69,9 @@ As an example, suppose we want to solve the following system of linear equations
 The following program solves this system:
 
 
-\include Tutorial_PartialPivLU_solve.cpp +\include Tutorial_PartialLU_solve.cpp -output: \include Tutorial_PartialPivLU_solve.out +output: \include Tutorial_PartialLU_solve.out
There are many situations in which we want to solve the same system of equations with different -- cgit v1.2.3 From 8bfa354ee3267691a7aec6fe576847296e074c90 Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Tue, 8 Dec 2009 15:12:27 +0000 Subject: Documentation clean up. * remove non-existant reference to CwiseAll * define \householder_module (used in HouseholderSequence.h) * update I01_TopicLazyEvaluation.dox - Product is now called GeneralProduct * remove reference to list of examples which was deleted ages ago * rename PartialLU_solve.cpp snippet to PartialPivLU_solve.cpp --- Eigen/Householder | 2 +- Eigen/src/Core/PermutationMatrix.h | 2 +- doc/C01_QuickStartGuide.dox | 2 +- doc/Doxyfile.in | 11 ++++++----- doc/I01_TopicLazyEvaluation.dox | 6 +++--- doc/Overview.dox | 2 +- doc/snippets/PartialLU_solve.cpp | 7 ------- doc/snippets/PartialPivLU_solve.cpp | 7 +++++++ 8 files changed, 20 insertions(+), 19 deletions(-) delete mode 100644 doc/snippets/PartialLU_solve.cpp create mode 100644 doc/snippets/PartialPivLU_solve.cpp diff --git a/Eigen/Householder b/Eigen/Householder index 98970ef0c..dcaeeeae8 100644 --- a/Eigen/Householder +++ b/Eigen/Householder @@ -8,7 +8,7 @@ namespace Eigen { /** \defgroup Householder_Module Householder module - * This module provides householder transformations. + * This module provides Householder transformations. * * \code * #include diff --git a/Eigen/src/Core/PermutationMatrix.h b/Eigen/src/Core/PermutationMatrix.h index 147c48734..284baf678 100644 --- a/Eigen/src/Core/PermutationMatrix.h +++ b/Eigen/src/Core/PermutationMatrix.h @@ -95,7 +95,7 @@ class PermutationMatrix : public AnyMatrixBase diff --git a/doc/C01_QuickStartGuide.dox b/doc/C01_QuickStartGuide.dox index 0c545f735..7c4aa8f76 100644 --- a/doc/C01_QuickStartGuide.dox +++ b/doc/C01_QuickStartGuide.dox @@ -470,7 +470,7 @@ mat = 2 7 8 Also note that maxCoeff and minCoeff can takes optional arguments returning the coordinates of the respective min/max coeff: \link MatrixBase::maxCoeff(int*,int*) const maxCoeff(int* i, int* j) \endlink, \link MatrixBase::minCoeff(int*,int*) const minCoeff(int* i, int* j) \endlink. -\b Side \b note: The all() and any() functions are especially useful in combination with coeff-wise comparison operators (\ref CwiseAll "example"). +\b Side \b note: The all() and any() functions are especially useful in combination with coeff-wise comparison operators. diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 497f7ab6c..3d79a300d 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -197,14 +197,15 @@ TAB_SIZE = 8 ALIASES = "only_for_vectors=This is only for vectors (either row-vectors or column-vectors), i.e. matrices which are known at compile-time to have either one row or one column." \ "array_module=This is defined in the %Array module. \code #include \endcode" \ - "lu_module=This is defined in the %LU module. \code #include \endcode" \ "cholesky_module=This is defined in the %Cholesky module. \code #include \endcode" \ - "qr_module=This is defined in the %QR module. \code #include \endcode" \ - "jacobi_module=This is defined in the %Jacobi module. \code #include \endcode" \ - "svd_module=This is defined in the %SVD module. \code #include \endcode" \ + "eigenvalues_module=This is defined in the %Eigenvalues module. \code #include \endcode" \ "geometry_module=This is defined in the %Geometry module. \code #include \endcode" \ + "householder_module=This is defined in the %Householder module. \code #include \endcode" \ + "jacobi_module=This is defined in the %Jacobi module. \code #include \endcode" \ "leastsquares_module=This is defined in the %LeastSquares module. \code #include \endcode" \ - "eigenvalues_module=This is defined in the %Eigenvalues module. \code #include \endcode" \ + "lu_module=This is defined in the %LU module. \code #include \endcode" \ + "qr_module=This is defined in the %QR module. \code #include \endcode" \ + "svd_module=This is defined in the %SVD module. \code #include \endcode" \ "label=\bug" \ "redstar=*" \ "nonstableyet=\warning This is not considered to be part of the stable public API yet. Changes may happen in future releases. See \ref Experimental \"Experimental parts of Eigen\"" \ diff --git a/doc/I01_TopicLazyEvaluation.dox b/doc/I01_TopicLazyEvaluation.dox index f40afa06d..68fa1e2df 100644 --- a/doc/I01_TopicLazyEvaluation.dox +++ b/doc/I01_TopicLazyEvaluation.dox @@ -36,7 +36,7 @@ Here is now a more involved example: Eigen chooses lazy evaluation at every stage in that example, which is clearly the correct choice. In fact, lazy evaluation is the "default choice" and Eigen will choose it except in a few circumstances. -The first circumstance in which Eigen chooses immediate evaluation, is when it sees an assignment a = b; and the expression \c b has the evaluate-before-assigning \link flags flag\endlink. The most important example of such an expression is the \link Product matrix product expression\endlink. For example, when you do +The first circumstance in which Eigen chooses immediate evaluation, is when it sees an assignment a = b; and the expression \c b has the evaluate-before-assigning \link flags flag\endlink. The most important example of such an expression is the \link GeneralProduct matrix product expression\endlink. For example, when you do \code matrix = matrix * matrix; \endcode @@ -48,7 +48,7 @@ What if you know that the result does no alias the operand of the product and wa Here, since we know that matrix2 is not the same matrix as matrix1, we know that lazy evaluation is not dangerous, so we may force lazy evaluation. Concretely, the effect of noalias() here is to bypass the evaluate-before-assigning \link flags flag\endlink. -The second circumstance in which Eigen chooses immediate evaluation, is when it sees a nested expression such as a + b where \c b is already an expression having the evaluate-before-nesting \link flags flag\endlink. Again, the most important example of such an expression is the \link Product matrix product expression\endlink. For example, when you do +The second circumstance in which Eigen chooses immediate evaluation, is when it sees a nested expression such as a + b where \c b is already an expression having the evaluate-before-nesting \link flags flag\endlink. Again, the most important example of such an expression is the \link GeneralProduct matrix product expression\endlink. For example, when you do \code matrix1 = matrix2 + matrix3 * matrix4; \endcode @@ -62,4 +62,4 @@ Here, provided the matrices have at least 2 rows and 2 columns, each coefficienc */ -} \ No newline at end of file +} diff --git a/doc/Overview.dox b/doc/Overview.dox index db0d9587a..78bf5f9dd 100644 --- a/doc/Overview.dox +++ b/doc/Overview.dox @@ -15,7 +15,7 @@ For a first contact with Eigen, the best place is to have a look at the \ref Tut Most of the API is available as methods in MatrixBase, so this is a good starting point for browsing. Also have a look at Matrix, as a few methods and the matrix constructors are there. Other notable classes for the Eigen API are Cwise, which contains the methods for doing certain coefficient-wise operations, and Part. -In fact, except for advanced use, the only class that you'll have to explicitly name in your program, i.e. of which you'll explicitly contruct objects, is Matrix. For instance, vectors are handled as a special case of Matrix with one column. Typedefs are provided, e.g. Vector2f is a typedef for Matrix. Finally, you might also have look at the \ref ExampleList "the list of selected examples". +In fact, except for advanced use, the only class that you'll have to explicitly name in your program, i.e. of which you'll explicitly contruct objects, is Matrix. For instance, vectors are handled as a special case of Matrix with one column. Typedefs are provided, e.g. Vector2f is a typedef for Matrix. Most of the other classes are just return types for MatrixBase methods. diff --git a/doc/snippets/PartialLU_solve.cpp b/doc/snippets/PartialLU_solve.cpp deleted file mode 100644 index fa3570ab8..000000000 --- a/doc/snippets/PartialLU_solve.cpp +++ /dev/null @@ -1,7 +0,0 @@ -MatrixXd A = MatrixXd::Random(3,3); -MatrixXd B = MatrixXd::Random(3,2); -cout << "Here is the invertible matrix A:" << endl << A << endl; -cout << "Here is the matrix B:" << endl << B << endl; -MatrixXd X = A.lu().solve(B); -cout << "Here is the (unique) solution X to the equation AX=B:" << endl << X << endl; -cout << "Relative error: " << (A*X-B).norm() / B.norm() << endl; diff --git a/doc/snippets/PartialPivLU_solve.cpp b/doc/snippets/PartialPivLU_solve.cpp new file mode 100644 index 000000000..fa3570ab8 --- /dev/null +++ b/doc/snippets/PartialPivLU_solve.cpp @@ -0,0 +1,7 @@ +MatrixXd A = MatrixXd::Random(3,3); +MatrixXd B = MatrixXd::Random(3,2); +cout << "Here is the invertible matrix A:" << endl << A << endl; +cout << "Here is the matrix B:" << endl << B << endl; +MatrixXd X = A.lu().solve(B); +cout << "Here is the (unique) solution X to the equation AX=B:" << endl << X << endl; +cout << "Relative error: " << (A*X-B).norm() / B.norm() << endl; -- cgit v1.2.3 From 097cab26fbc96a3e44ecc5ad6d4408b66008d2c4 Mon Sep 17 00:00:00 2001 From: Benjamin Schindler Date: Tue, 8 Dec 2009 18:06:03 +0100 Subject: Added a pretty printer python script for Eigen::Matrix (gdb-7.0 and later). --- debug/gdb/printers.py | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 debug/gdb/printers.py diff --git a/debug/gdb/printers.py b/debug/gdb/printers.py new file mode 100644 index 000000000..9e72c8cad --- /dev/null +++ b/debug/gdb/printers.py @@ -0,0 +1,115 @@ +# -*- coding: iso-8859-1 -*- +# Pretty printers for Eigen::Matrix +# Author: Benjamin Schindler +# This is still pretty basic as the python extension to gdb is still pretty basic. +# It cannot handle complex eigen types and it doesn't support any of the other eigen types +# Such as quaternion or some other type. +# This code supports fixed size as well as dynamic size matrices +# Licence - ment to be included in Eigen, so dual GPLv3 or LGPL +# NOTE: This code was only tested with the stable branch of eigen! + +import gdb +import re +import itertools + + +class EigenMatrixPrinter: + "Print Eigen Matrix of some kind" + + def __init__(self, val): + "Extract all the necessary information" + # The gdb extension does not support value template arguments - need to extract them by hand + type = val.type + if type.code == gdb.TYPE_CODE_REF: + type = type.target() + self.type = type.unqualified().strip_typedefs() + tag = self.type.tag + regex = re.compile('\<.*\>') + m = regex.findall(tag)[0][1:-1] + template_params = m.split(',') + template_params = map(lambda x:x.replace(" ", ""), template_params) + + self.rows = int(template_params[1]) + self.cols = int(template_params[2]) + + if self.rows == 10000: + self.rows = val['m_storage']['m_rows'] + + if self.cols == 10000: + self.cols = val['m_storage']['m_cols'] + + self.innerType = self.type.template_argument(0) + + self.val = val + + class _iterator: + def __init__ (self, rows, cols, dataPtr): + self.rows = rows + self.cols = cols + self.dataPtr = dataPtr + self.currentRow = 0 + self.currentCol = 0 + + def __iter__ (self): + return self + + def next(self): + if self.currentCol >= self.cols: + raise StopIteration + + row = self.currentRow + col = self.currentCol + self.currentRow = self.currentRow + 1 + if self.currentRow >= self.rows: + self.currentRow = 0 + self.currentCol = self.currentCol + 1 + + item = self.dataPtr.dereference() + self.dataPtr = self.dataPtr + 1 + + return ('[%d, %d]' % (row, col), item) + + def children(self): + data = self.val['m_storage']['m_data'] + # Fixed size matrices have a struct as their storage, so we need to walk through this + if data.type.code == gdb.TYPE_CODE_STRUCT: + data = data['array'] + data = data.cast(self.innerType.pointer()) + return self._iterator(self.rows, self.cols, data) + + def to_string(self): + return "Eigen::Matrix<%s,%d,%d>" % (self.innerType, self.rows, self.cols) + +def build_eigen_dictionary (): + pretty_printers_dict[re.compile('^Eigen::Matrix<.*>$')] = lambda val: EigenMatrixPrinter(val) + +def register_eigen_printers(obj): + "Register eigen pretty-printers with objfile Obj" + + if obj == None: + obj = gdb + obj.pretty_printers.append(lookup_function) + +def lookup_function(val): + "Look-up and return a pretty-printer that can print va." + + type = val.type + + if type.code == gdb.TYPE_CODE_REF: + type = type.target() + + type = type.unqualified().strip_typedefs() + + typename = type.tag + if typename == None: + return None + + for function in pretty_printers_dict: + if function.search(typename): + return pretty_printers_dict[function](val) + + return None + +pretty_printers_dict = {} + +build_eigen_dictionary () -- cgit v1.2.3 From 64beff03b6f48c58ed74acddcb69f91a33358d30 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Tue, 8 Dec 2009 18:09:00 +0100 Subject: Added a 'pretty printer' for the msvc debugger (tested on Visual Studio 2008). --- debug/msvc/eigen_autoexp_part.dat | 306 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 306 insertions(+) create mode 100644 debug/msvc/eigen_autoexp_part.dat diff --git a/debug/msvc/eigen_autoexp_part.dat b/debug/msvc/eigen_autoexp_part.dat new file mode 100644 index 000000000..394397e5d --- /dev/null +++ b/debug/msvc/eigen_autoexp_part.dat @@ -0,0 +1,306 @@ +; *************************************************************** +; * Eigen Visualizer +; * +; * Author: Hauke Heibel +; * +; * Support the enhanced debugging of the following Eigen +; * types (*: any, +:fixed dimension) : +; * +; * - Eigen::Matrix<*,4,1,*,*,*> and Eigen::Matrix<*,1,4,*,*,*> +; * - Eigen::Matrix<*,3,1,*,*,*> and Eigen::Matrix<*,1,3,*,*,*> +; * - Eigen::Matrix<*,2,1,*,*,*> and Eigen::Matrix<*,1,2,*,*,*> +; * - Eigen::Matrix<*,33331,33331,*,*,*> +; * - Eigen::Matrix<*,+,33331,*,*,*> +; * - Eigen::Matrix<*,33331,+,*,*,*> +; * - Eigen::Matrix<*,+,+,*,*,*> +; * +; * Matrices are displayed properly independantly of the memory +; * alignment (RowMajor vs. ColMajor). +; * +; * This file is distributed WITHOUT ANY WARRANTY. Please ensure +; * that your original autoexp.dat file is copied to a safe +; * place before proceeding with its modification. +; *************************************************************** + +; Fixed size 4-vectors +Eigen::Matrix<*,4,1,*,*,*>|Eigen::Matrix<*,1,4,*,*,*>{ + children + ( + #( + [internals]: [$c,!], + x : ($c.m_storage.m_data.array)[0], + y : ($c.m_storage.m_data.array)[1], + z : ($c.m_storage.m_data.array)[2], + w : ($c.m_storage.m_data.array)[3] + ) + ) + + preview + ( + #( + "(", + + #array + ( + expr : [($c.m_storage.m_data.array)[$i],g], + size : 4 + ), + ")" + ) + ) +} + +; Fixed size 3-vectors +Eigen::Matrix<*,3,1,*,*,*>|Eigen::Matrix<*,1,3,*,*,*>{ + children + ( + #( + [internals]: [$c,!], + x : ($c.m_storage.m_data.array)[0], + y : ($c.m_storage.m_data.array)[1], + z : ($c.m_storage.m_data.array)[2] + ) + ) + + preview + ( + #( + "(", + + #array + ( + expr : [($c.m_storage.m_data.array)[$i],g], + size : 3 + ), + ")" + ) + ) +} + +; Fixed size floating point 2-vectors +Eigen::Matrix|Eigen::Matrix|Eigen::Matrix|Eigen::Matrix{ + children + ( + #( + [internals]: [$c,!], + x : ($c.m_storage.m_data.array)[0], + y : ($c.m_storage.m_data.array)[1] + ) + ) + + preview + ( + #( + "(", + + #array + ( + expr : [($c.m_storage.m_data.array)[$i],g], + size : 2 + ), + ")" + ) + ) +} + +; Fixed size integral 2-vectors +Eigen::Matrix<*,2,1,*,*,*>|Eigen::Matrix<*,1,2,*,*,*>{ + children + ( + #( + [internals]: [$c,!], + x : ($c.m_storage.m_data.array)[0], + y : ($c.m_storage.m_data.array)[1] + ) + ) + + preview + ( + #( + "(", + + #array + ( + expr : ($c.m_storage.m_data.array)[$i], + size : 2 + ), + ")" + ) + ) +} + +; Dynamic matrices (ColMajor and RowMajor support) +Eigen::Matrix<*,33331,33331,*,*,*>{ + children + ( + #( + [internals]: [$c,!], + rows: $c.m_storage.m_rows, + cols: $c.m_storage.m_cols, + ; Check for RowMajorBit + #if ($c.Flags & 0x1) ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data)[($i % $c.m_storage.m_rows)*$c.m_storage.m_cols + (($i- $i % $c.m_storage.m_rows)/$c.m_storage.m_rows)], + size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.m_storage.m_cols + ) + ) #else ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data)[$i], + size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.m_storage.m_cols + ) + ) + ) + ) + + preview + ( + #( + "[", + $c.m_storage.m_rows, + ",", + $c.m_storage.m_cols, + "](", + #array( + expr : [($c.m_storage.m_data)[$i],g], + size : $c.m_storage.m_rows*$c.m_storage.m_cols + ), + ")" + ) + ) +} + +; Fixed rows, dynamic columns matrix (ColMajor and RowMajor support) +Eigen::Matrix<*,*,33331,*,*,*>{ + children + ( + #( + [internals]: [$c,!], + rows: $c.RowsAtCompileTime, + cols: $c.m_storage.m_cols, + ; Check for RowMajorBit + #if ($c.Flags & 0x1) ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data)[($i % $c.RowsAtCompileTime)*$c.m_storage.m_cols + (($i- $i % $c.RowsAtCompileTime)/$c.RowsAtCompileTime)], + size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.m_storage.m_cols + ) + ) #else ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data)[$i], + size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.m_storage.m_cols + ) + ) + ) + ) + + preview + ( + #( + "[", + $c.RowsAtCompileTime, + ",", + $c.m_storage.m_cols, + "](", + #array( + expr : [($c.m_storage.m_data)[$i],g], + size : $c.RowsAtCompileTime*$c.m_storage.m_cols + ), + ")" + ) + ) +} + +; Dynamic rows, fixed columns matrix (ColMajor and RowMajor support) +Eigen::Matrix<*,33331,*,*,*,*>{ + children + ( + #( + [internals]: [$c,!], + rows: $c.m_storage.m_rows, + cols: $c.ColsAtCompileTime, + ; Check for RowMajorBit + #if ($c.Flags & 0x1) ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data)[($i % $c.m_storage.m_rows)*$c.ColsAtCompileTime + (($i- $i % $c.m_storage.m_rows)/$c.m_storage.m_rows)], + size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.ColsAtCompileTime + ) + ) #else ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data)[$i], + size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.ColsAtCompileTime + ) + ) + ) + ) + + preview + ( + #( + "[", + $c.m_storage.m_rows, + ",", + $c.ColsAtCompileTime, + "](", + #array( + expr : [($c.m_storage.m_data)[$i],g], + size : $c.m_storage.m_rows*$c.ColsAtCompileTime + ), + ")" + ) + ) +} + +; Fixed size matrix (ColMajor and RowMajor support) +Eigen::Matrix<*,*,*,*,*,*>{ + children + ( + #( + [internals]: [$c,!], + rows: $c.RowsAtCompileTime, + cols: $c.ColsAtCompileTime, + ; Check for RowMajorBit + #if ($c.Flags & 0x1) ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data.array)[($i % $c.RowsAtCompileTime)*$c.ColsAtCompileTime + (($i- $i % $c.RowsAtCompileTime)/$c.RowsAtCompileTime)], + size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.ColsAtCompileTime + ) + ) #else ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data.array)[$i], + size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.ColsAtCompileTime + ) + ) + ) + ) + + preview + ( + #( + "[", + $c.RowsAtCompileTime, + ",", + $c.ColsAtCompileTime, + "](", + #array( + expr : [($c.m_storage.m_data.array)[$i],g], + size : $c.RowsAtCompileTime*$c.ColsAtCompileTime + ), + ")" + ) + ) +} -- cgit v1.2.3 From f2304f3b88171e350d305dd7e326b7b345f343f5 Mon Sep 17 00:00:00 2001 From: Benjamin Schindler Date: Tue, 8 Dec 2009 18:17:46 +0100 Subject: Adding __init__.py so the printers can be used directly from the checkout --- debug/gdb/__init__.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 debug/gdb/__init__.py diff --git a/debug/gdb/__init__.py b/debug/gdb/__init__.py new file mode 100644 index 000000000..bb7b160de --- /dev/null +++ b/debug/gdb/__init__.py @@ -0,0 +1 @@ +# Intentionally empty -- cgit v1.2.3 From a4c162dbdc0e59eb2dac0e6b598ac87b1341b5c4 Mon Sep 17 00:00:00 2001 From: Benjamin Schindler Date: Tue, 8 Dec 2009 18:18:05 +0100 Subject: Correct license header of the gdb pretty printer --- debug/gdb/printers.py | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/debug/gdb/printers.py b/debug/gdb/printers.py index 9e72c8cad..3df7535c3 100644 --- a/debug/gdb/printers.py +++ b/debug/gdb/printers.py @@ -1,12 +1,39 @@ -# -*- coding: iso-8859-1 -*- +# -*- coding: utf-8 -*- +# This file is part of Eigen, a lightweight C++ template library +# for linear algebra. +# +# Copyright (C) 2009 Benjamin Schindler +# +# 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 . + # Pretty printers for Eigen::Matrix -# Author: Benjamin Schindler # This is still pretty basic as the python extension to gdb is still pretty basic. # It cannot handle complex eigen types and it doesn't support any of the other eigen types # Such as quaternion or some other type. # This code supports fixed size as well as dynamic size matrices -# Licence - ment to be included in Eigen, so dual GPLv3 or LGPL -# NOTE: This code was only tested with the stable branch of eigen! + +# To use it: +# +# * create a directory and put the file as well as an empty __init__.py in that directory +# * Create a ~/.gdbinit file, that contains the following: + import gdb import re -- cgit v1.2.3 From 4da991eaa811b8e8c31253e1b00d95b0d721d8ef Mon Sep 17 00:00:00 2001 From: Benjamin Schindler Date: Tue, 8 Dec 2009 18:40:36 +0100 Subject: Display the data ptr as part of the header --- debug/gdb/printers.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/debug/gdb/printers.py b/debug/gdb/printers.py index 3df7535c3..0b4230498 100644 --- a/debug/gdb/printers.py +++ b/debug/gdb/printers.py @@ -68,7 +68,13 @@ class EigenMatrixPrinter: self.innerType = self.type.template_argument(0) self.val = val - + + # Fixed size matrices have a struct as their storage, so we need to walk through this + self.data = self.val['m_storage']['m_data'] + if self.data.type.code == gdb.TYPE_CODE_STRUCT: + self.data = self.data['array'] + self.data = self.data.cast(self.innerType.pointer()) + class _iterator: def __init__ (self, rows, cols, dataPtr): self.rows = rows @@ -97,15 +103,11 @@ class EigenMatrixPrinter: return ('[%d, %d]' % (row, col), item) def children(self): - data = self.val['m_storage']['m_data'] - # Fixed size matrices have a struct as their storage, so we need to walk through this - if data.type.code == gdb.TYPE_CODE_STRUCT: - data = data['array'] - data = data.cast(self.innerType.pointer()) - return self._iterator(self.rows, self.cols, data) + + return self._iterator(self.rows, self.cols, self.data) def to_string(self): - return "Eigen::Matrix<%s,%d,%d>" % (self.innerType, self.rows, self.cols) + return "Eigen::Matrix<%s,%d,%d> (data ptr: %s)" % (self.innerType, self.rows, self.cols, self.data) def build_eigen_dictionary (): pretty_printers_dict[re.compile('^Eigen::Matrix<.*>$')] = lambda val: EigenMatrixPrinter(val) -- cgit v1.2.3 From f0315295e9ae2fd8afdc05d3e5b790b4660ffc58 Mon Sep 17 00:00:00 2001 From: Benjamin Schindler Date: Tue, 8 Dec 2009 19:12:26 +0100 Subject: Handle row and col major matrices in the gdb pretty printer --- debug/gdb/printers.py | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/debug/gdb/printers.py b/debug/gdb/printers.py index 0b4230498..9f6cfa5d5 100644 --- a/debug/gdb/printers.py +++ b/debug/gdb/printers.py @@ -58,6 +58,11 @@ class EigenMatrixPrinter: self.rows = int(template_params[1]) self.cols = int(template_params[2]) + self.options = 0 # default value + if len(template_params) > 3: + self.options = template_params[3]; + + self.rowMajor = (int(self.options) & 0x1) if self.rows == 10000: self.rows = val['m_storage']['m_rows'] @@ -76,38 +81,50 @@ class EigenMatrixPrinter: self.data = self.data.cast(self.innerType.pointer()) class _iterator: - def __init__ (self, rows, cols, dataPtr): + def __init__ (self, rows, cols, dataPtr, rowMajor): self.rows = rows self.cols = cols self.dataPtr = dataPtr self.currentRow = 0 self.currentCol = 0 + self.rowMajor = rowMajor def __iter__ (self): return self def next(self): - if self.currentCol >= self.cols: - raise StopIteration - + row = self.currentRow col = self.currentCol - self.currentRow = self.currentRow + 1 - if self.currentRow >= self.rows: - self.currentRow = 0 + if self.rowMajor == 0: + if self.currentCol >= self.cols: + raise StopIteration + + self.currentRow = self.currentRow + 1 + if self.currentRow >= self.rows: + self.currentRow = 0 + self.currentCol = self.currentCol + 1 + else: + if self.currentRow >= self.rows: + raise StopIteration + self.currentCol = self.currentCol + 1 + if self.currentCol >= self.cols: + self.currentCol = 0 + self.currentRow = self.currentRow + 1 + item = self.dataPtr.dereference() self.dataPtr = self.dataPtr + 1 - + return ('[%d, %d]' % (row, col), item) def children(self): - return self._iterator(self.rows, self.cols, self.data) + return self._iterator(self.rows, self.cols, self.data, self.rowMajor) def to_string(self): - return "Eigen::Matrix<%s,%d,%d> (data ptr: %s)" % (self.innerType, self.rows, self.cols, self.data) + return "Eigen::Matrix<%s,%d,%d,%s> (data ptr: %s)" % (self.innerType, self.rows, self.cols, "RowMajor" if self.rowMajor else "ColMajor", self.data) def build_eigen_dictionary (): pretty_printers_dict[re.compile('^Eigen::Matrix<.*>$')] = lambda val: EigenMatrixPrinter(val) -- cgit v1.2.3 From d2e44f263631981d9e547caafe36b1de5ba785f9 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 9 Dec 2009 12:43:25 -0500 Subject: * 4x4 inverse: revert to cofactors method * inverse tests: use createRandomMatrixOfRank, use more strict precision * tests: createRandomMatrixOfRank: support 1x1 matrices * determinant: nest the xpr * Minor: add comment --- Eigen/src/Core/Minor.h | 5 ++- Eigen/src/LU/Determinant.h | 4 +- Eigen/src/LU/Inverse.h | 101 ++++++++------------------------------------- test/inverse.cpp | 11 +---- test/main.h | 15 ++++++- test/prec_inverse_4x4.cpp | 28 ++----------- 6 files changed, 43 insertions(+), 121 deletions(-) diff --git a/Eigen/src/Core/Minor.h b/Eigen/src/Core/Minor.h index ab058b187..eb44f3760 100644 --- a/Eigen/src/Core/Minor.h +++ b/Eigen/src/Core/Minor.h @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2006-2008 Benoit Jacob +// Copyright (C) 2006-2009 Benoit Jacob // // Eigen is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -54,7 +54,8 @@ struct ei_traits > MaxColsAtCompileTime = (MatrixType::MaxColsAtCompileTime != Dynamic) ? int(MatrixType::MaxColsAtCompileTime) - 1 : Dynamic, Flags = _MatrixTypeNested::Flags & HereditaryBits, - CoeffReadCost = _MatrixTypeNested::CoeffReadCost + CoeffReadCost = _MatrixTypeNested::CoeffReadCost // minor is used typically on tiny matrices, + // where loops are unrolled and the 'if' evaluates at compile time }; }; diff --git a/Eigen/src/LU/Determinant.h b/Eigen/src/LU/Determinant.h index 8870d9f20..27ad6abe9 100644 --- a/Eigen/src/LU/Determinant.h +++ b/Eigen/src/LU/Determinant.h @@ -118,7 +118,9 @@ template inline typename ei_traits::Scalar MatrixBase::determinant() const { assert(rows() == cols()); - return ei_determinant_impl::run(derived()); + typedef typename ei_nested::type Nested; + Nested nested(derived()); + return ei_determinant_impl::type>::run(nested); } #endif // EIGEN_DETERMINANT_H diff --git a/Eigen/src/LU/Inverse.h b/Eigen/src/LU/Inverse.h index 9d5e86845..8afbfda96 100644 --- a/Eigen/src/LU/Inverse.h +++ b/Eigen/src/LU/Inverse.h @@ -182,93 +182,28 @@ struct ei_compute_inverse_and_det_with_check *** Size 4 implementation *** ****************************/ -template -void ei_compute_inverse_size4_helper(const MatrixType& matrix, ResultType& result) -{ - /* Let's split M into four 2x2 blocks: - * (P Q) - * (R S) - * If P is invertible, with inverse denoted by P_inverse, and if - * (S - R*P_inverse*Q) is also invertible, then the inverse of M is - * (P' Q') - * (R' S') - * where - * S' = (S - R*P_inverse*Q)^(-1) - * P' = P1 + (P1*Q) * S' *(R*P_inverse) - * Q' = -(P_inverse*Q) * S' - * R' = -S' * (R*P_inverse) - */ - typedef Block XprBlock22; - typedef typename MatrixBase::PlainMatrixType Block22; - Block22 P_inverse; - ei_compute_inverse::run(matrix.template block<2,2>(0,0), P_inverse); - const Block22 Q = matrix.template block<2,2>(0,2); - const Block22 P_inverse_times_Q = P_inverse * Q; - const XprBlock22 R = matrix.template block<2,2>(2,0); - const Block22 R_times_P_inverse = R * P_inverse; - const Block22 R_times_P_inverse_times_Q = R_times_P_inverse * Q; - const XprBlock22 S = matrix.template block<2,2>(2,2); - const Block22 X = S - R_times_P_inverse_times_Q; - Block22 Y; - ei_compute_inverse::run(X, Y); - result.template block<2,2>(2,2) = Y; - result.template block<2,2>(2,0) = - Y * R_times_P_inverse; - const Block22 Z = P_inverse_times_Q * Y; - result.template block<2,2>(0,2) = - Z; - result.template block<2,2>(0,0) = P_inverse + Z * R_times_P_inverse; -} - template struct ei_compute_inverse { - static inline void run(const MatrixType& _matrix, ResultType& result) + static inline void run(const MatrixType& matrix, ResultType& result) { - typedef typename ResultType::Scalar Scalar; - typedef typename MatrixType::RealScalar RealScalar; - - // we will do row permutations on the matrix. This copy should have negligible cost. - // if not, consider working in-place on the matrix (const-cast it, but then undo the permutations - // to nevertheless honor constness) - typename MatrixType::PlainMatrixType matrix(_matrix); - - // let's extract from the 2 first colums a 2x2 block whose determinant is as big as possible. - int good_row0, good_row1, good_i; - Matrix absdet; - - // any 2x2 block with determinant above this threshold will be considered good enough. - // The magic value 1e-1 here comes from experimentation. The bigger it is, the higher the precision, - // the slower the computation. This value 1e-1 gives precision almost as good as the brutal cofactors - // algorithm, both in average and in worst-case precision. - RealScalar d = (matrix.col(0).squaredNorm()+matrix.col(1).squaredNorm()) * RealScalar(1e-1); - #define ei_inv_size4_helper_macro(i,row0,row1) \ - absdet[i] = ei_abs(matrix.coeff(row0,0)*matrix.coeff(row1,1) \ - - matrix.coeff(row0,1)*matrix.coeff(row1,0)); \ - if(absdet[i] > d) { good_row0=row0; good_row1=row1; goto good; } - ei_inv_size4_helper_macro(0,0,1) - ei_inv_size4_helper_macro(1,0,2) - ei_inv_size4_helper_macro(2,0,3) - ei_inv_size4_helper_macro(3,1,2) - ei_inv_size4_helper_macro(4,1,3) - ei_inv_size4_helper_macro(5,2,3) - - // no 2x2 block has determinant bigger than the threshold. So just take the one that - // has the biggest determinant - absdet.maxCoeff(&good_i); - good_row0 = good_i <= 2 ? 0 : good_i <= 4 ? 1 : 2; - good_row1 = good_i <= 2 ? good_i+1 : good_i <= 4 ? good_i-1 : 3; - - // now good_row0 and good_row1 are correctly set - good: - - // do row permutations to move this 2x2 block to the top - matrix.row(0).swap(matrix.row(good_row0)); - matrix.row(1).swap(matrix.row(good_row1)); - // now applying our helper function is numerically stable - ei_compute_inverse_size4_helper(matrix, result); - // Since we did row permutations on the original matrix, we need to do column permutations - // in the reverse order on the inverse - result.col(1).swap(result.col(good_row1)); - result.col(0).swap(result.col(good_row0)); + result.coeffRef(0,0) = matrix.minor(0,0).determinant(); + result.coeffRef(1,0) = -matrix.minor(0,1).determinant(); + result.coeffRef(2,0) = matrix.minor(0,2).determinant(); + result.coeffRef(3,0) = -matrix.minor(0,3).determinant(); + result.coeffRef(0,2) = matrix.minor(2,0).determinant(); + result.coeffRef(1,2) = -matrix.minor(2,1).determinant(); + result.coeffRef(2,2) = matrix.minor(2,2).determinant(); + result.coeffRef(3,2) = -matrix.minor(2,3).determinant(); + result.coeffRef(0,1) = -matrix.minor(1,0).determinant(); + result.coeffRef(1,1) = matrix.minor(1,1).determinant(); + result.coeffRef(2,1) = -matrix.minor(1,2).determinant(); + result.coeffRef(3,1) = matrix.minor(1,3).determinant(); + result.coeffRef(0,3) = -matrix.minor(3,0).determinant(); + result.coeffRef(1,3) = matrix.minor(3,1).determinant(); + result.coeffRef(2,3) = -matrix.minor(3,2).determinant(); + result.coeffRef(3,3) = matrix.minor(3,3).determinant(); + result /= (matrix.col(0).cwise()*result.row(0).transpose()).sum(); } }; diff --git a/test/inverse.cpp b/test/inverse.cpp index 59b791507..b80e139e0 100644 --- a/test/inverse.cpp +++ b/test/inverse.cpp @@ -38,18 +38,11 @@ template void inverse(const MatrixType& m) typedef typename NumTraits::Real RealScalar; typedef Matrix VectorType; - MatrixType m1 = MatrixType::Random(rows, cols), + MatrixType m1(rows, cols), m2(rows, cols), mzero = MatrixType::Zero(rows, cols), identity = MatrixType::Identity(rows, rows); - - if (ei_is_same_type::ret) - { - // let's build a more stable to inverse matrix - MatrixType a = MatrixType::Random(rows,cols); - m1 += m1 * m1.adjoint() + a * a.adjoint(); - } - + createRandomMatrixOfRank(rows,rows,rows,m1); m2 = m1.inverse(); VERIFY_IS_APPROX(m1, m2.inverse() ); diff --git a/test/main.h b/test/main.h index 8bc71b3ae..06c17a9ae 100644 --- a/test/main.h +++ b/test/main.h @@ -353,13 +353,26 @@ void createRandomMatrixOfRank(int desired_rank, int rows, int cols, MatrixType& typedef Matrix MatrixAType; typedef Matrix MatrixBType; + if(desired_rank == 0) + { + m.setZero(rows,cols); + return; + } + + if(desired_rank == 1) + { + m = VectorType::Random(rows) * VectorType::Random(cols).transpose(); + return; + } + MatrixAType a = MatrixAType::Random(rows,rows); MatrixType d = MatrixType::Identity(rows,cols); MatrixBType b = MatrixBType::Random(cols,cols); // set the diagonal such that only desired_rank non-zero entries reamain const int diag_size = std::min(d.rows(),d.cols()); - d.diagonal().segment(desired_rank, diag_size-desired_rank) = VectorType::Zero(diag_size-desired_rank); + if(diag_size != desired_rank) + d.diagonal().segment(desired_rank, diag_size-desired_rank) = VectorType::Zero(diag_size-desired_rank); HouseholderQR qra(a); HouseholderQR qrb(b); diff --git a/test/prec_inverse_4x4.cpp b/test/prec_inverse_4x4.cpp index 613535346..83b1a8a71 100644 --- a/test/prec_inverse_4x4.cpp +++ b/test/prec_inverse_4x4.cpp @@ -26,28 +26,6 @@ #include #include -Matrix4f inverse(const Matrix4f& m) -{ - Matrix4f r; - r(0,0) = m.minor(0,0).determinant(); - r(1,0) = -m.minor(0,1).determinant(); - r(2,0) = m.minor(0,2).determinant(); - r(3,0) = -m.minor(0,3).determinant(); - r(0,2) = m.minor(2,0).determinant(); - r(1,2) = -m.minor(2,1).determinant(); - r(2,2) = m.minor(2,2).determinant(); - r(3,2) = -m.minor(2,3).determinant(); - r(0,1) = -m.minor(1,0).determinant(); - r(1,1) = m.minor(1,1).determinant(); - r(2,1) = -m.minor(1,2).determinant(); - r(3,1) = m.minor(1,3).determinant(); - r(0,3) = -m.minor(3,0).determinant(); - r(1,3) = m.minor(3,1).determinant(); - r(2,3) = -m.minor(3,2).determinant(); - r(3,3) = m.minor(3,3).determinant(); - return r / (m(0,0)*r(0,0) + m(1,0)*r(0,1) + m(2,0)*r(0,2) + m(3,0)*r(0,3)); -} - template void inverse_permutation_4x4() { typedef typename MatrixType::Scalar Scalar; @@ -79,7 +57,7 @@ template void inverse_general_4x4(int repeat) do { m = MatrixType::Random(); absdet = ei_abs(m.determinant()); - } while(absdet < 10 * epsilon()); + } while(absdet < epsilon()); MatrixType inv = m.inverse(); double error = double( (m*inv-MatrixType::Identity()).norm() * absdet / epsilon() ); error_sum += error; @@ -89,8 +67,8 @@ template void inverse_general_4x4(int repeat) double error_avg = error_sum / repeat; EIGEN_DEBUG_VAR(error_avg); EIGEN_DEBUG_VAR(error_max); - VERIFY(error_avg < (NumTraits::IsComplex ? 8.4 : 1.4) ); - VERIFY(error_max < (NumTraits::IsComplex ? 160.0 : 75.) ); + VERIFY(error_avg < (NumTraits::IsComplex ? 8.0 : 1.0)); + VERIFY(error_max < (NumTraits::IsComplex ? 64.0 : 16.0)); } void test_prec_inverse_4x4() -- cgit v1.2.3 From 7d444375e744f8f666c15ccd97e9d3dc4b342389 Mon Sep 17 00:00:00 2001 From: Thomas Capricelli Date: Fri, 11 Dec 2009 02:38:28 +0100 Subject: fix compilation (for some reason the pb happens only under windows) --- unsupported/Eigen/NonLinearOptimization | 1 + 1 file changed, 1 insertion(+) diff --git a/unsupported/Eigen/NonLinearOptimization b/unsupported/Eigen/NonLinearOptimization index 5e64bc585..3cce1e3ae 100644 --- a/unsupported/Eigen/NonLinearOptimization +++ b/unsupported/Eigen/NonLinearOptimization @@ -26,6 +26,7 @@ #define EIGEN_NONLINEAROPTIMIZATION_MODULE #include +#include #include namespace Eigen { -- cgit v1.2.3 From 2026ea7ff2be0473511cc74c56538cb98c13d301 Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Fri, 11 Dec 2009 15:54:21 +0000 Subject: Coax doxygen in producing better docs for MatrixFunctions. The //@{ ... //@} in unsupported/Eigen/MatrixFunctions for some reason caused doxygen to list the constructor of the MatrixExponential class as a separate function in the MatrixFunctions module without any reference to the class; very confusing. --- doc/Doxyfile.in | 2 +- unsupported/Eigen/MatrixFunctions | 3 --- unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h | 8 ++++++-- unsupported/doc/Doxyfile.in | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 3d79a300d..64bb7bd01 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -610,7 +610,7 @@ EXCLUDE_PATTERNS = CMake* \ *.sh \ *.orig \ *.diff \ - diff + diff \ *~ # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names diff --git a/unsupported/Eigen/MatrixFunctions b/unsupported/Eigen/MatrixFunctions index 0d785c344..5614f915e 100644 --- a/unsupported/Eigen/MatrixFunctions +++ b/unsupported/Eigen/MatrixFunctions @@ -41,12 +41,9 @@ namespace Eigen { * #include * \endcode */ -//@{ #include "src/MatrixFunctions/MatrixExponential.h" -//@} - } diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h index bb4706c35..add000c44 100644 --- a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h +++ b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h @@ -29,7 +29,9 @@ template Scalar log2(Scalar v) { return std::log(v)/std::log(Scalar(2)); } #endif -/** \brief Compute the matrix exponential. +/** \ingroup MatrixFunctions_Module + * + * \brief Compute the matrix exponential. * * \param M matrix whose exponential is to be computed. * \param result pointer to the matrix in which to store the result. @@ -81,7 +83,9 @@ template EIGEN_STRONG_INLINE void ei_matrix_exponential(const MatrixBase &M, typename MatrixBase::PlainMatrixType* result); -/** \brief Class for computing the matrix exponential.*/ +/** \ingroup MatrixFunctions_Module + * \brief Class for computing the matrix exponential. + */ template class MatrixExponential { diff --git a/unsupported/doc/Doxyfile.in b/unsupported/doc/Doxyfile.in index e55d53f7e..12f2f39eb 100644 --- a/unsupported/doc/Doxyfile.in +++ b/unsupported/doc/Doxyfile.in @@ -602,7 +602,7 @@ EXCLUDE_PATTERNS = CMake* \ *.sh \ *.diff \ *.orig \ - diff + diff \ *~ # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -- cgit v1.2.3 From 9a8c16810be4e4859152789e125fbbcce6c0aeb3 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Fri, 11 Dec 2009 19:11:01 +0100 Subject: Reverted Jitse's change - the targets unsupported_examples and unsupported_snippets are unknown over here. --- doc/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index af756a516..1d20a6075 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -63,7 +63,7 @@ add_custom_target( ) add_dependencies(doc-eigen-prerequisites all_snippets all_examples) -add_dependencies(doc-unsupported-prerequisites unsupported_snippets unsupported_examples) +# add_dependencies(doc-unsupported-prerequisites unsupported_snippets unsupported_examples) add_custom_target(doc ALL COMMAND doxygen Doxyfile-unsupported COMMAND doxygen -- cgit v1.2.3 From 494a88685ee995b34da0f3b79a68fa06c0ee63ff Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Fri, 11 Dec 2009 19:39:01 +0100 Subject: Fixed the bad fix - now the unsupported examples and snippets work on windows. --- doc/CMakeLists.txt | 2 +- doc/snippets/MatrixBase_extract.cpp | 4 +++- doc/snippets/MatrixBase_marked.cpp | 4 +++- doc/snippets/MatrixBase_part.cpp | 4 +++- unsupported/doc/CMakeLists.txt | 8 ++------ unsupported/doc/examples/MatrixExponential.cpp | 2 +- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 1d20a6075..af756a516 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -63,7 +63,7 @@ add_custom_target( ) add_dependencies(doc-eigen-prerequisites all_snippets all_examples) -# add_dependencies(doc-unsupported-prerequisites unsupported_snippets unsupported_examples) +add_dependencies(doc-unsupported-prerequisites unsupported_snippets unsupported_examples) add_custom_target(doc ALL COMMAND doxygen Doxyfile-unsupported COMMAND doxygen diff --git a/doc/snippets/MatrixBase_extract.cpp b/doc/snippets/MatrixBase_extract.cpp index a5ccd7574..c96220f72 100644 --- a/doc/snippets/MatrixBase_extract.cpp +++ b/doc/snippets/MatrixBase_extract.cpp @@ -1,4 +1,6 @@ -#warning deprecated +#ifndef _MSC_VER + #warning deprecated +#endif /* deprecated Matrix3i m = Matrix3i::Random(); cout << "Here is the matrix m:" << endl << m << endl; diff --git a/doc/snippets/MatrixBase_marked.cpp b/doc/snippets/MatrixBase_marked.cpp index f536773c9..f60712178 100644 --- a/doc/snippets/MatrixBase_marked.cpp +++ b/doc/snippets/MatrixBase_marked.cpp @@ -1,4 +1,6 @@ -#warning deprecated +#ifndef _MSC_VER + #warning deprecated +#endif /* Matrix3d m = Matrix3d::Zero(); m.part().setOnes(); diff --git a/doc/snippets/MatrixBase_part.cpp b/doc/snippets/MatrixBase_part.cpp index 81e66c4cd..d3e7f482e 100644 --- a/doc/snippets/MatrixBase_part.cpp +++ b/doc/snippets/MatrixBase_part.cpp @@ -1,4 +1,6 @@ -#warning deprecated +#ifndef _MSC_VER + #warning deprecated +#endif /* Matrix3d m = Matrix3d::Zero(); m.part().setOnes(); diff --git a/unsupported/doc/CMakeLists.txt b/unsupported/doc/CMakeLists.txt index a50d07798..9e9ab9800 100644 --- a/unsupported/doc/CMakeLists.txt +++ b/unsupported/doc/CMakeLists.txt @@ -1,8 +1,4 @@ - set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL TRUE) - -if(NOT MSVC) - add_subdirectory(examples) - add_subdirectory(snippets) -endif(NOT MSVC) +add_subdirectory(examples) +add_subdirectory(snippets) diff --git a/unsupported/doc/examples/MatrixExponential.cpp b/unsupported/doc/examples/MatrixExponential.cpp index 86062e3a6..7dc2396df 100644 --- a/unsupported/doc/examples/MatrixExponential.cpp +++ b/unsupported/doc/examples/MatrixExponential.cpp @@ -4,7 +4,7 @@ using namespace Eigen; int main() { - const double pi = std::acos(-1); + const double pi = std::acos(-1.0); MatrixXd A(3,3); A << 0, -pi/4, 0, -- cgit v1.2.3 From d088ee35f644f9178270f0c3dc8c76011d208099 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Sat, 12 Dec 2009 11:39:07 +0100 Subject: Added to possibility to compile unit tests at maximum warning level. Silenced (amongst others) many conversion related warnings. --- CMakeLists.txt | 3 ++- Eigen/src/Array/Functors.h | 4 ++++ Eigen/src/Array/VectorwiseOp.h | 2 ++ Eigen/src/Cholesky/LDLT.h | 2 ++ Eigen/src/Cholesky/LLT.h | 2 ++ Eigen/src/Core/Flagged.h | 3 +++ Eigen/src/Core/SelfAdjointView.h | 4 +++- Eigen/src/Core/util/Memory.h | 10 +++++----- Eigen/src/Geometry/Homogeneous.h | 4 ++++ Eigen/src/LU/FullPivLU.h | 9 +++++++++ Eigen/src/LU/Inverse.h | 2 ++ Eigen/src/QR/HouseholderQR.h | 2 ++ Eigen/src/SVD/SVD.h | 4 +++- Eigen/src/Sparse/CompressedStorage.h | 4 ++-- Eigen/src/Sparse/DynamicSparseMatrix.h | 6 +++--- Eigen/src/Sparse/RandomSetter.h | 2 +- Eigen/src/Sparse/SparseBlock.h | 2 ++ Eigen/src/Sparse/SparseCwise.h | 3 +++ Eigen/src/Sparse/SparseCwiseBinaryOp.h | 7 +++++++ Eigen/src/Sparse/SparseCwiseUnaryOp.h | 3 +++ Eigen/src/Sparse/SparseDiagonalProduct.h | 4 ++++ Eigen/src/Sparse/SparseFlagged.h | 6 ++++++ Eigen/src/Sparse/SparseMatrix.h | 9 ++++++--- Eigen/src/Sparse/SparseTranspose.h | 6 ++++++ Eigen/src/Sparse/SparseTriangular.h | 3 +++ Eigen/src/Sparse/SparseVector.h | 6 +++--- Eigen/src/misc/Image.h | 9 ++++++--- Eigen/src/misc/Kernel.h | 7 +++++-- Eigen/src/misc/Solve.h | 7 +++++-- cmake/EigenTesting.cmake | 12 +++++++++--- test/sparse_basic.cpp | 4 ++-- unsupported/Eigen/FFT | 4 ++-- unsupported/Eigen/src/BVH/BVAlgorithms.h | 4 ++++ unsupported/Eigen/src/BVH/KdBVH.h | 4 ++-- unsupported/Eigen/src/FFT/ei_kissfft_impl.h | 4 ++-- unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h | 2 +- unsupported/test/Complex.cpp | 2 +- unsupported/test/FFT.cpp | 8 ++++---- 38 files changed, 135 insertions(+), 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d1d9b12de..a7d4089c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,7 +124,8 @@ endif(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION) option(EIGEN_TEST_C++0x "Enables all C++0x features." OFF) -option(EIGEN_TEST_RVALUE_REF_SUPPORT "Enable rvalue references for unit tests." OFF) +option(EIGEN_TEST_MAX_WARNING_LEVEL "Sets the warning level to /Wall while building the unit tests." OFF) +mark_as_advanced(EIGEN_TEST_MAX_WARNING_LEVEL) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/Eigen/src/Array/Functors.h b/Eigen/src/Array/Functors.h index fd259f7bc..3a7753d04 100644 --- a/Eigen/src/Array/Functors.h +++ b/Eigen/src/Array/Functors.h @@ -43,6 +43,8 @@ struct ei_scalar_add_op { inline const PacketScalar packetOp(const PacketScalar& a) const { return ei_padd(a, ei_pset1(m_other)); } const Scalar m_other; +private: + ei_scalar_add_op& operator=(const ei_scalar_add_op&); }; template struct ei_functor_traits > @@ -128,6 +130,8 @@ struct ei_scalar_pow_op { inline ei_scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {} inline Scalar operator() (const Scalar& a) const { return ei_pow(a, m_exponent); } const Scalar m_exponent; +private: + ei_scalar_pow_op& operator=(const ei_scalar_pow_op&); }; template struct ei_functor_traits > diff --git a/Eigen/src/Array/VectorwiseOp.h b/Eigen/src/Array/VectorwiseOp.h index 71b83eaad..92e5cc000 100644 --- a/Eigen/src/Array/VectorwiseOp.h +++ b/Eigen/src/Array/VectorwiseOp.h @@ -147,6 +147,8 @@ struct ei_member_redux { inline result_type operator()(const MatrixBase& mat) const { return mat.redux(m_functor); } const BinaryOp m_functor; +private: + ei_member_redux& operator=(const ei_member_redux&); }; /** \array_module \ingroup Array_Module diff --git a/Eigen/src/Cholesky/LDLT.h b/Eigen/src/Cholesky/LDLT.h index d0f292634..2898d8747 100644 --- a/Eigen/src/Cholesky/LDLT.h +++ b/Eigen/src/Cholesky/LDLT.h @@ -275,6 +275,8 @@ struct ei_solve_retval, Rhs> dst = rhs(); dec().solveInPlace(dst); } +private: + ei_solve_retval& operator=(const ei_solve_retval&); }; /** This is the \em in-place version of solve(). diff --git a/Eigen/src/Cholesky/LLT.h b/Eigen/src/Cholesky/LLT.h index ad737aaeb..871530aef 100644 --- a/Eigen/src/Cholesky/LLT.h +++ b/Eigen/src/Cholesky/LLT.h @@ -270,6 +270,8 @@ struct ei_solve_retval, Rhs> dst = rhs(); dec().solveInPlace(dst); } +private: + ei_solve_retval_base& operator=(const ei_solve_retval_base&); }; /** This is the \em in-place version of solve(). diff --git a/Eigen/src/Core/Flagged.h b/Eigen/src/Core/Flagged.h index 754eaf6c5..b98861f42 100644 --- a/Eigen/src/Core/Flagged.h +++ b/Eigen/src/Core/Flagged.h @@ -111,6 +111,9 @@ template clas protected: ExpressionTypeNested m_matrix; + + private: + Flagged& operator=(const Flagged&); }; /** \deprecated it is only used by lazy() which is deprecated diff --git a/Eigen/src/Core/SelfAdjointView.h b/Eigen/src/Core/SelfAdjointView.h index 95ce666c9..9518a6498 100644 --- a/Eigen/src/Core/SelfAdjointView.h +++ b/Eigen/src/Core/SelfAdjointView.h @@ -150,8 +150,10 @@ template class SelfAdjointView const LDLT ldlt() const; protected: - const typename MatrixType::Nested m_matrix; + + private: + SelfAdjointView& operator=(const SelfAdjointView&); }; diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h index bc5235582..1bff682ff 100644 --- a/Eigen/src/Core/util/Memory.h +++ b/Eigen/src/Core/util/Memory.h @@ -210,15 +210,15 @@ template inline void ei_conditional_aligned_delete(T *pt } /** \internal \returns the number of elements which have to be skipped such that data are 16 bytes aligned */ -template -inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset) +template +inline static Integer ei_alignmentOffset(const Scalar* ptr, Integer maxOffset) { typedef typename ei_packet_traits::type Packet; - const int PacketSize = ei_packet_traits::size; - const int PacketAlignedMask = PacketSize-1; + const Integer PacketSize = ei_packet_traits::size; + const Integer PacketAlignedMask = PacketSize-1; const bool Vectorized = PacketSize>1; return Vectorized - ? std::min( (PacketSize - (int((size_t(ptr)/sizeof(Scalar))) & PacketAlignedMask)) + ? std::min( (PacketSize - (Integer((Integer(ptr)/sizeof(Scalar))) & PacketAlignedMask)) & PacketAlignedMask, maxOffset) : 0; } diff --git a/Eigen/src/Geometry/Homogeneous.h b/Eigen/src/Geometry/Homogeneous.h index ffa828f71..f2a2fe73e 100644 --- a/Eigen/src/Geometry/Homogeneous.h +++ b/Eigen/src/Geometry/Homogeneous.h @@ -241,6 +241,8 @@ struct ei_homogeneous_left_product_impl,Lhs> const typename Lhs::Nested m_lhs; const typename MatrixType::Nested m_rhs; +private: + ei_homogeneous_left_product_impl& operator=(const ei_homogeneous_left_product_impl&); }; template @@ -280,6 +282,8 @@ struct ei_homogeneous_right_product_impl,Rhs> const typename MatrixType::Nested m_lhs; const typename Rhs::Nested m_rhs; +private: + ei_homogeneous_right_product_impl& operator=(const ei_homogeneous_right_product_impl&); }; #endif // EIGEN_HOMOGENEOUS_H diff --git a/Eigen/src/LU/FullPivLU.h b/Eigen/src/LU/FullPivLU.h index 1358c9490..5505d3bee 100644 --- a/Eigen/src/LU/FullPivLU.h +++ b/Eigen/src/LU/FullPivLU.h @@ -562,6 +562,9 @@ struct ei_kernel_retval > for(int i = rank(); i < cols; ++i) dst.row(dec().permutationQ().indices().coeff(i)).setZero(); for(int k = 0; k < dimker; ++k) dst.coeffRef(dec().permutationQ().indices().coeff(rank()+k), k) = Scalar(1); } + +private: + ei_kernel_retval& operator=(const ei_kernel_retval&); }; /***** Implementation of image() *****************************************************/ @@ -599,6 +602,9 @@ struct ei_image_retval > for(int i = 0; i < rank(); ++i) dst.col(i) = originalMatrix().col(dec().permutationQ().indices().coeff(pivots.coeff(i))); } + +private: + ei_image_retval& operator=(const ei_image_retval&); }; /***** Implementation of solve() *****************************************************/ @@ -659,6 +665,9 @@ struct ei_solve_retval, Rhs> for(int i = nonzero_pivots; i < dec().matrixLU().cols(); ++i) dst.row(dec().permutationQ().indices().coeff(i)).setZero(); } + +private: + ei_solve_retval& operator=(const ei_solve_retval&); }; /******* MatrixBase methods *****************************************************************/ diff --git a/Eigen/src/LU/Inverse.h b/Eigen/src/LU/Inverse.h index 8afbfda96..c31b3502e 100644 --- a/Eigen/src/LU/Inverse.h +++ b/Eigen/src/LU/Inverse.h @@ -258,6 +258,8 @@ struct ei_inverse_impl : public ReturnByValue > { ei_compute_inverse::run(m_matrix, dst); } +private: + ei_inverse_impl& operator=(const ei_inverse_impl&); }; /** \lu_module diff --git a/Eigen/src/QR/HouseholderQR.h b/Eigen/src/QR/HouseholderQR.h index 95496b943..3b174a873 100644 --- a/Eigen/src/QR/HouseholderQR.h +++ b/Eigen/src/QR/HouseholderQR.h @@ -237,6 +237,8 @@ struct ei_solve_retval, Rhs> dst.corner(TopLeft, rank, c.cols()) = c.corner(TopLeft, rank, c.cols()); dst.corner(BottomLeft, cols-rank, c.cols()).setZero(); } +private: + ei_solve_retval& operator=(const ei_solve_retval&); }; #endif // EIGEN_HIDE_HEAVY_CODE diff --git a/Eigen/src/SVD/SVD.h b/Eigen/src/SVD/SVD.h index 3c7aaf322..a90704cb9 100644 --- a/Eigen/src/SVD/SVD.h +++ b/Eigen/src/SVD/SVD.h @@ -190,7 +190,7 @@ SVD& SVD::compute(const MatrixType& matrix) SingularValuesType& W = m_sigma; bool flag; - int i,its,j,k,l,nm; + int i=0,its=0,j=0,k=0,l=0,nm=0; Scalar anorm, c, f, g, h, s, scale, x, y, z; bool convergence = true; Scalar eps = dummy_precision(); @@ -456,6 +456,8 @@ struct ei_solve_retval, Rhs> dst.col(j) = dec().matrixV() * dst.col(j); } } +private: + ei_solve_retval& operator=(const ei_solve_retval&); }; /** Computes the polar decomposition of the matrix, as a product unitary x positive. diff --git a/Eigen/src/Sparse/CompressedStorage.h b/Eigen/src/Sparse/CompressedStorage.h index fcf5c7bfe..b25b05e91 100644 --- a/Eigen/src/Sparse/CompressedStorage.h +++ b/Eigen/src/Sparse/CompressedStorage.h @@ -93,7 +93,7 @@ class CompressedStorage void append(const Scalar& v, int i) { - int id = m_size; + int id = static_cast(m_size); resize(m_size+1, 1); m_values[id] = v; m_indices[id] = i; @@ -135,7 +135,7 @@ class CompressedStorage else end = mid; } - return start; + return static_cast(start); } /** \returns the stored value at index \a key diff --git a/Eigen/src/Sparse/DynamicSparseMatrix.h b/Eigen/src/Sparse/DynamicSparseMatrix.h index 189a56bd0..f4f83533a 100644 --- a/Eigen/src/Sparse/DynamicSparseMatrix.h +++ b/Eigen/src/Sparse/DynamicSparseMatrix.h @@ -88,7 +88,7 @@ class DynamicSparseMatrix inline int rows() const { return IsRowMajor ? outerSize() : m_innerSize; } inline int cols() const { return IsRowMajor ? m_innerSize : outerSize(); } inline int innerSize() const { return m_innerSize; } - inline int outerSize() const { return m_data.size(); } + inline int outerSize() const { return static_cast(m_data.size()); } inline int innerNonZeros(int j) const { return m_data[j].size(); } std::vector >& _data() { return m_data; } @@ -128,7 +128,7 @@ class DynamicSparseMatrix { int res = 0; for (int j=0; j(m_data[j].size()); return res; } @@ -195,7 +195,7 @@ class DynamicSparseMatrix const int inner = IsRowMajor ? col : row; int startId = 0; - int id = m_data[outer].size() - 1; + int id = static_cast(m_data[outer].size()) - 1; m_data[outer].resize(id+2,1); while ( (id >= startId) && (m_data[outer].index(id) > inner) ) diff --git a/Eigen/src/Sparse/RandomSetter.h b/Eigen/src/Sparse/RandomSetter.h index 50824eba1..b34ca19a8 100644 --- a/Eigen/src/Sparse/RandomSetter.h +++ b/Eigen/src/Sparse/RandomSetter.h @@ -322,7 +322,7 @@ class RandomSetter { int nz = 0; for (int k=0; k(m_hashmaps[k].size()); return nz; } diff --git a/Eigen/src/Sparse/SparseBlock.h b/Eigen/src/Sparse/SparseBlock.h index 6659a88e2..1fe919736 100644 --- a/Eigen/src/Sparse/SparseBlock.h +++ b/Eigen/src/Sparse/SparseBlock.h @@ -220,6 +220,8 @@ class SparseInnerVectorSet, Size> inline int col() const { return IsRowMajor ? this->index() : m_outer; } protected: int m_outer; + private: + InnerIterator& operator=(const InnerIterator&); }; inline SparseInnerVectorSet(const MatrixType& matrix, int outerStart, int outerSize) diff --git a/Eigen/src/Sparse/SparseCwise.h b/Eigen/src/Sparse/SparseCwise.h index bf8f2355c..c2e302956 100644 --- a/Eigen/src/Sparse/SparseCwise.h +++ b/Eigen/src/Sparse/SparseCwise.h @@ -156,6 +156,9 @@ template class SparseCwise protected: ExpressionTypeNested m_matrix; + + private: + SparseCwise& operator=(const SparseCwise&); }; template diff --git a/Eigen/src/Sparse/SparseCwiseBinaryOp.h b/Eigen/src/Sparse/SparseCwiseBinaryOp.h index 2dcd6b944..bb93b60ef 100644 --- a/Eigen/src/Sparse/SparseCwiseBinaryOp.h +++ b/Eigen/src/Sparse/SparseCwiseBinaryOp.h @@ -126,6 +126,9 @@ class SparseCwiseBinaryOp::InnerIterator EIGEN_STRONG_INLINE InnerIterator(const SparseCwiseBinaryOp& binOp, int outer) : Base(binOp,outer) {} + + private: + InnerIterator& operator=(const InnerIterator&); }; /*************************************************************************** @@ -197,6 +200,8 @@ class ei_sparse_cwise_binary_op_inner_iterator_selector, LhsIterator m_lhsIter; RhsIterator m_rhsIter; const BinaryFunc& m_functor; + private: + ei_sparse_cwise_binary_op_inner_iterator_selector& operator=(const ei_sparse_cwise_binary_op_inner_iterator_selector&); }; // sparse - dense (product) diff --git a/Eigen/src/Sparse/SparseCwiseUnaryOp.h b/Eigen/src/Sparse/SparseCwiseUnaryOp.h index 9a73374bd..9c102ed64 100644 --- a/Eigen/src/Sparse/SparseCwiseUnaryOp.h +++ b/Eigen/src/Sparse/SparseCwiseUnaryOp.h @@ -90,6 +90,9 @@ class SparseCwiseUnaryOp::InnerIterator protected: MatrixTypeIterator m_iter; const UnaryOp m_functor; + + private: + InnerIterator& operator=(const InnerIterator&); }; template diff --git a/Eigen/src/Sparse/SparseDiagonalProduct.h b/Eigen/src/Sparse/SparseDiagonalProduct.h index e9ba47f70..24f724ad1 100644 --- a/Eigen/src/Sparse/SparseDiagonalProduct.h +++ b/Eigen/src/Sparse/SparseDiagonalProduct.h @@ -133,6 +133,8 @@ class ei_sparse_diagonal_product_inner_iterator_selector const SparseDiagonalProductType& expr, int outer) : Base(expr.rhs().innerVector(outer) .cwise()* expr.lhs().diagonal(), 0) {} + private: + ei_sparse_diagonal_product_inner_iterator_selector& operator=(const ei_sparse_diagonal_product_inner_iterator_selector&); }; template @@ -165,6 +167,8 @@ class ei_sparse_diagonal_product_inner_iterator_selector const SparseDiagonalProductType& expr, int outer) : Base(expr.lhs().innerVector(outer) .cwise()* expr.rhs().diagonal().transpose(), 0) {} + private: + ei_sparse_diagonal_product_inner_iterator_selector& operator=(const ei_sparse_diagonal_product_inner_iterator_selector&); }; // SparseMatrixBase functions diff --git a/Eigen/src/Sparse/SparseFlagged.h b/Eigen/src/Sparse/SparseFlagged.h index 386a80abc..34233e5a1 100644 --- a/Eigen/src/Sparse/SparseFlagged.h +++ b/Eigen/src/Sparse/SparseFlagged.h @@ -64,6 +64,9 @@ template clas protected: ExpressionTypeNested m_matrix; + + private: + SparseFlagged& operator=(const SparseFlagged&); }; template @@ -74,6 +77,9 @@ template EIGEN_STRONG_INLINE InnerIterator(const SparseFlagged& xpr, int outer) : ExpressionType::InnerIterator(xpr.m_matrix, outer) {} + + private: + InnerIterator& operator=(const InnerIterator&); }; template diff --git a/Eigen/src/Sparse/SparseMatrix.h b/Eigen/src/Sparse/SparseMatrix.h index 36fa123fb..e1c740cdb 100644 --- a/Eigen/src/Sparse/SparseMatrix.h +++ b/Eigen/src/Sparse/SparseMatrix.h @@ -138,7 +138,7 @@ class SparseMatrix } /** \returns the number of non zero coefficients */ - inline int nonZeros() const { return m_data.size(); } + inline int nonZeros() const { return static_cast(m_data.size()); } /** \deprecated use setZero() and reserve() * Initializes the filling process of \c *this. @@ -236,7 +236,7 @@ class SparseMatrix // we start a new inner vector while (previousOuter>=0 && m_outerIndex[previousOuter]==0) { - m_outerIndex[previousOuter] = m_data.size(); + m_outerIndex[previousOuter] = static_cast(m_data.size()); --previousOuter; } m_outerIndex[outer+1] = m_outerIndex[outer]; @@ -335,7 +335,7 @@ class SparseMatrix */ inline void finalize() { - int size = m_data.size(); + int size = static_cast(m_data.size()); int i = m_outerSize; // find the last filled column while (i>=0 && m_outerIndex[i]==0) @@ -557,6 +557,9 @@ class SparseMatrix::InnerIterator int m_id; const int m_start; const int m_end; + + private: + InnerIterator& operator=(const InnerIterator&); }; #endif // EIGEN_SPARSEMATRIX_H diff --git a/Eigen/src/Sparse/SparseTranspose.h b/Eigen/src/Sparse/SparseTranspose.h index 9a702739d..2689caf79 100644 --- a/Eigen/src/Sparse/SparseTranspose.h +++ b/Eigen/src/Sparse/SparseTranspose.h @@ -62,6 +62,9 @@ template class SparseTranspose protected: const typename MatrixType::Nested m_matrix; + + private: + SparseTranspose& operator=(const SparseTranspose&); }; template class SparseTranspose::InnerIterator : public MatrixType::InnerIterator @@ -74,6 +77,9 @@ template class SparseTranspose::InnerIterator : {} inline int row() const { return Base::col(); } inline int col() const { return Base::row(); } + + private: + InnerIterator& operator=(const InnerIterator&); }; template class SparseTranspose::ReverseInnerIterator : public MatrixType::ReverseInnerIterator diff --git a/Eigen/src/Sparse/SparseTriangular.h b/Eigen/src/Sparse/SparseTriangular.h index 42e7ff02a..c3d3ea48f 100644 --- a/Eigen/src/Sparse/SparseTriangular.h +++ b/Eigen/src/Sparse/SparseTriangular.h @@ -47,6 +47,9 @@ template class SparseTriangular protected: ExpressionTypeNested m_matrix; + + private: + SparseTriangular& operator=(const SparseTriangular&); }; template diff --git a/Eigen/src/Sparse/SparseVector.h b/Eigen/src/Sparse/SparseVector.h index 1fa1980b2..b87cae856 100644 --- a/Eigen/src/Sparse/SparseVector.h +++ b/Eigen/src/Sparse/SparseVector.h @@ -125,7 +125,7 @@ class SparseVector inline void setZero() { m_data.clear(); } /** \returns the number of non zero coefficients */ - inline int nonZeros() const { return m_data.size(); } + inline int nonZeros() const { return static_cast(m_data.size()); } inline void startVec(int outer) { @@ -374,13 +374,13 @@ class SparseVector::InnerIterator { public: InnerIterator(const SparseVector& vec, int outer=0) - : m_data(vec.m_data), m_id(0), m_end(m_data.size()) + : m_data(vec.m_data), m_id(0), m_end(static_cast(m_data.size())) { ei_assert(outer==0); } InnerIterator(const CompressedStorage& data) - : m_data(data), m_id(0), m_end(m_data.size()) + : m_data(data), m_id(0), m_end(static_cast(m_data.size())) {} template diff --git a/Eigen/src/misc/Image.h b/Eigen/src/misc/Image.h index 9ed5d5f70..05ffa667c 100644 --- a/Eigen/src/misc/Image.h +++ b/Eigen/src/misc/Image.h @@ -67,9 +67,12 @@ template struct ei_image_retval_base } protected: - const DecompositionType& m_dec; - int m_rank, m_cols; - const MatrixType& m_originalMatrix; + const DecompositionType& m_dec; + int m_rank, m_cols; + const MatrixType& m_originalMatrix; + + private: + ei_image_retval_base& operator=(const ei_image_retval_base&); }; #define EIGEN_MAKE_IMAGE_HELPERS(DecompositionType) \ diff --git a/Eigen/src/misc/Kernel.h b/Eigen/src/misc/Kernel.h index 717eef450..bb8458e11 100644 --- a/Eigen/src/misc/Kernel.h +++ b/Eigen/src/misc/Kernel.h @@ -67,8 +67,11 @@ template struct ei_kernel_retval_base } protected: - const DecompositionType& m_dec; - int m_rank, m_cols; + const DecompositionType& m_dec; + int m_rank, m_cols; + + private: + ei_kernel_retval_base& operator=(const ei_kernel_retval_base&); }; #define EIGEN_MAKE_KERNEL_HELPERS(DecompositionType) \ diff --git a/Eigen/src/misc/Solve.h b/Eigen/src/misc/Solve.h index d93869121..75597564b 100644 --- a/Eigen/src/misc/Solve.h +++ b/Eigen/src/misc/Solve.h @@ -61,8 +61,11 @@ template struct ei_solve_retval_base } protected: - const DecompositionType& m_dec; - const typename Rhs::Nested m_rhs; + const DecompositionType& m_dec; + const typename Rhs::Nested m_rhs; + + private: + ei_solve_retval_base& operator=(const ei_solve_retval_base&); }; #define EIGEN_MAKE_SOLVE_HELPERS(DecompositionType,Rhs) \ diff --git a/cmake/EigenTesting.cmake b/cmake/EigenTesting.cmake index 8e52152e4..bb1da41de 100644 --- a/cmake/EigenTesting.cmake +++ b/cmake/EigenTesting.cmake @@ -222,9 +222,12 @@ if(CMAKE_COMPILER_IS_GNUCXX) else(EIGEN_COVERAGE_TESTING) set(COVERAGE_FLAGS "") endif(EIGEN_COVERAGE_TESTING) - if(EIGEN_TEST_RVALUE_REF_SUPPORT OR EIGEN_TEST_C++0x) + if(EIGEN_TEST_C++0x) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x") - endif(EIGEN_TEST_RVALUE_REF_SUPPORT OR EIGEN_TEST_C++0x) + endif(EIGEN_TEST_C++0x) + if(EIGEN_TEST_MAX_WARNING_LEVEL) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion") + endif(EIGEN_TEST_MAX_WARNING_LEVEL) if(CMAKE_SYSTEM_NAME MATCHES Linux) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_FLAGS} -g2") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COVERAGE_FLAGS} -O2 -g2") @@ -232,5 +235,8 @@ if(CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COVERAGE_FLAGS} -O0 -g3") endif(CMAKE_SYSTEM_NAME MATCHES Linux) elseif(MSVC) - set(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /MDd /Zi /Ob0 /Od" CACHE STRING "Flags used by the compiler during debug builds." FORCE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS") + if(EIGEN_TEST_MAX_WARNING_LEVEL) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") + endif(EIGEN_TEST_MAX_WARNING_LEVEL) endif(CMAKE_COMPILER_IS_GNUCXX) diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp index 050b14995..009cc5ae2 100644 --- a/test/sparse_basic.cpp +++ b/test/sparse_basic.cpp @@ -34,7 +34,7 @@ bool test_random_setter(SparseMatrix& sm, const DenseType& ref, std::vector remaining = nonzeroCoords; while(!remaining.empty()) { - int i = ei_random(0,remaining.size()-1); + int i = ei_random(0,static_cast(remaining.size())-1); w(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y()); remaining[i] = remaining.back(); remaining.pop_back(); @@ -50,7 +50,7 @@ bool test_random_setter(DynamicSparseMatrix& sm, const DenseType& ref, const std::vector remaining = nonzeroCoords; while(!remaining.empty()) { - int i = ei_random(0,remaining.size()-1); + int i = ei_random(0,static_cast(remaining.size())-1); sm.coeffRef(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y()); remaining[i] = remaining.back(); remaining.pop_back(); diff --git a/unsupported/Eigen/FFT b/unsupported/Eigen/FFT index fc2efc1d6..a43cd8d97 100644 --- a/unsupported/Eigen/FFT +++ b/unsupported/Eigen/FFT @@ -160,7 +160,7 @@ class FFT dst.resize( (src.size()>>1)+1); else dst.resize(src.size()); - fwd(&dst[0],&src[0],src.size()); + fwd(&dst[0],&src[0],static_cast(src.size())); } template @@ -224,7 +224,7 @@ class FFT dst.resize( 2*(src.size()-1) ); else dst.resize( src.size() ); - inv( &dst[0],&src[0],dst.size() ); + inv( &dst[0],&src[0],static_cast(dst.size()) ); } // TODO: multi-dimensional FFTs diff --git a/unsupported/Eigen/src/BVH/BVAlgorithms.h b/unsupported/Eigen/src/BVH/BVAlgorithms.h index 47c49be7f..63725763a 100644 --- a/unsupported/Eigen/src/BVH/BVAlgorithms.h +++ b/unsupported/Eigen/src/BVH/BVAlgorithms.h @@ -74,6 +74,8 @@ struct ei_intersector_helper1 bool intersectObject(const Object1 &obj) { return intersector.intersectObjectObject(obj, stored); } Object2 stored; Intersector &intersector; +private: + ei_intersector_helper1& operator=(const ei_intersector_helper1&); }; template @@ -216,6 +218,8 @@ struct ei_minimizer_helper2 Scalar minimumOnObject(const Object2 &obj) { return minimizer.minimumOnObjectObject(stored, obj); } Object1 stored; Minimizer &minimizer; +private: + ei_minimizer_helper2& operator=(const ei_minimizer_helper2&); }; /** Given two BVH's, runs the query on their cartesian product encapsulated by \a minimizer. diff --git a/unsupported/Eigen/src/BVH/KdBVH.h b/unsupported/Eigen/src/BVH/KdBVH.h index ec47254af..c4719607f 100644 --- a/unsupported/Eigen/src/BVH/KdBVH.h +++ b/unsupported/Eigen/src/BVH/KdBVH.h @@ -107,7 +107,7 @@ public: children.clear(); objects.insert(objects.end(), begin, end); - int n = objects.size(); + int n = static_cast(objects.size()); if(n < 2) return; //if we have at most one object, we don't need any internal nodes @@ -149,7 +149,7 @@ public: return; } - int numBoxes = boxes.size(); + int numBoxes = static_cast(boxes.size()); int idx = index * 2; if(children[idx + 1] < numBoxes) { //second index is always bigger diff --git a/unsupported/Eigen/src/FFT/ei_kissfft_impl.h b/unsupported/Eigen/src/FFT/ei_kissfft_impl.h index 2dff2bd00..dbd92132e 100644 --- a/unsupported/Eigen/src/FFT/ei_kissfft_impl.h +++ b/unsupported/Eigen/src/FFT/ei_kissfft_impl.h @@ -247,7 +247,7 @@ struct ei_kiss_cpx_fft int u,k,q1,q; Complex * twiddles = &m_twiddles[0]; Complex t; - int Norig = m_twiddles.size(); + int Norig = static_cast(m_twiddles.size()); Complex * scratchbuf = &m_scratchBuf[0]; for ( u=0; u(fstride) * k; if (twidx>=Norig) twidx-=Norig; t=scratchbuf[q] * twiddles[twidx]; Fout[ k ] += t; diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h index add000c44..9c0d2e53f 100644 --- a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h +++ b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h @@ -292,7 +292,7 @@ void MatrixExponential::computeUV(float) } else { const float maxnorm = 3.925724783138660f; m_squarings = std::max(0, (int)ceil(log2(m_l1norm / maxnorm))); - MatrixType A = *m_M / std::pow(Scalar(2), Scalar(m_squarings)); + MatrixType A = *m_M / std::pow(Scalar(2), Scalar(static_cast(m_squarings))); pade7(A); } } diff --git a/unsupported/test/Complex.cpp b/unsupported/test/Complex.cpp index 969e3f4f9..9ea91cf42 100644 --- a/unsupported/test/Complex.cpp +++ b/unsupported/test/Complex.cpp @@ -40,7 +40,7 @@ template void take_std( std::complex * dst, int n ) { for (int i=0;i(i,i); + dst[i] = std::complex(static_cast(i),static_cast(i)); cout << dst[n-1] << endl; } diff --git a/unsupported/test/FFT.cpp b/unsupported/test/FFT.cpp index b029ba655..056be2ef3 100644 --- a/unsupported/test/FFT.cpp +++ b/unsupported/test/FFT.cpp @@ -46,10 +46,10 @@ complex promote(long double x) { return complex( x); long double difpower=0; cerr <<"idx\ttruth\t\tvalue\t|dif|=\n"; long double pi = acos((long double)-1); - for (size_t k0=0;k0 acc = 0; long double phinc = -2.*k0* pi / timebuf.size(); - for (size_t k1=0;k1(0,k1*phinc) ); } totalpower += norm(acc); @@ -67,8 +67,8 @@ complex promote(long double x) { return complex( x); { long double totalpower=0; long double difpower=0; - size_t n = min( buf1.size(),buf2.size() ); - for (size_t k=0;k Date: Sat, 12 Dec 2009 14:49:43 +0100 Subject: Removed more warnings. --- Eigen/src/Core/Functors.h | 4 ++++ Eigen/src/Core/PermutationMatrix.h | 3 +++ Eigen/src/Core/util/DisableMSVCWarnings.h | 6 ++++-- Eigen/src/Sparse/DynamicSparseMatrix.h | 3 +++ Eigen/src/Sparse/SparseCwiseBinaryOp.h | 3 +++ cmake/EigenTesting.cmake | 4 +++- test/unalignedassert.cpp | 1 + 7 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h index 259f40244..e2a212c89 100644 --- a/Eigen/src/Core/Functors.h +++ b/Eigen/src/Core/Functors.h @@ -365,6 +365,8 @@ struct ei_scalar_multiple2_op { EIGEN_STRONG_INLINE ei_scalar_multiple2_op(const Scalar2& other) : m_other(other) { } EIGEN_STRONG_INLINE result_type operator() (const Scalar1& a) const { return a * m_other; } typename ei_makeconst::Nested>::type m_other; +private: + ei_scalar_multiple2_op& operator=(ei_scalar_multiple2_op&); }; template struct ei_functor_traits > @@ -394,6 +396,8 @@ struct ei_scalar_quotient1_impl { EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const Scalar& other) : m_other(other) {} EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; } typename ei_makeconst::Nested>::type m_other; +private: + ei_scalar_quotient1_impl& operator=(const ei_scalar_quotient1_impl&); }; template struct ei_functor_traits > diff --git a/Eigen/src/Core/PermutationMatrix.h b/Eigen/src/Core/PermutationMatrix.h index 284baf678..4d30b2dac 100644 --- a/Eigen/src/Core/PermutationMatrix.h +++ b/Eigen/src/Core/PermutationMatrix.h @@ -320,6 +320,9 @@ struct ei_permut_matrix_product_retval protected: const PermutationType& m_permutation; const typename MatrixType::Nested m_matrix; + + private: + ei_permut_matrix_product_retval& operator=(ei_permut_matrix_product_retval&); }; #endif // EIGEN_PERMUTATIONMATRIX_H diff --git a/Eigen/src/Core/util/DisableMSVCWarnings.h b/Eigen/src/Core/util/DisableMSVCWarnings.h index c08d0389f..18484e490 100644 --- a/Eigen/src/Core/util/DisableMSVCWarnings.h +++ b/Eigen/src/Core/util/DisableMSVCWarnings.h @@ -1,6 +1,8 @@ #ifdef _MSC_VER - // 4273 - QtAlignedMalloc, inconsistent dll linkage + // 4273 - QtAlignedMalloc, inconsistent DLL linkage + // 4100 - unreferenced formal parameter (occurred e.g. in aligned_allocator::destroy(pointer p)) + // 4101 - we need this one for the inlining fix #pragma warning( push ) - #pragma warning( disable : 4181 4244 4127 4211 4273 4522 4717 ) + #pragma warning( disable : 4100 4101 4181 4244 4127 4211 4273 4522 4717 ) #endif diff --git a/Eigen/src/Sparse/DynamicSparseMatrix.h b/Eigen/src/Sparse/DynamicSparseMatrix.h index f4f83533a..00386442c 100644 --- a/Eigen/src/Sparse/DynamicSparseMatrix.h +++ b/Eigen/src/Sparse/DynamicSparseMatrix.h @@ -323,6 +323,9 @@ class DynamicSparseMatrix::InnerIterator : public SparseVector, LhsIterator m_lhsIter; const BinaryFunc m_functor; const int m_outer; + +private: + ei_sparse_cwise_binary_op_inner_iterator_selector& operator=(ei_sparse_cwise_binary_op_inner_iterator_selector&); }; // sparse - dense (product) diff --git a/cmake/EigenTesting.cmake b/cmake/EigenTesting.cmake index bb1da41de..b8cd63ac1 100644 --- a/cmake/EigenTesting.cmake +++ b/cmake/EigenTesting.cmake @@ -237,6 +237,8 @@ if(CMAKE_COMPILER_IS_GNUCXX) elseif(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS") if(EIGEN_TEST_MAX_WARNING_LEVEL) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") + # C4127 - conditional expression is constant + # C4505 - unreferenced local function has been removed + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /wd4127 /wd4505") endif(EIGEN_TEST_MAX_WARNING_LEVEL) endif(CMAKE_COMPILER_IS_GNUCXX) diff --git a/test/unalignedassert.cpp b/test/unalignedassert.cpp index 2b819417e..c3a07d195 100644 --- a/test/unalignedassert.cpp +++ b/test/unalignedassert.cpp @@ -87,6 +87,7 @@ void construct_at_boundary(int boundary) _buf += (16 - (_buf % 16)); // make 16-byte aligned _buf += boundary; // make exact boundary-aligned T *x = ::new(reinterpret_cast(_buf)) T; + x[0]; // just in order to silence warnings x->~T(); } #endif -- cgit v1.2.3 From 929521678dfdae2a0f698bb88e87ec469d94346c Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Sat, 12 Dec 2009 23:54:44 +0000 Subject: Correct type of ei_solve_retval::operator= --- Eigen/src/Cholesky/LLT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Eigen/src/Cholesky/LLT.h b/Eigen/src/Cholesky/LLT.h index 871530aef..6612984ab 100644 --- a/Eigen/src/Cholesky/LLT.h +++ b/Eigen/src/Cholesky/LLT.h @@ -271,7 +271,7 @@ struct ei_solve_retval, Rhs> dec().solveInPlace(dst); } private: - ei_solve_retval_base& operator=(const ei_solve_retval_base&); + ei_solve_retval& operator=(const ei_solve_retval&); }; /** This is the \em in-place version of solve(). -- cgit v1.2.3 From 63957ad5d6a254df983cd5c6ac29b99a6af63258 Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Sun, 13 Dec 2009 00:29:31 +0000 Subject: Remove //@{ ... //@} for same reason as in changeset 2026ea7ff2be0473511cc74c56538cb98c13d301 . --- unsupported/Eigen/NonLinearOptimization | 3 --- unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h | 1 + unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/unsupported/Eigen/NonLinearOptimization b/unsupported/Eigen/NonLinearOptimization index 3cce1e3ae..c413af436 100644 --- a/unsupported/Eigen/NonLinearOptimization +++ b/unsupported/Eigen/NonLinearOptimization @@ -122,8 +122,6 @@ namespace Eigen { * */ -//@{ - #ifndef EIGEN_PARSED_BY_DOXYGEN #include "src/NonLinearOptimization/qrsolv.h" @@ -143,7 +141,6 @@ namespace Eigen { #include "src/NonLinearOptimization/HybridNonLinearSolver.h" #include "src/NonLinearOptimization/LevenbergMarquardt.h" -//@} } diff --git a/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h b/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h index b2e297741..bcf1016db 100644 --- a/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h +++ b/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h @@ -29,6 +29,7 @@ #define EIGEN_HYBRIDNONLINEARSOLVER_H /** + * \ingroup NonLinearOptimization_Module * \brief Finds a zero of a system of n * nonlinear functions in n variables by a modification of the Powell * hybrid method ("dogleg"). diff --git a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h index 5895fb578..2cf96eb14 100644 --- a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h +++ b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h @@ -29,6 +29,7 @@ #define EIGEN_LEVENBERGMARQUARDT__H /** + * \ingroup NonLinearOptimization_Module * \brief Performs non linear optimization over a non-linear function, * using a variant of the Levenberg Marquardt algorithm. * -- cgit v1.2.3 From 4498864fc83340f3f52a55c12027faac19d1ede1 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Sun, 13 Dec 2009 09:26:57 +0100 Subject: Fixed a bad type conversion. --- Eigen/src/Core/util/Memory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h index 1bff682ff..ebeb55ddd 100644 --- a/Eigen/src/Core/util/Memory.h +++ b/Eigen/src/Core/util/Memory.h @@ -218,7 +218,7 @@ inline static Integer ei_alignmentOffset(const Scalar* ptr, Integer maxOffset) const Integer PacketAlignedMask = PacketSize-1; const bool Vectorized = PacketSize>1; return Vectorized - ? std::min( (PacketSize - (Integer((Integer(ptr)/sizeof(Scalar))) & PacketAlignedMask)) + ? std::min( (PacketSize - (Integer((size_t(ptr)/sizeof(Scalar))) & PacketAlignedMask)) & PacketAlignedMask, maxOffset) : 0; } -- cgit v1.2.3 From 832045d363a6edf59d4dc4ad0cfbe02272dcce3c Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Mon, 14 Dec 2009 10:32:43 +0100 Subject: Warning 4512 (assignment operators could not be generated) is now simply disabled. All unimplemented assignment operators have been removed. --- Eigen/src/Array/Functors.h | 4 ---- Eigen/src/Array/Replicate.h | 3 --- Eigen/src/Array/VectorwiseOp.h | 5 ----- Eigen/src/Cholesky/LDLT.h | 2 -- Eigen/src/Cholesky/LLT.h | 2 -- Eigen/src/Core/CommaInitializer.h | 3 --- Eigen/src/Core/Cwise.h | 3 --- Eigen/src/Core/Flagged.h | 3 --- Eigen/src/Core/Functors.h | 10 ---------- Eigen/src/Core/NestByValue.h | 3 --- Eigen/src/Core/NoAlias.h | 3 --- Eigen/src/Core/PermutationMatrix.h | 3 --- Eigen/src/Core/Product.h | 6 ------ Eigen/src/Core/ProductBase.h | 2 -- Eigen/src/Core/SelfAdjointView.h | 3 --- Eigen/src/Core/Swap.h | 3 --- Eigen/src/Core/util/DisableMSVCWarnings.h | 3 ++- Eigen/src/Geometry/Homogeneous.h | 5 ----- Eigen/src/Householder/HouseholderSequence.h | 3 --- Eigen/src/LU/FullPivLU.h | 9 --------- Eigen/src/LU/Inverse.h | 2 -- Eigen/src/QR/HouseholderQR.h | 2 -- Eigen/src/SVD/SVD.h | 2 -- Eigen/src/Sparse/AmbiVector.h | 4 ---- Eigen/src/Sparse/DynamicSparseMatrix.h | 4 ---- Eigen/src/Sparse/SparseBlock.h | 2 -- Eigen/src/Sparse/SparseCwise.h | 3 --- Eigen/src/Sparse/SparseCwiseBinaryOp.h | 10 ---------- Eigen/src/Sparse/SparseCwiseUnaryOp.h | 3 --- Eigen/src/Sparse/SparseDiagonalProduct.h | 4 ---- Eigen/src/Sparse/SparseFlagged.h | 6 ------ Eigen/src/Sparse/SparseMatrix.h | 3 --- Eigen/src/Sparse/SparseTranspose.h | 6 ------ Eigen/src/Sparse/SparseTriangular.h | 3 --- Eigen/src/misc/Image.h | 3 --- Eigen/src/misc/Kernel.h | 3 --- Eigen/src/misc/Solve.h | 3 --- 37 files changed, 2 insertions(+), 139 deletions(-) diff --git a/Eigen/src/Array/Functors.h b/Eigen/src/Array/Functors.h index 3a7753d04..fd259f7bc 100644 --- a/Eigen/src/Array/Functors.h +++ b/Eigen/src/Array/Functors.h @@ -43,8 +43,6 @@ struct ei_scalar_add_op { inline const PacketScalar packetOp(const PacketScalar& a) const { return ei_padd(a, ei_pset1(m_other)); } const Scalar m_other; -private: - ei_scalar_add_op& operator=(const ei_scalar_add_op&); }; template struct ei_functor_traits > @@ -130,8 +128,6 @@ struct ei_scalar_pow_op { inline ei_scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {} inline Scalar operator() (const Scalar& a) const { return ei_pow(a, m_exponent); } const Scalar m_exponent; -private: - ei_scalar_pow_op& operator=(const ei_scalar_pow_op&); }; template struct ei_functor_traits > diff --git a/Eigen/src/Array/Replicate.h b/Eigen/src/Array/Replicate.h index 478c0bf68..653bda666 100644 --- a/Eigen/src/Array/Replicate.h +++ b/Eigen/src/Array/Replicate.h @@ -94,9 +94,6 @@ template class Replicate const typename MatrixType::Nested m_matrix; const ei_int_if_dynamic m_rowFactor; const ei_int_if_dynamic m_colFactor; - - private: - Replicate& operator=(const Replicate&); }; /** \nonstableyet diff --git a/Eigen/src/Array/VectorwiseOp.h b/Eigen/src/Array/VectorwiseOp.h index 92e5cc000..37ed8ac17 100644 --- a/Eigen/src/Array/VectorwiseOp.h +++ b/Eigen/src/Array/VectorwiseOp.h @@ -147,8 +147,6 @@ struct ei_member_redux { inline result_type operator()(const MatrixBase& mat) const { return mat.redux(m_functor); } const BinaryOp m_functor; -private: - ei_member_redux& operator=(const ei_member_redux&); }; /** \array_module \ingroup Array_Module @@ -490,9 +488,6 @@ template class VectorwiseOp protected: ExpressionTypeNested m_matrix; - - private: - VectorwiseOp& operator=(const VectorwiseOp&); }; /** \array_module diff --git a/Eigen/src/Cholesky/LDLT.h b/Eigen/src/Cholesky/LDLT.h index 2898d8747..d0f292634 100644 --- a/Eigen/src/Cholesky/LDLT.h +++ b/Eigen/src/Cholesky/LDLT.h @@ -275,8 +275,6 @@ struct ei_solve_retval, Rhs> dst = rhs(); dec().solveInPlace(dst); } -private: - ei_solve_retval& operator=(const ei_solve_retval&); }; /** This is the \em in-place version of solve(). diff --git a/Eigen/src/Cholesky/LLT.h b/Eigen/src/Cholesky/LLT.h index 6612984ab..ad737aaeb 100644 --- a/Eigen/src/Cholesky/LLT.h +++ b/Eigen/src/Cholesky/LLT.h @@ -270,8 +270,6 @@ struct ei_solve_retval, Rhs> dst = rhs(); dec().solveInPlace(dst); } -private: - ei_solve_retval& operator=(const ei_solve_retval&); }; /** This is the \em in-place version of solve(). diff --git a/Eigen/src/Core/CommaInitializer.h b/Eigen/src/Core/CommaInitializer.h index 328c5580c..e86f47ad0 100644 --- a/Eigen/src/Core/CommaInitializer.h +++ b/Eigen/src/Core/CommaInitializer.h @@ -116,9 +116,6 @@ struct CommaInitializer int m_row; // current row id int m_col; // current col id int m_currentBlockRows; // current block height - -private: - CommaInitializer& operator=(const CommaInitializer&); }; /** \anchor MatrixBaseCommaInitRef diff --git a/Eigen/src/Core/Cwise.h b/Eigen/src/Core/Cwise.h index 80414782e..4f3d641cb 100644 --- a/Eigen/src/Core/Cwise.h +++ b/Eigen/src/Core/Cwise.h @@ -178,9 +178,6 @@ template class Cwise protected: ExpressionTypeNested m_matrix; - - private: - Cwise& operator=(const Cwise&); }; /** \returns a Cwise wrapper of *this providing additional coefficient-wise operations diff --git a/Eigen/src/Core/Flagged.h b/Eigen/src/Core/Flagged.h index b98861f42..754eaf6c5 100644 --- a/Eigen/src/Core/Flagged.h +++ b/Eigen/src/Core/Flagged.h @@ -111,9 +111,6 @@ template clas protected: ExpressionTypeNested m_matrix; - - private: - Flagged& operator=(const Flagged&); }; /** \deprecated it is only used by lazy() which is deprecated diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h index e2a212c89..6b62fb4ea 100644 --- a/Eigen/src/Core/Functors.h +++ b/Eigen/src/Core/Functors.h @@ -351,8 +351,6 @@ struct ei_scalar_multiple_op { EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const { return ei_pmul(a, ei_pset1(m_other)); } typename ei_makeconst::Nested>::type m_other; -private: - ei_scalar_multiple_op& operator=(const ei_scalar_multiple_op&); }; template struct ei_functor_traits > @@ -365,8 +363,6 @@ struct ei_scalar_multiple2_op { EIGEN_STRONG_INLINE ei_scalar_multiple2_op(const Scalar2& other) : m_other(other) { } EIGEN_STRONG_INLINE result_type operator() (const Scalar1& a) const { return a * m_other; } typename ei_makeconst::Nested>::type m_other; -private: - ei_scalar_multiple2_op& operator=(ei_scalar_multiple2_op&); }; template struct ei_functor_traits > @@ -382,8 +378,6 @@ struct ei_scalar_quotient1_impl { EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const { return ei_pmul(a, ei_pset1(m_other)); } const Scalar m_other; -private: - ei_scalar_quotient1_impl& operator=(const ei_scalar_quotient1_impl&); }; template struct ei_functor_traits > @@ -396,8 +390,6 @@ struct ei_scalar_quotient1_impl { EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const Scalar& other) : m_other(other) {} EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; } typename ei_makeconst::Nested>::type m_other; -private: - ei_scalar_quotient1_impl& operator=(const ei_scalar_quotient1_impl&); }; template struct ei_functor_traits > @@ -431,8 +423,6 @@ struct ei_scalar_constant_op { EIGEN_STRONG_INLINE const Scalar operator() (int, int = 0) const { return m_other; } EIGEN_STRONG_INLINE const PacketScalar packetOp() const { return ei_pset1(m_other); } const Scalar m_other; -private: - ei_scalar_constant_op& operator=(const ei_scalar_constant_op&); }; template struct ei_functor_traits > diff --git a/Eigen/src/Core/NestByValue.h b/Eigen/src/Core/NestByValue.h index 94a8f8078..85a672779 100644 --- a/Eigen/src/Core/NestByValue.h +++ b/Eigen/src/Core/NestByValue.h @@ -102,9 +102,6 @@ template class NestByValue protected: const ExpressionType m_expression; - - private: - NestByValue& operator=(const NestByValue&); }; /** \returns an expression of the temporary version of *this. diff --git a/Eigen/src/Core/NoAlias.h b/Eigen/src/Core/NoAlias.h index dc32c2f7b..66d8d834d 100644 --- a/Eigen/src/Core/NoAlias.h +++ b/Eigen/src/Core/NoAlias.h @@ -73,9 +73,6 @@ class NoAlias protected: ExpressionType& m_expression; - - private: - NoAlias& operator=(const NoAlias&); }; /** \returns a pseudo expression of \c *this with an operator= assuming diff --git a/Eigen/src/Core/PermutationMatrix.h b/Eigen/src/Core/PermutationMatrix.h index 4d30b2dac..284baf678 100644 --- a/Eigen/src/Core/PermutationMatrix.h +++ b/Eigen/src/Core/PermutationMatrix.h @@ -320,9 +320,6 @@ struct ei_permut_matrix_product_retval protected: const PermutationType& m_permutation; const typename MatrixType::Nested m_matrix; - - private: - ei_permut_matrix_product_retval& operator=(ei_permut_matrix_product_retval&); }; #endif // EIGEN_PERMUTATIONMATRIX_H diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index cc751650d..d24ef6159 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -211,9 +211,6 @@ class GeneralProduct { ei_outer_product_selector<(int(Dest::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(*this, dest, alpha); } - - private: - GeneralProduct& operator=(const GeneralProduct&); }; template<> struct ei_outer_product_selector { @@ -279,9 +276,6 @@ class GeneralProduct ei_gemv_selector::ActualAccess)>::run(*this, dst, alpha); } - -private: - GeneralProduct& operator=(const GeneralProduct&); }; // The vector is on the left => transposition diff --git a/Eigen/src/Core/ProductBase.h b/Eigen/src/Core/ProductBase.h index 955e87feb..33ada4bee 100644 --- a/Eigen/src/Core/ProductBase.h +++ b/Eigen/src/Core/ProductBase.h @@ -129,8 +129,6 @@ class ProductBase : public MatrixBase void coeffRef(int,int); void coeff(int) const; void coeffRef(int); - - ProductBase& operator=(const ProductBase&); }; template diff --git a/Eigen/src/Core/SelfAdjointView.h b/Eigen/src/Core/SelfAdjointView.h index 9518a6498..9b6b3261f 100644 --- a/Eigen/src/Core/SelfAdjointView.h +++ b/Eigen/src/Core/SelfAdjointView.h @@ -151,9 +151,6 @@ template class SelfAdjointView protected: const typename MatrixType::Nested m_matrix; - - private: - SelfAdjointView& operator=(const SelfAdjointView&); }; diff --git a/Eigen/src/Core/Swap.h b/Eigen/src/Core/Swap.h index 45c180983..a7cf219f7 100644 --- a/Eigen/src/Core/Swap.h +++ b/Eigen/src/Core/Swap.h @@ -117,9 +117,6 @@ template class SwapWrapper protected: ExpressionType& m_expression; - - private: - SwapWrapper& operator=(const SwapWrapper&); }; /** swaps *this with the expression \a other. diff --git a/Eigen/src/Core/util/DisableMSVCWarnings.h b/Eigen/src/Core/util/DisableMSVCWarnings.h index 18484e490..c11d582fd 100644 --- a/Eigen/src/Core/util/DisableMSVCWarnings.h +++ b/Eigen/src/Core/util/DisableMSVCWarnings.h @@ -2,7 +2,8 @@ #ifdef _MSC_VER // 4273 - QtAlignedMalloc, inconsistent DLL linkage // 4100 - unreferenced formal parameter (occurred e.g. in aligned_allocator::destroy(pointer p)) - // 4101 - we need this one for the inlining fix + // 4101 - unreferenced local variable + // 4512 - assignment operator could not be generated #pragma warning( push ) #pragma warning( disable : 4100 4101 4181 4244 4127 4211 4273 4522 4717 ) #endif diff --git a/Eigen/src/Geometry/Homogeneous.h b/Eigen/src/Geometry/Homogeneous.h index f2a2fe73e..229fd80b3 100644 --- a/Eigen/src/Geometry/Homogeneous.h +++ b/Eigen/src/Geometry/Homogeneous.h @@ -241,8 +241,6 @@ struct ei_homogeneous_left_product_impl,Lhs> const typename Lhs::Nested m_lhs; const typename MatrixType::Nested m_rhs; -private: - ei_homogeneous_left_product_impl& operator=(const ei_homogeneous_left_product_impl&); }; template @@ -281,9 +279,6 @@ struct ei_homogeneous_right_product_impl,Rhs> const typename MatrixType::Nested m_lhs; const typename Rhs::Nested m_rhs; - -private: - ei_homogeneous_right_product_impl& operator=(const ei_homogeneous_right_product_impl&); }; #endif // EIGEN_HOMOGENEOUS_H diff --git a/Eigen/src/Householder/HouseholderSequence.h b/Eigen/src/Householder/HouseholderSequence.h index 1159f03ed..25e962001 100644 --- a/Eigen/src/Householder/HouseholderSequence.h +++ b/Eigen/src/Householder/HouseholderSequence.h @@ -161,9 +161,6 @@ template class HouseholderSequence typename CoeffsType::Nested m_coeffs; bool m_trans; int m_actualVectors; - -private: - HouseholderSequence& operator=(const HouseholderSequence&); }; template diff --git a/Eigen/src/LU/FullPivLU.h b/Eigen/src/LU/FullPivLU.h index 5505d3bee..1358c9490 100644 --- a/Eigen/src/LU/FullPivLU.h +++ b/Eigen/src/LU/FullPivLU.h @@ -562,9 +562,6 @@ struct ei_kernel_retval > for(int i = rank(); i < cols; ++i) dst.row(dec().permutationQ().indices().coeff(i)).setZero(); for(int k = 0; k < dimker; ++k) dst.coeffRef(dec().permutationQ().indices().coeff(rank()+k), k) = Scalar(1); } - -private: - ei_kernel_retval& operator=(const ei_kernel_retval&); }; /***** Implementation of image() *****************************************************/ @@ -602,9 +599,6 @@ struct ei_image_retval > for(int i = 0; i < rank(); ++i) dst.col(i) = originalMatrix().col(dec().permutationQ().indices().coeff(pivots.coeff(i))); } - -private: - ei_image_retval& operator=(const ei_image_retval&); }; /***** Implementation of solve() *****************************************************/ @@ -665,9 +659,6 @@ struct ei_solve_retval, Rhs> for(int i = nonzero_pivots; i < dec().matrixLU().cols(); ++i) dst.row(dec().permutationQ().indices().coeff(i)).setZero(); } - -private: - ei_solve_retval& operator=(const ei_solve_retval&); }; /******* MatrixBase methods *****************************************************************/ diff --git a/Eigen/src/LU/Inverse.h b/Eigen/src/LU/Inverse.h index c31b3502e..8afbfda96 100644 --- a/Eigen/src/LU/Inverse.h +++ b/Eigen/src/LU/Inverse.h @@ -258,8 +258,6 @@ struct ei_inverse_impl : public ReturnByValue > { ei_compute_inverse::run(m_matrix, dst); } -private: - ei_inverse_impl& operator=(const ei_inverse_impl&); }; /** \lu_module diff --git a/Eigen/src/QR/HouseholderQR.h b/Eigen/src/QR/HouseholderQR.h index 3b174a873..95496b943 100644 --- a/Eigen/src/QR/HouseholderQR.h +++ b/Eigen/src/QR/HouseholderQR.h @@ -237,8 +237,6 @@ struct ei_solve_retval, Rhs> dst.corner(TopLeft, rank, c.cols()) = c.corner(TopLeft, rank, c.cols()); dst.corner(BottomLeft, cols-rank, c.cols()).setZero(); } -private: - ei_solve_retval& operator=(const ei_solve_retval&); }; #endif // EIGEN_HIDE_HEAVY_CODE diff --git a/Eigen/src/SVD/SVD.h b/Eigen/src/SVD/SVD.h index a90704cb9..0ec41e36d 100644 --- a/Eigen/src/SVD/SVD.h +++ b/Eigen/src/SVD/SVD.h @@ -456,8 +456,6 @@ struct ei_solve_retval, Rhs> dst.col(j) = dec().matrixV() * dst.col(j); } } -private: - ei_solve_retval& operator=(const ei_solve_retval&); }; /** Computes the polar decomposition of the matrix, as a product unitary x positive. diff --git a/Eigen/src/Sparse/AmbiVector.h b/Eigen/src/Sparse/AmbiVector.h index 5e75bd6e7..2988999d6 100644 --- a/Eigen/src/Sparse/AmbiVector.h +++ b/Eigen/src/Sparse/AmbiVector.h @@ -126,10 +126,6 @@ template class AmbiVector int m_llStart; int m_llCurrent; int m_llSize; - - private: - AmbiVector(const AmbiVector&); - }; /** \returns the number of non zeros in the current sub vector */ diff --git a/Eigen/src/Sparse/DynamicSparseMatrix.h b/Eigen/src/Sparse/DynamicSparseMatrix.h index 00386442c..3ce5e84da 100644 --- a/Eigen/src/Sparse/DynamicSparseMatrix.h +++ b/Eigen/src/Sparse/DynamicSparseMatrix.h @@ -320,12 +320,8 @@ class DynamicSparseMatrix::InnerIterator : public SparseVector, Size> inline int col() const { return IsRowMajor ? this->index() : m_outer; } protected: int m_outer; - private: - InnerIterator& operator=(const InnerIterator&); }; inline SparseInnerVectorSet(const MatrixType& matrix, int outerStart, int outerSize) diff --git a/Eigen/src/Sparse/SparseCwise.h b/Eigen/src/Sparse/SparseCwise.h index c2e302956..bf8f2355c 100644 --- a/Eigen/src/Sparse/SparseCwise.h +++ b/Eigen/src/Sparse/SparseCwise.h @@ -156,9 +156,6 @@ template class SparseCwise protected: ExpressionTypeNested m_matrix; - - private: - SparseCwise& operator=(const SparseCwise&); }; template diff --git a/Eigen/src/Sparse/SparseCwiseBinaryOp.h b/Eigen/src/Sparse/SparseCwiseBinaryOp.h index 01f4da197..2dcd6b944 100644 --- a/Eigen/src/Sparse/SparseCwiseBinaryOp.h +++ b/Eigen/src/Sparse/SparseCwiseBinaryOp.h @@ -126,9 +126,6 @@ class SparseCwiseBinaryOp::InnerIterator EIGEN_STRONG_INLINE InnerIterator(const SparseCwiseBinaryOp& binOp, int outer) : Base(binOp,outer) {} - - private: - InnerIterator& operator=(const InnerIterator&); }; /*************************************************************************** @@ -200,8 +197,6 @@ class ei_sparse_cwise_binary_op_inner_iterator_selector, LhsIterator m_lhsIter; RhsIterator m_rhsIter; const BinaryFunc& m_functor; - private: - ei_sparse_cwise_binary_op_inner_iterator_selector& operator=(const ei_sparse_cwise_binary_op_inner_iterator_selector&); }; // sparse - dense (product) @@ -297,9 +290,6 @@ class ei_sparse_cwise_binary_op_inner_iterator_selector, LhsIterator m_lhsIter; const BinaryFunc m_functor; const int m_outer; - -private: - ei_sparse_cwise_binary_op_inner_iterator_selector& operator=(ei_sparse_cwise_binary_op_inner_iterator_selector&); }; // sparse - dense (product) diff --git a/Eigen/src/Sparse/SparseCwiseUnaryOp.h b/Eigen/src/Sparse/SparseCwiseUnaryOp.h index 9c102ed64..9a73374bd 100644 --- a/Eigen/src/Sparse/SparseCwiseUnaryOp.h +++ b/Eigen/src/Sparse/SparseCwiseUnaryOp.h @@ -90,9 +90,6 @@ class SparseCwiseUnaryOp::InnerIterator protected: MatrixTypeIterator m_iter; const UnaryOp m_functor; - - private: - InnerIterator& operator=(const InnerIterator&); }; template diff --git a/Eigen/src/Sparse/SparseDiagonalProduct.h b/Eigen/src/Sparse/SparseDiagonalProduct.h index 24f724ad1..e9ba47f70 100644 --- a/Eigen/src/Sparse/SparseDiagonalProduct.h +++ b/Eigen/src/Sparse/SparseDiagonalProduct.h @@ -133,8 +133,6 @@ class ei_sparse_diagonal_product_inner_iterator_selector const SparseDiagonalProductType& expr, int outer) : Base(expr.rhs().innerVector(outer) .cwise()* expr.lhs().diagonal(), 0) {} - private: - ei_sparse_diagonal_product_inner_iterator_selector& operator=(const ei_sparse_diagonal_product_inner_iterator_selector&); }; template @@ -167,8 +165,6 @@ class ei_sparse_diagonal_product_inner_iterator_selector const SparseDiagonalProductType& expr, int outer) : Base(expr.lhs().innerVector(outer) .cwise()* expr.rhs().diagonal().transpose(), 0) {} - private: - ei_sparse_diagonal_product_inner_iterator_selector& operator=(const ei_sparse_diagonal_product_inner_iterator_selector&); }; // SparseMatrixBase functions diff --git a/Eigen/src/Sparse/SparseFlagged.h b/Eigen/src/Sparse/SparseFlagged.h index 34233e5a1..386a80abc 100644 --- a/Eigen/src/Sparse/SparseFlagged.h +++ b/Eigen/src/Sparse/SparseFlagged.h @@ -64,9 +64,6 @@ template clas protected: ExpressionTypeNested m_matrix; - - private: - SparseFlagged& operator=(const SparseFlagged&); }; template @@ -77,9 +74,6 @@ template EIGEN_STRONG_INLINE InnerIterator(const SparseFlagged& xpr, int outer) : ExpressionType::InnerIterator(xpr.m_matrix, outer) {} - - private: - InnerIterator& operator=(const InnerIterator&); }; template diff --git a/Eigen/src/Sparse/SparseMatrix.h b/Eigen/src/Sparse/SparseMatrix.h index e1c740cdb..8369bba54 100644 --- a/Eigen/src/Sparse/SparseMatrix.h +++ b/Eigen/src/Sparse/SparseMatrix.h @@ -557,9 +557,6 @@ class SparseMatrix::InnerIterator int m_id; const int m_start; const int m_end; - - private: - InnerIterator& operator=(const InnerIterator&); }; #endif // EIGEN_SPARSEMATRIX_H diff --git a/Eigen/src/Sparse/SparseTranspose.h b/Eigen/src/Sparse/SparseTranspose.h index 2689caf79..9a702739d 100644 --- a/Eigen/src/Sparse/SparseTranspose.h +++ b/Eigen/src/Sparse/SparseTranspose.h @@ -62,9 +62,6 @@ template class SparseTranspose protected: const typename MatrixType::Nested m_matrix; - - private: - SparseTranspose& operator=(const SparseTranspose&); }; template class SparseTranspose::InnerIterator : public MatrixType::InnerIterator @@ -77,9 +74,6 @@ template class SparseTranspose::InnerIterator : {} inline int row() const { return Base::col(); } inline int col() const { return Base::row(); } - - private: - InnerIterator& operator=(const InnerIterator&); }; template class SparseTranspose::ReverseInnerIterator : public MatrixType::ReverseInnerIterator diff --git a/Eigen/src/Sparse/SparseTriangular.h b/Eigen/src/Sparse/SparseTriangular.h index c3d3ea48f..42e7ff02a 100644 --- a/Eigen/src/Sparse/SparseTriangular.h +++ b/Eigen/src/Sparse/SparseTriangular.h @@ -47,9 +47,6 @@ template class SparseTriangular protected: ExpressionTypeNested m_matrix; - - private: - SparseTriangular& operator=(const SparseTriangular&); }; template diff --git a/Eigen/src/misc/Image.h b/Eigen/src/misc/Image.h index 05ffa667c..2f39d6b9d 100644 --- a/Eigen/src/misc/Image.h +++ b/Eigen/src/misc/Image.h @@ -70,9 +70,6 @@ template struct ei_image_retval_base const DecompositionType& m_dec; int m_rank, m_cols; const MatrixType& m_originalMatrix; - - private: - ei_image_retval_base& operator=(const ei_image_retval_base&); }; #define EIGEN_MAKE_IMAGE_HELPERS(DecompositionType) \ diff --git a/Eigen/src/misc/Kernel.h b/Eigen/src/misc/Kernel.h index bb8458e11..908c408e9 100644 --- a/Eigen/src/misc/Kernel.h +++ b/Eigen/src/misc/Kernel.h @@ -69,9 +69,6 @@ template struct ei_kernel_retval_base protected: const DecompositionType& m_dec; int m_rank, m_cols; - - private: - ei_kernel_retval_base& operator=(const ei_kernel_retval_base&); }; #define EIGEN_MAKE_KERNEL_HELPERS(DecompositionType) \ diff --git a/Eigen/src/misc/Solve.h b/Eigen/src/misc/Solve.h index 75597564b..4ab0775fc 100644 --- a/Eigen/src/misc/Solve.h +++ b/Eigen/src/misc/Solve.h @@ -63,9 +63,6 @@ template struct ei_solve_retval_base protected: const DecompositionType& m_dec; const typename Rhs::Nested m_rhs; - - private: - ei_solve_retval_base& operator=(const ei_solve_retval_base&); }; #define EIGEN_MAKE_SOLVE_HELPERS(DecompositionType,Rhs) \ -- cgit v1.2.3 From d5f3b2dc943a712a92834cebaea8bb9caae2f6e9 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 14 Dec 2009 17:26:24 -0500 Subject: change the Arch constants: const int ---> enum, more explicit names, and use of a namespace instead of Prefix_Name. --- Eigen/src/Core/util/Constants.h | 21 ++++++++++++--------- Eigen/src/Geometry/OrthoMethods.h | 5 +++-- Eigen/src/Geometry/Quaternion.h | 2 +- Eigen/src/Geometry/arch/Geometry_SSE.h | 6 ++++-- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h index 5489d063a..1128876f8 100644 --- a/Eigen/src/Core/util/Constants.h +++ b/Eigen/src/Core/util/Constants.h @@ -228,8 +228,7 @@ enum { RowMajor = 0x1, // it is only a coincidence that this is equal to RowMajorBit -- don't rely on that /** \internal Align the matrix itself if it is vectorizable fixed-size */ AutoAlign = 0, - /** \internal Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be - requested to be aligned) */ + /** \internal Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be requested to be aligned) */ // FIXME --- clarify the situation DontAlign = 0x2 }; @@ -277,16 +276,20 @@ enum TransformTraits { Projective = 0x20 }; -const int EiArch_Generic = 0x0; -const int EiArch_SSE = 0x1; -const int EiArch_AltiVec = 0x2; - +namespace Architecture +{ + enum Type { + Generic = 0x0, + SSE = 0x1, + AltiVec = 0x2, #if defined EIGEN_VECTORIZE_SSE - const int EiArch = EiArch_SSE; + Target = SSE #elif defined EIGEN_VECTORIZE_ALTIVEC - const int EiArch = EiArch_AltiVec; + Target = AltiVec #else - const int EiArch = EiArch_Generic; + Target = Generic #endif + }; +} #endif // EIGEN_CONSTANTS_H diff --git a/Eigen/src/Geometry/OrthoMethods.h b/Eigen/src/Geometry/OrthoMethods.h index 6d4a8f673..d16b72c43 100644 --- a/Eigen/src/Geometry/OrthoMethods.h +++ b/Eigen/src/Geometry/OrthoMethods.h @@ -90,8 +90,9 @@ MatrixBase::cross3(const MatrixBase& other) const const DerivedNested lhs(derived()); const OtherDerivedNested rhs(other.derived()); - return ei_cross3_impl::type, - typename ei_cleantype::type>::run(lhs,rhs); + return ei_cross3_impl::type, + typename ei_cleantype::type>::run(lhs,rhs); } /** \returns a matrix expression of the cross product of each column or row diff --git a/Eigen/src/Geometry/Quaternion.h b/Eigen/src/Geometry/Quaternion.h index b6eb74d66..861eff19c 100644 --- a/Eigen/src/Geometry/Quaternion.h +++ b/Eigen/src/Geometry/Quaternion.h @@ -367,7 +367,7 @@ QuaternionBase::operator* (const QuaternionBase& other) c { EIGEN_STATIC_ASSERT((ei_is_same_type::ret), YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - return ei_quat_product::Scalar, ei_traits::PacketAccess && ei_traits::PacketAccess>::run(*this, other); } diff --git a/Eigen/src/Geometry/arch/Geometry_SSE.h b/Eigen/src/Geometry/arch/Geometry_SSE.h index a6ed10d82..297932f92 100644 --- a/Eigen/src/Geometry/arch/Geometry_SSE.h +++ b/Eigen/src/Geometry/arch/Geometry_SSE.h @@ -26,7 +26,8 @@ #ifndef EIGEN_GEOMETRY_SSE_H #define EIGEN_GEOMETRY_SSE_H -template struct ei_quat_product +template +struct ei_quat_product { inline static Quaternion run(const QuaternionBase& _a, const QuaternionBase& _b) { @@ -48,7 +49,8 @@ template struct ei_quat_product -struct ei_cross3_impl { +struct ei_cross3_impl +{ inline static typename ei_plain_matrix_type::type run(const VectorLhs& lhs, const VectorRhs& rhs) { -- cgit v1.2.3 From d02eccf5840b356e741ea0e3166db2c7623b88c4 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 14 Dec 2009 22:47:14 -0500 Subject: add SSE path for Matrix4f inverse, taken from Intel except that we do a kosher division instead of RCPPS-followed-by-Newton-Raphson. The rationale for that is that elsewhere in Eigen we dont allow ourselves this approximation (which throws 2 bits of mantissa), so there's no reason we should allow it here. --- COPYING.LGPL | 2 +- Eigen/LU | 1 + Eigen/src/LU/Inverse.h | 18 +++-- Eigen/src/LU/arch/CMakeLists.txt | 6 ++ Eigen/src/LU/arch/Inverse_SSE.h | 152 +++++++++++++++++++++++++++++++++++++++ test/prec_inverse_4x4.cpp | 7 +- 6 files changed, 175 insertions(+), 11 deletions(-) create mode 100644 Eigen/src/LU/arch/CMakeLists.txt create mode 100644 Eigen/src/LU/arch/Inverse_SSE.h diff --git a/COPYING.LGPL b/COPYING.LGPL index fc8a5de7e..0e4fa8aaf 100644 --- a/COPYING.LGPL +++ b/COPYING.LGPL @@ -1,4 +1,4 @@ - GNU LESSER GENERAL PUBLIC LICENSE + GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. diff --git a/Eigen/LU b/Eigen/LU index c17b9852e..ce11279b6 100644 --- a/Eigen/LU +++ b/Eigen/LU @@ -25,6 +25,7 @@ namespace Eigen { #include "src/LU/PartialPivLU.h" #include "src/LU/Determinant.h" #include "src/LU/Inverse.h" +#include "src/LU/arch/Inverse_SSE.h" } // namespace Eigen diff --git a/Eigen/src/LU/Inverse.h b/Eigen/src/LU/Inverse.h index 8afbfda96..91d02164c 100644 --- a/Eigen/src/LU/Inverse.h +++ b/Eigen/src/LU/Inverse.h @@ -182,10 +182,10 @@ struct ei_compute_inverse_and_det_with_check *** Size 4 implementation *** ****************************/ -template -struct ei_compute_inverse +template +struct ei_compute_inverse_size4 { - static inline void run(const MatrixType& matrix, ResultType& result) + static void run(const MatrixType& matrix, ResultType& result) { result.coeffRef(0,0) = matrix.minor(0,0).determinant(); result.coeffRef(1,0) = -matrix.minor(0,1).determinant(); @@ -207,6 +207,13 @@ struct ei_compute_inverse } }; +template +struct ei_compute_inverse + : ei_compute_inverse_size4 +{ +}; + template struct ei_compute_inverse_and_det_with_check { @@ -238,7 +245,8 @@ template struct ei_inverse_impl : public ReturnByValue > { // for 2x2, it's worth giving a chance to avoid evaluating. - // for larger sizes, evaluating has negligible cost and limits code size. + // for larger sizes, evaluating has negligible cost, limits code size, + // and allows for vectorized paths. typedef typename ei_meta_if< MatrixType::RowsAtCompileTime == 2, typename ei_nested::type, @@ -264,7 +272,7 @@ struct ei_inverse_impl : public ReturnByValue > * * \returns the matrix inverse of this matrix. * - * For small fixed sizes up to 4x4, this method uses ad-hoc methods (cofactors up to 3x3, Euler's trick for 4x4). + * For small fixed sizes up to 4x4, this method uses cofactors. * In the general case, this method uses class PartialPivLU. * * \note This matrix must be invertible, otherwise the result is undefined. If you need an diff --git a/Eigen/src/LU/arch/CMakeLists.txt b/Eigen/src/LU/arch/CMakeLists.txt new file mode 100644 index 000000000..f6b7ed9ec --- /dev/null +++ b/Eigen/src/LU/arch/CMakeLists.txt @@ -0,0 +1,6 @@ +FILE(GLOB Eigen_LU_arch_SRCS "*.h") + +INSTALL(FILES + ${Eigen_LU_arch_SRCS} + DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/LU/arch COMPONENT Devel + ) diff --git a/Eigen/src/LU/arch/Inverse_SSE.h b/Eigen/src/LU/arch/Inverse_SSE.h new file mode 100644 index 000000000..371861aa5 --- /dev/null +++ b/Eigen/src/LU/arch/Inverse_SSE.h @@ -0,0 +1,152 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 1999 Intel Corporation +// Copyright (C) 2009 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 . + +// The SSE code for the 4x4 float matrix inverse in this file comes from the file +// ftp://download.intel.com/design/PentiumIII/sml/24504301.pdf +// See page ii of that document for legal stuff. Not being lawyers, we just assume +// here that if Intel makes this document publically available, with source code +// and detailed explanations, it's because they want their CPUs to be fed with +// good code, and therefore they presumably don't mind us using it in Eigen. + +#ifndef EIGEN_INVERSE_SSE_H +#define EIGEN_INVERSE_SSE_H + +template +struct ei_compute_inverse_size4 +{ + static void run(const MatrixType& matrix, ResultType& result) + { + // Variables (Streaming SIMD Extensions registers) which will contain cofactors and, later, the + // lines of the inverted matrix. + __m128 minor0, minor1, minor2, minor3; + + // Variables which will contain the lines of the reference matrix and, later (after the transposition), + // the columns of the original matrix. + __m128 row0, row1, row2, row3; + + // Temporary variables and the variable that will contain the matrix determinant. + __m128 det, tmp1; + + // Matrix transposition + const float *src = matrix.data(); + tmp1 = _mm_loadh_pi(_mm_loadl_pi(tmp1, (__m64*)(src)), (__m64*)(src+ 4)); + row1 = _mm_loadh_pi(_mm_loadl_pi(row1, (__m64*)(src+8)), (__m64*)(src+12)); + row0 = _mm_shuffle_ps(tmp1, row1, 0x88); + row1 = _mm_shuffle_ps(row1, tmp1, 0xDD); + tmp1 = _mm_loadh_pi(_mm_loadl_pi(tmp1, (__m64*)(src+ 2)), (__m64*)(src+ 6)); + row3 = _mm_loadh_pi(_mm_loadl_pi(row3, (__m64*)(src+10)), (__m64*)(src+14)); + row2 = _mm_shuffle_ps(tmp1, row3, 0x88); + row3 = _mm_shuffle_ps(row3, tmp1, 0xDD); + + + // Cofactors calculation. Because in the process of cofactor computation some pairs in three- + // element products are repeated, it is not reasonable to load these pairs anew every time. The + // values in the registers with these pairs are formed using shuffle instruction. Cofactors are + // calculated row by row (4 elements are placed in 1 SP FP SIMD floating point register). + + tmp1 = _mm_mul_ps(row2, row3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor0 = _mm_mul_ps(row1, tmp1); + minor1 = _mm_mul_ps(row0, tmp1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor0 = _mm_sub_ps(_mm_mul_ps(row1, tmp1), minor0); + minor1 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor1); + minor1 = _mm_shuffle_ps(minor1, minor1, 0x4E); + // ----------------------------------------------- + tmp1 = _mm_mul_ps(row1, row2); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor0 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor0); + minor3 = _mm_mul_ps(row0, tmp1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row3, tmp1)); + minor3 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor3); + minor3 = _mm_shuffle_ps(minor3, minor3, 0x4E); + // ----------------------------------------------- + tmp1 = _mm_mul_ps(_mm_shuffle_ps(row1, row1, 0x4E), row3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + row2 = _mm_shuffle_ps(row2, row2, 0x4E); + minor0 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor0); + minor2 = _mm_mul_ps(row0, tmp1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row2, tmp1)); + minor2 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor2); + minor2 = _mm_shuffle_ps(minor2, minor2, 0x4E); + // ----------------------------------------------- + tmp1 = _mm_mul_ps(row0, row1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor2 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor2); + minor3 = _mm_sub_ps(_mm_mul_ps(row2, tmp1), minor3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor2 = _mm_sub_ps(_mm_mul_ps(row3, tmp1), minor2); + minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row2, tmp1)); + // ----------------------------------------------- + tmp1 = _mm_mul_ps(row0, row3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row2, tmp1)); + minor2 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor2); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor1 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor1); + minor2 = _mm_sub_ps(minor2, _mm_mul_ps(row1, tmp1)); + // ----------------------------------------------- + tmp1 = _mm_mul_ps(row0, row2); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor1 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor1); + minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row1, tmp1)); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row3, tmp1)); + minor3 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor3); + + // Evaluation of determinant and its reciprocal value. In the original Intel document, + // 1/det was evaluated using a fast rcpps command with subsequent approximation using + // the Newton-Raphson algorithm. Here, we go for a IEEE-compliant division instead, + // so as to not compromise precision at all. + det = _mm_mul_ps(row0, minor0); + det = _mm_add_ps(_mm_shuffle_ps(det, det, 0x4E), det); + det = _mm_add_ss(_mm_shuffle_ps(det, det, 0xB1), det); + // tmp1= _mm_rcp_ss(det); + // det= _mm_sub_ss(_mm_add_ss(tmp1, tmp1), _mm_mul_ss(det, _mm_mul_ss(tmp1, tmp1))); + det = _mm_div_ps(ei_pset1(1.0f), det); // <--- yay, one original line not copied from Intel + det = _mm_shuffle_ps(det, det, 0x00); + // warning, Intel's variable naming is very confusing: now 'det' is 1/det ! + + // Multiplication of cofactors by 1/det. Storing the inverse matrix to the address in pointer src. + minor0 = _mm_mul_ps(det, minor0); + float *dst = result.data(); + _mm_storel_pi((__m64*)(dst), minor0); + _mm_storeh_pi((__m64*)(dst+2), minor0); + minor1 = _mm_mul_ps(det, minor1); + _mm_storel_pi((__m64*)(dst+4), minor1); + _mm_storeh_pi((__m64*)(dst+6), minor1); + minor2 = _mm_mul_ps(det, minor2); + _mm_storel_pi((__m64*)(dst+ 8), minor2); + _mm_storeh_pi((__m64*)(dst+10), minor2); + minor3 = _mm_mul_ps(det, minor3); + _mm_storel_pi((__m64*)(dst+12), minor3); + _mm_storeh_pi((__m64*)(dst+14), minor3); + } +}; + +#endif // EIGEN_INVERSE_SSE_H + \ No newline at end of file diff --git a/test/prec_inverse_4x4.cpp b/test/prec_inverse_4x4.cpp index 83b1a8a71..8b7dbd8e7 100644 --- a/test/prec_inverse_4x4.cpp +++ b/test/prec_inverse_4x4.cpp @@ -37,12 +37,9 @@ template void inverse_permutation_4x4() MatrixType m = PermutationMatrix<4>(indices); MatrixType inv = m.inverse(); double error = double( (m*inv-MatrixType::Identity()).norm() / epsilon() ); - error_max = std::max(error_max, error); + VERIFY(error == 0.0); std::next_permutation(indices.data(),indices.data()+4); } - std::cerr << "inverse_permutation_4x4, Scalar = " << type_name() << std::endl; - EIGEN_DEBUG_VAR(error_max); - VERIFY(error_max < 1. ); } template void inverse_general_4x4(int repeat) @@ -68,7 +65,7 @@ template void inverse_general_4x4(int repeat) EIGEN_DEBUG_VAR(error_avg); EIGEN_DEBUG_VAR(error_max); VERIFY(error_avg < (NumTraits::IsComplex ? 8.0 : 1.0)); - VERIFY(error_max < (NumTraits::IsComplex ? 64.0 : 16.0)); + VERIFY(error_max < (NumTraits::IsComplex ? 64.0 : 20.0)); } void test_prec_inverse_4x4() -- cgit v1.2.3 From 39095c8faa00a4a8a3409a25986f0d1ac58c0606 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 14 Dec 2009 22:52:11 -0500 Subject: only include SSE path if SSE enabled --- Eigen/LU | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Eigen/LU b/Eigen/LU index ce11279b6..9ef9c97ec 100644 --- a/Eigen/LU +++ b/Eigen/LU @@ -25,7 +25,10 @@ namespace Eigen { #include "src/LU/PartialPivLU.h" #include "src/LU/Determinant.h" #include "src/LU/Inverse.h" -#include "src/LU/arch/Inverse_SSE.h" + +#if defined EIGEN_VECTORIZE_SSE + #include "src/LU/arch/Inverse_SSE.h" +#endif } // namespace Eigen -- cgit v1.2.3 From 4948448939ca6694179ea3f04dd79c74cea7cb82 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 14 Dec 2009 23:13:54 -0500 Subject: *use scalar instructions, packet not needed here *remove unused var warning --- Eigen/src/LU/arch/Inverse_SSE.h | 2 +- test/prec_inverse_4x4.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Eigen/src/LU/arch/Inverse_SSE.h b/Eigen/src/LU/arch/Inverse_SSE.h index 371861aa5..30ce81af7 100644 --- a/Eigen/src/LU/arch/Inverse_SSE.h +++ b/Eigen/src/LU/arch/Inverse_SSE.h @@ -127,7 +127,7 @@ struct ei_compute_inverse_size4(1.0f), det); // <--- yay, one original line not copied from Intel + det = _mm_div_ss(_mm_set_ss(1.0f), det); // <--- yay, one original line not copied from Intel det = _mm_shuffle_ps(det, det, 0x00); // warning, Intel's variable naming is very confusing: now 'det' is 1/det ! diff --git a/test/prec_inverse_4x4.cpp b/test/prec_inverse_4x4.cpp index 8b7dbd8e7..e1b05aa0d 100644 --- a/test/prec_inverse_4x4.cpp +++ b/test/prec_inverse_4x4.cpp @@ -30,7 +30,6 @@ template void inverse_permutation_4x4() { typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::RealScalar RealScalar; - double error_max = 0.; Vector4i indices(0,1,2,3); for(int i = 0; i < 24; ++i) { -- cgit v1.2.3 From 46a9cac7fbd4b17d42c703886750d93188916f9a Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 14 Dec 2009 23:31:00 -0500 Subject: silence 'statement has no effect' warning with gcc 4.4 --- test/unalignedassert.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unalignedassert.cpp b/test/unalignedassert.cpp index c3a07d195..85a83b7b5 100644 --- a/test/unalignedassert.cpp +++ b/test/unalignedassert.cpp @@ -87,7 +87,7 @@ void construct_at_boundary(int boundary) _buf += (16 - (_buf % 16)); // make 16-byte aligned _buf += boundary; // make exact boundary-aligned T *x = ::new(reinterpret_cast(_buf)) T; - x[0]; // just in order to silence warnings + x[0].setZero(); // just in order to silence warnings x->~T(); } #endif -- cgit v1.2.3 From 3ea1f97f6911a29b98a77b5ba793e8c0a9fc75e0 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Tue, 15 Dec 2009 08:09:14 +0100 Subject: Suppressed the warning for missing assignment generators (forgot that in the last submission). Commented Quake3's fast inverser sqrt in SSE's MathFunction header. --- Eigen/src/Core/arch/SSE/MathFunctions.h | 2 ++ Eigen/src/Core/util/DisableMSVCWarnings.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Eigen/src/Core/arch/SSE/MathFunctions.h b/Eigen/src/Core/arch/SSE/MathFunctions.h index 8399aac30..3c0020248 100644 --- a/Eigen/src/Core/arch/SSE/MathFunctions.h +++ b/Eigen/src/Core/arch/SSE/MathFunctions.h @@ -365,6 +365,8 @@ static EIGEN_DONT_INLINE EIGEN_UNUSED Packet4f ei_pcos(Packet4f x) return _mm_xor_ps(y, sign_bit); } +// This is Quake3's fast inverse square root. +// For detail see here: http://www.beyond3d.com/content/articles/8/ static EIGEN_UNUSED Packet4f ei_psqrt(Packet4f _x) { Packet4f half = ei_pmul(_x, ei_pset1(.5f)); diff --git a/Eigen/src/Core/util/DisableMSVCWarnings.h b/Eigen/src/Core/util/DisableMSVCWarnings.h index c11d582fd..dcc71143d 100644 --- a/Eigen/src/Core/util/DisableMSVCWarnings.h +++ b/Eigen/src/Core/util/DisableMSVCWarnings.h @@ -5,5 +5,5 @@ // 4101 - unreferenced local variable // 4512 - assignment operator could not be generated #pragma warning( push ) - #pragma warning( disable : 4100 4101 4181 4244 4127 4211 4273 4522 4717 ) + #pragma warning( disable : 4100 4101 4181 4244 4127 4211 4273 4512 4522 4717 ) #endif -- cgit v1.2.3 From 805eb9cc8bcb337483e72a7831014d73a1c5388e Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Tue, 15 Dec 2009 06:50:40 -0500 Subject: Gael, who is a man of few words^Winstructions, is right, as usual. --- Eigen/src/LU/arch/Inverse_SSE.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Eigen/src/LU/arch/Inverse_SSE.h b/Eigen/src/LU/arch/Inverse_SSE.h index 30ce81af7..0b54edfd4 100644 --- a/Eigen/src/LU/arch/Inverse_SSE.h +++ b/Eigen/src/LU/arch/Inverse_SSE.h @@ -51,8 +51,8 @@ struct ei_compute_inverse_size4 Date: Tue, 15 Dec 2009 07:43:05 -0500 Subject: no, this wasn't equivalent to ei_pload at all, after all! --- Eigen/src/LU/arch/Inverse_SSE.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Eigen/src/LU/arch/Inverse_SSE.h b/Eigen/src/LU/arch/Inverse_SSE.h index 0b54edfd4..30ce81af7 100644 --- a/Eigen/src/LU/arch/Inverse_SSE.h +++ b/Eigen/src/LU/arch/Inverse_SSE.h @@ -51,8 +51,8 @@ struct ei_compute_inverse_size4 Date: Tue, 15 Dec 2009 13:59:02 +0100 Subject: suppress unused variable warnings --- Eigen/src/LU/arch/Inverse_SSE.h | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Eigen/src/LU/arch/Inverse_SSE.h b/Eigen/src/LU/arch/Inverse_SSE.h index 30ce81af7..cded9195c 100644 --- a/Eigen/src/LU/arch/Inverse_SSE.h +++ b/Eigen/src/LU/arch/Inverse_SSE.h @@ -51,12 +51,12 @@ struct ei_compute_inverse_size4 Date: Fri, 11 Dec 2009 02:39:49 +0100 Subject: ignore more build*/ directories --- .hgignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.hgignore b/.hgignore index 9432702ba..3f08ce8d5 100644 --- a/.hgignore +++ b/.hgignore @@ -12,7 +12,7 @@ core core.* *.bak *~ -build +build* *.moc.* *.moc ui_* @@ -21,4 +21,4 @@ tags .*.swp activity.png *.out -*.php* \ No newline at end of file +*.php* -- cgit v1.2.3 From 6db6774c4685b997ab4343e5c5b4d48af84e45e7 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Wed, 16 Dec 2009 11:41:16 +0100 Subject: * fix aliasing checks when the lhs is also transposed. At the same time, significantly simplify the code of these checks while extending them to catch much more expressions! * move the enabling/disabling of vectorized sin/cos to the architecture traits --- Eigen/src/Array/Functors.h | 4 +- Eigen/src/Core/Assign.h | 3 ++ Eigen/src/Core/MatrixBase.h | 23 ++++------- Eigen/src/Core/Transpose.h | 78 +++++++++--------------------------- Eigen/src/Core/arch/SSE/PacketMath.h | 4 +- Eigen/src/Core/util/BlasUtil.h | 4 ++ test/adjoint.cpp | 8 ++++ 7 files changed, 46 insertions(+), 78 deletions(-) diff --git a/Eigen/src/Array/Functors.h b/Eigen/src/Array/Functors.h index fd259f7bc..120c56cc1 100644 --- a/Eigen/src/Array/Functors.h +++ b/Eigen/src/Array/Functors.h @@ -87,7 +87,7 @@ struct ei_functor_traits > { enum { Cost = 5 * NumTraits::MulCost, - PacketAccess = ei_packet_traits::HasCos && EIGEN_FAST_MATH + PacketAccess = ei_packet_traits::HasCos }; }; @@ -109,7 +109,7 @@ struct ei_functor_traits > { enum { Cost = 5 * NumTraits::MulCost, - PacketAccess = ei_packet_traits::HasSin && EIGEN_FAST_MATH + PacketAccess = ei_packet_traits::HasSin }; }; diff --git a/Eigen/src/Core/Assign.h b/Eigen/src/Core/Assign.h index 00febdc5d..d544a6198 100644 --- a/Eigen/src/Core/Assign.h +++ b/Eigen/src/Core/Assign.h @@ -484,6 +484,9 @@ EIGEN_STRONG_INLINE Derived& MatrixBase ei_assign_impl::run(derived(),other.derived()); #ifdef EIGEN_DEBUG_ASSIGN ei_assign_traits::debug(); +#endif +#ifndef EIGEN_NO_DEBUG + checkTransposeAliasing(other.derived()); #endif return derived(); } diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 03d8d5f55..593108522 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -436,21 +436,12 @@ template class MatrixBase void transposeInPlace(); const AdjointReturnType adjoint() const; void adjointInPlace(); - #ifndef EIGEN_NO_DEBUG - template - Derived& lazyAssign(const Transpose& other); - template - Derived& lazyAssign(const CwiseBinaryOp,Transpose,DerivedB>& other); - template - Derived& lazyAssign(const CwiseBinaryOp,DerivedA,Transpose >& other); - +#ifndef EIGEN_NO_DEBUG + protected: template - Derived& lazyAssign(const CwiseUnaryOp, Eigen::Transpose >& other); - template - Derived& lazyAssign(const CwiseBinaryOp,CwiseUnaryOp, Eigen::Transpose >,DerivedB>& other); - template - Derived& lazyAssign(const CwiseBinaryOp,DerivedA,CwiseUnaryOp, Eigen::Transpose > >& other); - #endif + void checkTransposeAliasing(const OtherDerived& other) const; + public: +#endif RowXpr row(int i); const RowXpr row(int i) const; @@ -638,7 +629,7 @@ template class MatrixBase const CwiseBinaryOp binaryExpr(const MatrixBase &other, const CustomBinaryOp& func = CustomBinaryOp()) const; - + Scalar sum() const; Scalar mean() const; Scalar trace() const; @@ -818,7 +809,7 @@ template class MatrixBase INVALID_MATRIXBASE_TEMPLATE_PARAMETERS) #endif } - + private: explicit MatrixBase(int); MatrixBase(int,int); diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h index 79aef9fa7..796ec8573 100644 --- a/Eigen/src/Core/Transpose.h +++ b/Eigen/src/Core/Transpose.h @@ -268,13 +268,7 @@ inline void MatrixBase::adjointInPlace() #ifndef EIGEN_NO_DEBUG -// The following is to detect aliasing problems in the following common cases: -// a = a.transpose() -// a = a.transpose() + X -// a = X + a.transpose() -// a = a.adjoint() -// a = a.adjoint() + X -// a = X + a.adjoint() +// The following is to detect aliasing problems in most common cases. template::ActualAccess> struct ei_extract_data_selector { @@ -294,63 +288,31 @@ template typename T::Scalar* ei_extract_data(const T& m) return ei_extract_data_selector::run(m); } -template -template -Derived& MatrixBase::lazyAssign(const Transpose& other) -{ - ei_assert(ei_extract_data(other) != ei_extract_data(derived()) - && "aliasing detected during tranposition, please use transposeInPlace()"); - return lazyAssign(static_cast >& >(other)); -} - -template -template -Derived& MatrixBase:: -lazyAssign(const CwiseBinaryOp,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,Transpose,DerivedB> >& >(other)); -} - -template -template -Derived& MatrixBase:: -lazyAssign(const CwiseBinaryOp,DerivedA,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,Transpose > >& >(other)); -} - -template -template Derived& -MatrixBase:: -lazyAssign(const CwiseUnaryOp, Eigen::Transpose >& other) +template +struct ei_check_transpose_aliasing_selector { - ei_assert(ei_extract_data(other) != ei_extract_data(derived()) - && "aliasing detected during tranposition, please use adjointInPlace()"); - return lazyAssign(static_cast, Eigen::Transpose > >& >(other)); -} + static bool run(const Scalar* dest, const OtherDerived& src) + { + return (ei_blas_traits::IsTransposed != DestIsTranposed) && (dest==ei_extract_data(src)); + } +}; -template -template -Derived& MatrixBase:: -lazyAssign(const CwiseBinaryOp,CwiseUnaryOp, Eigen::Transpose >,DerivedB>& other) +template +struct ei_check_transpose_aliasing_selector > { - ei_assert(ei_extract_data(derived()) != ei_extract_data(other.lhs()) - && "aliasing detected during tranposition, please evaluate your expression"); - return lazyAssign(static_cast,CwiseUnaryOp, Eigen::Transpose >,DerivedB> >& >(other)); -} + static bool run(const Scalar* dest, const CwiseBinaryOp& src) + { + return ((ei_blas_traits::IsTransposed != DestIsTranposed) && dest==ei_extract_data(src.lhs())) + || ((ei_blas_traits::IsTransposed != DestIsTranposed) && dest==ei_extract_data(src.rhs())); + } +}; template -template -Derived& MatrixBase:: -lazyAssign(const CwiseBinaryOp,DerivedA,CwiseUnaryOp, Eigen::Transpose > >& other) +template +void MatrixBase::checkTransposeAliasing(const OtherDerived& other) const { - 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, Eigen::Transpose > > >& >(other)); + ei_assert((!ei_check_transpose_aliasing_selector::IsTransposed,OtherDerived>::run(ei_extract_data(derived()), other)) + && "aliasing detected during tranposition, use transposeInPlace() or evaluate the rhs into a temporary using .eval()"); } #endif diff --git a/Eigen/src/Core/arch/SSE/PacketMath.h b/Eigen/src/Core/arch/SSE/PacketMath.h index 69f6979bd..dbdddb38d 100644 --- a/Eigen/src/Core/arch/SSE/PacketMath.h +++ b/Eigen/src/Core/arch/SSE/PacketMath.h @@ -58,8 +58,8 @@ template<> struct ei_packet_traits : ei_default_packet_traits { typedef Packet4f type; enum {size=4}; enum { - HasSin = 1, - HasCos = 1, + HasSin = EIGEN_FAST_MATH, + HasCos = EIGEN_FAST_MATH, HasLog = 1, HasExp = 1, HasSqrt = 1 diff --git a/Eigen/src/Core/util/BlasUtil.h b/Eigen/src/Core/util/BlasUtil.h index a012a6e12..fa21ceebb 100644 --- a/Eigen/src/Core/util/BlasUtil.h +++ b/Eigen/src/Core/util/BlasUtil.h @@ -160,6 +160,7 @@ template struct ei_blas_traits typedef XprType _ExtractType; enum { IsComplex = NumTraits::IsComplex, + IsTransposed = false, NeedToConjugate = false, ActualAccess = int(ei_traits::Flags)&DirectAccessBit ? HasDirectAccess : NoDirectAccess }; @@ -227,6 +228,9 @@ struct ei_blas_traits > ExtractType, typename ExtractType::PlainMatrixType >::ret DirectLinearAccessType; + enum { + IsTransposed = Base::IsTransposed ? 0 : 1 + }; static inline const ExtractType extract(const XprType& x) { return Base::extract(x._expression()); } static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x._expression()); } }; diff --git a/test/adjoint.cpp b/test/adjoint.cpp index 344399257..b34112249 100644 --- a/test/adjoint.cpp +++ b/test/adjoint.cpp @@ -128,6 +128,14 @@ void test_adjoint() VERIFY_RAISES_ASSERT(a = a.adjoint()); VERIFY_RAISES_ASSERT(a = a.adjoint() + b); VERIFY_RAISES_ASSERT(a = b + a.adjoint()); + + // no assertion should be triggered for these cases: + a.transpose() = a.transpose(); + a.transpose() += a.transpose(); + a.transpose() += a.transpose() + b; + a.transpose() = a.adjoint(); + a.transpose() += a.adjoint(); + a.transpose() += a.adjoint() + b; } #endif } -- cgit v1.2.3 From bb59c22dc99517080276b61e09c53c00bbdb844d Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Wed, 16 Dec 2009 12:48:15 +0100 Subject: fix compilation when mixing types --- Eigen/src/Core/Transpose.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h index 796ec8573..1e037e618 100644 --- a/Eigen/src/Core/Transpose.h +++ b/Eigen/src/Core/Transpose.h @@ -293,7 +293,7 @@ struct ei_check_transpose_aliasing_selector { static bool run(const Scalar* dest, const OtherDerived& src) { - return (ei_blas_traits::IsTransposed != DestIsTranposed) && (dest==ei_extract_data(src)); + return (ei_blas_traits::IsTransposed != DestIsTranposed) && (dest==(Scalar*)ei_extract_data(src)); } }; @@ -302,8 +302,8 @@ struct ei_check_transpose_aliasing_selector& src) { - return ((ei_blas_traits::IsTransposed != DestIsTranposed) && dest==ei_extract_data(src.lhs())) - || ((ei_blas_traits::IsTransposed != DestIsTranposed) && dest==ei_extract_data(src.rhs())); + return ((ei_blas_traits::IsTransposed != DestIsTranposed) && dest==(Scalar*)ei_extract_data(src.lhs())) + || ((ei_blas_traits::IsTransposed != DestIsTranposed) && dest==(Scalar*)ei_extract_data(src.rhs())); } }; -- cgit v1.2.3 From c35fcf3bbdbc746e0739c7ae3a6865ccf606d5ed Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Wed, 16 Dec 2009 12:53:55 +0100 Subject: fix warning by making ei_empty_struct::_ei_dummy_ private --- 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 5f3b6286c..eb7f30ced 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -28,7 +28,7 @@ // just a workaround because GCC seems to not really like empty structs #ifdef __GNUG__ - struct ei_empty_struct{char _ei_dummy_;}; + class ei_empty_struct{char _ei_dummy_;}; #define EIGEN_EMPTY_STRUCT : Eigen::ei_empty_struct #else #define EIGEN_EMPTY_STRUCT -- cgit v1.2.3 From e0aa29121fe72ea5f8e420d363b18ac9d7a96949 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Wed, 16 Dec 2009 13:06:47 +0100 Subject: this really fix the previous warning --- Eigen/src/Core/util/XprHelper.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index eb7f30ced..622c84a8e 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -28,7 +28,13 @@ // just a workaround because GCC seems to not really like empty structs #ifdef __GNUG__ - class ei_empty_struct{char _ei_dummy_;}; + struct ei_empty_struct + { + EIGEN_ALWAYS_INLINE_ATTRIB ei_empty_struct() {} + EIGEN_ALWAYS_INLINE_ATTRIB ei_empty_struct(const ei_empty_struct&) {} + EIGEN_ALWAYS_INLINE_ATTRIB ei_empty_struct& operator=(const ei_empty_struct&) { return *this; } + char _ei_dummy_; + }; #define EIGEN_EMPTY_STRUCT : Eigen::ei_empty_struct #else #define EIGEN_EMPTY_STRUCT -- cgit v1.2.3 From 5cb779e5e15ff0e10976f59672bd9067ea0e972e Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Wed, 16 Dec 2009 08:53:14 -0500 Subject: * introduce ei_alignmentOffset(MatrixBase&,Integer) couldnt put it in Memory.h as it needs the definition of MatrixBase * make Redux use it --- Eigen/src/Core/Coeffs.h | 32 ++++++++++++++++++++++++++++++++ Eigen/src/Core/Redux.h | 5 +---- Eigen/src/Core/util/Memory.h | 6 +++++- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/Eigen/src/Core/Coeffs.h b/Eigen/src/Core/Coeffs.h index 2618f0dce..eda36b7bb 100644 --- a/Eigen/src/Core/Coeffs.h +++ b/Eigen/src/Core/Coeffs.h @@ -379,6 +379,38 @@ EIGEN_STRONG_INLINE void MatrixBase::copyPacket(int index, const Matrix other.derived().template packet(index)); } + +template +struct ei_alignmentOffset_impl +{ + inline static Integer run(const MatrixBase&, Integer) + { return 0; } +}; + +template +struct ei_alignmentOffset_impl +{ + inline static Integer run(const MatrixBase& m, Integer maxOffset) + { + return ei_alignmentOffset(&m.const_cast_derived().coeffRef(0,0), maxOffset); + } +}; + +/** \internal \returns the number of elements which have to be skipped, starting + * from the address of coeffRef(0,0), to find the first 16-byte aligned element. + * + * \note If the expression doesn't have the DirectAccessBit, this function returns 0. + * + * There is also the variant ei_alignmentOffset(const Scalar*, Integer) defined in Memory.h. + */ +template +inline static Integer ei_alignmentOffset(const MatrixBase& m, Integer maxOffset) +{ + return ei_alignmentOffset_impl + ::run(m, maxOffset); +} + #endif #endif // EIGEN_COEFFS_H diff --git a/Eigen/src/Core/Redux.h b/Eigen/src/Core/Redux.h index 171f6dcf5..ae6b01f57 100644 --- a/Eigen/src/Core/Redux.h +++ b/Eigen/src/Core/Redux.h @@ -209,10 +209,7 @@ struct ei_redux_impl { const int size = mat.size(); const int packetSize = ei_packet_traits::size; - const int alignedStart = (Derived::Flags & AlignedBit) - || !(Derived::Flags & DirectAccessBit) - ? 0 - : ei_alignmentOffset(&mat.const_cast_derived().coeffRef(0), size); + const int alignedStart = ei_alignmentOffset(mat,size); enum { alignment = (Derived::Flags & DirectAccessBit) || (Derived::Flags & AlignedBit) ? Aligned : Unaligned diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h index ebeb55ddd..524bec2fc 100644 --- a/Eigen/src/Core/util/Memory.h +++ b/Eigen/src/Core/util/Memory.h @@ -209,7 +209,11 @@ template inline void ei_conditional_aligned_delete(T *pt ei_conditional_aligned_free(ptr); } -/** \internal \returns the number of elements which have to be skipped such that data are 16 bytes aligned */ +/** \internal \returns the number of elements which have to be skipped to + * find the first 16-byte aligned element + * + * There is also the variant ei_alignmentOffset(const MatrixBase&, Integer) defined in Coeffs.h. + */ template inline static Integer ei_alignmentOffset(const Scalar* ptr, Integer maxOffset) { -- cgit v1.2.3 From 945cbc3bc602e29298c9bc878e7f4c3f9e804ea4 Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Wed, 16 Dec 2009 22:24:24 +0000 Subject: Add test for issue #75 (Hessenberg of 1x1 matrix). Also remove an superfluous #include in matrixExponential test. --- test/eigensolver_complex.cpp | 1 + unsupported/test/matrixExponential.cpp | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/test/eigensolver_complex.cpp b/test/eigensolver_complex.cpp index 756527d57..2af289116 100644 --- a/test/eigensolver_complex.cpp +++ b/test/eigensolver_complex.cpp @@ -60,5 +60,6 @@ void test_eigensolver_complex() for(int i = 0; i < g_repeat; i++) { CALL_SUBTEST_1( eigensolver(Matrix4cf()) ); CALL_SUBTEST_2( eigensolver(MatrixXcd(14,14)) ); + CALL_SUBTEST_3( eigensolver(Matrix, 1, 1>()) ); } } diff --git a/unsupported/test/matrixExponential.cpp b/unsupported/test/matrixExponential.cpp index f7ee71768..828504547 100644 --- a/unsupported/test/matrixExponential.cpp +++ b/unsupported/test/matrixExponential.cpp @@ -23,7 +23,6 @@ // Eigen. If not, see . #include "main.h" -#include #include double binom(int n, int k) -- cgit v1.2.3 From 9d5478303667bd97f3e20696f8a8c82cb5b2d65f Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Fri, 18 Dec 2009 17:08:59 +0100 Subject: much better workaround for empty struct (the previous one caused GCC 4.3 to generate wrong code leading to segfaults) --- Eigen/src/Array/Functors.h | 12 +++++++--- Eigen/src/Array/Random.h | 4 ++-- Eigen/src/Array/VectorwiseOp.h | 3 ++- Eigen/src/Core/Functors.h | 51 +++++++++++++++++++++++++++-------------- Eigen/src/Core/util/XprHelper.h | 17 +++++--------- 5 files changed, 53 insertions(+), 34 deletions(-) diff --git a/Eigen/src/Array/Functors.h b/Eigen/src/Array/Functors.h index 120c56cc1..975fd9c7f 100644 --- a/Eigen/src/Array/Functors.h +++ b/Eigen/src/Array/Functors.h @@ -56,7 +56,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, Cwise::sqrt() */ -template struct ei_scalar_sqrt_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_sqrt_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_sqrt_op) inline const Scalar operator() (const Scalar& a) const { return ei_sqrt(a); } typedef typename ei_packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return ei_psqrt(a); } @@ -77,7 +78,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, Cwise::cos() */ -template struct ei_scalar_cos_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_cos_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cos_op) inline Scalar operator() (const Scalar& a) const { return ei_cos(a); } typedef typename ei_packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return ei_pcos(a); } @@ -99,7 +101,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, Cwise::sin() */ -template struct ei_scalar_sin_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_sin_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_sin_op) inline const Scalar operator() (const Scalar& a) const { return ei_sin(a); } typedef typename ei_packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return ei_psin(a); } @@ -143,6 +146,7 @@ struct ei_functor_traits > */ template struct ei_scalar_inverse_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_inverse_op) inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; } template inline const PacketScalar packetOp(const PacketScalar& a) const @@ -162,6 +166,7 @@ struct ei_functor_traits > */ template struct ei_scalar_square_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_square_op) inline Scalar operator() (const Scalar& a) const { return a*a; } template inline const PacketScalar packetOp(const PacketScalar& a) const @@ -181,6 +186,7 @@ struct ei_functor_traits > */ template struct ei_scalar_cube_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cube_op) inline Scalar operator() (const Scalar& a) const { return a*a*a; } template inline const PacketScalar packetOp(const PacketScalar& a) const diff --git a/Eigen/src/Array/Random.h b/Eigen/src/Array/Random.h index adadf99e3..b94ccda68 100644 --- a/Eigen/src/Array/Random.h +++ b/Eigen/src/Array/Random.h @@ -25,8 +25,8 @@ #ifndef EIGEN_RANDOM_H #define EIGEN_RANDOM_H -template struct ei_scalar_random_op EIGEN_EMPTY_STRUCT { - inline ei_scalar_random_op(void) {} +template struct ei_scalar_random_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_random_op) inline const Scalar operator() (int, int) const { return ei_random(); } }; template diff --git a/Eigen/src/Array/VectorwiseOp.h b/Eigen/src/Array/VectorwiseOp.h index 37ed8ac17..bb695c795 100644 --- a/Eigen/src/Array/VectorwiseOp.h +++ b/Eigen/src/Array/VectorwiseOp.h @@ -110,7 +110,8 @@ class PartialReduxExpr : ei_no_assignment_operator, #define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \ template \ - struct ei_member_##MEMBER EIGEN_EMPTY_STRUCT { \ + struct ei_member_##MEMBER { \ + EIGEN_EMPTY_STRUCT_CTOR(ei_member_##MEMBER) \ typedef ResultType result_type; \ template struct Cost \ { enum { value = COST }; }; \ diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h index 6b62fb4ea..1a4edfc4a 100644 --- a/Eigen/src/Core/Functors.h +++ b/Eigen/src/Core/Functors.h @@ -32,7 +32,8 @@ * * \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum() */ -template struct ei_scalar_sum_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_sum_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_sum_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -54,7 +55,8 @@ struct ei_functor_traits > { * * \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux() */ -template struct ei_scalar_product_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_product_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_product_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -76,7 +78,8 @@ struct ei_functor_traits > { * * \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff() */ -template struct ei_scalar_min_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_min_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_min_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::min(a, b); } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -98,7 +101,8 @@ struct ei_functor_traits > { * * \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff() */ -template struct ei_scalar_max_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_max_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_max_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::max(a, b); } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -120,7 +124,8 @@ struct ei_functor_traits > { * * \sa MatrixBase::stableNorm(), class Redux */ -template struct ei_scalar_hypot_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_hypot_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_hypot_op) // typedef typename NumTraits::Real result_type; EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const { @@ -142,7 +147,8 @@ struct ei_functor_traits > { * * \sa class CwiseBinaryOp, MatrixBase::operator- */ -template struct ei_scalar_difference_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_difference_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_difference_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -161,7 +167,8 @@ struct ei_functor_traits > { * * \sa class CwiseBinaryOp, Cwise::operator/() */ -template struct ei_scalar_quotient_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_quotient_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_quotient_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -185,7 +192,8 @@ struct ei_functor_traits > { * * \sa class CwiseUnaryOp, MatrixBase::operator- */ -template struct ei_scalar_opposite_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_opposite_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_opposite_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const @@ -203,7 +211,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, Cwise::abs */ -template struct ei_scalar_abs_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_abs_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_abs_op) typedef typename NumTraits::Real result_type; EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs(a); } template @@ -224,7 +233,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, Cwise::abs2 */ -template struct ei_scalar_abs2_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_abs2_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_abs2_op) typedef typename NumTraits::Real result_type; EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs2(a); } template @@ -240,7 +250,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, MatrixBase::conjugate() */ -template struct ei_scalar_conjugate_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_conjugate_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_conjugate_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return ei_conj(a); } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const { return a; } @@ -260,7 +271,8 @@ struct ei_functor_traits > * \sa class CwiseUnaryOp, MatrixBase::cast() */ template -struct ei_scalar_cast_op EIGEN_EMPTY_STRUCT { +struct ei_scalar_cast_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cast_op) typedef NewType result_type; EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return static_cast(a); } }; @@ -274,7 +286,8 @@ struct ei_functor_traits > * \sa class CwiseUnaryOp, MatrixBase::real() */ template -struct ei_scalar_real_op EIGEN_EMPTY_STRUCT { +struct ei_scalar_real_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_real_op) typedef typename NumTraits::Real result_type; EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_real(a); } EIGEN_STRONG_INLINE result_type& operator() (Scalar& a) const { return ei_real_ref(a); } @@ -289,7 +302,8 @@ struct ei_functor_traits > * \sa class CwiseUnaryOp, MatrixBase::imag() */ template -struct ei_scalar_imag_op EIGEN_EMPTY_STRUCT { +struct ei_scalar_imag_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_imag_op) typedef typename NumTraits::Real result_type; EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_imag(a); } EIGEN_STRONG_INLINE result_type& operator() (Scalar& a) const { return ei_imag_ref(a); } @@ -304,7 +318,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, Cwise::exp() */ -template struct ei_scalar_exp_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_exp_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_exp_op) inline const Scalar operator() (const Scalar& a) const { return ei_exp(a); } typedef typename ei_packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return ei_pexp(a); } @@ -319,7 +334,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, Cwise::log() */ -template struct ei_scalar_log_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_log_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_log_op) inline const Scalar operator() (const Scalar& a) const { return ei_log(a); } typedef typename ei_packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return ei_plog(a); } @@ -428,7 +444,8 @@ template struct ei_functor_traits > { enum { Cost = 1, PacketAccess = ei_packet_traits::size>1, IsRepeatable = true }; }; -template struct ei_scalar_identity_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_identity_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_identity_op) EIGEN_STRONG_INLINE ei_scalar_identity_op(void) {} EIGEN_STRONG_INLINE const Scalar operator() (int row, int col) const { return row==col ? Scalar(1) : Scalar(0); } }; diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index 622c84a8e..2a9feaeeb 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -28,16 +28,11 @@ // just a workaround because GCC seems to not really like empty structs #ifdef __GNUG__ - struct ei_empty_struct - { - EIGEN_ALWAYS_INLINE_ATTRIB ei_empty_struct() {} - EIGEN_ALWAYS_INLINE_ATTRIB ei_empty_struct(const ei_empty_struct&) {} - EIGEN_ALWAYS_INLINE_ATTRIB ei_empty_struct& operator=(const ei_empty_struct&) { return *this; } - char _ei_dummy_; - }; - #define EIGEN_EMPTY_STRUCT : Eigen::ei_empty_struct + #define EIGEN_EMPTY_STRUCT_CTOR(X) \ + EIGEN_STRONG_INLINE X() {} \ + EIGEN_STRONG_INLINE X(const X&) {} #else - #define EIGEN_EMPTY_STRUCT + #define EIGEN_EMPTY_STRUCT_CTOR(X) #endif //classes inheriting ei_no_assignment_operator don't generate a default operator=. @@ -51,10 +46,10 @@ class ei_no_assignment_operator * can be accessed using value() and setValue(). * Otherwise, this class is an empty structure and value() just returns the template parameter Value. */ -template class ei_int_if_dynamic EIGEN_EMPTY_STRUCT +template class ei_int_if_dynamic { public: - ei_int_if_dynamic() {} + EIGEN_EMPTY_STRUCT_CTOR(ei_int_if_dynamic) explicit ei_int_if_dynamic(int) {} static int value() { return Value; } void setValue(int) {} -- cgit v1.2.3 From f8cb9a6230d21d9b9fa618f3d5ebc4ecb6ab6de1 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Sat, 19 Dec 2009 13:45:14 +0100 Subject: oops, remove duplicated ctor --- Eigen/src/Core/Functors.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h index 1a4edfc4a..aa3eba5cc 100644 --- a/Eigen/src/Core/Functors.h +++ b/Eigen/src/Core/Functors.h @@ -446,7 +446,6 @@ struct ei_functor_traits > template struct ei_scalar_identity_op { EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_identity_op) - EIGEN_STRONG_INLINE ei_scalar_identity_op(void) {} EIGEN_STRONG_INLINE const Scalar operator() (int row, int col) const { return row==col ? Scalar(1) : Scalar(0); } }; template -- cgit v1.2.3 From 02beaea2f8accd3bfb7975e5c9e78c033fd1cb94 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Sat, 19 Dec 2009 13:49:00 +0100 Subject: add missing inclusion of LU/arch, thanks to J.B. Rouault --- Eigen/src/LU/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Eigen/src/LU/CMakeLists.txt b/Eigen/src/LU/CMakeLists.txt index 2788595b0..e0d8d78c1 100644 --- a/Eigen/src/LU/CMakeLists.txt +++ b/Eigen/src/LU/CMakeLists.txt @@ -4,3 +4,5 @@ INSTALL(FILES ${Eigen_LU_SRCS} DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/LU COMPONENT Devel ) + +ADD_SUBDIRECTORY(arch) -- cgit v1.2.3 From 32f6242b601b7554c8c5d4510b8d769777744006 Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Mon, 21 Dec 2009 11:35:08 +0000 Subject: Set default for second argument for check script. Otherwise, buildtests will be run with a second argument of "" if check is called with only one argument, which leads to infinitely many jobs. --- scripts/check.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/check.in b/scripts/check.in index ff3c96441..82d805b79 100755 --- a/scripts/check.in +++ b/scripts/check.in @@ -1,5 +1,5 @@ #!/bin/bash -# mctestr : shorthand for make and ctest -R +# check : shorthand for make and ctest -R if [ $# == 0 -o $# -ge 3 ] then @@ -9,4 +9,4 @@ then fi # TODO when ctest 2.8 comes out, honor the jobs parameter -./buildtests "$1" "$2" && ctest -R "$1" +./buildtests "$1" "${2:-1}" && ctest -R "$1" -- cgit v1.2.3 From 9f1fa6ea5e3664b7c31eb8250561289c891a749e Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Mon, 21 Dec 2009 18:16:01 +0000 Subject: Fix compilation error in doc/examples/class_CwiseBinaryOp.cpp . This is a follow-up of 9d5478303667bd97f3e20696f8a8c82cb5b2d65f (better work around for empty structs). --- doc/examples/class_CwiseBinaryOp.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/examples/class_CwiseBinaryOp.cpp b/doc/examples/class_CwiseBinaryOp.cpp index fb9b2ff09..7ca5bf6ef 100644 --- a/doc/examples/class_CwiseBinaryOp.cpp +++ b/doc/examples/class_CwiseBinaryOp.cpp @@ -4,7 +4,8 @@ USING_PART_OF_NAMESPACE_EIGEN using namespace std; // define a custom template binary functor -template struct MakeComplexOp EIGEN_EMPTY_STRUCT { +template struct MakeComplexOp { + EIGEN_EMPTY_STRUCT_CTOR(MakeComplexOp) typedef complex result_type; complex operator()(const Scalar& a, const Scalar& b) const { return complex(a,b); } }; -- cgit v1.2.3 From 4ec99bbc0c3756520fb6e53ffdc0f63a739dd87a Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 21 Dec 2009 13:49:43 -0500 Subject: support gcc 4.5 --- Eigen/src/Core/Product.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index d24ef6159..7066e5743 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -58,10 +58,12 @@ enum { OuterProduct, InnerProduct, UnrolledProduct, GemvProduct, GemmProduct }; template struct ei_product_type { + typedef typename ei_cleantype::type _Lhs; + typedef typename ei_cleantype::type _Rhs; enum { - Rows = Lhs::RowsAtCompileTime, - Cols = Rhs::ColsAtCompileTime, - Depth = EIGEN_ENUM_MIN(Lhs::ColsAtCompileTime,Rhs::RowsAtCompileTime) + Rows = _Lhs::RowsAtCompileTime, + Cols = _Rhs::ColsAtCompileTime, + Depth = EIGEN_ENUM_MIN(_Lhs::ColsAtCompileTime,_Rhs::RowsAtCompileTime) }; // the splitting into different lines of code here, introducing the _select enums and the typedef below, -- cgit v1.2.3 From f54a2a0484149c3d8fc09ad613478e0c154d034f Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Mon, 21 Dec 2009 18:53:00 +0000 Subject: Add support for general matrix functions. This does the job but it is only a first version. Further plans: improved docs, more tests, improve code by refactoring, add convenience functions for sine, cosine, sinh, cosh, and (eventually) add the matrix logarithm. --- unsupported/Eigen/MatrixFunctions | 9 +- .../Eigen/src/MatrixFunctions/MatrixExponential.h | 2 +- .../Eigen/src/MatrixFunctions/MatrixFunction.h | 475 +++++++++++++++++++++ unsupported/doc/examples/MatrixFunction.cpp | 23 + unsupported/test/matrixExponential.cpp | 49 ++- 5 files changed, 549 insertions(+), 9 deletions(-) create mode 100644 unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h create mode 100644 unsupported/doc/examples/MatrixFunction.cpp diff --git a/unsupported/Eigen/MatrixFunctions b/unsupported/Eigen/MatrixFunctions index 5614f915e..bf2223a6e 100644 --- a/unsupported/Eigen/MatrixFunctions +++ b/unsupported/Eigen/MatrixFunctions @@ -25,17 +25,21 @@ #ifndef EIGEN_MATRIX_FUNCTIONS #define EIGEN_MATRIX_FUNCTIONS +#include +#include +#include + #include #include #include +#include namespace Eigen { /** \ingroup Unsupported_modules * \defgroup MatrixFunctions_Module Matrix functions module * \brief This module aims to provide various methods for the computation of - * matrix functions. Currently, there is only support for the matrix - * exponential. + * matrix functions. * * \code * #include @@ -43,6 +47,7 @@ namespace Eigen { */ #include "src/MatrixFunctions/MatrixExponential.h" +#include "src/MatrixFunctions/MatrixFunction.h" } diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h index 9c0d2e53f..b45aeae58 100644 --- a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h +++ b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h @@ -72,7 +72,7 @@ * \end{array} \right]. \f] * This corresponds to a rotation of \f$ \frac14\pi \f$ radians around * the z-axis. - + * * \include MatrixExponential.cpp * Output: \verbinclude MatrixExponential.out * diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h b/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h new file mode 100644 index 000000000..7103ac541 --- /dev/null +++ b/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h @@ -0,0 +1,475 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Jitse Niesen +// +// 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_MATRIX_FUNCTION +#define EIGEN_MATRIX_FUNCTION + +template +struct ei_stem_function +{ + typedef std::complex::Real> ComplexScalar; + typedef ComplexScalar type(ComplexScalar, int); +}; + +/** \ingroup MatrixFunctions_Module + * + * \brief Compute a matrix function. + * + * \param[in] M argument of matrix function, should be a square matrix. + * \param[in] f an entire function; \c f(x,n) should compute the n-th derivative of f at x. + * \param[out] result pointer to the matrix in which to store the result, \f$ f(M) \f$. + * + * Suppose that \f$ f \f$ is an entire function (that is, a function + * on the complex plane that is everywhere complex differentiable). + * Then its Taylor series + * \f[ f(0) + f'(0) x + \frac{f''(0)}{2} x^2 + \frac{f'''(0)}{3!} x^3 + \cdots \f] + * converges to \f$ f(x) \f$. In this case, we can define the matrix + * function by the same series: + * \f[ f(M) = f(0) + f'(0) M + \frac{f''(0)}{2} M^2 + \frac{f'''(0)}{3!} M^3 + \cdots \f] + * + * This routine uses the algorithm described in: + * Philip Davies and Nicholas J. Higham, + * "A Schur-Parlett algorithm for computing matrix functions", + * SIAM J. %Matrix Anal. Applic., 25:464–485, 2003. + * + * Example: The following program checks that + * \f[ \exp \left[ \begin{array}{ccc} + * 0 & \frac14\pi & 0 \\ + * -\frac14\pi & 0 & 0 \\ + * 0 & 0 & 0 + * \end{array} \right] = \left[ \begin{array}{ccc} + * \frac12\sqrt2 & -\frac12\sqrt2 & 0 \\ + * \frac12\sqrt2 & \frac12\sqrt2 & 0 \\ + * 0 & 0 & 1 + * \end{array} \right]. \f] + * This corresponds to a rotation of \f$ \frac14\pi \f$ radians around + * the z-axis. This is the same example as used in the documentation + * of ei_matrix_exponential(). + * + * Note that the function \c expfn is defined for complex numbers \c x, + * even though the matrix \c A is over the reals. + * + * \include MatrixFunction.cpp + * Output: \verbinclude MatrixFunction.out + */ +template +EIGEN_STRONG_INLINE void ei_matrix_function(const MatrixBase& M, + typename ei_stem_function::Scalar>::type f, + typename MatrixBase::PlainMatrixType* result); + + +/** \ingroup MatrixFunctions_Module + * \class MatrixFunction + * \brief Helper class for computing matrix functions. + */ +template ::Scalar>::IsComplex, + int IsDynamic = ( (ei_traits::RowsAtCompileTime == Dynamic) + && (ei_traits::RowsAtCompileTime == Dynamic) ) > +class MatrixFunction; + +/* Partial specialization of MatrixFunction for real matrices */ + +template +class MatrixFunction, 0, IsDynamic> +{ + public: + + typedef std::complex ComplexScalar; + typedef Matrix MatrixType; + typedef Matrix ComplexMatrix; + typedef typename ei_stem_function::type StemFunction; + + MatrixFunction(const MatrixType& A, StemFunction f, MatrixType* result) + { + ComplexMatrix CA = A.template cast(); + ComplexMatrix Cresult; + MatrixFunction(CA, f, &Cresult); + result->resize(A.cols(), A.rows()); + for (int j = 0; j < A.cols(); j++) + for (int i = 0; i < A.rows(); i++) + (*result)(i,j) = std::real(Cresult(i,j)); + } +}; + +/* Partial specialization of MatrixFunction for complex static-size matrices */ + +template +class MatrixFunction, 1, 0> +{ + public: + + typedef Matrix MatrixType; + typedef Matrix DynamicMatrix; + typedef typename ei_stem_function::type StemFunction; + + MatrixFunction(const MatrixType& A, StemFunction f, MatrixType* result) + { + DynamicMatrix DA = A; + DynamicMatrix Dresult; + MatrixFunction(DA, f, &Dresult); + *result = Dresult; + } +}; + +/* Partial specialization of MatrixFunction for complex dynamic-size matrices */ + +template +class MatrixFunction +{ + public: + + typedef ei_traits Traits; + typedef typename Traits::Scalar Scalar; + typedef typename NumTraits::Real RealScalar; + typedef typename ei_stem_function::type StemFunction; + typedef Matrix VectorType; + typedef Matrix IntVectorType; + typedef std::list listOfScalars; + typedef std::list listOfLists; + + /** \brief Compute matrix function. + * + * \param A argument of matrix function. + * \param f function to compute. + * \param result pointer to the matrix in which to store the result. + */ + MatrixFunction(const MatrixType& A, StemFunction f, MatrixType* result); + + private: + + // Prevent copying + MatrixFunction(const MatrixFunction&); + MatrixFunction& operator=(const MatrixFunction&); + + void separateBlocksInSchur(MatrixType& T, MatrixType& U, IntVectorType& blockSize); + void permuteSchur(const IntVectorType& permutation, MatrixType& T, MatrixType& U); + void swapEntriesInSchur(int index, MatrixType& T, MatrixType& U); + void computeTriangular(const MatrixType& T, MatrixType& result, const IntVectorType& blockSize); + void computeBlockAtomic(const MatrixType& T, MatrixType& result, const IntVectorType& blockSize); + MatrixType solveSylvester(const MatrixType& A, const MatrixType& B, const MatrixType& C); + MatrixType computeAtomic(const MatrixType& T); + void divideInBlocks(const VectorType& v, listOfLists* result); + void constructPermutation(const VectorType& diag, const listOfLists& blocks, + IntVectorType& blockSize, IntVectorType& permutation); + + RealScalar computeMu(const MatrixType& M); + bool taylorConverged(const MatrixType& T, int s, const MatrixType& F, + const MatrixType& Fincr, const MatrixType& P, RealScalar mu); + + static const RealScalar separation() { return static_cast(0.01); } + StemFunction *m_f; +}; + +template +MatrixFunction::MatrixFunction(const MatrixType& A, StemFunction f, MatrixType* result) : + m_f(f) +{ + if (A.rows() == 1) { + result->resize(1,1); + (*result)(0,0) = f(A(0,0), 0); + } else { + const ComplexSchur schurOfA(A); + MatrixType T = schurOfA.matrixT(); + MatrixType U = schurOfA.matrixU(); + IntVectorType blockSize, permutation; + separateBlocksInSchur(T, U, blockSize); + MatrixType fT; + computeTriangular(T, fT, blockSize); + *result = U * fT * U.adjoint(); + } +} + +template +void MatrixFunction::separateBlocksInSchur(MatrixType& T, MatrixType& U, IntVectorType& blockSize) +{ + const VectorType d = T.diagonal(); + listOfLists blocks; + divideInBlocks(d, &blocks); + + IntVectorType permutation; + constructPermutation(d, blocks, blockSize, permutation); + permuteSchur(permutation, T, U); +} + +template +void MatrixFunction::permuteSchur(const IntVectorType& permutation, MatrixType& T, MatrixType& U) +{ + IntVectorType p = permutation; + for (int i = 0; i < p.rows() - 1; i++) { + int j; + for (j = i; j < p.rows(); j++) { + if (p(j) == i) break; + } + ei_assert(p(j) == i); + for (int k = j-1; k >= i; k--) { + swapEntriesInSchur(k, T, U); + std::swap(p.coeffRef(k), p.coeffRef(k+1)); + } + } +} + +// swap T(index, index) and T(index+1, index+1) +template +void MatrixFunction::swapEntriesInSchur(int index, MatrixType& T, MatrixType& U) +{ + PlanarRotation rotation; + rotation.makeGivens(T(index, index+1), T(index+1, index+1) - T(index, index)); + T.applyOnTheLeft(index, index+1, rotation.adjoint()); + T.applyOnTheRight(index, index+1, rotation); + U.applyOnTheRight(index, index+1, rotation); +} + +template +void MatrixFunction::computeTriangular(const MatrixType& T, MatrixType& result, + const IntVectorType& blockSize) +{ + MatrixType expT; + ei_matrix_exponential(T, &expT); + computeBlockAtomic(T, result, blockSize); + IntVectorType blockStart(blockSize.rows()); + blockStart(0) = 0; + for (int i = 1; i < blockSize.rows(); i++) { + blockStart(i) = blockStart(i-1) + blockSize(i-1); + } + for (int diagIndex = 1; diagIndex < blockSize.rows(); diagIndex++) { + for (int blockIndex = 0; blockIndex < blockSize.rows() - diagIndex; blockIndex++) { + // compute (blockIndex, blockIndex+diagIndex) block + MatrixType A = T.block(blockStart(blockIndex), blockStart(blockIndex), blockSize(blockIndex), blockSize(blockIndex)); + MatrixType B = -T.block(blockStart(blockIndex+diagIndex), blockStart(blockIndex+diagIndex), blockSize(blockIndex+diagIndex), blockSize(blockIndex+diagIndex)); + MatrixType C = result.block(blockStart(blockIndex), blockStart(blockIndex), blockSize(blockIndex), blockSize(blockIndex)) * T.block(blockStart(blockIndex), blockStart(blockIndex+diagIndex), blockSize(blockIndex), blockSize(blockIndex+diagIndex)); + C -= T.block(blockStart(blockIndex), blockStart(blockIndex+diagIndex), blockSize(blockIndex), blockSize(blockIndex+diagIndex)) * result.block(blockStart(blockIndex+diagIndex), blockStart(blockIndex+diagIndex), blockSize(blockIndex+diagIndex), blockSize(blockIndex+diagIndex)); + for (int k = blockIndex + 1; k < blockIndex + diagIndex; k++) { + C += result.block(blockStart(blockIndex), blockStart(k), blockSize(blockIndex), blockSize(k)) * T.block(blockStart(k), blockStart(blockIndex+diagIndex), blockSize(k), blockSize(blockIndex+diagIndex)); + C -= T.block(blockStart(blockIndex), blockStart(k), blockSize(blockIndex), blockSize(k)) * result.block(blockStart(k), blockStart(blockIndex+diagIndex), blockSize(k), blockSize(blockIndex+diagIndex)); + } + result.block(blockStart(blockIndex), blockStart(blockIndex+diagIndex), blockSize(blockIndex), blockSize(blockIndex+diagIndex)) = solveSylvester(A, B, C); + } + } +} + +// solve AX + XB = C <=> U* A' U X V V* + U* U X V B' V* = U* U C V V* <=> A' U X V + U X V B' = U C V +// Schur: A* = U A'* U* (so A = U* A' U), B = V B' V*, define: X' = U X V, C' = U C V, to get: A' X' + X' B' = C' +// A is m-by-m, B is n-by-n, X is m-by-n, C is m-by-n, U is m-by-m, V is n-by-n +template +MatrixType MatrixFunction::solveSylvester(const MatrixType& A, const MatrixType& B, const MatrixType& C) +{ + MatrixType U = MatrixType::Zero(A.rows(), A.rows()); + for (int i = 0; i < A.rows(); i++) { + U(i, A.rows() - 1 - i) = static_cast(1); + } + MatrixType Aprime = U * A * U; + + MatrixType Bprime = B; + MatrixType V = MatrixType::Identity(B.rows(), B.rows()); + + MatrixType Cprime = U * C * V; + MatrixType Xprime(A.rows(), B.rows()); + for (int l = 0; l < B.rows(); l++) { + for (int k = 0; k < A.rows(); k++) { + Scalar tmp1, tmp2; + if (k == 0) { + tmp1 = 0; + } else { + Matrix tmp1matrix = Aprime.row(k).start(k) * Xprime.col(l).start(k); + tmp1 = tmp1matrix(0,0); + } + if (l == 0) { + tmp2 = 0; + } else { + Matrix tmp2matrix = Xprime.row(k).start(l) * Bprime.col(l).start(l); + tmp2 = tmp2matrix(0,0); + } + Xprime(k,l) = (Cprime(k,l) - tmp1 - tmp2) / (Aprime(k,k) + Bprime(l,l)); + } + } + return U.adjoint() * Xprime * V.adjoint(); +} + + +// does not touch irrelevant parts of T +template +void MatrixFunction::computeBlockAtomic(const MatrixType& T, MatrixType& result, + const IntVectorType& blockSize) +{ + int blockStart = 0; + result.resize(T.rows(), T.cols()); + result.setZero(); + for (int i = 0; i < blockSize.rows(); i++) { + result.block(blockStart, blockStart, blockSize(i), blockSize(i)) + = computeAtomic(T.block(blockStart, blockStart, blockSize(i), blockSize(i))); + blockStart += blockSize(i); + } +} + +template +typename std::list >::iterator ei_find_in_list_of_lists(typename std::list >& ll, Scalar x) +{ + typename std::list::iterator j; + for (typename std::list >::iterator i = ll.begin(); i != ll.end(); i++) { + j = std::find(i->begin(), i->end(), x); + if (j != i->end()) + return i; + } + return ll.end(); +} + +// Alg 4.1 +template +void MatrixFunction::divideInBlocks(const VectorType& v, listOfLists* result) +{ + const int n = v.rows(); + for (int i=0; iend()) { + listOfScalars l; + l.push_back(v(i)); + result->push_back(l); + qi = result->end(); + qi--; + } + // Look for other element to add to the set + for (int j=i+1; jbegin(), qi->end(), v(j)) == qi->end()) { + typename listOfLists::iterator qj = ei_find_in_list_of_lists(*result, v(j)); + if (qj == result->end()) { + qi->push_back(v(j)); + } else { + qi->insert(qi->end(), qj->begin(), qj->end()); + result->erase(qj); + } + } + } + } +} + +// Construct permutation P, such that P(D) has eigenvalues clustered together +template +void MatrixFunction::constructPermutation(const VectorType& diag, const listOfLists& blocks, + IntVectorType& blockSize, IntVectorType& permutation) +{ + const int n = diag.rows(); + const int numBlocks = blocks.size(); + + // For every block in blocks, mark and count the entries in diag that + // appear in that block + blockSize.setZero(numBlocks); + IntVectorType entryToBlock(n); + int blockIndex = 0; + for (typename listOfLists::const_iterator block = blocks.begin(); block != blocks.end(); block++) { + for (int i = 0; i < diag.rows(); i++) { + if (std::find(block->begin(), block->end(), diag(i)) != block->end()) { + blockSize[blockIndex]++; + entryToBlock[i] = blockIndex; + } + } + blockIndex++; + } + + // Compute index of first entry in every block as the sum of sizes + // of all the preceding blocks + IntVectorType indexNextEntry(numBlocks); + indexNextEntry[0] = 0; + for (blockIndex = 1; blockIndex < numBlocks; blockIndex++) { + indexNextEntry[blockIndex] = indexNextEntry[blockIndex-1] + blockSize[blockIndex-1]; + } + + // Construct permutation + permutation.resize(n); + for (int i = 0; i < n; i++) { + int block = entryToBlock[i]; + permutation[i] = indexNextEntry[block]; + indexNextEntry[block]++; + } +} + +template +MatrixType MatrixFunction::computeAtomic(const MatrixType& T) +{ + // TODO: Use that T is upper triangular + const int n = T.rows(); + const Scalar sigma = T.trace() / Scalar(n); + const MatrixType M = T - sigma * MatrixType::Identity(n, n); + const RealScalar mu = computeMu(M); + MatrixType F = m_f(sigma, 0) * MatrixType::Identity(n, n); + MatrixType P = M; + MatrixType Fincr; + for (int s = 1; s < 1.1*n + 10; s++) { // upper limit is fairly arbitrary + Fincr = m_f(sigma, s) * P; + F += Fincr; + P = (1/(s + 1.0)) * P * M; + if (taylorConverged(T, s, F, Fincr, P, mu)) { + return F; + } + } + ei_assert("Taylor series does not converge" && 0); + return F; +} + +template +typename MatrixFunction::RealScalar MatrixFunction::computeMu(const MatrixType& M) +{ + const int n = M.rows(); + const MatrixType N = MatrixType::Identity(n, n) - M; + VectorType e = VectorType::Ones(n); + N.template triangularView().solveInPlace(e); + return e.cwise().abs().maxCoeff(); +} + +template +bool MatrixFunction::taylorConverged(const MatrixType& T, int s, const MatrixType& F, + const MatrixType& Fincr, const MatrixType& P, RealScalar mu) +{ + const int n = F.rows(); + const RealScalar F_norm = F.cwise().abs().rowwise().sum().maxCoeff(); + const RealScalar Fincr_norm = Fincr.cwise().abs().rowwise().sum().maxCoeff(); + if (Fincr_norm < epsilon() * F_norm) { + RealScalar delta = 0; + RealScalar rfactorial = 1; + for (int r = 0; r < n; r++) { + RealScalar mx = 0; + for (int i = 0; i < n; i++) + mx = std::max(mx, std::abs(m_f(T(i, i), s+r))); + if (r != 0) + rfactorial *= r; + delta = std::max(delta, mx / rfactorial); + } + const RealScalar P_norm = P.cwise().abs().rowwise().sum().maxCoeff(); + if (mu * delta * P_norm < epsilon() * F_norm) + return true; + } + return false; +} + +template +EIGEN_STRONG_INLINE void ei_matrix_function(const MatrixBase& M, + typename ei_stem_function::Scalar>::type f, + typename MatrixBase::PlainMatrixType* result) +{ + ei_assert(M.rows() == M.cols()); + MatrixFunction::PlainMatrixType>(M, f, result); +} + +#endif // EIGEN_MATRIX_FUNCTION diff --git a/unsupported/doc/examples/MatrixFunction.cpp b/unsupported/doc/examples/MatrixFunction.cpp new file mode 100644 index 000000000..c11cb821b --- /dev/null +++ b/unsupported/doc/examples/MatrixFunction.cpp @@ -0,0 +1,23 @@ +#include + +using namespace Eigen; + +std::complex expfn(std::complex x, int) +{ + return std::exp(x); +} + +int main() +{ + const double pi = std::acos(-1.0); + + MatrixXd A(3,3); + A << 0, -pi/4, 0, + pi/4, 0, 0, + 0, 0, 0; + std::cout << "The matrix A is:\n" << A << "\n\n"; + + MatrixXd B; + ei_matrix_function(A, expfn, &B); + std::cout << "The matrix exponential of A is:\n" << B << "\n\n"; +} diff --git a/unsupported/test/matrixExponential.cpp b/unsupported/test/matrixExponential.cpp index 828504547..9e4d8e611 100644 --- a/unsupported/test/matrixExponential.cpp +++ b/unsupported/test/matrixExponential.cpp @@ -33,6 +33,18 @@ double binom(int n, int k) return res; } +template +double relerr(const MatrixBase& A, const MatrixBase& B) +{ + return std::sqrt((A - B).cwise().abs2().sum() / std::min(A.cwise().abs2().sum(), B.cwise().abs2().sum())); +} + +template +T expfn(T x, int) +{ + return std::exp(x); +} + template void test2dRotation(double tol) { @@ -44,7 +56,13 @@ void test2dRotation(double tol) { angle = static_cast(pow(10, i / 5. - 2)); B << cos(angle), sin(angle), -sin(angle), cos(angle); + + ei_matrix_function(angle*A, expfn, &C); + std::cout << "test2dRotation: i = " << i << " error funm = " << relerr(C, B); + VERIFY(C.isApprox(B, static_cast(tol))); + ei_matrix_exponential(angle*A, &C); + std::cout << " error expm = " << relerr(C, B) << "\n"; VERIFY(C.isApprox(B, static_cast(tol))); } } @@ -63,7 +81,13 @@ void test2dHyperbolicRotation(double tol) sh = std::sinh(angle); A << 0, angle*imagUnit, -angle*imagUnit, 0; B << ch, sh*imagUnit, -sh*imagUnit, ch; + + ei_matrix_function(A, expfn, &C); + std::cout << "test2dHyperbolicRotation: i = " << i << " error funm = " << relerr(C, B); + VERIFY(C.isApprox(B, static_cast(tol))); + ei_matrix_exponential(A, &C); + std::cout << " error expm = " << relerr(C, B) << "\n"; VERIFY(C.isApprox(B, static_cast(tol))); } } @@ -81,7 +105,13 @@ void testPascal(double tol) for (int i=0; i(binom(i,j)); + + ei_matrix_function(A, expfn, &C); + std::cout << "testPascal: size = " << size << " error funm = " << relerr(C, B); + VERIFY(C.isApprox(B, static_cast(tol))); + ei_matrix_exponential(A, &C); + std::cout << " error expm = " << relerr(C, B) << "\n"; VERIFY(C.isApprox(B, static_cast(tol))); } } @@ -101,26 +131,33 @@ void randomTest(const MatrixType& m, double tol) for(int i = 0; i < g_repeat; i++) { m1 = MatrixType::Random(rows, cols); + + ei_matrix_function(m1, expfn, &m2); + ei_matrix_function(-m1, expfn, &m3); + std::cout << "randomTest: error funm = " << relerr(identity, m2 * m3); + VERIFY(identity.isApprox(m2 * m3, static_cast(tol))); + ei_matrix_exponential(m1, &m2); ei_matrix_exponential(-m1, &m3); - VERIFY(identity.isApprox(m2 * m3, static_cast(tol))); + std::cout << " error expm = " << relerr(identity, m2 * m3) << "\n"; + VERIFY(identity.isApprox(m2 * m3, static_cast(tol))); } } void test_matrixExponential() { - CALL_SUBTEST_2(test2dRotation(1e-14)); + CALL_SUBTEST_2(test2dRotation(1e-13)); CALL_SUBTEST_1(test2dRotation(1e-5)); CALL_SUBTEST_2(test2dHyperbolicRotation(1e-14)); CALL_SUBTEST_1(test2dHyperbolicRotation(1e-5)); - CALL_SUBTEST_1(testPascal(1e-5)); - CALL_SUBTEST_2(testPascal(1e-14)); + CALL_SUBTEST_6(testPascal(1e-6)); + CALL_SUBTEST_5(testPascal(1e-15)); CALL_SUBTEST_2(randomTest(Matrix2d(), 1e-13)); - CALL_SUBTEST_2(randomTest(Matrix(), 1e-13)); + CALL_SUBTEST_7(randomTest(Matrix(), 1e-13)); CALL_SUBTEST_3(randomTest(Matrix4cd(), 1e-13)); CALL_SUBTEST_4(randomTest(MatrixXd(8,8), 1e-13)); CALL_SUBTEST_1(randomTest(Matrix2f(), 1e-4)); - CALL_SUBTEST_5(randomTest(Matrix3cf(), 1e-4)); + CALL_SUBTEST_5(randomTest(Matrix3cf(), 1e-4)); CALL_SUBTEST_1(randomTest(Matrix4f(), 1e-4)); CALL_SUBTEST_6(randomTest(MatrixXf(8,8), 1e-4)); } -- cgit v1.2.3