diff --git a/eigenlib/Eigen/Core b/eigenlib/Eigen/Core index d4801702..9131cc3f 100644 --- a/eigenlib/Eigen/Core +++ b/eigenlib/Eigen/Core @@ -19,6 +19,12 @@ // defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization. #include "src/Core/util/Macros.h" +// Disable the ipa-cp-clone optimization flag with MinGW 6.x or newer (enabled by default with -O3) +// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556 for details. +#if defined(__MINGW32__) && EIGEN_GNUC_AT_LEAST(4,6) + #pragma GCC optimize ("-fno-ipa-cp-clone") +#endif + #include // this include file manages BLAS and MKL related macros @@ -44,7 +50,7 @@ #endif #else // Remember that usage of defined() in a #define is undefined by the standard - #if (defined __SSE2__) && ( (!defined __GNUC__) || EIGEN_GNUC_AT_LEAST(4,2) ) + #if (defined __SSE2__) && ( (!defined __GNUC__) || (defined __INTEL_COMPILER) || EIGEN_GNUC_AT_LEAST(4,2) ) #define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC #endif #endif @@ -87,19 +93,25 @@ // so, to avoid compile errors when windows.h is included after Eigen/Core, ensure intrinsics are extern "C" here too. // notice that since these are C headers, the extern "C" is theoretically needed anyways. extern "C" { - #include - #include - #ifdef EIGEN_VECTORIZE_SSE3 - #include - #endif - #ifdef EIGEN_VECTORIZE_SSSE3 - #include - #endif - #ifdef EIGEN_VECTORIZE_SSE4_1 - #include - #endif - #ifdef EIGEN_VECTORIZE_SSE4_2 - #include + // In theory we should only include immintrin.h and not the other *mmintrin.h header files directly. + // Doing so triggers some issues with ICC. However old gcc versions seems to not have this file, thus: + #ifdef __INTEL_COMPILER + #include + #else + #include + #include + #ifdef EIGEN_VECTORIZE_SSE3 + #include + #endif + #ifdef EIGEN_VECTORIZE_SSSE3 + #include + #endif + #ifdef EIGEN_VECTORIZE_SSE4_1 + #include + #endif + #ifdef EIGEN_VECTORIZE_SSE4_2 + #include + #endif #endif } // end extern "C" #elif defined __ALTIVEC__ @@ -236,15 +248,11 @@ using std::ptrdiff_t; * \endcode */ -/** \defgroup Support_modules Support modules [category] - * Category of modules which add support for external libraries. - */ - #include "src/Core/util/Constants.h" #include "src/Core/util/ForwardDeclarations.h" #include "src/Core/util/Meta.h" -#include "src/Core/util/XprHelper.h" #include "src/Core/util/StaticAssert.h" +#include "src/Core/util/XprHelper.h" #include "src/Core/util/Memory.h" #include "src/Core/NumTraits.h" @@ -297,6 +305,7 @@ using std::ptrdiff_t; #include "src/Core/Map.h" #include "src/Core/Block.h" #include "src/Core/VectorBlock.h" +#include "src/Core/Ref.h" #include "src/Core/Transpose.h" #include "src/Core/DiagonalMatrix.h" #include "src/Core/Diagonal.h" @@ -330,6 +339,7 @@ using std::ptrdiff_t; #include "src/Core/products/TriangularSolverMatrix.h" #include "src/Core/products/TriangularSolverVector.h" #include "src/Core/BandMatrix.h" +#include "src/Core/CoreIterators.h" #include "src/Core/BooleanRedux.h" #include "src/Core/Select.h" diff --git a/eigenlib/Eigen/Eigen2Support b/eigenlib/Eigen/Eigen2Support index 36156d29..6aa009d2 100644 --- a/eigenlib/Eigen/Eigen2Support +++ b/eigenlib/Eigen/Eigen2Support @@ -14,12 +14,25 @@ #error Eigen2 support must be enabled by defining EIGEN2_SUPPORT before including any Eigen header #endif +#ifndef EIGEN_NO_EIGEN2_DEPRECATED_WARNING + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) +#warning "Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. (Define EIGEN_NO_EIGEN2_DEPRECATED_WARNING to disable this warning)" +#else +#pragma message ("Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. (Define EIGEN_NO_EIGEN2_DEPRECATED_WARNING to disable this warning)") +#endif + +#endif // EIGEN_NO_EIGEN2_DEPRECATED_WARNING + #include "src/Core/util/DisableStupidWarnings.h" /** \ingroup Support_modules * \defgroup Eigen2Support_Module Eigen2 support module - * This module provides a couple of deprecated functions improving the compatibility with Eigen2. * + * \warning Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. + * + * This module provides a couple of deprecated functions improving the compatibility with Eigen2. + * * To use it, define EIGEN2_SUPPORT before including any Eigen header * \code * #define EIGEN2_SUPPORT diff --git a/eigenlib/Eigen/Eigenvalues b/eigenlib/Eigen/Eigenvalues index af99ccd1..53c5a73a 100644 --- a/eigenlib/Eigen/Eigenvalues +++ b/eigenlib/Eigen/Eigenvalues @@ -33,6 +33,8 @@ #include "src/Eigenvalues/HessenbergDecomposition.h" #include "src/Eigenvalues/ComplexSchur.h" #include "src/Eigenvalues/ComplexEigenSolver.h" +#include "src/Eigenvalues/RealQZ.h" +#include "src/Eigenvalues/GeneralizedEigenSolver.h" #include "src/Eigenvalues/MatrixBaseEigenvalues.h" #ifdef EIGEN_USE_LAPACKE #include "src/Eigenvalues/RealSchur_MKL.h" diff --git a/eigenlib/Eigen/IterativeLinearSolvers b/eigenlib/Eigen/IterativeLinearSolvers index 315c2dd1..0f4159dc 100644 --- a/eigenlib/Eigen/IterativeLinearSolvers +++ b/eigenlib/Eigen/IterativeLinearSolvers @@ -6,7 +6,7 @@ #include "src/Core/util/DisableStupidWarnings.h" -/** \ingroup Sparse_modules +/** * \defgroup IterativeLinearSolvers_Module IterativeLinearSolvers module * * This module currently provides iterative methods to solve problems of the form \c A \c x = \c b, where \c A is a squared matrix, usually very large and sparse. diff --git a/eigenlib/Eigen/MetisSupport b/eigenlib/Eigen/MetisSupport new file mode 100644 index 00000000..6a113f7a --- /dev/null +++ b/eigenlib/Eigen/MetisSupport @@ -0,0 +1,28 @@ +#ifndef EIGEN_METISSUPPORT_MODULE_H +#define EIGEN_METISSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +extern "C" { +#include +} + + +/** \ingroup Support_modules + * \defgroup MetisSupport_Module MetisSupport module + * + * \code + * #include + * \endcode + * This module defines an interface to the METIS reordering package (http://glaros.dtc.umn.edu/gkhome/views/metis). + * It can be used just as any other built-in method as explained in \link OrderingMethods_Module here. \endlink + */ + + +#include "src/MetisSupport/MetisSupport.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif // EIGEN_METISSUPPORT_MODULE_H diff --git a/eigenlib/Eigen/OrderingMethods b/eigenlib/Eigen/OrderingMethods index 1e2d8745..7c0f1fff 100644 --- a/eigenlib/Eigen/OrderingMethods +++ b/eigenlib/Eigen/OrderingMethods @@ -5,19 +5,62 @@ #include "src/Core/util/DisableStupidWarnings.h" -/** \ingroup Sparse_modules +/** * \defgroup OrderingMethods_Module OrderingMethods module * - * This module is currently for internal use only. - * - * + * This module is currently for internal use only + * + * It defines various built-in and external ordering methods for sparse matrices. + * They are typically used to reduce the number of elements during + * the sparse matrix decomposition (LLT, LU, QR). + * Precisely, in a preprocessing step, a permutation matrix P is computed using + * those ordering methods and applied to the columns of the matrix. + * Using for instance the sparse Cholesky decomposition, it is expected that + * the nonzeros elements in LLT(A*P) will be much smaller than that in LLT(A). + * + * + * Usage : * \code * #include * \endcode + * + * A simple usage is as a template parameter in the sparse decomposition classes : + * + * \code + * SparseLU > solver; + * \endcode + * + * \code + * SparseQR > solver; + * \endcode + * + * It is possible as well to call directly a particular ordering method for your own purpose, + * \code + * AMDOrdering ordering; + * PermutationMatrix perm; + * SparseMatrix A; + * //Fill the matrix ... + * + * ordering(A, perm); // Call AMD + * \endcode + * + * \note Some of these methods (like AMD or METIS), need the sparsity pattern + * of the input matrix to be symmetric. When the matrix is structurally unsymmetric, + * Eigen computes internally the pattern of \f$A^T*A\f$ before calling the method. + * If your matrix is already symmetric (at leat in structure), you can avoid that + * by calling the method with a SelfAdjointView type. + * + * \code + * // Call the ordering on the pattern of the lower triangular matrix A + * ordering(A.selfadjointView(), perm); + * \endcode */ +#ifndef EIGEN_MPL2_ONLY #include "src/OrderingMethods/Amd.h" +#endif +#include "src/OrderingMethods/Ordering.h" #include "src/Core/util/ReenableStupidWarnings.h" #endif // EIGEN_ORDERINGMETHODS_MODULE_H diff --git a/eigenlib/Eigen/SPQRSupport b/eigenlib/Eigen/SPQRSupport new file mode 100644 index 00000000..77016442 --- /dev/null +++ b/eigenlib/Eigen/SPQRSupport @@ -0,0 +1,29 @@ +#ifndef EIGEN_SPQRSUPPORT_MODULE_H +#define EIGEN_SPQRSUPPORT_MODULE_H + +#include "SparseCore" + +#include "src/Core/util/DisableStupidWarnings.h" + +#include "SuiteSparseQR.hpp" + +/** \ingroup Support_modules + * \defgroup SPQRSupport_Module SuiteSparseQR module + * + * This module provides an interface to the SPQR library, which is part of the suitesparse package. + * + * \code + * #include + * \endcode + * + * In order to use this module, the SPQR headers must be accessible from the include paths, and your binary must be linked to the SPQR library and its dependencies (Cholmod, AMD, COLAMD,...). + * For a cmake based project, you can use our FindSPQR.cmake and FindCholmod.Cmake modules + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" +#include "src/CholmodSupport/CholmodSupport.h" +#include "src/SPQRSupport/SuiteSparseQRSupport.h" + +#endif diff --git a/eigenlib/Eigen/Sparse b/eigenlib/Eigen/Sparse index 2d175717..7cc9c091 100644 --- a/eigenlib/Eigen/Sparse +++ b/eigenlib/Eigen/Sparse @@ -1,13 +1,15 @@ #ifndef EIGEN_SPARSE_MODULE_H #define EIGEN_SPARSE_MODULE_H -/** \defgroup Sparse_modules Sparse modules +/** \defgroup Sparse_Module Sparse meta-module * * Meta-module including all related modules: - * - SparseCore - * - OrderingMethods - * - SparseCholesky - * - IterativeLinearSolvers + * - \ref SparseCore_Module + * - \ref OrderingMethods_Module + * - \ref SparseCholesky_Module + * - \ref SparseLU_Module + * - \ref SparseQR_Module + * - \ref IterativeLinearSolvers_Module * * \code * #include @@ -17,6 +19,8 @@ #include "SparseCore" #include "OrderingMethods" #include "SparseCholesky" +#include "SparseLU" +#include "SparseQR" #include "IterativeLinearSolvers" #endif // EIGEN_SPARSE_MODULE_H diff --git a/eigenlib/Eigen/SparseCholesky b/eigenlib/Eigen/SparseCholesky index 5f82742f..9f5056aa 100644 --- a/eigenlib/Eigen/SparseCholesky +++ b/eigenlib/Eigen/SparseCholesky @@ -1,11 +1,21 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2013 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + #ifndef EIGEN_SPARSECHOLESKY_MODULE_H #define EIGEN_SPARSECHOLESKY_MODULE_H #include "SparseCore" +#include "OrderingMethods" #include "src/Core/util/DisableStupidWarnings.h" -/** \ingroup Sparse_modules +/** * \defgroup SparseCholesky_Module SparseCholesky module * * This module currently provides two variants of the direct sparse Cholesky decomposition for selfadjoint (hermitian) matrices. @@ -20,11 +30,18 @@ * \endcode */ +#ifdef EIGEN_MPL2_ONLY +#error The SparseCholesky module has nothing to offer in MPL2 only mode +#endif + #include "src/misc/Solve.h" #include "src/misc/SparseSolve.h" - #include "src/SparseCholesky/SimplicialCholesky.h" +#ifndef EIGEN_MPL2_ONLY +#include "src/SparseCholesky/SimplicialCholesky_impl.h" +#endif + #include "src/Core/util/ReenableStupidWarnings.h" #endif // EIGEN_SPARSECHOLESKY_MODULE_H diff --git a/eigenlib/Eigen/SparseCore b/eigenlib/Eigen/SparseCore index 41d28c92..9b5be5e1 100644 --- a/eigenlib/Eigen/SparseCore +++ b/eigenlib/Eigen/SparseCore @@ -11,7 +11,7 @@ #include #include -/** \ingroup Sparse_modules +/** * \defgroup SparseCore_Module SparseCore module * * This module provides a sparse matrix representation, and basic associatd matrix manipulations @@ -40,14 +40,12 @@ struct Sparse {}; #include "src/SparseCore/SparseMatrix.h" #include "src/SparseCore/MappedSparseMatrix.h" #include "src/SparseCore/SparseVector.h" -#include "src/SparseCore/CoreIterators.h" #include "src/SparseCore/SparseBlock.h" #include "src/SparseCore/SparseTranspose.h" #include "src/SparseCore/SparseCwiseUnaryOp.h" #include "src/SparseCore/SparseCwiseBinaryOp.h" #include "src/SparseCore/SparseDot.h" #include "src/SparseCore/SparsePermutation.h" -#include "src/SparseCore/SparseAssign.h" #include "src/SparseCore/SparseRedux.h" #include "src/SparseCore/SparseFuzzy.h" #include "src/SparseCore/ConservativeSparseSparseProduct.h" diff --git a/eigenlib/Eigen/SparseLU b/eigenlib/Eigen/SparseLU new file mode 100644 index 00000000..8527a49b --- /dev/null +++ b/eigenlib/Eigen/SparseLU @@ -0,0 +1,49 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2012 Désiré Nuentsa-Wakam +// Copyright (C) 2012 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_SPARSELU_MODULE_H +#define EIGEN_SPARSELU_MODULE_H + +#include "SparseCore" + +/** + * \defgroup SparseLU_Module SparseLU module + * This module defines a supernodal factorization of general sparse matrices. + * The code is fully optimized for supernode-panel updates with specialized kernels. + * Please, see the documentation of the SparseLU class for more details. + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +// Ordering interface +#include "OrderingMethods" + +#include "src/SparseLU/SparseLU_gemm_kernel.h" + +#include "src/SparseLU/SparseLU_Structs.h" +#include "src/SparseLU/SparseLU_SupernodalMatrix.h" +#include "src/SparseLU/SparseLUImpl.h" +#include "src/SparseCore/SparseColEtree.h" +#include "src/SparseLU/SparseLU_Memory.h" +#include "src/SparseLU/SparseLU_heap_relax_snode.h" +#include "src/SparseLU/SparseLU_relax_snode.h" +#include "src/SparseLU/SparseLU_pivotL.h" +#include "src/SparseLU/SparseLU_panel_dfs.h" +#include "src/SparseLU/SparseLU_kernel_bmod.h" +#include "src/SparseLU/SparseLU_panel_bmod.h" +#include "src/SparseLU/SparseLU_column_dfs.h" +#include "src/SparseLU/SparseLU_column_bmod.h" +#include "src/SparseLU/SparseLU_copy_to_ucol.h" +#include "src/SparseLU/SparseLU_pruneL.h" +#include "src/SparseLU/SparseLU_Utils.h" +#include "src/SparseLU/SparseLU.h" + +#endif // EIGEN_SPARSELU_MODULE_H diff --git a/eigenlib/Eigen/SparseQR b/eigenlib/Eigen/SparseQR new file mode 100644 index 00000000..4ee42065 --- /dev/null +++ b/eigenlib/Eigen/SparseQR @@ -0,0 +1,33 @@ +#ifndef EIGEN_SPARSEQR_MODULE_H +#define EIGEN_SPARSEQR_MODULE_H + +#include "SparseCore" +#include "OrderingMethods" +#include "src/Core/util/DisableStupidWarnings.h" + +/** \defgroup SparseQR_Module SparseQR module + * \brief Provides QR decomposition for sparse matrices + * + * This module provides a simplicial version of the left-looking Sparse QR decomposition. + * The columns of the input matrix should be reordered to limit the fill-in during the + * decomposition. Built-in methods (COLAMD, AMD) or external methods (METIS) can be used to this end. + * See the \link OrderingMethods_Module OrderingMethods\endlink module for the list + * of built-in and external ordering methods. + * + * \code + * #include + * \endcode + * + * + */ + +#include "src/misc/Solve.h" +#include "src/misc/SparseSolve.h" + +#include "OrderingMethods" +#include "src/SparseCore/SparseColEtree.h" +#include "src/SparseQR/SparseQR.h" + +#include "src/Core/util/ReenableStupidWarnings.h" + +#endif diff --git a/eigenlib/Eigen/src/Cholesky/LDLT.h b/eigenlib/Eigen/src/Cholesky/LDLT.h index 68e54b1d..d026418f 100644 --- a/eigenlib/Eigen/src/Cholesky/LDLT.h +++ b/eigenlib/Eigen/src/Cholesky/LDLT.h @@ -16,7 +16,10 @@ namespace Eigen { namespace internal { -template struct LDLT_Traits; + template struct LDLT_Traits; + + // PositiveSemiDef means positive semi-definite and non-zero; same for NegativeSemiDef + enum SignMatrix { PositiveSemiDef, NegativeSemiDef, ZeroSign, Indefinite }; } /** \ingroup Cholesky_Module @@ -69,7 +72,12 @@ template class LDLT * The default constructor is useful in cases in which the user intends to * perform decompositions via LDLT::compute(const MatrixType&). */ - LDLT() : m_matrix(), m_transpositions(), m_isInitialized(false) {} + LDLT() + : m_matrix(), + m_transpositions(), + m_sign(internal::ZeroSign), + m_isInitialized(false) + {} /** \brief Default Constructor with memory preallocation * @@ -81,6 +89,7 @@ template class LDLT : m_matrix(size, size), m_transpositions(size), m_temporary(size), + m_sign(internal::ZeroSign), m_isInitialized(false) {} @@ -93,6 +102,7 @@ template class LDLT : m_matrix(matrix.rows(), matrix.cols()), m_transpositions(matrix.rows()), m_temporary(matrix.rows()), + m_sign(internal::ZeroSign), m_isInitialized(false) { compute(matrix); @@ -139,7 +149,7 @@ template class LDLT inline bool isPositive() const { eigen_assert(m_isInitialized && "LDLT is not initialized."); - return m_sign == 1; + return m_sign == internal::PositiveSemiDef || m_sign == internal::ZeroSign; } #ifdef EIGEN2_SUPPORT @@ -153,7 +163,7 @@ template class LDLT inline bool isNegative(void) const { eigen_assert(m_isInitialized && "LDLT is not initialized."); - return m_sign == -1; + return m_sign == internal::NegativeSemiDef || m_sign == internal::ZeroSign; } /** \returns a solution x of \f$ A x = b \f$ using the current decomposition of A. @@ -196,7 +206,7 @@ template class LDLT LDLT& compute(const MatrixType& matrix); template - LDLT& rankUpdate(const MatrixBase& w,RealScalar alpha=1); + LDLT& rankUpdate(const MatrixBase& w, const RealScalar& alpha=1); /** \returns the internal LDLT decomposition matrix * @@ -235,7 +245,7 @@ template class LDLT MatrixType m_matrix; TranspositionType m_transpositions; TmpMatrixType m_temporary; - int m_sign; + internal::SignMatrix m_sign; bool m_isInitialized; }; @@ -246,8 +256,9 @@ template struct ldlt_inplace; template<> struct ldlt_inplace { template - static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, int* sign=0) + static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, SignMatrix& sign) { + using std::abs; typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::RealScalar RealScalar; typedef typename MatrixType::Index Index; @@ -257,8 +268,9 @@ template<> struct ldlt_inplace if (size <= 1) { transpositions.setIdentity(); - if(sign) - *sign = real(mat.coeff(0,0))>0 ? 1:-1; + if (numext::real(mat.coeff(0,0)) > 0) sign = PositiveSemiDef; + else if (numext::real(mat.coeff(0,0)) < 0) sign = NegativeSemiDef; + else sign = ZeroSign; return true; } @@ -277,9 +289,6 @@ template<> struct ldlt_inplace // are compared; if any diagonal is negligible compared // to the largest overall, the algorithm bails. cutoff = abs(NumTraits::epsilon() * biggest_in_corner); - - if(sign) - *sign = real(mat.diagonal().coeff(index_of_biggest_in_corner)) > 0 ? 1 : -1; } // Finish early if the matrix is not full rank. @@ -301,11 +310,11 @@ template<> struct ldlt_inplace for(int i=k+1;i::IsComplex) - mat.coeffRef(index_of_biggest_in_corner,k) = conj(mat.coeff(index_of_biggest_in_corner,k)); + mat.coeffRef(index_of_biggest_in_corner,k) = numext::conj(mat.coeff(index_of_biggest_in_corner,k)); } // partition the matrix: @@ -326,6 +335,16 @@ template<> struct ldlt_inplace } if((rs>0) && (abs(mat.coeffRef(k,k)) > cutoff)) A21 /= mat.coeffRef(k,k); + + RealScalar realAkk = numext::real(mat.coeffRef(k,k)); + if (sign == PositiveSemiDef) { + if (realAkk < 0) sign = Indefinite; + } else if (sign == NegativeSemiDef) { + if (realAkk > 0) sign = Indefinite; + } else if (sign == ZeroSign) { + if (realAkk > 0) sign = PositiveSemiDef; + else if (realAkk < 0) sign = NegativeSemiDef; + } } return true; @@ -339,9 +358,9 @@ template<> struct ldlt_inplace // Here only rank-1 updates are implemented, to reduce the // requirement for intermediate storage and improve accuracy template - static bool updateInPlace(MatrixType& mat, MatrixBase& w, typename MatrixType::RealScalar sigma=1) + static bool updateInPlace(MatrixType& mat, MatrixBase& w, const typename MatrixType::RealScalar& sigma=1) { - using internal::isfinite; + using numext::isfinite; typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::RealScalar RealScalar; typedef typename MatrixType::Index Index; @@ -359,9 +378,9 @@ template<> struct ldlt_inplace break; // Update the diagonal terms - RealScalar dj = real(mat.coeff(j,j)); + RealScalar dj = numext::real(mat.coeff(j,j)); Scalar wj = w.coeff(j); - RealScalar swj2 = sigma*abs2(wj); + RealScalar swj2 = sigma*numext::abs2(wj); RealScalar gamma = dj*alpha + swj2; mat.coeffRef(j,j) += swj2/alpha; @@ -372,13 +391,13 @@ template<> struct ldlt_inplace Index rs = size-j-1; w.tail(rs) -= wj * mat.col(j).tail(rs); if(gamma != 0) - mat.col(j).tail(rs) += (sigma*conj(wj)/gamma)*w.tail(rs); + mat.col(j).tail(rs) += (sigma*numext::conj(wj)/gamma)*w.tail(rs); } return true; } template - static bool update(MatrixType& mat, const TranspositionType& transpositions, Workspace& tmp, const WType& w, typename MatrixType::RealScalar sigma=1) + static bool update(MatrixType& mat, const TranspositionType& transpositions, Workspace& tmp, const WType& w, const typename MatrixType::RealScalar& sigma=1) { // Apply the permutation to the input w tmp = transpositions * w; @@ -390,14 +409,14 @@ template<> struct ldlt_inplace template<> struct ldlt_inplace { template - static EIGEN_STRONG_INLINE bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, int* sign=0) + static EIGEN_STRONG_INLINE bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, SignMatrix& sign) { Transpose matt(mat); return ldlt_inplace::unblocked(matt, transpositions, temp, sign); } template - static EIGEN_STRONG_INLINE bool update(MatrixType& mat, TranspositionType& transpositions, Workspace& tmp, WType& w, typename MatrixType::RealScalar sigma=1) + static EIGEN_STRONG_INLINE bool update(MatrixType& mat, TranspositionType& transpositions, Workspace& tmp, WType& w, const typename MatrixType::RealScalar& sigma=1) { Transpose matt(mat); return ldlt_inplace::update(matt, transpositions, tmp, w.conjugate(), sigma); @@ -436,7 +455,7 @@ LDLT& LDLT::compute(const MatrixType& a) m_isInitialized = false; m_temporary.resize(size); - internal::ldlt_inplace::unblocked(m_matrix, m_transpositions, m_temporary, &m_sign); + internal::ldlt_inplace::unblocked(m_matrix, m_transpositions, m_temporary, m_sign); m_isInitialized = true; return *this; @@ -449,7 +468,7 @@ LDLT& LDLT::compute(const MatrixType& a) */ template template -LDLT& LDLT::rankUpdate(const MatrixBase& w,typename NumTraits::Real sigma) +LDLT& LDLT::rankUpdate(const MatrixBase& w, const typename NumTraits::Real& sigma) { const Index size = w.rows(); if (m_isInitialized) @@ -464,7 +483,7 @@ LDLT& LDLT::rankUpdate(const MatrixBase=0 ? 1 : -1; + m_sign = sigma>=0 ? internal::PositiveSemiDef : internal::NegativeSemiDef; m_isInitialized = true; } @@ -534,8 +553,7 @@ template bool LDLT::solveInPlace(MatrixBase &bAndX) const { eigen_assert(m_isInitialized && "LDLT is not initialized."); - const Index size = m_matrix.rows(); - eigen_assert(size == bAndX.rows()); + eigen_assert(m_matrix.rows() == bAndX.rows()); bAndX = this->solve(bAndX); diff --git a/eigenlib/Eigen/src/Cholesky/LLT.h b/eigenlib/Eigen/src/Cholesky/LLT.h index 41d14e53..2e6189f7 100644 --- a/eigenlib/Eigen/src/Cholesky/LLT.h +++ b/eigenlib/Eigen/src/Cholesky/LLT.h @@ -190,6 +190,7 @@ template struct llt_inplace; template static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma) { + using std::sqrt; typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::RealScalar RealScalar; typedef typename MatrixType::Index Index; @@ -199,7 +200,7 @@ static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const V typedef Matrix TempVectorType; typedef typename TempVectorType::SegmentReturnType TempVecSegment; - int n = mat.cols(); + Index n = mat.cols(); eigen_assert(mat.rows()==n && vec.size()==n); TempVectorType temp; @@ -211,12 +212,12 @@ static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const V // i.e., for sigma > 0 temp = sqrt(sigma) * vec; - for(int i=0; i g; g.makeGivens(mat(i,i), -temp(i), &mat(i,i)); - int rs = n-i-1; + Index rs = n-i-1; if(rs>0) { ColXprSegment x(mat.col(i).tail(rs)); @@ -229,12 +230,12 @@ static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const V { temp = vec; RealScalar beta = 1; - for(int j=0; j struct llt_inplace template static typename MatrixType::Index unblocked(MatrixType& mat) { + using std::sqrt; typedef typename MatrixType::Index Index; eigen_assert(mat.rows()==mat.cols()); @@ -275,7 +277,7 @@ template struct llt_inplace Block A10(mat,k,0,1,k); Block A20(mat,k+1,0,rs,k); - RealScalar x = real(mat.coeff(k,k)); + RealScalar x = numext::real(mat.coeff(k,k)); if (k>0) x -= A10.squaredNorm(); if (x<=RealScalar(0)) return k; diff --git a/eigenlib/Eigen/src/CholmodSupport/CholmodSupport.h b/eigenlib/Eigen/src/CholmodSupport/CholmodSupport.h index 37f14215..c449960d 100644 --- a/eigenlib/Eigen/src/CholmodSupport/CholmodSupport.h +++ b/eigenlib/Eigen/src/CholmodSupport/CholmodSupport.h @@ -51,7 +51,6 @@ void cholmod_configure_matrix(CholmodType& mat) template cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat) { - typedef SparseMatrix<_Scalar,_Options,_Index> MatrixType; cholmod_sparse res; res.nzmax = mat.nonZeros(); res.nrow = mat.rows();; @@ -59,10 +58,12 @@ cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat) res.p = mat.outerIndexPtr(); res.i = mat.innerIndexPtr(); res.x = mat.valuePtr(); + res.z = 0; res.sorted = 1; if(mat.isCompressed()) { res.packed = 1; + res.nz = 0; } else { @@ -77,9 +78,13 @@ cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat) { res.itype = CHOLMOD_INT; } + else if (internal::is_same<_Index,UF_long>::value) + { + res.itype = CHOLMOD_LONG; + } else { - eigen_assert(false && "Index type different than int is not supported yet"); + eigen_assert(false && "Index type not supported yet"); } // setup res.xtype @@ -123,7 +128,7 @@ cholmod_dense viewAsCholmod(MatrixBase& mat) res.ncol = mat.cols(); res.nzmax = res.nrow * res.ncol; res.d = Derived::IsVectorAtCompileTime ? mat.derived().size() : mat.derived().outerStride(); - res.x = mat.derived().data(); + res.x = (void*)(mat.derived().data()); res.z = 0; internal::cholmod_configure_matrix(res); @@ -137,8 +142,8 @@ template MappedSparseMatrix viewAsEigen(cholmod_sparse& cm) { return MappedSparseMatrix - (cm.nrow, cm.ncol, reinterpret_cast(cm.p)[cm.ncol], - reinterpret_cast(cm.p), reinterpret_cast(cm.i),reinterpret_cast(cm.x) ); + (cm.nrow, cm.ncol, static_cast(cm.p)[cm.ncol], + static_cast(cm.p), static_cast(cm.i),static_cast(cm.x) ); } enum CholmodMode { @@ -167,12 +172,14 @@ class CholmodBase : internal::noncopyable CholmodBase() : m_cholmodFactor(0), m_info(Success), m_isInitialized(false) { + m_shiftOffset[0] = m_shiftOffset[1] = RealScalar(0.0); cholmod_start(&m_cholmod); } CholmodBase(const MatrixType& matrix) : m_cholmodFactor(0), m_info(Success), m_isInitialized(false) { + m_shiftOffset[0] = m_shiftOffset[1] = RealScalar(0.0); cholmod_start(&m_cholmod); compute(matrix); } @@ -237,7 +244,7 @@ class CholmodBase : internal::noncopyable return internal::sparse_solve_retval(*this, b.derived()); } - /** Performs a symbolic decomposition on the sparcity of \a matrix. + /** Performs a symbolic decomposition on the sparsity pattern of \a matrix. * * This function is particularly useful when solving for several problems having the same structure. * @@ -261,7 +268,7 @@ class CholmodBase : internal::noncopyable /** Performs a numeric decomposition of \a matrix * - * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed. + * The given matrix must have the same sparsity pattern as the matrix on which the symbolic decomposition has been performed. * * \sa analyzePattern() */ @@ -269,9 +276,10 @@ class CholmodBase : internal::noncopyable { eigen_assert(m_analysisIsOk && "You must first call analyzePattern()"); cholmod_sparse A = viewAsCholmod(matrix.template selfadjointView()); - cholmod_factorize(&A, m_cholmodFactor, &m_cholmod); + cholmod_factorize_p(&A, m_shiftOffset, 0, 0, m_cholmodFactor, &m_cholmod); - this->m_info = Success; + // If the factorization failed, minor is the column at which it did. On success minor == n. + this->m_info = (m_cholmodFactor->minor == m_cholmodFactor->n ? Success : NumericalIssue); m_factorizationIsOk = true; } @@ -286,16 +294,18 @@ class CholmodBase : internal::noncopyable { eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); const Index size = m_cholmodFactor->n; + EIGEN_UNUSED_VARIABLE(size); eigen_assert(size==b.rows()); // note: cd stands for Cholmod Dense - cholmod_dense b_cd = viewAsCholmod(b.const_cast_derived()); + Rhs& b_ref(b.const_cast_derived()); + cholmod_dense b_cd = viewAsCholmod(b_ref); cholmod_dense* x_cd = cholmod_solve(CHOLMOD_A, m_cholmodFactor, &b_cd, &m_cholmod); if(!x_cd) { this->m_info = NumericalIssue; } - // TODO optimize this copy by swapping when possible (be carreful with alignment, etc.) + // TODO optimize this copy by swapping when possible (be careful with alignment, etc.) dest = Matrix::Map(reinterpret_cast(x_cd->x),b.rows(),b.cols()); cholmod_free_dense(&x_cd, &m_cholmod); } @@ -306,6 +316,7 @@ class CholmodBase : internal::noncopyable { eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()"); const Index size = m_cholmodFactor->n; + EIGEN_UNUSED_VARIABLE(size); eigen_assert(size==b.rows()); // note: cs stands for Cholmod Sparse @@ -315,19 +326,36 @@ class CholmodBase : internal::noncopyable { this->m_info = NumericalIssue; } - // TODO optimize this copy by swapping when possible (be carreful with alignment, etc.) + // TODO optimize this copy by swapping when possible (be careful with alignment, etc.) dest = viewAsEigen(*x_cs); cholmod_free_sparse(&x_cs, &m_cholmod); } #endif // EIGEN_PARSED_BY_DOXYGEN + + /** Sets the shift parameter that will be used to adjust the diagonal coefficients during the numerical factorization. + * + * During the numerical factorization, an offset term is added to the diagonal coefficients:\n + * \c d_ii = \a offset + \c d_ii + * + * The default is \a offset=0. + * + * \returns a reference to \c *this. + */ + Derived& setShift(const RealScalar& offset) + { + m_shiftOffset[0] = offset; + return derived(); + } + template - void dumpMemory(Stream& s) + void dumpMemory(Stream& /*s*/) {} protected: mutable cholmod_common m_cholmod; cholmod_factor* m_cholmodFactor; + RealScalar m_shiftOffset[2]; mutable ComputationInfo m_info; bool m_isInitialized; int m_factorizationIsOk; @@ -340,8 +368,8 @@ class CholmodBase : internal::noncopyable * * This class allows to solve for A.X = B sparse linear problems via a simplicial LL^T Cholesky factorization * using the Cholmod library. - * This simplicial variant is equivalent to Eigen's built-in SimplicialLLT class. Thefore, it has little practical interest. - * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * This simplicial variant is equivalent to Eigen's built-in SimplicialLLT class. Therefore, it has little practical interest. + * The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices * X and B can be either dense or sparse. * * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> @@ -387,8 +415,8 @@ class CholmodSimplicialLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimpl * * This class allows to solve for A.X = B sparse linear problems via a simplicial LDL^T Cholesky factorization * using the Cholmod library. - * This simplicial variant is equivalent to Eigen's built-in SimplicialLDLT class. Thefore, it has little practical interest. - * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * This simplicial variant is equivalent to Eigen's built-in SimplicialLDLT class. Therefore, it has little practical interest. + * The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices * X and B can be either dense or sparse. * * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> @@ -433,7 +461,7 @@ class CholmodSimplicialLDLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimp * This class allows to solve for A.X = B sparse linear problems via a supernodal LL^T Cholesky factorization * using the Cholmod library. * This supernodal variant performs best on dense enough problems, e.g., 3D FEM, or very high order 2D FEM. - * The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices * X and B can be either dense or sparse. * * \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<> @@ -476,7 +504,7 @@ class CholmodSupernodalLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSuper * \brief A general Cholesky factorization and solver based on Cholmod * * This class allows to solve for A.X = B sparse linear problems via a LL^T or LDL^T Cholesky factorization - * using the Cholmod library. The sparse matrix A must be selfajoint and positive definite. The vectors or matrices + * using the Cholmod library. The sparse matrix A must be selfadjoint and positive definite. The vectors or matrices * X and B can be either dense or sparse. * * This variant permits to change the underlying Cholesky method at runtime. diff --git a/eigenlib/Eigen/src/Core/Array.h b/eigenlib/Eigen/src/Core/Array.h index aaa38997..0ab03eff 100644 --- a/eigenlib/Eigen/src/Core/Array.h +++ b/eigenlib/Eigen/src/Core/Array.h @@ -107,10 +107,10 @@ class Array * * \sa resize(Index,Index) */ - EIGEN_STRONG_INLINE explicit Array() : Base() + EIGEN_STRONG_INLINE Array() : Base() { Base::_check_template_params(); - EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED } #ifndef EIGEN_PARSED_BY_DOXYGEN @@ -120,7 +120,7 @@ class Array : Base(internal::constructor_without_unaligned_array_assert()) { Base::_check_template_params(); - EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED } #endif @@ -137,15 +137,15 @@ class Array EIGEN_STATIC_ASSERT_VECTOR_ONLY(Array) eigen_assert(dim >= 0); eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim); - EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED } #ifndef EIGEN_PARSED_BY_DOXYGEN template - EIGEN_STRONG_INLINE Array(const T0& x, const T1& y) + EIGEN_STRONG_INLINE Array(const T0& val0, const T1& val1) { Base::_check_template_params(); - this->template _init2(x, y); + this->template _init2(val0, val1); } #else /** constructs an uninitialized matrix with \a rows rows and \a cols columns. @@ -155,27 +155,27 @@ class Array * Matrix() instead. */ Array(Index rows, Index cols); /** constructs an initialized 2D vector with given coefficients */ - Array(const Scalar& x, const Scalar& y); + Array(const Scalar& val0, const Scalar& val1); #endif /** constructs an initialized 3D vector with given coefficients */ - EIGEN_STRONG_INLINE Array(const Scalar& x, const Scalar& y, const Scalar& z) + EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2) { Base::_check_template_params(); EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3) - m_storage.data()[0] = x; - m_storage.data()[1] = y; - m_storage.data()[2] = z; + m_storage.data()[0] = val0; + m_storage.data()[1] = val1; + m_storage.data()[2] = val2; } /** constructs an initialized 4D vector with given coefficients */ - EIGEN_STRONG_INLINE Array(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w) + EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3) { Base::_check_template_params(); EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4) - m_storage.data()[0] = x; - m_storage.data()[1] = y; - m_storage.data()[2] = z; - m_storage.data()[3] = w; + m_storage.data()[0] = val0; + m_storage.data()[1] = val1; + m_storage.data()[2] = val2; + m_storage.data()[3] = val3; } explicit Array(const Scalar *data); @@ -210,7 +210,7 @@ class Array : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) { Base::_check_template_params(); - Base::resize(other.rows(), other.cols()); + Base::_resize_to_match(other); *this = other; } diff --git a/eigenlib/Eigen/src/Core/ArrayBase.h b/eigenlib/Eigen/src/Core/ArrayBase.h index 004b117c..38852600 100644 --- a/eigenlib/Eigen/src/Core/ArrayBase.h +++ b/eigenlib/Eigen/src/Core/ArrayBase.h @@ -143,7 +143,7 @@ template class ArrayBase ArrayBase& array() { return *this; } const ArrayBase& array() const { return *this; } - /** \returns an \link MatrixBase Matrix \endlink expression of this array + /** \returns an \link Eigen::MatrixBase Matrix \endlink expression of this array * \sa MatrixBase::array() */ MatrixWrapper matrix() { return derived(); } const MatrixWrapper matrix() const { return derived(); } diff --git a/eigenlib/Eigen/src/Core/ArrayWrapper.h b/eigenlib/Eigen/src/Core/ArrayWrapper.h index 65ffd64c..a791bc35 100644 --- a/eigenlib/Eigen/src/Core/ArrayWrapper.h +++ b/eigenlib/Eigen/src/Core/ArrayWrapper.h @@ -55,22 +55,22 @@ class ArrayWrapper : public ArrayBase > inline Index outerStride() const { return m_expression.outerStride(); } inline Index innerStride() const { return m_expression.innerStride(); } - inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); } + inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); } inline const Scalar* data() const { return m_expression.data(); } - inline CoeffReturnType coeff(Index row, Index col) const + inline CoeffReturnType coeff(Index rowId, Index colId) const { - return m_expression.coeff(row, col); + return m_expression.coeff(rowId, colId); } - inline Scalar& coeffRef(Index row, Index col) + inline Scalar& coeffRef(Index rowId, Index colId) { - return m_expression.const_cast_derived().coeffRef(row, col); + return m_expression.const_cast_derived().coeffRef(rowId, colId); } - inline const Scalar& coeffRef(Index row, Index col) const + inline const Scalar& coeffRef(Index rowId, Index colId) const { - return m_expression.const_cast_derived().coeffRef(row, col); + return m_expression.const_cast_derived().coeffRef(rowId, colId); } inline CoeffReturnType coeff(Index index) const @@ -89,15 +89,15 @@ class ArrayWrapper : public ArrayBase > } template - inline const PacketScalar packet(Index row, Index col) const + inline const PacketScalar packet(Index rowId, Index colId) const { - return m_expression.template packet(row, col); + return m_expression.template packet(rowId, colId); } template - inline void writePacket(Index row, Index col, const PacketScalar& x) + inline void writePacket(Index rowId, Index colId, const PacketScalar& val) { - m_expression.const_cast_derived().template writePacket(row, col, x); + m_expression.const_cast_derived().template writePacket(rowId, colId, val); } template @@ -107,9 +107,9 @@ class ArrayWrapper : public ArrayBase > } template - inline void writePacket(Index index, const PacketScalar& x) + inline void writePacket(Index index, const PacketScalar& val) { - m_expression.const_cast_derived().template writePacket(index, x); + m_expression.const_cast_derived().template writePacket(index, val); } template @@ -168,29 +168,29 @@ class MatrixWrapper : public MatrixBase > typedef typename internal::nested::type NestedExpressionType; - inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {} + inline MatrixWrapper(ExpressionType& a_matrix) : m_expression(a_matrix) {} inline Index rows() const { return m_expression.rows(); } inline Index cols() const { return m_expression.cols(); } inline Index outerStride() const { return m_expression.outerStride(); } inline Index innerStride() const { return m_expression.innerStride(); } - inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); } + inline ScalarWithConstIfNotLvalue* data() { return m_expression.const_cast_derived().data(); } inline const Scalar* data() const { return m_expression.data(); } - inline CoeffReturnType coeff(Index row, Index col) const + inline CoeffReturnType coeff(Index rowId, Index colId) const { - return m_expression.coeff(row, col); + return m_expression.coeff(rowId, colId); } - inline Scalar& coeffRef(Index row, Index col) + inline Scalar& coeffRef(Index rowId, Index colId) { - return m_expression.const_cast_derived().coeffRef(row, col); + return m_expression.const_cast_derived().coeffRef(rowId, colId); } - inline const Scalar& coeffRef(Index row, Index col) const + inline const Scalar& coeffRef(Index rowId, Index colId) const { - return m_expression.derived().coeffRef(row, col); + return m_expression.derived().coeffRef(rowId, colId); } inline CoeffReturnType coeff(Index index) const @@ -209,15 +209,15 @@ class MatrixWrapper : public MatrixBase > } template - inline const PacketScalar packet(Index row, Index col) const + inline const PacketScalar packet(Index rowId, Index colId) const { - return m_expression.template packet(row, col); + return m_expression.template packet(rowId, colId); } template - inline void writePacket(Index row, Index col, const PacketScalar& x) + inline void writePacket(Index rowId, Index colId, const PacketScalar& val) { - m_expression.const_cast_derived().template writePacket(row, col, x); + m_expression.const_cast_derived().template writePacket(rowId, colId, val); } template @@ -227,9 +227,9 @@ class MatrixWrapper : public MatrixBase > } template - inline void writePacket(Index index, const PacketScalar& x) + inline void writePacket(Index index, const PacketScalar& val) { - m_expression.const_cast_derived().template writePacket(index, x); + m_expression.const_cast_derived().template writePacket(index, val); } const typename internal::remove_all::type& diff --git a/eigenlib/Eigen/src/Core/Assign.h b/eigenlib/Eigen/src/Core/Assign.h index cd29a88f..1dccc2f4 100644 --- a/eigenlib/Eigen/src/Core/Assign.h +++ b/eigenlib/Eigen/src/Core/Assign.h @@ -155,7 +155,7 @@ struct assign_DefaultTraversal_CompleteUnrolling template struct assign_DefaultTraversal_InnerUnrolling { - static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, int outer) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer) { dst.copyCoeffByOuterInner(outer, Index, src); assign_DefaultTraversal_InnerUnrolling::run(dst, src, outer); @@ -165,7 +165,7 @@ struct assign_DefaultTraversal_InnerUnrolling template struct assign_DefaultTraversal_InnerUnrolling { - static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, int) {} + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {} }; /*********************** @@ -218,7 +218,7 @@ struct assign_innervec_CompleteUnrolling template struct assign_innervec_InnerUnrolling { - static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, int outer) + static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer) { dst.template copyPacketByOuterInner(outer, Index, src); assign_innervec_InnerUnrolling struct assign_innervec_InnerUnrolling { - static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, int) {} + static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {} }; /*************************************************************************** @@ -507,19 +507,19 @@ EIGEN_STRONG_INLINE Derived& DenseBase namespace internal { template + bool EvalBeforeAssigning = (int(internal::traits::Flags) & EvalBeforeAssigningBit) != 0, + bool NeedToTranspose = ((int(Derived::RowsAtCompileTime) == 1 && int(OtherDerived::ColsAtCompileTime) == 1) + | // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&". + // revert to || as soon as not needed anymore. + (int(Derived::ColsAtCompileTime) == 1 && int(OtherDerived::RowsAtCompileTime) == 1)) + && int(Derived::SizeAtCompileTime) != 1> struct assign_selector; template struct assign_selector { static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); } + template + static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { other.evalTo(dst); return dst; } }; template struct assign_selector { @@ -528,6 +528,8 @@ struct assign_selector { template struct assign_selector { static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); } + template + static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { Transpose dstTrans(dst); other.evalTo(dstTrans); return dst; } }; template struct assign_selector { @@ -566,16 +568,14 @@ template template EIGEN_STRONG_INLINE Derived& MatrixBase::operator=(const EigenBase& other) { - other.derived().evalTo(derived()); - return derived(); + return internal::assign_selector::evalTo(derived(), other.derived()); } template template EIGEN_STRONG_INLINE Derived& MatrixBase::operator=(const ReturnByValue& other) { - other.evalTo(derived()); - return derived(); + return internal::assign_selector::evalTo(derived(), other.derived()); } } // end namespace Eigen diff --git a/eigenlib/Eigen/src/Core/Assign_MKL.h b/eigenlib/Eigen/src/Core/Assign_MKL.h index 428c6367..7772951b 100644 --- a/eigenlib/Eigen/src/Core/Assign_MKL.h +++ b/eigenlib/Eigen/src/Core/Assign_MKL.h @@ -210,7 +210,7 @@ EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr) // The vm*powx functions are not avaibale in the windows version of MKL. -#ifdef _WIN32 +#ifndef _WIN32 EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmspowx_, float, float) EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmdpowx_, double, double) EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmcpowx_, scomplex, MKL_Complex8) diff --git a/eigenlib/Eigen/src/Core/Block.h b/eigenlib/Eigen/src/Core/Block.h index 5f29cb3d..358b3188 100644 --- a/eigenlib/Eigen/src/Core/Block.h +++ b/eigenlib/Eigen/src/Core/Block.h @@ -21,7 +21,6 @@ namespace Eigen { * \param XprType the type of the expression in which we are taking a block * \param BlockRows the number of rows of the block we are taking at compile time (optional) * \param BlockCols the number of columns of the block we are taking at compile time (optional) - * \param _DirectAccessStatus \internal used for partial specialization * * This class represents an expression of either a fixed-size or dynamic-size block. It is the return * type of DenseBase::block(Index,Index,Index,Index) and DenseBase::block(Index,Index) and @@ -47,8 +46,8 @@ namespace Eigen { */ namespace internal { -template -struct traits > : traits +template +struct traits > : traits { typedef typename traits::Scalar Scalar; typedef typename traits::StorageKind StorageKind; @@ -92,21 +91,92 @@ struct traits Flags = Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit }; }; -} -template class Block - : public internal::dense_xpr_base >::type +template::ret> class BlockImpl_dense; + +} // end namespace internal + +template class BlockImpl; + +template class Block + : public BlockImpl::StorageKind> { + typedef BlockImpl::StorageKind> Impl; + public: + //typedef typename Impl::Base Base; + typedef Impl Base; + EIGEN_GENERIC_PUBLIC_INTERFACE(Block) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block) + + /** Column or Row constructor + */ + inline Block(XprType& xpr, Index i) : Impl(xpr,i) + { + eigen_assert( (i>=0) && ( + ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i= 0 && BlockRows >= 1 && a_startRow + BlockRows <= xpr.rows() + && a_startCol >= 0 && BlockCols >= 1 && a_startCol + BlockCols <= xpr.cols()); + } + + /** Dynamic-size constructor + */ + inline Block(XprType& xpr, + Index a_startRow, Index a_startCol, + Index blockRows, Index blockCols) + : Impl(xpr, a_startRow, a_startCol, blockRows, blockCols) + { + eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows) + && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols)); + eigen_assert(a_startRow >= 0 && blockRows >= 0 && a_startRow <= xpr.rows() - blockRows + && a_startCol >= 0 && blockCols >= 0 && a_startCol <= xpr.cols() - blockCols); + } +}; + +// The generic default implementation for dense block simplu forward to the internal::BlockImpl_dense +// that must be specialized for direct and non-direct access... +template +class BlockImpl + : public internal::BlockImpl_dense +{ + typedef internal::BlockImpl_dense Impl; + typedef typename XprType::Index Index; + public: + typedef Impl Base; + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl) + inline BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {} + inline BlockImpl(XprType& xpr, Index a_startRow, Index a_startCol) : Impl(xpr, a_startRow, a_startCol) {} + inline BlockImpl(XprType& xpr, Index a_startRow, Index a_startCol, Index blockRows, Index blockCols) + : Impl(xpr, a_startRow, a_startCol, blockRows, blockCols) {} +}; + +namespace internal { + +/** \internal Internal implementation of dense Blocks in the general case. */ +template class BlockImpl_dense + : public internal::dense_xpr_base >::type +{ + typedef Block BlockType; public: - typedef typename internal::dense_xpr_base::type Base; - EIGEN_DENSE_PUBLIC_INTERFACE(Block) + typedef typename internal::dense_xpr_base::type Base; + EIGEN_DENSE_PUBLIC_INTERFACE(BlockType) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense) class InnerIterator; /** Column or Row constructor */ - inline Block(XprType& xpr, Index i) + inline BlockImpl_dense(XprType& xpr, Index i) : m_xpr(xpr), // It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime, // and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1, @@ -116,58 +186,43 @@ template=0) && ( - ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i= 0 && BlockRows >= 1 && startRow + BlockRows <= xpr.rows() - && startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= xpr.cols()); - } + inline BlockImpl_dense(XprType& xpr, Index a_startRow, Index a_startCol) + : m_xpr(xpr), m_startRow(a_startRow), m_startCol(a_startCol), + m_blockRows(BlockRows), m_blockCols(BlockCols) + {} /** Dynamic-size constructor */ - inline Block(XprType& xpr, - Index startRow, Index startCol, + inline BlockImpl_dense(XprType& xpr, + Index a_startRow, Index a_startCol, Index blockRows, Index blockCols) - : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol), - m_blockRows(blockRows), m_blockCols(blockCols) - { - eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows) - && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols)); - eigen_assert(startRow >= 0 && blockRows >= 0 && startRow + blockRows <= xpr.rows() - && startCol >= 0 && blockCols >= 0 && startCol + blockCols <= xpr.cols()); - } - - EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block) + : m_xpr(xpr), m_startRow(a_startRow), m_startCol(a_startCol), + m_blockRows(blockRows), m_blockCols(blockCols) + {} inline Index rows() const { return m_blockRows.value(); } inline Index cols() const { return m_blockCols.value(); } - inline Scalar& coeffRef(Index row, Index col) + inline Scalar& coeffRef(Index rowId, Index colId) { EIGEN_STATIC_ASSERT_LVALUE(XprType) return m_xpr.const_cast_derived() - .coeffRef(row + m_startRow.value(), col + m_startCol.value()); + .coeffRef(rowId + m_startRow.value(), colId + m_startCol.value()); } - inline const Scalar& coeffRef(Index row, Index col) const + inline const Scalar& coeffRef(Index rowId, Index colId) const { return m_xpr.derived() - .coeffRef(row + m_startRow.value(), col + m_startCol.value()); + .coeffRef(rowId + m_startRow.value(), colId + m_startCol.value()); } - EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const + EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const { - return m_xpr.coeff(row + m_startRow.value(), col + m_startCol.value()); + return m_xpr.coeff(rowId + m_startRow.value(), colId + m_startCol.value()); } inline Scalar& coeffRef(Index index) @@ -193,17 +248,17 @@ template - inline PacketScalar packet(Index row, Index col) const + inline PacketScalar packet(Index rowId, Index colId) const { return m_xpr.template packet - (row + m_startRow.value(), col + m_startCol.value()); + (rowId + m_startRow.value(), colId + m_startCol.value()); } template - inline void writePacket(Index row, Index col, const PacketScalar& x) + inline void writePacket(Index rowId, Index colId, const PacketScalar& val) { m_xpr.const_cast_derived().template writePacket - (row + m_startRow.value(), col + m_startCol.value(), x); + (rowId + m_startRow.value(), colId + m_startCol.value(), val); } template @@ -215,11 +270,11 @@ template - inline void writePacket(Index index, const PacketScalar& x) + inline void writePacket(Index index, const PacketScalar& val) { m_xpr.const_cast_derived().template writePacket (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), - m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), x); + m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), val); } #ifdef EIGEN_PARSED_BY_DOXYGEN @@ -253,21 +308,21 @@ template m_blockCols; }; -/** \internal */ +/** \internal Internal implementation of dense Blocks in the direct access case.*/ template -class Block - : public MapBase > +class BlockImpl_dense + : public MapBase > { + typedef Block BlockType; public: - typedef MapBase Base; - EIGEN_DENSE_PUBLIC_INTERFACE(Block) - - EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block) + typedef MapBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(BlockType) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense) /** Column or Row constructor */ - inline Block(XprType& xpr, Index i) + inline BlockImpl_dense(XprType& xpr, Index i) : Base(internal::const_cast_ptr(&xpr.coeffRef( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0, (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)), @@ -275,34 +330,25 @@ class Block BlockCols==1 ? 1 : xpr.cols()), m_xpr(xpr) { - eigen_assert( (i>=0) && ( - ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i= 0 && BlockRows >= 1 && startRow + BlockRows <= xpr.rows() - && startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= xpr.cols()); init(); } /** Dynamic-size constructor */ - inline Block(XprType& xpr, + inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols) : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol)), blockRows, blockCols), m_xpr(xpr) { - eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows) - && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols)); - eigen_assert(startRow >= 0 && blockRows >= 0 && startRow + blockRows <= xpr.rows() - && startCol >= 0 && blockCols >= 0 && startCol + blockCols <= xpr.cols()); init(); } @@ -314,7 +360,7 @@ class Block /** \sa MapBase::innerStride() */ inline Index innerStride() const { - return internal::traits::HasSameStorageOrderAsXprType + return internal::traits::HasSameStorageOrderAsXprType ? m_xpr.innerStride() : m_xpr.outerStride(); } @@ -333,7 +379,7 @@ class Block #ifndef EIGEN_PARSED_BY_DOXYGEN /** \internal used by allowAligned() */ - inline Block(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols) + inline BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols) : Base(data, blockRows, blockCols), m_xpr(xpr) { init(); @@ -343,7 +389,7 @@ class Block protected: void init() { - m_outerStride = internal::traits::HasSameStorageOrderAsXprType + m_outerStride = internal::traits::HasSameStorageOrderAsXprType ? m_xpr.outerStride() : m_xpr.innerStride(); } @@ -352,6 +398,8 @@ class Block Index m_outerStride; }; +} // end namespace internal + } // end namespace Eigen #endif // EIGEN_BLOCK_H diff --git a/eigenlib/Eigen/src/Core/BooleanRedux.h b/eigenlib/Eigen/src/Core/BooleanRedux.h index 57efd8e6..be9f48a8 100644 --- a/eigenlib/Eigen/src/Core/BooleanRedux.h +++ b/eigenlib/Eigen/src/Core/BooleanRedux.h @@ -29,9 +29,9 @@ struct all_unroller }; template -struct all_unroller +struct all_unroller { - static inline bool run(const Derived &mat) { return mat.coeff(0, 0); } + static inline bool run(const Derived &/*mat*/) { return true; } }; template @@ -55,9 +55,9 @@ struct any_unroller }; template -struct any_unroller +struct any_unroller { - static inline bool run(const Derived &mat) { return mat.coeff(0, 0); } + static inline bool run(const Derived & /*mat*/) { return false; } }; template @@ -85,9 +85,7 @@ inline bool DenseBase::all() const && SizeAtCompileTime * (CoeffReadCost + NumTraits::AddCost) <= EIGEN_UNROLLING_LIMIT }; if(unroll) - return internal::all_unroller::run(derived()); + return internal::all_unroller::run(derived()); else { for(Index j = 0; j < cols(); ++j) @@ -111,9 +109,7 @@ inline bool DenseBase::any() const && SizeAtCompileTime * (CoeffReadCost + NumTraits::AddCost) <= EIGEN_UNROLLING_LIMIT }; if(unroll) - return internal::any_unroller::run(derived()); + return internal::any_unroller::run(derived()); else { for(Index j = 0; j < cols(); ++j) @@ -133,6 +129,26 @@ inline typename DenseBase::Index DenseBase::count() const return derived().template cast().template cast().sum(); } +/** \returns true is \c *this contains at least one Not A Number (NaN). + * + * \sa allFinite() + */ +template +inline bool DenseBase::hasNaN() const +{ + return !((derived().array()==derived().array()).all()); +} + +/** \returns true if \c *this contains only finite numbers, i.e., no NaN and no +/-INF values. + * + * \sa hasNaN() + */ +template +inline bool DenseBase::allFinite() const +{ + return !((derived()-derived()).hasNaN()); +} + } // end namespace Eigen #endif // EIGEN_ALLANDANY_H diff --git a/eigenlib/Eigen/src/Core/CommaInitializer.h b/eigenlib/Eigen/src/Core/CommaInitializer.h index f20c1774..a96867af 100644 --- a/eigenlib/Eigen/src/Core/CommaInitializer.h +++ b/eigenlib/Eigen/src/Core/CommaInitializer.h @@ -118,6 +118,8 @@ struct CommaInitializer * * Example: \include MatrixBase_set.cpp * Output: \verbinclude MatrixBase_set.out + * + * \note According the c++ standard, the argument expressions of this comma initializer are evaluated in arbitrary order. * * \sa CommaInitializer::finished(), class CommaInitializer */ diff --git a/eigenlib/Eigen/src/SparseCore/CoreIterators.h b/eigenlib/Eigen/src/Core/CoreIterators.h similarity index 100% rename from eigenlib/Eigen/src/SparseCore/CoreIterators.h rename to eigenlib/Eigen/src/Core/CoreIterators.h diff --git a/eigenlib/Eigen/src/Core/CwiseBinaryOp.h b/eigenlib/Eigen/src/Core/CwiseBinaryOp.h index 1b93af31..586f77aa 100644 --- a/eigenlib/Eigen/src/Core/CwiseBinaryOp.h +++ b/eigenlib/Eigen/src/Core/CwiseBinaryOp.h @@ -94,8 +94,8 @@ struct traits > // So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to // add together a float matrix and a double matrix. #define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \ - EIGEN_STATIC_ASSERT((internal::functor_allows_mixing_real_and_complex::ret \ - ? int(internal::is_same::Real, typename NumTraits::Real>::value) \ + EIGEN_STATIC_ASSERT((internal::functor_is_product_like::ret \ + ? int(internal::scalar_product_traits::Defined) \ : int(internal::is_same::value)), \ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) @@ -122,13 +122,13 @@ class CwiseBinaryOp : internal::no_assignment_operator, typedef typename internal::remove_reference::type _LhsNested; typedef typename internal::remove_reference::type _RhsNested; - EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& lhs, const Rhs& rhs, const BinaryOp& func = BinaryOp()) - : m_lhs(lhs), m_rhs(rhs), m_functor(func) + EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs, const BinaryOp& func = BinaryOp()) + : m_lhs(aLhs), m_rhs(aRhs), m_functor(func) { EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar); // require the sizes to match EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs) - eigen_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols()); + eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols()); } EIGEN_STRONG_INLINE Index rows() const { @@ -169,17 +169,17 @@ class CwiseBinaryOpImpl typedef typename internal::dense_xpr_base >::type Base; EIGEN_DENSE_PUBLIC_INTERFACE( Derived ) - EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const + EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const { - return derived().functor()(derived().lhs().coeff(row, col), - derived().rhs().coeff(row, col)); + return derived().functor()(derived().lhs().coeff(rowId, colId), + derived().rhs().coeff(rowId, colId)); } template - EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const + EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const { - return derived().functor().packetOp(derived().lhs().template packet(row, col), - derived().rhs().template packet(row, col)); + return derived().functor().packetOp(derived().lhs().template packet(rowId, colId), + derived().rhs().template packet(rowId, colId)); } EIGEN_STRONG_INLINE const Scalar coeff(Index index) const diff --git a/eigenlib/Eigen/src/Core/CwiseNullaryOp.h b/eigenlib/Eigen/src/Core/CwiseNullaryOp.h index 2635a62b..a93bab2d 100644 --- a/eigenlib/Eigen/src/Core/CwiseNullaryOp.h +++ b/eigenlib/Eigen/src/Core/CwiseNullaryOp.h @@ -54,27 +54,27 @@ class CwiseNullaryOp : internal::no_assignment_operator, typedef typename internal::dense_xpr_base::type Base; EIGEN_DENSE_PUBLIC_INTERFACE(CwiseNullaryOp) - CwiseNullaryOp(Index rows, Index cols, const NullaryOp& func = NullaryOp()) - : m_rows(rows), m_cols(cols), m_functor(func) + CwiseNullaryOp(Index nbRows, Index nbCols, const NullaryOp& func = NullaryOp()) + : m_rows(nbRows), m_cols(nbCols), m_functor(func) { - eigen_assert(rows >= 0 - && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) - && cols >= 0 - && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)); + eigen_assert(nbRows >= 0 + && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == nbRows) + && nbCols >= 0 + && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == nbCols)); } EIGEN_STRONG_INLINE Index rows() const { return m_rows.value(); } EIGEN_STRONG_INLINE Index cols() const { return m_cols.value(); } - EIGEN_STRONG_INLINE const Scalar coeff(Index rows, Index cols) const + EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const { - return m_functor(rows, cols); + return m_functor(rowId, colId); } template - EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const + EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const { - return m_functor.packetOp(row, col); + return m_functor.packetOp(rowId, colId); } EIGEN_STRONG_INLINE const Scalar coeff(Index index) const @@ -163,11 +163,11 @@ DenseBase::NullaryExpr(const CustomNullaryOp& func) /** \returns an expression of a constant matrix of value \a value * - * The parameters \a rows and \a cols are the number of rows and of columns of + * The parameters \a nbRows and \a nbCols are the number of rows and of columns of * the returned matrix. Must be compatible with this DenseBase type. * * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, - * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used + * it is redundant to pass \a nbRows and \a nbCols as arguments, so Zero() should be used * instead. * * The template parameter \a CustomNullaryOp is the type of the functor. @@ -176,9 +176,9 @@ DenseBase::NullaryExpr(const CustomNullaryOp& func) */ template EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType -DenseBase::Constant(Index rows, Index cols, const Scalar& value) +DenseBase::Constant(Index nbRows, Index nbCols, const Scalar& value) { - return DenseBase::NullaryExpr(rows, cols, internal::scalar_constant_op(value)); + return DenseBase::NullaryExpr(nbRows, nbCols, internal::scalar_constant_op(value)); } /** \returns an expression of a constant matrix of value \a value @@ -292,14 +292,14 @@ DenseBase::LinSpaced(const Scalar& low, const Scalar& high) return DenseBase::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op(low,high,Derived::SizeAtCompileTime)); } -/** \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */ +/** \returns true if all coefficients in this matrix are approximately equal to \a val, to within precision \a prec */ template bool DenseBase::isApproxToConstant -(const Scalar& value, RealScalar prec) const +(const Scalar& val, const RealScalar& prec) const { for(Index j = 0; j < cols(); ++j) for(Index i = 0; i < rows(); ++i) - if(!internal::isApprox(this->coeff(i, j), value, prec)) + if(!internal::isApprox(this->coeff(i, j), val, prec)) return false; return true; } @@ -309,19 +309,19 @@ bool DenseBase::isApproxToConstant * \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */ template bool DenseBase::isConstant -(const Scalar& value, RealScalar prec) const +(const Scalar& val, const RealScalar& prec) const { - return isApproxToConstant(value, prec); + return isApproxToConstant(val, prec); } -/** Alias for setConstant(): sets all coefficients in this expression to \a value. +/** Alias for setConstant(): sets all coefficients in this expression to \a val. * * \sa setConstant(), Constant(), class CwiseNullaryOp */ template -EIGEN_STRONG_INLINE void DenseBase::fill(const Scalar& value) +EIGEN_STRONG_INLINE void DenseBase::fill(const Scalar& val) { - setConstant(value); + setConstant(val); } /** Sets all coefficients in this expression to \a value. @@ -329,9 +329,9 @@ EIGEN_STRONG_INLINE void DenseBase::fill(const Scalar& value) * \sa fill(), setConstant(Index,const Scalar&), setConstant(Index,Index,const Scalar&), setZero(), setOnes(), Constant(), class CwiseNullaryOp, setZero(), setOnes() */ template -EIGEN_STRONG_INLINE Derived& DenseBase::setConstant(const Scalar& value) +EIGEN_STRONG_INLINE Derived& DenseBase::setConstant(const Scalar& val) { - return derived() = Constant(rows(), cols(), value); + return derived() = Constant(rows(), cols(), val); } /** Resizes to the given \a size, and sets all coefficients in this expression to the given \a value. @@ -345,17 +345,17 @@ EIGEN_STRONG_INLINE Derived& DenseBase::setConstant(const Scalar& value */ template EIGEN_STRONG_INLINE Derived& -PlainObjectBase::setConstant(Index size, const Scalar& value) +PlainObjectBase::setConstant(Index size, const Scalar& val) { resize(size); - return setConstant(value); + return setConstant(val); } /** Resizes to the given size, and sets all coefficients in this expression to the given \a value. * - * \param rows the new number of rows - * \param cols the new number of columns - * \param value the value to which all coefficients are set + * \param nbRows the new number of rows + * \param nbCols the new number of columns + * \param val the value to which all coefficients are set * * Example: \include Matrix_setConstant_int_int.cpp * Output: \verbinclude Matrix_setConstant_int_int.out @@ -364,10 +364,10 @@ PlainObjectBase::setConstant(Index size, const Scalar& value) */ template EIGEN_STRONG_INLINE Derived& -PlainObjectBase::setConstant(Index rows, Index cols, const Scalar& value) +PlainObjectBase::setConstant(Index nbRows, Index nbCols, const Scalar& val) { - resize(rows, cols); - return setConstant(value); + resize(nbRows, nbCols); + return setConstant(val); } /** @@ -384,10 +384,10 @@ PlainObjectBase::setConstant(Index rows, Index cols, const Scalar& valu * \sa CwiseNullaryOp */ template -EIGEN_STRONG_INLINE Derived& DenseBase::setLinSpaced(Index size, const Scalar& low, const Scalar& high) +EIGEN_STRONG_INLINE Derived& DenseBase::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return derived() = Derived::NullaryExpr(size, internal::linspaced_op(low,high,size)); + return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op(low,high,newSize)); } /** @@ -425,9 +425,9 @@ EIGEN_STRONG_INLINE Derived& DenseBase::setLinSpaced(const Scalar& low, */ template EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType -DenseBase::Zero(Index rows, Index cols) +DenseBase::Zero(Index nbRows, Index nbCols) { - return Constant(rows, cols, Scalar(0)); + return Constant(nbRows, nbCols, Scalar(0)); } /** \returns an expression of a zero vector. @@ -479,7 +479,7 @@ DenseBase::Zero() * \sa class CwiseNullaryOp, Zero() */ template -bool DenseBase::isZero(RealScalar prec) const +bool DenseBase::isZero(const RealScalar& prec) const { for(Index j = 0; j < cols(); ++j) for(Index i = 0; i < rows(); ++i) @@ -512,16 +512,16 @@ EIGEN_STRONG_INLINE Derived& DenseBase::setZero() */ template EIGEN_STRONG_INLINE Derived& -PlainObjectBase::setZero(Index size) +PlainObjectBase::setZero(Index newSize) { - resize(size); + resize(newSize); return setConstant(Scalar(0)); } /** Resizes to the given size, and sets all coefficients in this expression to zero. * - * \param rows the new number of rows - * \param cols the new number of columns + * \param nbRows the new number of rows + * \param nbCols the new number of columns * * Example: \include Matrix_setZero_int_int.cpp * Output: \verbinclude Matrix_setZero_int_int.out @@ -530,9 +530,9 @@ PlainObjectBase::setZero(Index size) */ template EIGEN_STRONG_INLINE Derived& -PlainObjectBase::setZero(Index rows, Index cols) +PlainObjectBase::setZero(Index nbRows, Index nbCols) { - resize(rows, cols); + resize(nbRows, nbCols); return setConstant(Scalar(0)); } @@ -540,7 +540,7 @@ PlainObjectBase::setZero(Index rows, Index cols) /** \returns an expression of a matrix where all coefficients equal one. * - * The parameters \a rows and \a cols are the number of rows and of columns of + * The parameters \a nbRows and \a nbCols are the number of rows and of columns of * the returned matrix. Must be compatible with this MatrixBase type. * * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, @@ -554,14 +554,14 @@ PlainObjectBase::setZero(Index rows, Index cols) */ template EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType -DenseBase::Ones(Index rows, Index cols) +DenseBase::Ones(Index nbRows, Index nbCols) { - return Constant(rows, cols, Scalar(1)); + return Constant(nbRows, nbCols, Scalar(1)); } /** \returns an expression of a vector where all coefficients equal one. * - * The parameter \a size is the size of the returned vector. + * The parameter \a newSize is the size of the returned vector. * Must be compatible with this MatrixBase type. * * \only_for_vectors @@ -577,9 +577,9 @@ DenseBase::Ones(Index rows, Index cols) */ template EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType -DenseBase::Ones(Index size) +DenseBase::Ones(Index newSize) { - return Constant(size, Scalar(1)); + return Constant(newSize, Scalar(1)); } /** \returns an expression of a fixed-size matrix or vector where all coefficients equal one. @@ -609,7 +609,7 @@ DenseBase::Ones() */ template bool DenseBase::isOnes -(RealScalar prec) const +(const RealScalar& prec) const { return isApproxToConstant(Scalar(1), prec); } @@ -627,7 +627,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase::setOnes() return setConstant(Scalar(1)); } -/** Resizes to the given \a size, and sets all coefficients in this expression to one. +/** Resizes to the given \a newSize, and sets all coefficients in this expression to one. * * \only_for_vectors * @@ -638,16 +638,16 @@ EIGEN_STRONG_INLINE Derived& DenseBase::setOnes() */ template EIGEN_STRONG_INLINE Derived& -PlainObjectBase::setOnes(Index size) +PlainObjectBase::setOnes(Index newSize) { - resize(size); + resize(newSize); return setConstant(Scalar(1)); } /** Resizes to the given size, and sets all coefficients in this expression to one. * - * \param rows the new number of rows - * \param cols the new number of columns + * \param nbRows the new number of rows + * \param nbCols the new number of columns * * Example: \include Matrix_setOnes_int_int.cpp * Output: \verbinclude Matrix_setOnes_int_int.out @@ -656,9 +656,9 @@ PlainObjectBase::setOnes(Index size) */ template EIGEN_STRONG_INLINE Derived& -PlainObjectBase::setOnes(Index rows, Index cols) +PlainObjectBase::setOnes(Index nbRows, Index nbCols) { - resize(rows, cols); + resize(nbRows, nbCols); return setConstant(Scalar(1)); } @@ -666,7 +666,7 @@ PlainObjectBase::setOnes(Index rows, Index cols) /** \returns an expression of the identity matrix (not necessarily square). * - * The parameters \a rows and \a cols are the number of rows and of columns of + * The parameters \a nbRows and \a nbCols are the number of rows and of columns of * the returned matrix. Must be compatible with this MatrixBase type. * * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, @@ -680,9 +680,9 @@ PlainObjectBase::setOnes(Index rows, Index cols) */ template EIGEN_STRONG_INLINE const typename MatrixBase::IdentityReturnType -MatrixBase::Identity(Index rows, Index cols) +MatrixBase::Identity(Index nbRows, Index nbCols) { - return DenseBase::NullaryExpr(rows, cols, internal::scalar_identity_op()); + return DenseBase::NullaryExpr(nbRows, nbCols, internal::scalar_identity_op()); } /** \returns an expression of the identity matrix (not necessarily square). @@ -714,7 +714,7 @@ MatrixBase::Identity() */ template bool MatrixBase::isIdentity -(RealScalar prec) const +(const RealScalar& prec) const { for(Index j = 0; j < cols(); ++j) { @@ -776,8 +776,8 @@ EIGEN_STRONG_INLINE Derived& MatrixBase::setIdentity() /** \brief Resizes to the given size, and writes the identity expression (not necessarily square) into *this. * - * \param rows the new number of rows - * \param cols the new number of columns + * \param nbRows the new number of rows + * \param nbCols the new number of columns * * Example: \include Matrix_setIdentity_int_int.cpp * Output: \verbinclude Matrix_setIdentity_int_int.out @@ -785,9 +785,9 @@ EIGEN_STRONG_INLINE Derived& MatrixBase::setIdentity() * \sa MatrixBase::setIdentity(), class CwiseNullaryOp, MatrixBase::Identity() */ template -EIGEN_STRONG_INLINE Derived& MatrixBase::setIdentity(Index rows, Index cols) +EIGEN_STRONG_INLINE Derived& MatrixBase::setIdentity(Index nbRows, Index nbCols) { - derived().resize(rows, cols); + derived().resize(nbRows, nbCols); return setIdentity(); } @@ -798,10 +798,10 @@ EIGEN_STRONG_INLINE Derived& MatrixBase::setIdentity(Index rows, Index * \sa MatrixBase::Unit(Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() */ template -EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::Unit(Index size, Index i) +EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::Unit(Index newSize, Index i) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - return BasisReturnType(SquareMatrixType::Identity(size,size), i); + return BasisReturnType(SquareMatrixType::Identity(newSize,newSize), i); } /** \returns an expression of the i-th unit (basis) vector. diff --git a/eigenlib/Eigen/src/Core/CwiseUnaryOp.h b/eigenlib/Eigen/src/Core/CwiseUnaryOp.h index 063355ae..f2de749f 100644 --- a/eigenlib/Eigen/src/Core/CwiseUnaryOp.h +++ b/eigenlib/Eigen/src/Core/CwiseUnaryOp.h @@ -98,15 +98,15 @@ class CwiseUnaryOpImpl typedef typename internal::dense_xpr_base >::type Base; EIGEN_DENSE_PUBLIC_INTERFACE(Derived) - EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const + EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const { - return derived().functor()(derived().nestedExpression().coeff(row, col)); + return derived().functor()(derived().nestedExpression().coeff(rowId, colId)); } template - EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const + EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const { - return derived().functor().packetOp(derived().nestedExpression().template packet(row, col)); + return derived().functor().packetOp(derived().nestedExpression().template packet(rowId, colId)); } EIGEN_STRONG_INLINE const Scalar coeff(Index index) const diff --git a/eigenlib/Eigen/src/Core/CwiseUnaryView.h b/eigenlib/Eigen/src/Core/CwiseUnaryView.h index 66f73a95..b2638d32 100644 --- a/eigenlib/Eigen/src/Core/CwiseUnaryView.h +++ b/eigenlib/Eigen/src/Core/CwiseUnaryView.h @@ -44,9 +44,10 @@ struct traits > // "error: no integral type can represent all of the enumerator values InnerStrideAtCompileTime = MatrixTypeInnerStride == Dynamic ? int(Dynamic) - : int(MatrixTypeInnerStride) - * int(sizeof(typename traits::Scalar) / sizeof(Scalar)), - OuterStrideAtCompileTime = outer_stride_at_compile_time::ret + : int(MatrixTypeInnerStride) * int(sizeof(typename traits::Scalar) / sizeof(Scalar)), + OuterStrideAtCompileTime = outer_stride_at_compile_time::ret == Dynamic + ? int(Dynamic) + : outer_stride_at_compile_time::ret * int(sizeof(typename traits::Scalar) / sizeof(Scalar)) }; }; } @@ -55,8 +56,7 @@ template class CwiseUnaryViewImpl; template -class CwiseUnaryView : internal::no_assignment_operator, - public CwiseUnaryViewImpl::StorageKind> +class CwiseUnaryView : public CwiseUnaryViewImpl::StorageKind> { public: @@ -98,6 +98,10 @@ class CwiseUnaryViewImpl typedef typename internal::dense_xpr_base< CwiseUnaryView >::type Base; EIGEN_DENSE_PUBLIC_INTERFACE(Derived) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl) + + inline Scalar* data() { return &coeffRef(0); } + inline const Scalar* data() const { return &coeff(0); } inline Index innerStride() const { @@ -106,7 +110,7 @@ class CwiseUnaryViewImpl inline Index outerStride() const { - return derived().nestedExpression().outerStride(); + return derived().nestedExpression().outerStride() * sizeof(typename internal::traits::Scalar) / sizeof(Scalar); } EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const diff --git a/eigenlib/Eigen/src/Core/DenseBase.h b/eigenlib/Eigen/src/Core/DenseBase.h index 1cc0314e..c5800f6c 100644 --- a/eigenlib/Eigen/src/Core/DenseBase.h +++ b/eigenlib/Eigen/src/Core/DenseBase.h @@ -13,6 +13,16 @@ namespace Eigen { +namespace internal { + +// The index type defined by EIGEN_DEFAULT_DENSE_INDEX_TYPE must be a signed type. +// This dummy function simply aims at checking that at compile time. +static inline void check_DenseIndex_is_signed() { + EIGEN_STATIC_ASSERT(NumTraits::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE); +} + +} // end namespace internal + /** \class DenseBase * \ingroup Core_Module * @@ -204,21 +214,21 @@ template class DenseBase * Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does * nothing else. */ - void resize(Index size) + void resize(Index newSize) { - EIGEN_ONLY_USED_FOR_DEBUG(size); - eigen_assert(size == this->size() + EIGEN_ONLY_USED_FOR_DEBUG(newSize); + eigen_assert(newSize == this->size() && "DenseBase::resize() does not actually allow to resize."); } /** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are * Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does * nothing else. */ - void resize(Index rows, Index cols) + void resize(Index nbRows, Index nbCols) { - EIGEN_ONLY_USED_FOR_DEBUG(rows); - EIGEN_ONLY_USED_FOR_DEBUG(cols); - eigen_assert(rows == this->rows() && cols == this->cols() + EIGEN_ONLY_USED_FOR_DEBUG(nbRows); + EIGEN_ONLY_USED_FOR_DEBUG(nbCols); + eigen_assert(nbRows == this->rows() && nbCols == this->cols() && "DenseBase::resize() does not actually allow to resize."); } @@ -271,7 +281,7 @@ template class DenseBase CommaInitializer operator<< (const DenseBase& other); Eigen::Transpose transpose(); - typedef const Transpose ConstTransposeReturnType; + typedef typename internal::add_const >::type ConstTransposeReturnType; ConstTransposeReturnType transpose() const; void transposeInPlace(); #ifndef EIGEN_NO_DEBUG @@ -281,29 +291,6 @@ template class DenseBase public: #endif - typedef VectorBlock SegmentReturnType; - typedef const VectorBlock ConstSegmentReturnType; - template struct FixedSegmentReturnType { typedef VectorBlock Type; }; - template struct ConstFixedSegmentReturnType { typedef const VectorBlock Type; }; - - // Note: The "DenseBase::" prefixes are added to help MSVC9 to match these declarations with the later implementations. - SegmentReturnType segment(Index start, Index size); - typename DenseBase::ConstSegmentReturnType segment(Index start, Index size) const; - - SegmentReturnType head(Index size); - typename DenseBase::ConstSegmentReturnType head(Index size) const; - - SegmentReturnType tail(Index size); - typename DenseBase::ConstSegmentReturnType tail(Index size) const; - - template typename FixedSegmentReturnType::Type head(); - template typename ConstFixedSegmentReturnType::Type head() const; - - template typename FixedSegmentReturnType::Type tail(); - template typename ConstFixedSegmentReturnType::Type tail() const; - - template typename FixedSegmentReturnType::Type segment(Index start); - template typename ConstFixedSegmentReturnType::Type segment(Index start) const; static const ConstantReturnType Constant(Index rows, Index cols, const Scalar& value); @@ -348,17 +335,20 @@ template class DenseBase template bool isApprox(const DenseBase& other, - RealScalar prec = NumTraits::dummy_precision()) const; + const RealScalar& prec = NumTraits::dummy_precision()) const; bool isMuchSmallerThan(const RealScalar& other, - RealScalar prec = NumTraits::dummy_precision()) const; + const RealScalar& prec = NumTraits::dummy_precision()) const; template bool isMuchSmallerThan(const DenseBase& other, - RealScalar prec = NumTraits::dummy_precision()) const; + const RealScalar& prec = NumTraits::dummy_precision()) const; - bool isApproxToConstant(const Scalar& value, RealScalar prec = NumTraits::dummy_precision()) const; - bool isConstant(const Scalar& value, RealScalar prec = NumTraits::dummy_precision()) const; - bool isZero(RealScalar prec = NumTraits::dummy_precision()) const; - bool isOnes(RealScalar prec = NumTraits::dummy_precision()) const; + bool isApproxToConstant(const Scalar& value, const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isConstant(const Scalar& value, const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isZero(const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isOnes(const RealScalar& prec = NumTraits::dummy_precision()) const; + + inline bool hasNaN() const; + inline bool allFinite() const; inline Derived& operator*=(const Scalar& other); inline Derived& operator/=(const Scalar& other); @@ -438,8 +428,6 @@ template class DenseBase return derived().coeff(0,0); } -/////////// Array module /////////// - bool all(void) const; bool any(void) const; Index count() const; @@ -465,11 +453,11 @@ template class DenseBase template inline const Select - select(const DenseBase& thenMatrix, typename ThenDerived::Scalar elseScalar) const; + select(const DenseBase& thenMatrix, const typename ThenDerived::Scalar& elseScalar) const; template inline const Select - select(typename ElseDerived::Scalar thenScalar, const DenseBase& elseMatrix) const; + select(const typename ElseDerived::Scalar& thenScalar, const DenseBase& elseMatrix) const; template RealScalar lpNorm() const; diff --git a/eigenlib/Eigen/src/Core/DenseCoeffsBase.h b/eigenlib/Eigen/src/Core/DenseCoeffsBase.h index 72704c2d..3c890f21 100644 --- a/eigenlib/Eigen/src/Core/DenseCoeffsBase.h +++ b/eigenlib/Eigen/src/Core/DenseCoeffsBase.h @@ -427,22 +427,22 @@ class DenseCoeffsBase : public DenseCoeffsBase EIGEN_STRONG_INLINE void writePacket - (Index row, Index col, const typename internal::packet_traits::type& x) + (Index row, Index col, const typename internal::packet_traits::type& val) { eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols()); - derived().template writePacket(row,col,x); + derived().template writePacket(row,col,val); } /** \internal */ template EIGEN_STRONG_INLINE void writePacketByOuterInner - (Index outer, Index inner, const typename internal::packet_traits::type& x) + (Index outer, Index inner, const typename internal::packet_traits::type& val) { writePacket(rowIndexByOuterInner(outer, inner), colIndexByOuterInner(outer, inner), - x); + val); } /** \internal @@ -456,10 +456,10 @@ class DenseCoeffsBase : public DenseCoeffsBase EIGEN_STRONG_INLINE void writePacket - (Index index, const typename internal::packet_traits::type& x) + (Index index, const typename internal::packet_traits::type& val) { eigen_internal_assert(index >= 0 && index < size()); - derived().template writePacket(index,x); + derived().template writePacket(index,val); } #ifndef EIGEN_PARSED_BY_DOXYGEN diff --git a/eigenlib/Eigen/src/Core/DenseStorage.h b/eigenlib/Eigen/src/Core/DenseStorage.h index 1fc2daf2..3e7f9c1b 100644 --- a/eigenlib/Eigen/src/Core/DenseStorage.h +++ b/eigenlib/Eigen/src/Core/DenseStorage.h @@ -35,17 +35,36 @@ template + EIGEN_ALWAYS_INLINE PtrType eigen_unaligned_array_assert_workaround_gcc47(PtrType array) { return array; } + #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \ + eigen_assert((reinterpret_cast(eigen_unaligned_array_assert_workaround_gcc47(array)) & sizemask) == 0 \ + && "this assertion is explained here: " \ + "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \ + " **** READ THIS WEB PAGE !!! ****"); #else #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \ eigen_assert((reinterpret_cast(array) & sizemask) == 0 \ && "this assertion is explained here: " \ - "http://eigen.tuxfamily.org/dox-devel/TopicUnalignedArrayAssert.html" \ + "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \ " **** READ THIS WEB PAGE !!! ****"); #endif @@ -53,8 +72,17 @@ template struct plain_array { EIGEN_USER_ALIGN16 T array[Size]; - plain_array() { EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf) } - plain_array(constructor_without_unaligned_array_assert) {} + + plain_array() + { + EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf); + EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG); + } + + plain_array(constructor_without_unaligned_array_assert) + { + EIGEN_STATIC_ASSERT(Size * sizeof(T) <= 128 * 128 * 8, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG); + } }; template @@ -86,7 +114,7 @@ template class DenseSt { internal::plain_array m_data; public: - inline explicit DenseStorage() {} + inline DenseStorage() {} inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(internal::constructor_without_unaligned_array_assert()) {} inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} @@ -103,7 +131,7 @@ template class DenseSt template class DenseStorage { public: - inline explicit DenseStorage() {} + inline DenseStorage() {} inline DenseStorage(internal::constructor_without_unaligned_array_assert) {} inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {} inline void swap(DenseStorage& ) {} @@ -132,16 +160,16 @@ template class DenseStorage class DenseStorage m_data; DenseIndex m_rows; public: - inline explicit DenseStorage() : m_rows(0) {} + inline DenseStorage() : m_rows(0) {} inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {} - inline DenseStorage(DenseIndex, DenseIndex rows, DenseIndex) : m_rows(rows) {} + 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 rows, DenseIndex) { m_rows = rows; } - inline void resize(DenseIndex, DenseIndex rows, DenseIndex) { m_rows = rows; } + 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; } }; @@ -171,15 +199,15 @@ template class DenseStorage m_data; DenseIndex m_cols; public: - inline explicit DenseStorage() : m_cols(0) {} + inline DenseStorage() : m_cols(0) {} inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {} - inline DenseStorage(DenseIndex, DenseIndex, DenseIndex cols) : m_cols(cols) {} + 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 cols) { m_cols = cols; } - inline void resize(DenseIndex, DenseIndex, DenseIndex cols) { m_cols = 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; } }; @@ -191,24 +219,24 @@ template class DenseStorage(size)), m_rows(rows), m_cols(cols) + inline DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols) + : m_data(internal::conditional_aligned_new_auto(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) { 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 rows, DenseIndex cols) + inline 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 = rows; - m_cols = cols; + m_rows = nbRows; + m_cols = nbCols; } - void resize(DenseIndex size, DenseIndex rows, DenseIndex cols) + void resize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols) { if(size != m_rows*m_cols) { @@ -219,8 +247,8 @@ template class DenseStorage class DenseStorage(size)), m_cols(cols) + inline 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 cols) + inline void conservativeResize(DenseIndex size, DenseIndex, DenseIndex nbCols) { m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, _Rows*m_cols); - m_cols = cols; + m_cols = nbCols; } - EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex, DenseIndex cols) + EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex, DenseIndex nbCols) { if(size != _Rows*m_cols) { @@ -256,7 +284,7 @@ template class DenseStorage class DenseStorage(size)), m_rows(rows) + inline 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 rows, DenseIndex) + inline void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex) { m_data = internal::conditional_aligned_realloc_new_auto(m_data, size, m_rows*_Cols); - m_rows = rows; + m_rows = nbRows; } - EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex rows, DenseIndex) + EIGEN_STRONG_INLINE void resize(DenseIndex size, DenseIndex nbRows, DenseIndex) { if(size != m_rows*_Cols) { @@ -292,7 +320,7 @@ template class DenseStorage > typedef typename remove_reference::type _MatrixTypeNested; typedef typename MatrixType::StorageKind StorageKind; enum { - RowsAtCompileTime = (int(DiagIndex) == Dynamic || int(MatrixType::SizeAtCompileTime) == Dynamic) ? Dynamic - : (EIGEN_PLAIN_ENUM_MIN(MatrixType::RowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0), - MatrixType::ColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))), + RowsAtCompileTime = (int(DiagIndex) == DynamicIndex || int(MatrixType::SizeAtCompileTime) == Dynamic) ? Dynamic + : (EIGEN_PLAIN_ENUM_MIN(MatrixType::RowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0), + MatrixType::ColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))), ColsAtCompileTime = 1, MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic - : DiagIndex == Dynamic ? EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime, + : DiagIndex == DynamicIndex ? EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime, MatrixType::MaxColsAtCompileTime) : (EIGEN_PLAIN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0), MatrixType::MaxColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))), @@ -61,20 +61,21 @@ struct traits > }; } -template class Diagonal - : public internal::dense_xpr_base< Diagonal >::type +template class Diagonal + : public internal::dense_xpr_base< Diagonal >::type { public: + enum { DiagIndex = _DiagIndex }; typedef typename internal::dense_xpr_base::type Base; EIGEN_DENSE_PUBLIC_INTERFACE(Diagonal) - inline Diagonal(MatrixType& matrix, Index index = DiagIndex) : m_matrix(matrix), m_index(index) {} + inline Diagonal(MatrixType& matrix, Index a_index = DiagIndex) : m_matrix(matrix), m_index(a_index) {} EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal) inline Index rows() const - { return m_index.value()<0 ? (std::min)(m_matrix.cols(),m_matrix.rows()+m_index.value()) : (std::min)(m_matrix.rows(),m_matrix.cols()-m_index.value()); } + { return m_index.value()<0 ? (std::min)(m_matrix.cols(),m_matrix.rows()+m_index.value()) : (std::min)(m_matrix.rows(),m_matrix.cols()-m_index.value()); } inline Index cols() const { return 1; } @@ -113,20 +114,20 @@ template class Diagonal return m_matrix.coeff(row+rowOffset(), row+colOffset()); } - inline Scalar& coeffRef(Index index) + inline Scalar& coeffRef(Index idx) { EIGEN_STATIC_ASSERT_LVALUE(MatrixType) - return m_matrix.const_cast_derived().coeffRef(index+rowOffset(), index+colOffset()); + return m_matrix.const_cast_derived().coeffRef(idx+rowOffset(), idx+colOffset()); } - inline const Scalar& coeffRef(Index index) const + inline const Scalar& coeffRef(Index idx) const { - return m_matrix.const_cast_derived().coeffRef(index+rowOffset(), index+colOffset()); + return m_matrix.const_cast_derived().coeffRef(idx+rowOffset(), idx+colOffset()); } - inline CoeffReturnType coeff(Index index) const + inline CoeffReturnType coeff(Index idx) const { - return m_matrix.coeff(index+rowOffset(), index+colOffset()); + return m_matrix.coeff(idx+rowOffset(), idx+colOffset()); } const typename internal::remove_all::type& @@ -142,7 +143,7 @@ template class Diagonal protected: typename MatrixType::Nested m_matrix; - const internal::variable_if_dynamic m_index; + const internal::variable_if_dynamicindex m_index; private: // some compilers may fail to optimize std::max etc in case of compile-time constants... @@ -171,7 +172,7 @@ MatrixBase::diagonal() /** This is the const version of diagonal(). */ template -inline const typename MatrixBase::ConstDiagonalReturnType +inline typename MatrixBase::ConstDiagonalReturnType MatrixBase::diagonal() const { return ConstDiagonalReturnType(derived()); @@ -189,18 +190,18 @@ MatrixBase::diagonal() const * * \sa MatrixBase::diagonal(), class Diagonal */ template -inline typename MatrixBase::template DiagonalIndexReturnType::Type +inline typename MatrixBase::template DiagonalIndexReturnType::Type MatrixBase::diagonal(Index index) { - return typename DiagonalIndexReturnType::Type(derived(), index); + return typename DiagonalIndexReturnType::Type(derived(), index); } /** This is the const version of diagonal(Index). */ template -inline typename MatrixBase::template ConstDiagonalIndexReturnType::Type +inline typename MatrixBase::template ConstDiagonalIndexReturnType::Type MatrixBase::diagonal(Index index) const { - return typename ConstDiagonalIndexReturnType::Type(derived(), index); + return typename ConstDiagonalIndexReturnType::Type(derived(), index); } /** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this diff --git a/eigenlib/Eigen/src/Core/DiagonalMatrix.h b/eigenlib/Eigen/src/Core/DiagonalMatrix.h index 6e8b50fa..e6c220f4 100644 --- a/eigenlib/Eigen/src/Core/DiagonalMatrix.h +++ b/eigenlib/Eigen/src/Core/DiagonalMatrix.h @@ -56,9 +56,14 @@ class DiagonalBase : public EigenBase inline Index rows() const { return diagonal().size(); } inline Index cols() const { return diagonal().size(); } + /** \returns the diagonal matrix product of \c *this by the matrix \a matrix. + */ template const DiagonalProduct - operator*(const MatrixBase &matrix) const; + operator*(const MatrixBase &matrix) const + { + return DiagonalProduct(matrix.derived(), derived()); + } inline const DiagonalWrapper, const DiagonalVectorType> > inverse() const @@ -250,7 +255,7 @@ class DiagonalWrapper #endif /** Constructor from expression of diagonal coefficients to wrap. */ - inline DiagonalWrapper(DiagonalVectorType& diagonal) : m_diagonal(diagonal) {} + inline DiagonalWrapper(DiagonalVectorType& a_diagonal) : m_diagonal(a_diagonal) {} /** \returns a const reference to the wrapped expression of diagonal coefficients. */ const DiagonalVectorType& diagonal() const { return m_diagonal; } @@ -284,13 +289,14 @@ MatrixBase::asDiagonal() const * \sa asDiagonal() */ template -bool MatrixBase::isDiagonal(RealScalar prec) const +bool MatrixBase::isDiagonal(const RealScalar& prec) const { + using std::abs; if(cols() != rows()) return false; RealScalar maxAbsOnDiagonal = static_cast(-1); for(Index j = 0; j < cols(); ++j) { - RealScalar absOnDiagonal = internal::abs(coeff(j,j)); + RealScalar absOnDiagonal = abs(coeff(j,j)); if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal; } for(Index j = 0; j < cols(); ++j) diff --git a/eigenlib/Eigen/src/Core/DiagonalProduct.h b/eigenlib/Eigen/src/Core/DiagonalProduct.h index 598c6b3e..c03a0c2e 100644 --- a/eigenlib/Eigen/src/Core/DiagonalProduct.h +++ b/eigenlib/Eigen/src/Core/DiagonalProduct.h @@ -26,14 +26,15 @@ struct traits > MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, _StorageOrder = MatrixType::Flags & RowMajorBit ? RowMajor : ColMajor, - _PacketOnDiag = !((int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft) - ||(int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)), + _ScalarAccessOnDiag = !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft) + ||(int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheRight)), _SameTypes = is_same::value, // FIXME currently we need same types, but in the future the next rule should be the one - //_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagonalType::Flags)&PacketAccessBit))), - _Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && ((!_PacketOnDiag) || (bool(int(DiagonalType::Flags)&PacketAccessBit))), + //_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))), + _Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))), + _LinearAccessMask = (RowsAtCompileTime==1 || ColsAtCompileTime==1) ? LinearAccessBit : 0, - Flags = (HereditaryBits & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0), + Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0) | AlignedBit,//(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit), CoeffReadCost = NumTraits::MulCost + MatrixType::CoeffReadCost + DiagonalType::DiagonalVectorType::CoeffReadCost }; }; @@ -54,13 +55,21 @@ class DiagonalProduct : internal::no_assignment_operator, eigen_assert(diagonal.diagonal().size() == (ProductOrder == OnTheLeft ? matrix.rows() : matrix.cols())); } - inline Index rows() const { return m_matrix.rows(); } - inline Index cols() const { return m_matrix.cols(); } + EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); } + EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); } - const Scalar coeff(Index row, Index col) const + EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const { return m_diagonal.diagonal().coeff(ProductOrder == OnTheLeft ? row : col) * m_matrix.coeff(row, col); } + + EIGEN_STRONG_INLINE const Scalar coeff(Index idx) const + { + enum { + StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor + }; + return coeff(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx); + } template EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const @@ -69,11 +78,19 @@ class DiagonalProduct : internal::no_assignment_operator, StorageOrder = Flags & RowMajorBit ? RowMajor : ColMajor }; const Index indexInDiagonalVector = ProductOrder == OnTheLeft ? row : col; - return packet_impl(row,col,indexInDiagonalVector,typename internal::conditional< ((int(StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft) ||(int(StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)), internal::true_type, internal::false_type>::type()); } + + template + EIGEN_STRONG_INLINE PacketScalar packet(Index idx) const + { + enum { + StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor + }; + return packet(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx); + } protected: template @@ -88,7 +105,7 @@ class DiagonalProduct : internal::no_assignment_operator, { enum { InnerSize = (MatrixType::Flags & RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime, - DiagonalVectorPacketLoadMode = (LoadMode == Aligned && ((InnerSize%16) == 0)) ? Aligned : Unaligned + DiagonalVectorPacketLoadMode = (LoadMode == Aligned && (((InnerSize%16) == 0) || (int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit)==AlignedBit) ? Aligned : Unaligned) }; return internal::pmul(m_matrix.template packet(row, col), m_diagonal.diagonal().template packet(id)); @@ -103,19 +120,9 @@ class DiagonalProduct : internal::no_assignment_operator, template template inline const DiagonalProduct -MatrixBase::operator*(const DiagonalBase &diagonal) const +MatrixBase::operator*(const DiagonalBase &a_diagonal) const { - return DiagonalProduct(derived(), diagonal.derived()); -} - -/** \returns the diagonal matrix product of \c *this by the matrix \a matrix. - */ -template -template -inline const DiagonalProduct -DiagonalBase::operator*(const MatrixBase &matrix) const -{ - return DiagonalProduct(matrix.derived(), derived()); + return DiagonalProduct(derived(), a_diagonal.derived()); } } // end namespace Eigen diff --git a/eigenlib/Eigen/src/Core/Dot.h b/eigenlib/Eigen/src/Core/Dot.h index ae9274e3..9d7651f1 100644 --- a/eigenlib/Eigen/src/Core/Dot.h +++ b/eigenlib/Eigen/src/Core/Dot.h @@ -112,7 +112,7 @@ MatrixBase::eigen2_dot(const MatrixBase& other) const template EIGEN_STRONG_INLINE typename NumTraits::Scalar>::Real MatrixBase::squaredNorm() const { - return internal::real((*this).cwiseAbs2().sum()); + return numext::real((*this).cwiseAbs2().sum()); } /** \returns, for vectors, the \em l2 norm of \c *this, and for matrices the Frobenius norm. @@ -124,7 +124,8 @@ EIGEN_STRONG_INLINE typename NumTraits::Scala template inline typename NumTraits::Scalar>::Real MatrixBase::norm() const { - return internal::sqrt(squaredNorm()); + using std::sqrt; + return sqrt(squaredNorm()); } /** \returns an expression of the quotient of *this by its own norm. @@ -165,6 +166,7 @@ struct lpNorm_selector typedef typename NumTraits::Scalar>::Real RealScalar; static inline RealScalar run(const MatrixBase& m) { + using std::pow; return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p); } }; @@ -223,11 +225,11 @@ MatrixBase::lpNorm() const template template bool MatrixBase::isOrthogonal -(const MatrixBase& other, RealScalar prec) const +(const MatrixBase& other, const RealScalar& prec) const { typename internal::nested::type nested(derived()); typename internal::nested::type otherNested(other.derived()); - return internal::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm(); + return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm(); } /** \returns true if *this is approximately an unitary matrix, @@ -242,7 +244,7 @@ bool MatrixBase::isOrthogonal * Output: \verbinclude MatrixBase_isUnitary.out */ template -bool MatrixBase::isUnitary(RealScalar prec) const +bool MatrixBase::isUnitary(const RealScalar& prec) const { typename Derived::Nested nested(derived()); for(Index i = 0; i < cols(); ++i) diff --git a/eigenlib/Eigen/src/Core/EigenBase.h b/eigenlib/Eigen/src/Core/EigenBase.h index 0bbd28be..fadb4585 100644 --- a/eigenlib/Eigen/src/Core/EigenBase.h +++ b/eigenlib/Eigen/src/Core/EigenBase.h @@ -126,35 +126,6 @@ Derived& DenseBase::operator-=(const EigenBase &other) return derived(); } -/** replaces \c *this by \c *this * \a other. - * - * \returns a reference to \c *this - */ -template -template -inline Derived& -MatrixBase::operator*=(const EigenBase &other) -{ - other.derived().applyThisOnTheRight(derived()); - return derived(); -} - -/** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=() */ -template -template -inline void MatrixBase::applyOnTheRight(const EigenBase &other) -{ - other.derived().applyThisOnTheRight(derived()); -} - -/** replaces \c *this by \c *this * \a other. */ -template -template -inline void MatrixBase::applyOnTheLeft(const EigenBase &other) -{ - other.derived().applyThisOnTheLeft(derived()); -} - } // end namespace Eigen #endif // EIGEN_EIGENBASE_H diff --git a/eigenlib/Eigen/src/Core/Functors.h b/eigenlib/Eigen/src/Core/Functors.h index 2f46abfd..04fb2173 100644 --- a/eigenlib/Eigen/src/Core/Functors.h +++ b/eigenlib/Eigen/src/Core/Functors.h @@ -154,6 +154,7 @@ template struct scalar_hypot_op { { using std::max; using std::min; + using std::sqrt; Scalar p = (max)(_x, _y); Scalar q = (min)(_x, _y); Scalar qp = q/p; @@ -170,7 +171,7 @@ struct functor_traits > { */ template struct scalar_binary_pow_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_binary_pow_op) - inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return internal::pow(a, b); } + inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return numext::pow(a, b); } }; template struct functor_traits > { @@ -204,21 +205,28 @@ struct functor_traits > { * * \sa class CwiseBinaryOp, Cwise::operator/() */ -template struct scalar_quotient_op { +template struct scalar_quotient_op { + enum { + // TODO vectorize mixed product + Vectorizable = is_same::value && packet_traits::HasDiv && packet_traits::HasDiv + }; + typedef typename scalar_product_traits::ReturnType result_type; EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op) - EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; } + EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; } template EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const { return internal::pdiv(a,b); } }; -template -struct functor_traits > { +template +struct functor_traits > { enum { - Cost = 2 * NumTraits::MulCost, - PacketAccess = packet_traits::HasDiv + Cost = (NumTraits::MulCost + NumTraits::MulCost), // rough estimate! + PacketAccess = scalar_quotient_op::Vectorizable }; }; + + /** \internal * \brief Template functor to compute the and of two booleans * @@ -280,7 +288,7 @@ struct functor_traits > template struct scalar_abs_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op) typedef typename NumTraits::Real result_type; - EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return internal::abs(a); } + EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { using std::abs; return abs(a); } template EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pabs(a); } @@ -302,7 +310,7 @@ struct functor_traits > template struct scalar_abs2_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op) typedef typename NumTraits::Real result_type; - EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return internal::abs2(a); } + EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::abs2(a); } template EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pmul(a,a); } @@ -318,7 +326,7 @@ struct functor_traits > */ template struct scalar_conjugate_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op) - EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return internal::conj(a); } + EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { using numext::conj; return conj(a); } template EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); } }; @@ -355,7 +363,7 @@ template struct scalar_real_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op) typedef typename NumTraits::Real result_type; - EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::real(a); } + EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::real(a); } }; template struct functor_traits > @@ -370,7 +378,7 @@ template struct scalar_imag_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op) typedef typename NumTraits::Real result_type; - EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return internal::imag(a); } + EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::imag(a); } }; template struct functor_traits > @@ -385,7 +393,7 @@ template struct scalar_real_ref_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op) typedef typename NumTraits::Real result_type; - EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::real_ref(*const_cast(&a)); } + EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::real_ref(*const_cast(&a)); } }; template struct functor_traits > @@ -400,7 +408,7 @@ template struct scalar_imag_ref_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op) typedef typename NumTraits::Real result_type; - EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return internal::imag_ref(*const_cast(&a)); } + EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::imag_ref(*const_cast(&a)); } }; template struct functor_traits > @@ -414,7 +422,7 @@ struct functor_traits > */ template struct scalar_exp_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op) - inline const Scalar operator() (const Scalar& a) const { return internal::exp(a); } + inline const Scalar operator() (const Scalar& a) const { using std::exp; return exp(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::pexp(a); } }; @@ -430,7 +438,7 @@ struct functor_traits > */ template struct scalar_log_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op) - inline const Scalar operator() (const Scalar& a) const { return internal::log(a); } + inline const Scalar operator() (const Scalar& a) const { using std::log; return log(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::plog(a); } }; @@ -533,20 +541,28 @@ template struct linspaced_op_impl; // linear access for packet ops: // 1) initialization // base = [low, ..., low] + ([step, ..., step] * [-size, ..., 0]) -// 2) each step +// 2) each step (where size is 1 for coeff access or PacketSize for packet access) // base += [size*step, ..., size*step] +// +// TODO: Perhaps it's better to initialize lazily (so not in the constructor but in packetOp) +// in order to avoid the padd() in operator() ? template struct linspaced_op_impl { typedef typename packet_traits::type Packet; - linspaced_op_impl(Scalar low, Scalar step) : + linspaced_op_impl(const Scalar& low, const Scalar& step) : m_low(low), m_step(step), m_packetStep(pset1(packet_traits::size*step)), - m_base(padd(pset1(low),pmul(pset1(step),plset(-packet_traits::size)))) {} + m_base(padd(pset1(low), pmul(pset1(step),plset(-packet_traits::size)))) {} template - EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; } + EIGEN_STRONG_INLINE const Scalar operator() (Index i) const + { + m_base = padd(m_base, pset1(m_step)); + return m_low+Scalar(i)*m_step; + } + template EIGEN_STRONG_INLINE const Packet packetOp(Index) const { return m_base = padd(m_base,m_packetStep); } @@ -564,7 +580,7 @@ struct linspaced_op_impl { typedef typename packet_traits::type Packet; - linspaced_op_impl(Scalar low, Scalar step) : + linspaced_op_impl(const Scalar& low, const Scalar& step) : m_low(low), m_step(step), m_lowPacket(pset1(m_low)), m_stepPacket(pset1(m_step)), m_interPacket(plset(0)) {} @@ -593,7 +609,7 @@ template struct functor_traits< linspaced_o template struct linspaced_op { typedef typename packet_traits::type Packet; - linspaced_op(Scalar low, Scalar high, int num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/(num_steps-1))) {} + linspaced_op(const Scalar& low, const Scalar& high, DenseIndex num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/(num_steps-1))) {} template EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); } @@ -632,12 +648,14 @@ template struct linspaced_op template struct functor_has_linear_access { enum { ret = 1 }; }; template struct functor_has_linear_access > { enum { ret = 0 }; }; -// in CwiseBinaryOp, we require the Lhs and Rhs to have the same scalar type, except for multiplication -// where we only require them to have the same _real_ scalar type so one may multiply, say, float by complex. +// In Eigen, any binary op (Product, CwiseBinaryOp) require the Lhs and Rhs to have the same scalar type, except for multiplication +// where the mixing of different types is handled by scalar_product_traits +// In particular, real * complex is allowed. // FIXME move this to functor_traits adding a functor_default -template struct functor_allows_mixing_real_and_complex { enum { ret = 0 }; }; -template struct functor_allows_mixing_real_and_complex > { enum { ret = 1 }; }; -template struct functor_allows_mixing_real_and_complex > { enum { ret = 1 }; }; +template struct functor_is_product_like { enum { ret = 0 }; }; +template struct functor_is_product_like > { enum { ret = 1 }; }; +template struct functor_is_product_like > { enum { ret = 1 }; }; +template struct functor_is_product_like > { enum { ret = 1 }; }; /** \internal @@ -666,7 +684,7 @@ struct functor_traits > */ template struct scalar_sqrt_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op) - inline const Scalar operator() (const Scalar& a) const { return internal::sqrt(a); } + inline const Scalar operator() (const Scalar& a) const { using std::sqrt; return sqrt(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); } }; @@ -684,7 +702,7 @@ struct functor_traits > */ template struct scalar_cos_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op) - inline Scalar operator() (const Scalar& a) const { return internal::cos(a); } + inline Scalar operator() (const Scalar& a) const { using std::cos; return cos(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::pcos(a); } }; @@ -703,7 +721,7 @@ struct functor_traits > */ template struct scalar_sin_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op) - inline const Scalar operator() (const Scalar& a) const { return internal::sin(a); } + inline const Scalar operator() (const Scalar& a) const { using std::sin; return sin(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::psin(a); } }; @@ -723,7 +741,7 @@ struct functor_traits > */ template struct scalar_tan_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op) - inline const Scalar operator() (const Scalar& a) const { return internal::tan(a); } + inline const Scalar operator() (const Scalar& a) const { using std::tan; return tan(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::ptan(a); } }; @@ -742,7 +760,7 @@ struct functor_traits > */ template struct scalar_acos_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op) - inline const Scalar operator() (const Scalar& a) const { return internal::acos(a); } + inline const Scalar operator() (const Scalar& a) const { using std::acos; return acos(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::pacos(a); } }; @@ -761,7 +779,7 @@ struct functor_traits > */ template struct scalar_asin_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op) - inline const Scalar operator() (const Scalar& a) const { return internal::asin(a); } + inline const Scalar operator() (const Scalar& a) const { using std::asin; return asin(a); } typedef typename packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return internal::pasin(a); } }; @@ -783,7 +801,7 @@ struct scalar_pow_op { // FIXME default copy constructors seems bugged with std::complex<> inline scalar_pow_op(const scalar_pow_op& other) : m_exponent(other.m_exponent) { } inline scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {} - inline Scalar operator() (const Scalar& a) const { return internal::pow(a, m_exponent); } + inline Scalar operator() (const Scalar& a) const { return numext::pow(a, m_exponent); } const Scalar m_exponent; }; template diff --git a/eigenlib/Eigen/src/Core/Fuzzy.h b/eigenlib/Eigen/src/Core/Fuzzy.h index d74edcfd..fe63bd29 100644 --- a/eigenlib/Eigen/src/Core/Fuzzy.h +++ b/eigenlib/Eigen/src/Core/Fuzzy.h @@ -19,7 +19,7 @@ namespace internal template::IsInteger> struct isApprox_selector { - static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar prec) + static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec) { using std::min; typename internal::nested::type nested(x); @@ -31,7 +31,7 @@ struct isApprox_selector template struct isApprox_selector { - static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar) + static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar&) { return x.matrix() == y.matrix(); } @@ -40,16 +40,16 @@ struct isApprox_selector template::IsInteger> struct isMuchSmallerThan_object_selector { - static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar prec) + static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec) { - return x.cwiseAbs2().sum() <= abs2(prec) * y.cwiseAbs2().sum(); + return x.cwiseAbs2().sum() <= numext::abs2(prec) * y.cwiseAbs2().sum(); } }; template struct isMuchSmallerThan_object_selector { - static bool run(const Derived& x, const OtherDerived&, typename Derived::RealScalar) + static bool run(const Derived& x, const OtherDerived&, const typename Derived::RealScalar&) { return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix(); } @@ -58,16 +58,16 @@ struct isMuchSmallerThan_object_selector template::IsInteger> struct isMuchSmallerThan_scalar_selector { - static bool run(const Derived& x, const typename Derived::RealScalar& y, typename Derived::RealScalar prec) + static bool run(const Derived& x, const typename Derived::RealScalar& y, const typename Derived::RealScalar& prec) { - return x.cwiseAbs2().sum() <= abs2(prec * y); + return x.cwiseAbs2().sum() <= numext::abs2(prec * y); } }; template struct isMuchSmallerThan_scalar_selector { - static bool run(const Derived& x, const typename Derived::RealScalar&, typename Derived::RealScalar) + static bool run(const Derived& x, const typename Derived::RealScalar&, const typename Derived::RealScalar&) { return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix(); } @@ -97,7 +97,7 @@ template template bool DenseBase::isApprox( const DenseBase& other, - RealScalar prec + const RealScalar& prec ) const { return internal::isApprox_selector::run(derived(), other.derived(), prec); @@ -119,7 +119,7 @@ bool DenseBase::isApprox( template bool DenseBase::isMuchSmallerThan( const typename NumTraits::Real& other, - RealScalar prec + const RealScalar& prec ) const { return internal::isMuchSmallerThan_scalar_selector::run(derived(), other, prec); @@ -139,7 +139,7 @@ template template bool DenseBase::isMuchSmallerThan( const DenseBase& other, - RealScalar prec + const RealScalar& prec ) const { return internal::isMuchSmallerThan_object_selector::run(derived(), other.derived(), prec); diff --git a/eigenlib/Eigen/src/Core/GeneralProduct.h b/eigenlib/Eigen/src/Core/GeneralProduct.h index bfc2a67b..2a59d946 100644 --- a/eigenlib/Eigen/src/Core/GeneralProduct.h +++ b/eigenlib/Eigen/src/Core/GeneralProduct.h @@ -222,7 +222,29 @@ class GeneralProduct ***********************************************************************/ namespace internal { -template struct outer_product_selector; + +// Column major +template +EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest& dest, const Func& func, const false_type&) +{ + typedef typename Dest::Index Index; + // FIXME make sure lhs is sequentially stored + // FIXME not very good if rhs is real and lhs complex while alpha is real too + const Index cols = dest.cols(); + for (Index j=0; j +EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest& dest, const Func& func, const true_type&) { + typedef typename Dest::Index Index; + // FIXME make sure rhs is sequentially stored + // FIXME not very good if lhs is real and rhs complex while alpha is real too + const Index rows = dest.rows(); + for (Index i=0; i struct traits > @@ -235,6 +257,8 @@ template class GeneralProduct : public ProductBase, Lhs, Rhs> { + template struct IsRowMajor : internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {}; + public: EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct) @@ -243,41 +267,39 @@ class GeneralProduct EIGEN_STATIC_ASSERT((internal::is_same::value), YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) } + + struct set { template void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() = src; } }; + struct add { template void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() += src; } }; + struct sub { template void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() -= src; } }; + struct adds { + Scalar m_scale; + adds(const Scalar& s) : m_scale(s) {} + template void operator()(const Dst& dst, const Src& src) const { + dst.const_cast_derived() += m_scale * src; + } + }; + + template + inline void evalTo(Dest& dest) const { + internal::outer_product_selector_run(*this, dest, set(), IsRowMajor()); + } + + template + inline void addTo(Dest& dest) const { + internal::outer_product_selector_run(*this, dest, add(), IsRowMajor()); + } - template void scaleAndAddTo(Dest& dest, Scalar alpha) const + template + inline void subTo(Dest& dest) const { + internal::outer_product_selector_run(*this, dest, sub(), IsRowMajor()); + } + + template void scaleAndAddTo(Dest& dest, const Scalar& alpha) const { - internal::outer_product_selector<(int(Dest::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(*this, dest, alpha); + internal::outer_product_selector_run(*this, dest, adds(alpha), IsRowMajor()); } }; -namespace internal { - -template<> struct outer_product_selector { - template - static EIGEN_DONT_INLINE void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) { - typedef typename Dest::Index Index; - // FIXME make sure lhs is sequentially stored - // FIXME not very good if rhs is real and lhs complex while alpha is real too - const Index cols = dest.cols(); - for (Index j=0; j struct outer_product_selector { - template - static EIGEN_DONT_INLINE void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) { - typedef typename Dest::Index Index; - // FIXME make sure rhs is sequentially stored - // FIXME not very good if lhs is real and rhs complex while alpha is real too - const Index rows = dest.rows(); - for (Index i=0; i typedef typename Lhs::Scalar LhsScalar; typedef typename Rhs::Scalar RhsScalar; - GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) + GeneralProduct(const Lhs& a_lhs, const Rhs& a_rhs) : Base(a_lhs,a_rhs) { // EIGEN_STATIC_ASSERT((internal::is_same::value), // YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) @@ -320,7 +342,7 @@ class GeneralProduct enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight }; typedef typename internal::conditional::type MatrixType; - template void scaleAndAddTo(Dest& dst, Scalar alpha) const + template void scaleAndAddTo(Dest& dst, const Scalar& alpha) const { eigen_assert(m_lhs.rows() == dst.rows() && m_rhs.cols() == dst.cols()); internal::gemv_selector struct gemv_selector { template - static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) + static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha) { Transpose destT(dest); enum { OtherStorageOrder = StorageOrder == RowMajor ? ColMajor : RowMajor }; @@ -384,7 +406,7 @@ struct gemv_static_vector_if template<> struct gemv_selector { template - static inline void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) + static inline void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha) { typedef typename ProductType::Index Index; typedef typename ProductType::LhsScalar LhsScalar; @@ -413,7 +435,7 @@ template<> struct gemv_selector gemv_static_vector_if static_dest; - bool alphaIsCompatible = (!ComplexByReal) || (imag(actualAlpha)==RealScalar(0)); + bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0)); bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible; RhsScalar compatibleAlpha = get_factor::run(actualAlpha); @@ -457,7 +479,7 @@ template<> struct gemv_selector template<> struct gemv_selector { template - static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) + static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha) { typedef typename ProductType::LhsScalar LhsScalar; typedef typename ProductType::RhsScalar RhsScalar; @@ -508,7 +530,7 @@ template<> struct gemv_selector template<> struct gemv_selector { template - static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) + static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha) { typedef typename Dest::Index Index; // TODO makes sure dest is sequentially stored in memory, otherwise use a temp @@ -521,7 +543,7 @@ template<> struct gemv_selector template<> struct gemv_selector { template - static void run(const ProductType& prod, Dest& dest, typename ProductType::Scalar alpha) + static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha) { typedef typename Dest::Index Index; // TODO makes sure rhs is sequentially stored in memory, otherwise use a temp diff --git a/eigenlib/Eigen/src/Core/GenericPacketMath.h b/eigenlib/Eigen/src/Core/GenericPacketMath.h index 858fb243..5f783ebe 100644 --- a/eigenlib/Eigen/src/Core/GenericPacketMath.h +++ b/eigenlib/Eigen/src/Core/GenericPacketMath.h @@ -106,7 +106,7 @@ pnegate(const Packet& a) { return -a; } /** \internal \returns conj(a) (coeff-wise) */ template inline Packet -pconj(const Packet& a) { return conj(a); } +pconj(const Packet& a) { return numext::conj(a); } /** \internal \returns a * b (coeff-wise) */ template inline Packet @@ -130,7 +130,7 @@ pmax(const Packet& a, /** \internal \returns the absolute value of \a a */ template inline Packet -pabs(const Packet& a) { return abs(a); } +pabs(const Packet& a) { using std::abs; return abs(a); } /** \internal \returns the bitwise and of \a a and \a b */ template inline Packet @@ -156,7 +156,11 @@ pload(const typename unpacket_traits::type* from) { return *from; } template inline Packet ploadu(const typename unpacket_traits::type* from) { return *from; } -/** \internal \returns a packet with elements of \a *from duplicated, e.g.: (from[0],from[0],from[1],from[1]) */ +/** \internal \returns a packet with elements of \a *from duplicated. + * For instance, for a packet of 8 elements, 4 scalar will be read from \a *from and + * duplicated to form: {from[0],from[0],from[1],from[1],,from[2],from[2],,from[3],from[3]} + * Currently, this function is only used for scalar * complex products. + */ template inline Packet ploaddup(const typename unpacket_traits::type* from) { return *from; } @@ -215,7 +219,12 @@ template inline Packet preverse(const Packet& a) /** \internal \returns \a a with real and imaginary part flipped (for complex type only) */ template inline Packet pcplxflip(const Packet& a) -{ return Packet(imag(a),real(a)); } +{ + // FIXME: uncomment the following in case we drop the internal imag and real functions. +// using std::imag; +// using std::real; + return Packet(imag(a),real(a)); +} /************************** * Special math functions @@ -223,35 +232,35 @@ template inline Packet pcplxflip(const Packet& a) /** \internal \returns the sine of \a a (coeff-wise) */ template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -Packet psin(const Packet& a) { return sin(a); } +Packet psin(const Packet& a) { using std::sin; return sin(a); } /** \internal \returns the cosine of \a a (coeff-wise) */ template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -Packet pcos(const Packet& a) { return cos(a); } +Packet pcos(const Packet& a) { using std::cos; return cos(a); } /** \internal \returns the tan of \a a (coeff-wise) */ template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -Packet ptan(const Packet& a) { return tan(a); } +Packet ptan(const Packet& a) { using std::tan; return tan(a); } /** \internal \returns the arc sine of \a a (coeff-wise) */ template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -Packet pasin(const Packet& a) { return asin(a); } +Packet pasin(const Packet& a) { using std::asin; return asin(a); } /** \internal \returns the arc cosine of \a a (coeff-wise) */ template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -Packet pacos(const Packet& a) { return acos(a); } +Packet pacos(const Packet& a) { using std::acos; return acos(a); } /** \internal \returns the exp of \a a (coeff-wise) */ template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -Packet pexp(const Packet& a) { return exp(a); } +Packet pexp(const Packet& a) { using std::exp; return exp(a); } /** \internal \returns the log of \a a (coeff-wise) */ template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -Packet plog(const Packet& a) { return log(a); } +Packet plog(const Packet& a) { using std::log; return log(a); } /** \internal \returns the square-root of \a a (coeff-wise) */ template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -Packet psqrt(const Packet& a) { return sqrt(a); } +Packet psqrt(const Packet& a) { using std::sqrt; return sqrt(a); } /*************************************************************************** * The following functions might not have to be overwritten for vectorized types @@ -302,8 +311,21 @@ struct palign_impl static inline void run(PacketType&, const PacketType&) {} }; -/** \internal update \a first using the concatenation of the \a Offset last elements - * of \a first and packet_size minus \a Offset first elements of \a second */ +/** \internal update \a first using the concatenation of the packet_size minus \a Offset last elements + * of \a first and \a Offset first elements of \a second. + * + * This function is currently only used to optimize matrix-vector products on unligned matrices. + * It takes 2 packets that represent a contiguous memory array, and returns a packet starting + * at the position \a Offset. For instance, for packets of 4 elements, we have: + * Input: + * - first = {f0,f1,f2,f3} + * - second = {s0,s1,s2,s3} + * Output: + * - if Offset==0 then {f0,f1,f2,f3} + * - if Offset==1 then {f1,f2,f3,s0} + * - if Offset==2 then {f2,f3,s0,s1} + * - if Offset==3 then {f3,s0,s1,s3} + */ template inline void palign(PacketType& first, const PacketType& second) { diff --git a/eigenlib/Eigen/src/Core/GlobalFunctions.h b/eigenlib/Eigen/src/Core/GlobalFunctions.h index e63726c4..2acf9772 100644 --- a/eigenlib/Eigen/src/Core/GlobalFunctions.h +++ b/eigenlib/Eigen/src/Core/GlobalFunctions.h @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2010 Gael Guennebaud +// Copyright (C) 2010-2012 Gael Guennebaud // Copyright (C) 2010 Benoit Jacob // // This Source Code Form is subject to the terms of the Mozilla @@ -11,7 +11,7 @@ #ifndef EIGEN_GLOBAL_FUNCTIONS_H #define EIGEN_GLOBAL_FUNCTIONS_H -#define EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(NAME,FUNCTOR) \ +#define EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(NAME,FUNCTOR) \ template \ inline const Eigen::CwiseUnaryOp, const Derived> \ NAME(const Eigen::ArrayBase& x) { \ @@ -35,20 +35,21 @@ }; -namespace std +namespace Eigen { - EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(real,scalar_real_op) - EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(imag,scalar_imag_op) - EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(sin,scalar_sin_op) - EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(cos,scalar_cos_op) - EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(asin,scalar_asin_op) - EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(acos,scalar_acos_op) - EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(tan,scalar_tan_op) - EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(exp,scalar_exp_op) - EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(log,scalar_log_op) - EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(abs,scalar_abs_op) - EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(sqrt,scalar_sqrt_op) - + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(real,scalar_real_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(imag,scalar_imag_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(conj,scalar_conjugate_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sin,scalar_sin_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cos,scalar_cos_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(asin,scalar_asin_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(acos,scalar_acos_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tan,scalar_tan_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sqrt,scalar_sqrt_op) + template inline const Eigen::CwiseUnaryOp, const Derived> pow(const Eigen::ArrayBase& x, const typename Derived::Scalar& exponent) { @@ -64,16 +65,13 @@ namespace std exponents.derived() ); } -} - -namespace Eigen -{ + /** * \brief Component-wise division of a scalar by array elements. **/ template inline const Eigen::CwiseUnaryOp, const Derived> - operator/(typename Derived::Scalar s, const Eigen::ArrayBase& a) + operator/(const typename Derived::Scalar& s, const Eigen::ArrayBase& a) { return Eigen::CwiseUnaryOp, const Derived>( a.derived(), @@ -85,19 +83,10 @@ namespace Eigen { EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(real,scalar_real_op) EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(imag,scalar_imag_op) - EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(sin,scalar_sin_op) - EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(cos,scalar_cos_op) - EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(asin,scalar_asin_op) - EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(acos,scalar_acos_op) - EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(tan,scalar_tan_op) - EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(exp,scalar_exp_op) - EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(log,scalar_log_op) - EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(abs,scalar_abs_op) EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(abs2,scalar_abs2_op) - EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(sqrt,scalar_sqrt_op) } } -// TODO: cleanly disable those functions that are not supported on Array (internal::real_ref, internal::random, internal::isApprox...) +// TODO: cleanly disable those functions that are not supported on Array (numext::real_ref, internal::random, internal::isApprox...) #endif // EIGEN_GLOBAL_FUNCTIONS_H diff --git a/eigenlib/Eigen/src/Core/IO.h b/eigenlib/Eigen/src/Core/IO.h index cc8e18a0..8d4bc59e 100644 --- a/eigenlib/Eigen/src/Core/IO.h +++ b/eigenlib/Eigen/src/Core/IO.h @@ -55,9 +55,8 @@ struct IOFormat const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="", const std::string& _matPrefix="", const std::string& _matSuffix="") : matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator), - coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags) + rowSpacer(""), coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags) { - rowSpacer = ""; int i = int(matSuffix.length())-1; while (i>=0 && matSuffix[i]!='\n') { @@ -129,6 +128,7 @@ struct significant_decimals_default_impl static inline int run() { using std::ceil; + using std::log; return cast(ceil(-log(NumTraits::epsilon())/log(RealScalar(10)))); } }; @@ -185,21 +185,22 @@ std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& explicit_precision = fmt.precision; } + std::streamsize old_precision = 0; + if(explicit_precision) old_precision = s.precision(explicit_precision); + bool align_cols = !(fmt.flags & DontAlignCols); if(align_cols) { // compute the largest width - for(Index j = 1; j < m.cols(); ++j) + for(Index j = 0; j < m.cols(); ++j) for(Index i = 0; i < m.rows(); ++i) { std::stringstream sstr; - if(explicit_precision) sstr.precision(explicit_precision); + sstr.copyfmt(s); sstr << m.coeff(i,j); width = std::max(width, Index(sstr.str().length())); } } - std::streamsize old_precision = 0; - if(explicit_precision) old_precision = s.precision(explicit_precision); s << fmt.matPrefix; for(Index i = 0; i < m.rows(); ++i) { diff --git a/eigenlib/Eigen/src/Core/Map.h b/eigenlib/Eigen/src/Core/Map.h index 15a19226..f804c89d 100644 --- a/eigenlib/Eigen/src/Core/Map.h +++ b/eigenlib/Eigen/src/Core/Map.h @@ -133,36 +133,36 @@ template class Ma /** Constructor in the fixed-size case. * - * \param data pointer to the array to map - * \param stride optional Stride object, passing the strides. + * \param dataPtr pointer to the array to map + * \param a_stride optional Stride object, passing the strides. */ - inline Map(PointerArgType data, const StrideType& stride = StrideType()) - : Base(cast_to_pointer_type(data)), m_stride(stride) + inline Map(PointerArgType dataPtr, const StrideType& a_stride = StrideType()) + : Base(cast_to_pointer_type(dataPtr)), m_stride(a_stride) { PlainObjectType::Base::_check_template_params(); } /** Constructor in the dynamic-size vector case. * - * \param data pointer to the array to map - * \param size the size of the vector expression - * \param stride optional Stride object, passing the strides. + * \param dataPtr pointer to the array to map + * \param a_size the size of the vector expression + * \param a_stride optional Stride object, passing the strides. */ - inline Map(PointerArgType data, Index size, const StrideType& stride = StrideType()) - : Base(cast_to_pointer_type(data), size), m_stride(stride) + inline Map(PointerArgType dataPtr, Index a_size, const StrideType& a_stride = StrideType()) + : Base(cast_to_pointer_type(dataPtr), a_size), m_stride(a_stride) { PlainObjectType::Base::_check_template_params(); } /** Constructor in the dynamic-size matrix case. * - * \param data pointer to the array to map - * \param rows the number of rows of the matrix expression - * \param cols the number of columns of the matrix expression - * \param stride optional Stride object, passing the strides. + * \param dataPtr pointer to the array to map + * \param nbRows the number of rows of the matrix expression + * \param nbCols the number of columns of the matrix expression + * \param a_stride optional Stride object, passing the strides. */ - inline Map(PointerArgType data, Index rows, Index cols, const StrideType& stride = StrideType()) - : Base(cast_to_pointer_type(data), rows, cols), m_stride(stride) + inline Map(PointerArgType dataPtr, Index nbRows, Index nbCols, const StrideType& a_stride = StrideType()) + : Base(cast_to_pointer_type(dataPtr), nbRows, nbCols), m_stride(a_stride) { PlainObjectType::Base::_check_template_params(); } diff --git a/eigenlib/Eigen/src/Core/MapBase.h b/eigenlib/Eigen/src/Core/MapBase.h index a388d61e..6876de58 100644 --- a/eigenlib/Eigen/src/Core/MapBase.h +++ b/eigenlib/Eigen/src/Core/MapBase.h @@ -87,9 +87,9 @@ template class MapBase */ inline const Scalar* data() const { return m_data; } - inline const Scalar& coeff(Index row, Index col) const + inline const Scalar& coeff(Index rowId, Index colId) const { - return m_data[col * colStride() + row * rowStride()]; + return m_data[colId * colStride() + rowId * rowStride()]; } inline const Scalar& coeff(Index index) const @@ -98,9 +98,9 @@ template class MapBase return m_data[index * innerStride()]; } - inline const Scalar& coeffRef(Index row, Index col) const + inline const Scalar& coeffRef(Index rowId, Index colId) const { - return this->m_data[col * colStride() + row * rowStride()]; + return this->m_data[colId * colStride() + rowId * rowStride()]; } inline const Scalar& coeffRef(Index index) const @@ -110,10 +110,10 @@ template class MapBase } template - inline PacketScalar packet(Index row, Index col) const + inline PacketScalar packet(Index rowId, Index colId) const { return internal::ploadt - (m_data + (col * colStride() + row * rowStride())); + (m_data + (colId * colStride() + rowId * rowStride())); } template @@ -123,29 +123,29 @@ template class MapBase return internal::ploadt(m_data + index * innerStride()); } - inline MapBase(PointerType data) : m_data(data), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) + inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) { EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) checkSanity(); } - inline MapBase(PointerType data, Index size) - : m_data(data), - m_rows(RowsAtCompileTime == Dynamic ? size : Index(RowsAtCompileTime)), - m_cols(ColsAtCompileTime == Dynamic ? size : Index(ColsAtCompileTime)) + inline MapBase(PointerType dataPtr, Index vecSize) + : m_data(dataPtr), + m_rows(RowsAtCompileTime == Dynamic ? vecSize : Index(RowsAtCompileTime)), + m_cols(ColsAtCompileTime == Dynamic ? vecSize : Index(ColsAtCompileTime)) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) - eigen_assert(size >= 0); - eigen_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size); + eigen_assert(vecSize >= 0); + eigen_assert(dataPtr == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == vecSize); checkSanity(); } - inline MapBase(PointerType data, Index rows, Index cols) - : m_data(data), m_rows(rows), m_cols(cols) + inline MapBase(PointerType dataPtr, Index nbRows, Index nbCols) + : m_data(dataPtr), m_rows(nbRows), m_cols(nbCols) { - eigen_assert( (data == 0) - || ( rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) - && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols))); + eigen_assert( (dataPtr == 0) + || ( nbRows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == nbRows) + && nbCols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == nbCols))); checkSanity(); } @@ -210,23 +210,23 @@ template class MapBase } template - inline void writePacket(Index row, Index col, const PacketScalar& x) + inline void writePacket(Index row, Index col, const PacketScalar& val) { internal::pstoret - (this->m_data + (col * colStride() + row * rowStride()), x); + (this->m_data + (col * colStride() + row * rowStride()), val); } template - inline void writePacket(Index index, const PacketScalar& x) + inline void writePacket(Index index, const PacketScalar& val) { EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) internal::pstoret - (this->m_data + index * innerStride(), x); + (this->m_data + index * innerStride(), val); } - explicit inline MapBase(PointerType data) : Base(data) {} - inline MapBase(PointerType data, Index size) : Base(data, size) {} - inline MapBase(PointerType data, Index rows, Index cols) : Base(data, rows, cols) {} + explicit inline MapBase(PointerType dataPtr) : Base(dataPtr) {} + inline MapBase(PointerType dataPtr, Index vecSize) : Base(dataPtr, vecSize) {} + inline MapBase(PointerType dataPtr, Index nbRows, Index nbCols) : Base(dataPtr, nbRows, nbCols) {} Derived& operator=(const MapBase& other) { diff --git a/eigenlib/Eigen/src/Core/MathFunctions.h b/eigenlib/Eigen/src/Core/MathFunctions.h index 05e913f2..2bfc5ebd 100644 --- a/eigenlib/Eigen/src/Core/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/MathFunctions.h @@ -51,16 +51,15 @@ struct global_math_functions_filtering_base typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type; }; -#define EIGEN_MATHFUNC_IMPL(func, scalar) func##_impl::type> -#define EIGEN_MATHFUNC_RETVAL(func, scalar) typename func##_retval::type>::type - +#define EIGEN_MATHFUNC_IMPL(func, scalar) Eigen::internal::func##_impl::type> +#define EIGEN_MATHFUNC_RETVAL(func, scalar) typename Eigen::internal::func##_retval::type>::type /**************************************************************************** * Implementation of real * ****************************************************************************/ -template -struct real_impl +template::IsComplex> +struct real_default_impl { typedef typename NumTraits::Real RealScalar; static inline RealScalar run(const Scalar& x) @@ -69,34 +68,32 @@ struct real_impl } }; -template -struct real_impl > +template +struct real_default_impl { - static inline RealScalar run(const std::complex& x) + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar& x) { using std::real; return real(x); } }; +template struct real_impl : real_default_impl {}; + template struct real_retval { typedef typename NumTraits::Real type; }; -template -inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x) -{ - return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x); -} /**************************************************************************** * Implementation of imag * ****************************************************************************/ -template -struct imag_impl +template::IsComplex> +struct imag_default_impl { typedef typename NumTraits::Real RealScalar; static inline RealScalar run(const Scalar&) @@ -105,28 +102,25 @@ struct imag_impl } }; -template -struct imag_impl > +template +struct imag_default_impl { - static inline RealScalar run(const std::complex& x) + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar& x) { using std::imag; return imag(x); } }; +template struct imag_impl : imag_default_impl {}; + template struct imag_retval { typedef typename NumTraits::Real type; }; -template -inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x) -{ - return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x); -} - /**************************************************************************** * Implementation of real_ref * ****************************************************************************/ @@ -151,18 +145,6 @@ struct real_ref_retval typedef typename NumTraits::Real & type; }; -template -inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x) -{ - return real_ref_impl::run(x); -} - -template -inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x) -{ - return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x); -} - /**************************************************************************** * Implementation of imag_ref * ****************************************************************************/ @@ -203,23 +185,11 @@ struct imag_ref_retval typedef typename NumTraits::Real & type; }; -template -inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x) -{ - return imag_ref_impl::run(x); -} - -template -inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x) -{ - return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x); -} - /**************************************************************************** * Implementation of conj * ****************************************************************************/ -template +template::IsComplex> struct conj_impl { static inline Scalar run(const Scalar& x) @@ -228,10 +198,10 @@ struct conj_impl } }; -template -struct conj_impl > +template +struct conj_impl { - static inline std::complex run(const std::complex& x) + static inline Scalar run(const Scalar& x) { using std::conj; return conj(x); @@ -244,39 +214,6 @@ struct conj_retval typedef Scalar type; }; -template -inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x) -{ - return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x); -} - -/**************************************************************************** -* Implementation of abs * -****************************************************************************/ - -template -struct abs_impl -{ - typedef typename NumTraits::Real RealScalar; - static inline RealScalar run(const Scalar& x) - { - using std::abs; - return abs(x); - } -}; - -template -struct abs_retval -{ - typedef typename NumTraits::Real type; -}; - -template -inline EIGEN_MATHFUNC_RETVAL(abs, Scalar) abs(const Scalar& x) -{ - return EIGEN_MATHFUNC_IMPL(abs, Scalar)::run(x); -} - /**************************************************************************** * Implementation of abs2 * ****************************************************************************/ @@ -306,12 +243,6 @@ struct abs2_retval typedef typename NumTraits::Real type; }; -template -inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x) -{ - return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x); -} - /**************************************************************************** * Implementation of norm1 * ****************************************************************************/ @@ -322,6 +253,7 @@ struct norm1_default_impl typedef typename NumTraits::Real RealScalar; static inline RealScalar run(const Scalar& x) { + using std::abs; return abs(real(x)) + abs(imag(x)); } }; @@ -331,6 +263,7 @@ struct norm1_default_impl { static inline Scalar run(const Scalar& x) { + using std::abs; return abs(x); } }; @@ -344,12 +277,6 @@ struct norm1_retval typedef typename NumTraits::Real type; }; -template -inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x) -{ - return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x); -} - /**************************************************************************** * Implementation of hypot * ****************************************************************************/ @@ -362,9 +289,12 @@ struct hypot_impl { using std::max; using std::min; + using std::abs; + using std::sqrt; RealScalar _x = abs(x); RealScalar _y = abs(y); RealScalar p = (max)(_x, _y); + if(p==RealScalar(0)) return 0; RealScalar q = (min)(_x, _y); RealScalar qp = q/p; return p * sqrt(RealScalar(1) + qp*qp); @@ -377,12 +307,6 @@ struct hypot_retval typedef typename NumTraits::Real type; }; -template -inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y) -{ - return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y); -} - /**************************************************************************** * Implementation of cast * ****************************************************************************/ @@ -405,97 +329,29 @@ inline NewType cast(const OldType& x) } /**************************************************************************** -* Implementation of sqrt * +* Implementation of atanh2 * ****************************************************************************/ template -struct sqrt_default_impl -{ - static inline Scalar run(const Scalar& x) - { - using std::sqrt; - return sqrt(x); - } -}; - -template -struct sqrt_default_impl -{ - static inline Scalar run(const Scalar&) - { -#ifdef EIGEN2_SUPPORT - eigen_assert(!NumTraits::IsInteger); -#else - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) -#endif - return Scalar(0); - } -}; - -template -struct sqrt_impl : sqrt_default_impl::IsInteger> {}; - -template -struct sqrt_retval -{ - typedef Scalar type; -}; - -template -inline EIGEN_MATHFUNC_RETVAL(sqrt, Scalar) sqrt(const Scalar& x) -{ - return EIGEN_MATHFUNC_IMPL(sqrt, Scalar)::run(x); -} - -/**************************************************************************** -* Implementation of standard unary real functions (exp, log, sin, cos, ... * -****************************************************************************/ - -// This macro instanciate all the necessary template mechanism which is common to all unary real functions. -#define EIGEN_MATHFUNC_STANDARD_REAL_UNARY(NAME) \ - template struct NAME##_default_impl { \ - static inline Scalar run(const Scalar& x) { using std::NAME; return NAME(x); } \ - }; \ - template struct NAME##_default_impl { \ - static inline Scalar run(const Scalar&) { \ - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) \ - return Scalar(0); \ - } \ - }; \ - template struct NAME##_impl \ - : NAME##_default_impl::IsInteger> \ - {}; \ - template struct NAME##_retval { typedef Scalar type; }; \ - template \ - inline EIGEN_MATHFUNC_RETVAL(NAME, Scalar) NAME(const Scalar& x) { \ - return EIGEN_MATHFUNC_IMPL(NAME, Scalar)::run(x); \ - } - -EIGEN_MATHFUNC_STANDARD_REAL_UNARY(exp) -EIGEN_MATHFUNC_STANDARD_REAL_UNARY(log) -EIGEN_MATHFUNC_STANDARD_REAL_UNARY(sin) -EIGEN_MATHFUNC_STANDARD_REAL_UNARY(cos) -EIGEN_MATHFUNC_STANDARD_REAL_UNARY(tan) -EIGEN_MATHFUNC_STANDARD_REAL_UNARY(asin) -EIGEN_MATHFUNC_STANDARD_REAL_UNARY(acos) - -/**************************************************************************** -* Implementation of atan2 * -****************************************************************************/ - -template -struct atan2_default_impl +struct atanh2_default_impl { typedef Scalar retval; + typedef typename NumTraits::Real RealScalar; static inline Scalar run(const Scalar& x, const Scalar& y) { - using std::atan2; - return atan2(x, y); + using std::abs; + using std::log; + using std::sqrt; + Scalar z = x / y; + if (y == Scalar(0) || abs(z) > sqrt(NumTraits::epsilon())) + return RealScalar(0.5) * log((y + x) / (y - x)); + else + return z + z*z*z / RealScalar(3); } }; template -struct atan2_default_impl +struct atanh2_default_impl { static inline Scalar run(const Scalar&, const Scalar&) { @@ -505,20 +361,14 @@ struct atan2_default_impl }; template -struct atan2_impl : atan2_default_impl::IsInteger> {}; +struct atanh2_impl : atanh2_default_impl::IsInteger> {}; template -struct atan2_retval +struct atanh2_retval { typedef Scalar type; }; -template -inline EIGEN_MATHFUNC_RETVAL(atan2, Scalar) atan2(const Scalar& x, const Scalar& y) -{ - return EIGEN_MATHFUNC_IMPL(atan2, Scalar)::run(x, y); -} - /**************************************************************************** * Implementation of pow * ****************************************************************************/ @@ -562,12 +412,6 @@ struct pow_retval typedef Scalar type; }; -template -inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y) -{ - return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y); -} - /**************************************************************************** * Implementation of random * ****************************************************************************/ @@ -666,11 +510,10 @@ struct random_default_impl #else enum { rand_bits = floor_log2<(unsigned int)(RAND_MAX)+1>::value, scalar_bits = sizeof(Scalar) * CHAR_BIT, - shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits)) + shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits)), + offset = NumTraits::IsSigned ? (1 << (EIGEN_PLAIN_ENUM_MIN(rand_bits,scalar_bits)-1)) : 0 }; - Scalar x = Scalar(std::rand() >> shift); - Scalar offset = NumTraits::IsSigned ? Scalar(1 << (rand_bits-1)) : Scalar(0); - return x - offset; + return Scalar((std::rand() >> shift) - offset); #endif } }; @@ -702,6 +545,97 @@ inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random() return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(); } +} // end namespace internal + +/**************************************************************************** +* Generic math function * +****************************************************************************/ + +namespace numext { + +template +inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x); +} + +template +inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x) +{ + return internal::real_ref_impl::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x); +} + +template +inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x) +{ + return internal::imag_ref_impl::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x); +} + +template +inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y) +{ + return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y); +} + +template +inline EIGEN_MATHFUNC_RETVAL(atanh2, Scalar) atanh2(const Scalar& x, const Scalar& y) +{ + return EIGEN_MATHFUNC_IMPL(atanh2, Scalar)::run(x, y); +} + +template +inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y) +{ + return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y); +} + +// std::isfinite is non standard, so let's define our own version, +// even though it is not very efficient. +template bool (isfinite)(const T& x) +{ + return x::highest() && x>NumTraits::lowest(); +} + +} // end namespace numext + +namespace internal { + /**************************************************************************** * Implementation of fuzzy comparisons * ****************************************************************************/ @@ -718,11 +652,13 @@ struct scalar_fuzzy_default_impl template static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec) { + using std::abs; return abs(x) <= abs(y) * prec; } static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec) { using std::min; + using std::abs; return abs(x - y) <= (min)(abs(x), abs(y)) * prec; } static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec) @@ -757,12 +693,12 @@ struct scalar_fuzzy_default_impl template static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec) { - return abs2(x) <= abs2(y) * prec * prec; + return numext::abs2(x) <= numext::abs2(y) * prec * prec; } static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec) { using std::min; - return abs2(x - y) <= (min)(abs2(x), abs2(y)) * prec * prec; + return numext::abs2(x - y) <= (min)(numext::abs2(x), numext::abs2(y)) * prec * prec; } }; @@ -824,17 +760,7 @@ template<> struct scalar_fuzzy_impl }; -/**************************************************************************** -* Special functions * -****************************************************************************/ - -// std::isfinite is non standard, so let's define our own version, -// even though it is not very efficient. -template bool (isfinite)(const T& x) -{ - return x::highest() && x>NumTraits::lowest(); -} - + } // end namespace internal } // end namespace Eigen diff --git a/eigenlib/Eigen/src/Core/Matrix.h b/eigenlib/Eigen/src/Core/Matrix.h index 99160b59..d7d0b5b9 100644 --- a/eigenlib/Eigen/src/Core/Matrix.h +++ b/eigenlib/Eigen/src/Core/Matrix.h @@ -200,16 +200,16 @@ class Matrix * * \sa resize(Index,Index) */ - EIGEN_STRONG_INLINE explicit Matrix() : Base() + EIGEN_STRONG_INLINE Matrix() : Base() { Base::_check_template_params(); - EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED } // FIXME is it still needed Matrix(internal::constructor_without_unaligned_array_assert) : Base(internal::constructor_without_unaligned_array_assert()) - { Base::_check_template_params(); EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED } + { Base::_check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED } /** \brief Constructs a vector or row-vector with given dimension. \only_for_vectors * @@ -224,7 +224,7 @@ class Matrix EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix) eigen_assert(dim >= 0); eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim); - EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED } #ifndef EIGEN_PARSED_BY_DOXYGEN @@ -304,7 +304,7 @@ class Matrix : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) { Base::_check_template_params(); - Base::resize(other.rows(), other.cols()); + Base::_resize_to_match(other); // FIXME/CHECK: isn't *this = other.derived() more efficient. it allows to // go for pure _set() implementations, right? *this = other; diff --git a/eigenlib/Eigen/src/Core/MatrixBase.h b/eigenlib/Eigen/src/Core/MatrixBase.h index 36ea2cee..344b38f2 100644 --- a/eigenlib/Eigen/src/Core/MatrixBase.h +++ b/eigenlib/Eigen/src/Core/MatrixBase.h @@ -162,6 +162,9 @@ template class MatrixBase #ifndef EIGEN_PARSED_BY_DOXYGEN template Derived& lazyAssign(const ProductBase& other); + + template + Derived& lazyAssign(const MatrixPowerProduct& other); #endif // not EIGEN_PARSED_BY_DOXYGEN template @@ -212,8 +215,8 @@ template class MatrixBase typedef Diagonal DiagonalReturnType; DiagonalReturnType diagonal(); - typedef const Diagonal ConstDiagonalReturnType; - const ConstDiagonalReturnType diagonal() const; + typedef typename internal::add_const >::type ConstDiagonalReturnType; + ConstDiagonalReturnType diagonal() const; template struct DiagonalIndexReturnType { typedef Diagonal Type; }; template struct ConstDiagonalIndexReturnType { typedef const Diagonal Type; }; @@ -224,11 +227,11 @@ template class MatrixBase // Note: The "MatrixBase::" prefixes are added to help MSVC9 to match these declarations with the later implementations. // On the other hand they confuse MSVC8... #if (defined _MSC_VER) && (_MSC_VER >= 1500) // 2008 or later - typename MatrixBase::template DiagonalIndexReturnType::Type diagonal(Index index); - typename MatrixBase::template ConstDiagonalIndexReturnType::Type diagonal(Index index) const; + typename MatrixBase::template DiagonalIndexReturnType::Type diagonal(Index index); + typename MatrixBase::template ConstDiagonalIndexReturnType::Type diagonal(Index index) const; #else - typename DiagonalIndexReturnType::Type diagonal(Index index); - typename ConstDiagonalIndexReturnType::Type diagonal(Index index) const; + typename DiagonalIndexReturnType::Type diagonal(Index index); + typename ConstDiagonalIndexReturnType::Type diagonal(Index index) const; #endif #ifdef EIGEN2_SUPPORT @@ -255,7 +258,7 @@ template class MatrixBase template typename ConstSelfAdjointViewReturnType::Type selfadjointView() const; const SparseView sparseView(const Scalar& m_reference = Scalar(0), - typename NumTraits::Real m_epsilon = NumTraits::dummy_precision()) const; + const typename NumTraits::Real& m_epsilon = NumTraits::dummy_precision()) const; static const IdentityReturnType Identity(); static const IdentityReturnType Identity(Index rows, Index cols); static const BasisReturnType Unit(Index size, Index i); @@ -271,16 +274,16 @@ template class MatrixBase Derived& setIdentity(); Derived& setIdentity(Index rows, Index cols); - bool isIdentity(RealScalar prec = NumTraits::dummy_precision()) const; - bool isDiagonal(RealScalar prec = NumTraits::dummy_precision()) const; + bool isIdentity(const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isDiagonal(const RealScalar& prec = NumTraits::dummy_precision()) const; - bool isUpperTriangular(RealScalar prec = NumTraits::dummy_precision()) const; - bool isLowerTriangular(RealScalar prec = NumTraits::dummy_precision()) const; + bool isUpperTriangular(const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isLowerTriangular(const RealScalar& prec = NumTraits::dummy_precision()) const; template bool isOrthogonal(const MatrixBase& other, - RealScalar prec = NumTraits::dummy_precision()) const; - bool isUnitary(RealScalar prec = NumTraits::dummy_precision()) const; + const RealScalar& prec = NumTraits::dummy_precision()) const; + bool isUnitary(const RealScalar& prec = NumTraits::dummy_precision()) const; /** \returns true if each coefficients of \c *this and \a other are all exactly equal. * \warning When using floating point scalar values you probably should rather use a @@ -314,7 +317,7 @@ template class MatrixBase MatrixBase& matrix() { return *this; } const MatrixBase& matrix() const { return *this; } - /** \returns an \link ArrayBase Array \endlink expression of this matrix + /** \returns an \link Eigen::ArrayBase Array \endlink expression of this matrix * \sa ArrayBase::matrix() */ ArrayWrapper array() { return derived(); } const ArrayWrapper array() const { return derived(); } @@ -454,6 +457,7 @@ template class MatrixBase const MatrixFunctionReturnValue sin() const; const MatrixSquareRootReturnValue sqrt() const; const MatrixLogarithmReturnValue log() const; + const MatrixPowerReturnValue pow(const RealScalar& p) const; #ifdef EIGEN2_SUPPORT template @@ -506,6 +510,51 @@ template class MatrixBase {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;} }; + +/*************************************************************************** +* Implementation of matrix base methods +***************************************************************************/ + +/** replaces \c *this by \c *this * \a other. + * + * \returns a reference to \c *this + * + * Example: \include MatrixBase_applyOnTheRight.cpp + * Output: \verbinclude MatrixBase_applyOnTheRight.out + */ +template +template +inline Derived& +MatrixBase::operator*=(const EigenBase &other) +{ + other.derived().applyThisOnTheRight(derived()); + return derived(); +} + +/** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=(). + * + * Example: \include MatrixBase_applyOnTheRight.cpp + * Output: \verbinclude MatrixBase_applyOnTheRight.out + */ +template +template +inline void MatrixBase::applyOnTheRight(const EigenBase &other) +{ + other.derived().applyThisOnTheRight(derived()); +} + +/** replaces \c *this by \a other * \c *this. + * + * Example: \include MatrixBase_applyOnTheLeft.cpp + * Output: \verbinclude MatrixBase_applyOnTheLeft.out + */ +template +template +inline void MatrixBase::applyOnTheLeft(const EigenBase &other) +{ + other.derived().applyThisOnTheLeft(derived()); +} + } // end namespace Eigen #endif // EIGEN_MATRIXBASE_H diff --git a/eigenlib/Eigen/src/Core/NoAlias.h b/eigenlib/Eigen/src/Core/NoAlias.h index ecb3fa28..768bfb18 100644 --- a/eigenlib/Eigen/src/Core/NoAlias.h +++ b/eigenlib/Eigen/src/Core/NoAlias.h @@ -80,8 +80,17 @@ class NoAlias template EIGEN_STRONG_INLINE ExpressionType& operator-=(const CoeffBasedProduct& other) { return m_expression.derived() -= CoeffBasedProduct(other.lhs(), other.rhs()); } + + template + ExpressionType& operator=(const ReturnByValue& func) + { return m_expression = func; } #endif + ExpressionType& expression() const + { + return m_expression; + } + protected: ExpressionType& m_expression; }; diff --git a/eigenlib/Eigen/src/Core/NumTraits.h b/eigenlib/Eigen/src/Core/NumTraits.h index c94ef026..bac9e50b 100644 --- a/eigenlib/Eigen/src/Core/NumTraits.h +++ b/eigenlib/Eigen/src/Core/NumTraits.h @@ -140,6 +140,9 @@ struct NumTraits > AddCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits::AddCost, MulCost = ArrayType::SizeAtCompileTime==Dynamic ? Dynamic : ArrayType::SizeAtCompileTime * NumTraits::MulCost }; + + static inline RealScalar epsilon() { return NumTraits::epsilon(); } + static inline RealScalar dummy_precision() { return NumTraits::dummy_precision(); } }; } // end namespace Eigen diff --git a/eigenlib/Eigen/src/Core/PermutationMatrix.h b/eigenlib/Eigen/src/Core/PermutationMatrix.h index bc29f814..1297b841 100644 --- a/eigenlib/Eigen/src/Core/PermutationMatrix.h +++ b/eigenlib/Eigen/src/Core/PermutationMatrix.h @@ -105,13 +105,13 @@ class PermutationBase : public EigenBase #endif /** \returns the number of rows */ - inline Index rows() const { return indices().size(); } + inline Index rows() const { return Index(indices().size()); } /** \returns the number of columns */ - inline Index cols() const { return indices().size(); } + inline Index cols() const { return Index(indices().size()); } /** \returns the size of a side of the respective square matrix, i.e., the number of indices */ - inline Index size() const { return indices().size(); } + inline Index size() const { return Index(indices().size()); } #ifndef EIGEN_PARSED_BY_DOXYGEN template @@ -139,9 +139,9 @@ class PermutationBase : public EigenBase /** Resizes to given size. */ - inline void resize(Index size) + inline void resize(Index newSize) { - indices().resize(size); + indices().resize(newSize); } /** Sets *this to be the identity permutation matrix */ @@ -153,9 +153,9 @@ class PermutationBase : public EigenBase /** Sets *this to be the identity permutation matrix of given size. */ - void setIdentity(Index size) + void setIdentity(Index newSize) { - resize(size); + resize(newSize); setIdentity(); } @@ -317,7 +317,7 @@ class PermutationMatrix : public PermutationBase - explicit inline PermutationMatrix(const MatrixBase& indices) : m_indices(indices) + explicit inline PermutationMatrix(const MatrixBase& a_indices) : m_indices(a_indices) {} /** Convert the Transpositions \a tr to a permutation matrix */ @@ -406,12 +406,12 @@ class Map, typedef typename IndicesType::Scalar Index; #endif - inline Map(const Index* indices) - : m_indices(indices) + inline Map(const Index* indicesPtr) + : m_indices(indicesPtr) {} - inline Map(const Index* indices, Index size) - : m_indices(indices,size) + inline Map(const Index* indicesPtr, Index size) + : m_indices(indicesPtr,size) {} /** Copies the other permutation into *this */ @@ -490,8 +490,8 @@ class PermutationWrapper : public PermutationBase > { typedef typename remove_all::type MatrixTypeNestedCleaned; + typedef typename MatrixType::Index Index; permut_matrix_product_retval(const PermutationType& perm, const MatrixType& matrix) : m_permutation(perm), m_matrix(matrix) {} - inline int rows() const { return m_matrix.rows(); } - inline int cols() const { return m_matrix.cols(); } + inline Index rows() const { return m_matrix.rows(); } + inline Index cols() const { return m_matrix.cols(); } template inline void evalTo(Dest& dst) const { - const int n = Side==OnTheLeft ? rows() : cols(); - + const Index n = Side==OnTheLeft ? rows() : cols(); + // FIXME we need an is_same for expression that is not sensitive to constness. For instance + // is_same_xpr, Block >::value should be true. if(is_same::value && extract_data(dst) == extract_data(m_matrix)) { // apply the permutation inplace Matrix mask(m_permutation.size()); mask.fill(false); - int r = 0; + Index r = 0; while(r < m_permutation.size()) { // search for the next seed @@ -566,10 +568,10 @@ struct permut_matrix_product_retval if(r>=m_permutation.size()) break; // we got one, let's follow it until we are back to the seed - int k0 = r++; - int kPrev = k0; + Index k0 = r++; + Index kPrev = k0; mask.coeffRef(k0) = true; - for(int k=m_permutation.indices().coeff(k0); k!=k0; k=m_permutation.indices().coeff(k)) + for(Index k=m_permutation.indices().coeff(k0); k!=k0; k=m_permutation.indices().coeff(k)) { Block(dst, k) .swap(Block diff --git a/eigenlib/Eigen/src/Core/PlainObjectBase.h b/eigenlib/Eigen/src/Core/PlainObjectBase.h index 71c74309..dd34b59e 100644 --- a/eigenlib/Eigen/src/Core/PlainObjectBase.h +++ b/eigenlib/Eigen/src/Core/PlainObjectBase.h @@ -11,30 +11,46 @@ #ifndef EIGEN_DENSESTORAGEBASE_H #define EIGEN_DENSESTORAGEBASE_H -#ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO -# define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED for(int i=0;i::quiet_NaN(); #else -# define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED +# undef EIGEN_INITIALIZE_COEFFS +# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED #endif namespace Eigen { namespace internal { -template -EIGEN_ALWAYS_INLINE void check_rows_cols_for_overflow(Index rows, Index cols) -{ - // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242 - // we assume Index is signed - Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed - bool error = (rows < 0 || cols < 0) ? true - : (rows == 0 || cols == 0) ? false - : (rows > max_index / cols); - if (error) - throw_std_bad_alloc(); -} +template struct check_rows_cols_for_overflow { + template + static EIGEN_ALWAYS_INLINE void run(Index, Index) + { + } +}; -template struct conservative_resize_like_impl; +template<> struct check_rows_cols_for_overflow { + template + static EIGEN_ALWAYS_INLINE void run(Index rows, Index cols) + { + // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242 + // we assume Index is signed + Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed + bool error = (rows == 0 || cols == 0) ? false + : (rows > max_index / cols); + if (error) + throw_std_bad_alloc(); + } +}; + +template +struct conservative_resize_like_impl; template struct matrix_swap_impl; @@ -119,12 +135,12 @@ class PlainObjectBase : public internal::dense_xpr_base::type EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); } EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); } - EIGEN_STRONG_INLINE const Scalar& coeff(Index row, Index col) const + EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const { if(Flags & RowMajorBit) - return m_storage.data()[col + row * m_storage.cols()]; + return m_storage.data()[colId + rowId * m_storage.cols()]; else // column-major - return m_storage.data()[row + col * m_storage.rows()]; + return m_storage.data()[rowId + colId * m_storage.rows()]; } EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const @@ -132,12 +148,12 @@ class PlainObjectBase : public internal::dense_xpr_base::type return m_storage.data()[index]; } - EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) + EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId) { if(Flags & RowMajorBit) - return m_storage.data()[col + row * m_storage.cols()]; + return m_storage.data()[colId + rowId * m_storage.cols()]; else // column-major - return m_storage.data()[row + col * m_storage.rows()]; + return m_storage.data()[rowId + colId * m_storage.rows()]; } EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) @@ -145,12 +161,12 @@ class PlainObjectBase : public internal::dense_xpr_base::type return m_storage.data()[index]; } - EIGEN_STRONG_INLINE const Scalar& coeffRef(Index row, Index col) const + EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const { if(Flags & RowMajorBit) - return m_storage.data()[col + row * m_storage.cols()]; + return m_storage.data()[colId + rowId * m_storage.cols()]; else // column-major - return m_storage.data()[row + col * m_storage.rows()]; + return m_storage.data()[rowId + colId * m_storage.rows()]; } EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const @@ -160,12 +176,12 @@ class PlainObjectBase : public internal::dense_xpr_base::type /** \internal */ template - EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const + EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const { return internal::ploadt (m_storage.data() + (Flags & RowMajorBit - ? col + row * m_storage.cols() - : row + col * m_storage.rows())); + ? colId + rowId * m_storage.cols() + : rowId + colId * m_storage.rows())); } /** \internal */ @@ -177,19 +193,19 @@ class PlainObjectBase : public internal::dense_xpr_base::type /** \internal */ template - EIGEN_STRONG_INLINE void writePacket(Index row, Index col, const PacketScalar& x) + EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val) { internal::pstoret (m_storage.data() + (Flags & RowMajorBit - ? col + row * m_storage.cols() - : row + col * m_storage.rows()), x); + ? colId + rowId * m_storage.cols() + : rowId + colId * m_storage.rows()), val); } /** \internal */ template - EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& x) + EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val) { - internal::pstoret(m_storage.data() + index, x); + internal::pstoret(m_storage.data() + index, val); } /** \returns a const pointer to the data array of this matrix */ @@ -216,17 +232,22 @@ class PlainObjectBase : public internal::dense_xpr_base::type * * \sa resize(Index) for vectors, resize(NoChange_t, Index), resize(Index, NoChange_t) */ - EIGEN_STRONG_INLINE void resize(Index rows, Index cols) + EIGEN_STRONG_INLINE void resize(Index nbRows, Index nbCols) { - #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO - internal::check_rows_cols_for_overflow(rows, cols); - Index size = rows*cols; + eigen_assert( EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,nbRows==RowsAtCompileTime) + && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,nbCols==ColsAtCompileTime) + && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,nbRows<=MaxRowsAtCompileTime) + && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,nbCols<=MaxColsAtCompileTime) + && nbRows>=0 && nbCols>=0 && "Invalid sizes when resizing a matrix or array."); + internal::check_rows_cols_for_overflow::run(nbRows, nbCols); + #ifdef EIGEN_INITIALIZE_COEFFS + Index size = nbRows*nbCols; bool size_changed = size != this->size(); - m_storage.resize(size, rows, cols); - if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + m_storage.resize(size, nbRows, nbCols); + if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED #else - internal::check_rows_cols_for_overflow(rows, cols); - m_storage.resize(rows*cols, rows, cols); + internal::check_rows_cols_for_overflow::run(nbRows, nbCols); + m_storage.resize(nbRows*nbCols, nbRows, nbCols); #endif } @@ -244,16 +265,16 @@ class PlainObjectBase : public internal::dense_xpr_base::type inline void resize(Index size) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase) - eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size); - #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO + eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0); + #ifdef EIGEN_INITIALIZE_COEFFS bool size_changed = size != this->size(); #endif if(RowsAtCompileTime == 1) m_storage.resize(size, 1, size); else m_storage.resize(size, size, 1); - #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO - if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + #ifdef EIGEN_INITIALIZE_COEFFS + if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED #endif } @@ -265,9 +286,9 @@ class PlainObjectBase : public internal::dense_xpr_base::type * * \sa resize(Index,Index) */ - inline void resize(NoChange_t, Index cols) + inline void resize(NoChange_t, Index nbCols) { - resize(rows(), cols); + resize(rows(), nbCols); } /** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange @@ -278,9 +299,9 @@ class PlainObjectBase : public internal::dense_xpr_base::type * * \sa resize(Index,Index) */ - inline void resize(Index rows, NoChange_t) + inline void resize(Index nbRows, NoChange_t) { - resize(rows, cols()); + resize(nbRows, cols()); } /** Resizes \c *this to have the same dimensions as \a other. @@ -294,7 +315,7 @@ class PlainObjectBase : public internal::dense_xpr_base::type EIGEN_STRONG_INLINE void resizeLike(const EigenBase& _other) { const OtherDerived& other = _other.derived(); - internal::check_rows_cols_for_overflow(other.rows(), other.cols()); + internal::check_rows_cols_for_overflow::run(other.rows(), other.cols()); const Index othersize = other.rows()*other.cols(); if(RowsAtCompileTime == 1) { @@ -318,9 +339,9 @@ class PlainObjectBase : public internal::dense_xpr_base::type * Matrices are resized relative to the top-left element. In case values need to be * appended to the matrix they will be uninitialized. */ - EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols) + EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, Index nbCols) { - internal::conservative_resize_like_impl::run(*this, rows, cols); + internal::conservative_resize_like_impl::run(*this, nbRows, nbCols); } /** Resizes the matrix to \a rows x \a cols while leaving old values untouched. @@ -330,10 +351,10 @@ class PlainObjectBase : public internal::dense_xpr_base::type * * In case the matrix is growing, new rows will be uninitialized. */ - EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t) + EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, NoChange_t) { // Note: see the comment in conservativeResize(Index,Index) - conservativeResize(rows, cols()); + conservativeResize(nbRows, cols()); } /** Resizes the matrix to \a rows x \a cols while leaving old values untouched. @@ -343,10 +364,10 @@ class PlainObjectBase : public internal::dense_xpr_base::type * * In case the matrix is growing, new columns will be uninitialized. */ - EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols) + EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index nbCols) { // Note: see the comment in conservativeResize(Index,Index) - conservativeResize(rows(), cols); + conservativeResize(rows(), nbCols); } /** Resizes the vector to \a size while retaining old values. @@ -400,10 +421,10 @@ class PlainObjectBase : public internal::dense_xpr_base::type return Base::operator=(func); } - EIGEN_STRONG_INLINE explicit PlainObjectBase() : m_storage() + EIGEN_STRONG_INLINE PlainObjectBase() : m_storage() { // _check_template_params(); -// EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED +// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED } #ifndef EIGEN_PARSED_BY_DOXYGEN @@ -412,15 +433,15 @@ class PlainObjectBase : public internal::dense_xpr_base::type PlainObjectBase(internal::constructor_without_unaligned_array_assert) : m_storage(internal::constructor_without_unaligned_array_assert()) { -// _check_template_params(); EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED +// _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED } #endif - EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols) - : m_storage(size, rows, cols) + EIGEN_STRONG_INLINE PlainObjectBase(Index a_size, Index nbRows, Index nbCols) + : m_storage(a_size, nbRows, nbCols) { // _check_template_params(); -// EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED +// EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED } /** \copydoc MatrixBase::operator=(const EigenBase&) @@ -439,7 +460,7 @@ class PlainObjectBase : public internal::dense_xpr_base::type : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) { _check_template_params(); - internal::check_rows_cols_for_overflow(other.derived().rows(), other.derived().cols()); + internal::check_rows_cols_for_overflow::run(other.derived().rows(), other.derived().cols()); Base::operator=(other.derived()); } @@ -551,6 +572,7 @@ class PlainObjectBase : public internal::dense_xpr_base::type eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size()) : (rows() == other.rows() && cols() == other.cols()))) && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined"); + EIGEN_ONLY_USED_FOR_DEBUG(other); #else resizeLike(other); #endif @@ -600,23 +622,19 @@ class PlainObjectBase : public internal::dense_xpr_base::type } template - EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if::type* = 0) + EIGEN_STRONG_INLINE void _init2(Index nbRows, Index nbCols, typename internal::enable_if::type* = 0) { EIGEN_STATIC_ASSERT(bool(NumTraits::IsInteger) && bool(NumTraits::IsInteger), FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED) - eigen_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) - && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)); - internal::check_rows_cols_for_overflow(rows, cols); - m_storage.resize(rows*cols,rows,cols); - EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + resize(nbRows,nbCols); } template - EIGEN_STRONG_INLINE void _init2(const Scalar& x, const Scalar& y, typename internal::enable_if::type* = 0) + EIGEN_STRONG_INLINE void _init2(const Scalar& val0, const Scalar& val1, typename internal::enable_if::type* = 0) { EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2) - m_storage.data()[0] = x; - m_storage.data()[1] = y; + m_storage.data()[0] = val0; + m_storage.data()[1] = val1; } template @@ -653,8 +671,10 @@ private: enum { ThisConstantIsPrivateInPlainObjectBase }; }; +namespace internal { + template -struct internal::conservative_resize_like_impl +struct conservative_resize_like_impl { typedef typename Derived::Index Index; static void run(DenseBase& _this, Index rows, Index cols) @@ -665,7 +685,7 @@ struct internal::conservative_resize_like_impl if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows (!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns { - internal::check_rows_cols_for_overflow(rows, cols); + internal::check_rows_cols_for_overflow::run(rows, cols); _this.derived().m_storage.conservativeResize(rows*cols,rows,cols); } else @@ -714,11 +734,14 @@ struct internal::conservative_resize_like_impl } }; -namespace internal { - +// Here, the specialization for vectors inherits from the general matrix case +// to allow calling .conservativeResize(rows,cols) on vectors. template struct conservative_resize_like_impl + : conservative_resize_like_impl { + using conservative_resize_like_impl::run; + typedef typename Derived::Index Index; static void run(DenseBase& _this, Index size) { diff --git a/eigenlib/Eigen/src/Core/Product.h b/eigenlib/Eigen/src/Core/Product.h deleted file mode 100644 index 30aa8943..00000000 --- a/eigenlib/Eigen/src/Core/Product.h +++ /dev/null @@ -1,98 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2011 Gael Guennebaud -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_PRODUCT_H -#define EIGEN_PRODUCT_H - -template class Product; -template class ProductImpl; - -/** \class Product - * \ingroup Core_Module - * - * \brief Expression of the product of two arbitrary matrices or vectors - * - * \param Lhs the type of the left-hand side expression - * \param Rhs the type of the right-hand side expression - * - * This class represents an expression of the product of two arbitrary matrices. - * - */ - -namespace internal { -template -struct traits > -{ - typedef MatrixXpr XprKind; - typedef typename remove_all::type LhsCleaned; - typedef typename remove_all::type RhsCleaned; - typedef typename scalar_product_traits::Scalar, typename traits::Scalar>::ReturnType Scalar; - typedef typename promote_storage_type::StorageKind, - typename traits::StorageKind>::ret StorageKind; - typedef typename promote_index_type::Index, - typename traits::Index>::type Index; - enum { - RowsAtCompileTime = LhsCleaned::RowsAtCompileTime, - ColsAtCompileTime = RhsCleaned::ColsAtCompileTime, - MaxRowsAtCompileTime = LhsCleaned::MaxRowsAtCompileTime, - MaxColsAtCompileTime = RhsCleaned::MaxColsAtCompileTime, - Flags = (MaxRowsAtCompileTime==1 ? RowMajorBit : 0), // TODO should be no storage order - CoeffReadCost = 0 // TODO CoeffReadCost should not be part of the expression traits - }; -}; -} // end namespace internal - - -template -class Product : public ProductImpl::StorageKind, - typename internal::traits::StorageKind>::ret> -{ - public: - - typedef typename ProductImpl< - Lhs, Rhs, - typename internal::promote_storage_type::ret>::Base Base; - EIGEN_GENERIC_PUBLIC_INTERFACE(Product) - - typedef typename Lhs::Nested LhsNested; - typedef typename Rhs::Nested RhsNested; - typedef typename internal::remove_all::type LhsNestedCleaned; - typedef typename internal::remove_all::type RhsNestedCleaned; - - Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs) - { - eigen_assert(lhs.cols() == rhs.rows() - && "invalid matrix product" - && "if you wanted a coeff-wise or a dot product use the respective explicit functions"); - } - - inline Index rows() const { return m_lhs.rows(); } - inline Index cols() const { return m_rhs.cols(); } - - const LhsNestedCleaned& lhs() const { return m_lhs; } - const RhsNestedCleaned& rhs() const { return m_rhs; } - - protected: - - const LhsNested m_lhs; - const RhsNested m_rhs; -}; - -template -class ProductImpl : public internal::dense_xpr_base >::type -{ - typedef Product Derived; - public: - - typedef typename internal::dense_xpr_base >::type Base; - EIGEN_DENSE_PUBLIC_INTERFACE(Derived) -}; - -#endif // EIGEN_PRODUCT_H diff --git a/eigenlib/Eigen/src/Core/ProductBase.h b/eigenlib/Eigen/src/Core/ProductBase.h index ec12e5c9..a494b5f8 100644 --- a/eigenlib/Eigen/src/Core/ProductBase.h +++ b/eigenlib/Eigen/src/Core/ProductBase.h @@ -87,10 +87,10 @@ class ProductBase : public MatrixBase typedef typename Base::PlainObject PlainObject; - ProductBase(const Lhs& lhs, const Rhs& rhs) - : m_lhs(lhs), m_rhs(rhs) + ProductBase(const Lhs& a_lhs, const Rhs& a_rhs) + : m_lhs(a_lhs), m_rhs(a_rhs) { - eigen_assert(lhs.cols() == rhs.rows() + eigen_assert(a_lhs.cols() == a_rhs.rows() && "invalid matrix product" && "if you wanted a coeff-wise or a dot product use the respective explicit functions"); } @@ -108,7 +108,7 @@ class ProductBase : public MatrixBase inline void subTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(-1)); } template - inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { derived().scaleAndAddTo(dst,alpha); } + inline void scaleAndAddTo(Dest& dst, const Scalar& alpha) const { derived().scaleAndAddTo(dst,alpha); } const _LhsNested& lhs() const { return m_lhs; } const _RhsNested& rhs() const { return m_rhs; } @@ -195,25 +195,25 @@ class ScaledProduct; // Also note that here we accept any compatible scalar types template const ScaledProduct -operator*(const ProductBase& prod, typename Derived::Scalar x) +operator*(const ProductBase& prod, const typename Derived::Scalar& x) { return ScaledProduct(prod.derived(), x); } template typename internal::enable_if::value, const ScaledProduct >::type -operator*(const ProductBase& prod, typename Derived::RealScalar x) +operator*(const ProductBase& prod, const typename Derived::RealScalar& x) { return ScaledProduct(prod.derived(), x); } template const ScaledProduct -operator*(typename Derived::Scalar x,const ProductBase& prod) +operator*(const typename Derived::Scalar& x,const ProductBase& prod) { return ScaledProduct(prod.derived(), x); } template typename internal::enable_if::value, const ScaledProduct >::type -operator*(typename Derived::RealScalar x,const ProductBase& prod) +operator*(const typename Derived::RealScalar& x,const ProductBase& prod) { return ScaledProduct(prod.derived(), x); } namespace internal { @@ -241,7 +241,7 @@ class ScaledProduct typedef typename Base::PlainObject PlainObject; // EIGEN_PRODUCT_PUBLIC_INTERFACE(ScaledProduct) - ScaledProduct(const NestedProduct& prod, Scalar x) + ScaledProduct(const NestedProduct& prod, const Scalar& x) : Base(prod.lhs(),prod.rhs()), m_prod(prod), m_alpha(x) {} template @@ -254,7 +254,7 @@ class ScaledProduct inline void subTo(Dest& dst) const { scaleAndAddTo(dst, Scalar(-1)); } template - inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { m_prod.derived().scaleAndAddTo(dst,alpha * m_alpha); } + inline void scaleAndAddTo(Dest& dst, const Scalar& a_alpha) const { m_prod.derived().scaleAndAddTo(dst,a_alpha * m_alpha); } const Scalar& alpha() const { return m_alpha; } diff --git a/eigenlib/Eigen/src/Core/Random.h b/eigenlib/Eigen/src/Core/Random.h index a9f7f434..480fea40 100644 --- a/eigenlib/Eigen/src/Core/Random.h +++ b/eigenlib/Eigen/src/Core/Random.h @@ -112,7 +112,7 @@ inline Derived& DenseBase::setRandom() return *this = Random(rows(), cols()); } -/** Resizes to the given \a size, and sets all coefficients in this expression to random values. +/** Resizes to the given \a newSize, and sets all coefficients in this expression to random values. * * \only_for_vectors * @@ -123,16 +123,16 @@ inline Derived& DenseBase::setRandom() */ template EIGEN_STRONG_INLINE Derived& -PlainObjectBase::setRandom(Index size) +PlainObjectBase::setRandom(Index newSize) { - resize(size); + resize(newSize); return setRandom(); } /** Resizes to the given size, and sets all coefficients in this expression to random values. * - * \param rows the new number of rows - * \param cols the new number of columns + * \param nbRows the new number of rows + * \param nbCols the new number of columns * * Example: \include Matrix_setRandom_int_int.cpp * Output: \verbinclude Matrix_setRandom_int_int.out @@ -141,9 +141,9 @@ PlainObjectBase::setRandom(Index size) */ template EIGEN_STRONG_INLINE Derived& -PlainObjectBase::setRandom(Index rows, Index cols) +PlainObjectBase::setRandom(Index nbRows, Index nbCols) { - resize(rows, cols); + resize(nbRows, nbCols); return setRandom(); } diff --git a/eigenlib/Eigen/src/Core/Redux.h b/eigenlib/Eigen/src/Core/Redux.h index b7ce7c65..50548fa9 100644 --- a/eigenlib/Eigen/src/Core/Redux.h +++ b/eigenlib/Eigen/src/Core/Redux.h @@ -330,7 +330,8 @@ DenseBase::redux(const Func& func) const ::run(derived(), func); } -/** \returns the minimum of all coefficients of *this +/** \returns the minimum of all coefficients of \c *this. + * \warning the result is undefined if \c *this contains NaN. */ template EIGEN_STRONG_INLINE typename internal::traits::Scalar @@ -339,7 +340,8 @@ DenseBase::minCoeff() const return this->redux(Eigen::internal::scalar_min_op()); } -/** \returns the maximum of all coefficients of *this +/** \returns the maximum of all coefficients of \c *this. + * \warning the result is undefined if \c *this contains NaN. */ template EIGEN_STRONG_INLINE typename internal::traits::Scalar diff --git a/eigenlib/Eigen/src/Core/Ref.h b/eigenlib/Eigen/src/Core/Ref.h new file mode 100644 index 00000000..00d9e6d2 --- /dev/null +++ b/eigenlib/Eigen/src/Core/Ref.h @@ -0,0 +1,256 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2012 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_REF_H +#define EIGEN_REF_H + +namespace Eigen { + +template class RefBase; +template,OuterStride<> >::type > class Ref; + +/** \class Ref + * \ingroup Core_Module + * + * \brief A matrix or vector expression mapping an existing expressions + * + * \tparam PlainObjectType the equivalent matrix type of the mapped data + * \tparam Options specifies whether the pointer is \c #Aligned, or \c #Unaligned. + * The default is \c #Unaligned. + * \tparam StrideType optionally specifies strides. By default, Ref implies a contiguous storage along the inner dimension (inner stride==1), + * but accept a variable outer stride (leading dimension). + * This can be overridden by specifying strides. + * The type passed here must be a specialization of the Stride template, see examples below. + * + * This class permits to write non template functions taking Eigen's object as parameters while limiting the number of copies. + * A Ref<> object can represent either a const expression or a l-value: + * \code + * // in-out argument: + * void foo1(Ref x); + * + * // read-only const argument: + * void foo2(const Ref& x); + * \endcode + * + * In the in-out case, the input argument must satisfies the constraints of the actual Ref<> type, otherwise a compilation issue will be triggered. + * By default, a Ref can reference any dense vector expression of float having a contiguous memory layout. + * Likewise, a Ref can reference any column major dense matrix expression of float whose column's elements are contiguously stored with + * the possibility to have a constant space inbetween each column, i.e.: the inner stride mmust be equal to 1, but the outer-stride (or leading dimension), + * can be greater than the number of rows. + * + * In the const case, if the input expression does not match the above requirement, then it is evaluated into a temporary before being passed to the function. + * Here are some examples: + * \code + * MatrixXf A; + * VectorXf a; + * foo1(a.head()); // OK + * foo1(A.col()); // OK + * foo1(A.row()); // compilation error because here innerstride!=1 + * foo2(A.row()); // The row is copied into a contiguous temporary + * foo2(2*a); // The expression is evaluated into a temporary + * foo2(A.col().segment(2,4)); // No temporary + * \endcode + * + * The range of inputs that can be referenced without temporary can be enlarged using the last two template parameter. + * Here is an example accepting an innerstride!=1: + * \code + * // in-out argument: + * void foo3(Ref > x); + * foo3(A.row()); // OK + * \endcode + * The downside here is that the function foo3 might be significantly slower than foo1 because it won't be able to exploit vectorization, and will involved more + * expensive address computations even if the input is contiguously stored in memory. To overcome this issue, one might propose to overloads internally calling a + * template function, e.g.: + * \code + * // in the .h: + * void foo(const Ref& A); + * void foo(const Ref >& A); + * + * // in the .cpp: + * template void foo_impl(const TypeOfA& A) { + * ... // crazy code goes here + * } + * void foo(const Ref& A) { foo_impl(A); } + * void foo(const Ref >& A) { foo_impl(A); } + * \endcode + * + * + * \sa PlainObjectBase::Map(), \ref TopicStorageOrders + */ + +namespace internal { + +template +struct traits > + : public traits > +{ + typedef _PlainObjectType PlainObjectType; + typedef _StrideType StrideType; + enum { + Options = _Options, + Flags = traits >::Flags | NestByRefBit + }; + + template struct match { + enum { + HasDirectAccess = internal::has_direct_access::ret, + StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)), + InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic) + || int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime) + || (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1), + OuterStrideMatch = Derived::IsVectorAtCompileTime + || int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime), + AlignmentMatch = (_Options!=Aligned) || ((PlainObjectType::Flags&AlignedBit)==0) || ((traits::Flags&AlignedBit)==AlignedBit), + MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch + }; + typedef typename internal::conditional::type type; + }; + +}; + +template +struct traits > : public traits {}; + +} + +template class RefBase + : public MapBase +{ + typedef typename internal::traits::PlainObjectType PlainObjectType; + typedef typename internal::traits::StrideType StrideType; + +public: + + typedef MapBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(RefBase) + + inline Index innerStride() const + { + return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1; + } + + inline Index outerStride() const + { + return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer() + : IsVectorAtCompileTime ? this->size() + : int(Flags)&RowMajorBit ? this->cols() + : this->rows(); + } + + RefBase() + : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime), + // Stride<> does not allow default ctor for Dynamic strides, so let' initialize it with dummy values: + m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime, + StrideType::InnerStrideAtCompileTime==Dynamic?0:StrideType::InnerStrideAtCompileTime) + {} + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase) + +protected: + + typedef Stride StrideBase; + + template + void construct(Expression& expr) + { + if(PlainObjectType::RowsAtCompileTime==1) + { + eigen_assert(expr.rows()==1 || expr.cols()==1); + ::new (static_cast(this)) Base(expr.data(), 1, expr.size()); + } + else if(PlainObjectType::ColsAtCompileTime==1) + { + eigen_assert(expr.rows()==1 || expr.cols()==1); + ::new (static_cast(this)) Base(expr.data(), expr.size(), 1); + } + else + ::new (static_cast(this)) Base(expr.data(), expr.rows(), expr.cols()); + ::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(), + StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride()); + } + + StrideBase m_stride; +}; + + +template class Ref + : public RefBase > +{ + typedef internal::traits Traits; + public: + + typedef RefBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Ref) + + + #ifndef EIGEN_PARSED_BY_DOXYGEN + template + inline Ref(PlainObjectBase& expr, + typename internal::enable_if::MatchAtCompileTime),Derived>::type* = 0) + { + Base::construct(expr); + } + template + inline Ref(const DenseBase& expr, + typename internal::enable_if::value&&bool(Traits::template match::MatchAtCompileTime)),Derived>::type* = 0, + int = Derived::ThisConstantIsPrivateInPlainObjectBase) + #else + template + inline Ref(DenseBase& expr) + #endif + { + Base::construct(expr.const_cast_derived()); + } + + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref) + +}; + +// this is the const ref version +template class Ref + : public RefBase > +{ + typedef internal::traits Traits; + public: + + typedef RefBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Ref) + + template + inline Ref(const DenseBase& expr) + { +// std::cout << match_helper::HasDirectAccess << "," << match_helper::OuterStrideMatch << "," << match_helper::InnerStrideMatch << "\n"; +// std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n"; +// std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n"; + construct(expr.derived(), typename Traits::template match::type()); + } + + protected: + + template + void construct(const Expression& expr,internal::true_type) + { + Base::construct(expr); + } + + template + void construct(const Expression& expr, internal::false_type) + { + m_object.lazyAssign(expr); + Base::construct(m_object); + } + + protected: + TPlainObjectType m_object; +}; + +} // end namespace Eigen + +#endif // EIGEN_REF_H diff --git a/eigenlib/Eigen/src/Core/Replicate.h b/eigenlib/Eigen/src/Core/Replicate.h index b61fdc29..dde86a83 100644 --- a/eigenlib/Eigen/src/Core/Replicate.h +++ b/eigenlib/Eigen/src/Core/Replicate.h @@ -70,8 +70,8 @@ template class Replicate EIGEN_DENSE_PUBLIC_INTERFACE(Replicate) template - inline explicit Replicate(const OriginalMatrixType& matrix) - : m_matrix(matrix), m_rowFactor(RowFactor), m_colFactor(ColFactor) + inline explicit Replicate(const OriginalMatrixType& a_matrix) + : m_matrix(a_matrix), m_rowFactor(RowFactor), m_colFactor(ColFactor) { EIGEN_STATIC_ASSERT((internal::is_same::type,OriginalMatrixType>::value), THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE) @@ -79,8 +79,8 @@ template class Replicate } template - inline Replicate(const OriginalMatrixType& matrix, Index rowFactor, Index colFactor) - : m_matrix(matrix), m_rowFactor(rowFactor), m_colFactor(colFactor) + inline Replicate(const OriginalMatrixType& a_matrix, Index rowFactor, Index colFactor) + : m_matrix(a_matrix), m_rowFactor(rowFactor), m_colFactor(colFactor) { EIGEN_STATIC_ASSERT((internal::is_same::type,OriginalMatrixType>::value), THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE) @@ -89,27 +89,27 @@ template class Replicate inline Index rows() const { return m_matrix.rows() * m_rowFactor.value(); } inline Index cols() const { return m_matrix.cols() * m_colFactor.value(); } - inline Scalar coeff(Index row, Index col) const + inline Scalar coeff(Index rowId, Index colId) const { // try to avoid using modulo; this is a pure optimization strategy const Index actual_row = internal::traits::RowsAtCompileTime==1 ? 0 - : RowFactor==1 ? row - : row%m_matrix.rows(); + : RowFactor==1 ? rowId + : rowId%m_matrix.rows(); const Index actual_col = internal::traits::ColsAtCompileTime==1 ? 0 - : ColFactor==1 ? col - : col%m_matrix.cols(); + : ColFactor==1 ? colId + : colId%m_matrix.cols(); return m_matrix.coeff(actual_row, actual_col); } template - inline PacketScalar packet(Index row, Index col) const + inline PacketScalar packet(Index rowId, Index colId) const { const Index actual_row = internal::traits::RowsAtCompileTime==1 ? 0 - : RowFactor==1 ? row - : row%m_matrix.rows(); + : RowFactor==1 ? rowId + : rowId%m_matrix.rows(); const Index actual_col = internal::traits::ColsAtCompileTime==1 ? 0 - : ColFactor==1 ? col - : col%m_matrix.cols(); + : ColFactor==1 ? colId + : colId%m_matrix.cols(); return m_matrix.template packet(actual_row, actual_col); } diff --git a/eigenlib/Eigen/src/Core/ReturnByValue.h b/eigenlib/Eigen/src/Core/ReturnByValue.h index 613912ff..d66c24ba 100644 --- a/eigenlib/Eigen/src/Core/ReturnByValue.h +++ b/eigenlib/Eigen/src/Core/ReturnByValue.h @@ -48,7 +48,7 @@ struct nested, n, PlainObject> } // end namespace internal template class ReturnByValue - : public internal::dense_xpr_base< ReturnByValue >::type + : internal::no_assignment_operator, public internal::dense_xpr_base< ReturnByValue >::type { public: typedef typename internal::traits::ReturnType ReturnType; diff --git a/eigenlib/Eigen/src/Core/Select.h b/eigenlib/Eigen/src/Core/Select.h index 2bf6e91d..87993bbb 100644 --- a/eigenlib/Eigen/src/Core/Select.h +++ b/eigenlib/Eigen/src/Core/Select.h @@ -60,10 +60,10 @@ class Select : internal::no_assignment_operator, typedef typename internal::dense_xpr_base