aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Benoit Jacob <jacob.benoit.1@gmail.com>2010-02-25 21:07:30 -0500
committerGravatar Benoit Jacob <jacob.benoit.1@gmail.com>2010-02-25 21:07:30 -0500
commitb1c6c215a43850b2bc5bdc393ab5a1179e858024 (patch)
tree9ae1234383bef2204802606501a47bb5c05ec1d2
parent769641bc58745fecc1fa4e537466a1fff48f4a8a (diff)
parent90e4a605ef920759a23cdbd24e6e7b69ce549162 (diff)
merge
-rw-r--r--CMakeLists.txt113
-rw-r--r--Eigen/Core53
-rw-r--r--Eigen/src/Array/Array.h8
-rw-r--r--Eigen/src/Array/ArrayBase.h4
-rw-r--r--Eigen/src/Array/VectorwiseOp.h2
-rw-r--r--Eigen/src/Cholesky/LDLT.h78
-rw-r--r--Eigen/src/Cholesky/LLT.h22
-rw-r--r--Eigen/src/Core/BandMatrix.h2
-rw-r--r--Eigen/src/Core/DenseBase.h12
-rw-r--r--Eigen/src/Core/DenseStorageBase.h18
-rw-r--r--Eigen/src/Core/DiagonalMatrix.h2
-rw-r--r--Eigen/src/Core/Dot.h2
-rw-r--r--Eigen/src/Core/EigenBase.h (renamed from Eigen/src/Core/AnyMatrixBase.h)30
-rw-r--r--Eigen/src/Core/Flagged.h2
-rw-r--r--Eigen/src/Core/Matrix.h10
-rw-r--r--Eigen/src/Core/MatrixBase.h37
-rw-r--r--Eigen/src/Core/PermutationMatrix.h194
-rw-r--r--Eigen/src/Core/Product.h8
-rw-r--r--Eigen/src/Core/ProductBase.h14
-rw-r--r--Eigen/src/Core/ReturnByValue.h16
-rw-r--r--Eigen/src/Core/SelfAdjointView.h6
-rw-r--r--Eigen/src/Core/SelfCwiseBinaryOp.h8
-rw-r--r--Eigen/src/Core/Transpose.h19
-rw-r--r--Eigen/src/Core/TriangularMatrix.h4
-rw-r--r--Eigen/src/Core/arch/SSE/PacketMath.h8
-rw-r--r--Eigen/src/Core/products/CoeffBasedProduct.h14
-rw-r--r--Eigen/src/Core/products/GeneralBlockPanelKernel.h418
-rw-r--r--Eigen/src/Core/util/BlasUtil.h22
-rw-r--r--Eigen/src/Core/util/ForwardDeclarations.h2
-rw-r--r--Eigen/src/Core/util/Macros.h2
-rw-r--r--Eigen/src/Core/util/XprHelper.h22
-rw-r--r--Eigen/src/Eigen2Support/TriangularSolver.h2
-rw-r--r--Eigen/src/Eigenvalues/ComplexSchur.h42
-rw-r--r--Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h4
-rw-r--r--Eigen/src/Geometry/Homogeneous.h8
-rw-r--r--Eigen/src/Geometry/OrthoMethods.h6
-rw-r--r--Eigen/src/Geometry/Quaternion.h1
-rw-r--r--Eigen/src/Geometry/RotationBase.h4
-rw-r--r--Eigen/src/Geometry/Transform.h12
-rw-r--r--Eigen/src/Geometry/Translation.h6
-rw-r--r--Eigen/src/Householder/Householder.h4
-rw-r--r--Eigen/src/Householder/HouseholderSequence.h2
-rw-r--r--Eigen/src/LU/FullPivLU.h47
-rw-r--r--Eigen/src/LU/Inverse.h4
-rw-r--r--Eigen/src/LU/PartialPivLU.h27
-rw-r--r--Eigen/src/QR/ColPivHouseholderQR.h8
-rw-r--r--Eigen/src/QR/FullPivHouseholderQR.h6
-rw-r--r--Eigen/src/QR/HouseholderQR.h6
-rw-r--r--Eigen/src/SVD/SVD.h4
-rw-r--r--Eigen/src/SVD/UpperBidiagonalization.h4
-rw-r--r--Eigen/src/Sparse/SparseMatrixBase.h6
-rw-r--r--Eigen/src/Sparse/SparseSelfAdjointView.h4
-rw-r--r--Eigen/src/misc/Image.h2
-rw-r--r--Eigen/src/misc/Kernel.h2
-rw-r--r--Eigen/src/misc/Solve.h4
-rw-r--r--bench/BenchTimer.h94
-rwxr-xr-xbench/bench_unrolling3
-rwxr-xr-xbench/benchmark_suite1
-rw-r--r--bench/btl/libs/eigen2/eigen2_interface.hh27
-rw-r--r--cmake/EigenTesting.cmake13
-rw-r--r--disabled/SkylineMatrix.h6
-rw-r--r--test/cholesky.cpp7
-rw-r--r--test/inverse.cpp2
-rw-r--r--test/lu.cpp85
-rw-r--r--test/main.h12
-rw-r--r--test/permutationmatrices.cpp23
-rw-r--r--test/qr_colpivoting.cpp4
-rw-r--r--test/qr_fullpivoting.cpp2
-rw-r--r--test/testsuite.cmake3
-rw-r--r--unsupported/Eigen/FFT92
-rw-r--r--unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h2
-rw-r--r--unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h4
-rw-r--r--unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h14
-rw-r--r--unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h108
-rw-r--r--unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h95
-rw-r--r--unsupported/Eigen/src/Skyline/SkylineMatrixBase.h2
-rw-r--r--unsupported/test/NonLinearOptimization.cpp6
-rw-r--r--unsupported/test/matrix_function.cpp12
78 files changed, 1230 insertions, 754 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f4c2973d5..eefaf4b47 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -52,64 +52,64 @@ else()
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
- if(CMAKE_SYSTEM_NAME MATCHES Linux)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fexceptions -fno-check-new -fno-common -fstrict-aliasing")
- set(CMAKE_CXX_FLAGS_DEBUG "-g3")
- set(CMAKE_CXX_FLAGS_RELEASE "-g0 -O2")
-
- check_cxx_compiler_flag("-Wno-variadic-macros" COMPILER_SUPPORT_WNOVARIADICMACRO)
- if(COMPILER_SUPPORT_WNOVARIADICMACRO)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-variadic-macros")
- endif()
-
- check_cxx_compiler_flag("-Wextra" COMPILER_SUPPORT_WEXTRA)
- if(COMPILER_SUPPORT_WEXTRA)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra")
- endif()
-
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
-
- option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
- if(EIGEN_TEST_SSE2)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2")
- message("Enabling SSE2 in tests/examples")
- endif()
-
- option(EIGEN_TEST_SSE3 "Enable/Disable SSE3 in tests/examples" OFF)
- if(EIGEN_TEST_SSE3)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse3")
- message("Enabling SSE3 in tests/examples")
- endif()
-
- option(EIGEN_TEST_SSSE3 "Enable/Disable SSSE3 in tests/examples" OFF)
- if(EIGEN_TEST_SSSE3)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mssse3")
- message("Enabling SSSE3 in tests/examples")
- endif()
-
- option(EIGEN_TEST_SSE4_1 "Enable/Disable SSE4.1 in tests/examples" OFF)
- if(EIGEN_TEST_SSE4_1)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
- message("Enabling SSE4.1 in tests/examples")
- endif()
-
- option(EIGEN_TEST_SSE4_2 "Enable/Disable SSE4.2 in tests/examples" OFF)
- if(EIGEN_TEST_SSE4_2)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2")
- message("Enabling SSE4.2 in tests/examples")
- endif()
-
- option(EIGEN_TEST_ALTIVEC "Enable/Disable altivec in tests/examples" OFF)
- if(EIGEN_TEST_ALTIVEC)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec -mabi=altivec")
- message("Enabling AltiVec in tests/examples")
- endif()
-
- endif(CMAKE_SYSTEM_NAME MATCHES Linux)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fexceptions -fno-check-new -fno-common -fstrict-aliasing")
+ set(CMAKE_CXX_FLAGS_DEBUG "-g3")
+ set(CMAKE_CXX_FLAGS_RELEASE "-g0 -O2")
+
+ check_cxx_compiler_flag("-Wno-variadic-macros" COMPILER_SUPPORT_WNOVARIADICMACRO)
+ if(COMPILER_SUPPORT_WNOVARIADICMACRO)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-variadic-macros")
+ endif()
+
+ check_cxx_compiler_flag("-Wextra" COMPILER_SUPPORT_WEXTRA)
+ if(COMPILER_SUPPORT_WEXTRA)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra")
+ endif()
+
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
+
+ option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
+ if(EIGEN_TEST_SSE2)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2")
+ message("Enabling SSE2 in tests/examples")
+ endif()
+
+ option(EIGEN_TEST_SSE3 "Enable/Disable SSE3 in tests/examples" OFF)
+ if(EIGEN_TEST_SSE3)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse3")
+ message("Enabling SSE3 in tests/examples")
+ endif()
+
+ option(EIGEN_TEST_SSSE3 "Enable/Disable SSSE3 in tests/examples" OFF)
+ if(EIGEN_TEST_SSSE3)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mssse3")
+ message("Enabling SSSE3 in tests/examples")
+ endif()
+
+ option(EIGEN_TEST_SSE4_1 "Enable/Disable SSE4.1 in tests/examples" OFF)
+ if(EIGEN_TEST_SSE4_1)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
+ message("Enabling SSE4.1 in tests/examples")
+ endif()
+
+ option(EIGEN_TEST_SSE4_2 "Enable/Disable SSE4.2 in tests/examples" OFF)
+ if(EIGEN_TEST_SSE4_2)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2")
+ message("Enabling SSE4.2 in tests/examples")
+ endif()
+
+ option(EIGEN_TEST_ALTIVEC "Enable/Disable altivec in tests/examples" OFF)
+ if(EIGEN_TEST_ALTIVEC)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec -mabi=altivec")
+ message("Enabling AltiVec in tests/examples")
+ endif()
endif(CMAKE_COMPILER_IS_GNUCXX)
if(MSVC)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
+ # C4127 - conditional expression is constant
+ # C4505 - unreferenced local function has been removed
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /wd4127 /wd4505")
+ string(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
if(EIGEN_TEST_SSE2)
if(NOT CMAKE_CL_64)
@@ -128,9 +128,6 @@ endif(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
option(EIGEN_TEST_C++0x "Enables all C++0x features." OFF)
-option(EIGEN_TEST_MAX_WARNING_LEVEL "Sets the warning level to /Wall while building the unit tests." OFF)
-mark_as_advanced(EIGEN_TEST_MAX_WARNING_LEVEL)
-
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
set(INCLUDE_INSTALL_DIR
diff --git a/Eigen/Core b/Eigen/Core
index b5eb91023..1af04a7ee 100644
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -61,20 +61,45 @@
#ifndef EIGEN_DONT_VECTORIZE
#if defined (EIGEN_SSE2_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
+
+ // Defines symbols for compile-time detection of which instructions are
+ // used.
+ // EIGEN_VECTORIZE_YY is defined if and only if the instruction set YY is used
#define EIGEN_VECTORIZE
#define EIGEN_VECTORIZE_SSE
+ #define EIGEN_VECTORIZE_SSE2
+
+ // Detect sse3/ssse3/sse4:
+ // gcc and icc defines __SSE3__, ..,
+ // there is no way to know about this on msvc. You can define EIGEN_VECTORIZE_SSE* if you
+ // want to force the use of those instructions with msvc.
+ #ifdef __SSE3__
+ #define EIGEN_VECTORIZE_SSE3
+ #endif
+ #ifdef __SSSE3__
+ #define EIGEN_VECTORIZE_SSSE3
+ #endif
+ #ifdef __SSE4_1__
+ #define EIGEN_VECTORIZE_SSE4_1
+ #endif
+ #ifdef __SSE4_2__
+ #define EIGEN_VECTORIZE_SSE4_2
+ #endif
+
+ // include files
+
#include <emmintrin.h>
#include <xmmintrin.h>
- #ifdef __SSE3__
+ #ifdef EIGEN_VECTORIZE_SSE3
#include <pmmintrin.h>
#endif
- #ifdef __SSSE3__
+ #ifdef EIGEN_VECTORIZE_SSSE3
#include <tmmintrin.h>
#endif
- #ifdef __SSE4_1__
+ #ifdef EIGEN_VECTORIZE_SSE4_1
#include <smmintrin.h>
#endif
- #ifdef __SSE4_2__
+ #ifdef EIGEN_VECTORIZE_SSE4_2
#include <nmmintrin.h>
#endif
#elif defined __ALTIVEC__
@@ -121,6 +146,24 @@
namespace Eigen {
+inline static const char *SimdInstructionSetsInUse(void) {
+#if defined(EIGEN_VECTORIZE_SSE4_2)
+ return "SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
+#elif defined(EIGEN_VECTORIZE_SSE4_1)
+ return "SSE, SSE2, SSE3, SSSE3, SSE4.1";
+#elif defined(EIGEN_VECTORIZE_SSSE3)
+ return "SSE, SSE2, SSE3, SSSE3";
+#elif defined(EIGEN_VECTORIZE_SSE3)
+ return "SSE, SSE2, SSE3";
+#elif defined(EIGEN_VECTORIZE_SSE2)
+ return "SSE, SSE2";
+#elif defined(EIGEN_VECTORIZE_ALTIVEC)
+ return "AltiVec";
+#else
+ return "None";
+#endif
+}
+
// we use size_t frequently and we'll never remember to prepend it with std:: everytime just to
// ensure QNX/QCC support
using std::size_t;
@@ -164,7 +207,7 @@ struct Dense {};
#include "src/Core/Functors.h"
#include "src/Core/DenseBase.h"
#include "src/Core/MatrixBase.h"
-#include "src/Core/AnyMatrixBase.h"
+#include "src/Core/EigenBase.h"
#include "src/Core/Coeffs.h"
#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874
diff --git a/Eigen/src/Array/Array.h b/Eigen/src/Array/Array.h
index 533d638a4..91a091152 100644
--- a/Eigen/src/Array/Array.h
+++ b/Eigen/src/Array/Array.h
@@ -41,7 +41,7 @@ class Array
EIGEN_DENSE_PUBLIC_INTERFACE(Array)
enum { Options = _Options };
- typedef typename Base::PlainMatrixType PlainMatrixType;
+ typedef typename Base::PlainObject PlainObject;
protected:
using Base::m_storage;
@@ -61,7 +61,7 @@ class Array
* the usage of 'using'. This should be done only for operator=.
*/
template<typename OtherDerived>
- EIGEN_STRONG_INLINE Array& operator=(const AnyMatrixBase<OtherDerived> &other)
+ EIGEN_STRONG_INLINE Array& operator=(const EigenBase<OtherDerived> &other)
{
return Base::operator=(other);
}
@@ -196,9 +196,9 @@ class Array
other.evalTo(*this);
}
- /** \sa MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&) */
+ /** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
template<typename OtherDerived>
- EIGEN_STRONG_INLINE Array(const AnyMatrixBase<OtherDerived> &other)
+ EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other)
: Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
{
Base::_check_template_params();
diff --git a/Eigen/src/Array/ArrayBase.h b/Eigen/src/Array/ArrayBase.h
index 21f6fefb1..97807e5fc 100644
--- a/Eigen/src/Array/ArrayBase.h
+++ b/Eigen/src/Array/ArrayBase.h
@@ -97,7 +97,7 @@ template<typename Derived> class ArrayBase
/** \internal the plain matrix type corresponding to this expression. Note that is not necessarily
* exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const
* reference to a matrix, not a matrix! It is however guaranteed that the return type of eval() is either
- * PlainMatrixType or const PlainMatrixType&.
+ * PlainObject or const PlainObject&.
*/
typedef Array<typename ei_traits<Derived>::Scalar,
ei_traits<Derived>::RowsAtCompileTime,
@@ -105,7 +105,7 @@ template<typename Derived> class ArrayBase
AutoAlign | (ei_traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor),
ei_traits<Derived>::MaxRowsAtCompileTime,
ei_traits<Derived>::MaxColsAtCompileTime
- > PlainMatrixType;
+ > PlainObject;
/** \internal Represents a matrix with all coefficients equal to one another*/
diff --git a/Eigen/src/Array/VectorwiseOp.h b/Eigen/src/Array/VectorwiseOp.h
index 697a07d32..06d999b14 100644
--- a/Eigen/src/Array/VectorwiseOp.h
+++ b/Eigen/src/Array/VectorwiseOp.h
@@ -462,7 +462,7 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
const Homogeneous<ExpressionType,Direction> homogeneous() const;
- typedef typename ExpressionType::PlainMatrixType CrossReturnType;
+ typedef typename ExpressionType::PlainObject CrossReturnType;
template<typename OtherDerived>
const CrossReturnType cross(const MatrixBase<OtherDerived>& other) const;
diff --git a/Eigen/src/Cholesky/LDLT.h b/Eigen/src/Cholesky/LDLT.h
index b794b0c43..8699fe7e0 100644
--- a/Eigen/src/Cholesky/LDLT.h
+++ b/Eigen/src/Cholesky/LDLT.h
@@ -62,14 +62,21 @@ template<typename _MatrixType> class LDLT
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
typedef Matrix<int, 1, MatrixType::RowsAtCompileTime> IntRowVectorType;
- /**
- * \brief Default Constructor.
- *
- * The default constructor is useful in cases in which the user intends to
- * perform decompositions via LDLT::compute(const MatrixType&).
- */
+ /** \brief Default Constructor.
+ *
+ * The default constructor is useful in cases in which the user intends to
+ * perform decompositions via LDLT::compute(const MatrixType&).
+ */
LDLT() : m_matrix(), m_p(), m_transpositions(), m_isInitialized(false) {}
+ /** \brief Default Constructor with memory preallocation
+ *
+ * Like the default constructor but with preallocation of the internal data
+ * according to the specified problem \a size.
+ * \sa LDLT()
+ */
+ LDLT(int size) : m_matrix(size,size), m_p(size), m_transpositions(size), m_isInitialized(false) {}
+
LDLT(const MatrixType& matrix)
: m_matrix(matrix.rows(), matrix.cols()),
m_p(matrix.rows()),
@@ -148,6 +155,8 @@ template<typename _MatrixType> class LDLT
return m_matrix;
}
+ MatrixType reconstructedMatrix() const;
+
inline int rows() const { return m_matrix.rows(); }
inline int cols() const { return m_matrix.cols(); }
@@ -175,6 +184,10 @@ LDLT<MatrixType>& LDLT<MatrixType>::compute(const MatrixType& a)
m_matrix = a;
+ m_p.resize(size);
+ m_transpositions.resize(size);
+ m_isInitialized = false;
+
if (size <= 1) {
m_p.setZero();
m_transpositions.setZero();
@@ -202,11 +215,8 @@ LDLT<MatrixType>& LDLT<MatrixType>::compute(const MatrixType& a)
{
// The biggest overall is the point of reference to which further diagonals
// are compared; if any diagonal is negligible compared
- // to the largest overall, the algorithm bails. This cutoff is suggested
- // in "Analysis of the Cholesky Decomposition of a Semi-definite Matrix" by
- // Nicholas J. Higham. Also see "Accuracy and Stability of Numerical
- // Algorithms" page 217, also by Higham.
- cutoff = ei_abs(NumTraits<Scalar>::epsilon() * RealScalar(size) * biggest_in_corner);
+ // to the largest overall, the algorithm bails.
+ cutoff = ei_abs(NumTraits<Scalar>::epsilon() * biggest_in_corner);
m_sign = ei_real(m_matrix.diagonal().coeff(index_of_biggest_in_corner)) > 0 ? 1 : -1;
}
@@ -231,26 +241,21 @@ LDLT<MatrixType>& LDLT<MatrixType>::compute(const MatrixType& a)
continue;
}
- RealScalar Djj = ei_real(m_matrix.coeff(j,j) - m_matrix.row(j).head(j)
- .dot(m_matrix.col(j).head(j)));
+ RealScalar Djj = ei_real(m_matrix.coeff(j,j) - m_matrix.row(j).head(j).dot(m_matrix.col(j).head(j)));
m_matrix.coeffRef(j,j) = Djj;
- // Finish early if the matrix is not full rank.
- if(ei_abs(Djj) < cutoff)
- {
- for(int i = j; i < size; i++) m_transpositions.coeffRef(i) = i;
- break;
- }
-
int endSize = size - j - 1;
if (endSize > 0) {
_temporary.tail(endSize).noalias() = m_matrix.block(j+1,0, endSize, j)
* m_matrix.col(j).head(j).conjugate();
m_matrix.row(j).tail(endSize) = m_matrix.row(j).tail(endSize).conjugate()
- - _temporary.tail(endSize).transpose();
+ - _temporary.tail(endSize).transpose();
- m_matrix.col(j).tail(endSize) = m_matrix.row(j).tail(endSize) / Djj;
+ if(ei_abs(Djj) > cutoff)
+ {
+ m_matrix.col(j).tail(endSize) = m_matrix.row(j).tail(endSize) / Djj;
+ }
}
}
@@ -315,14 +320,39 @@ bool LDLT<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const
return true;
}
+/** \returns the matrix represented by the decomposition,
+ * i.e., it returns the product: P^T L D L^* P.
+ * This function is provided for debug purpose. */
+template<typename MatrixType>
+MatrixType LDLT<MatrixType>::reconstructedMatrix() const
+{
+ ei_assert(m_isInitialized && "LDLT is not initialized.");
+ const int size = m_matrix.rows();
+ MatrixType res(size,size);
+ res.setIdentity();
+
+ // PI
+ for(int i = 0; i < size; ++i) res.row(m_transpositions.coeff(i)).swap(res.row(i));
+ // L^* P
+ res = matrixL().adjoint() * res;
+ // D(L^*P)
+ res = vectorD().asDiagonal() * res;
+ // L(DL^*P)
+ res = matrixL() * res;
+ // P^T (LDL^*P)
+ for (int i = size-1; i >= 0; --i) res.row(m_transpositions.coeff(i)).swap(res.row(i));
+
+ return res;
+}
+
/** \cholesky_module
* \returns the Cholesky decomposition with full pivoting without square root of \c *this
*/
template<typename Derived>
-inline const LDLT<typename MatrixBase<Derived>::PlainMatrixType>
+inline const LDLT<typename MatrixBase<Derived>::PlainObject>
MatrixBase<Derived>::ldlt() const
{
- return derived();
+ return LDLT<PlainObject>(derived());
}
#endif // EIGEN_LDLT_H
diff --git a/Eigen/src/Cholesky/LLT.h b/Eigen/src/Cholesky/LLT.h
index 8a149a316..2e8df7661 100644
--- a/Eigen/src/Cholesky/LLT.h
+++ b/Eigen/src/Cholesky/LLT.h
@@ -117,7 +117,7 @@ template<typename _MatrixType, int _UpLo> class LLT
&& "LLT::solve(): invalid number of rows of the right hand side matrix b");
return ei_solve_retval<LLT, Rhs>(*this, b.derived());
}
-
+
template<typename Derived>
bool solveInPlace(MatrixBase<Derived> &bAndX) const;
@@ -133,6 +133,8 @@ template<typename _MatrixType, int _UpLo> class LLT
return m_matrix;
}
+ MatrixType reconstructedMatrix() const;
+
inline int rows() const { return m_matrix.rows(); }
inline int cols() const { return m_matrix.cols(); }
@@ -295,24 +297,34 @@ bool LLT<MatrixType,_UpLo>::solveInPlace(MatrixBase<Derived> &bAndX) const
return true;
}
+/** \returns the matrix represented by the decomposition,
+ * i.e., it returns the product: L L^*.
+ * This function is provided for debug purpose. */
+template<typename MatrixType, int _UpLo>
+MatrixType LLT<MatrixType,_UpLo>::reconstructedMatrix() const
+{
+ ei_assert(m_isInitialized && "LLT is not initialized.");
+ return matrixL() * matrixL().adjoint().toDenseMatrix();
+}
+
/** \cholesky_module
* \returns the LLT decomposition of \c *this
*/
template<typename Derived>
-inline const LLT<typename MatrixBase<Derived>::PlainMatrixType>
+inline const LLT<typename MatrixBase<Derived>::PlainObject>
MatrixBase<Derived>::llt() const
{
- return LLT<PlainMatrixType>(derived());
+ return LLT<PlainObject>(derived());
}
/** \cholesky_module
* \returns the LLT decomposition of \c *this
*/
template<typename MatrixType, unsigned int UpLo>
-inline const LLT<typename SelfAdjointView<MatrixType, UpLo>::PlainMatrixType, UpLo>
+inline const LLT<typename SelfAdjointView<MatrixType, UpLo>::PlainObject, UpLo>
SelfAdjointView<MatrixType, UpLo>::llt() const
{
- return LLT<PlainMatrixType,UpLo>(m_matrix);
+ return LLT<PlainObject,UpLo>(m_matrix);
}
#endif // EIGEN_LLT_H
diff --git a/Eigen/src/Core/BandMatrix.h b/Eigen/src/Core/BandMatrix.h
index 538e6dd76..432df0b34 100644
--- a/Eigen/src/Core/BandMatrix.h
+++ b/Eigen/src/Core/BandMatrix.h
@@ -57,7 +57,7 @@ struct ei_traits<BandMatrix<_Scalar,Rows,Cols,Supers,Subs,Options> >
};
template<typename _Scalar, int Rows, int Cols, int Supers, int Subs, int Options>
-class BandMatrix : public AnyMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs,Options> >
+class BandMatrix : public EigenBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs,Options> >
{
public:
diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h
index 2078f023b..5682d7278 100644
--- a/Eigen/src/Core/DenseBase.h
+++ b/Eigen/src/Core/DenseBase.h
@@ -40,7 +40,7 @@ template<typename Derived> class DenseBase
: public ei_special_scalar_op_base<Derived,typename ei_traits<Derived>::Scalar,
typename NumTraits<typename ei_traits<Derived>::Scalar>::Real>
#else
- : public AnyMatrixBase<Derived>
+ : public EigenBase<Derived>
#endif // not EIGEN_PARSED_BY_DOXYGEN
{
public:
@@ -53,8 +53,8 @@ template<typename Derived> class DenseBase
typedef typename ei_traits<Derived>::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
- using AnyMatrixBase<Derived>::derived;
- using AnyMatrixBase<Derived>::const_cast_derived;
+ using EigenBase<Derived>::derived;
+ using EigenBase<Derived>::const_cast_derived;
#endif // not EIGEN_PARSED_BY_DOXYGEN
enum {
@@ -292,13 +292,13 @@ template<typename Derived> class DenseBase
Derived& operator=(const DenseBase& other);
template<typename OtherDerived>
- Derived& operator=(const AnyMatrixBase<OtherDerived> &other);
+ Derived& operator=(const EigenBase<OtherDerived> &other);
template<typename OtherDerived>
- Derived& operator+=(const AnyMatrixBase<OtherDerived> &other);
+ Derived& operator+=(const EigenBase<OtherDerived> &other);
template<typename OtherDerived>
- Derived& operator-=(const AnyMatrixBase<OtherDerived> &other);
+ Derived& operator-=(const EigenBase<OtherDerived> &other);
template<typename OtherDerived>
Derived& operator=(const ReturnByValue<OtherDerived>& func);
diff --git a/Eigen/src/Core/DenseStorageBase.h b/Eigen/src/Core/DenseStorageBase.h
index e93e439e6..89e6e7112 100644
--- a/Eigen/src/Core/DenseStorageBase.h
+++ b/Eigen/src/Core/DenseStorageBase.h
@@ -44,7 +44,7 @@ class DenseStorageBase : public _Base<Derived>
public:
enum { Options = _Options };
typedef _Base<Derived> Base;
- typedef typename Base::PlainMatrixType PlainMatrixType;
+ typedef typename Base::PlainObject PlainObject;
typedef typename Base::Scalar Scalar;
typedef typename Base::PacketScalar PacketScalar;
using Base::RowsAtCompileTime;
@@ -338,19 +338,19 @@ class DenseStorageBase : public _Base<Derived>
// EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
}
- /** \copydoc MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&)
+ /** \copydoc MatrixBase::operator=(const EigenBase<OtherDerived>&)
*/
template<typename OtherDerived>
- EIGEN_STRONG_INLINE Derived& operator=(const AnyMatrixBase<OtherDerived> &other)
+ EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
{
resize(other.derived().rows(), other.derived().cols());
Base::operator=(other.derived());
return this->derived();
}
- /** \sa MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&) */
+ /** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
template<typename OtherDerived>
- EIGEN_STRONG_INLINE DenseStorageBase(const AnyMatrixBase<OtherDerived> &other)
+ EIGEN_STRONG_INLINE DenseStorageBase(const EigenBase<OtherDerived> &other)
: m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
{
_check_template_params();
@@ -527,7 +527,7 @@ struct ei_conservative_resize_like_impl
{
if (_this.rows() == rows && _this.cols() == cols) return;
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
- typename Derived::PlainMatrixType tmp(rows,cols);
+ typename Derived::PlainObject tmp(rows,cols);
const int common_rows = std::min(rows, _this.rows());
const int common_cols = std::min(cols, _this.cols());
tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
@@ -546,7 +546,7 @@ struct ei_conservative_resize_like_impl
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
- typename Derived::PlainMatrixType tmp(other);
+ typename Derived::PlainObject tmp(other);
const int common_rows = std::min(tmp.rows(), _this.rows());
const int common_cols = std::min(tmp.cols(), _this.cols());
tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
@@ -560,7 +560,7 @@ struct ei_conservative_resize_like_impl<Derived,OtherDerived,true>
static void run(DenseBase<Derived>& _this, int size)
{
if (_this.size() == size) return;
- typename Derived::PlainMatrixType tmp(size);
+ typename Derived::PlainObject tmp(size);
const int common_size = std::min<int>(_this.size(),size);
tmp.segment(0,common_size) = _this.segment(0,common_size);
_this.derived().swap(tmp);
@@ -571,7 +571,7 @@ struct ei_conservative_resize_like_impl<Derived,OtherDerived,true>
if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
// segment(...) will check whether Derived/OtherDerived are vectors!
- typename Derived::PlainMatrixType tmp(other);
+ typename Derived::PlainObject tmp(other);
const int common_size = std::min<int>(_this.size(),tmp.size());
tmp.segment(0,common_size) = _this.segment(0,common_size);
_this.derived().swap(tmp);
diff --git a/Eigen/src/Core/DiagonalMatrix.h b/Eigen/src/Core/DiagonalMatrix.h
index 08c046611..774b0d7ae 100644
--- a/Eigen/src/Core/DiagonalMatrix.h
+++ b/Eigen/src/Core/DiagonalMatrix.h
@@ -28,7 +28,7 @@
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename Derived>
-class DiagonalBase : public AnyMatrixBase<Derived>
+class DiagonalBase : public EigenBase<Derived>
{
public:
typedef typename ei_traits<Derived>::DiagonalVectorType DiagonalVectorType;
diff --git a/Eigen/src/Core/Dot.h b/Eigen/src/Core/Dot.h
index f0c520b1f..201bd23ca 100644
--- a/Eigen/src/Core/Dot.h
+++ b/Eigen/src/Core/Dot.h
@@ -299,7 +299,7 @@ inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real MatrixBase<
* \sa norm(), normalize()
*/
template<typename Derived>
-inline const typename MatrixBase<Derived>::PlainMatrixType
+inline const typename MatrixBase<Derived>::PlainObject
MatrixBase<Derived>::normalized() const
{
typedef typename ei_nested<Derived>::type Nested;
diff --git a/Eigen/src/Core/AnyMatrixBase.h b/Eigen/src/Core/EigenBase.h
index a5d1cfe9f..cf1ce4376 100644
--- a/Eigen/src/Core/AnyMatrixBase.h
+++ b/Eigen/src/Core/EigenBase.h
@@ -23,21 +23,21 @@
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
-#ifndef EIGEN_ANYMATRIXBASE_H
-#define EIGEN_ANYMATRIXBASE_H
+#ifndef EIGEN_EIGENBASE_H
+#define EIGEN_EIGENBASE_H
/** Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T).
*
- * In other words, an AnyMatrixBase object is an object that can be copied into a MatrixBase.
+ * In other words, an EigenBase object is an object that can be copied into a MatrixBase.
*
* Besides MatrixBase-derived classes, this also includes special matrix classes such as diagonal matrices, etc.
*
* Notice that this class is trivial, it is only used to disambiguate overloaded functions.
*/
-template<typename Derived> struct AnyMatrixBase
+template<typename Derived> struct EigenBase
{
-// typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType;
+// typedef typename ei_plain_matrix_type<Derived>::type PlainObject;
/** \returns a reference to the derived object */
Derived& derived() { return *static_cast<Derived*>(this); }
@@ -45,7 +45,7 @@ template<typename Derived> struct AnyMatrixBase
const Derived& derived() const { return *static_cast<const Derived*>(this); }
inline Derived& const_cast_derived() const
- { return *static_cast<Derived*>(const_cast<AnyMatrixBase*>(this)); }
+ { return *static_cast<Derived*>(const_cast<EigenBase*>(this)); }
/** \returns the number of rows. \sa cols(), RowsAtCompileTime */
inline int rows() const { return derived().rows(); }
@@ -61,7 +61,7 @@ template<typename Derived> struct AnyMatrixBase
{
// This is the default implementation,
// derived class can reimplement it in a more optimized way.
- typename Dest::PlainMatrixType res(rows(),cols());
+ typename Dest::PlainObject res(rows(),cols());
evalTo(res);
dst += res;
}
@@ -71,7 +71,7 @@ template<typename Derived> struct AnyMatrixBase
{
// This is the default implementation,
// derived class can reimplement it in a more optimized way.
- typename Dest::PlainMatrixType res(rows(),cols());
+ typename Dest::PlainObject res(rows(),cols());
evalTo(res);
dst -= res;
}
@@ -108,7 +108,7 @@ template<typename Derived> struct AnyMatrixBase
*/
template<typename Derived>
template<typename OtherDerived>
-Derived& DenseBase<Derived>::operator=(const AnyMatrixBase<OtherDerived> &other)
+Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
{
other.derived().evalTo(derived());
return derived();
@@ -116,7 +116,7 @@ Derived& DenseBase<Derived>::operator=(const AnyMatrixBase<OtherDerived> &other)
template<typename Derived>
template<typename OtherDerived>
-Derived& DenseBase<Derived>::operator+=(const AnyMatrixBase<OtherDerived> &other)
+Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other)
{
other.derived().addTo(derived());
return derived();
@@ -124,7 +124,7 @@ Derived& DenseBase<Derived>::operator+=(const AnyMatrixBase<OtherDerived> &other
template<typename Derived>
template<typename OtherDerived>
-Derived& DenseBase<Derived>::operator-=(const AnyMatrixBase<OtherDerived> &other)
+Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other)
{
other.derived().subTo(derived());
return derived();
@@ -137,7 +137,7 @@ Derived& DenseBase<Derived>::operator-=(const AnyMatrixBase<OtherDerived> &other
template<typename Derived>
template<typename OtherDerived>
inline Derived&
-MatrixBase<Derived>::operator*=(const AnyMatrixBase<OtherDerived> &other)
+MatrixBase<Derived>::operator*=(const EigenBase<OtherDerived> &other)
{
other.derived().applyThisOnTheRight(derived());
return derived();
@@ -146,7 +146,7 @@ MatrixBase<Derived>::operator*=(const AnyMatrixBase<OtherDerived> &other)
/** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=() */
template<typename Derived>
template<typename OtherDerived>
-inline void MatrixBase<Derived>::applyOnTheRight(const AnyMatrixBase<OtherDerived> &other)
+inline void MatrixBase<Derived>::applyOnTheRight(const EigenBase<OtherDerived> &other)
{
other.derived().applyThisOnTheRight(derived());
}
@@ -154,9 +154,9 @@ inline void MatrixBase<Derived>::applyOnTheRight(const AnyMatrixBase<OtherDerive
/** replaces \c *this by \c *this * \a other. */
template<typename Derived>
template<typename OtherDerived>
-inline void MatrixBase<Derived>::applyOnTheLeft(const AnyMatrixBase<OtherDerived> &other)
+inline void MatrixBase<Derived>::applyOnTheLeft(const EigenBase<OtherDerived> &other)
{
other.derived().applyThisOnTheLeft(derived());
}
-#endif // EIGEN_ANYMATRIXBASE_H
+#endif // EIGEN_EIGENBASE_H
diff --git a/Eigen/src/Core/Flagged.h b/Eigen/src/Core/Flagged.h
index 9d14aceaa..9413b74fa 100644
--- a/Eigen/src/Core/Flagged.h
+++ b/Eigen/src/Core/Flagged.h
@@ -110,7 +110,7 @@ template<typename ExpressionType, unsigned int Added, unsigned int Removed> clas
const ExpressionType& _expression() const { return m_matrix; }
template<typename OtherDerived>
- typename ExpressionType::PlainMatrixType solveTriangular(const MatrixBase<OtherDerived>& other) const;
+ typename ExpressionType::PlainObject solveTriangular(const MatrixBase<OtherDerived>& other) const;
template<typename OtherDerived>
void solveTriangularInPlace(const MatrixBase<OtherDerived>& other) const;
diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h
index b494b2f00..eae2711f4 100644
--- a/Eigen/src/Core/Matrix.h
+++ b/Eigen/src/Core/Matrix.h
@@ -139,7 +139,7 @@ class Matrix
EIGEN_DENSE_PUBLIC_INTERFACE(Matrix)
- typedef typename Base::PlainMatrixType PlainMatrixType;
+ typedef typename Base::PlainObject PlainObject;
enum { NeedsToAlign = (!(Options&DontAlign))
&& SizeAtCompileTime!=Dynamic && ((sizeof(Scalar)*SizeAtCompileTime)%16)==0 };
@@ -181,10 +181,10 @@ class Matrix
/**
* \brief Copies the generic expression \a other into *this.
- * \copydetails DenseBase::operator=(const AnyMatrixBase<OtherDerived> &other)
+ * \copydetails DenseBase::operator=(const EigenBase<OtherDerived> &other)
*/
template<typename OtherDerived>
- EIGEN_STRONG_INLINE Matrix& operator=(const AnyMatrixBase<OtherDerived> &other)
+ EIGEN_STRONG_INLINE Matrix& operator=(const EigenBase<OtherDerived> &other)
{
return Base::operator=(other);
}
@@ -297,10 +297,10 @@ class Matrix
}
/** \brief Copy constructor for generic expressions.
- * \sa MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&)
+ * \sa MatrixBase::operator=(const EigenBase<OtherDerived>&)
*/
template<typename OtherDerived>
- EIGEN_STRONG_INLINE Matrix(const AnyMatrixBase<OtherDerived> &other)
+ EIGEN_STRONG_INLINE Matrix(const EigenBase<OtherDerived> &other)
: Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
{
Base::_check_template_params();
diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h
index 229195046..9c62163ba 100644
--- a/Eigen/src/Core/MatrixBase.h
+++ b/Eigen/src/Core/MatrixBase.h
@@ -121,7 +121,7 @@ template<typename Derived> class MatrixBase
*
* This is not necessarily exactly the return type of eval(). In the case of plain matrices,
* the return type of eval() is a const reference to a matrix, not a matrix! It is however guaranteed
- * that the return type of eval() is either PlainMatrixType or const PlainMatrixType&.
+ * that the return type of eval() is either PlainObject or const PlainObject&.
*/
typedef Matrix<typename ei_traits<Derived>::Scalar,
ei_traits<Derived>::RowsAtCompileTime,
@@ -129,8 +129,7 @@ template<typename Derived> class MatrixBase
AutoAlign | (ei_traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor),
ei_traits<Derived>::MaxRowsAtCompileTime,
ei_traits<Derived>::MaxColsAtCompileTime
- > PlainMatrixType;
- // typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType;
+ > PlainObject;
#ifndef EIGEN_PARSED_BY_DOXYGEN
/** \internal Represents a matrix with all coefficients equal to one another*/
@@ -193,13 +192,13 @@ template<typename Derived> class MatrixBase
lazyProduct(const MatrixBase<OtherDerived> &other) const;
template<typename OtherDerived>
- Derived& operator*=(const AnyMatrixBase<OtherDerived>& other);
+ Derived& operator*=(const EigenBase<OtherDerived>& other);
template<typename OtherDerived>
- void applyOnTheLeft(const AnyMatrixBase<OtherDerived>& other);
+ void applyOnTheLeft(const EigenBase<OtherDerived>& other);
template<typename OtherDerived>
- void applyOnTheRight(const AnyMatrixBase<OtherDerived>& other);
+ void applyOnTheRight(const EigenBase<OtherDerived>& other);
template<typename DiagonalDerived>
const DiagonalProduct<Derived, DiagonalDerived, OnTheRight>
@@ -212,7 +211,7 @@ template<typename Derived> class MatrixBase
RealScalar stableNorm() const;
RealScalar blueNorm() const;
RealScalar hypotNorm() const;
- const PlainMatrixType normalized() const;
+ const PlainObject normalized() const;
void normalize();
const AdjointReturnType adjoint() const;
@@ -301,9 +300,9 @@ template<typename Derived> class MatrixBase
/////////// LU module ///////////
- const FullPivLU<PlainMatrixType> fullPivLu() const;
- const PartialPivLU<PlainMatrixType> partialPivLu() const;
- const PartialPivLU<PlainMatrixType> lu() const;
+ const FullPivLU<PlainObject> fullPivLu() const;
+ const PartialPivLU<PlainObject> partialPivLu() const;
+ const PartialPivLU<PlainObject> lu() const;
const ei_inverse_impl<Derived> inverse() const;
template<typename ResultType>
void computeInverseAndDetWithCheck(
@@ -322,29 +321,29 @@ template<typename Derived> class MatrixBase
/////////// Cholesky module ///////////
- const LLT<PlainMatrixType> llt() const;
- const LDLT<PlainMatrixType> ldlt() const;
+ const LLT<PlainObject> llt() const;
+ const LDLT<PlainObject> ldlt() const;
/////////// QR module ///////////
- const HouseholderQR<PlainMatrixType> householderQr() const;
- const ColPivHouseholderQR<PlainMatrixType> colPivHouseholderQr() const;
- const FullPivHouseholderQR<PlainMatrixType> fullPivHouseholderQr() const;
+ const HouseholderQR<PlainObject> householderQr() const;
+ const ColPivHouseholderQR<PlainObject> colPivHouseholderQr() const;
+ const FullPivHouseholderQR<PlainObject> fullPivHouseholderQr() const;
EigenvaluesReturnType eigenvalues() const;
RealScalar operatorNorm() const;
/////////// SVD module ///////////
- SVD<PlainMatrixType> svd() const;
+ SVD<PlainObject> svd() const;
/////////// Geometry module ///////////
template<typename OtherDerived>
- PlainMatrixType cross(const MatrixBase<OtherDerived>& other) const;
+ PlainObject cross(const MatrixBase<OtherDerived>& other) const;
template<typename OtherDerived>
- PlainMatrixType cross3(const MatrixBase<OtherDerived>& other) const;
- PlainMatrixType unitOrthogonal(void) const;
+ PlainObject cross3(const MatrixBase<OtherDerived>& other) const;
+ PlainObject unitOrthogonal(void) const;
Matrix<Scalar,3,1> eulerAngles(int a0, int a1, int a2) const;
const ScalarMultipleReturnType operator*(const UniformScaling<Scalar>& s) const;
enum {
diff --git a/Eigen/src/Core/PermutationMatrix.h b/Eigen/src/Core/PermutationMatrix.h
index 284baf678..46884dc3f 100644
--- a/Eigen/src/Core/PermutationMatrix.h
+++ b/Eigen/src/Core/PermutationMatrix.h
@@ -47,7 +47,7 @@
* \sa class DiagonalMatrix
*/
template<int SizeAtCompileTime, int MaxSizeAtCompileTime = SizeAtCompileTime> class PermutationMatrix;
-template<typename PermutationType, typename MatrixType, int Side> struct ei_permut_matrix_product_retval;
+template<typename PermutationType, typename MatrixType, int Side, bool Transposed=false> struct ei_permut_matrix_product_retval;
template<int SizeAtCompileTime, int MaxSizeAtCompileTime>
struct ei_traits<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime> >
@@ -55,7 +55,7 @@ struct ei_traits<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime> >
{};
template<int SizeAtCompileTime, int MaxSizeAtCompileTime>
-class PermutationMatrix : public AnyMatrixBase<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime> >
+class PermutationMatrix : public EigenBase<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime> >
{
public:
@@ -132,6 +132,9 @@ class PermutationMatrix : public AnyMatrixBase<PermutationMatrix<SizeAtCompileTi
/** \returns the number of columns */
inline int cols() const { return m_indices.size(); }
+ /** \returns the size of a side of the respective square matrix, i.e., the number of indices */
+ inline int size() const { return m_indices.size(); }
+
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename DenseDerived>
void evalTo(MatrixBase<DenseDerived>& other) const
@@ -144,7 +147,7 @@ class PermutationMatrix : public AnyMatrixBase<PermutationMatrix<SizeAtCompileTi
/** \returns a Matrix object initialized from this permutation matrix. Notice that it
* is inefficient to return this Matrix object by value. For efficiency, favor using
- * the Matrix constructor taking AnyMatrixBase objects.
+ * the Matrix constructor taking EigenBase objects.
*/
DenseMatrixType toDenseMatrix() const
{
@@ -213,16 +216,29 @@ class PermutationMatrix : public AnyMatrixBase<PermutationMatrix<SizeAtCompileTi
return *this;
}
- /**** inversion and multiplication helpers to hopefully get RVO ****/
+ /** \returns the inverse permutation matrix.
+ *
+ * \note \note_try_to_help_rvo
+ */
+ inline Transpose<PermutationMatrix> inverse() const
+ { return *this; }
+ /** \returns the tranpose permutation matrix.
+ *
+ * \note \note_try_to_help_rvo
+ */
+ inline Transpose<PermutationMatrix> transpose() const
+ { return *this; }
+
+ /**** multiplication helpers to hopefully get RVO ****/
#ifndef EIGEN_PARSED_BY_DOXYGEN
- protected:
- enum Inverse_t {Inverse};
- PermutationMatrix(Inverse_t, const PermutationMatrix& other)
- : m_indices(other.m_indices.size())
+ template<int OtherSize, int OtherMaxSize>
+ PermutationMatrix(const Transpose<PermutationMatrix<OtherSize,OtherMaxSize> >& other)
+ : m_indices(other.nestedPermutation().size())
{
- for (int i=0; i<rows();++i) m_indices.coeffRef(other.m_indices.coeff(i)) = i;
+ for (int i=0; i<rows();++i) m_indices.coeffRef(other.nestedPermutation().indices().coeff(i)) = i;
}
+ protected:
enum Product_t {Product};
PermutationMatrix(Product_t, const PermutationMatrix& lhs, const PermutationMatrix& rhs)
: m_indices(lhs.m_indices.size())
@@ -233,12 +249,7 @@ class PermutationMatrix : public AnyMatrixBase<PermutationMatrix<SizeAtCompileTi
#endif
public:
- /** \returns the inverse permutation matrix.
- *
- * \note \note_try_to_help_rvo
- */
- inline PermutationMatrix inverse() const
- { return PermutationMatrix(Inverse, *this); }
+
/** \returns the product permutation matrix.
*
* \note \note_try_to_help_rvo
@@ -247,6 +258,22 @@ class PermutationMatrix : public AnyMatrixBase<PermutationMatrix<SizeAtCompileTi
inline PermutationMatrix operator*(const PermutationMatrix<OtherSize, OtherMaxSize>& other) const
{ return PermutationMatrix(Product, *this, other); }
+ /** \returns the product of a permutation with another inverse permutation.
+ *
+ * \note \note_try_to_help_rvo
+ */
+ template<int OtherSize, int OtherMaxSize>
+ inline PermutationMatrix operator*(const Transpose<PermutationMatrix<OtherSize,OtherMaxSize> >& other) const
+ { return PermutationMatrix(Product, *this, other.eval()); }
+
+ /** \returns the product of an inverse permutation with another permutation.
+ *
+ * \note \note_try_to_help_rvo
+ */
+ template<int OtherSize, int OtherMaxSize> friend
+ inline PermutationMatrix operator*(const Transpose<PermutationMatrix<OtherSize,OtherMaxSize> >& other, const PermutationMatrix& perm)
+ { return PermutationMatrix(Product, other.eval(), perm); }
+
protected:
IndicesType m_indices;
@@ -277,15 +304,15 @@ operator*(const PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime> &perm
(permutation, matrix.derived());
}
-template<typename PermutationType, typename MatrixType, int Side>
-struct ei_traits<ei_permut_matrix_product_retval<PermutationType, MatrixType, Side> >
+template<typename PermutationType, typename MatrixType, int Side, bool Transposed>
+struct ei_traits<ei_permut_matrix_product_retval<PermutationType, MatrixType, Side, Transposed> >
{
- typedef typename MatrixType::PlainMatrixType ReturnMatrixType;
+ typedef typename MatrixType::PlainObject ReturnType;
};
-template<typename PermutationType, typename MatrixType, int Side>
+template<typename PermutationType, typename MatrixType, int Side, bool Transposed>
struct ei_permut_matrix_product_retval
- : public ReturnByValue<ei_permut_matrix_product_retval<PermutationType, MatrixType, Side> >
+ : public ReturnByValue<ei_permut_matrix_product_retval<PermutationType, MatrixType, Side, Transposed> >
{
typedef typename ei_cleantype<typename MatrixType::Nested>::type MatrixTypeNestedCleaned;
@@ -299,21 +326,46 @@ struct ei_permut_matrix_product_retval
template<typename Dest> inline void evalTo(Dest& dst) const
{
const int n = Side==OnTheLeft ? rows() : cols();
- for(int i = 0; i < n; ++i)
+
+ if(ei_is_same_type<MatrixTypeNestedCleaned,Dest>::ret && ei_extract_data(dst) == ei_extract_data(m_matrix))
{
- Block<
- Dest,
- Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime,
- Side==OnTheRight ? 1 : Dest::ColsAtCompileTime
- >(dst, Side==OnTheLeft ? m_permutation.indices().coeff(i) : i)
-
- =
-
- Block<
- MatrixTypeNestedCleaned,
- Side==OnTheLeft ? 1 : MatrixType::RowsAtCompileTime,
- Side==OnTheRight ? 1 : MatrixType::ColsAtCompileTime
- >(m_matrix, Side==OnTheRight ? m_permutation.indices().coeff(i) : i);
+ // apply the permutation inplace
+ Matrix<bool,PermutationType::RowsAtCompileTime,1,0,PermutationType::MaxRowsAtCompileTime> mask(m_permutation.size());
+ mask.fill(false);
+ int r = 0;
+ while(r < m_permutation.size())
+ {
+ // search for the next seed
+ while(r<m_permutation.size() && mask[r]) r++;
+ 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;
+ mask.coeffRef(k0) = true;
+ for(int k=m_permutation.indices().coeff(k0); k!=k0; k=m_permutation.indices().coeff(k))
+ {
+ Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>(dst, k)
+ .swap(Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
+ (dst,((Side==OnTheLeft) ^ Transposed) ? k0 : kPrev));
+
+ mask.coeffRef(k) = true;
+ kPrev = k;
+ }
+ }
+ }
+ else
+ {
+ for(int i = 0; i < n; ++i)
+ {
+ Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
+ (dst, ((Side==OnTheLeft) ^ Transposed) ? m_permutation.indices().coeff(i) : i)
+
+ =
+
+ Block<MatrixTypeNestedCleaned,Side==OnTheLeft ? 1 : MatrixType::RowsAtCompileTime,Side==OnTheRight ? 1 : MatrixType::ColsAtCompileTime>
+ (m_matrix, ((Side==OnTheRight) ^ Transposed) ? m_permutation.indices().coeff(i) : i);
+ }
}
}
@@ -322,4 +374,78 @@ struct ei_permut_matrix_product_retval
const typename MatrixType::Nested m_matrix;
};
+/* Template partial specialization for transposed/inverse permutations */
+
+template<int SizeAtCompileTime, int MaxSizeAtCompileTime>
+struct ei_traits<Transpose<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime> > >
+ : ei_traits<Matrix<int,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
+{};
+
+template<int SizeAtCompileTime, int MaxSizeAtCompileTime>
+class Transpose<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime> >
+ : public EigenBase<Transpose<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime> > >
+{
+ typedef PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime> PermutationType;
+ typedef typename PermutationType::IndicesType IndicesType;
+ public:
+
+ #ifndef EIGEN_PARSED_BY_DOXYGEN
+ typedef ei_traits<PermutationType> Traits;
+ typedef Matrix<int,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime>
+ DenseMatrixType;
+ enum {
+ Flags = Traits::Flags,
+ CoeffReadCost = Traits::CoeffReadCost,
+ RowsAtCompileTime = Traits::RowsAtCompileTime,
+ ColsAtCompileTime = Traits::ColsAtCompileTime,
+ MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = Traits::MaxColsAtCompileTime
+ };
+ typedef typename Traits::Scalar Scalar;
+ #endif
+
+ Transpose(const PermutationType& p) : m_permutation(p) {}
+
+ inline int rows() const { return m_permutation.rows(); }
+ inline int cols() const { return m_permutation.cols(); }
+
+ #ifndef EIGEN_PARSED_BY_DOXYGEN
+ template<typename DenseDerived>
+ void evalTo(MatrixBase<DenseDerived>& other) const
+ {
+ other.setZero();
+ for (int i=0; i<rows();++i)
+ other.coeffRef(i, m_permutation.indices().coeff(i)) = typename DenseDerived::Scalar(1);
+ }
+ #endif
+
+ /** \return the equivalent permutation matrix */
+ PermutationType eval() const { return *this; }
+
+ DenseMatrixType toDenseMatrix() const { return *this; }
+
+ /** \returns the matrix with the inverse permutation applied to the columns.
+ */
+ template<typename Derived> friend
+ inline const ei_permut_matrix_product_retval<PermutationType, Derived, OnTheRight, true>
+ operator*(const MatrixBase<Derived>& matrix, const Transpose& trPerm)
+ {
+ return ei_permut_matrix_product_retval<PermutationType, Derived, OnTheRight, true>(trPerm.m_permutation, matrix.derived());
+ }
+
+ /** \returns the matrix with the inverse permutation applied to the rows.
+ */
+ template<typename Derived>
+ inline const ei_permut_matrix_product_retval<PermutationType, Derived, OnTheLeft, true>
+ operator*(const MatrixBase<Derived>& matrix) const
+ {
+ return ei_permut_matrix_product_retval<PermutationType, Derived, OnTheLeft, true>(m_permutation, matrix.derived());
+ }
+
+ const PermutationType& nestedPermutation() const { return m_permutation; }
+
+ protected:
+ const PermutationType& m_permutation;
+};
+
#endif // EIGEN_PERMUTATIONMATRIX_H
diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h
index af05773ee..236e4f130 100644
--- a/Eigen/src/Core/Product.h
+++ b/Eigen/src/Core/Product.h
@@ -50,8 +50,8 @@ class GeneralProduct;
template<int Rows, int Cols, int Depth> struct ei_product_type_selector;
enum {
- Large = Dynamic,
- Small = Dynamic/2
+ Large = 2,
+ Small = 3
};
template<typename Lhs, typename Rhs> struct ei_product_type
@@ -95,10 +95,10 @@ template<> struct ei_product_type_selector<Small, Large, 1>
template<> struct ei_product_type_selector<Large, Small, 1> { enum { ret = LazyCoeffBasedProductMode }; };
template<> struct ei_product_type_selector<1, Large,Small> { enum { ret = GemvProduct }; };
template<> struct ei_product_type_selector<1, Large,Large> { enum { ret = GemvProduct }; };
-template<> struct ei_product_type_selector<1, Small,Large> { enum { ret = GemvProduct }; };
+template<> struct ei_product_type_selector<1, Small,Large> { enum { ret = CoeffBasedProductMode }; };
template<> struct ei_product_type_selector<Large,1, Small> { enum { ret = GemvProduct }; };
template<> struct ei_product_type_selector<Large,1, Large> { enum { ret = GemvProduct }; };
-template<> struct ei_product_type_selector<Small,1, Large> { enum { ret = GemvProduct }; };
+template<> struct ei_product_type_selector<Small,1, Large> { enum { ret = CoeffBasedProductMode }; };
template<> struct ei_product_type_selector<Small,Small,Large> { enum { ret = GemmProduct }; };
template<> struct ei_product_type_selector<Large,Small,Large> { enum { ret = GemmProduct }; };
template<> struct ei_product_type_selector<Small,Large,Large> { enum { ret = GemmProduct }; };
diff --git a/Eigen/src/Core/ProductBase.h b/Eigen/src/Core/ProductBase.h
index 481e7c760..789aecfb6 100644
--- a/Eigen/src/Core/ProductBase.h
+++ b/Eigen/src/Core/ProductBase.h
@@ -88,7 +88,7 @@ class ProductBase : public MatrixBase<Derived>
public:
- typedef typename Base::PlainMatrixType PlainMatrixType;
+ typedef typename Base::PlainObject PlainObject;
ProductBase(const Lhs& lhs, const Rhs& rhs)
: m_lhs(lhs), m_rhs(rhs)
@@ -116,8 +116,8 @@ class ProductBase : public MatrixBase<Derived>
const _LhsNested& lhs() const { return m_lhs; }
const _RhsNested& rhs() const { return m_rhs; }
- // Implicit convertion to the nested type (trigger the evaluation of the product)
- operator const PlainMatrixType& () const
+ // Implicit conversion to the nested type (trigger the evaluation of the product)
+ operator const PlainObject& () const
{
m_result.resize(m_lhs.rows(), m_rhs.cols());
this->evalTo(m_result);
@@ -139,7 +139,7 @@ class ProductBase : public MatrixBase<Derived>
const LhsNested m_lhs;
const RhsNested m_rhs;
- mutable PlainMatrixType m_result;
+ mutable PlainObject m_result;
private:
@@ -152,10 +152,10 @@ class ProductBase : public MatrixBase<Derived>
// here we need to overload the nested rule for products
// such that the nested type is a const reference to a plain matrix
-template<typename Lhs, typename Rhs, int Mode, int N, typename PlainMatrixType>
-struct ei_nested<GeneralProduct<Lhs,Rhs,Mode>, N, PlainMatrixType>
+template<typename Lhs, typename Rhs, int Mode, int N, typename PlainObject>
+struct ei_nested<GeneralProduct<Lhs,Rhs,Mode>, N, PlainObject>
{
- typedef PlainMatrixType const& type;
+ typedef PlainObject const& type;
};
template<typename NestedProduct>
diff --git a/Eigen/src/Core/ReturnByValue.h b/Eigen/src/Core/ReturnByValue.h
index 8d45fc31b..160b973bd 100644
--- a/Eigen/src/Core/ReturnByValue.h
+++ b/Eigen/src/Core/ReturnByValue.h
@@ -31,13 +31,13 @@
*/
template<typename Derived>
struct ei_traits<ReturnByValue<Derived> >
- : public ei_traits<typename ei_traits<Derived>::ReturnMatrixType>
+ : public ei_traits<typename ei_traits<Derived>::ReturnType>
{
enum {
// We're disabling the DirectAccess because e.g. the constructor of
// the Block-with-DirectAccess expression requires to have a coeffRef method.
// Also, we don't want to have to implement the stride stuff.
- Flags = (ei_traits<typename ei_traits<Derived>::ReturnMatrixType>::Flags
+ Flags = (ei_traits<typename ei_traits<Derived>::ReturnType>::Flags
| EvalBeforeNestingBit) & ~DirectAccessBit
};
};
@@ -46,18 +46,18 @@ struct ei_traits<ReturnByValue<Derived> >
* So the only way that nesting it in an expression can work, is by evaluating it into a plain matrix.
* So ei_nested always gives the plain return matrix type.
*/
-template<typename Derived,int n,typename PlainMatrixType>
-struct ei_nested<ReturnByValue<Derived>, n, PlainMatrixType>
+template<typename Derived,int n,typename PlainObject>
+struct ei_nested<ReturnByValue<Derived>, n, PlainObject>
{
- typedef typename ei_traits<Derived>::ReturnMatrixType type;
+ typedef typename ei_traits<Derived>::ReturnType type;
};
template<typename Derived> class ReturnByValue
- : public ei_traits<Derived>::ReturnMatrixType::template MakeBase<ReturnByValue<Derived> >::Type
+ : public ei_traits<Derived>::ReturnType::template MakeBase<ReturnByValue<Derived> >::Type
{
public:
- typedef typename ei_traits<Derived>::ReturnMatrixType ReturnMatrixType;
- typedef typename ReturnMatrixType::template MakeBase<ReturnByValue<Derived> >::Type Base;
+ typedef typename ei_traits<Derived>::ReturnType ReturnType;
+ typedef typename ReturnType::template MakeBase<ReturnByValue<Derived> >::Type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(ReturnByValue)
template<typename Dest>
diff --git a/Eigen/src/Core/SelfAdjointView.h b/Eigen/src/Core/SelfAdjointView.h
index add5a3afb..0b57b9968 100644
--- a/Eigen/src/Core/SelfAdjointView.h
+++ b/Eigen/src/Core/SelfAdjointView.h
@@ -68,7 +68,7 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
enum {
Mode = ei_traits<SelfAdjointView>::Mode
};
- typedef typename MatrixType::PlainMatrixType PlainMatrixType;
+ typedef typename MatrixType::PlainObject PlainObject;
inline SelfAdjointView(const MatrixType& matrix) : m_matrix(matrix)
{ ei_assert(ei_are_flags_consistent<Mode>::ret); }
@@ -147,8 +147,8 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
/////////// Cholesky module ///////////
- const LLT<PlainMatrixType, UpLo> llt() const;
- const LDLT<PlainMatrixType> ldlt() const;
+ const LLT<PlainObject, UpLo> llt() const;
+ const LDLT<PlainObject> ldlt() const;
protected:
const typename MatrixType::Nested m_matrix;
diff --git a/Eigen/src/Core/SelfCwiseBinaryOp.h b/Eigen/src/Core/SelfCwiseBinaryOp.h
index 58aee182d..529a9994d 100644
--- a/Eigen/src/Core/SelfCwiseBinaryOp.h
+++ b/Eigen/src/Core/SelfCwiseBinaryOp.h
@@ -125,8 +125,8 @@ template<typename Derived>
inline Derived& DenseBase<Derived>::operator*=(const Scalar& other)
{
SelfCwiseBinaryOp<ei_scalar_product_op<Scalar>, Derived> tmp(derived());
- typedef typename Derived::PlainMatrixType PlainMatrixType;
- tmp = PlainMatrixType::Constant(rows(),cols(),other);
+ typedef typename Derived::PlainObject PlainObject;
+ tmp = PlainObject::Constant(rows(),cols(),other);
return derived();
}
@@ -134,8 +134,8 @@ template<typename Derived>
inline Derived& DenseBase<Derived>::operator/=(const Scalar& other)
{
SelfCwiseBinaryOp<typename ei_meta_if<NumTraits<Scalar>::HasFloatingPoint,ei_scalar_product_op<Scalar>,ei_scalar_quotient_op<Scalar> >::ret, Derived> tmp(derived());
- typedef typename Derived::PlainMatrixType PlainMatrixType;
- tmp = PlainMatrixType::Constant(rows(),cols(), NumTraits<Scalar>::HasFloatingPoint ? Scalar(1)/other : other);
+ typedef typename Derived::PlainObject PlainObject;
+ tmp = PlainObject::Constant(rows(),cols(), NumTraits<Scalar>::HasFloatingPoint ? Scalar(1)/other : other);
return derived();
}
diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h
index 47dae5776..1f064d1c2 100644
--- a/Eigen/src/Core/Transpose.h
+++ b/Eigen/src/Core/Transpose.h
@@ -296,25 +296,6 @@ struct ei_blas_traits<SelfCwiseBinaryOp<BinOp,NestedXpr> >
static inline const XprType extract(const XprType& x) { return x; }
};
-
-template<typename T, int Access=ei_blas_traits<T>::ActualAccess>
-struct ei_extract_data_selector {
- static typename T::Scalar* run(const T& m)
- {
- return &ei_blas_traits<T>::extract(m).const_cast_derived().coeffRef(0,0);
- }
-};
-
-template<typename T>
-struct ei_extract_data_selector<T,NoDirectAccess> {
- static typename T::Scalar* run(const T&) { return 0; }
-};
-
-template<typename T> typename T::Scalar* ei_extract_data(const T& m)
-{
- return ei_extract_data_selector<T>::run(m);
-}
-
template<typename Scalar, bool DestIsTranposed, typename OtherDerived>
struct ei_check_transpose_aliasing_selector
{
diff --git a/Eigen/src/Core/TriangularMatrix.h b/Eigen/src/Core/TriangularMatrix.h
index c61a6d7cc..2230680d1 100644
--- a/Eigen/src/Core/TriangularMatrix.h
+++ b/Eigen/src/Core/TriangularMatrix.h
@@ -32,7 +32,7 @@
*
* \brief Base class for triangular part in a matrix
*/
-template<typename Derived> class TriangularBase : public AnyMatrixBase<Derived>
+template<typename Derived> class TriangularBase : public EigenBase<Derived>
{
public:
@@ -149,7 +149,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
typedef TriangularBase<TriangularView> Base;
typedef typename ei_traits<TriangularView>::Scalar Scalar;
typedef _MatrixType MatrixType;
- typedef typename MatrixType::PlainMatrixType DenseMatrixType;
+ typedef typename MatrixType::PlainObject DenseMatrixType;
typedef typename MatrixType::Nested MatrixTypeNested;
typedef typename ei_cleantype<MatrixTypeNested>::type _MatrixTypeNested;
diff --git a/Eigen/src/Core/arch/SSE/PacketMath.h b/Eigen/src/Core/arch/SSE/PacketMath.h
index a5a56f759..f78bf0dd3 100644
--- a/Eigen/src/Core/arch/SSE/PacketMath.h
+++ b/Eigen/src/Core/arch/SSE/PacketMath.h
@@ -122,7 +122,7 @@ template<> EIGEN_STRONG_INLINE Packet4f ei_pmul<Packet4f>(const Packet4f& a, con
template<> EIGEN_STRONG_INLINE Packet2d ei_pmul<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_mul_pd(a,b); }
template<> EIGEN_STRONG_INLINE Packet4i ei_pmul<Packet4i>(const Packet4i& a, const Packet4i& b)
{
-#ifdef __SSE4_1__
+#ifdef EIGEN_VECTORIZE_SSE4_1
return _mm_mullo_epi32(a,b);
#else
// this version is slightly faster than 4 scalar products
@@ -269,7 +269,7 @@ template<> EIGEN_STRONG_INLINE Packet2d ei_pabs(const Packet2d& a)
}
template<> EIGEN_STRONG_INLINE Packet4i ei_pabs(const Packet4i& a)
{
- #ifdef __SSSE3__
+ #ifdef EIGEN_VECTORIZE_SSSE3
return _mm_abs_epi32(a);
#else
Packet4i aux = _mm_srai_epi32(a,31);
@@ -278,7 +278,7 @@ template<> EIGEN_STRONG_INLINE Packet4i ei_pabs(const Packet4i& a)
}
-#ifdef __SSE3__
+#ifdef EIGEN_VECTORIZE_SSE3
// TODO implement SSE2 versions as well as integer versions
template<> EIGEN_STRONG_INLINE Packet4f ei_preduxp<Packet4f>(const Packet4f* vecs)
{
@@ -439,7 +439,7 @@ template<> EIGEN_STRONG_INLINE int ei_predux_max<Packet4i>(const Packet4i& a)
// }
#endif
-#ifdef __SSSE3__
+#ifdef EIGEN_VECTORIZE_SSSE3
// SSSE3 versions
template<int Offset>
struct ei_palign_impl<Offset,Packet4f>
diff --git a/Eigen/src/Core/products/CoeffBasedProduct.h b/Eigen/src/Core/products/CoeffBasedProduct.h
index f030d59b5..3343b1875 100644
--- a/Eigen/src/Core/products/CoeffBasedProduct.h
+++ b/Eigen/src/Core/products/CoeffBasedProduct.h
@@ -109,7 +109,7 @@ class CoeffBasedProduct
typedef MatrixBase<CoeffBasedProduct> Base;
EIGEN_DENSE_PUBLIC_INTERFACE(CoeffBasedProduct)
- typedef typename Base::PlainMatrixType PlainMatrixType;
+ typedef typename Base::PlainObject PlainObject;
private:
@@ -181,8 +181,8 @@ class CoeffBasedProduct
return res;
}
- // Implicit convertion to the nested type (trigger the evaluation of the product)
- operator const PlainMatrixType& () const
+ // Implicit conversion to the nested type (trigger the evaluation of the product)
+ operator const PlainObject& () const
{
m_result.lazyAssign(*this);
return m_result;
@@ -205,15 +205,15 @@ class CoeffBasedProduct
const LhsNested m_lhs;
const RhsNested m_rhs;
- mutable PlainMatrixType m_result;
+ mutable PlainObject m_result;
};
// here we need to overload the nested rule for products
// such that the nested type is a const reference to a plain matrix
-template<typename Lhs, typename Rhs, int N, typename PlainMatrixType>
-struct ei_nested<CoeffBasedProduct<Lhs,Rhs,EvalBeforeNestingBit|EvalBeforeAssigningBit>, N, PlainMatrixType>
+template<typename Lhs, typename Rhs, int N, typename PlainObject>
+struct ei_nested<CoeffBasedProduct<Lhs,Rhs,EvalBeforeNestingBit|EvalBeforeAssigningBit>, N, PlainObject>
{
- typedef PlainMatrixType const& type;
+ typedef PlainObject const& type;
};
/***************************************************************************
diff --git a/Eigen/src/Core/products/GeneralBlockPanelKernel.h b/Eigen/src/Core/products/GeneralBlockPanelKernel.h
index fe1987bdd..18e913b0e 100644
--- a/Eigen/src/Core/products/GeneralBlockPanelKernel.h
+++ b/Eigen/src/Core/products/GeneralBlockPanelKernel.h
@@ -27,6 +27,12 @@
#ifndef EIGEN_EXTERN_INSTANTIATIONS
+#ifdef EIGEN_HAS_FUSE_CJMADD
+#define CJMADD(A,B,C,T) C = cj.pmadd(A,B,C);
+#else
+#define CJMADD(A,B,C,T) T = A; T = cj.pmul(T,B); C = ei_padd(C,T);
+#endif
+
// optimized GEneral packed Block * packed Panel product kernel
template<typename Scalar, int mr, int nr, typename Conj>
struct ei_gebp_kernel
@@ -74,65 +80,111 @@ struct ei_gebp_kernel
const Scalar* blB = &blockB[j2*strideB*PacketSize+offsetB*nr];
for(int k=0; k<peeled_kc; k+=4)
{
- PacketType B0, B1, B2, B3, A0, A1;
-
- A0 = ei_pload(&blA[0*PacketSize]);
- A1 = ei_pload(&blA[1*PacketSize]);
- B0 = ei_pload(&blB[0*PacketSize]);
- B1 = ei_pload(&blB[1*PacketSize]);
- C0 = cj.pmadd(A0, B0, C0);
- if(nr==4) B2 = ei_pload(&blB[2*PacketSize]);
- C4 = cj.pmadd(A1, B0, C4);
- if(nr==4) B3 = ei_pload(&blB[3*PacketSize]);
- B0 = ei_pload(&blB[(nr==4 ? 4 : 2)*PacketSize]);
- C1 = cj.pmadd(A0, B1, C1);
- C5 = cj.pmadd(A1, B1, C5);
- B1 = ei_pload(&blB[(nr==4 ? 5 : 3)*PacketSize]);
- if(nr==4) C2 = cj.pmadd(A0, B2, C2);
- if(nr==4) C6 = cj.pmadd(A1, B2, C6);
- if(nr==4) B2 = ei_pload(&blB[6*PacketSize]);
- if(nr==4) C3 = cj.pmadd(A0, B3, C3);
- A0 = ei_pload(&blA[2*PacketSize]);
- if(nr==4) C7 = cj.pmadd(A1, B3, C7);
- A1 = ei_pload(&blA[3*PacketSize]);
- if(nr==4) B3 = ei_pload(&blB[7*PacketSize]);
- C0 = cj.pmadd(A0, B0, C0);
- C4 = cj.pmadd(A1, B0, C4);
- B0 = ei_pload(&blB[(nr==4 ? 8 : 4)*PacketSize]);
- C1 = cj.pmadd(A0, B1, C1);
- C5 = cj.pmadd(A1, B1, C5);
- B1 = ei_pload(&blB[(nr==4 ? 9 : 5)*PacketSize]);
- if(nr==4) C2 = cj.pmadd(A0, B2, C2);
- if(nr==4) C6 = cj.pmadd(A1, B2, C6);
- if(nr==4) B2 = ei_pload(&blB[10*PacketSize]);
- if(nr==4) C3 = cj.pmadd(A0, B3, C3);
- A0 = ei_pload(&blA[4*PacketSize]);
- if(nr==4) C7 = cj.pmadd(A1, B3, C7);
- A1 = ei_pload(&blA[5*PacketSize]);
- if(nr==4) B3 = ei_pload(&blB[11*PacketSize]);
-
- C0 = cj.pmadd(A0, B0, C0);
- C4 = cj.pmadd(A1, B0, C4);
- B0 = ei_pload(&blB[(nr==4 ? 12 : 6)*PacketSize]);
- C1 = cj.pmadd(A0, B1, C1);
- C5 = cj.pmadd(A1, B1, C5);
- B1 = ei_pload(&blB[(nr==4 ? 13 : 7)*PacketSize]);
- if(nr==4) C2 = cj.pmadd(A0, B2, C2);
- if(nr==4) C6 = cj.pmadd(A1, B2, C6);
- if(nr==4) B2 = ei_pload(&blB[14*PacketSize]);
- if(nr==4) C3 = cj.pmadd(A0, B3, C3);
- A0 = ei_pload(&blA[6*PacketSize]);
- if(nr==4) C7 = cj.pmadd(A1, B3, C7);
- A1 = ei_pload(&blA[7*PacketSize]);
- if(nr==4) B3 = ei_pload(&blB[15*PacketSize]);
- C0 = cj.pmadd(A0, B0, C0);
- C4 = cj.pmadd(A1, B0, C4);
- C1 = cj.pmadd(A0, B1, C1);
- C5 = cj.pmadd(A1, B1, C5);
- if(nr==4) C2 = cj.pmadd(A0, B2, C2);
- if(nr==4) C6 = cj.pmadd(A1, B2, C6);
- if(nr==4) C3 = cj.pmadd(A0, B3, C3);
- if(nr==4) C7 = cj.pmadd(A1, B3, C7);
+ if(nr==2)
+ {
+ PacketType B0, T0, A0, A1;
+
+ A0 = ei_pload(&blA[0*PacketSize]);
+ A1 = ei_pload(&blA[1*PacketSize]);
+ B0 = ei_pload(&blB[0*PacketSize]);
+ CJMADD(A0,B0,C0,T0);
+ CJMADD(A1,B0,C4,T0);
+ B0 = ei_pload(&blB[1*PacketSize]);
+ CJMADD(A0,B0,C1,T0);
+ CJMADD(A1,B0,C5,T0);
+
+ A0 = ei_pload(&blA[2*PacketSize]);
+ A1 = ei_pload(&blA[3*PacketSize]);
+ B0 = ei_pload(&blB[2*PacketSize]);
+ CJMADD(A0,B0,C0,T0);
+ CJMADD(A1,B0,C4,T0);
+ B0 = ei_pload(&blB[3*PacketSize]);
+ CJMADD(A0,B0,C1,T0);
+ CJMADD(A1,B0,C5,T0);
+
+ A0 = ei_pload(&blA[4*PacketSize]);
+ A1 = ei_pload(&blA[5*PacketSize]);
+ B0 = ei_pload(&blB[4*PacketSize]);
+ CJMADD(A0,B0,C0,T0);
+ CJMADD(A1,B0,C4,T0);
+ B0 = ei_pload(&blB[5*PacketSize]);
+ CJMADD(A0,B0,C1,T0);
+ CJMADD(A1,B0,C5,T0);
+
+ A0 = ei_pload(&blA[6*PacketSize]);
+ A1 = ei_pload(&blA[7*PacketSize]);
+ B0 = ei_pload(&blB[6*PacketSize]);
+ CJMADD(A0,B0,C0,T0);
+ CJMADD(A1,B0,C4,T0);
+ B0 = ei_pload(&blB[7*PacketSize]);
+ CJMADD(A0,B0,C1,T0);
+ CJMADD(A1,B0,C5,T0);
+ }
+ else
+ {
+
+ PacketType B0, B1, B2, B3, A0, A1;
+ PacketType T0, T1;
+
+ A0 = ei_pload(&blA[0*PacketSize]);
+ A1 = ei_pload(&blA[1*PacketSize]);
+ B0 = ei_pload(&blB[0*PacketSize]);
+ B1 = ei_pload(&blB[1*PacketSize]);
+
+ CJMADD(A0,B0,C0,T0);
+ if(nr==4) B2 = ei_pload(&blB[2*PacketSize]);
+ CJMADD(A1,B0,C4,T1);
+ if(nr==4) B3 = ei_pload(&blB[3*PacketSize]);
+ B0 = ei_pload(&blB[(nr==4 ? 4 : 2)*PacketSize]);
+ CJMADD(A0,B1,C1,T0);
+ CJMADD(A1,B1,C5,T1);
+ B1 = ei_pload(&blB[(nr==4 ? 5 : 3)*PacketSize]);
+ if(nr==4) { CJMADD(A0,B2,C2,T0); }
+ if(nr==4) { CJMADD(A1,B2,C6,T1); }
+ if(nr==4) B2 = ei_pload(&blB[6*PacketSize]);
+ if(nr==4) { CJMADD(A0,B3,C3,T0); }
+ A0 = ei_pload(&blA[2*PacketSize]);
+ if(nr==4) { CJMADD(A1,B3,C7,T1); }
+ A1 = ei_pload(&blA[3*PacketSize]);
+ if(nr==4) B3 = ei_pload(&blB[7*PacketSize]);
+ CJMADD(A0,B0,C0,T0);
+ CJMADD(A1,B0,C4,T1);
+ B0 = ei_pload(&blB[(nr==4 ? 8 : 4)*PacketSize]);
+ CJMADD(A0,B1,C1,T0);
+ CJMADD(A1,B1,C5,T1);
+ B1 = ei_pload(&blB[(nr==4 ? 9 : 5)*PacketSize]);
+ if(nr==4) { CJMADD(A0,B2,C2,T0); }
+ if(nr==4) { CJMADD(A1,B2,C6,T1); }
+ if(nr==4) B2 = ei_pload(&blB[10*PacketSize]);
+ if(nr==4) { CJMADD(A0,B3,C3,T0); }
+ A0 = ei_pload(&blA[4*PacketSize]);
+ if(nr==4) { CJMADD(A1,B3,C7,T1); }
+ A1 = ei_pload(&blA[5*PacketSize]);
+ if(nr==4) B3 = ei_pload(&blB[11*PacketSize]);
+
+ CJMADD(A0,B0,C0,T0);
+ CJMADD(A1,B0,C4,T1);
+ B0 = ei_pload(&blB[(nr==4 ? 12 : 6)*PacketSize]);
+ CJMADD(A0,B1,C1,T0);
+ CJMADD(A1,B1,C5,T1);
+ B1 = ei_pload(&blB[(nr==4 ? 13 : 7)*PacketSize]);
+ if(nr==4) { CJMADD(A0,B2,C2,T0); }
+ if(nr==4) { CJMADD(A1,B2,C6,T1); }
+ if(nr==4) B2 = ei_pload(&blB[14*PacketSize]);
+ if(nr==4) { CJMADD(A0,B3,C3,T0); }
+ A0 = ei_pload(&blA[6*PacketSize]);
+ if(nr==4) { CJMADD(A1,B3,C7,T1); }
+ A1 = ei_pload(&blA[7*PacketSize]);
+ if(nr==4) B3 = ei_pload(&blB[15*PacketSize]);
+ CJMADD(A0,B0,C0,T0);
+ CJMADD(A1,B0,C4,T1);
+ CJMADD(A0,B1,C1,T0);
+ CJMADD(A1,B1,C5,T1);
+ if(nr==4) { CJMADD(A0,B2,C2,T0); }
+ if(nr==4) { CJMADD(A1,B2,C6,T1); }
+ if(nr==4) { CJMADD(A0,B3,C3,T0); }
+ if(nr==4) { CJMADD(A1,B3,C7,T1); }
+ }
blB += 4*nr*PacketSize;
blA += 4*mr;
@@ -140,22 +192,40 @@ struct ei_gebp_kernel
// process remaining peeled loop
for(int k=peeled_kc; k<depth; k++)
{
- PacketType B0, B1, B2, B3, A0, A1;
-
- A0 = ei_pload(&blA[0*PacketSize]);
- A1 = ei_pload(&blA[1*PacketSize]);
- B0 = ei_pload(&blB[0*PacketSize]);
- B1 = ei_pload(&blB[1*PacketSize]);
- C0 = cj.pmadd(A0, B0, C0);
- if(nr==4) B2 = ei_pload(&blB[2*PacketSize]);
- C4 = cj.pmadd(A1, B0, C4);
- if(nr==4) B3 = ei_pload(&blB[3*PacketSize]);
- C1 = cj.pmadd(A0, B1, C1);
- C5 = cj.pmadd(A1, B1, C5);
- if(nr==4) C2 = cj.pmadd(A0, B2, C2);
- if(nr==4) C6 = cj.pmadd(A1, B2, C6);
- if(nr==4) C3 = cj.pmadd(A0, B3, C3);
- if(nr==4) C7 = cj.pmadd(A1, B3, C7);
+ if(nr==2)
+ {
+ PacketType B0, T0, A0, A1;
+
+ A0 = ei_pload(&blA[0*PacketSize]);
+ A1 = ei_pload(&blA[1*PacketSize]);
+ B0 = ei_pload(&blB[0*PacketSize]);
+ CJMADD(A0,B0,C0,T0);
+ CJMADD(A1,B0,C4,T0);
+ B0 = ei_pload(&blB[1*PacketSize]);
+ CJMADD(A0,B0,C1,T0);
+ CJMADD(A1,B0,C5,T0);
+ }
+ else
+ {
+ PacketType B0, B1, B2, B3, A0, A1, T0, T1;
+
+ A0 = ei_pload(&blA[0*PacketSize]);
+ A1 = ei_pload(&blA[1*PacketSize]);
+ B0 = ei_pload(&blB[0*PacketSize]);
+ B1 = ei_pload(&blB[1*PacketSize]);
+
+ CJMADD(A0,B0,C0,T0);
+ if(nr==4) B2 = ei_pload(&blB[2*PacketSize]);
+ CJMADD(A1,B0,C4,T1);
+ if(nr==4) B3 = ei_pload(&blB[3*PacketSize]);
+ B0 = ei_pload(&blB[(nr==4 ? 4 : 2)*PacketSize]);
+ CJMADD(A0,B1,C1,T0);
+ CJMADD(A1,B1,C5,T1);
+ if(nr==4) { CJMADD(A0,B2,C2,T0); }
+ if(nr==4) { CJMADD(A1,B2,C6,T1); }
+ if(nr==4) { CJMADD(A0,B3,C3,T0); }
+ if(nr==4) { CJMADD(A1,B3,C7,T1); }
+ }
blB += nr*PacketSize;
blA += mr;
@@ -189,45 +259,79 @@ struct ei_gebp_kernel
const Scalar* blB = &blockB[j2*strideB*PacketSize+offsetB*nr];
for(int k=0; k<peeled_kc; k+=4)
{
- PacketType B0, B1, B2, B3, A0;
-
- A0 = ei_pload(&blA[0*PacketSize]);
- B0 = ei_pload(&blB[0*PacketSize]);
- B1 = ei_pload(&blB[1*PacketSize]);
- C0 = cj.pmadd(A0, B0, C0);
- if(nr==4) B2 = ei_pload(&blB[2*PacketSize]);
- if(nr==4) B3 = ei_pload(&blB[3*PacketSize]);
- B0 = ei_pload(&blB[(nr==4 ? 4 : 2)*PacketSize]);
- C1 = cj.pmadd(A0, B1, C1);
- B1 = ei_pload(&blB[(nr==4 ? 5 : 3)*PacketSize]);
- if(nr==4) C2 = cj.pmadd(A0, B2, C2);
- if(nr==4) B2 = ei_pload(&blB[6*PacketSize]);
- if(nr==4) C3 = cj.pmadd(A0, B3, C3);
- A0 = ei_pload(&blA[1*PacketSize]);
- if(nr==4) B3 = ei_pload(&blB[7*PacketSize]);
- C0 = cj.pmadd(A0, B0, C0);
- B0 = ei_pload(&blB[(nr==4 ? 8 : 4)*PacketSize]);
- C1 = cj.pmadd(A0, B1, C1);
- B1 = ei_pload(&blB[(nr==4 ? 9 : 5)*PacketSize]);
- if(nr==4) C2 = cj.pmadd(A0, B2, C2);
- if(nr==4) B2 = ei_pload(&blB[10*PacketSize]);
- if(nr==4) C3 = cj.pmadd(A0, B3, C3);
- A0 = ei_pload(&blA[2*PacketSize]);
- if(nr==4) B3 = ei_pload(&blB[11*PacketSize]);
-
- C0 = cj.pmadd(A0, B0, C0);
- B0 = ei_pload(&blB[(nr==4 ? 12 : 6)*PacketSize]);
- C1 = cj.pmadd(A0, B1, C1);
- B1 = ei_pload(&blB[(nr==4 ? 13 : 7)*PacketSize]);
- if(nr==4) C2 = cj.pmadd(A0, B2, C2);
- if(nr==4) B2 = ei_pload(&blB[14*PacketSize]);
- if(nr==4) C3 = cj.pmadd(A0, B3, C3);
- A0 = ei_pload(&blA[3*PacketSize]);
- if(nr==4) B3 = ei_pload(&blB[15*PacketSize]);
- C0 = cj.pmadd(A0, B0, C0);
- C1 = cj.pmadd(A0, B1, C1);
- if(nr==4) C2 = cj.pmadd(A0, B2, C2);
- if(nr==4) C3 = cj.pmadd(A0, B3, C3);
+ if(nr==2)
+ {
+ PacketType B0, T0, A0;
+
+ A0 = ei_pload(&blA[0*PacketSize]);
+ B0 = ei_pload(&blB[0*PacketSize]);
+ CJMADD(A0,B0,C0,T0);
+ B0 = ei_pload(&blB[1*PacketSize]);
+ CJMADD(A0,B0,C1,T0);
+
+ A0 = ei_pload(&blA[1*PacketSize]);
+ B0 = ei_pload(&blB[2*PacketSize]);
+ CJMADD(A0,B0,C0,T0);
+ B0 = ei_pload(&blB[3*PacketSize]);
+ CJMADD(A0,B0,C1,T0);
+
+ A0 = ei_pload(&blA[2*PacketSize]);
+ B0 = ei_pload(&blB[4*PacketSize]);
+ CJMADD(A0,B0,C0,T0);
+ B0 = ei_pload(&blB[5*PacketSize]);
+ CJMADD(A0,B0,C1,T0);
+
+ A0 = ei_pload(&blA[3*PacketSize]);
+ B0 = ei_pload(&blB[6*PacketSize]);
+ CJMADD(A0,B0,C0,T0);
+ B0 = ei_pload(&blB[7*PacketSize]);
+ CJMADD(A0,B0,C1,T0);
+ }
+ else
+ {
+
+ PacketType B0, B1, B2, B3, A0;
+ PacketType T0, T1;
+
+ A0 = ei_pload(&blA[0*PacketSize]);
+ B0 = ei_pload(&blB[0*PacketSize]);
+ B1 = ei_pload(&blB[1*PacketSize]);
+
+ CJMADD(A0,B0,C0,T0);
+ if(nr==4) B2 = ei_pload(&blB[2*PacketSize]);
+ if(nr==4) B3 = ei_pload(&blB[3*PacketSize]);
+ B0 = ei_pload(&blB[(nr==4 ? 4 : 2)*PacketSize]);
+ CJMADD(A0,B1,C1,T1);
+ B1 = ei_pload(&blB[(nr==4 ? 5 : 3)*PacketSize]);
+ if(nr==4) { CJMADD(A0,B2,C2,T0); }
+ if(nr==4) B2 = ei_pload(&blB[6*PacketSize]);
+ if(nr==4) { CJMADD(A0,B3,C3,T1); }
+ A0 = ei_pload(&blA[1*PacketSize]);
+ if(nr==4) B3 = ei_pload(&blB[7*PacketSize]);
+ CJMADD(A0,B0,C0,T0);
+ B0 = ei_pload(&blB[(nr==4 ? 8 : 4)*PacketSize]);
+ CJMADD(A0,B1,C1,T1);
+ B1 = ei_pload(&blB[(nr==4 ? 9 : 5)*PacketSize]);
+ if(nr==4) { CJMADD(A0,B2,C2,T0); }
+ if(nr==4) B2 = ei_pload(&blB[10*PacketSize]);
+ if(nr==4) { CJMADD(A0,B3,C3,T1); }
+ A0 = ei_pload(&blA[2*PacketSize]);
+ if(nr==4) B3 = ei_pload(&blB[11*PacketSize]);
+
+ CJMADD(A0,B0,C0,T0);
+ B0 = ei_pload(&blB[(nr==4 ? 12 : 6)*PacketSize]);
+ CJMADD(A0,B1,C1,T1);
+ B1 = ei_pload(&blB[(nr==4 ? 13 : 7)*PacketSize]);
+ if(nr==4) { CJMADD(A0,B2,C2,T0); }
+ if(nr==4) B2 = ei_pload(&blB[14*PacketSize]);
+ if(nr==4) { CJMADD(A0,B3,C3,T1); }
+ A0 = ei_pload(&blA[3*PacketSize]);
+ if(nr==4) B3 = ei_pload(&blB[15*PacketSize]);
+ CJMADD(A0,B0,C0,T0);
+ CJMADD(A0,B1,C1,T1);
+ if(nr==4) { CJMADD(A0,B2,C2,T0); }
+ if(nr==4) { CJMADD(A0,B3,C3,T1); }
+ }
blB += 4*nr*PacketSize;
blA += 4*PacketSize;
@@ -235,17 +339,32 @@ struct ei_gebp_kernel
// process remaining peeled loop
for(int k=peeled_kc; k<depth; k++)
{
- PacketType B0, B1, B2, B3, A0;
-
- A0 = ei_pload(&blA[0*PacketSize]);
- B0 = ei_pload(&blB[0*PacketSize]);
- B1 = ei_pload(&blB[1*PacketSize]);
- C0 = cj.pmadd(A0, B0, C0);
- if(nr==4) B2 = ei_pload(&blB[2*PacketSize]);
- if(nr==4) B3 = ei_pload(&blB[3*PacketSize]);
- C1 = cj.pmadd(A0, B1, C1);
- if(nr==4) C2 = cj.pmadd(A0, B2, C2);
- if(nr==4) C3 = cj.pmadd(A0, B3, C3);
+ if(nr==2)
+ {
+ PacketType B0, T0, A0;
+
+ A0 = ei_pload(&blA[0*PacketSize]);
+ B0 = ei_pload(&blB[0*PacketSize]);
+ CJMADD(A0,B0,C0,T0);
+ B0 = ei_pload(&blB[1*PacketSize]);
+ CJMADD(A0,B0,C1,T0);
+ }
+ else
+ {
+ PacketType B0, B1, B2, B3, A0;
+ PacketType T0, T1;
+
+ A0 = ei_pload(&blA[0*PacketSize]);
+ B0 = ei_pload(&blB[0*PacketSize]);
+ B1 = ei_pload(&blB[1*PacketSize]);
+ if(nr==4) B2 = ei_pload(&blB[2*PacketSize]);
+ if(nr==4) B3 = ei_pload(&blB[3*PacketSize]);
+
+ CJMADD(A0,B0,C0,T0);
+ CJMADD(A0,B1,C1,T1);
+ if(nr==4) { CJMADD(A0,B2,C2,T0); }
+ if(nr==4) { CJMADD(A0,B3,C3,T1); }
+ }
blB += nr*PacketSize;
blA += PacketSize;
@@ -268,17 +387,32 @@ struct ei_gebp_kernel
const Scalar* blB = &blockB[j2*strideB*PacketSize+offsetB*nr];
for(int k=0; k<depth; k++)
{
- Scalar B0, B1, B2, B3, A0;
-
- A0 = blA[k];
- B0 = blB[0*PacketSize];
- B1 = blB[1*PacketSize];
- C0 = cj.pmadd(A0, B0, C0);
- if(nr==4) B2 = blB[2*PacketSize];
- if(nr==4) B3 = blB[3*PacketSize];
- C1 = cj.pmadd(A0, B1, C1);
- if(nr==4) C2 = cj.pmadd(A0, B2, C2);
- if(nr==4) C3 = cj.pmadd(A0, B3, C3);
+ if(nr==2)
+ {
+ Scalar B0, T0, A0;
+
+ A0 = blA[0*PacketSize];
+ B0 = blB[0*PacketSize];
+ CJMADD(A0,B0,C0,T0);
+ B0 = blB[1*PacketSize];
+ CJMADD(A0,B0,C1,T0);
+ }
+ else
+ {
+ Scalar B0, B1, B2, B3, A0;
+ Scalar T0, T1;
+
+ A0 = blA[k];
+ B0 = blB[0*PacketSize];
+ B1 = blB[1*PacketSize];
+ if(nr==4) B2 = blB[2*PacketSize];
+ if(nr==4) B3 = blB[3*PacketSize];
+
+ CJMADD(A0,B0,C0,T0);
+ CJMADD(A0,B1,C1,T1);
+ if(nr==4) { CJMADD(A0,B2,C2,T0); }
+ if(nr==4) { CJMADD(A0,B3,C3,T1); }
+ }
blB += nr*PacketSize;
}
@@ -310,13 +444,13 @@ struct ei_gebp_kernel
const Scalar* blB = &blockB[j2*strideB*PacketSize+offsetB];
for(int k=0; k<depth; k++)
{
- PacketType B0, A0, A1;
+ PacketType B0, A0, A1, T0, T1;
A0 = ei_pload(&blA[0*PacketSize]);
A1 = ei_pload(&blA[1*PacketSize]);
B0 = ei_pload(&blB[0*PacketSize]);
- C0 = cj.pmadd(A0, B0, C0);
- C4 = cj.pmadd(A1, B0, C4);
+ CJMADD(A0,B0,C0,T0);
+ CJMADD(A1,B0,C4,T1);
blB += PacketSize;
blA += mr;
@@ -334,7 +468,7 @@ struct ei_gebp_kernel
#endif
PacketType C0 = ei_ploadu(&res[(j2+0)*resStride + i]);
-
+
const Scalar* blB = &blockB[j2*strideB*PacketSize+offsetB];
for(int k=0; k<depth; k++)
{
@@ -363,6 +497,8 @@ struct ei_gebp_kernel
}
};
+#undef CJMADD
+
// pack a block of the lhs
// The travesal is as follow (mr==4):
// 0 4 8 12 ...
@@ -474,7 +610,7 @@ struct ei_gemm_pack_rhs<Scalar, nr, ColMajor, PanelMode>
// skip what we have after
if(PanelMode) count += PacketSize * nr * (stride-offset-depth);
}
-
+
// copy the remaining columns one at a time (nr==1)
for(int j2=packet_cols; j2<cols; ++j2)
{
diff --git a/Eigen/src/Core/util/BlasUtil.h b/Eigen/src/Core/util/BlasUtil.h
index 3777464dc..4d216d77a 100644
--- a/Eigen/src/Core/util/BlasUtil.h
+++ b/Eigen/src/Core/util/BlasUtil.h
@@ -166,7 +166,7 @@ template<typename XprType> struct ei_blas_traits
};
typedef typename ei_meta_if<int(ActualAccess)==HasDirectAccess,
ExtractType,
- typename _ExtractType::PlainMatrixType
+ typename _ExtractType::PlainObject
>::ret DirectLinearAccessType;
static inline ExtractType extract(const XprType& x) { return x; }
static inline Scalar extractScalarFactor(const XprType&) { return Scalar(1); }
@@ -227,7 +227,7 @@ struct ei_blas_traits<Transpose<NestedXpr> >
typedef Transpose<typename Base::_ExtractType> _ExtractType;
typedef typename ei_meta_if<int(Base::ActualAccess)==HasDirectAccess,
ExtractType,
- typename ExtractType::PlainMatrixType
+ typename ExtractType::PlainObject
>::ret DirectLinearAccessType;
enum {
IsTransposed = Base::IsTransposed ? 0 : 1
@@ -236,4 +236,22 @@ struct ei_blas_traits<Transpose<NestedXpr> >
static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x.nestedExpression()); }
};
+template<typename T, int Access=ei_blas_traits<T>::ActualAccess>
+struct ei_extract_data_selector {
+ static const typename T::Scalar* run(const T& m)
+ {
+ return &ei_blas_traits<T>::extract(m).const_cast_derived().coeffRef(0,0); // FIXME this should be .data()
+ }
+};
+
+template<typename T>
+struct ei_extract_data_selector<T,NoDirectAccess> {
+ static typename T::Scalar* run(const T&) { return 0; }
+};
+
+template<typename T> const typename T::Scalar* ei_extract_data(const T& m)
+{
+ return ei_extract_data_selector<T>::run(m);
+}
+
#endif // EIGEN_BLASUTIL_H
diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h
index c2d45dc30..6096272fa 100644
--- a/Eigen/src/Core/util/ForwardDeclarations.h
+++ b/Eigen/src/Core/util/ForwardDeclarations.h
@@ -29,7 +29,7 @@
template<typename T> struct ei_traits;
template<typename T> struct NumTraits;
-template<typename Derived> struct AnyMatrixBase;
+template<typename Derived> struct EigenBase;
template<typename _Scalar, int _Rows, int _Cols,
int _Options = EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION | AutoAlign,
diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h
index dc1aa150b..37ccef047 100644
--- a/Eigen/src/Core/util/Macros.h
+++ b/Eigen/src/Core/util/Macros.h
@@ -211,7 +211,7 @@ using Eigen::ei_cos;
*/
#if !EIGEN_ALIGN
#define EIGEN_ALIGN_TO_BOUNDARY(n)
-#elif (defined __GNUC__)
+#elif (defined __GNUC__) || (defined __PGI)
#define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
#elif (defined _MSC_VER)
#define EIGEN_ALIGN_TO_BOUNDARY(n) __declspec(align(n))
diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h
index 8ddf4450a..eceb5ab2a 100644
--- a/Eigen/src/Core/util/XprHelper.h
+++ b/Eigen/src/Core/util/XprHelper.h
@@ -147,7 +147,7 @@ template<typename T, typename StorageType = typename ei_traits<T>::StorageType>
template<typename T> struct ei_eval<T,Dense>
{
typedef typename ei_plain_matrix_type<T>::type type;
-// typedef typename T::PlainMatrixType type;
+// typedef typename T::PlainObject type;
// typedef T::Matrix<typename ei_traits<T>::Scalar,
// ei_traits<T>::RowsAtCompileTime,
// ei_traits<T>::ColsAtCompileTime,
@@ -201,6 +201,18 @@ template<typename T> struct ei_plain_matrix_type_row_major
// we should be able to get rid of this one too
template<typename T> struct ei_must_nest_by_value { enum { ret = false }; };
+template<class T>
+struct ei_is_reference
+{
+ enum { ret = false };
+};
+
+template<class T>
+struct ei_is_reference<T&>
+{
+ enum { ret = true };
+};
+
/**
* The reference selector for template expressions. The idea is that we don't
* need to use references for expressions since they are light weight proxy
@@ -234,7 +246,7 @@ struct ei_ref_selector
* const Matrix3d&, because the internal logic of ei_nested determined that since a was already a matrix, there was no point
* in copying it into another matrix.
*/
-template<typename T, int n=1, typename PlainMatrixType = typename ei_eval<T>::type> struct ei_nested
+template<typename T, int n=1, typename PlainObject = typename ei_eval<T>::type> struct ei_nested
{
enum {
CostEval = (n+1) * int(NumTraits<typename ei_traits<T>::Scalar>::ReadCost),
@@ -244,7 +256,7 @@ template<typename T, int n=1, typename PlainMatrixType = typename ei_eval<T>::ty
typedef typename ei_meta_if<
( int(ei_traits<T>::Flags) & EvalBeforeNestingBit ) ||
( int(CostEval) <= int(CostNoEval) ),
- PlainMatrixType,
+ PlainObject,
typename ei_ref_selector<T>::type
>::ret type;
};
@@ -258,7 +270,7 @@ template<unsigned int Flags> struct ei_are_flags_consistent
* overloads for complex types */
template<typename Derived,typename Scalar,typename OtherScalar,
bool EnableIt = !ei_is_same_type<Scalar,OtherScalar>::ret >
-struct ei_special_scalar_op_base : public AnyMatrixBase<Derived>
+struct ei_special_scalar_op_base : public EigenBase<Derived>
{
// dummy operator* so that the
// "using ei_special_scalar_op_base::operator*" compiles
@@ -266,7 +278,7 @@ struct ei_special_scalar_op_base : public AnyMatrixBase<Derived>
};
template<typename Derived,typename Scalar,typename OtherScalar>
-struct ei_special_scalar_op_base<Derived,Scalar,OtherScalar,true> : public AnyMatrixBase<Derived>
+struct ei_special_scalar_op_base<Derived,Scalar,OtherScalar,true> : public EigenBase<Derived>
{
const CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,OtherScalar>, Derived>
operator*(const OtherScalar& scalar) const
diff --git a/Eigen/src/Eigen2Support/TriangularSolver.h b/Eigen/src/Eigen2Support/TriangularSolver.h
index 94b92577e..833dd58d2 100644
--- a/Eigen/src/Eigen2Support/TriangularSolver.h
+++ b/Eigen/src/Eigen2Support/TriangularSolver.h
@@ -37,7 +37,7 @@ const unsigned int UnitLowerTriangular = UnitLower;
template<typename ExpressionType, unsigned int Added, unsigned int Removed>
template<typename OtherDerived>
-typename ExpressionType::PlainMatrixType
+typename ExpressionType::PlainObject
Flagged<ExpressionType,Added,Removed>::solveTriangular(const MatrixBase<OtherDerived>& other) const
{
return m_matrix.template triangularView<Added>.solve(other.derived());
diff --git a/Eigen/src/Eigenvalues/ComplexSchur.h b/Eigen/src/Eigenvalues/ComplexSchur.h
index 5deac3247..0fad415a2 100644
--- a/Eigen/src/Eigenvalues/ComplexSchur.h
+++ b/Eigen/src/Eigenvalues/ComplexSchur.h
@@ -154,6 +154,14 @@ void ComplexSchur<MatrixType>::compute(const MatrixType& matrix, bool skipU)
m_matT = hess.matrixH();
if(!skipU) m_matU = hess.matrixQ();
+
+ // Reduce the Hessenberg matrix m_matT to triangular form by QR iteration.
+
+ // The matrix m_matT is divided in three parts.
+ // Rows 0,...,il-1 are decoupled from the rest because m_matT(il,il-1) is zero.
+ // Rows il,...,iu is the part we are working on (the active submatrix).
+ // Rows iu+1,...,end are already brought in triangular form.
+
int iu = m_matT.cols() - 1;
int il;
RealScalar d,sd,sf;
@@ -164,7 +172,7 @@ void ComplexSchur<MatrixType>::compute(const MatrixType& matrix, bool skipU)
int iter = 0;
while(true)
{
- //locate the range in which to iterate
+ // find iu, the bottom row of the active submatrix
while(iu > 0)
{
d = ei_norm1(m_matT.coeff(iu,iu)) + ei_norm1(m_matT.coeff(iu-1,iu-1));
@@ -187,6 +195,7 @@ void ComplexSchur<MatrixType>::compute(const MatrixType& matrix, bool skipU)
return;
}
+ // find il, the top row of the active submatrix
il = iu-1;
while(il > 0)
{
@@ -202,15 +211,16 @@ void ComplexSchur<MatrixType>::compute(const MatrixType& matrix, bool skipU)
if( il != 0 ) m_matT.coeffRef(il,il-1) = Complex(0);
- // compute the shift (the normalization by sf is to avoid under/overflow)
+ // compute the shift kappa as one of the eigenvalues of the 2x2
+ // diagonal block on the bottom of the active submatrix
+
Matrix<Scalar,2,2> t = m_matT.template block<2,2>(iu-1,iu-1);
sf = t.cwiseAbs().sum();
- t /= sf;
-
- c = t.determinant();
- b = t.diagonal().sum();
+ t /= sf; // the normalization by sf is to avoid under/overflow
- disc = ei_sqrt(b*b - RealScalar(4)*c);
+ b = t.coeff(0,0) + t.coeff(1,1);
+ c = t.coeff(0,0) - t.coeff(1,1);
+ disc = ei_sqrt(c*c + RealScalar(4)*t.coeff(0,1)*t.coeff(1,0));
r1 = (b+disc)/RealScalar(2);
r2 = (b-disc)/RealScalar(2);
@@ -224,6 +234,12 @@ void ComplexSchur<MatrixType>::compute(const MatrixType& matrix, bool skipU)
kappa = sf * r1;
else
kappa = sf * r2;
+
+ if (iter == 10 || iter == 20)
+ {
+ // exceptional shift, taken from http://www.netlib.org/eispack/comqr.f
+ kappa = ei_abs(ei_real(m_matT.coeff(iu,iu-1))) + ei_abs(ei_real(m_matT.coeff(iu-1,iu-2)));
+ }
// perform the QR step using Givens rotations
PlanarRotation<Complex> rot;
@@ -246,18 +262,6 @@ void ComplexSchur<MatrixType>::compute(const MatrixType& matrix, bool skipU)
}
}
- // FIXME : is it necessary ?
- /*
- for(int i=0 ; i<n ; i++)
- for(int j=0 ; j<n ; j++)
- {
- if(ei_abs(ei_real(m_matT.coeff(i,j))) < eps)
- ei_real_ref(m_matT.coeffRef(i,j)) = 0;
- if(ei_imag(ei_abs(m_matT.coeff(i,j))) < eps)
- ei_imag_ref(m_matT.coeffRef(i,j)) = 0;
- }
- */
-
m_isInitialized = true;
m_matUisUptodate = !skipU;
}
diff --git a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
index 960e9b417..e8e9bea97 100644
--- a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
+++ b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
@@ -276,7 +276,7 @@ inline Matrix<typename NumTraits<typename ei_traits<Derived>::Scalar>::Real, ei_
MatrixBase<Derived>::eigenvalues() const
{
ei_assert(Flags&SelfAdjoint);
- return SelfAdjointEigenSolver<typename Derived::PlainMatrixType>(eval(),false).eigenvalues();
+ return SelfAdjointEigenSolver<typename Derived::PlainObject>(eval(),false).eigenvalues();
}
template<typename Derived, bool IsSelfAdjoint>
@@ -296,7 +296,7 @@ template<typename Derived> struct ei_operatorNorm_selector<Derived, false>
static inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real
operatorNorm(const MatrixBase<Derived>& m)
{
- typename Derived::PlainMatrixType m_eval(m);
+ typename Derived::PlainObject m_eval(m);
// FIXME if it is really guaranteed that the eigenvalues are already sorted,
// then we don't need to compute a maxCoeff() here, comparing the 1st and last ones is enough.
return ei_sqrt(
diff --git a/Eigen/src/Geometry/Homogeneous.h b/Eigen/src/Geometry/Homogeneous.h
index 76ca66c57..2b8b9cf8e 100644
--- a/Eigen/src/Geometry/Homogeneous.h
+++ b/Eigen/src/Geometry/Homogeneous.h
@@ -213,9 +213,9 @@ struct ei_traits<ei_homogeneous_left_product_impl<Homogeneous<MatrixType,Vertica
typedef Matrix<typename ei_traits<MatrixType>::Scalar,
Lhs::RowsAtCompileTime,
MatrixType::ColsAtCompileTime,
- MatrixType::PlainMatrixType::Options,
+ MatrixType::PlainObject::Options,
Lhs::MaxRowsAtCompileTime,
- MatrixType::MaxColsAtCompileTime> ReturnMatrixType;
+ MatrixType::MaxColsAtCompileTime> ReturnType;
};
template<typename MatrixType,typename Lhs>
@@ -251,9 +251,9 @@ struct ei_traits<ei_homogeneous_right_product_impl<Homogeneous<MatrixType,Horizo
typedef Matrix<typename ei_traits<MatrixType>::Scalar,
MatrixType::RowsAtCompileTime,
Rhs::ColsAtCompileTime,
- MatrixType::PlainMatrixType::Options,
+ MatrixType::PlainObject::Options,
MatrixType::MaxRowsAtCompileTime,
- Rhs::MaxColsAtCompileTime> ReturnMatrixType;
+ Rhs::MaxColsAtCompileTime> ReturnType;
};
template<typename MatrixType,typename Rhs>
diff --git a/Eigen/src/Geometry/OrthoMethods.h b/Eigen/src/Geometry/OrthoMethods.h
index c10b6abf4..265507eb9 100644
--- a/Eigen/src/Geometry/OrthoMethods.h
+++ b/Eigen/src/Geometry/OrthoMethods.h
@@ -35,7 +35,7 @@
*/
template<typename Derived>
template<typename OtherDerived>
-inline typename MatrixBase<Derived>::PlainMatrixType
+inline typename MatrixBase<Derived>::PlainObject
MatrixBase<Derived>::cross(const MatrixBase<OtherDerived>& other) const
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived,3)
@@ -79,7 +79,7 @@ struct ei_cross3_impl {
*/
template<typename Derived>
template<typename OtherDerived>
-inline typename MatrixBase<Derived>::PlainMatrixType
+inline typename MatrixBase<Derived>::PlainObject
MatrixBase<Derived>::cross3(const MatrixBase<OtherDerived>& other) const
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived,4)
@@ -210,7 +210,7 @@ struct ei_unitOrthogonal_selector<Derived,2>
* \sa cross()
*/
template<typename Derived>
-typename MatrixBase<Derived>::PlainMatrixType
+typename MatrixBase<Derived>::PlainObject
MatrixBase<Derived>::unitOrthogonal() const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
diff --git a/Eigen/src/Geometry/Quaternion.h b/Eigen/src/Geometry/Quaternion.h
index 67319d15b..e0dfadd7c 100644
--- a/Eigen/src/Geometry/Quaternion.h
+++ b/Eigen/src/Geometry/Quaternion.h
@@ -211,6 +211,7 @@ public:
template<typename _Scalar>
struct ei_traits<Quaternion<_Scalar> >
{
+ typedef Quaternion<_Scalar> PlainObject;
typedef _Scalar Scalar;
typedef Matrix<_Scalar,4,1> Coefficients;
enum{
diff --git a/Eigen/src/Geometry/RotationBase.h b/Eigen/src/Geometry/RotationBase.h
index e8bb16f17..9b865889c 100644
--- a/Eigen/src/Geometry/RotationBase.h
+++ b/Eigen/src/Geometry/RotationBase.h
@@ -74,12 +74,12 @@ class RotationBase
*/
template<typename OtherDerived>
EIGEN_STRONG_INLINE typename ei_rotation_base_generic_product_selector<Derived,OtherDerived,OtherDerived::IsVectorAtCompileTime>::ReturnType
- operator*(const AnyMatrixBase<OtherDerived>& e) const
+ operator*(const EigenBase<OtherDerived>& e) const
{ return ei_rotation_base_generic_product_selector<Derived,OtherDerived>::run(derived(), e.derived()); }
/** \returns the concatenation of a linear transformation \a l with the rotation \a r */
template<typename OtherDerived> friend
- inline RotationMatrixType operator*(const AnyMatrixBase<OtherDerived>& l, const Derived& r)
+ inline RotationMatrixType operator*(const EigenBase<OtherDerived>& l, const Derived& r)
{ return l.derived() * r.toRotationMatrix(); }
/** \returns the concatenation of the rotation \c *this with a transformation \a t */
diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h
index 40bc7033a..1240a95bc 100644
--- a/Eigen/src/Geometry/Transform.h
+++ b/Eigen/src/Geometry/Transform.h
@@ -226,14 +226,14 @@ public:
/** Constructs and initializes a transformation from a Dim^2 or a (Dim+1)^2 matrix. */
template<typename OtherDerived>
- inline explicit Transform(const AnyMatrixBase<OtherDerived>& other)
+ inline explicit Transform(const EigenBase<OtherDerived>& other)
{
ei_transform_construct_from_matrix<OtherDerived,Mode,Dim,HDim>::run(this, other.derived());
}
/** Set \c *this from a Dim^2 or (Dim+1)^2 matrix. */
template<typename OtherDerived>
- inline Transform& operator=(const AnyMatrixBase<OtherDerived>& other)
+ inline Transform& operator=(const EigenBase<OtherDerived>& other)
{
ei_transform_construct_from_matrix<OtherDerived,Mode,Dim,HDim>::run(this, other.derived());
return *this;
@@ -310,7 +310,7 @@ public:
// note: this function is defined here because some compilers cannot find the respective declaration
template<typename OtherDerived>
inline const typename ei_transform_right_product_impl<OtherDerived,Mode,_Dim,_Dim+1>::ResultType
- operator * (const AnyMatrixBase<OtherDerived> &other) const
+ operator * (const EigenBase<OtherDerived> &other) const
{ return ei_transform_right_product_impl<OtherDerived,Mode,Dim,HDim>::run(*this,other.derived()); }
/** \returns the product expression of a transformation matrix \a a times a transform \a b
@@ -322,11 +322,11 @@ public:
*/
template<typename OtherDerived> friend
inline const typename ei_transform_left_product_impl<OtherDerived,Mode,_Dim,_Dim+1>::ResultType
- operator * (const AnyMatrixBase<OtherDerived> &a, const Transform &b)
+ operator * (const EigenBase<OtherDerived> &a, const Transform &b)
{ return ei_transform_left_product_impl<OtherDerived,Mode,Dim,HDim>::run(a.derived(),b); }
template<typename OtherDerived>
- inline Transform& operator*=(const AnyMatrixBase<OtherDerived>& other) { return *this = *this * other; }
+ inline Transform& operator*=(const EigenBase<OtherDerived>& other) { return *this = *this * other; }
/** Contatenates two transformations */
inline const Transform operator * (const Transform& other) const
@@ -1021,7 +1021,7 @@ struct ei_transform_construct_from_matrix<Other, AffineCompact,Dim,HDim, HDim,HD
};
/*********************************************************
-*** Specializations of operator* with a AnyMatrixBase ***
+*** Specializations of operator* with a EigenBase ***
*********************************************************/
// ei_general_product_return_type is a generalization of ProductReturnType, for all types (including e.g. DiagonalBase...),
diff --git a/Eigen/src/Geometry/Translation.h b/Eigen/src/Geometry/Translation.h
index 1e3906bde..bde72c738 100644
--- a/Eigen/src/Geometry/Translation.h
+++ b/Eigen/src/Geometry/Translation.h
@@ -93,7 +93,7 @@ public:
/** Concatenates a translation and a linear transformation */
template<typename OtherDerived>
- inline AffineTransformType operator* (const AnyMatrixBase<OtherDerived>& linear) const;
+ inline AffineTransformType operator* (const EigenBase<OtherDerived>& linear) const;
/** Concatenates a translation and a rotation */
template<typename Derived>
@@ -103,7 +103,7 @@ public:
/** \returns the concatenation of a linear transformation \a l with the translation \a t */
// its a nightmare to define a templated friend function outside its declaration
template<typename OtherDerived> friend
- inline AffineTransformType operator*(const AnyMatrixBase<OtherDerived>& linear, const Translation& t)
+ inline AffineTransformType operator*(const EigenBase<OtherDerived>& linear, const Translation& t)
{
AffineTransformType res;
res.matrix().setZero();
@@ -182,7 +182,7 @@ Translation<Scalar,Dim>::operator* (const UniformScaling<Scalar>& other) const
template<typename Scalar, int Dim>
template<typename OtherDerived>
inline typename Translation<Scalar,Dim>::AffineTransformType
-Translation<Scalar,Dim>::operator* (const AnyMatrixBase<OtherDerived>& linear) const
+Translation<Scalar,Dim>::operator* (const EigenBase<OtherDerived>& linear) const
{
AffineTransformType res;
res.matrix().setZero();
diff --git a/Eigen/src/Householder/Householder.h b/Eigen/src/Householder/Householder.h
index d86e287fa..9d1383543 100644
--- a/Eigen/src/Householder/Householder.h
+++ b/Eigen/src/Householder/Householder.h
@@ -99,7 +99,7 @@ void MatrixBase<Derived>::applyHouseholderOnTheLeft(
const Scalar& tau,
Scalar* workspace)
{
- Map<Matrix<Scalar, 1, Base::ColsAtCompileTime, PlainMatrixType::Options, 1, Base::MaxColsAtCompileTime> > tmp(workspace,cols());
+ Map<Matrix<Scalar, 1, Base::ColsAtCompileTime, PlainObject::Options, 1, Base::MaxColsAtCompileTime> > tmp(workspace,cols());
Block<Derived, EssentialPart::SizeAtCompileTime, Derived::ColsAtCompileTime> bottom(derived(), 1, 0, rows()-1, cols());
tmp.noalias() = essential.adjoint() * bottom;
tmp += this->row(0);
@@ -114,7 +114,7 @@ void MatrixBase<Derived>::applyHouseholderOnTheRight(
const Scalar& tau,
Scalar* workspace)
{
- Map<Matrix<Scalar, Base::RowsAtCompileTime, 1, PlainMatrixType::Options, Base::MaxRowsAtCompileTime, 1> > tmp(workspace,rows());
+ Map<Matrix<Scalar, Base::RowsAtCompileTime, 1, PlainObject::Options, Base::MaxRowsAtCompileTime, 1> > tmp(workspace,rows());
Block<Derived, Derived::RowsAtCompileTime, EssentialPart::SizeAtCompileTime> right(derived(), 0, 1, rows(), cols()-1);
tmp.noalias() = right * essential.conjugate();
tmp += this->col(0);
diff --git a/Eigen/src/Householder/HouseholderSequence.h b/Eigen/src/Householder/HouseholderSequence.h
index f8ae4136b..05e883168 100644
--- a/Eigen/src/Householder/HouseholderSequence.h
+++ b/Eigen/src/Householder/HouseholderSequence.h
@@ -97,7 +97,7 @@ template<typename OtherScalarType, typename MatrixType> struct ei_matrix_type_ti
};
template<typename VectorsType, typename CoeffsType, int Side> class HouseholderSequence
- : public AnyMatrixBase<HouseholderSequence<VectorsType,CoeffsType,Side> >
+ : public EigenBase<HouseholderSequence<VectorsType,CoeffsType,Side> >
{
enum {
RowsAtCompileTime = ei_traits<HouseholderSequence>::RowsAtCompileTime,
diff --git a/Eigen/src/LU/FullPivLU.h b/Eigen/src/LU/FullPivLU.h
index 72e878223..dea6ec41c 100644
--- a/Eigen/src/LU/FullPivLU.h
+++ b/Eigen/src/LU/FullPivLU.h
@@ -119,7 +119,7 @@ template<typename _MatrixType> class FullPivLU
* diagonal coefficient of U.
*/
RealScalar maxPivot() const { return m_maxpivot; }
-
+
/** \returns the permutation matrix P
*
* \sa permutationQ()
@@ -251,6 +251,7 @@ template<typename _MatrixType> class FullPivLU
{
m_usePrescribedThreshold = true;
m_prescribedThreshold = threshold;
+ return *this;
}
/** Allows to come back to the default behavior, letting Eigen use its default formula for
@@ -360,6 +361,8 @@ template<typename _MatrixType> class FullPivLU
(*this, MatrixType::Identity(m_lu.rows(), m_lu.cols()));
}
+ MatrixType reconstructedMatrix() const;
+
inline int rows() const { return m_lu.rows(); }
inline int cols() const { return m_lu.cols(); }
@@ -403,6 +406,7 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
m_maxpivot = RealScalar(0);
+ RealScalar cutoff(0);
for(int k = 0; k < size; ++k)
{
@@ -417,8 +421,14 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
row_of_biggest_in_corner += k; // correct the values! since they were computed in the corner,
col_of_biggest_in_corner += k; // need to add k to them.
- // if the pivot (hence the corner) is exactly zero, terminate to avoid generating nan/inf values
- if(biggest_in_corner == RealScalar(0))
+ // when k==0, biggest_in_corner is the biggest coeff absolute value in the original matrix
+ if(k == 0) cutoff = biggest_in_corner * NumTraits<Scalar>::epsilon();
+
+ // if the pivot (hence the corner) is "zero", terminate to avoid generating nan/inf values.
+ // Notice that using an exact comparison (biggest_in_corner==0) here, as Golub-van Loan do in
+ // their pseudo-code, results in numerical instability! The cutoff here has been validated
+ // by running the unit test 'lu' with many repetitions.
+ if(biggest_in_corner < cutoff)
{
// before exiting, make sure to initialize the still uninitialized transpositions
// in a sane state without destroying what we already have.
@@ -479,6 +489,31 @@ typename ei_traits<MatrixType>::Scalar FullPivLU<MatrixType>::determinant() cons
return Scalar(m_det_pq) * Scalar(m_lu.diagonal().prod());
}
+/** \returns the matrix represented by the decomposition,
+ * i.e., it returns the product: P^{-1} L U Q^{-1}.
+ * This function is provided for debug purpose. */
+template<typename MatrixType>
+MatrixType FullPivLU<MatrixType>::reconstructedMatrix() const
+{
+ ei_assert(m_isInitialized && "LU is not initialized.");
+ const int smalldim = std::min(m_lu.rows(), m_lu.cols());
+ // LU
+ MatrixType res(m_lu.rows(),m_lu.cols());
+ // FIXME the .toDenseMatrix() should not be needed...
+ res = m_lu.corner(TopLeft,m_lu.rows(),smalldim)
+ .template triangularView<UnitLower>().toDenseMatrix()
+ * m_lu.corner(TopLeft,smalldim,m_lu.cols())
+ .template triangularView<Upper>().toDenseMatrix();
+
+ // P^{-1}(LU)
+ res = m_p.inverse() * res;
+
+ // (P^{-1}LU)Q^{-1}
+ res = res * m_q.inverse();
+
+ return res;
+}
+
/********* Implementation of kernel() **************************************************/
template<typename _MatrixType>
@@ -630,7 +665,7 @@ struct ei_solve_retval<FullPivLU<_MatrixType>, Rhs>
return;
}
- typename Rhs::PlainMatrixType c(rhs().rows(), rhs().cols());
+ typename Rhs::PlainObject c(rhs().rows(), rhs().cols());
// Step 1
c = dec().permutationP() * rhs();
@@ -670,10 +705,10 @@ struct ei_solve_retval<FullPivLU<_MatrixType>, Rhs>
* \sa class FullPivLU
*/
template<typename Derived>
-inline const FullPivLU<typename MatrixBase<Derived>::PlainMatrixType>
+inline const FullPivLU<typename MatrixBase<Derived>::PlainObject>
MatrixBase<Derived>::fullPivLu() const
{
- return FullPivLU<PlainMatrixType>(eval());
+ return FullPivLU<PlainObject>(eval());
}
#endif // EIGEN_LU_H
diff --git a/Eigen/src/LU/Inverse.h b/Eigen/src/LU/Inverse.h
index 36392c8d8..e20da70d6 100644
--- a/Eigen/src/LU/Inverse.h
+++ b/Eigen/src/LU/Inverse.h
@@ -238,7 +238,7 @@ struct ei_compute_inverse_and_det_with_check<MatrixType, ResultType, 4>
template<typename MatrixType>
struct ei_traits<ei_inverse_impl<MatrixType> >
{
- typedef typename MatrixType::PlainMatrixType ReturnMatrixType;
+ typedef typename MatrixType::PlainObject ReturnType;
};
template<typename MatrixType>
@@ -327,7 +327,7 @@ inline void MatrixBase<Derived>::computeInverseAndDetWithCheck(
typedef typename ei_meta_if<
RowsAtCompileTime == 2,
typename ei_cleantype<typename ei_nested<Derived, 2>::type>::type,
- PlainMatrixType
+ PlainObject
>::ret MatrixType;
ei_compute_inverse_and_det_with_check<MatrixType, ResultType>::run
(derived(), absDeterminantThreshold, inverse, determinant, invertible);
diff --git a/Eigen/src/LU/PartialPivLU.h b/Eigen/src/LU/PartialPivLU.h
index 3925ac1b0..a60596668 100644
--- a/Eigen/src/LU/PartialPivLU.h
+++ b/Eigen/src/LU/PartialPivLU.h
@@ -165,6 +165,8 @@ template<typename _MatrixType> class PartialPivLU
*/
typename ei_traits<MatrixType>::Scalar determinant() const;
+ MatrixType reconstructedMatrix() const;
+
inline int rows() const { return m_lu.rows(); }
inline int cols() const { return m_lu.cols(); }
@@ -400,6 +402,23 @@ typename ei_traits<MatrixType>::Scalar PartialPivLU<MatrixType>::determinant() c
return Scalar(m_det_p) * m_lu.diagonal().prod();
}
+/** \returns the matrix represented by the decomposition,
+ * i.e., it returns the product: P^{-1} L U.
+ * This function is provided for debug purpose. */
+template<typename MatrixType>
+MatrixType PartialPivLU<MatrixType>::reconstructedMatrix() const
+{
+ ei_assert(m_isInitialized && "LU is not initialized.");
+ // LU
+ MatrixType res = m_lu.template triangularView<UnitLower>().toDenseMatrix()
+ * m_lu.template triangularView<Upper>();
+
+ // P^{-1}(LU)
+ res = m_p.inverse() * res;
+
+ return res;
+}
+
/***** Implementation of solve() *****************************************************/
template<typename _MatrixType, typename Rhs>
@@ -442,10 +461,10 @@ struct ei_solve_retval<PartialPivLU<_MatrixType>, Rhs>
* \sa class PartialPivLU
*/
template<typename Derived>
-inline const PartialPivLU<typename MatrixBase<Derived>::PlainMatrixType>
+inline const PartialPivLU<typename MatrixBase<Derived>::PlainObject>
MatrixBase<Derived>::partialPivLu() const
{
- return PartialPivLU<PlainMatrixType>(eval());
+ return PartialPivLU<PlainObject>(eval());
}
/** \lu_module
@@ -457,10 +476,10 @@ MatrixBase<Derived>::partialPivLu() const
* \sa class PartialPivLU
*/
template<typename Derived>
-inline const PartialPivLU<typename MatrixBase<Derived>::PlainMatrixType>
+inline const PartialPivLU<typename MatrixBase<Derived>::PlainObject>
MatrixBase<Derived>::lu() const
{
- return PartialPivLU<PlainMatrixType>(eval());
+ return PartialPivLU<PlainObject>(eval());
}
#endif // EIGEN_PARTIALLU_H
diff --git a/Eigen/src/QR/ColPivHouseholderQR.h b/Eigen/src/QR/ColPivHouseholderQR.h
index bf28605dd..1219f1918 100644
--- a/Eigen/src/QR/ColPivHouseholderQR.h
+++ b/Eigen/src/QR/ColPivHouseholderQR.h
@@ -441,7 +441,7 @@ struct ei_solve_retval<ColPivHouseholderQR<_MatrixType>, Rhs>
return;
}
- typename Rhs::PlainMatrixType c(rhs());
+ typename Rhs::PlainObject c(rhs());
// Note that the matrix Q = H_0^* H_1^*... so its inverse is Q^* = (H_0 H_1 ...)^T
c.applyOnTheLeft(householderSequence(
@@ -458,7 +458,7 @@ struct ei_solve_retval<ColPivHouseholderQR<_MatrixType>, Rhs>
.solveInPlace(c.corner(TopLeft, nonzero_pivots, c.cols()));
- typename Rhs::PlainMatrixType d(c);
+ typename Rhs::PlainObject d(c);
d.corner(TopLeft, nonzero_pivots, c.cols())
= dec().matrixQR()
.corner(TopLeft, nonzero_pivots, nonzero_pivots)
@@ -486,10 +486,10 @@ typename ColPivHouseholderQR<MatrixType>::HouseholderSequenceType ColPivHousehol
* \sa class ColPivHouseholderQR
*/
template<typename Derived>
-const ColPivHouseholderQR<typename MatrixBase<Derived>::PlainMatrixType>
+const ColPivHouseholderQR<typename MatrixBase<Derived>::PlainObject>
MatrixBase<Derived>::colPivHouseholderQr() const
{
- return ColPivHouseholderQR<PlainMatrixType>(eval());
+ return ColPivHouseholderQR<PlainObject>(eval());
}
diff --git a/Eigen/src/QR/FullPivHouseholderQR.h b/Eigen/src/QR/FullPivHouseholderQR.h
index 1ec60aeaf..07be47f47 100644
--- a/Eigen/src/QR/FullPivHouseholderQR.h
+++ b/Eigen/src/QR/FullPivHouseholderQR.h
@@ -352,7 +352,7 @@ struct ei_solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs>
return;
}
- typename Rhs::PlainMatrixType c(rhs());
+ typename Rhs::PlainObject c(rhs());
Matrix<Scalar,1,Rhs::ColsAtCompileTime> temp(rhs().cols());
for (int k = 0; k < dec().rank(); ++k)
@@ -413,10 +413,10 @@ typename FullPivHouseholderQR<MatrixType>::MatrixQType FullPivHouseholderQR<Matr
* \sa class FullPivHouseholderQR
*/
template<typename Derived>
-const FullPivHouseholderQR<typename MatrixBase<Derived>::PlainMatrixType>
+const FullPivHouseholderQR<typename MatrixBase<Derived>::PlainObject>
MatrixBase<Derived>::fullPivHouseholderQr() const
{
- return FullPivHouseholderQR<PlainMatrixType>(eval());
+ return FullPivHouseholderQR<PlainObject>(eval());
}
#endif // EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H
diff --git a/Eigen/src/QR/HouseholderQR.h b/Eigen/src/QR/HouseholderQR.h
index b6b07ea63..4709e4b77 100644
--- a/Eigen/src/QR/HouseholderQR.h
+++ b/Eigen/src/QR/HouseholderQR.h
@@ -221,7 +221,7 @@ struct ei_solve_retval<HouseholderQR<_MatrixType>, Rhs>
const int rank = std::min(rows, cols);
ei_assert(rhs().rows() == rows);
- typename Rhs::PlainMatrixType c(rhs());
+ typename Rhs::PlainObject c(rhs());
// Note that the matrix Q = H_0^* H_1^*... so its inverse is Q^* = (H_0 H_1 ...)^T
c.applyOnTheLeft(householderSequence(
@@ -246,10 +246,10 @@ struct ei_solve_retval<HouseholderQR<_MatrixType>, Rhs>
* \sa class HouseholderQR
*/
template<typename Derived>
-const HouseholderQR<typename MatrixBase<Derived>::PlainMatrixType>
+const HouseholderQR<typename MatrixBase<Derived>::PlainObject>
MatrixBase<Derived>::householderQr() const
{
- return HouseholderQR<PlainMatrixType>(eval());
+ return HouseholderQR<PlainObject>(eval());
}
diff --git a/Eigen/src/SVD/SVD.h b/Eigen/src/SVD/SVD.h
index c308ff3ee..fa3b82ce2 100644
--- a/Eigen/src/SVD/SVD.h
+++ b/Eigen/src/SVD/SVD.h
@@ -555,10 +555,10 @@ void SVD<MatrixType>::computeScalingRotation(ScalingType *scaling, RotationType
* \returns the SVD decomposition of \c *this
*/
template<typename Derived>
-inline SVD<typename MatrixBase<Derived>::PlainMatrixType>
+inline SVD<typename MatrixBase<Derived>::PlainObject>
MatrixBase<Derived>::svd() const
{
- return SVD<PlainMatrixType>(derived());
+ return SVD<PlainObject>(derived());
}
#endif // EIGEN_SVD_H
diff --git a/Eigen/src/SVD/UpperBidiagonalization.h b/Eigen/src/SVD/UpperBidiagonalization.h
index a2cb44733..0a63b4265 100644
--- a/Eigen/src/SVD/UpperBidiagonalization.h
+++ b/Eigen/src/SVD/UpperBidiagonalization.h
@@ -141,10 +141,10 @@ UpperBidiagonalization<_MatrixType>& UpperBidiagonalization<_MatrixType>::comput
* \sa class Bidiagonalization
*/
template<typename Derived>
-const UpperBidiagonalization<typename MatrixBase<Derived>::PlainMatrixType>
+const UpperBidiagonalization<typename MatrixBase<Derived>::PlainObject>
MatrixBase<Derived>::bidiagonalization() const
{
- return UpperBidiagonalization<PlainMatrixType>(eval());
+ return UpperBidiagonalization<PlainObject>(eval());
}
#endif
diff --git a/Eigen/src/Sparse/SparseMatrixBase.h b/Eigen/src/Sparse/SparseMatrixBase.h
index 205325939..cf1a5d7bf 100644
--- a/Eigen/src/Sparse/SparseMatrixBase.h
+++ b/Eigen/src/Sparse/SparseMatrixBase.h
@@ -36,7 +36,7 @@
*
*
*/
-template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived>
+template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
{
public:
@@ -109,7 +109,7 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived
Transpose<Derived>
>::ret AdjointReturnType;
- typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor> PlainMatrixType;
+ typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor> PlainObject;
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase
#include "../plugins/CommonCwiseUnaryOps.h"
@@ -396,7 +396,7 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived
template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
RealScalar squaredNorm() const;
RealScalar norm() const;
-// const PlainMatrixType normalized() const;
+// const PlainObject normalized() const;
// void normalize();
Transpose<Derived> transpose() { return derived(); }
diff --git a/Eigen/src/Sparse/SparseSelfAdjointView.h b/Eigen/src/Sparse/SparseSelfAdjointView.h
index 039e5c725..f3d4fbcbd 100644
--- a/Eigen/src/Sparse/SparseSelfAdjointView.h
+++ b/Eigen/src/Sparse/SparseSelfAdjointView.h
@@ -93,8 +93,8 @@ template<typename MatrixType, unsigned int UpLo> class SparseSelfAdjointView
template<typename DerivedU>
SparseSelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, Scalar alpha = Scalar(1));
- // const SparseLLT<PlainMatrixType, UpLo> llt() const;
- // const SparseLDLT<PlainMatrixType, UpLo> ldlt() const;
+ // const SparseLLT<PlainObject, UpLo> llt() const;
+ // const SparseLDLT<PlainObject, UpLo> ldlt() const;
protected:
diff --git a/Eigen/src/misc/Image.h b/Eigen/src/misc/Image.h
index 2f39d6b9d..1d63d8143 100644
--- a/Eigen/src/misc/Image.h
+++ b/Eigen/src/misc/Image.h
@@ -40,7 +40,7 @@ struct ei_traits<ei_image_retval_base<DecompositionType> >
MatrixType::Options,
MatrixType::MaxRowsAtCompileTime, // the image matrix will consist of columns from the original matrix,
MatrixType::MaxColsAtCompileTime // so it has the same number of rows and at most as many columns.
- > ReturnMatrixType;
+ > ReturnType;
};
template<typename _DecompositionType> struct ei_image_retval_base
diff --git a/Eigen/src/misc/Kernel.h b/Eigen/src/misc/Kernel.h
index 908c408e9..497b42eab 100644
--- a/Eigen/src/misc/Kernel.h
+++ b/Eigen/src/misc/Kernel.h
@@ -42,7 +42,7 @@ struct ei_traits<ei_kernel_retval_base<DecompositionType> >
MatrixType::MaxColsAtCompileTime, // see explanation for 2nd template parameter
MatrixType::MaxColsAtCompileTime // the kernel is a subspace of the domain space,
// whose dimension is the number of columns of the original matrix
- > ReturnMatrixType;
+ > ReturnType;
};
template<typename _DecompositionType> struct ei_kernel_retval_base
diff --git a/Eigen/src/misc/Solve.h b/Eigen/src/misc/Solve.h
index 4ab0775fc..028716aa2 100644
--- a/Eigen/src/misc/Solve.h
+++ b/Eigen/src/misc/Solve.h
@@ -35,9 +35,9 @@ struct ei_traits<ei_solve_retval_base<DecompositionType, Rhs> >
typedef Matrix<typename Rhs::Scalar,
MatrixType::ColsAtCompileTime,
Rhs::ColsAtCompileTime,
- Rhs::PlainMatrixType::Options,
+ Rhs::PlainObject::Options,
MatrixType::MaxColsAtCompileTime,
- Rhs::MaxColsAtCompileTime> ReturnMatrixType;
+ Rhs::MaxColsAtCompileTime> ReturnType;
};
template<typename _DecompositionType, typename Rhs> struct ei_solve_retval_base
diff --git a/bench/BenchTimer.h b/bench/BenchTimer.h
index b2d0fc5f6..e49afa07f 100644
--- a/bench/BenchTimer.h
+++ b/bench/BenchTimer.h
@@ -23,24 +23,31 @@
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
-#ifndef EIGEN_BENCH_TIMER_H
-#define EIGEN_BENCH_TIMER_H
+#ifndef EIGEN_BENCH_TIMERR_H
+#define EIGEN_BENCH_TIMERR_H
#if defined(_WIN32) || defined(__CYGWIN__)
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
+#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#endif
+#include <cmath>
#include <cstdlib>
#include <numeric>
namespace Eigen
{
+enum {
+ CPU_TIMER = 0,
+ REAL_TIMER = 1
+};
+
/** Elapsed time timer keeping the best try.
*
* On POSIX platforms we use clock_gettime with CLOCK_PROCESS_CPUTIME_ID.
@@ -52,37 +59,58 @@ class BenchTimer
{
public:
- BenchTimer()
- {
+ BenchTimer()
+ {
#if defined(_WIN32) || defined(__CYGWIN__)
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
m_frequency = (double)freq.QuadPart;
#endif
- reset();
+ reset();
}
~BenchTimer() {}
- inline void reset(void) {m_best = 1e6;}
- inline void start(void) {m_start = getTime();}
- inline void stop(void)
+ inline void reset()
+ {
+ m_bests.fill(1e9);
+ m_totals.setZero();
+ }
+ inline void start()
+ {
+ m_starts[CPU_TIMER] = getCpuTime();
+ m_starts[REAL_TIMER] = getRealTime();
+ }
+ inline void stop()
{
- m_best = std::min(m_best, getTime() - m_start);
+ m_times[CPU_TIMER] = getCpuTime() - m_starts[CPU_TIMER];
+ m_times[REAL_TIMER] = getRealTime() - m_starts[REAL_TIMER];
+ m_bests = m_bests.cwiseMin(m_times);
+ m_totals += m_times;
}
- /** Return the best elapsed time in seconds.
+ /** Return the elapsed time in seconds between the last start/stop pair
*/
- inline double value(void)
+ inline double value(int TIMER = CPU_TIMER)
{
- return m_best;
+ return m_times[TIMER];
}
-#if defined(_WIN32) || defined(__CYGWIN__)
- inline double getTime(void)
-#else
- static inline double getTime(void)
-#endif
+ /** Return the best elapsed time in seconds
+ */
+ inline double best(int TIMER = CPU_TIMER)
+ {
+ return m_bests[TIMER];
+ }
+
+ /** Return the total elapsed time in seconds.
+ */
+ inline double total(int TIMER = CPU_TIMER)
+ {
+ return m_totals[TIMER];
+ }
+
+ inline double getCpuTime()
{
#ifdef WIN32
LARGE_INTEGER query_ticks;
@@ -95,14 +123,42 @@ public:
#endif
}
+ inline double getRealTime()
+ {
+#ifdef WIN32
+ SYSTEMTIME st;
+ GetSystemTime(&st);
+ return (double)st.wSecond + 1.e-3 * (double)st.wMilliseconds;
+#else
+ struct timeval tv;
+ struct timezone tz;
+ gettimeofday(&tv, &tz);
+ return (double)tv.tv_sec + 1.e-6 * (double)tv.tv_usec;
+#endif
+ }
+
protected:
#if defined(_WIN32) || defined(__CYGWIN__)
double m_frequency;
#endif
- double m_best, m_start;
+ Vector2d m_starts;
+ Vector2d m_times;
+ Vector2d m_bests;
+ Vector2d m_totals;
};
+#define BENCH(TIMER,TRIES,REP,CODE) { \
+ TIMER.reset(); \
+ for(int uglyvarname1=0; uglyvarname1<TRIES; ++uglyvarname1){ \
+ TIMER.start(); \
+ for(int uglyvarname2=0; uglyvarname2<REP; ++uglyvarname2){ \
+ CODE; \
+ } \
+ TIMER.stop(); \
+ } \
+ }
+
}
-#endif // EIGEN_BENCH_TIMER_H
+#endif // EIGEN_BENCH_TIMERR_H
diff --git a/bench/bench_unrolling b/bench/bench_unrolling
index bf01cce7d..826443845 100755
--- a/bench/bench_unrolling
+++ b/bench/bench_unrolling
@@ -2,10 +2,11 @@
# gcc : CXX="g++ -finline-limit=10000 -ftemplate-depth-2000 --param max-inline-recursive-depth=2000"
# icc : CXX="icpc -fast -no-inline-max-size -fno-exceptions"
+CXX=${CXX-g++ -finline-limit=10000 -ftemplate-depth-2000 --param max-inline-recursive-depth=2000} # default value
for ((i=1; i<16; ++i)); do
echo "Matrix size: $i x $i :"
- $CXX -O3 -I.. -DNDEBUG benchmark.cpp -DMATSIZE=$i -DEIGEN_UNROLLING_LIMIT=1024 -DEIGEN_UNROLLING_LIMIT=400 -o benchmark && time ./benchmark >/dev/null
+ $CXX -O3 -I.. -DNDEBUG benchmark.cpp -DMATSIZE=$i -DEIGEN_UNROLLING_LIMIT=400 -o benchmark && time ./benchmark >/dev/null
$CXX -O3 -I.. -DNDEBUG -finline-limit=10000 benchmark.cpp -DMATSIZE=$i -DEIGEN_DONT_USE_UNROLLED_LOOPS=1 -o benchmark && time ./benchmark >/dev/null
echo " "
done
diff --git a/bench/benchmark_suite b/bench/benchmark_suite
index a8fc6dced..3f21d3661 100755
--- a/bench/benchmark_suite
+++ b/bench/benchmark_suite
@@ -1,4 +1,5 @@
#!/bin/bash
+CXX=${CXX-g++} # default value unless caller has defined CXX
echo "Fixed size 3x3, column-major, -DNDEBUG"
$CXX -O3 -I .. -DNDEBUG benchmark.cpp -o benchmark && time ./benchmark >/dev/null
echo "Fixed size 3x3, column-major, with asserts"
diff --git a/bench/btl/libs/eigen2/eigen2_interface.hh b/bench/btl/libs/eigen2/eigen2_interface.hh
index 1166a37a1..a8b5b884f 100644
--- a/bench/btl/libs/eigen2/eigen2_interface.hh
+++ b/bench/btl/libs/eigen2/eigen2_interface.hh
@@ -17,11 +17,8 @@
//
#ifndef EIGEN2_INTERFACE_HH
#define EIGEN2_INTERFACE_HH
-// #include <cblas.h>
-#include <Eigen/Array>
-#include <Eigen/Cholesky>
-#include <Eigen/LU>
-#include <Eigen/QR>
+
+#include <Eigen/Eigen>
#include <vector>
#include "btl.hh"
@@ -88,27 +85,27 @@ public :
}
static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){
- X = (A*B).lazy();
+ X.noalias() = A*B;
}
static inline void transposed_matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){
- X = (A.transpose()*B.transpose()).lazy();
+ X.noalias() = A.transpose()*B.transpose();
}
static inline void ata_product(const gene_matrix & A, gene_matrix & X, int N){
- X = (A.transpose()*A).lazy();
+ X.noalias() = A.transpose()*A;
}
static inline void aat_product(const gene_matrix & A, gene_matrix & X, int N){
- X = (A*A.transpose()).lazy();
+ X.noalias() = A*A.transpose();
}
static inline void matrix_vector_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N){
- X = (A*B).lazy();
+ X.noalias() = A*B;
}
static inline void symv(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N){
- X = (A.template selfadjointView<LowerTriangular>() * B)/*.lazy()*/;
+ X.noalias() = (A.template selfadjointView<Lower>() * B);
// ei_product_selfadjoint_vector<real,0,LowerTriangularBit,false,false>(N,A.data(),N, B.data(), 1, X.data(), 1);
}
@@ -173,7 +170,7 @@ public :
}
static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
- X = (A.transpose()*B).lazy();
+ X.noalias() = (A.transpose()*B);
}
static inline void axpy(real coef, const gene_vector & X, gene_vector & Y, int N){
@@ -193,16 +190,16 @@ public :
}
static inline void trisolve_lower(const gene_matrix & L, const gene_vector& B, gene_vector& X, int N){
- X = L.template triangularView<LowerTriangular>().solve(B);
+ X = L.template triangularView<Lower>().solve(B);
}
static inline void trisolve_lower_matrix(const gene_matrix & L, const gene_matrix& B, gene_matrix& X, int N){
- X = L.template triangularView<LowerTriangular>().solve(B);
+ X = L.template triangularView<Lower>().solve(B);
}
static inline void cholesky(const gene_matrix & X, gene_matrix & C, int N){
C = X;
- ei_llt_inplace<LowerTriangular>::blocked(C);
+ ei_llt_inplace<Lower>::blocked(C);
//C = X.llt().matrixL();
// C = X;
// Cholesky<gene_matrix>::computeInPlace(C);
diff --git a/cmake/EigenTesting.cmake b/cmake/EigenTesting.cmake
index c445f842b..7d90882a2 100644
--- a/cmake/EigenTesting.cmake
+++ b/cmake/EigenTesting.cmake
@@ -232,14 +232,6 @@ if(CMAKE_COMPILER_IS_GNUCXX)
if(EIGEN_TEST_C++0x)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
endif(EIGEN_TEST_C++0x)
- if(EIGEN_TEST_MAX_WARNING_LEVEL)
- CHECK_CXX_COMPILER_FLAG("-Wno-variadic-macros" FLAG_VARIADIC)
- if(FLAG_VARIADIC)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wno-variadic-macros")
- else(FLAG_VARIADIC)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion")
- endif(FLAG_VARIADIC)
- endif(EIGEN_TEST_MAX_WARNING_LEVEL)
if(CMAKE_SYSTEM_NAME MATCHES Linux)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_FLAGS} -g2")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COVERAGE_FLAGS} -O2 -g2")
@@ -248,9 +240,4 @@ if(CMAKE_COMPILER_IS_GNUCXX)
endif(CMAKE_SYSTEM_NAME MATCHES Linux)
elseif(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS")
- if(EIGEN_TEST_MAX_WARNING_LEVEL)
- # C4127 - conditional expression is constant
- # C4505 - unreferenced local function has been removed
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /wd4127 /wd4505")
- endif(EIGEN_TEST_MAX_WARNING_LEVEL)
endif(CMAKE_COMPILER_IS_GNUCXX)
diff --git a/disabled/SkylineMatrix.h b/disabled/SkylineMatrix.h
index 03d17dac2..640f676bd 100644
--- a/disabled/SkylineMatrix.h
+++ b/disabled/SkylineMatrix.h
@@ -62,7 +62,7 @@ class BandMatrix : public MultiplierBase<BandMatrix<_Scalar,Supers,Subs,Options>
MaxColsAtCompileTime = ei_traits<BandMatrix>::MaxColsAtCompileTime
};
typedef typename ei_traits<BandMatrix>::Scalar Scalar;
- typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> PlainMatrixType;
+ typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> PlainObject;
protected:
enum {
@@ -125,9 +125,9 @@ class BandMatrix : public MultiplierBase<BandMatrix<_Scalar,Supers,Subs,Options>
// inline VectorBlock<DataType,Size> subDiagonal()
// { return VectorBlock<DataType,Size>(m_data,0,m_size.value()); }
- PlainMatrixType toDense() const
+ PlainObject toDense() const
{
- PlainMatrixType res(rows(),cols());
+ PlainObject res(rows(),cols());
res.setZero();
res.diagonal() = diagonal();
for (int i=1; i<=supers();++i)
diff --git a/test/cholesky.cpp b/test/cholesky.cpp
index 1bb808d20..a446f5d73 100644
--- a/test/cholesky.cpp
+++ b/test/cholesky.cpp
@@ -95,7 +95,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
{
LLT<SquareMatrixType,Lower> chollo(symmLo);
- VERIFY_IS_APPROX(symm, chollo.matrixL().toDenseMatrix() * chollo.matrixL().adjoint().toDenseMatrix());
+ VERIFY_IS_APPROX(symm, chollo.reconstructedMatrix());
vecX = chollo.solve(vecB);
VERIFY_IS_APPROX(symm * vecX, vecB);
matX = chollo.solve(matB);
@@ -103,7 +103,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
// test the upper mode
LLT<SquareMatrixType,Upper> cholup(symmUp);
- VERIFY_IS_APPROX(symm, cholup.matrixL().toDenseMatrix() * cholup.matrixL().adjoint().toDenseMatrix());
+ VERIFY_IS_APPROX(symm, cholup.reconstructedMatrix());
vecX = cholup.solve(vecB);
VERIFY_IS_APPROX(symm * vecX, vecB);
matX = cholup.solve(matB);
@@ -119,8 +119,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
{
LDLT<SquareMatrixType> ldlt(symm);
- // TODO(keir): This doesn't make sense now that LDLT pivots.
- //VERIFY_IS_APPROX(symm, ldlt.matrixL() * ldlt.vectorD().asDiagonal() * ldlt.matrixL().adjoint());
+ VERIFY_IS_APPROX(symm, ldlt.reconstructedMatrix());
vecX = ldlt.solve(vecB);
VERIFY_IS_APPROX(symm * vecX, vecB);
matX = ldlt.solve(matB);
diff --git a/test/inverse.cpp b/test/inverse.cpp
index 713caf4a6..1e567ad14 100644
--- a/test/inverse.cpp
+++ b/test/inverse.cpp
@@ -42,7 +42,7 @@ template<typename MatrixType> void inverse(const MatrixType& m)
m2(rows, cols),
mzero = MatrixType::Zero(rows, cols),
identity = MatrixType::Identity(rows, rows);
- createRandomMatrixOfRank(rows,rows,rows,m1);
+ createRandomPIMatrixOfRank(rows,rows,rows,m1);
m2 = m1.inverse();
VERIFY_IS_APPROX(m1, m2.inverse() );
diff --git a/test/lu.cpp b/test/lu.cpp
index 45308ff82..1ed38cb2b 100644
--- a/test/lu.cpp
+++ b/test/lu.cpp
@@ -29,6 +29,7 @@ using namespace std;
template<typename MatrixType> void lu_non_invertible()
{
typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
/* this test covers the following files:
LU.h
*/
@@ -51,11 +52,16 @@ template<typename MatrixType> void lu_non_invertible()
cols2 = cols = MatrixType::ColsAtCompileTime;
}
- typedef typename ei_kernel_retval_base<FullPivLU<MatrixType> >::ReturnMatrixType KernelMatrixType;
- typedef typename ei_image_retval_base<FullPivLU<MatrixType> >::ReturnMatrixType ImageMatrixType;
- typedef Matrix<typename MatrixType::Scalar, Dynamic, Dynamic> DynamicMatrixType;
- typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime>
+ enum {
+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = MatrixType::ColsAtCompileTime
+ };
+ typedef typename ei_kernel_retval_base<FullPivLU<MatrixType> >::ReturnType KernelMatrixType;
+ typedef typename ei_image_retval_base<FullPivLU<MatrixType> >::ReturnType ImageMatrixType;
+ typedef Matrix<typename MatrixType::Scalar, ColsAtCompileTime, ColsAtCompileTime>
CMatrixType;
+ typedef Matrix<typename MatrixType::Scalar, RowsAtCompileTime, RowsAtCompileTime>
+ RMatrixType;
int rank = ei_random<int>(1, std::min(rows, cols)-1);
@@ -64,26 +70,28 @@ template<typename MatrixType> void lu_non_invertible()
MatrixType m1(rows, cols), m3(rows, cols2);
CMatrixType m2(cols, cols2);
- createRandomMatrixOfRank(rank, rows, cols, m1);
-
- FullPivLU<MatrixType> lu(m1);
- // FIXME need better way to construct trapezoid matrices. extend triangularView to support rectangular.
- DynamicMatrixType u(rows,cols);
- for(int i = 0; i < rows; i++)
- for(int j = 0; j < cols; j++)
- u(i,j) = i>j ? Scalar(0) : lu.matrixLU()(i,j);
- DynamicMatrixType l(rows,rows);
- for(int i = 0; i < rows; i++)
- for(int j = 0; j < rows; j++)
- l(i,j) = (i<j || j>=cols) ? Scalar(0)
- : i==j ? Scalar(1)
- : lu.matrixLU()(i,j);
+ createRandomPIMatrixOfRank(rank, rows, cols, m1);
+
+ FullPivLU<MatrixType> lu;
+
+ // The special value 0.01 below works well in tests. Keep in mind that we're only computing the rank
+ // of singular values are either 0 or 1.
+ // So it's not clear at all that the epsilon should play any role there.
+ lu.setThreshold(RealScalar(0.01));
+ lu.compute(m1);
+
+ MatrixType u(rows,cols);
+ u = lu.matrixLU().template triangularView<Upper>();
+ RMatrixType l = RMatrixType::Identity(rows,rows);
+ l.block(0,0,rows,std::min(rows,cols)).template triangularView<StrictlyLower>()
+ = lu.matrixLU().block(0,0,rows,std::min(rows,cols));
VERIFY_IS_APPROX(lu.permutationP() * m1 * lu.permutationQ(), l*u);
KernelMatrixType m1kernel = lu.kernel();
ImageMatrixType m1image = lu.image(m1);
+ VERIFY_IS_APPROX(m1, lu.reconstructedMatrix());
VERIFY(rank == lu.rank());
VERIFY(cols - lu.rank() == lu.dimensionOfKernel());
VERIFY(!lu.isInjective());
@@ -91,9 +99,8 @@ template<typename MatrixType> void lu_non_invertible()
VERIFY(!lu.isSurjective());
VERIFY((m1 * m1kernel).isMuchSmallerThan(m1));
VERIFY(m1image.fullPivLu().rank() == rank);
- DynamicMatrixType sidebyside(m1.rows(), m1.cols() + m1image.cols());
- sidebyside << m1, m1image;
- VERIFY(sidebyside.fullPivLu().rank() == rank);
+ VERIFY_IS_APPROX(m1 * m1.adjoint() * m1image, m1image);
+
m2 = CMatrixType::Random(cols,cols2);
m3 = m1*m2;
m2 = CMatrixType::Random(cols,cols2);
@@ -107,20 +114,19 @@ template<typename MatrixType> void lu_invertible()
/* this test covers the following files:
LU.h
*/
+ typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
int size = ei_random<int>(1,200);
MatrixType m1(size, size), m2(size, size), m3(size, size);
- m1 = MatrixType::Random(size,size);
-
- if (ei_is_same_type<RealScalar,float>::ret)
- {
- // let's build a matrix more stable to inverse
- MatrixType a = MatrixType::Random(size,size*2);
- m1 += a * a.adjoint();
- }
+ FullPivLU<MatrixType> lu;
+ lu.setThreshold(0.01);
+ do {
+ m1 = MatrixType::Random(size,size);
+ lu.compute(m1);
+ } while(!lu.isInvertible());
- FullPivLU<MatrixType> lu(m1);
+ VERIFY_IS_APPROX(m1, lu.reconstructedMatrix());
VERIFY(0 == lu.dimensionOfKernel());
VERIFY(lu.kernel().cols() == 1); // the kernel() should consist of a single (zero) column vector
VERIFY(size == lu.rank());
@@ -134,6 +140,23 @@ template<typename MatrixType> void lu_invertible()
VERIFY_IS_APPROX(m2, lu.inverse()*m3);
}
+template<typename MatrixType> void lu_partial_piv()
+{
+ /* this test covers the following files:
+ PartialPivLU.h
+ */
+ typedef typename MatrixType::Scalar Scalar;
+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
+ int rows = ei_random<int>(1,4);
+ int cols = rows;
+
+ MatrixType m1(cols, rows);
+ m1.setRandom();
+ PartialPivLU<MatrixType> plu(m1);
+
+ VERIFY_IS_APPROX(m1, plu.reconstructedMatrix());
+}
+
template<typename MatrixType> void lu_verify_assert()
{
MatrixType tmp;
@@ -176,6 +199,7 @@ void test_lu()
CALL_SUBTEST_4( lu_non_invertible<MatrixXd>() );
CALL_SUBTEST_4( lu_invertible<MatrixXd>() );
+ CALL_SUBTEST_4( lu_partial_piv<MatrixXd>() );
CALL_SUBTEST_4( lu_verify_assert<MatrixXd>() );
CALL_SUBTEST_5( lu_non_invertible<MatrixXcf>() );
@@ -184,6 +208,7 @@ void test_lu()
CALL_SUBTEST_6( lu_non_invertible<MatrixXcd>() );
CALL_SUBTEST_6( lu_invertible<MatrixXcd>() );
+ CALL_SUBTEST_6( lu_partial_piv<MatrixXcd>() );
CALL_SUBTEST_6( lu_verify_assert<MatrixXcd>() );
CALL_SUBTEST_7(( lu_non_invertible<Matrix<float,Dynamic,16> >() ));
diff --git a/test/main.h b/test/main.h
index 64f70b394..96324de33 100644
--- a/test/main.h
+++ b/test/main.h
@@ -148,7 +148,7 @@ namespace Eigen
#define EIGEN_INTERNAL_DEBUGGING
#define EIGEN_NICE_RANDOM
-#include <Eigen/QR> // required for createRandomMatrixOfRank
+#include <Eigen/QR> // required for createRandomPIMatrixOfRank
#define VERIFY(a) do { if (!(a)) { \
@@ -342,8 +342,13 @@ inline bool test_isUnitary(const MatrixBase<Derived>& m)
return m.isUnitary(test_precision<typename ei_traits<Derived>::Scalar>());
}
+/** Creates a random Partial Isometry matrix of given rank.
+ *
+ * A partial isometry is a matrix all of whose singular values are either 0 or 1.
+ * This is very useful to test rank-revealing algorithms.
+ */
template<typename MatrixType>
-void createRandomMatrixOfRank(int desired_rank, int rows, int cols, MatrixType& m)
+void createRandomPIMatrixOfRank(int desired_rank, int rows, int cols, MatrixType& m)
{
typedef typename ei_traits<MatrixType>::Scalar Scalar;
enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };
@@ -360,7 +365,8 @@ void createRandomMatrixOfRank(int desired_rank, int rows, int cols, MatrixType&
if(desired_rank == 1)
{
- m = VectorType::Random(rows) * VectorType::Random(cols).transpose();
+ // here we normalize the vectors to get a partial isometry
+ m = VectorType::Random(rows).normalized() * VectorType::Random(cols).normalized().transpose();
return;
}
diff --git a/test/permutationmatrices.cpp b/test/permutationmatrices.cpp
index 0ef0a371a..89142d910 100644
--- a/test/permutationmatrices.cpp
+++ b/test/permutationmatrices.cpp
@@ -51,7 +51,7 @@ template<typename MatrixType> void permutationmatrices(const MatrixType& m)
typedef Matrix<int, Rows, 1> LeftPermutationVectorType;
typedef PermutationMatrix<Cols> RightPermutationType;
typedef Matrix<int, Cols, 1> RightPermutationVectorType;
-
+
int rows = m.rows();
int cols = m.cols();
@@ -72,7 +72,7 @@ template<typename MatrixType> void permutationmatrices(const MatrixType& m)
Matrix<Scalar,Cols,Cols> rm(rp);
VERIFY_IS_APPROX(m_permuted, lm*m_original*rm);
-
+
VERIFY_IS_APPROX(lp.inverse()*m_permuted*rp.inverse(), m_original);
VERIFY((lp*lp.inverse()).toDenseMatrix().isIdentity());
@@ -86,6 +86,23 @@ template<typename MatrixType> void permutationmatrices(const MatrixType& m)
identityp.setIdentity(rows);
VERIFY_IS_APPROX(m_original, identityp*m_original);
+ // check inplace permutations
+ m_permuted = m_original;
+ m_permuted = lp.inverse() * m_permuted;
+ VERIFY_IS_APPROX(m_permuted, lp.inverse()*m_original);
+
+ m_permuted = m_original;
+ m_permuted = m_permuted * rp.inverse();
+ VERIFY_IS_APPROX(m_permuted, m_original*rp.inverse());
+
+ m_permuted = m_original;
+ m_permuted = lp * m_permuted;
+ VERIFY_IS_APPROX(m_permuted, lp*m_original);
+
+ m_permuted = m_original;
+ m_permuted = m_permuted * rp;
+ VERIFY_IS_APPROX(m_permuted, m_original*rp);
+
if(rows>1 && cols>1)
{
lp2 = lp;
@@ -114,7 +131,7 @@ void test_permutationmatrices()
CALL_SUBTEST_2( permutationmatrices(Matrix3f()) );
CALL_SUBTEST_3( permutationmatrices(Matrix<double,3,3,RowMajor>()) );
CALL_SUBTEST_4( permutationmatrices(Matrix4d()) );
- CALL_SUBTEST_5( permutationmatrices(Matrix<double,4,6>()) );
+ CALL_SUBTEST_5( permutationmatrices(Matrix<double,40,60>()) );
CALL_SUBTEST_6( permutationmatrices(Matrix<double,Dynamic,Dynamic,RowMajor>(20, 30)) );
CALL_SUBTEST_7( permutationmatrices(MatrixXcf(15, 10)) );
}
diff --git a/test/qr_colpivoting.cpp b/test/qr_colpivoting.cpp
index 16eb27c52..96cc66316 100644
--- a/test/qr_colpivoting.cpp
+++ b/test/qr_colpivoting.cpp
@@ -36,7 +36,7 @@ template<typename MatrixType> void qr()
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType;
typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
MatrixType m1;
- createRandomMatrixOfRank(rank,rows,cols,m1);
+ createRandomPIMatrixOfRank(rank,rows,cols,m1);
ColPivHouseholderQR<MatrixType> qr(m1);
VERIFY_IS_APPROX(rank, qr.rank());
VERIFY(cols - qr.rank() == qr.dimensionOfKernel());
@@ -64,7 +64,7 @@ template<typename MatrixType, int Cols2> void qr_fixedsize()
typedef typename MatrixType::Scalar Scalar;
int rank = ei_random<int>(1, std::min(int(Rows), int(Cols))-1);
Matrix<Scalar,Rows,Cols> m1;
- createRandomMatrixOfRank(rank,Rows,Cols,m1);
+ createRandomPIMatrixOfRank(rank,Rows,Cols,m1);
ColPivHouseholderQR<Matrix<Scalar,Rows,Cols> > qr(m1);
VERIFY_IS_APPROX(rank, qr.rank());
VERIFY(Cols - qr.rank() == qr.dimensionOfKernel());
diff --git a/test/qr_fullpivoting.cpp b/test/qr_fullpivoting.cpp
index c82ba4c7e..7ad3af1fe 100644
--- a/test/qr_fullpivoting.cpp
+++ b/test/qr_fullpivoting.cpp
@@ -35,7 +35,7 @@ template<typename MatrixType> void qr()
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType;
typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;
MatrixType m1;
- createRandomMatrixOfRank(rank,rows,cols,m1);
+ createRandomPIMatrixOfRank(rank,rows,cols,m1);
FullPivHouseholderQR<MatrixType> qr(m1);
VERIFY_IS_APPROX(rank, qr.rank());
VERIFY(cols - qr.rank() == qr.dimensionOfKernel());
diff --git a/test/testsuite.cmake b/test/testsuite.cmake
index 90edf2853..b68a327a9 100644
--- a/test/testsuite.cmake
+++ b/test/testsuite.cmake
@@ -147,6 +147,9 @@ endif(NOT EIGEN_NO_UPDATE)
# which ctest command to use for running the dashboard
SET (CTEST_COMMAND "${EIGEN_CMAKE_DIR}ctest -D ${EIGEN_MODE}")
+if($ENV{EIGEN_CTEST_ARGS})
+SET (CTEST_COMMAND "${CTEST_COMMAND} $ENV{EIGEN_CTEST_ARGS}")
+endif($ENV{EIGEN_CTEST_ARGS})
# what cmake command to use for configuring this dashboard
SET (CTEST_CMAKE_COMMAND "${EIGEN_CMAKE_DIR}cmake -DEIGEN_LEAVE_TEST_IN_ALL_TARGET=ON")
diff --git a/unsupported/Eigen/FFT b/unsupported/Eigen/FFT
index c37628ed8..3c4d85d3b 100644
--- a/unsupported/Eigen/FFT
+++ b/unsupported/Eigen/FFT
@@ -173,7 +173,7 @@ class FFT
template<typename InputDerived, typename ComplexDerived>
inline
- void fwd( MatrixBase<ComplexDerived> & dst, const MatrixBase<InputDerived> & src)
+ void fwd( MatrixBase<ComplexDerived> & dst, const MatrixBase<InputDerived> & src,int nfft=-1)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(InputDerived)
EIGEN_STATIC_ASSERT_VECTOR_ONLY(ComplexDerived)
@@ -183,16 +183,25 @@ class FFT
EIGEN_STATIC_ASSERT(int(InputDerived::Flags)&int(ComplexDerived::Flags)&DirectAccessBit,
THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES)
+ if (nfft<1)
+ nfft = src.size();
+
if ( NumTraits< typename InputDerived::Scalar >::IsComplex == 0 && HasFlag(HalfSpectrum) )
- dst.derived().resize( (src.size()>>1)+1);
+ dst.derived().resize( (nfft>>1)+1);
else
- dst.derived().resize(src.size());
+ dst.derived().resize(nfft);
- if (src.stride() != 1) {
- Matrix<typename InputDerived::Scalar,1,Dynamic> tmp = src;
- fwd( &dst[0],&tmp[0],src.size() );
+ if ( src.stride() != 1 || src.size() < nfft ) {
+ Matrix<typename InputDerived::Scalar,1,Dynamic> tmp;
+ if (src.size()<nfft) {
+ tmp.setZero(nfft);
+ tmp.block(0,0,src.size(),1 ) = src;
+ }else{
+ tmp = src;
+ }
+ fwd( &dst[0],&tmp[0],nfft );
}else{
- fwd( &dst[0],&src[0],src.size() );
+ fwd( &dst[0],&src[0],nfft );
}
}
@@ -216,25 +225,60 @@ class FFT
inline
void inv( MatrixBase<OutputDerived> & dst, const MatrixBase<ComplexDerived> & src, int nfft=-1)
{
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(OutputDerived)
- EIGEN_STATIC_ASSERT_VECTOR_ONLY(ComplexDerived)
- EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(ComplexDerived,OutputDerived) // size at compile-time
- EIGEN_STATIC_ASSERT((ei_is_same_type<typename ComplexDerived::Scalar, Complex>::ret),
- YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
- EIGEN_STATIC_ASSERT(int(OutputDerived::Flags)&int(ComplexDerived::Flags)&DirectAccessBit,
- THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES)
-
- if (nfft<1) {
- nfft = ( NumTraits<typename OutputDerived::Scalar>::IsComplex == 0 && HasFlag(HalfSpectrum) ) ? 2*(src.size()-1) : src.size();
- }
- dst.derived().resize( nfft );
- if (src.stride() != 1) {
- // if the vector is strided, then we need to copy it to a packed temporary
- Matrix<typename ComplexDerived::Scalar,1,Dynamic> tmp = src;
- inv( &dst[0],&tmp[0], nfft);
+ typedef typename ComplexDerived::Scalar src_type;
+ typedef typename OutputDerived::Scalar dst_type;
+ const bool realfft= (NumTraits<dst_type>::IsComplex == 0);
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(OutputDerived)
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(ComplexDerived)
+ EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(ComplexDerived,OutputDerived) // size at compile-time
+ EIGEN_STATIC_ASSERT((ei_is_same_type<src_type, Complex>::ret),
+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
+ EIGEN_STATIC_ASSERT(int(OutputDerived::Flags)&int(ComplexDerived::Flags)&DirectAccessBit,
+ THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES)
+
+ if (nfft<1) { //automatic FFT size determination
+ if ( realfft && HasFlag(HalfSpectrum) )
+ nfft = 2*(src.size()-1); //assume even fft size
+ else
+ nfft = src.size();
+ }
+ dst.derived().resize( nfft );
+
+ // check for nfft that does not fit the input data size
+ int resize_input= ( realfft && HasFlag(HalfSpectrum) )
+ ? ( (nfft/2+1) - src.size() )
+ : ( nfft - src.size() );
+
+ if ( src.stride() != 1 || resize_input ) {
+ // if the vector is strided, then we need to copy it to a packed temporary
+ Matrix<src_type,1,Dynamic> tmp;
+ if ( resize_input ) {
+ size_t ncopy = min(src.size(),src.size() + resize_input);
+ tmp.setZero(src.size() + resize_input);
+ if ( realfft && HasFlag(HalfSpectrum) ) {
+ // pad at the Nyquist bin
+ tmp.head(ncopy) = src.head(ncopy);
+ tmp(ncopy-1) = real(tmp(ncopy-1)); // enforce real-only Nyquist bin
+ }else{
+ size_t nhead,ntail;
+ nhead = 1+ncopy/2-1; // range [0:pi)
+ ntail = ncopy/2-1; // range (-pi:0)
+ tmp.head(nhead) = src.head(nhead);
+ tmp.tail(ntail) = src.tail(ntail);
+ if (resize_input<0) { //shrinking -- create the Nyquist bin as the average of the two bins that fold into it
+ tmp(nhead) = ( src(nfft/2) + src( src.size() - nfft/2 ) )*src_type(.5);
+ }else{ // expanding -- split the old Nyquist bin into two halves
+ tmp(nhead) = src(nhead) * src_type(.5);
+ tmp(tmp.size()-nhead) = tmp(nhead);
+ }
+ }
}else{
- inv( &dst[0],&src[0], nfft);
+ tmp = src;
}
+ inv( &dst[0],&tmp[0], nfft);
+ }else{
+ inv( &dst[0],&src[0], nfft);
+ }
}
template <typename _Output>
diff --git a/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h b/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
index ec25106f5..4b7331035 100644
--- a/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
+++ b/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h
@@ -563,6 +563,8 @@ template<typename DerType> struct NumTraits<AutoDiffScalar<DerType> >
AddCost = 1,
MulCost = 1
};
+ inline static Real epsilon() { return std::numeric_limits<Real>::epsilon(); }
+ inline static Real dummy_precision() { return NumTraits<Real>::dummy_precision(); }
};
}
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
index 39c23cdc5..2c761e648 100644
--- a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
+++ b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
@@ -313,7 +313,7 @@ template<typename Derived> struct MatrixExponentialReturnValue
inline void evalTo(ResultType& result) const
{
const typename ei_eval<Derived>::type srcEvaluated = m_src.eval();
- MatrixExponential<typename Derived::PlainMatrixType> me(srcEvaluated);
+ MatrixExponential<typename Derived::PlainObject> me(srcEvaluated);
me.compute(result);
}
@@ -327,7 +327,7 @@ template<typename Derived> struct MatrixExponentialReturnValue
template<typename Derived>
struct ei_traits<MatrixExponentialReturnValue<Derived> >
{
- typedef typename Derived::PlainMatrixType ReturnMatrixType;
+ typedef typename Derived::PlainObject ReturnType;
};
/** \ingroup MatrixFunctions_Module
diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h b/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h
index d63bcbce9..e8069154c 100644
--- a/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h
+++ b/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h
@@ -178,9 +178,9 @@ class MatrixFunction<MatrixType, 1>
*
* This is morally a \c static \c const \c Scalar, but only
* integers can be static constant class members in C++. The
- * separation constant is set to 0.01, a value taken from the
+ * separation constant is set to 0.1, a value taken from the
* paper by Davies and Higham. */
- static const RealScalar separation() { return static_cast<RealScalar>(0.01); }
+ static const RealScalar separation() { return static_cast<RealScalar>(0.1); }
};
/** \brief Constructor.
@@ -492,14 +492,12 @@ typename MatrixFunction<MatrixType,1>::DynMatrixType MatrixFunction<MatrixType,1
template<typename Derived> class MatrixFunctionReturnValue
: public ReturnByValue<MatrixFunctionReturnValue<Derived> >
{
- private:
+ public:
typedef typename ei_traits<Derived>::Scalar Scalar;
typedef typename ei_stem_function<Scalar>::type StemFunction;
- public:
-
- /** \brief Constructor.
+ /** \brief Constructor.
*
* \param[in] A %Matrix (expression) forming the argument of the
* matrix function.
@@ -516,7 +514,7 @@ template<typename Derived> class MatrixFunctionReturnValue
inline void evalTo(ResultType& result) const
{
const typename ei_eval<Derived>::type Aevaluated = m_A.eval();
- MatrixFunction<typename Derived::PlainMatrixType> mf(Aevaluated, m_f);
+ MatrixFunction<typename Derived::PlainObject> mf(Aevaluated, m_f);
mf.compute(result);
}
@@ -531,7 +529,7 @@ template<typename Derived> class MatrixFunctionReturnValue
template<typename Derived>
struct ei_traits<MatrixFunctionReturnValue<Derived> >
{
- typedef typename Derived::PlainMatrixType ReturnMatrixType;
+ typedef typename Derived::PlainObject ReturnType;
};
diff --git a/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h b/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
index 0754a426b..35dc332e0 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h
@@ -57,7 +57,7 @@ class HybridNonLinearSolver
{
public:
HybridNonLinearSolver(FunctorType &_functor)
- : functor(_functor) { nfev=njev=iter = 0; fnorm= 0.; }
+ : functor(_functor) { nfev=njev=iter = 0; fnorm= 0.; useExternalScaling=false;}
struct Parameters {
Parameters()
@@ -84,36 +84,18 @@ public:
const Scalar tol = ei_sqrt(NumTraits<Scalar>::epsilon())
);
- HybridNonLinearSolverSpace::Status solveInit(
- FVectorType &x,
- const int mode=1
- );
- HybridNonLinearSolverSpace::Status solveOneStep(
- FVectorType &x,
- const int mode=1
- );
- HybridNonLinearSolverSpace::Status solve(
- FVectorType &x,
- const int mode=1
- );
+ HybridNonLinearSolverSpace::Status solveInit(FVectorType &x);
+ HybridNonLinearSolverSpace::Status solveOneStep(FVectorType &x);
+ HybridNonLinearSolverSpace::Status solve(FVectorType &x);
HybridNonLinearSolverSpace::Status hybrd1(
FVectorType &x,
const Scalar tol = ei_sqrt(NumTraits<Scalar>::epsilon())
);
- HybridNonLinearSolverSpace::Status solveNumericalDiffInit(
- FVectorType &x,
- const int mode=1
- );
- HybridNonLinearSolverSpace::Status solveNumericalDiffOneStep(
- FVectorType &x,
- const int mode=1
- );
- HybridNonLinearSolverSpace::Status solveNumericalDiff(
- FVectorType &x,
- const int mode=1
- );
+ HybridNonLinearSolverSpace::Status solveNumericalDiffInit(FVectorType &x);
+ HybridNonLinearSolverSpace::Status solveNumericalDiffOneStep(FVectorType &x);
+ HybridNonLinearSolverSpace::Status solveNumericalDiff(FVectorType &x);
void resetParameters(void) { parameters = Parameters(); }
Parameters parameters;
@@ -124,6 +106,7 @@ public:
int njev;
int iter;
Scalar fnorm;
+ bool useExternalScaling;
private:
FunctorType &functor;
int n;
@@ -160,18 +143,13 @@ HybridNonLinearSolver<FunctorType,Scalar>::hybrj1(
parameters.maxfev = 100*(n+1);
parameters.xtol = tol;
diag.setConstant(n, 1.);
- return solve(
- x,
- 2
- );
+ useExternalScaling = true;
+ return solve(x);
}
template<typename FunctorType, typename Scalar>
HybridNonLinearSolverSpace::Status
-HybridNonLinearSolver<FunctorType,Scalar>::solveInit(
- FVectorType &x,
- const int mode
- )
+HybridNonLinearSolver<FunctorType,Scalar>::solveInit(FVectorType &x)
{
n = x.size();
@@ -179,9 +157,9 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveInit(
fvec.resize(n);
qtf.resize(n);
fjac.resize(n, n);
- if (mode != 2)
+ if (!useExternalScaling)
diag.resize(n);
- assert( (mode!=2 || diag.size()==n) || "When using mode==2, the caller must provide a valid 'diag'");
+ assert( (!useExternalScaling || diag.size()==n) || "When useExternalScaling is set, the caller must provide a valid 'diag'");
/* Function Body */
nfev = 0;
@@ -190,7 +168,7 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveInit(
/* check the input parameters for errors. */
if (n <= 0 || parameters.xtol < 0. || parameters.maxfev <= 0 || parameters.factor <= 0. )
return HybridNonLinearSolverSpace::ImproperInputParameters;
- if (mode == 2)
+ if (useExternalScaling)
for (int j = 0; j < n; ++j)
if (diag[j] <= 0.)
return HybridNonLinearSolverSpace::ImproperInputParameters;
@@ -214,10 +192,7 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveInit(
template<typename FunctorType, typename Scalar>
HybridNonLinearSolverSpace::Status
-HybridNonLinearSolver<FunctorType,Scalar>::solveOneStep(
- FVectorType &x,
- const int mode
- )
+HybridNonLinearSolver<FunctorType,Scalar>::solveOneStep(FVectorType &x)
{
int j;
std::vector<PlanarRotation<Scalar> > v_givens(n), w_givens(n);
@@ -231,10 +206,10 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveOneStep(
wa2 = fjac.colwise().blueNorm();
- /* on the first iteration and if mode is 1, scale according */
+ /* on the first iteration and if external scaling is not used, scale according */
/* to the norms of the columns of the initial jacobian. */
if (iter == 1) {
- if (mode != 2)
+ if (!useExternalScaling)
for (j = 0; j < n; ++j)
diag[j] = (wa2[j]==0.) ? 1. : wa2[j];
@@ -260,7 +235,7 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveOneStep(
qtf = fjac.transpose() * fvec;
/* rescale if necessary. */
- if (mode != 2)
+ if (!useExternalScaling)
diag = diag.cwiseMax(wa2);
while (true) {
@@ -372,14 +347,11 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveOneStep(
template<typename FunctorType, typename Scalar>
HybridNonLinearSolverSpace::Status
-HybridNonLinearSolver<FunctorType,Scalar>::solve(
- FVectorType &x,
- const int mode
- )
+HybridNonLinearSolver<FunctorType,Scalar>::solve(FVectorType &x)
{
- HybridNonLinearSolverSpace::Status status = solveInit(x, mode);
+ HybridNonLinearSolverSpace::Status status = solveInit(x);
while (status==HybridNonLinearSolverSpace::Running)
- status = solveOneStep(x, mode);
+ status = solveOneStep(x);
return status;
}
@@ -403,18 +375,13 @@ HybridNonLinearSolver<FunctorType,Scalar>::hybrd1(
parameters.xtol = tol;
diag.setConstant(n, 1.);
- return solveNumericalDiff(
- x,
- 2
- );
+ useExternalScaling = true;
+ return solveNumericalDiff(x);
}
template<typename FunctorType, typename Scalar>
HybridNonLinearSolverSpace::Status
-HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffInit(
- FVectorType &x,
- const int mode
- )
+HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffInit(FVectorType &x)
{
n = x.size();
@@ -425,10 +392,9 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffInit(
qtf.resize(n);
fjac.resize(n, n);
fvec.resize(n);
- if (mode != 2)
+ if (!useExternalScaling)
diag.resize(n);
- assert( (mode!=2 || diag.size()==n) || "When using mode==2, the caller must provide a valid 'diag'");
-
+ assert( (!useExternalScaling || diag.size()==n) || "When useExternalScaling is set, the caller must provide a valid 'diag'");
/* Function Body */
nfev = 0;
@@ -437,7 +403,7 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffInit(
/* check the input parameters for errors. */
if (n <= 0 || parameters.xtol < 0. || parameters.maxfev <= 0 || parameters.nb_of_subdiagonals< 0 || parameters.nb_of_superdiagonals< 0 || parameters.factor <= 0. )
return HybridNonLinearSolverSpace::ImproperInputParameters;
- if (mode == 2)
+ if (useExternalScaling)
for (int j = 0; j < n; ++j)
if (diag[j] <= 0.)
return HybridNonLinearSolverSpace::ImproperInputParameters;
@@ -461,10 +427,7 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffInit(
template<typename FunctorType, typename Scalar>
HybridNonLinearSolverSpace::Status
-HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffOneStep(
- FVectorType &x,
- const int mode
- )
+HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffOneStep(FVectorType &x)
{
int j;
std::vector<PlanarRotation<Scalar> > v_givens(n), w_givens(n);
@@ -480,10 +443,10 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffOneStep(
wa2 = fjac.colwise().blueNorm();
- /* on the first iteration and if mode is 1, scale according */
+ /* on the first iteration and if external scaling is not used, scale according */
/* to the norms of the columns of the initial jacobian. */
if (iter == 1) {
- if (mode != 2)
+ if (!useExternalScaling)
for (j = 0; j < n; ++j)
diag[j] = (wa2[j]==0.) ? 1. : wa2[j];
@@ -509,7 +472,7 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffOneStep(
qtf = fjac.transpose() * fvec;
/* rescale if necessary. */
- if (mode != 2)
+ if (!useExternalScaling)
diag = diag.cwiseMax(wa2);
while (true) {
@@ -621,14 +584,11 @@ HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffOneStep(
template<typename FunctorType, typename Scalar>
HybridNonLinearSolverSpace::Status
-HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiff(
- FVectorType &x,
- const int mode
- )
+HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiff(FVectorType &x)
{
- HybridNonLinearSolverSpace::Status status = solveNumericalDiffInit(x, mode);
+ HybridNonLinearSolverSpace::Status status = solveNumericalDiffInit(x);
while (status==HybridNonLinearSolverSpace::Running)
- status = solveNumericalDiffOneStep(x, mode);
+ status = solveNumericalDiffOneStep(x);
return status;
}
diff --git a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
index f21331e3e..8bae1e131 100644
--- a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
+++ b/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h
@@ -61,7 +61,7 @@ class LevenbergMarquardt
{
public:
LevenbergMarquardt(FunctorType &_functor)
- : functor(_functor) { nfev = njev = iter = 0; fnorm=gnorm = 0.; }
+ : functor(_functor) { nfev = njev = iter = 0; fnorm = gnorm = 0.; useExternalScaling=false; }
struct Parameters {
Parameters()
@@ -87,18 +87,9 @@ public:
const Scalar tol = ei_sqrt(NumTraits<Scalar>::epsilon())
);
- LevenbergMarquardtSpace::Status minimize(
- FVectorType &x,
- const int mode=1
- );
- LevenbergMarquardtSpace::Status minimizeInit(
- FVectorType &x,
- const int mode=1
- );
- LevenbergMarquardtSpace::Status minimizeOneStep(
- FVectorType &x,
- const int mode=1
- );
+ LevenbergMarquardtSpace::Status minimize(FVectorType &x);
+ LevenbergMarquardtSpace::Status minimizeInit(FVectorType &x);
+ LevenbergMarquardtSpace::Status minimizeOneStep(FVectorType &x);
static LevenbergMarquardtSpace::Status lmdif1(
FunctorType &functor,
@@ -112,18 +103,9 @@ public:
const Scalar tol = ei_sqrt(NumTraits<Scalar>::epsilon())
);
- LevenbergMarquardtSpace::Status minimizeOptimumStorage(
- FVectorType &x,
- const int mode=1
- );
- LevenbergMarquardtSpace::Status minimizeOptimumStorageInit(
- FVectorType &x,
- const int mode=1
- );
- LevenbergMarquardtSpace::Status minimizeOptimumStorageOneStep(
- FVectorType &x,
- const int mode=1
- );
+ LevenbergMarquardtSpace::Status minimizeOptimumStorage(FVectorType &x);
+ LevenbergMarquardtSpace::Status minimizeOptimumStorageInit(FVectorType &x);
+ LevenbergMarquardtSpace::Status minimizeOptimumStorageOneStep(FVectorType &x);
void resetParameters(void) { parameters = Parameters(); }
@@ -135,6 +117,7 @@ public:
int njev;
int iter;
Scalar fnorm, gnorm;
+ bool useExternalScaling;
Scalar lm_param(void) { return par; }
private:
@@ -175,24 +158,18 @@ LevenbergMarquardt<FunctorType,Scalar>::lmder1(
template<typename FunctorType, typename Scalar>
LevenbergMarquardtSpace::Status
-LevenbergMarquardt<FunctorType,Scalar>::minimize(
- FVectorType &x,
- const int mode
- )
+LevenbergMarquardt<FunctorType,Scalar>::minimize(FVectorType &x)
{
- LevenbergMarquardtSpace::Status status = minimizeInit(x, mode);
+ LevenbergMarquardtSpace::Status status = minimizeInit(x);
do {
- status = minimizeOneStep(x, mode);
+ status = minimizeOneStep(x);
} while (status==LevenbergMarquardtSpace::Running);
return status;
}
template<typename FunctorType, typename Scalar>
LevenbergMarquardtSpace::Status
-LevenbergMarquardt<FunctorType,Scalar>::minimizeInit(
- FVectorType &x,
- const int mode
- )
+LevenbergMarquardt<FunctorType,Scalar>::minimizeInit(FVectorType &x)
{
n = x.size();
m = functor.values();
@@ -201,9 +178,9 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeInit(
wa4.resize(m);
fvec.resize(m);
fjac.resize(m, n);
- if (mode != 2)
+ if (!useExternalScaling)
diag.resize(n);
- assert( (mode!=2 || diag.size()==n) || "When using mode==2, the caller must provide a valid 'diag'");
+ assert( (!useExternalScaling || diag.size()==n) || "When useExternalScaling is set, the caller must provide a valid 'diag'");
qtf.resize(n);
/* Function Body */
@@ -214,7 +191,7 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeInit(
if (n <= 0 || m < n || parameters.ftol < 0. || parameters.xtol < 0. || parameters.gtol < 0. || parameters.maxfev <= 0 || parameters.factor <= 0.)
return LevenbergMarquardtSpace::ImproperInputParameters;
- if (mode == 2)
+ if (useExternalScaling)
for (int j = 0; j < n; ++j)
if (diag[j] <= 0.)
return LevenbergMarquardtSpace::ImproperInputParameters;
@@ -235,10 +212,7 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeInit(
template<typename FunctorType, typename Scalar>
LevenbergMarquardtSpace::Status
-LevenbergMarquardt<FunctorType,Scalar>::minimizeOneStep(
- FVectorType &x,
- const int mode
- )
+LevenbergMarquardt<FunctorType,Scalar>::minimizeOneStep(FVectorType &x)
{
int j;
@@ -257,10 +231,10 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOneStep(
fjac = qrfac.matrixQR();
permutation = qrfac.colsPermutation();
- /* on the first iteration and if mode is 1, scale according */
+ /* on the first iteration and if external scaling is not used, scale according */
/* to the norms of the columns of the initial jacobian. */
if (iter == 1) {
- if (mode != 2)
+ if (!useExternalScaling)
for (j = 0; j < n; ++j)
diag[j] = (wa2[j]==0.)? 1. : wa2[j];
@@ -290,7 +264,7 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOneStep(
return LevenbergMarquardtSpace::CosinusTooSmall;
/* rescale if necessary. */
- if (mode != 2)
+ if (!useExternalScaling)
diag = diag.cwiseMax(wa2);
do {
@@ -406,10 +380,7 @@ LevenbergMarquardt<FunctorType,Scalar>::lmstr1(
template<typename FunctorType, typename Scalar>
LevenbergMarquardtSpace::Status
-LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageInit(
- FVectorType &x,
- const int mode
- )
+LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageInit(FVectorType &x)
{
n = x.size();
m = functor.values();
@@ -423,9 +394,9 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageInit(
// The purpose it to only use a nxn matrix, instead of mxn here, so
// that we can handle cases where m>>n :
fjac.resize(n, n);
- if (mode != 2)
+ if (!useExternalScaling)
diag.resize(n);
- assert( (mode!=2 || diag.size()==n) || "When using mode==2, the caller must provide a valid 'diag'");
+ assert( (!useExternalScaling || diag.size()==n) || "When useExternalScaling is set, the caller must provide a valid 'diag'");
qtf.resize(n);
/* Function Body */
@@ -436,7 +407,7 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageInit(
if (n <= 0 || m < n || parameters.ftol < 0. || parameters.xtol < 0. || parameters.gtol < 0. || parameters.maxfev <= 0 || parameters.factor <= 0.)
return LevenbergMarquardtSpace::ImproperInputParameters;
- if (mode == 2)
+ if (useExternalScaling)
for (int j = 0; j < n; ++j)
if (diag[j] <= 0.)
return LevenbergMarquardtSpace::ImproperInputParameters;
@@ -458,10 +429,7 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageInit(
template<typename FunctorType, typename Scalar>
LevenbergMarquardtSpace::Status
-LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageOneStep(
- FVectorType &x,
- const int mode
- )
+LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageOneStep(FVectorType &x)
{
int i, j;
bool sing;
@@ -514,10 +482,10 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageOneStep(
}
}
- /* on the first iteration and if mode is 1, scale according */
+ /* on the first iteration and if external scaling is not used, scale according */
/* to the norms of the columns of the initial jacobian. */
if (iter == 1) {
- if (mode != 2)
+ if (!useExternalScaling)
for (j = 0; j < n; ++j)
diag[j] = (wa2[j]==0.)? 1. : wa2[j];
@@ -541,7 +509,7 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageOneStep(
return LevenbergMarquardtSpace::CosinusTooSmall;
/* rescale if necessary. */
- if (mode != 2)
+ if (!useExternalScaling)
diag = diag.cwiseMax(wa2);
do {
@@ -635,14 +603,11 @@ LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageOneStep(
template<typename FunctorType, typename Scalar>
LevenbergMarquardtSpace::Status
-LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorage(
- FVectorType &x,
- const int mode
- )
+LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorage(FVectorType &x)
{
- LevenbergMarquardtSpace::Status status = minimizeOptimumStorageInit(x, mode);
+ LevenbergMarquardtSpace::Status status = minimizeOptimumStorageInit(x);
do {
- status = minimizeOptimumStorageOneStep(x, mode);
+ status = minimizeOptimumStorageOneStep(x);
} while (status==LevenbergMarquardtSpace::Running);
return status;
}
diff --git a/unsupported/Eigen/src/Skyline/SkylineMatrixBase.h b/unsupported/Eigen/src/Skyline/SkylineMatrixBase.h
index b90a6f9e9..ff20b830c 100644
--- a/unsupported/Eigen/src/Skyline/SkylineMatrixBase.h
+++ b/unsupported/Eigen/src/Skyline/SkylineMatrixBase.h
@@ -36,7 +36,7 @@
* \param Derived
*
*/
-template<typename Derived> class SkylineMatrixBase : public AnyMatrixBase<Derived> {
+template<typename Derived> class SkylineMatrixBase : public EigenBase<Derived> {
public:
typedef typename ei_traits<Derived>::Scalar Scalar;
diff --git a/unsupported/test/NonLinearOptimization.cpp b/unsupported/test/NonLinearOptimization.cpp
index 1313726a1..7aea7b361 100644
--- a/unsupported/test/NonLinearOptimization.cpp
+++ b/unsupported/test/NonLinearOptimization.cpp
@@ -317,7 +317,8 @@ void testHybrj()
hybrj_functor functor;
HybridNonLinearSolver<hybrj_functor> solver(functor);
solver.diag.setConstant(n, 1.);
- info = solver.solve(x, 2);
+ solver.useExternalScaling = true;
+ info = solver.solve(x);
// check return value
VERIFY( 1 == info);
@@ -401,7 +402,8 @@ void testHybrd()
solver.parameters.nb_of_subdiagonals = 1;
solver.parameters.nb_of_superdiagonals = 1;
solver.diag.setConstant(n, 1.);
- info = solver.solveNumericalDiff(x, 2);
+ solver.useExternalScaling = true;
+ info = solver.solveNumericalDiff(x);
// check return value
VERIFY( 1 == info);
diff --git a/unsupported/test/matrix_function.cpp b/unsupported/test/matrix_function.cpp
index 4ff6d7f1e..7a1501da2 100644
--- a/unsupported/test/matrix_function.cpp
+++ b/unsupported/test/matrix_function.cpp
@@ -109,11 +109,10 @@ template<typename MatrixType>
void testHyperbolicFunctions(const MatrixType& A)
{
for (int i = 0; i < g_repeat; i++) {
- MatrixType sinhA = ei_matrix_sinh(A);
- MatrixType coshA = ei_matrix_cosh(A);
MatrixType expA = ei_matrix_exponential(A);
- VERIFY_IS_APPROX(sinhA, (expA - expA.inverse())/2);
- VERIFY_IS_APPROX(coshA, (expA + expA.inverse())/2);
+ MatrixType expmA = ei_matrix_exponential(-A);
+ VERIFY_IS_APPROX(ei_matrix_sinh(A), (expA - expmA) / 2);
+ VERIFY_IS_APPROX(ei_matrix_cosh(A), (expA + expmA) / 2);
}
}
@@ -134,14 +133,15 @@ void testGonioFunctions(const MatrixType& A)
ComplexMatrix Ac = A.template cast<ComplexScalar>();
ComplexMatrix exp_iA = ei_matrix_exponential(imagUnit * Ac);
+ ComplexMatrix exp_miA = ei_matrix_exponential(-imagUnit * Ac);
MatrixType sinA = ei_matrix_sin(A);
ComplexMatrix sinAc = sinA.template cast<ComplexScalar>();
- VERIFY_IS_APPROX(sinAc, (exp_iA - exp_iA.inverse()) / (two*imagUnit));
+ VERIFY_IS_APPROX(sinAc, (exp_iA - exp_miA) / (two*imagUnit));
MatrixType cosA = ei_matrix_cos(A);
ComplexMatrix cosAc = cosA.template cast<ComplexScalar>();
- VERIFY_IS_APPROX(cosAc, (exp_iA + exp_iA.inverse()) / 2);
+ VERIFY_IS_APPROX(cosAc, (exp_iA + exp_miA) / 2);
}
}