From bb5315c1aeaae55464446cffdfcd40ae0f7fce11 Mon Sep 17 00:00:00 2001 From: koldo Date: Fri, 12 Feb 2016 22:23:46 +0000 Subject: [PATCH] Eigen: Updated to version 3.2.7 git-svn-id: svn://ultimatepp.org/upp/trunk@9469 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/plugin/Eigen/Eigen.h | 1 + uppsrc/plugin/Eigen/Eigen.upp | 2 + uppsrc/plugin/Eigen/Eigen/SparseCore | 2 +- uppsrc/plugin/Eigen/Eigen/src/Cholesky/LDLT.h | 2 +- uppsrc/plugin/Eigen/Eigen/src/Cholesky/LLT.h | 2 +- .../Eigen/src/CholmodSupport/CholmodSupport.h | 10 +- uppsrc/plugin/Eigen/Eigen/src/Core/Array.h | 15 ++ .../plugin/Eigen/Eigen/src/Core/ArrayBase.h | 4 +- uppsrc/plugin/Eigen/Eigen/src/Core/Assign.h | 2 +- .../Eigen/Eigen/src/Core/CwiseBinaryOp.h | 3 +- .../Eigen/Eigen/src/Core/CwiseUnaryOp.h | 2 +- .../plugin/Eigen/Eigen/src/Core/DenseBase.h | 14 +- .../Eigen/Eigen/src/Core/DenseStorage.h | 255 ++++++++++++------ .../Eigen/Eigen/src/Core/DiagonalProduct.h | 3 +- .../Eigen/Eigen/src/Core/GeneralProduct.h | 10 +- uppsrc/plugin/Eigen/Eigen/src/Core/MapBase.h | 2 +- .../Eigen/Eigen/src/Core/MathFunctions.h | 2 +- uppsrc/plugin/Eigen/Eigen/src/Core/Matrix.h | 15 ++ .../plugin/Eigen/Eigen/src/Core/MatrixBase.h | 9 + .../Eigen/Eigen/src/Core/PlainObjectBase.h | 30 +++ uppsrc/plugin/Eigen/Eigen/src/Core/Redux.h | 5 +- uppsrc/plugin/Eigen/Eigen/src/Core/Ref.h | 9 + .../Eigen/Eigen/src/Core/SelfCwiseBinaryOp.h | 10 +- .../Eigen/src/Core/arch/NEON/PacketMath.h | 1 + .../Eigen/src/Core/arch/SSE/MathFunctions.h | 8 +- .../products/TriangularMatrixMatrix_MKL.h | 4 +- .../Core/products/TriangularSolverMatrix.h | 9 +- .../Eigen/src/Core/util/ForwardDeclarations.h | 3 + .../Eigen/Eigen/src/Core/util/MKL_support.h | 32 +++ .../plugin/Eigen/Eigen/src/Core/util/Macros.h | 20 +- .../Eigen/Eigen/src/Core/util/XprHelper.h | 8 +- .../src/Eigenvalues/SelfAdjointEigenSolver.h | 23 +- .../Eigen/Eigen/src/Geometry/AlignedBox.h | 2 +- .../Eigen/Eigen/src/Geometry/AngleAxis.h | 6 +- .../Eigen/Eigen/src/Geometry/Quaternion.h | 4 +- .../BasicPreconditioners.h | 4 +- .../src/IterativeLinearSolvers/BiCGSTAB.h | 3 +- .../ConjugateGradient.h | 3 +- .../IterativeLinearSolvers/IncompleteLUT.h | 21 +- .../IterativeSolverBase.h | 48 +++- .../Eigen/Eigen/src/OrderingMethods/Amd.h | 5 +- .../src/SPQRSupport/SuiteSparseQRSupport.h | 4 +- .../src/SparseCore/SparseCwiseBinaryOp.h | 4 +- .../Eigen/Eigen/src/SparseCore/SparseMatrix.h | 5 +- .../Eigen/src/SparseCore/SparseMatrixBase.h | 35 ++- .../Eigen/Eigen/src/SparseCore/SparseUtil.h | 1 - .../Eigen/Eigen/src/SparseCore/SparseVector.h | 1 + .../Eigen/Eigen/src/SparseLU/SparseLU.h | 4 +- .../Eigen/Eigen/src/SparseLU/SparseLUImpl.h | 2 + .../Eigen/src/SparseLU/SparseLU_Memory.h | 4 +- .../src/SparseLU/SparseLU_SupernodalMatrix.h | 8 +- .../Eigen/src/SparseLU/SparseLU_column_bmod.h | 4 +- .../Eigen/src/SparseLU/SparseLU_kernel_bmod.h | 4 +- .../Eigen/src/SparseLU/SparseLU_panel_bmod.h | 8 +- .../Eigen/src/SparseLU/SparseLU_pivotL.h | 7 +- uppsrc/plugin/Eigen/ToStringPlugin.h | 2 +- .../plugin/Eigen/srcdoc.tpp/Eigen$en-us.tpp | 23 +- .../Eigen/src/AutoDiff/AutoDiffScalar.h | 2 +- .../unsupported/Eigen/src/CMakeLists.txt | 1 + .../Eigen/src/Eigenvalues/CMakeLists.txt | 6 + .../Eigen/src/IterativeSolvers/DGMRES.h | 4 +- .../Eigen/src/IterativeSolvers/GMRES.h | 3 +- .../Eigen/src/IterativeSolvers/MINRES.h | 3 +- 63 files changed, 526 insertions(+), 222 deletions(-) create mode 100644 uppsrc/plugin/Eigen/unsupported/Eigen/src/Eigenvalues/CMakeLists.txt diff --git a/uppsrc/plugin/Eigen/Eigen.h b/uppsrc/plugin/Eigen/Eigen.h index 9afee661c..7acec6dbf 100644 --- a/uppsrc/plugin/Eigen/Eigen.h +++ b/uppsrc/plugin/Eigen/Eigen.h @@ -22,6 +22,7 @@ //#undef Success #include "Eigen/Eigen" #include +#include NAMESPACE_UPP diff --git a/uppsrc/plugin/Eigen/Eigen.upp b/uppsrc/plugin/Eigen/Eigen.upp index 3958cdbd7..bdd4d2cff 100644 --- a/uppsrc/plugin/Eigen/Eigen.upp +++ b/uppsrc/plugin/Eigen/Eigen.upp @@ -3,6 +3,8 @@ description "Template library for linear algebra\377"; uses Core; +options(MSC) /bigobj; + include ../Eigen; diff --git a/uppsrc/plugin/Eigen/Eigen/SparseCore b/uppsrc/plugin/Eigen/Eigen/SparseCore index 9b5be5e15..24bcf0156 100644 --- a/uppsrc/plugin/Eigen/Eigen/SparseCore +++ b/uppsrc/plugin/Eigen/Eigen/SparseCore @@ -14,7 +14,7 @@ /** * \defgroup SparseCore_Module SparseCore module * - * This module provides a sparse matrix representation, and basic associatd matrix manipulations + * This module provides a sparse matrix representation, and basic associated matrix manipulations * and operations. * * See the \ref TutorialSparse "Sparse tutorial" diff --git a/uppsrc/plugin/Eigen/Eigen/src/Cholesky/LDLT.h b/uppsrc/plugin/Eigen/Eigen/src/Cholesky/LDLT.h index e01ae8233..abd30bd91 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Cholesky/LDLT.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Cholesky/LDLT.h @@ -464,7 +464,7 @@ LDLT& LDLT::compute(const MatrixType& a) */ template template -LDLT& LDLT::rankUpdate(const MatrixBase& w, const typename NumTraits::Real& sigma) +LDLT& LDLT::rankUpdate(const MatrixBase& w, const typename LDLT::RealScalar& sigma) { const Index size = w.rows(); if (m_isInitialized) diff --git a/uppsrc/plugin/Eigen/Eigen/src/Cholesky/LLT.h b/uppsrc/plugin/Eigen/Eigen/src/Cholesky/LLT.h index 59723a63d..7c11a2dc2 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Cholesky/LLT.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Cholesky/LLT.h @@ -289,7 +289,7 @@ template struct llt_inplace return k; mat.coeffRef(k,k) = x = sqrt(x); if (k>0 && rs>0) A21.noalias() -= A20 * A10.adjoint(); - if (rs>0) A21 *= RealScalar(1)/x; + if (rs>0) A21 /= x; } return -1; } diff --git a/uppsrc/plugin/Eigen/Eigen/src/CholmodSupport/CholmodSupport.h b/uppsrc/plugin/Eigen/Eigen/src/CholmodSupport/CholmodSupport.h index c449960de..99dbe171c 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/CholmodSupport/CholmodSupport.h +++ b/uppsrc/plugin/Eigen/Eigen/src/CholmodSupport/CholmodSupport.h @@ -78,7 +78,7 @@ cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat) { res.itype = CHOLMOD_INT; } - else if (internal::is_same<_Index,UF_long>::value) + else if (internal::is_same<_Index,SuiteSparse_long>::value) { res.itype = CHOLMOD_LONG; } @@ -395,7 +395,7 @@ class CholmodSimplicialLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimpl CholmodSimplicialLLT(const MatrixType& matrix) : Base() { init(); - compute(matrix); + Base::compute(matrix); } ~CholmodSimplicialLLT() {} @@ -442,7 +442,7 @@ class CholmodSimplicialLDLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimp CholmodSimplicialLDLT(const MatrixType& matrix) : Base() { init(); - compute(matrix); + Base::compute(matrix); } ~CholmodSimplicialLDLT() {} @@ -487,7 +487,7 @@ class CholmodSupernodalLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSuper CholmodSupernodalLLT(const MatrixType& matrix) : Base() { init(); - compute(matrix); + Base::compute(matrix); } ~CholmodSupernodalLLT() {} @@ -534,7 +534,7 @@ class CholmodDecomposition : public CholmodBase<_MatrixType, _UpLo, CholmodDecom CholmodDecomposition(const MatrixType& matrix) : Base() { init(); - compute(matrix); + Base::compute(matrix); } ~CholmodDecomposition() {} diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/Array.h b/uppsrc/plugin/Eigen/Eigen/src/Core/Array.h index 0ab03eff0..0b9c38c82 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/Array.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/Array.h @@ -124,6 +124,21 @@ class Array } #endif +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + Array(Array&& other) + : Base(std::move(other)) + { + Base::_check_template_params(); + if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic) + Base::_set_noalias(other); + } + Array& operator=(Array&& other) + { + other.swap(*this); + return *this; + } +#endif + /** Constructs a vector or row-vector with given dimension. \only_for_vectors * * Note that this is only useful for dynamic-size vectors. For fixed-size vectors, diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/ArrayBase.h b/uppsrc/plugin/Eigen/Eigen/src/Core/ArrayBase.h index 38852600d..33ff55371 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/ArrayBase.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/ArrayBase.h @@ -46,9 +46,6 @@ template class ArrayBase typedef ArrayBase Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl; - using internal::special_scalar_op_base::Scalar, - typename NumTraits::Scalar>::Real>::operator*; - typedef typename internal::traits::StorageKind StorageKind; typedef typename internal::traits::Index Index; typedef typename internal::traits::Scalar Scalar; @@ -56,6 +53,7 @@ template class ArrayBase typedef typename NumTraits::Real RealScalar; typedef DenseBase Base; + using Base::operator*; using Base::RowsAtCompileTime; using Base::ColsAtCompileTime; using Base::SizeAtCompileTime; diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/Assign.h b/uppsrc/plugin/Eigen/Eigen/src/Core/Assign.h index bcfc261e5..f48173172 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/Assign.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/Assign.h @@ -449,7 +449,7 @@ struct assign_impl::JointAlignment }; const Scalar *dst_ptr = &dst.coeffRef(0,0); - if((!bool(dstIsAligned)) && (Index(dst_ptr) % sizeof(Scalar))>0) + if((!bool(dstIsAligned)) && (size_t(dst_ptr) % sizeof(Scalar))>0) { // the pointer is not aligend-on scalar, so alignment is not possible return assign_impl::run(dst, src); diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/CwiseBinaryOp.h b/uppsrc/plugin/Eigen/Eigen/src/Core/CwiseBinaryOp.h index 586f77aaf..519a866e6 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/CwiseBinaryOp.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/CwiseBinaryOp.h @@ -81,7 +81,8 @@ struct traits > ) ), Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit), - CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + functor_traits::Cost + Cost0 = EIGEN_ADD_COST(LhsCoeffReadCost,RhsCoeffReadCost), + CoeffReadCost = EIGEN_ADD_COST(Cost0,functor_traits::Cost) }; }; } // end namespace internal diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/CwiseUnaryOp.h b/uppsrc/plugin/Eigen/Eigen/src/Core/CwiseUnaryOp.h index f2de749f9..f7ee60e98 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/CwiseUnaryOp.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/CwiseUnaryOp.h @@ -47,7 +47,7 @@ struct traits > Flags = _XprTypeNested::Flags & ( HereditaryBits | LinearAccessBit | AlignedBit | (functor_traits::PacketAccess ? PacketAccessBit : 0)), - CoeffReadCost = _XprTypeNested::CoeffReadCost + functor_traits::Cost + CoeffReadCost = EIGEN_ADD_COST(_XprTypeNested::CoeffReadCost, functor_traits::Cost) }; }; } diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/DenseBase.h b/uppsrc/plugin/Eigen/Eigen/src/Core/DenseBase.h index 32f60d8dc..4b371b075 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/DenseBase.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/DenseBase.h @@ -40,15 +40,14 @@ static inline void check_DenseIndex_is_signed() { */ template class DenseBase #ifndef EIGEN_PARSED_BY_DOXYGEN - : public internal::special_scalar_op_base::Scalar, - typename NumTraits::Scalar>::Real> + : public internal::special_scalar_op_base::Scalar, + typename NumTraits::Scalar>::Real, + DenseCoeffsBase > #else : public DenseCoeffsBase #endif // not EIGEN_PARSED_BY_DOXYGEN { public: - using internal::special_scalar_op_base::Scalar, - typename NumTraits::Scalar>::Real>::operator*; class InnerIterator; @@ -63,8 +62,9 @@ template class DenseBase typedef typename internal::traits::Scalar Scalar; typedef typename internal::packet_traits::type PacketScalar; typedef typename NumTraits::Real RealScalar; + typedef internal::special_scalar_op_base > Base; - typedef DenseCoeffsBase Base; + using Base::operator*; using Base::derived; using Base::const_cast_derived; using Base::rows; @@ -183,10 +183,6 @@ template class DenseBase /** \returns the number of nonzero coefficients which is in practice the number * of stored coefficients. */ inline Index nonZeros() const { return size(); } - /** \returns true if either the number of rows or the number of columns is equal to 1. - * In other words, this function returns - * \code rows()==1 || cols()==1 \endcode - * \sa rows(), cols(), IsVectorAtCompileTime. */ /** \returns the outer size. * diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/DenseStorage.h b/uppsrc/plugin/Eigen/Eigen/src/Core/DenseStorage.h index a72738e55..568493cba 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/DenseStorage.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/DenseStorage.h @@ -122,33 +122,41 @@ template class DenseSt { internal::plain_array m_data; public: - inline DenseStorage() {} - inline DenseStorage(internal::constructor_without_unaligned_array_assert) + DenseStorage() {} + DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(internal::constructor_without_unaligned_array_assert()) {} - inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} - inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); } - static inline DenseIndex rows(void) {return _Rows;} - static inline DenseIndex cols(void) {return _Cols;} - inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} - inline void resize(DenseIndex,DenseIndex,DenseIndex) {} - inline const T *data() const { return m_data.array; } - inline T *data() { return m_data.array; } + DenseStorage(const DenseStorage& other) : m_data(other.m_data) {} + DenseStorage& operator=(const DenseStorage& other) + { + if (this != &other) m_data = other.m_data; + return *this; + } + DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); } + static DenseIndex rows(void) {return _Rows;} + static DenseIndex cols(void) {return _Cols;} + void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} + void resize(DenseIndex,DenseIndex,DenseIndex) {} + const T *data() const { return m_data.array; } + T *data() { return m_data.array; } }; // null matrix template class DenseStorage { public: - inline DenseStorage() {} - inline DenseStorage(internal::constructor_without_unaligned_array_assert) {} - inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} - inline void swap(DenseStorage& ) {} - static inline DenseIndex rows(void) {return _Rows;} - static inline DenseIndex cols(void) {return _Cols;} - inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} - inline void resize(DenseIndex,DenseIndex,DenseIndex) {} - inline const T *data() const { return 0; } - inline T *data() { return 0; } + DenseStorage() {} + DenseStorage(internal::constructor_without_unaligned_array_assert) {} + DenseStorage(const DenseStorage&) {} + DenseStorage& operator=(const DenseStorage&) { return *this; } + DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} + void swap(DenseStorage& ) {} + static DenseIndex rows(void) {return _Rows;} + static DenseIndex cols(void) {return _Cols;} + void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {} + void resize(DenseIndex,DenseIndex,DenseIndex) {} + const T *data() const { return 0; } + T *data() { return 0; } }; // more specializations for null matrices; these are necessary to resolve ambiguities @@ -168,18 +176,29 @@ template class DenseStorage class DenseStorage m_data; DenseIndex m_rows; public: - inline DenseStorage() : m_rows(0) {} - inline DenseStorage(internal::constructor_without_unaligned_array_assert) + DenseStorage() : m_rows(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {} - inline DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex) : m_rows(nbRows) {} - inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } - inline DenseIndex rows(void) const {return m_rows;} - inline DenseIndex cols(void) const {return _Cols;} - inline void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; } - inline void resize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; } - inline const T *data() const { return m_data.array; } - inline T *data() { return m_data.array; } + DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows) {} + DenseStorage& operator=(const DenseStorage& other) + { + if (this != &other) + { + m_data = other.m_data; + m_rows = other.m_rows; + } + return *this; + } + DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex) : m_rows(nbRows) {} + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } + DenseIndex rows(void) const {return m_rows;} + DenseIndex cols(void) const {return _Cols;} + void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; } + void resize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; } + const T *data() const { return m_data.array; } + T *data() { return m_data.array; } }; // dynamic-size matrix with fixed-size storage and fixed height @@ -207,17 +236,27 @@ template class DenseStorage m_data; DenseIndex m_cols; public: - inline DenseStorage() : m_cols(0) {} - inline DenseStorage(internal::constructor_without_unaligned_array_assert) + DenseStorage() : m_cols(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {} - inline DenseStorage(DenseIndex, DenseIndex, DenseIndex nbCols) : m_cols(nbCols) {} - inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } - inline DenseIndex rows(void) const {return _Rows;} - inline DenseIndex cols(void) const {return m_cols;} - inline void conservativeResize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; } - inline void resize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; } - inline const T *data() const { return m_data.array; } - inline T *data() { return m_data.array; } + DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_cols(other.m_cols) {} + DenseStorage& operator=(const DenseStorage& other) + { + if (this != &other) + { + m_data = other.m_data; + m_cols = other.m_cols; + } + return *this; + } + DenseStorage(DenseIndex, DenseIndex, DenseIndex nbCols) : m_cols(nbCols) {} + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } + DenseIndex rows(void) const {return _Rows;} + DenseIndex cols(void) const {return m_cols;} + void conservativeResize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; } + void resize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; } + const T *data() const { return m_data.array; } + T *data() { return m_data.array; } }; // purely dynamic matrix. @@ -227,18 +266,35 @@ template class DenseStorage(size)), m_rows(nbRows), m_cols(nbCols) { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } - inline ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, m_rows*m_cols); } - inline void swap(DenseStorage& other) +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + DenseStorage(DenseStorage&& other) + : m_data(std::move(other.m_data)) + , m_rows(std::move(other.m_rows)) + , m_cols(std::move(other.m_cols)) + { + other.m_data = nullptr; + } + DenseStorage& operator=(DenseStorage&& other) + { + using std::swap; + swap(m_data, other.m_data); + swap(m_rows, other.m_rows); + swap(m_cols, other.m_cols); + return *this; + } +#endif + ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, m_rows*m_cols); } + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); } - inline DenseIndex rows(void) const {return m_rows;} - inline DenseIndex cols(void) const {return m_cols;} - inline void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols) + DenseIndex rows(void) const {return m_rows;} + DenseIndex cols(void) const {return m_cols;} + void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols) { m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, m_rows*m_cols); m_rows = nbRows; @@ -258,8 +314,11 @@ template class DenseStorage class DenseStorage(size)), m_cols(nbCols) + DenseStorage() : m_data(0), m_cols(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {} + DenseStorage(DenseIndex size, DenseIndex, DenseIndex nbCols) : m_data(internal::conditional_aligned_new_auto(size)), m_cols(nbCols) { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } - inline ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, _Rows*m_cols); } - inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } - static inline DenseIndex rows(void) {return _Rows;} - inline DenseIndex cols(void) const {return m_cols;} - inline void conservativeResize(DenseIndex size, DenseIndex, DenseIndex nbCols) +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + DenseStorage(DenseStorage&& other) + : m_data(std::move(other.m_data)) + , m_cols(std::move(other.m_cols)) + { + other.m_data = nullptr; + } + DenseStorage& operator=(DenseStorage&& other) + { + using std::swap; + swap(m_data, other.m_data); + swap(m_cols, other.m_cols); + return *this; + } +#endif + ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, _Rows*m_cols); } + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } + static DenseIndex rows(void) {return _Rows;} + DenseIndex cols(void) const {return m_cols;} + void conservativeResize(DenseIndex size, DenseIndex, DenseIndex nbCols) { m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, _Rows*m_cols); m_cols = nbCols; @@ -294,8 +368,11 @@ template class DenseStorage class DenseStorage(size)), m_rows(nbRows) + DenseStorage() : m_data(0), m_rows(0) {} + DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {} + DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex) : m_data(internal::conditional_aligned_new_auto(size)), m_rows(nbRows) { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN } - inline ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, _Cols*m_rows); } - inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } - inline DenseIndex rows(void) const {return m_rows;} - static inline DenseIndex cols(void) {return _Cols;} - inline void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex) +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + DenseStorage(DenseStorage&& other) + : m_data(std::move(other.m_data)) + , m_rows(std::move(other.m_rows)) + { + other.m_data = nullptr; + } + DenseStorage& operator=(DenseStorage&& other) + { + using std::swap; + swap(m_data, other.m_data); + swap(m_rows, other.m_rows); + return *this; + } +#endif + ~DenseStorage() { internal::conditional_aligned_delete_auto(m_data, _Cols*m_rows); } + void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } + DenseIndex rows(void) const {return m_rows;} + static DenseIndex cols(void) {return _Cols;} + void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex) { m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, m_rows*_Cols); m_rows = nbRows; @@ -330,8 +422,11 @@ template class DenseStorage > _LinearAccessMask = (RowsAtCompileTime==1 || ColsAtCompileTime==1) ? LinearAccessBit : 0, Flags = ((HereditaryBits|_LinearAccessMask|AlignedBit) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0),//(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit), - CoeffReadCost = NumTraits::MulCost + MatrixType::CoeffReadCost + DiagonalType::DiagonalVectorType::CoeffReadCost + Cost0 = EIGEN_ADD_COST(NumTraits::MulCost, MatrixType::CoeffReadCost), + CoeffReadCost = EIGEN_ADD_COST(Cost0,DiagonalType::DiagonalVectorType::CoeffReadCost) }; }; } diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/GeneralProduct.h b/uppsrc/plugin/Eigen/Eigen/src/Core/GeneralProduct.h index 9e805a80f..0eae52990 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/GeneralProduct.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/GeneralProduct.h @@ -257,7 +257,7 @@ template class GeneralProduct : public ProductBase, Lhs, Rhs> { - template struct IsRowMajor : internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {}; + template struct is_row_major : internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {}; public: EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) @@ -281,22 +281,22 @@ class GeneralProduct template inline void evalTo(Dest& dest) const { - internal::outer_product_selector_run(*this, dest, set(), IsRowMajor()); + internal::outer_product_selector_run(*this, dest, set(), is_row_major()); } template inline void addTo(Dest& dest) const { - internal::outer_product_selector_run(*this, dest, add(), IsRowMajor()); + internal::outer_product_selector_run(*this, dest, add(), is_row_major()); } template inline void subTo(Dest& dest) const { - internal::outer_product_selector_run(*this, dest, sub(), IsRowMajor()); + internal::outer_product_selector_run(*this, dest, sub(), is_row_major()); } template void scaleAndAddTo(Dest& dest, const Scalar& alpha) const { - internal::outer_product_selector_run(*this, dest, adds(alpha), IsRowMajor()); + internal::outer_product_selector_run(*this, dest, adds(alpha), is_row_major()); } }; diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/MapBase.h b/uppsrc/plugin/Eigen/Eigen/src/Core/MapBase.h index 92e114129..a9828f7f4 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/MapBase.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/MapBase.h @@ -123,7 +123,7 @@ template class MapBase return internal::ploadt(m_data + index * innerStride()); } - inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) + explicit inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) { EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) checkSanity(); diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/MathFunctions.h b/uppsrc/plugin/Eigen/Eigen/src/Core/MathFunctions.h index 2bfc5ebd9..adf2f9c51 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/MathFunctions.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/MathFunctions.h @@ -294,7 +294,7 @@ struct hypot_impl RealScalar _x = abs(x); RealScalar _y = abs(y); RealScalar p = (max)(_x, _y); - if(p==RealScalar(0)) return 0; + if(p==RealScalar(0)) return RealScalar(0); RealScalar q = (min)(_x, _y); RealScalar qp = q/p; return p * sqrt(RealScalar(1) + qp*qp); diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/Matrix.h b/uppsrc/plugin/Eigen/Eigen/src/Core/Matrix.h index d7d0b5b9a..02be142d8 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/Matrix.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/Matrix.h @@ -211,6 +211,21 @@ class Matrix : Base(internal::constructor_without_unaligned_array_assert()) { Base::_check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED } +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + Matrix(Matrix&& other) + : Base(std::move(other)) + { + Base::_check_template_params(); + if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic) + Base::_set_noalias(other); + } + Matrix& operator=(Matrix&& other) + { + other.swap(*this); + return *this; + } +#endif + /** \brief Constructs a vector or row-vector with given dimension. \only_for_vectors * * Note that this is only useful for dynamic-size vectors. For fixed-size vectors, diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/MatrixBase.h b/uppsrc/plugin/Eigen/Eigen/src/Core/MatrixBase.h index b67a7c119..e83ef4dc0 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/MatrixBase.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/MatrixBase.h @@ -440,6 +440,15 @@ template class MatrixBase template void applyOnTheRight(Index p, Index q, const JacobiRotation& j); +///////// SparseCore module ///////// + + template + EIGEN_STRONG_INLINE const typename SparseMatrixBase::template CwiseProductDenseReturnType::Type + cwiseProduct(const SparseMatrixBase &other) const + { + return other.cwiseProduct(derived()); + } + ///////// MatrixFunctions module ///////// typedef typename internal::stem_function::type StemFunction; diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/PlainObjectBase.h b/uppsrc/plugin/Eigen/Eigen/src/Core/PlainObjectBase.h index 8a3e4545a..a4e4af4a7 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/PlainObjectBase.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/PlainObjectBase.h @@ -437,6 +437,36 @@ class PlainObjectBase : public internal::dense_xpr_base::type } #endif +#ifdef EIGEN_HAVE_RVALUE_REFERENCES + PlainObjectBase(PlainObjectBase&& other) + : m_storage( std::move(other.m_storage) ) + { + } + + PlainObjectBase& operator=(PlainObjectBase&& other) + { + using std::swap; + swap(m_storage, other.m_storage); + return *this; + } +#endif + + /** Copy constructor */ + EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other) + : m_storage() + { + _check_template_params(); + lazyAssign(other); + } + + template + EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase &other) + : m_storage() + { + _check_template_params(); + lazyAssign(other); + } + EIGEN_STRONG_INLINE PlainObjectBase(Index a_size, Index nbRows, Index nbCols) : m_storage(a_size, nbRows, nbCols) { diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/Redux.h b/uppsrc/plugin/Eigen/Eigen/src/Core/Redux.h index 50548fa9a..9b8662a6f 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/Redux.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/Redux.h @@ -247,8 +247,9 @@ struct redux_impl } }; -template -struct redux_impl +// NOTE: for SliceVectorizedTraversal we simply bypass unrolling +template +struct redux_impl { typedef typename Derived::Scalar Scalar; typedef typename packet_traits::type PacketScalar; diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/Ref.h b/uppsrc/plugin/Eigen/Eigen/src/Core/Ref.h index f53674cff..7a3becaf8 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/Ref.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/Ref.h @@ -244,6 +244,15 @@ template class Ref< // std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n"; construct(expr.derived(), typename Traits::template match::type()); } + + inline Ref(const Ref& other) : Base(other) { + // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy + } + + template + inline Ref(const RefBase& other) { + construct(other.derived(), typename Traits::template match::type()); + } protected: diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/SelfCwiseBinaryOp.h b/uppsrc/plugin/Eigen/Eigen/src/Core/SelfCwiseBinaryOp.h index 22f3047b4..0956475af 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/SelfCwiseBinaryOp.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/SelfCwiseBinaryOp.h @@ -180,15 +180,9 @@ inline Derived& DenseBase::operator*=(const Scalar& other) template inline Derived& DenseBase::operator/=(const Scalar& other) { - typedef typename internal::conditional::IsInteger, - internal::scalar_quotient_op, - internal::scalar_product_op >::type BinOp; typedef typename Derived::PlainObject PlainObject; - SelfCwiseBinaryOp tmp(derived()); - Scalar actual_other; - if(NumTraits::IsInteger) actual_other = other; - else actual_other = Scalar(1)/other; - tmp = PlainObject::Constant(rows(),cols(), actual_other); + SelfCwiseBinaryOp, Derived, typename PlainObject::ConstantReturnType> tmp(derived()); + tmp = PlainObject::Constant(rows(),cols(), other); return derived(); } diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h b/uppsrc/plugin/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h index 94dfab330..d49670e04 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h @@ -384,6 +384,7 @@ template<> EIGEN_STRONG_INLINE int predux_max(const Packet4i& a) a_lo = vget_low_s32(a); a_hi = vget_high_s32(a); max = vpmax_s32(a_lo, a_hi); + max = vpmax_s32(max, max); return vget_lane_s32(max, 0); } diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/arch/SSE/MathFunctions.h b/uppsrc/plugin/Eigen/Eigen/src/Core/arch/SSE/MathFunctions.h index d16f30bb0..2b07168ae 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/arch/SSE/MathFunctions.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/arch/SSE/MathFunctions.h @@ -126,7 +126,7 @@ Packet4f pexp(const Packet4f& _x) _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p4, 1.6666665459E-1f); _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p5, 5.0000001201E-1f); - Packet4f tmp = _mm_setzero_ps(), fx; + Packet4f tmp, fx; Packet4i emm0; // clamp x @@ -195,7 +195,7 @@ Packet2d pexp(const Packet2d& _x) _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_C2, 1.42860682030941723212e-6); static const __m128i p4i_1023_0 = _mm_setr_epi32(1023, 1023, 0, 0); - Packet2d tmp = _mm_setzero_pd(), fx; + Packet2d tmp, fx; Packet4i emm0; // clamp x @@ -279,7 +279,7 @@ Packet4f psin(const Packet4f& _x) _EIGEN_DECLARE_CONST_Packet4f(coscof_p2, 4.166664568298827E-002f); _EIGEN_DECLARE_CONST_Packet4f(cephes_FOPI, 1.27323954473516f); // 4 / M_PI - Packet4f xmm1, xmm2 = _mm_setzero_ps(), xmm3, sign_bit, y; + Packet4f xmm1, xmm2, xmm3, sign_bit, y; Packet4i emm0, emm2; sign_bit = x; @@ -378,7 +378,7 @@ Packet4f pcos(const Packet4f& _x) _EIGEN_DECLARE_CONST_Packet4f(coscof_p2, 4.166664568298827E-002f); _EIGEN_DECLARE_CONST_Packet4f(cephes_FOPI, 1.27323954473516f); // 4 / M_PI - Packet4f xmm1, xmm2 = _mm_setzero_ps(), xmm3, y; + Packet4f xmm1, xmm2, xmm3, y; Packet4i emm0, emm2; x = pabs(x); diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h b/uppsrc/plugin/Eigen/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h index ba41a1c99..4cc56a42f 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h @@ -109,7 +109,7 @@ struct product_triangular_matrix_matrix_trmm class Rotation2D; template class AngleAxis; template class Translation; +// Sparse module: +template class SparseMatrixBase; + #ifdef EIGEN2_SUPPORT template class eigen2_RotationBase; template class eigen2_Cross; diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/util/MKL_support.h b/uppsrc/plugin/Eigen/Eigen/src/Core/util/MKL_support.h index 8acca9c8c..1ef3b61db 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/util/MKL_support.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/util/MKL_support.h @@ -76,6 +76,38 @@ #include #define EIGEN_MKL_VML_THRESHOLD 128 +/* MKL_DOMAIN_BLAS, etc are defined only in 10.3 update 7 */ +/* MKL_BLAS, etc are not defined in 11.2 */ +#ifdef MKL_DOMAIN_ALL +#define EIGEN_MKL_DOMAIN_ALL MKL_DOMAIN_ALL +#else +#define EIGEN_MKL_DOMAIN_ALL MKL_ALL +#endif + +#ifdef MKL_DOMAIN_BLAS +#define EIGEN_MKL_DOMAIN_BLAS MKL_DOMAIN_BLAS +#else +#define EIGEN_MKL_DOMAIN_BLAS MKL_BLAS +#endif + +#ifdef MKL_DOMAIN_FFT +#define EIGEN_MKL_DOMAIN_FFT MKL_DOMAIN_FFT +#else +#define EIGEN_MKL_DOMAIN_FFT MKL_FFT +#endif + +#ifdef MKL_DOMAIN_VML +#define EIGEN_MKL_DOMAIN_VML MKL_DOMAIN_VML +#else +#define EIGEN_MKL_DOMAIN_VML MKL_VML +#endif + +#ifdef MKL_DOMAIN_PARDISO +#define EIGEN_MKL_DOMAIN_PARDISO MKL_DOMAIN_PARDISO +#else +#define EIGEN_MKL_DOMAIN_PARDISO MKL_PARDISO +#endif + namespace Eigen { typedef std::complex dcomplex; diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/util/Macros.h b/uppsrc/plugin/Eigen/Eigen/src/Core/util/Macros.h index f69970f05..53fb5fae4 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/util/Macros.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/util/Macros.h @@ -13,7 +13,7 @@ #define EIGEN_WORLD_VERSION 3 #define EIGEN_MAJOR_VERSION 2 -#define EIGEN_MINOR_VERSION 5 +#define EIGEN_MINOR_VERSION 7 #define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \ (EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \ @@ -96,6 +96,20 @@ #define EIGEN_DEFAULT_DENSE_INDEX_TYPE std::ptrdiff_t #endif +// A Clang feature extension to determine compiler features. +// We use it to determine 'cxx_rvalue_references' +#ifndef __has_feature +# define __has_feature(x) 0 +#endif + +// Do we support r-value references? +#if (__has_feature(cxx_rvalue_references) || \ + defined(__GXX_EXPERIMENTAL_CXX0X__) || \ + (defined(_MSC_VER) && _MSC_VER >= 1600)) + #define EIGEN_HAVE_RVALUE_REFERENCES +#endif + + // Cross compiler wrapper around LLVM's __has_builtin #ifdef __has_builtin # define EIGEN_HAS_BUILTIN(x) __has_builtin(x) @@ -314,7 +328,7 @@ namespace Eigen { // just an empty macro ! #define EIGEN_EMPTY -#if defined(_MSC_VER) && (_MSC_VER < 1800) && (!defined(__INTEL_COMPILER)) +#if defined(_MSC_VER) && (_MSC_VER < 1900) && (!defined(__INTEL_COMPILER)) #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \ using Base::operator =; #elif defined(__clang__) // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653) @@ -409,6 +423,8 @@ namespace Eigen { #define EIGEN_SIZE_MAX(a,b) (((int)a == Dynamic || (int)b == Dynamic) ? Dynamic \ : ((int)a >= (int)b) ? (int)a : (int)b) +#define EIGEN_ADD_COST(a,b) int(a)==Dynamic || int(b)==Dynamic ? Dynamic : int(a)+int(b) + #define EIGEN_LOGICAL_XOR(a,b) (((a) || (b)) && !((a) && (b))) #define EIGEN_IMPLIES(a,b) (!(a) || (b)) diff --git a/uppsrc/plugin/Eigen/Eigen/src/Core/util/XprHelper.h b/uppsrc/plugin/Eigen/Eigen/src/Core/util/XprHelper.h index 781965d2c..d05f8e5f6 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Core/util/XprHelper.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Core/util/XprHelper.h @@ -366,17 +366,17 @@ struct dense_xpr_base /** \internal Helper base class to add a scalar multiple operator * overloads for complex types */ -template::value > -struct special_scalar_op_base : public DenseCoeffsBase +struct special_scalar_op_base : public BaseType { // dummy operator* so that the // "using special_scalar_op_base::operator*" compiles void operator*() const; }; -template -struct special_scalar_op_base : public DenseCoeffsBase +template +struct special_scalar_op_base : public BaseType { const CwiseUnaryOp, Derived> operator*(const OtherScalar& scalar) const diff --git a/uppsrc/plugin/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/uppsrc/plugin/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h index c2e76c884..1131c8af8 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h @@ -80,6 +80,8 @@ template class SelfAdjointEigenSolver /** \brief Scalar type for matrices of type \p _MatrixType. */ typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::Index Index; + + typedef Matrix EigenvectorsType; /** \brief Real scalar type for \p _MatrixType. * @@ -225,7 +227,7 @@ template class SelfAdjointEigenSolver * * \sa eigenvalues() */ - const MatrixType& eigenvectors() const + const EigenvectorsType& eigenvectors() const { eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized."); eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues."); @@ -356,7 +358,7 @@ template class SelfAdjointEigenSolver EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar); } - MatrixType m_eivec; + EigenvectorsType m_eivec; RealVectorType m_eivalues; typename TridiagonalizationType::SubDiagonalType m_subdiag; ComputationInfo m_info; @@ -381,7 +383,7 @@ template class SelfAdjointEigenSolver * "implicit symmetric QR step with Wilkinson shift" */ namespace internal { -template +template static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n); } @@ -413,7 +415,7 @@ SelfAdjointEigenSolver& SelfAdjointEigenSolver // declare some aliases RealVectorType& diag = m_eivalues; - MatrixType& mat = m_eivec; + EigenvectorsType& mat = m_eivec; // map the matrix coefficients to [-1:1] to avoid over- and underflow. mat = matrix.template triangularView(); @@ -449,7 +451,7 @@ SelfAdjointEigenSolver& SelfAdjointEigenSolver while (start>0 && m_subdiag[start-1]!=0) start--; - internal::tridiagonal_qr_step(diag.data(), m_subdiag.data(), start, end, computeEigenvectors ? m_eivec.data() : (Scalar*)0, n); + internal::tridiagonal_qr_step(diag.data(), m_subdiag.data(), start, end, computeEigenvectors ? m_eivec.data() : (Scalar*)0, n); } if (iter <= m_maxIterations * n) @@ -498,6 +500,7 @@ template struct direct_selfadjoint_eigenvalues struct direct_selfadjoint_eigenvalues struct direct_selfadjoint_eigenvalues struct direct_selfadjoint_eigenvalues& SelfAdjointEigenSolver } namespace internal { -template +template static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n) { using std::abs; @@ -784,8 +788,7 @@ static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index sta // apply the givens rotation to the unit matrix Q = Q * G if (matrixQ) { - // FIXME if StorageOrder == RowMajor this operation is not very efficient - Map > q(matrixQ,n,n); + Map > q(matrixQ,n,n); q.applyOnTheRight(k,k+1,rot); } } diff --git a/uppsrc/plugin/Eigen/Eigen/src/Geometry/AlignedBox.h b/uppsrc/plugin/Eigen/Eigen/src/Geometry/AlignedBox.h index b226336de..7e1cd9eb7 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Geometry/AlignedBox.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Geometry/AlignedBox.h @@ -163,7 +163,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) * a uniform distribution */ inline VectorType sample() const { - VectorType r; + VectorType r(dim()); for(Index d=0; d& AngleAxis::operator=(const QuaternionBase::dummy_precision()*NumTraits::dummy_precision()) { - m_angle = 0; - m_axis << 1, 0, 0; + m_angle = Scalar(0); + m_axis << Scalar(1), Scalar(0), Scalar(0); } else { diff --git a/uppsrc/plugin/Eigen/Eigen/src/Geometry/Quaternion.h b/uppsrc/plugin/Eigen/Eigen/src/Geometry/Quaternion.h index 93056f60d..25ed17bb6 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/Geometry/Quaternion.h +++ b/uppsrc/plugin/Eigen/Eigen/src/Geometry/Quaternion.h @@ -102,11 +102,11 @@ public: /** \returns a quaternion representing an identity rotation * \sa MatrixBase::Identity() */ - static inline Quaternion Identity() { return Quaternion(1, 0, 0, 0); } + static inline Quaternion Identity() { return Quaternion(Scalar(1), Scalar(0), Scalar(0), Scalar(0)); } /** \sa QuaternionBase::Identity(), MatrixBase::setIdentity() */ - inline QuaternionBase& setIdentity() { coeffs() << 0, 0, 0, 1; return *this; } + inline QuaternionBase& setIdentity() { coeffs() << Scalar(0), Scalar(0), Scalar(0), Scalar(1); return *this; } /** \returns the squared norm of the quaternion's coefficients * \sa QuaternionBase::norm(), MatrixBase::squaredNorm() diff --git a/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h b/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h index 73ca9bfde..1f3c060d0 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +++ b/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h @@ -65,10 +65,10 @@ class DiagonalPreconditioner { typename MatType::InnerIterator it(mat,j); while(it && it.index()!=j) ++it; - if(it && it.index()==j) + if(it && it.index()==j && it.value()!=Scalar(0)) m_invdiag(j) = Scalar(1)/it.value(); else - m_invdiag(j) = 0; + m_invdiag(j) = Scalar(1); } m_isInitialized = true; return *this; diff --git a/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h b/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h index 2625c4dc3..551221907 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +++ b/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h @@ -186,7 +186,8 @@ public: * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - BiCGSTAB(const MatrixType& A) : Base(A) {} + template + explicit BiCGSTAB(const EigenBase& A) : Base(A.derived()) {} ~BiCGSTAB() {} diff --git a/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h b/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h index 8ba4a8dbe..1a7e569c8 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +++ b/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h @@ -176,7 +176,8 @@ public: * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - ConjugateGradient(const MatrixType& A) : Base(A) {} + template + explicit ConjugateGradient(const EigenBase& A) : Base(A.derived()) {} ~ConjugateGradient() {} diff --git a/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h b/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h index 4c169aa60..d3f37fea2 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +++ b/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h @@ -159,7 +159,7 @@ class IncompleteLUT : internal::noncopyable template void _solve(const Rhs& b, Dest& x) const { - x = m_Pinv * b; + x = m_Pinv * b; x = m_lu.template triangularView().solve(x); x = m_lu.template triangularView().solve(x); x = m_P * x; @@ -222,16 +222,25 @@ template void IncompleteLUT::analyzePattern(const _MatrixType& amat) { // Compute the Fill-reducing permutation + // Since ILUT does not perform any numerical pivoting, + // it is highly preferable to keep the diagonal through symmetric permutations. +#ifndef EIGEN_MPL2_ONLY + // To this end, let's symmetrize the pattern and perform AMD on it. SparseMatrix mat1 = amat; SparseMatrix mat2 = amat.transpose(); - // Symmetrize the pattern // FIXME for a matrix with nearly symmetric pattern, mat2+mat1 is the appropriate choice. // on the other hand for a really non-symmetric pattern, mat2*mat1 should be prefered... SparseMatrix AtA = mat2 + mat1; - AtA.prune(keep_diag()); - internal::minimum_degree_ordering(AtA, m_P); // Then compute the AMD ordering... - - m_Pinv = m_P.inverse(); // ... and the inverse permutation + AMDOrdering ordering; + ordering(AtA,m_P); + m_Pinv = m_P.inverse(); // cache the inverse permutation +#else + // If AMD is not available, (MPL2-only), then let's use the slower COLAMD routine. + SparseMatrix mat1 = amat; + COLAMDOrdering ordering; + ordering(mat1,m_Pinv); + m_P = m_Pinv.inverse(); +#endif m_analysisIsOk = true; m_factorizationIsOk = false; diff --git a/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h b/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h index 2036922d6..501ef2f8d 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +++ b/uppsrc/plugin/Eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h @@ -49,10 +49,11 @@ public: * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - IterativeSolverBase(const MatrixType& A) + template + IterativeSolverBase(const EigenBase& A) { init(); - compute(A); + compute(A.derived()); } ~IterativeSolverBase() {} @@ -62,9 +63,11 @@ public: * Currently, this function mostly call analyzePattern on the preconditioner. In the future * we might, for instance, implement column reodering for faster matrix vector products. */ - Derived& analyzePattern(const MatrixType& A) + template + Derived& analyzePattern(const EigenBase& A) { - m_preconditioner.analyzePattern(A); + grabInput(A.derived()); + m_preconditioner.analyzePattern(*mp_matrix); m_isInitialized = true; m_analysisIsOk = true; m_info = Success; @@ -80,11 +83,12 @@ public: * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - Derived& factorize(const MatrixType& A) + template + Derived& factorize(const EigenBase& A) { + grabInput(A.derived()); eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); - mp_matrix = &A; - m_preconditioner.factorize(A); + m_preconditioner.factorize(*mp_matrix); m_factorizationIsOk = true; m_info = Success; return derived(); @@ -100,10 +104,11 @@ public: * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - Derived& compute(const MatrixType& A) + template + Derived& compute(const EigenBase& A) { - mp_matrix = &A; - m_preconditioner.compute(A); + grabInput(A.derived()); + m_preconditioner.compute(*mp_matrix); m_isInitialized = true; m_analysisIsOk = true; m_factorizationIsOk = true; @@ -212,6 +217,28 @@ public: } protected: + + template + void grabInput(const EigenBase& A) + { + // we const cast to prevent the creation of a MatrixType temporary by the compiler. + grabInput_impl(A.const_cast_derived()); + } + + template + void grabInput_impl(const EigenBase& A) + { + m_copyMatrix = A; + mp_matrix = &m_copyMatrix; + } + + void grabInput_impl(MatrixType& A) + { + if(MatrixType::RowsAtCompileTime==Dynamic && MatrixType::ColsAtCompileTime==Dynamic) + m_copyMatrix.resize(0,0); + mp_matrix = &A; + } + void init() { m_isInitialized = false; @@ -220,6 +247,7 @@ protected: m_maxIterations = -1; m_tolerance = NumTraits::epsilon(); } + MatrixType m_copyMatrix; const MatrixType* mp_matrix; Preconditioner m_preconditioner; diff --git a/uppsrc/plugin/Eigen/Eigen/src/OrderingMethods/Amd.h b/uppsrc/plugin/Eigen/Eigen/src/OrderingMethods/Amd.h index 1c28bdf41..70550b8a9 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/OrderingMethods/Amd.h +++ b/uppsrc/plugin/Eigen/Eigen/src/OrderingMethods/Amd.h @@ -137,9 +137,6 @@ void minimum_degree_ordering(SparseMatrix& C, Permutation degree[i] = len[i]; // degree of node i } mark = internal::cs_wclear(0, 0, w, n); /* clear w */ - elen[n] = -2; /* n is a dead element */ - Cp[n] = -1; /* n is a root of assembly tree */ - w[n] = 0; /* n is a dead element */ /* --- Initialize degree lists ------------------------------------------ */ for(i = 0; i < n; i++) @@ -153,7 +150,7 @@ void minimum_degree_ordering(SparseMatrix& C, Permutation } d = degree[i]; - if(d == 1) /* node i is empty */ + if(d == 1 && has_diag) /* node i is empty */ { elen[i] = -2; /* element i is dead */ nel++; diff --git a/uppsrc/plugin/Eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h b/uppsrc/plugin/Eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h index de00877de..36138101d 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +++ b/uppsrc/plugin/Eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h @@ -47,7 +47,7 @@ namespace Eigen { * You can then apply it to a vector. * * R is the sparse triangular factor. Use matrixQR() to get it as SparseMatrix. - * NOTE : The Index type of R is always UF_long. You can get it with SPQR::Index + * NOTE : The Index type of R is always SuiteSparse_long. You can get it with SPQR::Index * * \tparam _MatrixType The type of the sparse matrix A, must be a column-major SparseMatrix<> * NOTE @@ -59,7 +59,7 @@ class SPQR public: typedef typename _MatrixType::Scalar Scalar; typedef typename _MatrixType::RealScalar RealScalar; - typedef UF_long Index ; + typedef SuiteSparse_long Index ; typedef SparseMatrix MatrixType; typedef PermutationMatrix PermutationType; public: diff --git a/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h b/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h index 60ca7690c..4ca912833 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +++ b/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h @@ -314,10 +314,10 @@ SparseMatrixBase::operator+=(const SparseMatrixBase& othe template template -EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE +EIGEN_STRONG_INLINE const typename SparseMatrixBase::template CwiseProductDenseReturnType::Type SparseMatrixBase::cwiseProduct(const MatrixBase &other) const { - return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(derived(), other.derived()); + return typename CwiseProductDenseReturnType::Type(derived(), other.derived()); } } // end namespace Eigen diff --git a/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseMatrix.h b/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseMatrix.h index ba5e3a9b6..2ff201551 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseMatrix.h +++ b/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseMatrix.h @@ -691,7 +691,8 @@ class SparseMatrix m_data.swap(other.m_data); } - /** Sets *this to the identity matrix */ + /** Sets *this to the identity matrix. + * This function also turns the matrix into compressed mode, and drop any reserved memory. */ inline void setIdentity() { eigen_assert(rows() == cols() && "ONLY FOR SQUARED MATRICES"); @@ -699,6 +700,8 @@ class SparseMatrix Eigen::Map >(&this->m_data.index(0), rows()).setLinSpaced(0, rows()-1); Eigen::Map >(&this->m_data.value(0), rows()).setOnes(); Eigen::Map >(this->m_outerIndex, rows()+1).setLinSpaced(0, rows()); + std::free(m_innerNonZeros); + m_innerNonZeros = 0; } inline SparseMatrix& operator=(const SparseMatrix& other) { diff --git a/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseMatrixBase.h b/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseMatrixBase.h index 6b2169a7b..9341d9ad2 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseMatrixBase.h +++ b/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseMatrixBase.h @@ -23,7 +23,14 @@ namespace Eigen { * This class can be extended with the help of the plugin mechanism described on the page * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_SPARSEMATRIXBASE_PLUGIN. */ -template class SparseMatrixBase : public EigenBase +template class SparseMatrixBase +#ifndef EIGEN_PARSED_BY_DOXYGEN + : public internal::special_scalar_op_base::Scalar, + typename NumTraits::Scalar>::Real, + EigenBase > +#else + : public EigenBase +#endif // not EIGEN_PARSED_BY_DOXYGEN { public: @@ -36,7 +43,6 @@ template class SparseMatrixBase : public EigenBase >::type PacketReturnType; typedef SparseMatrixBase StorageBaseType; - typedef EigenBase Base; template Derived& operator=(const EigenBase &other) @@ -132,6 +138,9 @@ template class SparseMatrixBase : public EigenBase inline Derived& derived() { return *static_cast(this); } inline Derived& const_cast_derived() const { return *static_cast(const_cast(this)); } + + typedef internal::special_scalar_op_base > Base; + using Base::operator*; #endif // not EIGEN_PARSED_BY_DOXYGEN #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase @@ -317,20 +326,18 @@ template class SparseMatrixBase : public EigenBase Derived& operator*=(const Scalar& other); Derived& operator/=(const Scalar& other); - #define EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE \ - CwiseBinaryOp< \ - internal::scalar_product_op< \ - typename internal::scalar_product_traits< \ - typename internal::traits::Scalar, \ - typename internal::traits::Scalar \ - >::ReturnType \ - >, \ - const Derived, \ - const OtherDerived \ - > + template struct CwiseProductDenseReturnType { + typedef CwiseBinaryOp::Scalar, + typename internal::traits::Scalar + >::ReturnType>, + const Derived, + const OtherDerived + > Type; + }; template - EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE + EIGEN_STRONG_INLINE const typename CwiseProductDenseReturnType::Type cwiseProduct(const MatrixBase &other) const; // sparse * sparse diff --git a/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseUtil.h b/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseUtil.h index 0ba471320..d627546de 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseUtil.h +++ b/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseUtil.h @@ -67,7 +67,6 @@ const int InnerRandomAccessPattern = 0x2 | CoherentAccessPattern; const int OuterRandomAccessPattern = 0x4 | CoherentAccessPattern; const int RandomAccessPattern = 0x8 | OuterRandomAccessPattern | InnerRandomAccessPattern; -template class SparseMatrixBase; template class SparseMatrix; template class DynamicSparseMatrix; template class SparseVector; diff --git a/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseVector.h b/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseVector.h index 7e15c814b..49865d0e7 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseVector.h +++ b/uppsrc/plugin/Eigen/Eigen/src/SparseCore/SparseVector.h @@ -158,6 +158,7 @@ class SparseVector Index inner = IsColVector ? row : col; Index outer = IsColVector ? col : row; + EIGEN_ONLY_USED_FOR_DEBUG(outer); eigen_assert(outer==0); return insert(inner); } diff --git a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU.h b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU.h index 4514cfd9c..bdc4f193d 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU.h +++ b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU.h @@ -749,8 +749,8 @@ struct SparseLUMatrixUReturnType : internal::no_assignment_operator } else { - Map, 0, OuterStride<> > A( &(m_mapL.valuePtr()[luptr]), nsupc, nsupc, OuterStride<>(lda) ); - Map< Matrix, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) ); + Map, 0, OuterStride<> > A( &(m_mapL.valuePtr()[luptr]), nsupc, nsupc, OuterStride<>(lda) ); + Map< Matrix, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) ); U = A.template triangularView().solve(U); } diff --git a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLUImpl.h b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLUImpl.h index 14d70897d..99d651e40 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLUImpl.h +++ b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLUImpl.h @@ -21,6 +21,8 @@ class SparseLUImpl { public: typedef Matrix ScalarVector; + typedef Matrix ScalarMatrix; + typedef Map > MappedMatrixBlock; typedef Matrix IndexVector; typedef typename ScalarVector::RealScalar RealScalar; typedef Ref > BlockScalarVector; diff --git a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_Memory.h b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_Memory.h index 1ffa7d54e..45f96d16a 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_Memory.h +++ b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_Memory.h @@ -153,8 +153,8 @@ Index SparseLUImpl::memInit(Index m, Index n, Index annz, Index lw { Index& num_expansions = glu.num_expansions; //No memory expansions so far num_expansions = 0; - glu.nzumax = glu.nzlumax = (std::min)(fillratio * annz / n, m) * n; // estimated number of nonzeros in U - glu.nzlmax = (std::max)(Index(4), fillratio) * annz / 4; // estimated nnz in L factor + glu.nzumax = glu.nzlumax = (std::min)(fillratio * (annz+1) / n, m) * n; // estimated number of nonzeros in U + glu.nzlmax = (std::max)(Index(4), fillratio) * (annz+1) / 4; // estimated nnz in L factor // Return the estimated size to the user if necessary Index tempSpace; tempSpace = (2*panel_size + 4 + LUNoMarker) * m * sizeof(Index) + (panel_size + 1) * m * sizeof(Scalar); diff --git a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h index b16afd6a4..54a569408 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +++ b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h @@ -236,7 +236,7 @@ void MappedSuperNodalMatrix::solveInPlace( MatrixBase&X) con Index n = X.rows(); Index nrhs = X.cols(); const Scalar * Lval = valuePtr(); // Nonzero values - Matrix work(n, nrhs); // working vector + Matrix work(n, nrhs); // working vector work.setZero(); for (Index k = 0; k <= nsuper(); k ++) { @@ -267,12 +267,12 @@ void MappedSuperNodalMatrix::solveInPlace( MatrixBase&X) con Index lda = colIndexPtr()[fsupc+1] - luptr; // Triangular solve - Map, 0, OuterStride<> > A( &(Lval[luptr]), nsupc, nsupc, OuterStride<>(lda) ); - Map< Matrix, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) ); + Map, 0, OuterStride<> > A( &(Lval[luptr]), nsupc, nsupc, OuterStride<>(lda) ); + Map< Matrix, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) ); U = A.template triangularView().solve(U); // Matrix-vector product - new (&A) Map, 0, OuterStride<> > ( &(Lval[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) ); + new (&A) Map, 0, OuterStride<> > ( &(Lval[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) ); work.block(0, 0, nrow, nrhs) = A * U; //Begin Scatter diff --git a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h index f24bd87d3..cacc7e987 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h +++ b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h @@ -162,11 +162,11 @@ Index SparseLUImpl::column_bmod(const Index jcol, const Index nseg // points to the beginning of jcol in snode L\U(jsupno) ufirst = glu.xlusup(jcol) + d_fsupc; Index lda = glu.xlusup(jcol+1) - glu.xlusup(jcol); - Map, 0, OuterStride<> > A( &(glu.lusup.data()[luptr]), nsupc, nsupc, OuterStride<>(lda) ); + MappedMatrixBlock A( &(glu.lusup.data()[luptr]), nsupc, nsupc, OuterStride<>(lda) ); VectorBlock u(glu.lusup, ufirst, nsupc); u = A.template triangularView().solve(u); - new (&A) Map, 0, OuterStride<> > ( &(glu.lusup.data()[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) ); + new (&A) MappedMatrixBlock ( &(glu.lusup.data()[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) ); VectorBlock l(glu.lusup, ufirst+nsupc, nrow); l.noalias() -= A * u; diff --git a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h index 0d0283b13..6af026754 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +++ b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h @@ -56,7 +56,7 @@ EIGEN_DONT_INLINE void LU_kernel_bmod::run(const int segsi // Dense triangular solve -- start effective triangle luptr += lda * no_zeros + no_zeros; // Form Eigen matrix and vector - Map, 0, OuterStride<> > A( &(lusup.data()[luptr]), segsize, segsize, OuterStride<>(lda) ); + Map, 0, OuterStride<> > A( &(lusup.data()[luptr]), segsize, segsize, OuterStride<>(lda) ); Map > u(tempv.data(), segsize); u = A.template triangularView().solve(u); @@ -65,7 +65,7 @@ EIGEN_DONT_INLINE void LU_kernel_bmod::run(const int segsi luptr += segsize; const Index PacketSize = internal::packet_traits::size; Index ldl = internal::first_multiple(nrow, PacketSize); - Map, 0, OuterStride<> > B( &(lusup.data()[luptr]), nrow, segsize, OuterStride<>(lda) ); + Map, 0, OuterStride<> > B( &(lusup.data()[luptr]), nrow, segsize, OuterStride<>(lda) ); Index aligned_offset = internal::first_aligned(tempv.data()+segsize, PacketSize); Index aligned_with_B_offset = (PacketSize-internal::first_aligned(B.data(), PacketSize))%PacketSize; Map, 0, OuterStride<> > l(tempv.data()+segsize+aligned_offset+aligned_with_B_offset, nrow, OuterStride<>(ldl) ); diff --git a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h index da0e0fc3c..9d2ff2906 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h +++ b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h @@ -102,7 +102,7 @@ void SparseLUImpl::panel_bmod(const Index m, const Index w, const if(nsupc >= 2) { Index ldu = internal::first_multiple(u_rows, PacketSize); - Map, Aligned, OuterStride<> > U(tempv.data(), u_rows, u_cols, OuterStride<>(ldu)); + Map > U(tempv.data(), u_rows, u_cols, OuterStride<>(ldu)); // gather U Index u_col = 0; @@ -136,17 +136,17 @@ void SparseLUImpl::panel_bmod(const Index m, const Index w, const Index lda = glu.xlusup(fsupc+1) - glu.xlusup(fsupc); no_zeros = (krep - u_rows + 1) - fsupc; luptr += lda * no_zeros + no_zeros; - Map, 0, OuterStride<> > A(glu.lusup.data()+luptr, u_rows, u_rows, OuterStride<>(lda) ); + MappedMatrixBlock A(glu.lusup.data()+luptr, u_rows, u_rows, OuterStride<>(lda) ); U = A.template triangularView().solve(U); // update luptr += u_rows; - Map, 0, OuterStride<> > B(glu.lusup.data()+luptr, nrow, u_rows, OuterStride<>(lda) ); + MappedMatrixBlock B(glu.lusup.data()+luptr, nrow, u_rows, OuterStride<>(lda) ); eigen_assert(tempv.size()>w*ldu + nrow*w + 1); Index ldl = internal::first_multiple(nrow, PacketSize); Index offset = (PacketSize-internal::first_aligned(B.data(), PacketSize)) % PacketSize; - Map, 0, OuterStride<> > L(tempv.data()+w*ldu+offset, nrow, u_cols, OuterStride<>(ldl)); + MappedMatrixBlock L(tempv.data()+w*ldu+offset, nrow, u_cols, OuterStride<>(ldl)); L.setZero(); internal::sparselu_gemm(L.rows(), L.cols(), B.cols(), B.data(), B.outerStride(), U.data(), U.outerStride(), L.data(), L.outerStride()); diff --git a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_pivotL.h b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_pivotL.h index 457789c78..2e49ef667 100644 --- a/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_pivotL.h +++ b/uppsrc/plugin/Eigen/Eigen/src/SparseLU/SparseLU_pivotL.h @@ -71,7 +71,7 @@ Index SparseLUImpl::pivotL(const Index jcol, const RealScalar& dia // Determine the largest abs numerical value for partial pivoting Index diagind = iperm_c(jcol); // diagonal index - RealScalar pivmax = 0.0; + RealScalar pivmax(-1.0); Index pivptr = nsupc; Index diag = emptyIdxLU; RealScalar rtemp; @@ -87,8 +87,9 @@ Index SparseLUImpl::pivotL(const Index jcol, const RealScalar& dia } // Test for singularity - if ( pivmax == 0.0 ) { - pivrow = lsub_ptr[pivptr]; + if ( pivmax <= RealScalar(0.0) ) { + // if pivmax == -1, the column is structurally empty, otherwise it is only numerically zero + pivrow = pivmax < RealScalar(0.0) ? diagind : lsub_ptr[pivptr]; perm_r(pivrow) = jcol; return (jcol+1); } diff --git a/uppsrc/plugin/Eigen/ToStringPlugin.h b/uppsrc/plugin/Eigen/ToStringPlugin.h index 331f60dcd..8b555e8ef 100644 --- a/uppsrc/plugin/Eigen/ToStringPlugin.h +++ b/uppsrc/plugin/Eigen/ToStringPlugin.h @@ -1,7 +1,7 @@ #ifndef _Eigen_UppMatrixPlugin_h_ #define _Eigen_UppMatrixPlugin_h_ -UPP::String ToString() const{ +UPP::String ToString() const { std::stringstream s; s << *this; return s.str(); diff --git a/uppsrc/plugin/Eigen/srcdoc.tpp/Eigen$en-us.tpp b/uppsrc/plugin/Eigen/srcdoc.tpp/Eigen$en-us.tpp index 2f595f107..5603a1303 100644 --- a/uppsrc/plugin/Eigen/srcdoc.tpp/Eigen$en-us.tpp +++ b/uppsrc/plugin/Eigen/srcdoc.tpp/Eigen$en-us.tpp @@ -17,7 +17,7 @@ vectors, numerical solvers and related algorithms.]&] [s0; [C2 -|Matrix2d res `= a`*b;-|// Just multiply them using `*]&] [s0;#2 &] [s0;#2 &] -[s0;# [2 Eigen package is a wrapper of Eigen 3.2.5 library. It includes +[s0;# [2 Eigen package is a wrapper of Eigen 3.2.7 library. It includes the library and helper functions to integrate better Eigen with U`+`+. Starting from the 3.1.1 version, it is licensed under the ][^http`:`/`/www`.mozilla`.org`/MPL`/2`.0`/^2 MPL2][2 , which @@ -40,6 +40,27 @@ hurber][2 (see the graphs).]&] (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) ]&] [s0;#2 &] +[s0;# [2 It also includes a simple FFT (][^https`:`/`/en`.wikipedia`.org`/wiki`/Fast`_Fourier`_transform^2 F +ast Fourier Transform][2 ) sample.that:]&] +[s0;#i150;O0; [2 Generates a data series composed by three sinusoidal +series of amplitude 2, 5 and 30, and frequencies 1/50, 1/30 and +1/10 Hz:]&] +[s0;# [2 -|f(t) `= 2`*sin(2`*PI`*t/50 `- PI/3) `+ 5`*sin(2`*PI`*t/30 +`- PI/2) `+ 30`*sin(2`*PI`*t/10 `- PI/5)]&] +[s0;#i150;O0; [2 Gets the FFT]&] +[s0;#i150;O0; [2 Filters the frequencies between 1/25 and 1/35 Hz]&] +[s0;#i150;O0; [2 Gets the filtered data series]&] +[s0;#i150;O0; [2 Saves both FFT and series]&] +[s0;#2 &] +[s0;= [2 +@@image:2731&1368 +(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QUFBQUEeynssKCgoKCgoKCjIQ3mPBQUFBQUFBQUFeSjvsaCgoKCgoKCgIA/lPRYUFBQUFBQUFOShvMeCgoKCgoKCgoI8lPdYUFBQUFBQUFCQhxV4j1cvP3AOl67cuPXTjSuXbv9y+epR+1ZQUFBQUFBQULAFq/Aez53G23DTdySvsTmW6m8FBQUFBQUFBQXHhBV6j8155B/kvwsKCgoKCgoKCo4Oq/Aetw+uy3ssKCgoKCgoKFgtrMB7ZLh9Tl3eY0FBQUFBQUHBamFN3uNN9/Hy1dne46/+6q9eL1gBfPjDHz52FwpuQjFiJVCMWAkUI1YCxYiVwEc/+tHlDhs1tbydHcDNyzK3XMWZt2be+9737r9zBX1YiyA956EYsRIoRqwEihErgWLESmAnjDi693gnOY9Iz8OhkJlj6/IeVwJlGVYCxYiVQDFiJVCMWAkUI1YCp+E9LofyHlcCF12QTgaKESuBYsRKoBixEihGrATKeyQo73ElcNEF6WSgGLESKEasBIoRK4FixEqgvEeC8h5XAhddkE4GihErgWLESqAYsRIoRqwEynskKO9xJXDRBelkoBixEihGrASKESuBYsRKoLxHgvIeVwIXXZBOBooRK4FixEqgGLESKEasBMp7JCjvcSVw0QXpZKAYsRIoRqwEihErgWLESqC8R4LyHlcCF12QTgaKESuBYsRKoBixEihGrATKeyQo73ElcNEF6WSgGLESKEasBIoRK4FixEqgvEeC8h5XAhddkE4GihErgWLESqAYsRIoRqwEynskKO9xJXDRBelkoBixEihGrASKESuBYsRKoLxHgvIeVwIXXZBOBooRK4FixEqgGLESKEasBMp7JCjvcSVw0QXpZKAYsRIoRqwEihErgWLESqC8R4LyHlcCF12QTgaKESuBYsRKoBixEihGrATKeyQo73ElcNEF6WSgGLESKEasBIoRK4FixEqgvEeC8h5XAhddkE4GihErgWLESqAYsRIoRqwEynskKO9xJXDRBelkoBixEihGrASKESuBYsRKoLxHgvIeVwIXXZBOBooRK4FixEqgGLESKEasBMp7JCjvcSVw0QXpZKAYsRIoRqwEihErgWLESqC8R4LyHlcCF12QTgaKESuBYsRKoBixEihGrATKeyQo73ElcNEF6WSgGLESKEasBIoRK4FixEqgvEeC8h5XAhdd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8caVy+Q03nQZbzmL/I+bfiV7lCHkvUc+R+huoXAAMM+VS64iHncSVNP9f/rPf74njAPeYz424N5777377rujvx7FhkQUtjXJnlO1r/7OX1kiS5m00vv2Hv+L//KzDkzhJFs//elPP/vss7jNtgxpFuPatWu7QgpgwHtUpslutLIAEC8Wpik+vNZ85Pc/5WrNXvEOeI9J5/z+++8HNY9il6Lj8miak4zY9zQ3YJowIySuv/W6b27qcwAKb8p7PG/k6HuPt6E5jbdcxfP/l78hyHuPahIEMz4HAHO1Jc7e/mxIdxK8/7s/oEbaLMZyvC40QZp1x5C34zI7cnkbcjB1jiisqvFK5HNedE+r9sKX/M0lspQJ/t+39/jqb/m5Q1I4w1bKMtco/F9/zl/BstSWIW0Id911V+Rn7lCWBrxHZZqsqLBvwNWWbBkdXmve+f7fV/0/AN653iObplf8nX6g8tq8xwhpNM1heVuOV9aZa5raepC6l9HWtqrlgQyPIgNzp7kD51PNwMl4j+cn17dPqQ/mPf5P/8t9Ed/59//qv3kh77TMGZPf2m5tSHMd2yhe9rKXAaSf90WvanXaKBjp2574xEK8ETRByt8xlMvezO4uMNFz43x2BRGFVTX2917z7e9mcVqIdLcmusH3fM/3vPWtb+0iPeSMv0krzqyTAhY5rDg7kaVh7/He135j1zTtb2E73BoBliVWBznX71uWZnmPJE5NVYnC3e24Ae9xrze/IqSRLOHF73K8ss5c09QEibr30EMPdZHKgQyPIgNzp7m//pV/v4nTfQ8+0p3mDgYn4z3ehpsH1jddxYN5j121ohmfd1pmjsdpbbdWmtdlAClVeNVbfoqRvvEHn1mIN4ImSPk7hjSJkOvVnQR//dd/HYx0VpzPDiGisFuNypf/sx/72//oe9dmohvcddddEXkl0pe+/HVyzRUNZK/JCizSWScFZwKWIM3AsPeYMU07mSvdkS70bZKy9CVf+23SSQajSIYgApjlPZI4NY1+yZe+ppWucz4gS3u9+SURycPcSJao/6/8Jz+EudCmm2/4hm9YGII41zS94x3vuOeee+6///7HH38cICVZkhqxV/987jRHHfuCV78Jm6ZDwql5j7c2IS9fHfEer+cAmOioJqgj4bu+67sefvjhLt58g1249957P/dzP5cGApDKvVOA98efvPYl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) +]&] +[s0;#2 &] +[s0;= [2 +@@image:2730&1572 +(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r7zyytgFyd/D2Dcf0/RgsYOZPWZir5r2wx/+MMaiZa2HVZkDYrHIRCIWi0wkYrHIRFpJLP00tMq7znxVm+tlw5eMREOzeIJIxGKRiUQsFplIxGKRiZRhQ1sFNDQr01UZG7FYZCIRi0UmErFYZCLR0OBluipjIxaLTCRischEIhaLTCQaGrxMV2VsxGKRiUQsFplIxGKRiURDg5fpqoyNWCwykYjFIhOJWCwykWho8DJdlbERi0UmErFYZCIRi0UmEg0NXqarMjZischEIhaLTCRischEoqHBy3RVxkYsFplIxGKRiUQsFplINDR4ma7K2IjFIhOJWCwykYjFIhOJhgYv01UZG7FYZCIRi0UmErFYZCLR0OBluipjIxaLTCRischEIhaLTCQaGrxMV2VsxGKRiUQsFplIxGKRiURDg5fpqoyNWCwykYjFIhOJWCwykWho8DJdlbERi0UmErFYZCIRi0UmEg0NXqarMjZischEIhaLTCRischEoqHBy3RVxkYsFplIxGKRiUQsFplINDR4ma7K2IjFIhOJWCwykYjFIhOJhgYv01UZG7FYZCIRi0UmErFYZCLR0OBluipjIxaLTCRischEIhaLTCQaGrxMV2VsxGKRiUQsFplIxGKRiURDg5fpqoyNWCwykYjFIhOJWCwykWho8DJdlbERi0UmErFYZCIRi0UmEg0NXqarMjZischEIhaLTCRischEoqHBy3RVxkYsFplIxGKRiUQsFplINDR4ma7K2IjFIhOJWCwykYjFIhOJhgYv01UZG7FYZCIRi0UmErFYZCLR0OBluipjIxaLTCRischEIhaLTCQaGrxMV2VsxGKRiUQsFplIxGKRiURDg5fpqoyNWCwykYjFIhOJWCwykWho8DJdlbERi0UmErFYZCIRi0UmEg0NXqarMjZischEIhaLTCRischEoqHBy3RVxkYsFplIxGKRiUQsFplINDR4ma7K2IjFIhOJWCwykYjFIhOJhgYv01UZG7FYZCIRi0UmErFYZCLR0OBluipjIxaLTCRischEIhaLTCQaGrxMV2VsxGKRiUQsFplIxGKRiURDg5fpqoyNWCwykYjFIhOJWCwykWho8DJdlbERi0UmErFYZCIRi0UmEg0NXqarMjZischEIhaLTCRischEoqHBy3RVxkYsFplIxGKRiUQsFplINDR4ma7K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) +]&] [s0;#2 &] [s0;# [2 Eigen packages have been prepared by ][^http`:`/`/www`.ultimatepp`.org`/forum`/index`.php`?t`=usrinfo`&id`=647`&^2 d olik.rce][2 and ][^http`:`/`/www`.ultimatepp`.org`/forum`/index`.php`?t`=usrinfo`&id`=648`&^2 k diff --git a/uppsrc/plugin/Eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h b/uppsrc/plugin/Eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h index 8d42e69b9..fde3ff61a 100644 --- a/uppsrc/plugin/Eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h +++ b/uppsrc/plugin/Eigen/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h @@ -631,7 +631,7 @@ template struct NumTraits > { typedef AutoDiffScalar::Real,DerType::RowsAtCompileTime,DerType::ColsAtCompileTime> > Real; typedef AutoDiffScalar NonInteger; - typedef AutoDiffScalar& Nested; + typedef AutoDiffScalar Nested; enum{ RequireInitialization = 1 }; diff --git a/uppsrc/plugin/Eigen/unsupported/Eigen/src/CMakeLists.txt b/uppsrc/plugin/Eigen/unsupported/Eigen/src/CMakeLists.txt index 125c43fdf..d8b9f4068 100644 --- a/uppsrc/plugin/Eigen/unsupported/Eigen/src/CMakeLists.txt +++ b/uppsrc/plugin/Eigen/unsupported/Eigen/src/CMakeLists.txt @@ -1,5 +1,6 @@ ADD_SUBDIRECTORY(AutoDiff) ADD_SUBDIRECTORY(BVH) +ADD_SUBDIRECTORY(Eigenvalues) ADD_SUBDIRECTORY(FFT) ADD_SUBDIRECTORY(IterativeSolvers) ADD_SUBDIRECTORY(KroneckerProduct) diff --git a/uppsrc/plugin/Eigen/unsupported/Eigen/src/Eigenvalues/CMakeLists.txt b/uppsrc/plugin/Eigen/unsupported/Eigen/src/Eigenvalues/CMakeLists.txt new file mode 100644 index 000000000..1d4387c82 --- /dev/null +++ b/uppsrc/plugin/Eigen/unsupported/Eigen/src/Eigenvalues/CMakeLists.txt @@ -0,0 +1,6 @@ +FILE(GLOB Eigen_Eigenvalues_SRCS "*.h") + +INSTALL(FILES + ${Eigen_Eigenvalues_SRCS} + DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/Eigenvalues COMPONENT Devel + ) diff --git a/uppsrc/plugin/Eigen/unsupported/Eigen/src/IterativeSolvers/DGMRES.h b/uppsrc/plugin/Eigen/unsupported/Eigen/src/IterativeSolvers/DGMRES.h index 9fcc8a8d9..68fc997f7 100644 --- a/uppsrc/plugin/Eigen/unsupported/Eigen/src/IterativeSolvers/DGMRES.h +++ b/uppsrc/plugin/Eigen/unsupported/Eigen/src/IterativeSolvers/DGMRES.h @@ -133,8 +133,8 @@ class DGMRES : public IterativeSolverBase > * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - DGMRES(const MatrixType& A) : Base(A),m_restart(30),m_neig(0),m_r(0),m_maxNeig(5),m_isDeflAllocated(false),m_isDeflInitialized(false) - {} + template + explicit DGMRES(const EigenBase& A) : Base(A.derived()), m_restart(30),m_neig(0),m_r(0),m_maxNeig(5),m_isDeflAllocated(false),m_isDeflInitialized(false) {} ~DGMRES() {} diff --git a/uppsrc/plugin/Eigen/unsupported/Eigen/src/IterativeSolvers/GMRES.h b/uppsrc/plugin/Eigen/unsupported/Eigen/src/IterativeSolvers/GMRES.h index 7ba13afd2..ea5deb26d 100644 --- a/uppsrc/plugin/Eigen/unsupported/Eigen/src/IterativeSolvers/GMRES.h +++ b/uppsrc/plugin/Eigen/unsupported/Eigen/src/IterativeSolvers/GMRES.h @@ -285,7 +285,8 @@ public: * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - GMRES(const MatrixType& A) : Base(A), m_restart(30) {} + template + explicit GMRES(const EigenBase& A) : Base(A.derived()), m_restart(30) {} ~GMRES() {} diff --git a/uppsrc/plugin/Eigen/unsupported/Eigen/src/IterativeSolvers/MINRES.h b/uppsrc/plugin/Eigen/unsupported/Eigen/src/IterativeSolvers/MINRES.h index 30f26aa50..670f274bb 100644 --- a/uppsrc/plugin/Eigen/unsupported/Eigen/src/IterativeSolvers/MINRES.h +++ b/uppsrc/plugin/Eigen/unsupported/Eigen/src/IterativeSolvers/MINRES.h @@ -228,7 +228,8 @@ namespace Eigen { * this class becomes invalid. Call compute() to update it with the new * matrix A, or modify a copy of A. */ - MINRES(const MatrixType& A) : Base(A) {} + template + explicit MINRES(const EigenBase& A) : Base(A.derived()) {} /** Destructor. */ ~MINRES(){}