Compare commits

..

48 Commits

Author SHA1 Message Date
Benoit Jacob
6f158fb7fc one last compilation fix ... 2008-12-22 21:04:13 +00:00
Benoit Jacob
789ea9d676 unless i find more failures in the tests, this will be beta3...
* fixes for mistakes (especially in the cast() methods in Geometry) revealed by the new "mixing types" test
* dox love, including a section on coeff access in core and an overview in geometry
2008-12-22 20:50:47 +00:00
Benoit Jacob
4336cf3833 * add unit-tests to check allowed and forbiddent mixing of different scalar types
* fix issues in Product revealed by this test
* in Dot.h forbid mixing of different types (at least for now, might allow real.dot(complex) in the future).
2008-12-22 19:17:44 +00:00
Benoit Jacob
f5a05e7ed1 unfuck v.cwise()*w where v is real and w is complex 2008-12-21 20:55:46 +00:00
Benoit Jacob
9e00d94543 * the Upper->UpperTriangular change
* finally get ei_add_test right
2008-12-20 13:36:12 +00:00
Benoit Jacob
21ab65e4b3 fix nasty little bug in ei_add_test 2008-12-20 01:13:38 +00:00
Gael Guennebaud
ebf906a23a add matrix * transform product 2008-12-19 16:31:22 +00:00
Benoit Jacob
df4bd5e46f * fix a test giving some false positives
* add coverage for various operator*=
2008-12-19 16:16:39 +00:00
Benoit Jacob
a3fad2e3c3 Transform*Transform should return Transform
unit test compiles again
2008-12-19 15:55:35 +00:00
Gael Guennebaud
5f6fbaa0e7 * fix a vectorization issue in Product
* use _mm_malloc/_mm_free on other platforms than linux of MSVC (eg., cygwin, OSX)
* replace a lot of inline keywords by EIGEN_STRONG_INLINE to compensate for
  poor MSVC inlining
2008-12-19 15:38:39 +00:00
Gael Guennebaud
8679d895d3 various MSVC fixes in BTL 2008-12-19 15:31:47 +00:00
Benoit Jacob
22875683b9 * extractRotation ---> rotation
* expand the geometry/Transform tests, after Mek's reports
* fix my own stupidity in eigensolver test
2008-12-19 14:52:03 +00:00
Benoit Jacob
e4980616fd SelfAdjointEigenSolver: add operatorSqrt() and operatorInverseSqrt() 2008-12-19 14:15:32 +00:00
Benoit Jacob
84bb868f07 * more MSVC warning fixes from Kenneth Riddile
* actually GCC 4.3.0 has a bug, "deprecated" placed at the end
  of a function prototype doesn't have any effect, moving them to
  the start of the function prototype makes it actually work!
* finish porting the cholesky unit-test to the new LLT/LDLT,
  after the above fix revealed a deprecated warning
2008-12-19 02:59:04 +00:00
Benoit Jacob
f34a4fa335 * forgot to svn add 2 files
* idea of Keir Mierle: make the static assert error msgs UPPERCASE
2008-12-18 21:04:06 +00:00
Benoit Jacob
8106d35408 Patch by Kenneth Riddile: disable MSVC warnings, reenable them outside
of Eigen, and add a MSVC-friendly path in StaticAssert.
2008-12-18 20:48:02 +00:00
Benoit Jacob
fabaa6915b * fix in IO.h, a useless copy was made because of assignment from
Derived to MatrixBase.
* the optimization of eval() for Matrix now consists in a partial
  specialization of ei_eval, which returns a reference type for Matrix.
  No overriding of eval() in Matrix anymore. Consequence: careful,
  ei_eval is no longer guaranteed to give a plain matrix type!
  For that, use ei_plain_matrix_type, or the PlainMatrixType typedef.
* so lots of changes to adapt to that everywhere. Hope this doesn't
  break (too much) MSVC compilation.
* add code examples for the new image() stuff.
* lower a bit the precision for floats in the unit tests as
  we were already doing some workarounds in inverse.cpp and we got some
  failed tests.
2008-12-18 20:36:25 +00:00
Benoit Jacob
b27a3644a2 Macros: add MSVC paths, add an important comment on EIGEN_ALIGN_128 2008-12-18 13:36:31 +00:00
Gael Guennebaud
93f8d56789 improved MSVC support in cmake files (SSE) 2008-12-18 09:07:36 +00:00
Benoit Jacob
15d72d3f9a somehow we had forgotten this very important static assertion... 2008-12-18 03:47:49 +00:00
Gael Guennebaud
9084e2a216 oops I commited bad stuff in the previous commit 2008-12-17 18:54:28 +00:00
Gael Guennebaud
6e138d0069 more MSVC cmake fixes 2008-12-17 18:37:04 +00:00
Gael Guennebaud
4cb63808d4 some cmake fixes for windows and GSL 2008-12-17 17:50:43 +00:00
Gael Guennebaud
c98fe0185e fix non standard non-const std::complex::real/imag issue 2008-12-17 17:31:23 +00:00
Benoit Jacob
5f582aa4e8 fix bad typos, thanks to Kenneth Riddile 2008-12-17 17:14:37 +00:00
Benoit Jacob
c22d10f94c LU class:
* add image() and computeImage() methods, with unit test
* fix a mistake in the definition of KernelResultType
* fix and improve comments
2008-12-17 16:47:55 +00:00
Gael Guennebaud
e3a8431a4a found one bug in the previous ++ changes 2008-12-17 16:04:21 +00:00
Benoit Jacob
89f468671d * replace postfix ++ by prefix ++ wherever that makes sense in Eigen/
* fix some "unused variable" warnings in the tests; there remains a libstdc++ "deprecated"
warning which I haven't looked much into
2008-12-17 14:30:01 +00:00
Benoit Jacob
2110cca431 actually honor EIGEN_STACK_ALLOCATION.
Can set it to 0 to disable stack alloc which guarantees that bad alloc throws exceptions if they are enabled.
2008-12-16 15:44:48 +00:00
Benoit Jacob
38b83b4157 * throw bad_alloc if exceptions are enabled, after patch by Kenneth Riddile
* disable vectorization on MSVC 2005, as it doesn't have all the required intrinsics. require 2008.
2008-12-16 15:17:29 +00:00
Benoit Jacob
50105c3ed6 Hopefully fix compilation of SSE Packetmath with MSVC.
The reason why we didn't realize until now that it didn't compile at all
with MSVC is that before today with MSVC the SSE2 detection didn't work.
2008-12-16 03:48:49 +00:00
Benoit Jacob
0a220721d1 Finally work around enough of MSVC preprocessor dumbness so that it actually detects SSE2 2008-12-15 21:20:40 +00:00
Benoit Jacob
1ad751b991 only enable the "unaligned array" assert if vectorization is enabled.
if vectorization is disabled, WithAlignedOperatorNew is empty!
2008-12-15 20:49:03 +00:00
Benoit Jacob
55b603e457 * fix a bug I introduced in WithAlignedOperatorNew
* add an important comment
2008-12-15 20:14:59 +00:00
Benoit Jacob
763f0a2434 use ei_aligned_malloc and ei_aligned_free also in WithAlignedOperatorNew, so this too should now work with MSVC. 2008-12-15 17:55:11 +00:00
Benoit Jacob
9b1a3d6e19 small optimization (for MSVC) and simplification of ei_alligned_malloc 2008-12-15 17:33:19 +00:00
Benoit Jacob
dd139b92b4 work around the braindead msvc preprocessor 2008-12-15 17:16:22 +00:00
Benoit Jacob
11c8a6bf63 Fix detection of SSE2 with MSVC. 2008-12-15 16:14:54 +00:00
Benoit Jacob
703951d5cd Fix memory alignment (hence vectorization) on MSVC thanks to help from Armin Berres. 2008-12-15 15:54:33 +00:00
Gael Guennebaud
d11c8704e0 oops, forget to remove a line 2008-12-15 12:35:46 +00:00
Gael Guennebaud
a164646c77 more warning fixes by Armin Berres 2008-12-15 12:30:04 +00:00
Benoit Jacob
936eaf600a compilation fix thanks to Dennis Schridde 2008-12-13 21:09:19 +00:00
Gael Guennebaud
ef0cd3a289 one more warning fix, thanks to Armin Berres 2008-12-12 13:50:01 +00:00
Gael Guennebaud
1ed17b037d * fix a couple of warnings (patch from Armin Berres)
* allow Map to map null data
2008-12-12 12:54:45 +00:00
Gael Guennebaud
5015e48361 Sparse module: add a more flexible SparseMatrix::fillrand() function
which allows to fill a matrix with random inner coordinates (makes sense
only when a very few coeffs are inserted per col/row)
2008-12-11 18:26:24 +00:00
Gael Guennebaud
beabf008b0 bugfix in DiagonalProduct: a "DiagonalProduct<SomeXpr>" expression
is now evaluated as a "DiagonalProduct<Matrix<SomeXpr::Eval> >".
Note that currently this only happens in DiagonalProduct.
2008-12-10 19:02:13 +00:00
Gael Guennebaud
ba9a53f9c6 fix compilation issue for 64bit systems (pointer <=> size_t) 2008-12-08 15:07:42 +00:00
Gael Guennebaud
52a30c1d54 fix minor mistake in the inside eigen example 2008-12-08 10:07:09 +00:00
118 changed files with 1676 additions and 947 deletions

View File

@@ -1,5 +1,5 @@
project(Eigen)
set(EIGEN_VERSION_NUMBER "2.0-beta2")
set(EIGEN_VERSION_NUMBER "2.0-beta3")
#if the svnversion program is absent, this will leave the SVN_REVISION string empty,
#but won't stop CMake.
@@ -12,7 +12,7 @@ else(EIGEN_SVN_REVISION)
set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER}")
endif(EIGEN_SVN_REVISION)
cmake_minimum_required(VERSION 2.4)
cmake_minimum_required(VERSION 2.6)
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
@@ -31,29 +31,48 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
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 -fno-exceptions -fno-check-new -fno-common -fstrict-aliasing")
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 -Wextra -fno-exceptions -fno-check-new -fno-common -fstrict-aliasing")
if(NOT EIGEN_TEST_LIB)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
endif(NOT EIGEN_TEST_LIB)
option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
if(EIGEN_TEST_SSE2)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2")
message("Enabling SSE2 in tests/examples")
endif(EIGEN_TEST_SSE2)
option(EIGEN_TEST_SSE3 "Enable/Disable SSE3 in tests/examples" OFF)
if(EIGEN_TEST_SSE3)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse3")
message("Enabling SSE3 in tests/examples")
endif(EIGEN_TEST_SSE3)
option(EIGEN_TEST_SSSE3 "Enable/Disable SSSE3 in tests/examples" OFF)
if(EIGEN_TEST_SSSE3)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mssse3")
message("Enabling SSSE3 in tests/examples")
endif(EIGEN_TEST_SSSE3)
option(EIGEN_TEST_ALTIVEC "Enable/Disable altivec in tests/examples" OFF)
if(EIGEN_TEST_ALTIVEC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec -mabi=altivec")
message("Enabling AltiVec in tests/examples")
endif(EIGEN_TEST_ALTIVEC)
endif(CMAKE_SYSTEM_NAME MATCHES Linux)
endif(CMAKE_COMPILER_IS_GNUCXX)
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ")
option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
if(EIGEN_TEST_SSE2)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2")
message("Enabling SSE2 in tests/examples")
endif(EIGEN_TEST_SSE2)
endif(MSVC)
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
add_subdirectory(Eigen)

View File

@@ -3,6 +3,8 @@
#include "Core"
#include "src/Core/util/DisableMSVCWarnings.h"
namespace Eigen {
/** \defgroup Array Array module
@@ -32,4 +34,6 @@ namespace Eigen {
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_ARRAY_MODULE_H

View File

@@ -3,6 +3,8 @@
#include "Core"
#include "src/Core/util/DisableMSVCWarnings.h"
// Note that EIGEN_HIDE_HEAVY_CODE has to be defined per module
#if (defined EIGEN_EXTERN_INSTANTIATIONS) && (EIGEN_EXTERN_INSTANTIATIONS>=2)
#ifndef EIGEN_HIDE_HEAVY_CODE
@@ -57,4 +59,6 @@ namespace Eigen {
} // namespace Eigen
#endif
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_CHOLESKY_MODULE_H

View File

@@ -1,18 +1,32 @@
#ifndef EIGEN_CORE_H
#define EIGEN_CORE_H
// first thing Eigen does: prevent MSVC from committing suicide
#include "src/Core/util/DisableMSVCWarnings.h"
#ifdef _MSC_VER
#pragma warning( disable : 4181 4244 )
#if (_MSC_VER >= 1500) // 2008 or later
// Remember that usage of defined() in a #define is undefined by the standard
#ifdef _M_IX86_FP
#if _M_IX86_FP >= 2
#define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
#endif
#endif
#endif
#endif
#ifdef __GNUC__
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
#else
#define EIGEN_GNUC_AT_LEAST(x,y) 0
#define EIGEN_GNUC_AT_LEAST(x,y) 0
#endif
// Remember that usage of defined() in a #define is undefined by the standard
#if (defined __SSE2__) && ( (!defined __GNUC__) || EIGEN_GNUC_AT_LEAST(4,2) )
#define EIGEN_SSE2_BUT_NOT_OLD_GCC
#endif
#ifndef EIGEN_DONT_VECTORIZE
#if (defined __SSE2__) && ( (!defined __GNUC__) || EIGEN_GNUC_AT_LEAST(4,2) )
#if defined (EIGEN_SSE2_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
#define EIGEN_VECTORIZE
#define EIGEN_VECTORIZE_SSE
#include <emmintrin.h>
@@ -23,11 +37,11 @@
#ifdef __SSSE3__
#include <tmmintrin.h>
#endif
#elif (defined __ALTIVEC__)
#elif defined __ALTIVEC__
#define EIGEN_VECTORIZE
#define EIGEN_VECTORIZE_ALTIVEC
#include <altivec.h>
// We _need_ to #undef all these ugly tokens defined in <altivec.h>
// We need to #undef all these ugly tokens defined in <altivec.h>
// => use __vector instead of vector
#undef bool
#undef vector
@@ -44,6 +58,18 @@
#include <cstring>
#include <string>
#if defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER) && defined(EIGEN_VECTORIZE)
#include <malloc.h> // for _aligned_malloc
#endif
#if (defined(_CPPUNWIND) || defined(__EXCEPTIONS)) && !defined(EIGEN_NO_EXCEPTIONS)
#define EIGEN_EXCEPTIONS
#endif
#ifdef EIGEN_EXCEPTIONS
#include <new>
#endif
namespace Eigen {
/** \defgroup Core_Module Core module
@@ -69,9 +95,9 @@ namespace Eigen {
#include "src/Core/GenericPacketMath.h"
#if defined EIGEN_VECTORIZE_SSE
#include "src/Core/arch/SSE/PacketMath.h"
#include "src/Core/arch/SSE/PacketMath.h"
#elif defined EIGEN_VECTORIZE_ALTIVEC
#include "src/Core/arch/AltiVec/PacketMath.h"
#include "src/Core/arch/AltiVec/PacketMath.h"
#endif
#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
@@ -81,10 +107,12 @@ namespace Eigen {
#include "src/Core/Functors.h"
#include "src/Core/MatrixBase.h"
#include "src/Core/Coeffs.h"
#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874
// at least confirmed with Doxygen 1.5.5 and 1.5.6
#include "src/Core/Assign.h"
#include "src/Core/Assign.h"
#endif
#include "src/Core/MatrixStorage.h"
#include "src/Core/NestByValue.h"
#include "src/Core/Flagged.h"
@@ -116,4 +144,6 @@ namespace Eigen {
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_CORE_H

View File

@@ -1,6 +1,10 @@
#ifndef EIGEN_GEOMETRY_MODULE_H
#define EIGEN_GEOMETRY_MODULE_H
#include "Core"
#include "src/Core/util/DisableMSVCWarnings.h"
#include "Array"
#include <limits>
@@ -39,4 +43,6 @@ namespace Eigen {
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_GEOMETRY_MODULE_H

View File

@@ -3,6 +3,8 @@
#include "Core"
#include "src/Core/util/DisableMSVCWarnings.h"
namespace Eigen {
/** \defgroup LU_Module LU module
@@ -22,4 +24,6 @@ namespace Eigen {
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_LU_MODULE_H

View File

@@ -2,6 +2,9 @@
#define EIGEN_QR_MODULE_H
#include "Core"
#include "src/Core/util/DisableMSVCWarnings.h"
#include "Cholesky"
// Note that EIGEN_HIDE_HEAVY_CODE has to be defined per module
@@ -62,4 +65,6 @@ namespace Eigen {
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_QR_MODULE_H

View File

@@ -1,6 +1,10 @@
#ifndef EIGEN_REGRESSION_MODULE_H
#define EIGEN_REGRESSION_MODULE_H
#include "Core"
#include "src/Core/util/DisableMSVCWarnings.h"
#include "LU"
#include "QR"
#include "Geometry"
@@ -19,4 +23,6 @@ namespace Eigen {
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_REGRESSION_MODULE_H

View File

@@ -3,6 +3,8 @@
#include "Core"
#include "src/Core/util/DisableMSVCWarnings.h"
namespace Eigen {
/** \defgroup SVD_Module SVD module
@@ -19,4 +21,6 @@ namespace Eigen {
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_SVD_MODULE_H

View File

@@ -2,6 +2,9 @@
#define EIGEN_SPARSE_MODULE_H
#include "Core"
#include "src/Core/util/DisableMSVCWarnings.h"
#include <vector>
#include <map>
#include <cstdlib>
@@ -102,4 +105,6 @@ namespace Eigen {
} // namespace Eigen
#include "src/Core/util/EnableMSVCWarnings.h"
#endif // EIGEN_SPARSE_MODULE_H

View File

@@ -99,8 +99,8 @@ inline bool MatrixBase<Derived>::all(void) const
>::run(derived());
else
{
for(int j = 0; j < cols(); j++)
for(int i = 0; i < rows(); i++)
for(int j = 0; j < cols(); ++j)
for(int i = 0; i < rows(); ++i)
if (!coeff(i, j)) return false;
return true;
}
@@ -123,8 +123,8 @@ inline bool MatrixBase<Derived>::any(void) const
>::run(derived());
else
{
for(int j = 0; j < cols(); j++)
for(int i = 0; i < rows(); i++)
for(int j = 0; j < cols(); ++j)
for(int i = 0; i < rows(); ++i)
if (coeff(i, j)) return true;
return false;
}

View File

@@ -52,13 +52,13 @@ template<typename MatrixType> class Cholesky
}
/** \deprecated */
inline Part<MatrixType, Lower> matrixL(void) const { return m_matrix; }
inline Part<MatrixType, LowerTriangular> matrixL(void) const { return m_matrix; }
/** \deprecated */
inline bool isPositiveDefinite(void) const { return m_isPositiveDefinite; }
template<typename Derived>
typename Derived::Eval solve(const MatrixBase<Derived> &b) const EIGEN_DEPRECATED;
EIGEN_DEPRECATED typename MatrixBase<Derived>::PlainMatrixType_ColMajor solve(const MatrixBase<Derived> &b) const;
template<typename RhsDerived, typename ResDerived>
bool solve(const MatrixBase<RhsDerived> &b, MatrixBase<ResDerived> *result) const;
@@ -119,11 +119,11 @@ void Cholesky<MatrixType>::compute(const MatrixType& a)
/** \deprecated */
template<typename MatrixType>
template<typename Derived>
typename Derived::Eval Cholesky<MatrixType>::solve(const MatrixBase<Derived> &b) const
typename MatrixBase<Derived>::PlainMatrixType_ColMajor Cholesky<MatrixType>::solve(const MatrixBase<Derived> &b) const
{
const int size = m_matrix.rows();
ei_assert(size==b.rows());
typename ei_eval_to_column_major<Derived>::type x(b);
typename MatrixBase<Derived>::PlainMatrixType_ColMajor x(b);
solveInPlace(x);
return x;
}
@@ -148,7 +148,7 @@ bool Cholesky<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const
if (!m_isPositiveDefinite)
return false;
matrixL().solveTriangularInPlace(bAndX);
m_matrix.adjoint().template part<Upper>().solveTriangularInPlace(bAndX);
m_matrix.adjoint().template part<UpperTriangular>().solveTriangularInPlace(bAndX);
return true;
}
@@ -156,10 +156,10 @@ bool Cholesky<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const
* \deprecated has been renamed llt()
*/
template<typename Derived>
inline const Cholesky<typename MatrixBase<Derived>::EvalType>
inline const Cholesky<typename MatrixBase<Derived>::PlainMatrixType>
MatrixBase<Derived>::cholesky() const
{
return Cholesky<typename ei_eval<Derived>::type>(derived());
return Cholesky<PlainMatrixType>(derived());
}
#endif // EIGEN_CHOLESKY_H

View File

@@ -46,7 +46,7 @@ template<typename MatrixType> class CholeskyWithoutSquareRoot
}
/** \returns the lower triangular matrix L */
inline Part<MatrixType, UnitLower> matrixL(void) const { return m_matrix; }
inline Part<MatrixType, UnitLowerTriangular> matrixL(void) const { return m_matrix; }
/** \returns the coefficients of the diagonal matrix D */
inline DiagonalCoeffs<MatrixType> vectorD(void) const { return m_matrix.diagonal(); }
@@ -55,7 +55,7 @@ template<typename MatrixType> class CholeskyWithoutSquareRoot
inline bool isPositiveDefinite(void) const { return m_isPositiveDefinite; }
template<typename Derived>
typename Derived::Eval solve(const MatrixBase<Derived> &b) const EIGEN_DEPRECATED;
EIGEN_DEPRECATED typename Derived::Eval solve(const MatrixBase<Derived> &b) const;
template<typename RhsDerived, typename ResDerived>
bool solve(const MatrixBase<RhsDerived> &b, MatrixBase<ResDerived> *result) const;
@@ -137,7 +137,7 @@ typename Derived::Eval CholeskyWithoutSquareRoot<MatrixType>::solve(const Matrix
const int size = m_matrix.rows();
ei_assert(size==b.rows());
return m_matrix.adjoint().template part<UnitUpper>()
return m_matrix.adjoint().template part<UnitUpperTriangular>()
.solveTriangular(
( m_matrix.cwise().inverse().template part<Diagonal>()
* matrixL().solveTriangular(b))
@@ -167,7 +167,7 @@ bool CholeskyWithoutSquareRoot<MatrixType>::solveInPlace(MatrixBase<Derived> &bA
return false;
matrixL().solveTriangularInPlace(bAndX);
bAndX = (m_matrix.cwise().inverse().template part<Diagonal>() * bAndX).lazy();
m_matrix.adjoint().template part<UnitUpper>().solveTriangularInPlace(bAndX);
m_matrix.adjoint().template part<UnitUpperTriangular>().solveTriangularInPlace(bAndX);
return true;
}
@@ -175,7 +175,7 @@ bool CholeskyWithoutSquareRoot<MatrixType>::solveInPlace(MatrixBase<Derived> &bA
* \deprecated has been renamed ldlt()
*/
template<typename Derived>
inline const CholeskyWithoutSquareRoot<typename MatrixBase<Derived>::EvalType>
inline const CholeskyWithoutSquareRoot<typename MatrixBase<Derived>::PlainMatrixType>
MatrixBase<Derived>::choleskyNoSqrt() const
{
return derived();

View File

@@ -60,7 +60,7 @@ template<typename MatrixType> class LDLT
}
/** \returns the lower triangular matrix L */
inline Part<MatrixType, UnitLower> matrixL(void) const { return m_matrix; }
inline Part<MatrixType, UnitLowerTriangular> matrixL(void) const { return m_matrix; }
/** \returns the coefficients of the diagonal matrix D */
inline DiagonalCoeffs<MatrixType> vectorD(void) const { return m_matrix.diagonal(); }
@@ -181,7 +181,7 @@ bool LDLT<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const
return false;
matrixL().solveTriangularInPlace(bAndX);
bAndX = (m_matrix.cwise().inverse().template part<Diagonal>() * bAndX).lazy();
m_matrix.adjoint().template part<UnitUpper>().solveTriangularInPlace(bAndX);
m_matrix.adjoint().template part<UnitUpperTriangular>().solveTriangularInPlace(bAndX);
return true;
}
@@ -189,7 +189,7 @@ bool LDLT<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const
* \returns the Cholesky decomposition without square root of \c *this
*/
template<typename Derived>
inline const LDLT<typename MatrixBase<Derived>::EvalType>
inline const LDLT<typename MatrixBase<Derived>::PlainMatrixType>
MatrixBase<Derived>::ldlt() const
{
return derived();

View File

@@ -67,7 +67,7 @@ template<typename MatrixType> class LLT
}
/** \returns the lower triangular matrix L */
inline Part<MatrixType, Lower> matrixL(void) const { return m_matrix; }
inline Part<MatrixType, LowerTriangular> matrixL(void) const { return m_matrix; }
/** \returns true if the matrix is positive definite */
inline bool isPositiveDefinite(void) const { return m_isPositiveDefinite; }
@@ -169,7 +169,7 @@ bool LLT<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const
if (!m_isPositiveDefinite)
return false;
matrixL().solveTriangularInPlace(bAndX);
m_matrix.adjoint().template part<Upper>().solveTriangularInPlace(bAndX);
m_matrix.adjoint().template part<UpperTriangular>().solveTriangularInPlace(bAndX);
return true;
}
@@ -177,10 +177,10 @@ bool LLT<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const
* \returns the LLT decomposition of \c *this
*/
template<typename Derived>
inline const LLT<typename MatrixBase<Derived>::EvalType>
inline const LLT<typename MatrixBase<Derived>::PlainMatrixType>
MatrixBase<Derived>::llt() const
{
return LLT<typename ei_eval<Derived>::type>(derived());
return LLT<PlainMatrixType>(derived());
}
#endif // EIGEN_LLT_H

View File

@@ -112,7 +112,7 @@ struct ei_assign_novec_CompleteUnrolling
: Index / Derived1::RowsAtCompileTime
};
inline static void run(Derived1 &dst, const Derived2 &src)
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
dst.copyCoeff(row, col, src);
ei_assign_novec_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
@@ -122,13 +122,13 @@ struct ei_assign_novec_CompleteUnrolling
template<typename Derived1, typename Derived2, int Stop>
struct ei_assign_novec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
{
inline static void run(Derived1 &, const Derived2 &) {}
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
};
template<typename Derived1, typename Derived2, int Index, int Stop>
struct ei_assign_novec_InnerUnrolling
{
inline static void run(Derived1 &dst, const Derived2 &src, int row_or_col)
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int row_or_col)
{
const bool rowMajor = int(Derived1::Flags)&RowMajorBit;
const int row = rowMajor ? row_or_col : Index;
@@ -141,7 +141,7 @@ struct ei_assign_novec_InnerUnrolling
template<typename Derived1, typename Derived2, int Stop>
struct ei_assign_novec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
{
inline static void run(Derived1 &, const Derived2 &, int) {}
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {}
};
/**************************
@@ -161,7 +161,7 @@ struct ei_assign_innervec_CompleteUnrolling
SrcAlignment = ei_assign_traits<Derived1,Derived2>::SrcAlignment
};
inline static void run(Derived1 &dst, const Derived2 &src)
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
dst.template copyPacket<Derived2, Aligned, SrcAlignment>(row, col, src);
ei_assign_innervec_CompleteUnrolling<Derived1, Derived2,
@@ -172,13 +172,13 @@ struct ei_assign_innervec_CompleteUnrolling
template<typename Derived1, typename Derived2, int Stop>
struct ei_assign_innervec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
{
inline static void run(Derived1 &, const Derived2 &) {}
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {}
};
template<typename Derived1, typename Derived2, int Index, int Stop>
struct ei_assign_innervec_InnerUnrolling
{
inline static void run(Derived1 &dst, const Derived2 &src, int row_or_col)
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int row_or_col)
{
const int row = int(Derived1::Flags)&RowMajorBit ? row_or_col : Index;
const int col = int(Derived1::Flags)&RowMajorBit ? Index : row_or_col;
@@ -191,7 +191,7 @@ struct ei_assign_innervec_InnerUnrolling
template<typename Derived1, typename Derived2, int Stop>
struct ei_assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
{
inline static void run(Derived1 &, const Derived2 &, int) {}
EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {}
};
/***************************************************************************
@@ -210,12 +210,12 @@ struct ei_assign_impl;
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, NoVectorization, NoUnrolling>
{
static void run(Derived1 &dst, const Derived2 &src)
inline static void run(Derived1 &dst, const Derived2 &src)
{
const int innerSize = dst.innerSize();
const int outerSize = dst.outerSize();
for(int j = 0; j < outerSize; j++)
for(int i = 0; i < innerSize; i++)
for(int j = 0; j < outerSize; ++j)
for(int i = 0; i < innerSize; ++i)
{
if(int(Derived1::Flags)&RowMajorBit)
dst.copyCoeff(j, i, src);
@@ -228,7 +228,7 @@ struct ei_assign_impl<Derived1, Derived2, NoVectorization, NoUnrolling>
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, NoVectorization, CompleteUnrolling>
{
inline static void run(Derived1 &dst, const Derived2 &src)
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
ei_assign_novec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
::run(dst, src);
@@ -238,12 +238,12 @@ struct ei_assign_impl<Derived1, Derived2, NoVectorization, CompleteUnrolling>
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, NoVectorization, InnerUnrolling>
{
static void run(Derived1 &dst, const Derived2 &src)
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
const bool rowMajor = int(Derived1::Flags)&RowMajorBit;
const int innerSize = rowMajor ? Derived1::ColsAtCompileTime : Derived1::RowsAtCompileTime;
const int outerSize = dst.outerSize();
for(int j = 0; j < outerSize; j++)
for(int j = 0; j < outerSize; ++j)
ei_assign_novec_InnerUnrolling<Derived1, Derived2, 0, innerSize>
::run(dst, src, j);
}
@@ -256,12 +256,12 @@ struct ei_assign_impl<Derived1, Derived2, NoVectorization, InnerUnrolling>
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, InnerVectorization, NoUnrolling>
{
static void run(Derived1 &dst, const Derived2 &src)
inline static void run(Derived1 &dst, const Derived2 &src)
{
const int innerSize = dst.innerSize();
const int outerSize = dst.outerSize();
const int packetSize = ei_packet_traits<typename Derived1::Scalar>::size;
for(int j = 0; j < outerSize; j++)
for(int j = 0; j < outerSize; ++j)
for(int i = 0; i < innerSize; i+=packetSize)
{
if(int(Derived1::Flags)&RowMajorBit)
@@ -275,7 +275,7 @@ struct ei_assign_impl<Derived1, Derived2, InnerVectorization, NoUnrolling>
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, InnerVectorization, CompleteUnrolling>
{
inline static void run(Derived1 &dst, const Derived2 &src)
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
ei_assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
::run(dst, src);
@@ -285,12 +285,12 @@ struct ei_assign_impl<Derived1, Derived2, InnerVectorization, CompleteUnrolling>
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, InnerVectorization, InnerUnrolling>
{
static void run(Derived1 &dst, const Derived2 &src)
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
const bool rowMajor = int(Derived1::Flags)&RowMajorBit;
const int innerSize = rowMajor ? Derived1::ColsAtCompileTime : Derived1::RowsAtCompileTime;
const int outerSize = dst.outerSize();
for(int j = 0; j < outerSize; j++)
for(int j = 0; j < outerSize; ++j)
ei_assign_innervec_InnerUnrolling<Derived1, Derived2, 0, innerSize>
::run(dst, src, j);
}
@@ -303,7 +303,7 @@ struct ei_assign_impl<Derived1, Derived2, InnerVectorization, InnerUnrolling>
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
{
static void run(Derived1 &dst, const Derived2 &src)
inline static void run(Derived1 &dst, const Derived2 &src)
{
const int size = dst.size();
const int packetSize = ei_packet_traits<typename Derived1::Scalar>::size;
@@ -311,7 +311,7 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
: ei_alignmentOffset(&dst.coeffRef(0), size);
const int alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize;
for(int index = 0; index < alignedStart; index++)
for(int index = 0; index < alignedStart; ++index)
dst.copyCoeff(index, src);
for(int index = alignedStart; index < alignedEnd; index += packetSize)
@@ -319,7 +319,7 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
dst.template copyPacket<Derived2, Aligned, ei_assign_traits<Derived1,Derived2>::SrcAlignment>(index, src);
}
for(int index = alignedEnd; index < size; index++)
for(int index = alignedEnd; index < size; ++index)
dst.copyCoeff(index, src);
}
};
@@ -327,7 +327,7 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling>
{
static void run(Derived1 &dst, const Derived2 &src)
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
{
const int size = Derived1::SizeAtCompileTime;
const int packetSize = ei_packet_traits<typename Derived1::Scalar>::size;
@@ -345,7 +345,7 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling
template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, SliceVectorization, NoUnrolling>
{
static void run(Derived1 &dst, const Derived2 &src)
inline static void run(Derived1 &dst, const Derived2 &src)
{
const int packetSize = ei_packet_traits<typename Derived1::Scalar>::size;
const int packetAlignedMask = packetSize - 1;
@@ -355,12 +355,12 @@ struct ei_assign_impl<Derived1, Derived2, SliceVectorization, NoUnrolling>
int alignedStart = ei_assign_traits<Derived1,Derived2>::DstIsAligned ? 0
: ei_alignmentOffset(&dst.coeffRef(0), innerSize);
for(int i = 0; i < outerSize; i++)
for(int i = 0; i < outerSize; ++i)
{
const int alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask);
// do the non-vectorizable part of the assignment
for (int index = 0; index<alignedStart ; index++)
for (int index = 0; index<alignedStart ; ++index)
{
if(Derived1::Flags&RowMajorBit)
dst.copyCoeff(i, index, src);
@@ -378,7 +378,7 @@ struct ei_assign_impl<Derived1, Derived2, SliceVectorization, NoUnrolling>
}
// do the non-vectorizable part of the assignment
for (int index = alignedEnd; index<innerSize ; index++)
for (int index = alignedEnd; index<innerSize ; ++index)
{
if(Derived1::Flags&RowMajorBit)
dst.copyCoeff(i, index, src);
@@ -397,7 +397,7 @@ struct ei_assign_impl<Derived1, Derived2, SliceVectorization, NoUnrolling>
template<typename Derived>
template<typename OtherDerived>
inline Derived& MatrixBase<Derived>
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>
::lazyAssign(const MatrixBase<OtherDerived>& other)
{
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
@@ -407,7 +407,7 @@ inline Derived& MatrixBase<Derived>
}
template<typename Derived, typename OtherDerived,
bool EvalBeforeAssigning = int(OtherDerived::Flags) & EvalBeforeAssigningBit,
bool EvalBeforeAssigning = (int(OtherDerived::Flags) & EvalBeforeAssigningBit) != 0,
bool NeedToTranspose = Derived::IsVectorAtCompileTime
&& OtherDerived::IsVectorAtCompileTime
&& int(Derived::RowsAtCompileTime) == int(OtherDerived::ColsAtCompileTime)
@@ -417,26 +417,28 @@ struct ei_assign_selector;
template<typename Derived, typename OtherDerived>
struct ei_assign_selector<Derived,OtherDerived,false,false> {
static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); }
EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); }
};
template<typename Derived, typename OtherDerived>
struct ei_assign_selector<Derived,OtherDerived,true,false> {
static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); }
EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); }
};
template<typename Derived, typename OtherDerived>
struct ei_assign_selector<Derived,OtherDerived,false,true> {
static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); }
EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); }
};
template<typename Derived, typename OtherDerived>
struct ei_assign_selector<Derived,OtherDerived,true,true> {
static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); }
EIGEN_STRONG_INLINE static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); }
};
template<typename Derived>
template<typename OtherDerived>
inline Derived& MatrixBase<Derived>
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>
::operator=(const MatrixBase<OtherDerived>& other)
{
EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename OtherDerived::Scalar>::ret),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
return ei_assign_selector<Derived,OtherDerived>::run(derived(), other.derived());
}

View File

@@ -122,7 +122,7 @@ template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess, in
: m_matrix(matrix), m_startRow(startRow), m_startCol(startCol),
m_blockRows(matrix.rows()), m_blockCols(matrix.cols())
{
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && RowsAtCompileTime!=Dynamic,this_method_is_only_for_fixed_size)
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && RowsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
ei_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= matrix.rows()
&& startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= matrix.cols());
}

View File

@@ -433,7 +433,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
{
/* explicit vectorization */
// process initial unaligned coeffs
for (int j=0; j<alignedStart; j++)
for (int j=0; j<alignedStart; ++j)
res[j] += ei_pfirst(ptmp0)*lhs0[j] + ei_pfirst(ptmp1)*lhs1[j] + ei_pfirst(ptmp2)*lhs2[j] + ei_pfirst(ptmp3)*lhs3[j];
if (alignedSize>alignedStart)
@@ -493,8 +493,8 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
} // end explicit vectorization
/* process remaining coeffs (or all if there is no explicit vectorization) */
for (int j=alignedSize; j<size; j++)
res[j] += ei_pfirst(ptmp0)*lhs0[j] + ei_pfirst(ptmp1)*lhs1[j] + ei_pfirst(ptmp2)*lhs2[j] + ei_pfirst(ptmp3)*lhs3[j];
for (int j=alignedSize; j<size; ++j)
res[j] += ei_pfirst(ptmp0)*lhs0[j] + ei_pfirst(ptmp1)*lhs1[j] + ei_pfirst(ptmp2)*lhs2[j] + ei_pfirst(ptmp3)*lhs3[j];
}
// process remaining first and last columns (at most columnsAtOnce-1)
@@ -502,7 +502,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
int start = columnBound;
do
{
for (int i=start; i<end; i++)
for (int i=start; i<end; ++i)
{
Packet ptmp0 = ei_pset1(rhs[i]);
const Scalar* lhs0 = lhs + i*lhsStride;
@@ -511,7 +511,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
{
/* explicit vectorization */
// process first unaligned result's coeffs
for (int j=0; j<alignedStart; j++)
for (int j=0; j<alignedStart; ++j)
res[j] += ei_pfirst(ptmp0) * lhs0[j];
// process aligned result's coeffs
@@ -524,7 +524,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
}
// process remaining scalars (or all if no explicit vectorization)
for (int j=alignedSize; j<size; j++)
for (int j=alignedSize; j<size; ++j)
res[j] += ei_pfirst(ptmp0) * lhs0[j];
}
if (skipColumns)
@@ -624,7 +624,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
// process initial unaligned coeffs
// FIXME this loop get vectorized by the compiler !
for (int j=0; j<alignedStart; j++)
for (int j=0; j<alignedStart; ++j)
{
Scalar b = rhs[j];
tmp0 += b*lhs0[j]; tmp1 += b*lhs1[j]; tmp2 += b*lhs2[j]; tmp3 += b*lhs3[j];
@@ -695,7 +695,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
// process remaining coeffs (or all if no explicit vectorization)
// FIXME this loop get vectorized by the compiler !
for (int j=alignedSize; j<size; j++)
for (int j=alignedSize; j<size; ++j)
{
Scalar b = rhs[j];
tmp0 += b*lhs0[j]; tmp1 += b*lhs1[j]; tmp2 += b*lhs2[j]; tmp3 += b*lhs3[j];
@@ -708,14 +708,14 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
int start = rowBound;
do
{
for (int i=start; i<end; i++)
for (int i=start; i<end; ++i)
{
Scalar tmp0 = Scalar(0);
Packet ptmp0 = ei_pset1(tmp0);
const Scalar* lhs0 = lhs + i*lhsStride;
// process first unaligned result's coeffs
// FIXME this loop get vectorized by the compiler !
for (int j=0; j<alignedStart; j++)
for (int j=0; j<alignedStart; ++j)
tmp0 += rhs[j] * lhs0[j];
if (alignedSize>alignedStart)
@@ -732,7 +732,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
// process remaining scalars
// FIXME this loop get vectorized by the compiler !
for (int j=alignedSize; j<size; j++)
for (int j=alignedSize; j<size; ++j)
tmp0 += rhs[j] * lhs0[j];
res[i] += tmp0;
}

View File

@@ -40,7 +40,7 @@
* \sa operator()(int,int) const, coeffRef(int,int), coeff(int) const
*/
template<typename Derived>
inline const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::coeff(int row, int col) const
{
ei_internal_assert(row >= 0 && row < rows()
@@ -53,7 +53,7 @@ inline const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
* \sa operator()(int,int), operator[](int) const
*/
template<typename Derived>
inline const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::operator()(int row, int col) const
{
ei_assert(row >= 0 && row < rows()
@@ -76,7 +76,7 @@ inline const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
* \sa operator()(int,int), coeff(int, int) const, coeffRef(int)
*/
template<typename Derived>
inline typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::coeffRef(int row, int col)
{
ei_internal_assert(row >= 0 && row < rows()
@@ -89,7 +89,7 @@ inline typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
* \sa operator()(int,int) const, operator[](int)
*/
template<typename Derived>
inline typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::operator()(int row, int col)
{
ei_assert(row >= 0 && row < rows()
@@ -112,7 +112,7 @@ inline typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
* \sa operator[](int) const, coeffRef(int), coeff(int,int) const
*/
template<typename Derived>
inline const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::coeff(int index) const
{
ei_internal_assert(index >= 0 && index < size());
@@ -127,7 +127,7 @@ inline const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
* z() const, w() const
*/
template<typename Derived>
inline const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::operator[](int index) const
{
ei_assert(index >= 0 && index < size());
@@ -144,7 +144,7 @@ inline const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
* z() const, w() const
*/
template<typename Derived>
inline const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::operator()(int index) const
{
ei_assert(index >= 0 && index < size());
@@ -166,7 +166,7 @@ inline const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
* \sa operator[](int), coeff(int) const, coeffRef(int,int)
*/
template<typename Derived>
inline typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::coeffRef(int index)
{
ei_internal_assert(index >= 0 && index < size());
@@ -180,7 +180,7 @@ inline typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
* \sa operator[](int) const, operator()(int,int), x(), y(), z(), w()
*/
template<typename Derived>
inline typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::operator[](int index)
{
ei_assert(index >= 0 && index < size());
@@ -196,7 +196,7 @@ inline typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
* \sa operator[](int) const, operator()(int,int), x(), y(), z(), w()
*/
template<typename Derived>
inline typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::operator()(int index)
{
ei_assert(index >= 0 && index < size());
@@ -205,42 +205,42 @@ inline typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
/** equivalent to operator[](0). */
template<typename Derived>
inline const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::x() const { return (*this)[0]; }
/** equivalent to operator[](1). */
template<typename Derived>
inline const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::y() const { return (*this)[1]; }
/** equivalent to operator[](2). */
template<typename Derived>
inline const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::z() const { return (*this)[2]; }
/** equivalent to operator[](3). */
template<typename Derived>
inline const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
EIGEN_STRONG_INLINE const typename ei_traits<Derived>::Scalar MatrixBase<Derived>
::w() const { return (*this)[3]; }
/** equivalent to operator[](0). */
template<typename Derived>
inline typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::x() { return (*this)[0]; }
/** equivalent to operator[](1). */
template<typename Derived>
inline typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::y() { return (*this)[1]; }
/** equivalent to operator[](2). */
template<typename Derived>
inline typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::z() { return (*this)[2]; }
/** equivalent to operator[](3). */
template<typename Derived>
inline typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
::w() { return (*this)[3]; }
/** \returns the packet of coefficients starting at the given row and column. It is your responsibility
@@ -253,7 +253,7 @@ inline typename ei_traits<Derived>::Scalar& MatrixBase<Derived>
*/
template<typename Derived>
template<int LoadMode>
inline typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type
EIGEN_STRONG_INLINE typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type
MatrixBase<Derived>::packet(int row, int col) const
{
ei_internal_assert(row >= 0 && row < rows()
@@ -271,7 +271,7 @@ MatrixBase<Derived>::packet(int row, int col) const
*/
template<typename Derived>
template<int StoreMode>
inline void MatrixBase<Derived>::writePacket
EIGEN_STRONG_INLINE void MatrixBase<Derived>::writePacket
(int row, int col, const typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type& x)
{
ei_internal_assert(row >= 0 && row < rows()
@@ -289,7 +289,7 @@ inline void MatrixBase<Derived>::writePacket
*/
template<typename Derived>
template<int LoadMode>
inline typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type
EIGEN_STRONG_INLINE typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type
MatrixBase<Derived>::packet(int index) const
{
ei_internal_assert(index >= 0 && index < size());
@@ -306,7 +306,7 @@ MatrixBase<Derived>::packet(int index) const
*/
template<typename Derived>
template<int StoreMode>
inline void MatrixBase<Derived>::writePacket
EIGEN_STRONG_INLINE void MatrixBase<Derived>::writePacket
(int index, const typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type& x)
{
ei_internal_assert(index >= 0 && index < size());
@@ -322,7 +322,7 @@ inline void MatrixBase<Derived>::writePacket
*/
template<typename Derived>
template<typename OtherDerived>
inline void MatrixBase<Derived>::copyCoeff(int row, int col, const MatrixBase<OtherDerived>& other)
EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyCoeff(int row, int col, const MatrixBase<OtherDerived>& other)
{
ei_internal_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
@@ -338,7 +338,7 @@ inline void MatrixBase<Derived>::copyCoeff(int row, int col, const MatrixBase<Ot
*/
template<typename Derived>
template<typename OtherDerived>
inline void MatrixBase<Derived>::copyCoeff(int index, const MatrixBase<OtherDerived>& other)
EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyCoeff(int index, const MatrixBase<OtherDerived>& other)
{
ei_internal_assert(index >= 0 && index < size());
derived().coeffRef(index) = other.derived().coeff(index);
@@ -353,7 +353,7 @@ inline void MatrixBase<Derived>::copyCoeff(int index, const MatrixBase<OtherDeri
*/
template<typename Derived>
template<typename OtherDerived, int StoreMode, int LoadMode>
inline void MatrixBase<Derived>::copyPacket(int row, int col, const MatrixBase<OtherDerived>& other)
EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyPacket(int row, int col, const MatrixBase<OtherDerived>& other)
{
ei_internal_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
@@ -370,7 +370,7 @@ inline void MatrixBase<Derived>::copyPacket(int row, int col, const MatrixBase<O
*/
template<typename Derived>
template<typename OtherDerived, int StoreMode, int LoadMode>
inline void MatrixBase<Derived>::copyPacket(int index, const MatrixBase<OtherDerived>& other)
EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyPacket(int index, const MatrixBase<OtherDerived>& other)
{
ei_internal_assert(index >= 0 && index < size());
derived().template writePacket<StoreMode>(index,

View File

@@ -27,13 +27,13 @@
#define EIGEN_COMMAINITIALIZER_H
/** \class CommaInitializer
*
*
* \brief Helper class used by the comma initializer operator
*
* This class is internally used to implement the comma initializer feature. It is
* the return type of MatrixBase::operator<<, and most of the time this is the only
* way it is used.
*
*
* \sa \ref MatrixBaseCommaInitRef "MatrixBase::operator<<", CommaInitializer::finished()
*/
template<typename MatrixType>
@@ -128,7 +128,7 @@ struct CommaInitializer
*
* Example: \include MatrixBase_set.cpp
* Output: \verbinclude MatrixBase_set.out
*
*
* \sa CommaInitializer::finished(), class CommaInitializer
*/
template<typename Derived>

View File

@@ -31,6 +31,18 @@
#define EIGEN_CWISE_BINOP_RETURN_TYPE(OP) \
CwiseBinaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType, OtherDerived>
#define EIGEN_CWISE_PRODUCT_RETURN_TYPE \
CwiseBinaryOp< \
ei_scalar_product_op< \
typename ei_scalar_product_traits< \
typename ei_traits<ExpressionType>::Scalar, \
typename ei_traits<OtherDerived>::Scalar \
>::ReturnType \
>, \
ExpressionType, \
OtherDerived \
>
/** \internal
* convenient macro to defined the return type of a cwise unary operation */
#define EIGEN_CWISE_UNOP_RETURN_TYPE(OP) \
@@ -74,7 +86,7 @@ template<typename ExpressionType> class Cwise
inline const ExpressionType& _expression() const { return m_matrix; }
template<typename OtherDerived>
const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_product_op)
const EIGEN_CWISE_PRODUCT_RETURN_TYPE
operator*(const MatrixBase<OtherDerived> &other) const;
template<typename OtherDerived>

View File

@@ -54,7 +54,6 @@ struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
typename Rhs::Scalar
)
>::type Scalar;
typedef typename Lhs::Nested LhsNested;
typedef typename Rhs::Nested RhsNested;
typedef typename ei_unref<LhsNested>::type _LhsNested;
@@ -89,7 +88,7 @@ class CwiseBinaryOp : ei_no_assignment_operator,
class InnerIterator;
inline CwiseBinaryOp(const Lhs& lhs, const Rhs& rhs, const BinaryOp& func = BinaryOp())
EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& lhs, const Rhs& rhs, const BinaryOp& func = BinaryOp())
: m_lhs(lhs), m_rhs(rhs), m_functor(func)
{
// we require Lhs and Rhs to have the same scalar type. Currently there is no example of a binary functor
@@ -99,33 +98,36 @@ class CwiseBinaryOp : ei_no_assignment_operator,
// It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths.
// So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
// add together a float matrix and a double matrix.
EIGEN_STATIC_ASSERT((ei_is_same_type<typename Lhs::Scalar, typename Rhs::Scalar>::ret),
you_mixed_different_numeric_types__you_need_to_use_the_cast_method_of_MatrixBase_to_cast_numeric_types_explicitly)
EIGEN_STATIC_ASSERT((ei_functor_allows_mixing_real_and_complex<BinaryOp>::ret
? int(ei_is_same_type<typename Lhs::RealScalar, typename Rhs::RealScalar>::ret)
: int(ei_is_same_type<typename Lhs::Scalar, typename Rhs::Scalar>::ret)),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
// require the sizes to match
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs)
ei_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols());
}
inline int rows() const { return m_lhs.rows(); }
inline int cols() const { return m_lhs.cols(); }
EIGEN_STRONG_INLINE int rows() const { return m_lhs.rows(); }
EIGEN_STRONG_INLINE int cols() const { return m_lhs.cols(); }
inline const Scalar coeff(int row, int col) const
EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const
{
return m_functor(m_lhs.coeff(row, col), m_rhs.coeff(row, col));
}
template<int LoadMode>
inline PacketScalar packet(int row, int col) const
EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const
{
return m_functor.packetOp(m_lhs.template packet<LoadMode>(row, col), m_rhs.template packet<LoadMode>(row, col));
}
inline const Scalar coeff(int index) const
EIGEN_STRONG_INLINE const Scalar coeff(int index) const
{
return m_functor(m_lhs.coeff(index), m_rhs.coeff(index));
}
template<int LoadMode>
inline PacketScalar packet(int index) const
EIGEN_STRONG_INLINE PacketScalar packet(int index) const
{
return m_functor.packetOp(m_lhs.template packet<LoadMode>(index), m_rhs.template packet<LoadMode>(index));
}
@@ -144,7 +146,7 @@ class CwiseBinaryOp : ei_no_assignment_operator,
*/
template<typename Derived>
template<typename OtherDerived>
inline const CwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>,
EIGEN_STRONG_INLINE const CwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>,
Derived, OtherDerived>
MatrixBase<Derived>::operator-(const MatrixBase<OtherDerived> &other) const
{
@@ -158,7 +160,7 @@ MatrixBase<Derived>::operator-(const MatrixBase<OtherDerived> &other) const
*/
template<typename Derived>
template<typename OtherDerived>
inline Derived &
EIGEN_STRONG_INLINE Derived &
MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
{
return *this = *this - other;
@@ -174,7 +176,7 @@ MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
*/
template<typename Derived>
template<typename OtherDerived>
inline const CwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
EIGEN_STRONG_INLINE const CwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
MatrixBase<Derived>::operator+(const MatrixBase<OtherDerived> &other) const
{
return CwiseBinaryOp<ei_scalar_sum_op<Scalar>, Derived, OtherDerived>(derived(), other.derived());
@@ -186,7 +188,7 @@ MatrixBase<Derived>::operator+(const MatrixBase<OtherDerived> &other) const
*/
template<typename Derived>
template<typename OtherDerived>
inline Derived &
EIGEN_STRONG_INLINE Derived &
MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
{
return *this = *this + other;
@@ -201,10 +203,10 @@ MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
*/
template<typename ExpressionType>
template<typename OtherDerived>
inline const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_product_op)
EIGEN_STRONG_INLINE const EIGEN_CWISE_PRODUCT_RETURN_TYPE
Cwise<ExpressionType>::operator*(const MatrixBase<OtherDerived> &other) const
{
return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_product_op)(_expression(), other.derived());
return EIGEN_CWISE_PRODUCT_RETURN_TYPE(_expression(), other.derived());
}
/** \returns an expression of the coefficient-wise quotient of *this and \a other
@@ -216,7 +218,7 @@ Cwise<ExpressionType>::operator*(const MatrixBase<OtherDerived> &other) const
*/
template<typename ExpressionType>
template<typename OtherDerived>
inline const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)
EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)
Cwise<ExpressionType>::operator/(const MatrixBase<OtherDerived> &other) const
{
return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)(_expression(), other.derived());
@@ -231,7 +233,7 @@ Cwise<ExpressionType>::operator/(const MatrixBase<OtherDerived> &other) const
*/
template<typename ExpressionType>
template<typename OtherDerived>
inline const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)
EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)
Cwise<ExpressionType>::min(const MatrixBase<OtherDerived> &other) const
{
return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)(_expression(), other.derived());
@@ -246,7 +248,7 @@ Cwise<ExpressionType>::min(const MatrixBase<OtherDerived> &other) const
*/
template<typename ExpressionType>
template<typename OtherDerived>
inline const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)
EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)
Cwise<ExpressionType>::max(const MatrixBase<OtherDerived> &other) const
{
return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)(_expression(), other.derived());
@@ -267,7 +269,7 @@ Cwise<ExpressionType>::max(const MatrixBase<OtherDerived> &other) const
*/
template<typename Derived>
template<typename CustomBinaryOp, typename OtherDerived>
inline const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>
EIGEN_STRONG_INLINE const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>
MatrixBase<Derived>::binaryExpr(const MatrixBase<OtherDerived> &other, const CustomBinaryOp& func) const
{
return CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>(derived(), other.derived(), func);

View File

@@ -75,21 +75,21 @@ class CwiseNullaryOp : ei_no_assignment_operator,
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
}
int rows() const { return m_rows.value(); }
int cols() const { return m_cols.value(); }
EIGEN_STRONG_INLINE int rows() const { return m_rows.value(); }
EIGEN_STRONG_INLINE int cols() const { return m_cols.value(); }
const Scalar coeff(int rows, int cols) const
EIGEN_STRONG_INLINE const Scalar coeff(int rows, int cols) const
{
return m_functor(rows, cols);
}
template<int LoadMode>
PacketScalar packet(int, int) const
EIGEN_STRONG_INLINE PacketScalar packet(int, int) const
{
return m_functor.packetOp();
}
const Scalar coeff(int index) const
EIGEN_STRONG_INLINE const Scalar coeff(int index) const
{
if(RowsAtCompileTime == 1)
return m_functor(0, index);
@@ -98,7 +98,7 @@ class CwiseNullaryOp : ei_no_assignment_operator,
}
template<int LoadMode>
PacketScalar packet(int) const
EIGEN_STRONG_INLINE PacketScalar packet(int) const
{
return m_functor.packetOp();
}
@@ -125,7 +125,7 @@ class CwiseNullaryOp : ei_no_assignment_operator,
*/
template<typename Derived>
template<typename CustomNullaryOp>
const CwiseNullaryOp<CustomNullaryOp, Derived>
EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
MatrixBase<Derived>::NullaryExpr(int rows, int cols, const CustomNullaryOp& func)
{
return CwiseNullaryOp<CustomNullaryOp, Derived>(rows, cols, func);
@@ -148,7 +148,7 @@ MatrixBase<Derived>::NullaryExpr(int rows, int cols, const CustomNullaryOp& func
*/
template<typename Derived>
template<typename CustomNullaryOp>
const CwiseNullaryOp<CustomNullaryOp, Derived>
EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
MatrixBase<Derived>::NullaryExpr(int size, const CustomNullaryOp& func)
{
ei_assert(IsVectorAtCompileTime);
@@ -167,7 +167,7 @@ MatrixBase<Derived>::NullaryExpr(int size, const CustomNullaryOp& func)
*/
template<typename Derived>
template<typename CustomNullaryOp>
const CwiseNullaryOp<CustomNullaryOp, Derived>
EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
MatrixBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
{
return CwiseNullaryOp<CustomNullaryOp, Derived>(RowsAtCompileTime, ColsAtCompileTime, func);
@@ -187,7 +187,7 @@ MatrixBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
* \sa class CwiseNullaryOp
*/
template<typename Derived>
const typename MatrixBase<Derived>::ConstantReturnType
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Constant(int rows, int cols, const Scalar& value)
{
return NullaryExpr(rows, cols, ei_scalar_constant_op<Scalar>(value));
@@ -209,7 +209,7 @@ MatrixBase<Derived>::Constant(int rows, int cols, const Scalar& value)
* \sa class CwiseNullaryOp
*/
template<typename Derived>
const typename MatrixBase<Derived>::ConstantReturnType
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Constant(int size, const Scalar& value)
{
return NullaryExpr(size, ei_scalar_constant_op<Scalar>(value));
@@ -225,7 +225,7 @@ MatrixBase<Derived>::Constant(int size, const Scalar& value)
* \sa class CwiseNullaryOp
*/
template<typename Derived>
const typename MatrixBase<Derived>::ConstantReturnType
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Constant(const Scalar& value)
{
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
@@ -236,8 +236,8 @@ template<typename Derived>
bool MatrixBase<Derived>::isApproxToConstant
(const Scalar& value, RealScalar prec) const
{
for(int j = 0; j < cols(); j++)
for(int i = 0; i < rows(); i++)
for(int j = 0; j < cols(); ++j)
for(int i = 0; i < rows(); ++i)
if(!ei_isApprox(coeff(i, j), value, prec))
return false;
return true;
@@ -248,7 +248,7 @@ bool MatrixBase<Derived>::isApproxToConstant
* \sa class CwiseNullaryOp, Zero(), Ones()
*/
template<typename Derived>
Derived& MatrixBase<Derived>::setConstant(const Scalar& value)
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setConstant(const Scalar& value)
{
return derived() = Constant(rows(), cols(), value);
}
@@ -272,7 +272,7 @@ Derived& MatrixBase<Derived>::setConstant(const Scalar& value)
* \sa Zero(), Zero(int)
*/
template<typename Derived>
const typename MatrixBase<Derived>::ConstantReturnType
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Zero(int rows, int cols)
{
return Constant(rows, cols, Scalar(0));
@@ -295,7 +295,7 @@ MatrixBase<Derived>::Zero(int rows, int cols)
* \sa Zero(), Zero(int,int)
*/
template<typename Derived>
const typename MatrixBase<Derived>::ConstantReturnType
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Zero(int size)
{
return Constant(size, Scalar(0));
@@ -312,7 +312,7 @@ MatrixBase<Derived>::Zero(int size)
* \sa Zero(int), Zero(int,int)
*/
template<typename Derived>
const typename MatrixBase<Derived>::ConstantReturnType
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Zero()
{
return Constant(Scalar(0));
@@ -327,11 +327,10 @@ MatrixBase<Derived>::Zero()
* \sa class CwiseNullaryOp, Zero()
*/
template<typename Derived>
bool MatrixBase<Derived>::isZero
(RealScalar prec) const
bool MatrixBase<Derived>::isZero(RealScalar prec) const
{
for(int j = 0; j < cols(); j++)
for(int i = 0; i < rows(); i++)
for(int j = 0; j < cols(); ++j)
for(int i = 0; i < rows(); ++i)
if(!ei_isMuchSmallerThan(coeff(i, j), static_cast<Scalar>(1), prec))
return false;
return true;
@@ -345,7 +344,7 @@ bool MatrixBase<Derived>::isZero
* \sa class CwiseNullaryOp, Zero()
*/
template<typename Derived>
Derived& MatrixBase<Derived>::setZero()
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setZero()
{
return setConstant(Scalar(0));
}
@@ -369,7 +368,7 @@ Derived& MatrixBase<Derived>::setZero()
* \sa Ones(), Ones(int), isOnes(), class Ones
*/
template<typename Derived>
const typename MatrixBase<Derived>::ConstantReturnType
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Ones(int rows, int cols)
{
return Constant(rows, cols, Scalar(1));
@@ -392,7 +391,7 @@ MatrixBase<Derived>::Ones(int rows, int cols)
* \sa Ones(), Ones(int,int), isOnes(), class Ones
*/
template<typename Derived>
const typename MatrixBase<Derived>::ConstantReturnType
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Ones(int size)
{
return Constant(size, Scalar(1));
@@ -409,7 +408,7 @@ MatrixBase<Derived>::Ones(int size)
* \sa Ones(int), Ones(int,int), isOnes(), class Ones
*/
template<typename Derived>
const typename MatrixBase<Derived>::ConstantReturnType
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType
MatrixBase<Derived>::Ones()
{
return Constant(Scalar(1));
@@ -438,7 +437,7 @@ bool MatrixBase<Derived>::isOnes
* \sa class CwiseNullaryOp, Ones()
*/
template<typename Derived>
Derived& MatrixBase<Derived>::setOnes()
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setOnes()
{
return setConstant(Scalar(1));
}
@@ -462,7 +461,7 @@ Derived& MatrixBase<Derived>::setOnes()
* \sa Identity(), setIdentity(), isIdentity()
*/
template<typename Derived>
inline const typename MatrixBase<Derived>::IdentityReturnType
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
MatrixBase<Derived>::Identity(int rows, int cols)
{
return NullaryExpr(rows, cols, ei_scalar_identity_op<Scalar>());
@@ -479,7 +478,7 @@ MatrixBase<Derived>::Identity(int rows, int cols)
* \sa Identity(int,int), setIdentity(), isIdentity()
*/
template<typename Derived>
inline const typename MatrixBase<Derived>::IdentityReturnType
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
MatrixBase<Derived>::Identity()
{
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
@@ -499,9 +498,9 @@ template<typename Derived>
bool MatrixBase<Derived>::isIdentity
(RealScalar prec) const
{
for(int j = 0; j < cols(); j++)
for(int j = 0; j < cols(); ++j)
{
for(int i = 0; i < rows(); i++)
for(int i = 0; i < rows(); ++i)
{
if(i == j)
{
@@ -521,7 +520,7 @@ bool MatrixBase<Derived>::isIdentity
template<typename Derived, bool Big = (Derived::SizeAtCompileTime>=16)>
struct ei_setIdentity_impl
{
static inline Derived& run(Derived& m)
static EIGEN_STRONG_INLINE Derived& run(Derived& m)
{
return m = Derived::Identity(m.rows(), m.cols());
}
@@ -530,11 +529,11 @@ struct ei_setIdentity_impl
template<typename Derived>
struct ei_setIdentity_impl<Derived, true>
{
static inline Derived& run(Derived& m)
static EIGEN_STRONG_INLINE Derived& run(Derived& m)
{
m.setZero();
const int size = std::min(m.rows(), m.cols());
for(int i = 0; i < size; i++) m.coeffRef(i,i) = typename Derived::Scalar(1);
for(int i = 0; i < size; ++i) m.coeffRef(i,i) = typename Derived::Scalar(1);
return m;
}
};
@@ -547,7 +546,7 @@ struct ei_setIdentity_impl<Derived, true>
* \sa class CwiseNullaryOp, Identity(), Identity(int,int), isIdentity()
*/
template<typename Derived>
inline Derived& MatrixBase<Derived>::setIdentity()
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
{
return ei_setIdentity_impl<Derived>::run(derived());
}
@@ -559,7 +558,7 @@ inline Derived& MatrixBase<Derived>::setIdentity()
* \sa MatrixBase::Unit(int), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(int size, int i)
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(int size, int i)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return BasisReturnType(SquareMatrixType::Identity(size,size), i);
@@ -574,7 +573,7 @@ const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(in
* \sa MatrixBase::Unit(int,int), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(int i)
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(int i)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return BasisReturnType(SquareMatrixType::Identity(),i);
@@ -587,7 +586,7 @@ const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(in
* \sa MatrixBase::Unit(int,int), MatrixBase::Unit(int), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitX()
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitX()
{ return Derived::Unit(0); }
/** \returns an expression of the Y axis unit vector (0,1{,0}^*)
@@ -597,7 +596,7 @@ const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitX()
* \sa MatrixBase::Unit(int,int), MatrixBase::Unit(int), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitY()
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitY()
{ return Derived::Unit(1); }
/** \returns an expression of the Z axis unit vector (0,0,1{,0}^*)
@@ -607,7 +606,7 @@ const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitY()
* \sa MatrixBase::Unit(int,int), MatrixBase::Unit(int), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitZ()
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitZ()
{ return Derived::Unit(2); }
/** \returns an expression of the W axis unit vector (0,0,0,1)
@@ -617,7 +616,7 @@ const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitZ()
* \sa MatrixBase::Unit(int,int), MatrixBase::Unit(int), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW()
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW()
{ return Derived::Unit(3); }
#endif // EIGEN_CWISE_NULLARY_OP_H

View File

@@ -74,27 +74,27 @@ class CwiseUnaryOp : ei_no_assignment_operator,
inline CwiseUnaryOp(const MatrixType& mat, const UnaryOp& func = UnaryOp())
: m_matrix(mat), m_functor(func) {}
inline int rows() const { return m_matrix.rows(); }
inline int cols() const { return m_matrix.cols(); }
EIGEN_STRONG_INLINE int rows() const { return m_matrix.rows(); }
EIGEN_STRONG_INLINE int cols() const { return m_matrix.cols(); }
inline const Scalar coeff(int row, int col) const
EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const
{
return m_functor(m_matrix.coeff(row, col));
}
template<int LoadMode>
inline PacketScalar packet(int row, int col) const
EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const
{
return m_functor.packetOp(m_matrix.template packet<LoadMode>(row, col));
}
inline const Scalar coeff(int index) const
EIGEN_STRONG_INLINE const Scalar coeff(int index) const
{
return m_functor(m_matrix.coeff(index));
}
template<int LoadMode>
inline PacketScalar packet(int index) const
EIGEN_STRONG_INLINE PacketScalar packet(int index) const
{
return m_functor.packetOp(m_matrix.template packet<LoadMode>(index));
}
@@ -119,7 +119,7 @@ class CwiseUnaryOp : ei_no_assignment_operator,
*/
template<typename Derived>
template<typename CustomUnaryOp>
inline const CwiseUnaryOp<CustomUnaryOp, Derived>
EIGEN_STRONG_INLINE const CwiseUnaryOp<CustomUnaryOp, Derived>
MatrixBase<Derived>::unaryExpr(const CustomUnaryOp& func) const
{
return CwiseUnaryOp<CustomUnaryOp, Derived>(derived(), func);
@@ -128,7 +128,7 @@ MatrixBase<Derived>::unaryExpr(const CustomUnaryOp& func) const
/** \returns an expression of the opposite of \c *this
*/
template<typename Derived>
inline const CwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived>
EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived>
MatrixBase<Derived>::operator-() const
{
return derived();
@@ -142,7 +142,7 @@ MatrixBase<Derived>::operator-() const
* \sa abs2()
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs_op)
EIGEN_STRONG_INLINE const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs_op)
Cwise<ExpressionType>::abs() const
{
return _expression();
@@ -156,7 +156,7 @@ Cwise<ExpressionType>::abs() const
* \sa abs(), square()
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs2_op)
EIGEN_STRONG_INLINE const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs2_op)
Cwise<ExpressionType>::abs2() const
{
return _expression();
@@ -166,7 +166,7 @@ Cwise<ExpressionType>::abs2() const
*
* \sa adjoint() */
template<typename Derived>
inline typename MatrixBase<Derived>::ConjugateReturnType
EIGEN_STRONG_INLINE typename MatrixBase<Derived>::ConjugateReturnType
MatrixBase<Derived>::conjugate() const
{
return ConjugateReturnType(derived());
@@ -176,14 +176,14 @@ MatrixBase<Derived>::conjugate() const
*
* \sa imag() */
template<typename Derived>
inline const typename MatrixBase<Derived>::RealReturnType
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::RealReturnType
MatrixBase<Derived>::real() const { return derived(); }
/** \returns an expression of the imaginary part of \c *this.
*
* \sa real() */
template<typename Derived>
inline const typename MatrixBase<Derived>::ImagReturnType
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ImagReturnType
MatrixBase<Derived>::imag() const { return derived(); }
/** \returns an expression of *this with the \a Scalar type casted to
@@ -195,7 +195,7 @@ MatrixBase<Derived>::imag() const { return derived(); }
*/
template<typename Derived>
template<typename NewType>
inline const CwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived>
EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived>
MatrixBase<Derived>::cast() const
{
return derived();
@@ -203,7 +203,7 @@ MatrixBase<Derived>::cast() const
/** \relates MatrixBase */
template<typename Derived>
inline const typename MatrixBase<Derived>::ScalarMultipleReturnType
EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ScalarMultipleReturnType
MatrixBase<Derived>::operator*(const Scalar& scalar) const
{
return CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, Derived>
@@ -212,7 +212,7 @@ MatrixBase<Derived>::operator*(const Scalar& scalar) const
/** \relates MatrixBase */
template<typename Derived>
inline const CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived>
EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived>
MatrixBase<Derived>::operator/(const Scalar& scalar) const
{
return CwiseUnaryOp<ei_scalar_quotient1_op<Scalar>, Derived>
@@ -220,14 +220,14 @@ MatrixBase<Derived>::operator/(const Scalar& scalar) const
}
template<typename Derived>
inline Derived&
EIGEN_STRONG_INLINE Derived&
MatrixBase<Derived>::operator*=(const Scalar& other)
{
return *this = *this * other;
}
template<typename Derived>
inline Derived&
EIGEN_STRONG_INLINE Derived&
MatrixBase<Derived>::operator/=(const Scalar& other)
{
return *this = *this / other;

View File

@@ -62,10 +62,19 @@ class DiagonalMatrix : ei_no_assignment_operator,
EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalMatrix)
// needed to evaluate a DiagonalMatrix<Xpr> to a DiagonalMatrix<NestByValue<Vector> >
template<typename OtherCoeffsVectorType>
inline DiagonalMatrix(const DiagonalMatrix<OtherCoeffsVectorType>& other) : m_coeffs(other.diagonal())
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(CoeffsVectorType);
EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherCoeffsVectorType);
ei_assert(m_coeffs.size() > 0);
}
inline DiagonalMatrix(const CoeffsVectorType& coeffs) : m_coeffs(coeffs)
{
ei_assert(CoeffsVectorType::IsVectorAtCompileTime
&& coeffs.size() > 0);
EIGEN_STATIC_ASSERT_VECTOR_ONLY(CoeffsVectorType);
ei_assert(coeffs.size() > 0);
}
inline int rows() const { return m_coeffs.size(); }
@@ -76,6 +85,8 @@ class DiagonalMatrix : ei_no_assignment_operator,
return row == col ? m_coeffs.coeff(row) : static_cast<Scalar>(0);
}
inline const CoeffsVectorType& diagonal() const { return m_coeffs; }
protected:
const typename CoeffsVectorType::Nested m_coeffs;
};
@@ -112,13 +123,13 @@ bool MatrixBase<Derived>::isDiagonal
{
if(cols() != rows()) return false;
RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1);
for(int j = 0; j < cols(); j++)
for(int j = 0; j < cols(); ++j)
{
RealScalar absOnDiagonal = ei_abs(coeff(j,j));
if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal;
}
for(int j = 0; j < cols(); j++)
for(int i = 0; i < j; i++)
for(int j = 0; j < cols(); ++j)
for(int i = 0; i < j; ++i)
{
if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false;
if(!ei_isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false;

View File

@@ -26,12 +26,31 @@
#ifndef EIGEN_DIAGONALPRODUCT_H
#define EIGEN_DIAGONALPRODUCT_H
/** \internal Specialization of ei_nested for DiagonalMatrix.
* Unlike ei_nested, if the argument is a DiagonalMatrix and if it must be evaluated,
* then it evaluated to a DiagonalMatrix having its own argument evaluated.
*/
template<typename T, int N> struct ei_nested_diagonal : ei_nested<T,N> {};
template<typename T, int N> struct ei_nested_diagonal<DiagonalMatrix<T>,N >
: ei_nested<DiagonalMatrix<T>, N, DiagonalMatrix<NestByValue<typename ei_plain_matrix_type<T>::type> > >
{};
// specialization of ProductReturnType
template<typename Lhs, typename Rhs>
struct ProductReturnType<Lhs,Rhs,DiagonalProduct>
{
typedef typename ei_nested_diagonal<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
typedef typename ei_nested_diagonal<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
typedef Product<LhsNested, RhsNested, DiagonalProduct> Type;
};
template<typename LhsNested, typename RhsNested>
struct ei_traits<Product<LhsNested, RhsNested, DiagonalProduct> >
{
// clean the nested types:
typedef typename ei_unconst<typename ei_unref<LhsNested>::type>::type _LhsNested;
typedef typename ei_unconst<typename ei_unref<RhsNested>::type>::type _RhsNested;
typedef typename ei_cleantype<LhsNested>::type _LhsNested;
typedef typename ei_cleantype<RhsNested>::type _RhsNested;
typedef typename _LhsNested::Scalar Scalar;
enum {

View File

@@ -156,7 +156,7 @@ struct ei_dot_impl<Derived1, Derived2, NoVectorization, NoUnrolling>
ei_assert(v1.size()>0 && "you are using a non initialized vector");
Scalar res;
res = v1.coeff(0) * ei_conj(v2.coeff(0));
for(int i = 1; i < v1.size(); i++)
for(int i = 1; i < v1.size(); ++i)
res += v1.coeff(i) * ei_conj(v2.coeff(i));
return res;
}
@@ -211,7 +211,7 @@ struct ei_dot_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>
}
// do the remainder of the vector
for(int index = alignedSize; index < size; index++)
for(int index = alignedSize; index < size; ++index)
{
res += v1.coeff(index) * v2.coeff(index);
}
@@ -266,6 +266,9 @@ MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
EIGEN_STATIC_ASSERT_VECTOR_ONLY(_Nested)
EIGEN_STATIC_ASSERT_VECTOR_ONLY(_OtherNested)
EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(_Nested,_OtherNested)
EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename OtherDerived::Scalar>::ret),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
ei_assert(size() == other.size());
return ei_dot_impl<_Nested, _OtherNested>::run(derived(), other.derived());
@@ -318,7 +321,7 @@ inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real MatrixBase<
* \sa norm(), normalize()
*/
template<typename Derived>
inline const typename MatrixBase<Derived>::EvalType
inline const typename MatrixBase<Derived>::PlainMatrixType
MatrixBase<Derived>::normalized() const
{
typedef typename ei_nested<Derived>::type Nested;
@@ -370,11 +373,11 @@ template<typename Derived>
bool MatrixBase<Derived>::isUnitary(RealScalar prec) const
{
typename Derived::Nested nested(derived());
for(int i = 0; i < cols(); i++)
for(int i = 0; i < cols(); ++i)
{
if(!ei_isApprox(nested.col(i).squaredNorm(), static_cast<Scalar>(1), prec))
return false;
for(int j = 0; j < i; j++)
for(int j = 0; j < i; ++j)
if(!ei_isMuchSmallerThan(nested.col(i).dot(nested.col(j)), static_cast<Scalar>(1), prec))
return false;
}

View File

@@ -33,9 +33,9 @@
* \sa class CwiseBinaryOp, MatrixBase::operator+, class PartialRedux, MatrixBase::sum()
*/
template<typename Scalar> struct ei_scalar_sum_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
template<typename PacketScalar>
inline const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
{ return ei_padd(a,b); }
};
template<typename Scalar>
@@ -52,9 +52,9 @@ struct ei_functor_traits<ei_scalar_sum_op<Scalar> > {
* \sa class CwiseBinaryOp, Cwise::operator*(), class PartialRedux, MatrixBase::redux()
*/
template<typename Scalar> struct ei_scalar_product_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; }
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; }
template<typename PacketScalar>
inline const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
{ return ei_pmul(a,b); }
};
template<typename Scalar>
@@ -71,9 +71,9 @@ struct ei_functor_traits<ei_scalar_product_op<Scalar> > {
* \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class PartialRedux, MatrixBase::minCoeff()
*/
template<typename Scalar> struct ei_scalar_min_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::min(a, b); }
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::min(a, b); }
template<typename PacketScalar>
inline const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
{ return ei_pmin(a,b); }
};
template<typename Scalar>
@@ -90,9 +90,9 @@ struct ei_functor_traits<ei_scalar_min_op<Scalar> > {
* \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class PartialRedux, MatrixBase::maxCoeff()
*/
template<typename Scalar> struct ei_scalar_max_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::max(a, b); }
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::max(a, b); }
template<typename PacketScalar>
inline const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
{ return ei_pmax(a,b); }
};
template<typename Scalar>
@@ -112,9 +112,9 @@ struct ei_functor_traits<ei_scalar_max_op<Scalar> > {
* \sa class CwiseBinaryOp, MatrixBase::operator-
*/
template<typename Scalar> struct ei_scalar_difference_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; }
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; }
template<typename PacketScalar>
inline const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
{ return ei_psub(a,b); }
};
template<typename Scalar>
@@ -131,9 +131,9 @@ struct ei_functor_traits<ei_scalar_difference_op<Scalar> > {
* \sa class CwiseBinaryOp, Cwise::operator/()
*/
template<typename Scalar> struct ei_scalar_quotient_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; }
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; }
template<typename PacketScalar>
inline const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const
{ return ei_pdiv(a,b); }
};
template<typename Scalar>
@@ -155,7 +155,7 @@ struct ei_functor_traits<ei_scalar_quotient_op<Scalar> > {
* \sa class CwiseUnaryOp, MatrixBase::operator-
*/
template<typename Scalar> struct ei_scalar_opposite_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a) const { return -a; }
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_opposite_op<Scalar> >
@@ -168,7 +168,7 @@ struct ei_functor_traits<ei_scalar_opposite_op<Scalar> >
*/
template<typename Scalar> struct ei_scalar_abs_op EIGEN_EMPTY_STRUCT {
typedef typename NumTraits<Scalar>::Real result_type;
inline const result_type operator() (const Scalar& a) const { return ei_abs(a); }
EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs(a); }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_abs_op<Scalar> >
@@ -186,9 +186,9 @@ struct ei_functor_traits<ei_scalar_abs_op<Scalar> >
*/
template<typename Scalar> struct ei_scalar_abs2_op EIGEN_EMPTY_STRUCT {
typedef typename NumTraits<Scalar>::Real result_type;
inline const result_type operator() (const Scalar& a) const { return ei_abs2(a); }
EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs2(a); }
template<typename PacketScalar>
inline const PacketScalar packetOp(const PacketScalar& a) const
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
{ return ei_pmul(a,a); }
};
template<typename Scalar>
@@ -201,9 +201,9 @@ struct ei_functor_traits<ei_scalar_abs2_op<Scalar> >
* \sa class CwiseUnaryOp, MatrixBase::conjugate()
*/
template<typename Scalar> struct ei_scalar_conjugate_op EIGEN_EMPTY_STRUCT {
inline const Scalar operator() (const Scalar& a) const { return ei_conj(a); }
EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return ei_conj(a); }
template<typename PacketScalar>
inline const PacketScalar packetOp(const PacketScalar& a) const { return a; }
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const { return a; }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_conjugate_op<Scalar> >
@@ -222,7 +222,7 @@ struct ei_functor_traits<ei_scalar_conjugate_op<Scalar> >
template<typename Scalar, typename NewType>
struct ei_scalar_cast_op EIGEN_EMPTY_STRUCT {
typedef NewType result_type;
inline const NewType operator() (const Scalar& a) const { return static_cast<NewType>(a); }
EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return static_cast<NewType>(a); }
};
template<typename Scalar, typename NewType>
struct ei_functor_traits<ei_scalar_cast_op<Scalar,NewType> >
@@ -236,7 +236,7 @@ struct ei_functor_traits<ei_scalar_cast_op<Scalar,NewType> >
template<typename Scalar>
struct ei_scalar_real_op EIGEN_EMPTY_STRUCT {
typedef typename NumTraits<Scalar>::Real result_type;
inline result_type operator() (const Scalar& a) const { return ei_real(a); }
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_real(a); }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_real_op<Scalar> >
@@ -250,7 +250,7 @@ struct ei_functor_traits<ei_scalar_real_op<Scalar> >
template<typename Scalar>
struct ei_scalar_imag_op EIGEN_EMPTY_STRUCT {
typedef typename NumTraits<Scalar>::Real result_type;
inline result_type operator() (const Scalar& a) const { return ei_imag(a); }
EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_imag(a); }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_imag_op<Scalar> >
@@ -273,10 +273,10 @@ template<typename Scalar>
struct ei_scalar_multiple_op {
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
// FIXME default copy constructors seems bugged with std::complex<>
inline ei_scalar_multiple_op(const ei_scalar_multiple_op& other) : m_other(other.m_other) { }
inline ei_scalar_multiple_op(const Scalar& other) : m_other(other) { }
inline Scalar operator() (const Scalar& a) const { return a * m_other; }
inline const PacketScalar packetOp(const PacketScalar& a) const
EIGEN_STRONG_INLINE ei_scalar_multiple_op(const ei_scalar_multiple_op& other) : m_other(other.m_other) { }
EIGEN_STRONG_INLINE ei_scalar_multiple_op(const Scalar& other) : m_other(other) { }
EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
{ return ei_pmul(a, ei_pset1(m_other)); }
const Scalar m_other;
};
@@ -288,10 +288,10 @@ template<typename Scalar, bool HasFloatingPoint>
struct ei_scalar_quotient1_impl {
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
// FIXME default copy constructors seems bugged with std::complex<>
inline ei_scalar_quotient1_impl(const ei_scalar_quotient1_impl& other) : m_other(other.m_other) { }
inline ei_scalar_quotient1_impl(const Scalar& other) : m_other(static_cast<Scalar>(1) / other) {}
inline Scalar operator() (const Scalar& a) const { return a * m_other; }
inline const PacketScalar packetOp(const PacketScalar& a) const
EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const ei_scalar_quotient1_impl& other) : m_other(other.m_other) { }
EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const Scalar& other) : m_other(static_cast<Scalar>(1) / other) {}
EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
{ return ei_pmul(a, ei_pset1(m_other)); }
const Scalar m_other;
};
@@ -302,9 +302,9 @@ struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,true> >
template<typename Scalar>
struct ei_scalar_quotient1_impl<Scalar,false> {
// FIXME default copy constructors seems bugged with std::complex<>
inline ei_scalar_quotient1_impl(const ei_scalar_quotient1_impl& other) : m_other(other.m_other) { }
inline ei_scalar_quotient1_impl(const Scalar& other) : m_other(other) {}
inline Scalar operator() (const Scalar& a) const { return a / m_other; }
EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const ei_scalar_quotient1_impl& other) : m_other(other.m_other) { }
EIGEN_STRONG_INLINE ei_scalar_quotient1_impl(const Scalar& other) : m_other(other) {}
EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; }
const Scalar m_other;
};
template<typename Scalar>
@@ -321,7 +321,7 @@ struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,false> >
*/
template<typename Scalar>
struct ei_scalar_quotient1_op : ei_scalar_quotient1_impl<Scalar, NumTraits<Scalar>::HasFloatingPoint > {
inline ei_scalar_quotient1_op(const Scalar& other)
EIGEN_STRONG_INLINE ei_scalar_quotient1_op(const Scalar& other)
: ei_scalar_quotient1_impl<Scalar, NumTraits<Scalar>::HasFloatingPoint >(other) {}
};
@@ -330,10 +330,10 @@ struct ei_scalar_quotient1_op : ei_scalar_quotient1_impl<Scalar, NumTraits<Scala
template<typename Scalar>
struct ei_scalar_constant_op {
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
inline ei_scalar_constant_op(const ei_scalar_constant_op& other) : m_other(other.m_other) { }
inline ei_scalar_constant_op(const Scalar& other) : m_other(other) { }
inline const Scalar operator() (int, int = 0) const { return m_other; }
inline const PacketScalar packetOp() const { return ei_pset1(m_other); }
EIGEN_STRONG_INLINE ei_scalar_constant_op(const ei_scalar_constant_op& other) : m_other(other.m_other) { }
EIGEN_STRONG_INLINE ei_scalar_constant_op(const Scalar& other) : m_other(other) { }
EIGEN_STRONG_INLINE const Scalar operator() (int, int = 0) const { return m_other; }
EIGEN_STRONG_INLINE const PacketScalar packetOp() const { return ei_pset1(m_other); }
const Scalar m_other;
};
template<typename Scalar>
@@ -341,18 +341,22 @@ struct ei_functor_traits<ei_scalar_constant_op<Scalar> >
{ enum { Cost = 1, PacketAccess = ei_packet_traits<Scalar>::size>1, IsRepeatable = true }; };
template<typename Scalar> struct ei_scalar_identity_op EIGEN_EMPTY_STRUCT {
inline ei_scalar_identity_op(void) {}
inline const Scalar operator() (int row, int col) const { return row==col ? Scalar(1) : Scalar(0); }
EIGEN_STRONG_INLINE ei_scalar_identity_op(void) {}
EIGEN_STRONG_INLINE const Scalar operator() (int row, int col) const { return row==col ? Scalar(1) : Scalar(0); }
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_identity_op<Scalar> >
{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; };
// FIXME quick hack:
// all functors allow linear access, except ei_scalar_identity_op. So we fix here a quick meta
// to indicate whether a functor allows linear access, just always answering 'yes' except for
// ei_scalar_identity_op.
template<typename Functor> struct ei_functor_has_linear_access { enum { ret = 1 }; };
template<typename Scalar> struct ei_functor_has_linear_access<ei_scalar_identity_op<Scalar> > { enum { ret = 0 }; };
// in CwiseBinaryOp, we require the Lhs and Rhs to have the same scalar type, except for multiplication
// where we only require them to have the same _real_ scalar type so one may multiply, say, float by complex<float>.
template<typename Functor> struct ei_functor_allows_mixing_real_and_complex { enum { ret = 0 }; };
template<typename Scalar> struct ei_functor_allows_mixing_real_and_complex<ei_scalar_product_op<Scalar> > { enum { ret = 1 }; };
#endif // EIGEN_FUNCTORS_H

View File

@@ -202,7 +202,7 @@ struct ei_fuzzy_selector<Derived,OtherDerived,false>
ei_assert(self.rows() == other.rows() && self.cols() == other.cols());
typename Derived::Nested nested(self);
typename OtherDerived::Nested otherNested(other);
for(int i = 0; i < self.cols(); i++)
for(int i = 0; i < self.cols(); ++i)
if((nested.col(i) - otherNested.col(i)).squaredNorm()
> std::min(nested.col(i).squaredNorm(), otherNested.col(i).squaredNorm()) * prec * prec)
return false;
@@ -211,7 +211,7 @@ struct ei_fuzzy_selector<Derived,OtherDerived,false>
static bool isMuchSmallerThan(const Derived& self, const RealScalar& other, RealScalar prec)
{
typename Derived::Nested nested(self);
for(int i = 0; i < self.cols(); i++)
for(int i = 0; i < self.cols(); ++i)
if(nested.col(i).squaredNorm() > ei_abs2(other * prec))
return false;
return true;
@@ -222,7 +222,7 @@ struct ei_fuzzy_selector<Derived,OtherDerived,false>
ei_assert(self.rows() == other.rows() && self.cols() == other.cols());
typename Derived::Nested nested(self);
typename OtherDerived::Nested otherNested(other);
for(int i = 0; i < self.cols(); i++)
for(int i = 0; i < self.cols(); ++i)
if(nested.col(i).squaredNorm() > otherNested.col(i).squaredNorm() * prec * prec)
return false;
return true;

View File

@@ -6,12 +6,12 @@
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -19,7 +19,7 @@
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
@@ -58,7 +58,7 @@ struct IOFormat
coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags)
{
rowSpacer = "";
int i=matSuffix.length()-1;
int i = int(matSuffix.length())-1;
while (i>=0 && matSuffix[i]!='\n')
{
rowSpacer += ' ';
@@ -81,7 +81,7 @@ struct IOFormat
* This class represents an expression with stream operators controlled by a given IOFormat.
* It is the return type of MatrixBase::format()
* and most of the time this is the only way it is used.
*
*
* See class IOFormat for some examples.
*
* \sa MatrixBase::format(), class IOFormat
@@ -122,32 +122,33 @@ MatrixBase<Derived>::format(const IOFormat& fmt) const
/** \internal
* print the matrix \a _m to the output stream \a s using the output format \a fmt */
template<typename Derived>
std::ostream & ei_print_matrix(std::ostream & s, const MatrixBase<Derived> & _m, const IOFormat& fmt)
std::ostream & ei_print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt)
{
const typename Derived::Nested m = _m;
int width = 0;
if (fmt.flags & AlignCols)
{
// compute the largest width
for(int j = 1; j < m.cols(); j++)
for(int i = 0; i < m.rows(); i++)
for(int j = 1; j < m.cols(); ++j)
for(int i = 0; i < m.rows(); ++i)
{
std::stringstream sstr;
sstr.precision(fmt.precision);
sstr << m.coeff(i,j);
width = std::max<int>(width, sstr.str().length());
width = std::max<int>(width, int(sstr.str().length()));
}
}
s.precision(fmt.precision);
s << fmt.matPrefix;
for(int i = 0; i < m.rows(); i++)
for(int i = 0; i < m.rows(); ++i)
{
if (i)
s << fmt.rowSpacer;
s << fmt.rowPrefix;
if(width) s.width(width);
s << m.coeff(i, 0);
for(int j = 1; j < m.cols(); j++)
for(int j = 1; j < m.cols(); ++j)
{
s << fmt.coeffSeparator;
if (width) s.width(width);

View File

@@ -53,7 +53,7 @@ template<typename Derived> class MapBase
ColsAtCompileTime = ei_traits<Derived>::ColsAtCompileTime,
SizeAtCompileTime = Base::SizeAtCompileTime
};
typedef typename ei_traits<Derived>::AlignedDerivedType AlignedDerivedType;
typedef typename ei_traits<Derived>::Scalar Scalar;
typedef typename Base::PacketScalar PacketScalar;
@@ -83,7 +83,7 @@ template<typename Derived> class MapBase
else // column-major
return const_cast<Scalar*>(m_data)[row + col * stride()];
}
inline const Scalar coeff(int index) const
{
ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
@@ -138,28 +138,29 @@ template<typename Derived> class MapBase
m_cols(ColsAtCompileTime == Dynamic ? size : ColsAtCompileTime)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
ei_assert(size > 0);
ei_assert(size > 0 || data == 0);
ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
}
inline MapBase(const Scalar* data, int rows, int cols)
: m_data(data), m_rows(rows), m_cols(cols)
{
ei_assert(rows > 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& cols > 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
ei_assert( (data == 0)
|| ( rows > 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& cols > 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
}
template<typename OtherDerived>
Derived& operator+=(const MatrixBase<OtherDerived>& other)
{ return derived() = forceAligned() + other; }
template<typename OtherDerived>
Derived& operator-=(const MatrixBase<OtherDerived>& other)
{ return derived() = forceAligned() - other; }
Derived& operator*=(const Scalar& other)
{ return derived() = forceAligned() * other; }
Derived& operator/=(const Scalar& other)
{ return derived() = forceAligned() / other; }

View File

@@ -51,7 +51,7 @@ inline int ei_sin(int) { ei_assert(false); return 0; }
inline int ei_cos(int) { ei_assert(false); return 0; }
#if EIGEN_GNUC_AT_LEAST(4,3)
inline int ei_pow(int x, int y) { return std::pow(x, y); }
inline int ei_pow(int x, int y) { return int(std::pow(x, y)); }
#else
inline int ei_pow(int x, int y) { return int(std::pow(double(x), y)); }
#endif
@@ -101,9 +101,9 @@ template<> inline float ei_random(float a, float b)
int i;
do { i = ei_random<int>(256*int(a),256*int(b));
} while(i==0);
return i/256.f;
return float(i)/256.f;
#else
return a + (b-a) * std::rand() / RAND_MAX;
return a + (b-a) * float(std::rand()) / float(RAND_MAX);
#endif
}
template<> inline float ei_random()
@@ -254,7 +254,7 @@ inline long double ei_pow(long double x, long double y) { return std::pow(x, y)
template<> inline long double ei_random(long double a, long double b)
{
return ei_random<double>(a,b);
return ei_random<double>(static_cast<double>(a),static_cast<double>(b));
}
template<> inline long double ei_random()
{

View File

@@ -138,10 +138,10 @@ class Matrix
public:
inline int rows() const { return m_storage.rows(); }
inline int cols() const { return m_storage.cols(); }
EIGEN_STRONG_INLINE int rows() const { return m_storage.rows(); }
EIGEN_STRONG_INLINE int cols() const { return m_storage.cols(); }
inline int stride(void) const
EIGEN_STRONG_INLINE int stride(void) const
{
if(Flags & RowMajorBit)
return m_storage.cols();
@@ -149,7 +149,7 @@ class Matrix
return m_storage.rows();
}
inline const Scalar& coeff(int row, int col) const
EIGEN_STRONG_INLINE const Scalar& coeff(int row, int col) const
{
if(Flags & RowMajorBit)
return m_storage.data()[col + row * m_storage.cols()];
@@ -157,12 +157,12 @@ class Matrix
return m_storage.data()[row + col * m_storage.rows()];
}
inline const Scalar& coeff(int index) const
EIGEN_STRONG_INLINE const Scalar& coeff(int index) const
{
return m_storage.data()[index];
}
inline Scalar& coeffRef(int row, int col)
EIGEN_STRONG_INLINE Scalar& coeffRef(int row, int col)
{
if(Flags & RowMajorBit)
return m_storage.data()[col + row * m_storage.cols()];
@@ -170,13 +170,13 @@ class Matrix
return m_storage.data()[row + col * m_storage.rows()];
}
inline Scalar& coeffRef(int index)
EIGEN_STRONG_INLINE Scalar& coeffRef(int index)
{
return m_storage.data()[index];
}
template<int LoadMode>
inline PacketScalar packet(int row, int col) const
EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const
{
return ei_ploadt<Scalar, LoadMode>
(m_storage.data() + (Flags & RowMajorBit
@@ -185,13 +185,13 @@ class Matrix
}
template<int LoadMode>
inline PacketScalar packet(int index) const
EIGEN_STRONG_INLINE PacketScalar packet(int index) const
{
return ei_ploadt<Scalar, LoadMode>(m_storage.data() + index);
}
template<int StoreMode>
inline void writePacket(int row, int col, const PacketScalar& x)
EIGEN_STRONG_INLINE void writePacket(int row, int col, const PacketScalar& x)
{
ei_pstoret<Scalar, PacketScalar, StoreMode>
(m_storage.data() + (Flags & RowMajorBit
@@ -200,17 +200,17 @@ class Matrix
}
template<int StoreMode>
inline void writePacket(int index, const PacketScalar& x)
EIGEN_STRONG_INLINE void writePacket(int index, const PacketScalar& x)
{
ei_pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, x);
}
/** \returns a const pointer to the data array of this matrix */
inline const Scalar *data() const
EIGEN_STRONG_INLINE const Scalar *data() const
{ return m_storage.data(); }
/** \returns a pointer to the data array of this matrix */
inline Scalar *data()
EIGEN_STRONG_INLINE Scalar *data()
{ return m_storage.data(); }
/** Resizes \c *this to a \a rows x \a cols matrix.
@@ -260,7 +260,7 @@ class Matrix
* \sa set()
*/
template<typename OtherDerived>
inline Matrix& operator=(const MatrixBase<OtherDerived>& other)
EIGEN_STRONG_INLINE Matrix& operator=(const MatrixBase<OtherDerived>& other)
{
ei_assert(m_storage.data()!=0 && "you cannot use operator= with a non initialized matrix (instead use set()");
return Base::operator=(other.derived());
@@ -297,7 +297,7 @@ class Matrix
/** This is a special case of the templated operator=. Its purpose is to
* prevent a default operator= from hiding the templated operator=.
*/
inline Matrix& operator=(const Matrix& other)
EIGEN_STRONG_INLINE Matrix& operator=(const Matrix& other)
{
return operator=<Matrix>(other);
}
@@ -332,7 +332,7 @@ class Matrix
*
* \sa resize(int,int), set()
*/
inline explicit Matrix() : m_storage()
EIGEN_STRONG_INLINE explicit Matrix() : m_storage()
{
ei_assert(RowsAtCompileTime > 0 && ColsAtCompileTime > 0);
}
@@ -343,7 +343,7 @@ class Matrix
* it is redundant to pass the dimension here, so it makes more sense to use the default
* constructor Matrix() instead.
*/
inline explicit Matrix(int dim)
EIGEN_STRONG_INLINE explicit Matrix(int dim)
: m_storage(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix)
@@ -361,7 +361,7 @@ class Matrix
* it is redundant to pass these parameters, so one should use the default constructor
* Matrix() instead.
*/
inline Matrix(int x, int y) : m_storage(x*y, x, y)
EIGEN_STRONG_INLINE Matrix(int x, int y) : m_storage(x*y, x, y)
{
if((RowsAtCompileTime == 1 && ColsAtCompileTime == 2)
|| (RowsAtCompileTime == 2 && ColsAtCompileTime == 1))
@@ -376,21 +376,21 @@ class Matrix
}
}
/** constructs an initialized 2D vector with given coefficients */
inline Matrix(const float& x, const float& y)
EIGEN_STRONG_INLINE Matrix(const float& x, const float& y)
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 2)
m_storage.data()[0] = x;
m_storage.data()[1] = y;
}
/** constructs an initialized 2D vector with given coefficients */
inline Matrix(const double& x, const double& y)
EIGEN_STRONG_INLINE Matrix(const double& x, const double& y)
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 2)
m_storage.data()[0] = x;
m_storage.data()[1] = y;
}
/** constructs an initialized 3D vector with given coefficients */
inline Matrix(const Scalar& x, const Scalar& y, const Scalar& z)
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z)
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 3)
m_storage.data()[0] = x;
@@ -398,7 +398,7 @@ class Matrix
m_storage.data()[2] = z;
}
/** constructs an initialized 4D vector with given coefficients */
inline Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 4)
m_storage.data()[0] = x;
@@ -411,14 +411,14 @@ class Matrix
/** Constructor copying the value of the expression \a other */
template<typename OtherDerived>
inline Matrix(const MatrixBase<OtherDerived>& other)
EIGEN_STRONG_INLINE Matrix(const MatrixBase<OtherDerived>& other)
: m_storage(other.rows() * other.cols(), other.rows(), other.cols())
{
ei_assign_selector<Matrix,OtherDerived,false>::run(*this, other.derived());
//Base::operator=(other.derived());
}
/** Copy constructor */
inline Matrix(const Matrix& other)
EIGEN_STRONG_INLINE Matrix(const Matrix& other)
: Base(), m_storage(other.rows() * other.cols(), other.rows(), other.cols())
{
Base::lazyAssign(other);
@@ -426,14 +426,6 @@ class Matrix
/** Destructor */
inline ~Matrix() {}
/** Override MatrixBase::eval() since matrices don't need to be evaluated, it is enough to just read them.
* This prevents a useless copy when doing e.g. "m1 = m2.eval()"
*/
inline const Matrix& eval() const
{
return *this;
}
/** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the
* data pointers.
*/

View File

@@ -179,9 +179,20 @@ template<typename Derived> class MatrixBase
int innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
#ifndef EIGEN_PARSED_BY_DOXYGEN
/** \internal the type to which the expression gets evaluated (needed by MSVC) */
typedef typename ei_eval<Derived>::type EvalType;
/** \internal Represents a constant matrix */
/** \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 guaranteed however, that the return type of eval() is either
* PlainMatrixType or const PlainMatrixType&.
*/
typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType;
/** \internal the column-major 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!
* The only difference from PlainMatrixType is that PlainMatrixType_ColMajor is guaranteed to be column-major.
*/
typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType_ColMajor;
/** \internal Represents a matrix with all coefficients equal to one another*/
typedef CwiseNullaryOp<ei_scalar_constant_op<Scalar>,Derived> ConstantReturnType;
/** \internal Represents a scalar multiple of a matrix */
typedef CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, Derived> ScalarMultipleReturnType;
@@ -331,7 +342,7 @@ template<typename Derived> class MatrixBase
Derived& operator*=(const MatrixBase<OtherDerived>& other);
template<typename OtherDerived>
typename ei_eval_to_column_major<OtherDerived>::type
typename ei_plain_matrix_type_column_major<OtherDerived>::type
solveTriangular(const MatrixBase<OtherDerived>& other) const;
template<typename OtherDerived>
@@ -343,7 +354,7 @@ template<typename Derived> class MatrixBase
RealScalar squaredNorm() const;
RealScalar norm2() const;
RealScalar norm() const;
const EvalType normalized() const;
const PlainMatrixType normalized() const;
void normalize();
Eigen::Transpose<Derived> transpose();
@@ -459,8 +470,8 @@ template<typename Derived> class MatrixBase
bool isIdentity(RealScalar prec = precision<Scalar>()) const;
bool isDiagonal(RealScalar prec = precision<Scalar>()) const;
bool isUpper(RealScalar prec = precision<Scalar>()) const;
bool isLower(RealScalar prec = precision<Scalar>()) const;
bool isUpperTriangular(RealScalar prec = precision<Scalar>()) const;
bool isLowerTriangular(RealScalar prec = precision<Scalar>()) const;
template<typename OtherDerived>
bool isOrthogonal(const MatrixBase<OtherDerived>& other,
@@ -481,11 +492,11 @@ template<typename Derived> class MatrixBase
/** \returns the matrix or vector obtained by evaluating this expression.
*
* Notice that in the case of a plain matrix or vector (not an expression) this function just returns
* a const reference, in order to avoid a useless copy.
*/
EIGEN_ALWAYS_INLINE const typename ei_eval<Derived>::type eval() const
{
return typename ei_eval<Derived>::type(derived());
}
EIGEN_STRONG_INLINE const typename ei_eval<Derived>::type eval() const
{ return typename ei_eval<Derived>::type(derived()); }
template<typename OtherDerived>
void swap(const MatrixBase<OtherDerived>& other);
@@ -573,35 +584,35 @@ template<typename Derived> class MatrixBase
/////////// LU module ///////////
const LU<EvalType> lu() const;
const EvalType inverse() const;
void computeInverse(EvalType *result) const;
const LU<PlainMatrixType> lu() const;
const PlainMatrixType inverse() const;
void computeInverse(PlainMatrixType *result) const;
Scalar determinant() const;
/////////// Cholesky module ///////////
const LLT<EvalType> llt() const;
const LDLT<EvalType> ldlt() const;
const LLT<PlainMatrixType> llt() const;
const LDLT<PlainMatrixType> ldlt() const;
// deprecated:
const Cholesky<EvalType> cholesky() const;
const CholeskyWithoutSquareRoot<EvalType> choleskyNoSqrt() const;
const Cholesky<PlainMatrixType> cholesky() const;
const CholeskyWithoutSquareRoot<PlainMatrixType> choleskyNoSqrt() const;
/////////// QR module ///////////
const QR<EvalType> qr() const;
const QR<PlainMatrixType> qr() const;
EigenvaluesReturnType eigenvalues() const;
RealScalar operatorNorm() const;
/////////// SVD module ///////////
SVD<EvalType> svd() const;
SVD<PlainMatrixType> svd() const;
/////////// Geometry module ///////////
template<typename OtherDerived>
EvalType cross(const MatrixBase<OtherDerived>& other) const;
EvalType unitOrthogonal(void) const;
PlainMatrixType cross(const MatrixBase<OtherDerived>& other) const;
PlainMatrixType unitOrthogonal(void) const;
Matrix<Scalar,3,1> eulerAngles(int a0, int a1, int a2) const;
#ifdef EIGEN_MATRIXBASE_PLUGIN

View File

@@ -31,8 +31,8 @@
* \brief Expression of a triangular matrix extracted from a given matrix
*
* \param MatrixType the type of the object in which we are taking the triangular part
* \param Mode the kind of triangular matrix expression to construct. Can be Upper, StrictlyUpper,
* UnitUpper, Lower, StrictlyLower, UnitLower. This is in fact a bit field; it must have either
* \param Mode the kind of triangular matrix expression to construct. Can be UpperTriangular, StrictlyUpperTriangular,
* UnitUpperTriangular, LowerTriangular, StrictlyLowerTriangular, UnitLowerTriangular. This is in fact a bit field; it must have either
* UpperTriangularBit or LowerTriangularBit, and additionnaly it may have either ZeroDiagBit or
* UnitDiagBit.
*
@@ -102,12 +102,12 @@ template<typename MatrixType, unsigned int Mode> class Part
inline Scalar& coeffRef(int row, int col)
{
EIGEN_STATIC_ASSERT(!(Flags & UnitDiagBit), writing_to_triangular_part_with_unit_diagonal_is_not_supported)
EIGEN_STATIC_ASSERT(!(Flags & SelfAdjointBit), coefficient_write_access_to_selfadjoint_not_supported)
ei_assert( (Mode==Upper && col>=row)
|| (Mode==Lower && col<=row)
|| (Mode==StrictlyUpper && col>row)
|| (Mode==StrictlyLower && col<row));
EIGEN_STATIC_ASSERT(!(Flags & UnitDiagBit), WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED)
EIGEN_STATIC_ASSERT(!(Flags & SelfAdjointBit), COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED)
ei_assert( (Mode==UpperTriangular && col>=row)
|| (Mode==LowerTriangular && col<=row)
|| (Mode==StrictlyUpperTriangular && col>row)
|| (Mode==StrictlyLowerTriangular && col<row));
return m_matrix.const_cast_derived().coeffRef(row, col);
}
@@ -134,8 +134,8 @@ template<typename MatrixType, unsigned int Mode> class Part
/** \returns an expression of a triangular matrix extracted from the current matrix
*
* The parameter \a Mode can have the following values: \c Upper, \c StrictlyUpper, \c UnitUpper,
* \c Lower, \c StrictlyLower, \c UnitLower.
* The parameter \a Mode can have the following values: \c UpperTriangular, \c StrictlyUpperTriangular, \c UnitUpperTriangular,
* \c LowerTriangular, \c StrictlyLowerTriangular, \c UnitLowerTriangular.
*
* \addexample PartExample \label How to extract a triangular part of an arbitrary matrix
*
@@ -157,7 +157,7 @@ inline Part<MatrixType, Mode>& Part<MatrixType, Mode>::operator=(const Other& ot
{
if(Other::Flags & EvalBeforeAssigningBit)
{
typename ei_eval<Other>::type other_evaluated(other.rows(), other.cols());
typename MatrixBase<Other>::PlainMatrixType other_evaluated(other.rows(), other.cols());
other_evaluated.template part<Mode>().lazyAssign(other);
lazyAssign(other_evaluated);
}
@@ -187,11 +187,11 @@ struct ei_part_assignment_impl
}
else
{
ei_assert(Mode == Upper || Mode == Lower || Mode == StrictlyUpper || Mode == StrictlyLower);
if((Mode == Upper && row <= col)
|| (Mode == Lower && row >= col)
|| (Mode == StrictlyUpper && row < col)
|| (Mode == StrictlyLower && row > col))
ei_assert(Mode == UpperTriangular || Mode == LowerTriangular || Mode == StrictlyUpperTriangular || Mode == StrictlyLowerTriangular);
if((Mode == UpperTriangular && row <= col)
|| (Mode == LowerTriangular && row >= col)
|| (Mode == StrictlyUpperTriangular && row < col)
|| (Mode == StrictlyLowerTriangular && row > col))
dst.copyCoeff(row, col, src);
}
}
@@ -215,44 +215,44 @@ struct ei_part_assignment_impl<Derived1, Derived2, Mode, 0>
};
template<typename Derived1, typename Derived2>
struct ei_part_assignment_impl<Derived1, Derived2, Upper, Dynamic>
struct ei_part_assignment_impl<Derived1, Derived2, UpperTriangular, Dynamic>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
for(int j = 0; j < dst.cols(); j++)
for(int i = 0; i <= j; i++)
for(int j = 0; j < dst.cols(); ++j)
for(int i = 0; i <= j; ++i)
dst.copyCoeff(i, j, src);
}
};
template<typename Derived1, typename Derived2>
struct ei_part_assignment_impl<Derived1, Derived2, Lower, Dynamic>
struct ei_part_assignment_impl<Derived1, Derived2, LowerTriangular, Dynamic>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
for(int j = 0; j < dst.cols(); j++)
for(int i = j; i < dst.rows(); i++)
for(int j = 0; j < dst.cols(); ++j)
for(int i = j; i < dst.rows(); ++i)
dst.copyCoeff(i, j, src);
}
};
template<typename Derived1, typename Derived2>
struct ei_part_assignment_impl<Derived1, Derived2, StrictlyUpper, Dynamic>
struct ei_part_assignment_impl<Derived1, Derived2, StrictlyUpperTriangular, Dynamic>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
for(int j = 0; j < dst.cols(); j++)
for(int i = 0; i < j; i++)
for(int j = 0; j < dst.cols(); ++j)
for(int i = 0; i < j; ++i)
dst.copyCoeff(i, j, src);
}
};
template<typename Derived1, typename Derived2>
struct ei_part_assignment_impl<Derived1, Derived2, StrictlyLower, Dynamic>
struct ei_part_assignment_impl<Derived1, Derived2, StrictlyLowerTriangular, Dynamic>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
for(int j = 0; j < dst.cols(); j++)
for(int i = j+1; i < dst.rows(); i++)
for(int j = 0; j < dst.cols(); ++j)
for(int i = j+1; i < dst.rows(); ++i)
dst.copyCoeff(i, j, src);
}
};
@@ -261,9 +261,9 @@ struct ei_part_assignment_impl<Derived1, Derived2, SelfAdjoint, Dynamic>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
for(int j = 0; j < dst.cols(); j++)
for(int j = 0; j < dst.cols(); ++j)
{
for(int i = 0; i < j; i++)
for(int i = 0; i < j; ++i)
dst.coeffRef(j, i) = ei_conj(dst.coeffRef(i, j) = src.coeff(i, j));
dst.coeffRef(j, j) = ei_real(src.coeff(j, j));
}
@@ -285,8 +285,8 @@ void Part<MatrixType, Mode>::lazyAssign(const Other& other)
/** \returns a lvalue pseudo-expression allowing to perform special operations on \c *this.
*
* The \a Mode parameter can have the following values: \c Upper, \c StrictlyUpper, \c Lower,
* \c StrictlyLower, \c SelfAdjoint.
* The \a Mode parameter can have the following values: \c UpperTriangular, \c StrictlyUpperTriangular, \c LowerTriangular,
* \c StrictlyLowerTriangular, \c SelfAdjoint.
*
* \addexample PartExample \label How to write to a triangular part of a matrix
*
@@ -305,44 +305,44 @@ inline Part<Derived, Mode> MatrixBase<Derived>::part()
/** \returns true if *this is approximately equal to an upper triangular matrix,
* within the precision given by \a prec.
*
* \sa isLower(), extract(), part(), marked()
* \sa isLowerTriangular(), extract(), part(), marked()
*/
template<typename Derived>
bool MatrixBase<Derived>::isUpper(RealScalar prec) const
bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const
{
if(cols() != rows()) return false;
RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1);
for(int j = 0; j < cols(); j++)
for(int i = 0; i <= j; i++)
RealScalar maxAbsOnUpperTriangularPart = static_cast<RealScalar>(-1);
for(int j = 0; j < cols(); ++j)
for(int i = 0; i <= j; ++i)
{
RealScalar absValue = ei_abs(coeff(i,j));
if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
if(absValue > maxAbsOnUpperTriangularPart) maxAbsOnUpperTriangularPart = absValue;
}
for(int j = 0; j < cols()-1; j++)
for(int i = j+1; i < rows(); i++)
if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnUpperPart, prec)) return false;
for(int j = 0; j < cols()-1; ++j)
for(int i = j+1; i < rows(); ++i)
if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnUpperTriangularPart, prec)) return false;
return true;
}
/** \returns true if *this is approximately equal to a lower triangular matrix,
* within the precision given by \a prec.
*
* \sa isUpper(), extract(), part(), marked()
* \sa isUpperTriangular(), extract(), part(), marked()
*/
template<typename Derived>
bool MatrixBase<Derived>::isLower(RealScalar prec) const
bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const
{
if(cols() != rows()) return false;
RealScalar maxAbsOnLowerPart = static_cast<RealScalar>(-1);
for(int j = 0; j < cols(); j++)
for(int i = j; i < rows(); i++)
RealScalar maxAbsOnLowerTriangularPart = static_cast<RealScalar>(-1);
for(int j = 0; j < cols(); ++j)
for(int i = j; i < rows(); ++i)
{
RealScalar absValue = ei_abs(coeff(i,j));
if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
if(absValue > maxAbsOnLowerTriangularPart) maxAbsOnLowerTriangularPart = absValue;
}
for(int j = 1; j < cols(); j++)
for(int i = 0; i < j; i++)
if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnLowerPart, prec)) return false;
for(int j = 1; j < cols(); ++j)
for(int i = 0; i < j; ++i)
if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnLowerTriangularPart, prec)) return false;
return true;
}

View File

@@ -30,7 +30,7 @@
*** Forward declarations ***
***************************/
template<int VectorizationMode, int Index, typename Lhs, typename Rhs>
template<int VectorizationMode, int Index, typename Lhs, typename Rhs, typename RetScalar>
struct ei_product_coeff_impl;
template<int StorageOrder, int Index, typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
@@ -62,13 +62,14 @@ struct ProductReturnType
};
// cache friendly specialization
// note that there is a DiagonalProduct specialization in DiagonalProduct.h
template<typename Lhs, typename Rhs>
struct ProductReturnType<Lhs,Rhs,CacheFriendlyProduct>
{
typedef typename ei_nested<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
typedef typename ei_nested<Rhs,Lhs::RowsAtCompileTime,
typename ei_eval_to_column_major<Rhs>::type
typename ei_plain_matrix_type_column_major<Rhs>::type
>::type RhsNested;
typedef Product<LhsNested, RhsNested, CacheFriendlyProduct> Type;
@@ -77,7 +78,8 @@ struct ProductReturnType<Lhs,Rhs,CacheFriendlyProduct>
/* Helper class to determine the type of the product, can be either:
* - NormalProduct
* - CacheFriendlyProduct
* - NormalProduct
* - DiagonalProduct
* - SparseProduct
*/
template<typename Lhs, typename Rhs> struct ei_product_mode
{
@@ -92,6 +94,7 @@ template<typename Lhs, typename Rhs> struct ei_product_mode
|| Rhs::MaxColsAtCompileTime >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD )
&& (!(Rhs::IsVectorAtCompileTime && (Lhs::Flags&RowMajorBit) && (!(Lhs::Flags&DirectAccessBit))))
&& (!(Lhs::IsVectorAtCompileTime && (!(Rhs::Flags&RowMajorBit)) && (!(Rhs::Flags&DirectAccessBit))))
&& (ei_is_same_type<typename Lhs::Scalar, typename Rhs::Scalar>::ret)
? CacheFriendlyProduct
: NormalProduct };
};
@@ -118,7 +121,7 @@ struct ei_traits<Product<LhsNested, RhsNested, ProductMode> >
// clean the nested types:
typedef typename ei_cleantype<LhsNested>::type _LhsNested;
typedef typename ei_cleantype<RhsNested>::type _RhsNested;
typedef typename _LhsNested::Scalar Scalar;
typedef typename ei_scalar_product_traits<typename _LhsNested::Scalar, typename _RhsNested::Scalar>::ReturnType Scalar;
enum {
LhsCoeffReadCost = _LhsNested::CoeffReadCost,
@@ -149,7 +152,8 @@ struct ei_traits<Product<LhsNested, RhsNested, ProductMode> >
Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)
| EvalBeforeAssigningBit
| EvalBeforeNestingBit
| (CanVectorizeLhs || CanVectorizeRhs ? PacketAccessBit : 0),
| (CanVectorizeLhs || CanVectorizeRhs ? PacketAccessBit : 0)
| (LhsFlags & RhsFlags & AlignedBit),
CoeffReadCost = InnerSize == Dynamic ? Dynamic
: InnerSize * (NumTraits<Scalar>::MulCost + LhsCoeffReadCost + RhsCoeffReadCost)
@@ -186,7 +190,7 @@ template<typename LhsNested, typename RhsNested, int ProductMode> class Product
typedef ei_product_coeff_impl<CanVectorizeInner ? InnerVectorization : NoVectorization,
Unroll ? InnerSize-1 : Dynamic,
_LhsNested, _RhsNested> ScalarCoeffImpl;
_LhsNested, _RhsNested, Scalar> ScalarCoeffImpl;
public:
@@ -197,7 +201,7 @@ template<typename LhsNested, typename RhsNested, int ProductMode> class Product
// we don't allow taking products of matrices of different real types, as that wouldn't be vectorizable.
// We still allow to mix T and complex<T>.
EIGEN_STATIC_ASSERT((ei_is_same_type<typename Lhs::RealScalar, typename Rhs::RealScalar>::ret),
you_mixed_different_numeric_types__you_need_to_use_the_cast_method_of_MatrixBase_to_cast_numeric_types_explicitly)
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
ei_assert(lhs.cols() == rhs.rows()
&& "invalid matrix product"
&& "if you wanted a coeff-wise or a dot product use the respective explicit functions");
@@ -212,17 +216,17 @@ template<typename LhsNested, typename RhsNested, int ProductMode> class Product
/** \internal
* \returns whether it is worth it to use the cache friendly product.
*/
inline bool _useCacheFriendlyProduct() const
EIGEN_STRONG_INLINE bool _useCacheFriendlyProduct() const
{
return m_lhs.cols()>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
&& ( rows()>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
|| cols()>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD);
}
inline int rows() const { return m_lhs.rows(); }
inline int cols() const { return m_rhs.cols(); }
EIGEN_STRONG_INLINE int rows() const { return m_lhs.rows(); }
EIGEN_STRONG_INLINE int cols() const { return m_rhs.cols(); }
const Scalar coeff(int row, int col) const
EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const
{
Scalar res;
ScalarCoeffImpl::run(row, col, m_lhs, m_rhs, res);
@@ -232,7 +236,7 @@ template<typename LhsNested, typename RhsNested, int ProductMode> class Product
/* Allow index-based non-packet access. It is impossible though to allow index-based packed access,
* which is why we don't set the LinearAccessBit.
*/
const Scalar coeff(int index) const
EIGEN_STRONG_INLINE const Scalar coeff(int index) const
{
Scalar res;
const int row = RowsAtCompileTime == 1 ? 0 : index;
@@ -242,7 +246,7 @@ template<typename LhsNested, typename RhsNested, int ProductMode> class Product
}
template<int LoadMode>
const PacketScalar packet(int row, int col) const
EIGEN_STRONG_INLINE const PacketScalar packet(int row, int col) const
{
PacketScalar res;
ei_product_packet_impl<Flags&RowMajorBit ? RowMajor : ColMajor,
@@ -252,8 +256,8 @@ template<typename LhsNested, typename RhsNested, int ProductMode> class Product
return res;
}
inline const _LhsNested& lhs() const { return m_lhs; }
inline const _RhsNested& rhs() const { return m_rhs; }
EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; }
EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; }
protected:
const LhsNested m_lhs;
@@ -282,10 +286,10 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
// * for a dot product use: v1.dot(v2)
// * for a coeff-wise product use: v1.cwise()*v2
EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
invalid_vector_vector_product__if_you_wanted_a_dot_or_coeff_wise_product_you_must_use_the_explicit_functions)
INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
invalid_matrix_product__if_you_wanted_a_coeff_wise_product_you_must_use_the_explicit_function)
EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, invalid_matrix_product)
INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
}
@@ -309,42 +313,42 @@ MatrixBase<Derived>::operator*=(const MatrixBase<OtherDerived> &other)
*** Scalar path - no vectorization ***
**************************************/
template<int Index, typename Lhs, typename Rhs>
struct ei_product_coeff_impl<NoVectorization, Index, Lhs, Rhs>
template<int Index, typename Lhs, typename Rhs, typename RetScalar>
struct ei_product_coeff_impl<NoVectorization, Index, Lhs, Rhs, RetScalar>
{
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
{
ei_product_coeff_impl<NoVectorization, Index-1, Lhs, Rhs>::run(row, col, lhs, rhs, res);
ei_product_coeff_impl<NoVectorization, Index-1, Lhs, Rhs, RetScalar>::run(row, col, lhs, rhs, res);
res += lhs.coeff(row, Index) * rhs.coeff(Index, col);
}
};
template<typename Lhs, typename Rhs>
struct ei_product_coeff_impl<NoVectorization, 0, Lhs, Rhs>
template<typename Lhs, typename Rhs, typename RetScalar>
struct ei_product_coeff_impl<NoVectorization, 0, Lhs, Rhs, RetScalar>
{
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
{
res = lhs.coeff(row, 0) * rhs.coeff(0, col);
}
};
template<typename Lhs, typename Rhs>
struct ei_product_coeff_impl<NoVectorization, Dynamic, Lhs, Rhs>
template<typename Lhs, typename Rhs, typename RetScalar>
struct ei_product_coeff_impl<NoVectorization, Dynamic, Lhs, Rhs, RetScalar>
{
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar& res)
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar& res)
{
ei_assert(lhs.cols()>0 && "you are using a non initialized matrix");
res = lhs.coeff(row, 0) * rhs.coeff(0, col);
for(int i = 1; i < lhs.cols(); i++)
for(int i = 1; i < lhs.cols(); ++i)
res += lhs.coeff(row, i) * rhs.coeff(i, col);
}
};
// prevent buggy user code from causing an infinite recursion
template<typename Lhs, typename Rhs>
struct ei_product_coeff_impl<NoVectorization, -1, Lhs, Rhs>
template<typename Lhs, typename Rhs, typename RetScalar>
struct ei_product_coeff_impl<NoVectorization, -1, Lhs, Rhs, RetScalar>
{
inline static void run(int, int, const Lhs&, const Rhs&, typename Lhs::Scalar&) {}
EIGEN_STRONG_INLINE static void run(int, int, const Lhs&, const Rhs&, RetScalar&) {}
};
/*******************************************
@@ -355,7 +359,7 @@ template<int Index, typename Lhs, typename Rhs, typename PacketScalar>
struct ei_product_coeff_vectorized_unroller
{
enum { PacketSize = ei_packet_traits<typename Lhs::Scalar>::size };
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres)
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres)
{
ei_product_coeff_vectorized_unroller<Index-PacketSize, Lhs, Rhs, PacketScalar>::run(row, col, lhs, rhs, pres);
pres = ei_padd(pres, ei_pmul( lhs.template packet<Aligned>(row, Index) , rhs.template packet<Aligned>(Index, col) ));
@@ -365,22 +369,22 @@ struct ei_product_coeff_vectorized_unroller
template<typename Lhs, typename Rhs, typename PacketScalar>
struct ei_product_coeff_vectorized_unroller<0, Lhs, Rhs, PacketScalar>
{
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres)
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres)
{
pres = ei_pmul(lhs.template packet<Aligned>(row, 0) , rhs.template packet<Aligned>(0, col));
}
};
template<int Index, typename Lhs, typename Rhs>
struct ei_product_coeff_impl<InnerVectorization, Index, Lhs, Rhs>
template<int Index, typename Lhs, typename Rhs, typename RetScalar>
struct ei_product_coeff_impl<InnerVectorization, Index, Lhs, Rhs, RetScalar>
{
typedef typename Lhs::PacketScalar PacketScalar;
enum { PacketSize = ei_packet_traits<typename Lhs::Scalar>::size };
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
{
PacketScalar pres;
ei_product_coeff_vectorized_unroller<Index+1-PacketSize, Lhs, Rhs, PacketScalar>::run(row, col, lhs, rhs, pres);
ei_product_coeff_impl<NoVectorization,Index,Lhs,Rhs>::run(row, col, lhs, rhs, res);
ei_product_coeff_impl<NoVectorization,Index,Lhs,Rhs,RetScalar>::run(row, col, lhs, rhs, res);
res = ei_predux(pres);
}
};
@@ -388,7 +392,7 @@ struct ei_product_coeff_impl<InnerVectorization, Index, Lhs, Rhs>
template<typename Lhs, typename Rhs, int LhsRows = Lhs::RowsAtCompileTime, int RhsCols = Rhs::ColsAtCompileTime>
struct ei_product_coeff_vectorized_dyn_selector
{
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
{
res = ei_dot_impl<
Block<Lhs, 1, ei_traits<Lhs>::ColsAtCompileTime>,
@@ -402,7 +406,7 @@ struct ei_product_coeff_vectorized_dyn_selector
template<typename Lhs, typename Rhs, int RhsCols>
struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,RhsCols>
{
inline static void run(int /*row*/, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
EIGEN_STRONG_INLINE static void run(int /*row*/, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
{
res = ei_dot_impl<
Lhs,
@@ -414,7 +418,7 @@ struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,RhsCols>
template<typename Lhs, typename Rhs, int LhsRows>
struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,LhsRows,1>
{
inline static void run(int row, int /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
EIGEN_STRONG_INLINE static void run(int row, int /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
{
res = ei_dot_impl<
Block<Lhs, 1, ei_traits<Lhs>::ColsAtCompileTime>,
@@ -426,7 +430,7 @@ struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,LhsRows,1>
template<typename Lhs, typename Rhs>
struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,1>
{
inline static void run(int /*row*/, int /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
EIGEN_STRONG_INLINE static void run(int /*row*/, int /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
{
res = ei_dot_impl<
Lhs,
@@ -435,10 +439,10 @@ struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,1>
}
};
template<typename Lhs, typename Rhs>
struct ei_product_coeff_impl<InnerVectorization, Dynamic, Lhs, Rhs>
template<typename Lhs, typename Rhs, typename RetScalar>
struct ei_product_coeff_impl<InnerVectorization, Dynamic, Lhs, Rhs, RetScalar>
{
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
{
ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs>::run(row, col, lhs, rhs, res);
}
@@ -451,7 +455,7 @@ struct ei_product_coeff_impl<InnerVectorization, Dynamic, Lhs, Rhs>
template<int Index, typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
struct ei_product_packet_impl<RowMajor, Index, Lhs, Rhs, PacketScalar, LoadMode>
{
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
{
ei_product_packet_impl<RowMajor, Index-1, Lhs, Rhs, PacketScalar, LoadMode>::run(row, col, lhs, rhs, res);
res = ei_pmadd(ei_pset1(lhs.coeff(row, Index)), rhs.template packet<LoadMode>(Index, col), res);
@@ -461,7 +465,7 @@ struct ei_product_packet_impl<RowMajor, Index, Lhs, Rhs, PacketScalar, LoadMode>
template<int Index, typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
struct ei_product_packet_impl<ColMajor, Index, Lhs, Rhs, PacketScalar, LoadMode>
{
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
{
ei_product_packet_impl<ColMajor, Index-1, Lhs, Rhs, PacketScalar, LoadMode>::run(row, col, lhs, rhs, res);
res = ei_pmadd(lhs.template packet<LoadMode>(row, Index), ei_pset1(rhs.coeff(Index, col)), res);
@@ -471,7 +475,7 @@ struct ei_product_packet_impl<ColMajor, Index, Lhs, Rhs, PacketScalar, LoadMode>
template<typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
struct ei_product_packet_impl<RowMajor, 0, Lhs, Rhs, PacketScalar, LoadMode>
{
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
{
res = ei_pmul(ei_pset1(lhs.coeff(row, 0)),rhs.template packet<LoadMode>(0, col));
}
@@ -480,7 +484,7 @@ struct ei_product_packet_impl<RowMajor, 0, Lhs, Rhs, PacketScalar, LoadMode>
template<typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
struct ei_product_packet_impl<ColMajor, 0, Lhs, Rhs, PacketScalar, LoadMode>
{
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar &res)
{
res = ei_pmul(lhs.template packet<LoadMode>(row, 0), ei_pset1(rhs.coeff(0, col)));
}
@@ -489,11 +493,11 @@ struct ei_product_packet_impl<ColMajor, 0, Lhs, Rhs, PacketScalar, LoadMode>
template<typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
struct ei_product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, PacketScalar, LoadMode>
{
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar& res)
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar& res)
{
ei_assert(lhs.cols()>0 && "you are using a non initialized matrix");
res = ei_pmul(ei_pset1(lhs.coeff(row, 0)),rhs.template packet<LoadMode>(0, col));
for(int i = 1; i < lhs.cols(); i++)
for(int i = 1; i < lhs.cols(); ++i)
res = ei_pmadd(ei_pset1(lhs.coeff(row, i)), rhs.template packet<LoadMode>(i, col), res);
}
};
@@ -501,11 +505,11 @@ struct ei_product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, PacketScalar, LoadMod
template<typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
struct ei_product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, PacketScalar, LoadMode>
{
inline static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar& res)
EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, PacketScalar& res)
{
ei_assert(lhs.cols()>0 && "you are using a non initialized matrix");
res = ei_pmul(lhs.template packet<LoadMode>(row, 0), ei_pset1(rhs.coeff(0, col)));
for(int i = 1; i < lhs.cols(); i++)
for(int i = 1; i < lhs.cols(); ++i)
res = ei_pmadd(lhs.template packet<LoadMode>(row, i), ei_pset1(rhs.coeff(i, col)), res);
}
};
@@ -733,7 +737,7 @@ template<typename T> struct ei_product_copy_rhs
typedef typename ei_meta_if<
(ei_traits<T>::Flags & RowMajorBit)
|| (!(ei_traits<T>::Flags & DirectAccessBit)),
typename ei_eval_to_column_major<T>::type,
typename ei_plain_matrix_type_column_major<T>::type,
const T&
>::ret type;
};
@@ -742,7 +746,7 @@ template<typename T> struct ei_product_copy_lhs
{
typedef typename ei_meta_if<
(!(int(ei_traits<T>::Flags) & DirectAccessBit)),
typename ei_eval<T>::type,
typename ei_plain_matrix_type<T>::type,
const T&
>::ret type;
};

View File

@@ -68,10 +68,10 @@ struct ei_redux_impl<BinaryOp, Derived, Start, Dynamic>
ei_assert(mat.rows()>0 && mat.cols()>0 && "you are using a non initialized matrix");
Scalar res;
res = mat.coeff(0,0);
for(int i = 1; i < mat.rows(); i++)
for(int i = 1; i < mat.rows(); ++i)
res = func(res, mat.coeff(i, 0));
for(int j = 1; j < mat.cols(); j++)
for(int i = 0; i < mat.rows(); i++)
for(int j = 1; j < mat.cols(); ++j)
for(int i = 0; i < mat.rows(); ++i)
res = func(res, mat.coeff(i, j));
return res;
}

View File

@@ -30,9 +30,9 @@ template<typename XprType, unsigned int Mode> struct ei_is_part<Part<XprType,Mod
template<typename Lhs, typename Rhs,
int TriangularPart = (int(Lhs::Flags) & LowerTriangularBit)
? Lower
? LowerTriangular
: (int(Lhs::Flags) & UpperTriangularBit)
? Upper
? UpperTriangular
: -1,
int StorageOrder = ei_is_part<Lhs>::value ? -1 // this is to solve ambiguous specializations
: int(Lhs::Flags) & (RowMajorBit|SparseBit)
@@ -56,14 +56,14 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,RowMajor|IsDense>
typedef typename Rhs::Scalar Scalar;
static void run(const Lhs& lhs, Rhs& other)
{
const bool IsLower = (UpLo==Lower);
const bool IsLowerTriangular = (UpLo==LowerTriangular);
const int size = lhs.cols();
/* We perform the inverse product per block of 4 rows such that we perfectly match
* our optimized matrix * vector product. blockyStart represents the number of rows
* we have process first using the non-block version.
*/
int blockyStart = (std::max(size-5,0)/4)*4;
if (IsLower)
if (IsLowerTriangular)
blockyStart = size - blockyStart;
else
blockyStart -= 1;
@@ -72,15 +72,15 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,RowMajor|IsDense>
// process first rows using the non block version
if(!(Lhs::Flags & UnitDiagBit))
{
if (IsLower)
if (IsLowerTriangular)
other.coeffRef(0,c) = other.coeff(0,c)/lhs.coeff(0, 0);
else
other.coeffRef(size-1,c) = other.coeff(size-1, c)/lhs.coeff(size-1, size-1);
}
for(int i=(IsLower ? 1 : size-2); IsLower ? i<blockyStart : i>blockyStart; i += (IsLower ? 1 : -1) )
for(int i=(IsLowerTriangular ? 1 : size-2); IsLowerTriangular ? i<blockyStart : i>blockyStart; i += (IsLowerTriangular ? 1 : -1) )
{
Scalar tmp = other.coeff(i,c)
- (IsLower ? ((lhs.row(i).start(i)) * other.col(c).start(i)).coeff(0,0)
- (IsLowerTriangular ? ((lhs.row(i).start(i)) * other.col(c).start(i)).coeff(0,0)
: ((lhs.row(i).end(size-i-1)) * other.col(c).end(size-i-1)).coeff(0,0));
if (Lhs::Flags & UnitDiagBit)
other.coeffRef(i,c) = tmp;
@@ -89,15 +89,15 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,RowMajor|IsDense>
}
// now let's process the remaining rows 4 at once
for(int i=blockyStart; IsLower ? i<size : i>0; )
for(int i=blockyStart; IsLowerTriangular ? i<size : i>0; )
{
int startBlock = i;
int endBlock = startBlock + (IsLower ? 4 : -4);
int endBlock = startBlock + (IsLowerTriangular ? 4 : -4);
/* Process the i cols times 4 rows block, and keep the result in a temporary vector */
// FIXME use fixed size block but take care to small fixed size matrices...
Matrix<Scalar,Dynamic,1> btmp(4);
if (IsLower)
if (IsLowerTriangular)
btmp = lhs.block(startBlock,0,4,i) * other.col(c).start(i);
else
btmp = lhs.block(i-3,i+1,4,size-1-i) * other.col(c).end(size-1-i);
@@ -106,21 +106,21 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,RowMajor|IsDense>
* btmp stores the diagonal coefficients used to update the remaining part of the result.
*/
{
Scalar tmp = other.coeff(startBlock,c)-btmp.coeff(IsLower?0:3);
Scalar tmp = other.coeff(startBlock,c)-btmp.coeff(IsLowerTriangular?0:3);
if (Lhs::Flags & UnitDiagBit)
other.coeffRef(i,c) = tmp;
else
other.coeffRef(i,c) = tmp/lhs.coeff(i,i);
}
i += IsLower ? 1 : -1;
for (;IsLower ? i<endBlock : i>endBlock; i += IsLower ? 1 : -1)
i += IsLowerTriangular ? 1 : -1;
for (;IsLowerTriangular ? i<endBlock : i>endBlock; i += IsLowerTriangular ? 1 : -1)
{
int remainingSize = IsLower ? i-startBlock : startBlock-i;
int remainingSize = IsLowerTriangular ? i-startBlock : startBlock-i;
Scalar tmp = other.coeff(i,c)
- btmp.coeff(IsLower ? remainingSize : 3-remainingSize)
- ( lhs.row(i).segment(IsLower ? startBlock : i+1, remainingSize)
* other.col(c).segment(IsLower ? startBlock : i+1, remainingSize)).coeff(0,0);
- btmp.coeff(IsLowerTriangular ? remainingSize : 3-remainingSize)
- ( lhs.row(i).segment(IsLowerTriangular ? startBlock : i+1, remainingSize)
* other.col(c).segment(IsLowerTriangular ? startBlock : i+1, remainingSize)).coeff(0,0);
if (Lhs::Flags & UnitDiagBit)
other.coeffRef(i,c) = tmp;
@@ -133,10 +133,10 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,RowMajor|IsDense>
};
// Implements the following configurations:
// - inv(Lower, ColMajor) * Column vector
// - inv(Lower,UnitDiag,ColMajor) * Column vector
// - inv(Upper, ColMajor) * Column vector
// - inv(Upper,UnitDiag,ColMajor) * Column vector
// - inv(LowerTriangular, ColMajor) * Column vector
// - inv(LowerTriangular,UnitDiag,ColMajor) * Column vector
// - inv(UpperTriangular, ColMajor) * Column vector
// - inv(UpperTriangular,UnitDiag,ColMajor) * Column vector
template<typename Lhs, typename Rhs, int UpLo>
struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,ColMajor|IsDense>
{
@@ -146,7 +146,7 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,ColMajor|IsDense>
static void run(const Lhs& lhs, Rhs& other)
{
static const bool IsLower = (UpLo==Lower);
static const bool IsLowerTriangular = (UpLo==LowerTriangular);
const int size = lhs.cols();
for(int c=0 ; c<other.cols() ; ++c)
{
@@ -155,27 +155,27 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,ColMajor|IsDense>
* we can process using the block version.
*/
int blockyEnd = (std::max(size-5,0)/4)*4;
if (!IsLower)
if (!IsLowerTriangular)
blockyEnd = size-1 - blockyEnd;
for(int i=IsLower ? 0 : size-1; IsLower ? i<blockyEnd : i>blockyEnd;)
for(int i=IsLowerTriangular ? 0 : size-1; IsLowerTriangular ? i<blockyEnd : i>blockyEnd;)
{
/* Let's process the 4x4 sub-matrix as usual.
* btmp stores the diagonal coefficients used to update the remaining part of the result.
*/
int startBlock = i;
int endBlock = startBlock + (IsLower ? 4 : -4);
int endBlock = startBlock + (IsLowerTriangular ? 4 : -4);
Matrix<Scalar,4,1> btmp;
for (;IsLower ? i<endBlock : i>endBlock;
i += IsLower ? 1 : -1)
for (;IsLowerTriangular ? i<endBlock : i>endBlock;
i += IsLowerTriangular ? 1 : -1)
{
if(!(Lhs::Flags & UnitDiagBit))
other.coeffRef(i,c) /= lhs.coeff(i,i);
int remainingSize = IsLower ? endBlock-i-1 : i-endBlock-1;
int remainingSize = IsLowerTriangular ? endBlock-i-1 : i-endBlock-1;
if (remainingSize>0)
other.col(c).segment((IsLower ? i : endBlock) + 1, remainingSize) -=
other.col(c).segment((IsLowerTriangular ? i : endBlock) + 1, remainingSize) -=
other.coeffRef(i,c)
* Block<Lhs,Dynamic,1>(lhs, (IsLower ? i : endBlock) + 1, i, remainingSize, 1);
btmp.coeffRef(IsLower ? i-startBlock : remainingSize) = -other.coeffRef(i,c);
* Block<Lhs,Dynamic,1>(lhs, (IsLowerTriangular ? i : endBlock) + 1, i, remainingSize, 1);
btmp.coeffRef(IsLowerTriangular ? i-startBlock : remainingSize) = -other.coeffRef(i,c);
}
/* Now we can efficiently update the remaining part of the result as a matrix * vector product.
@@ -187,11 +187,11 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,ColMajor|IsDense>
// FIXME this is cool but what about conjugate/adjoint expressions ? do we want to evaluate them ?
// this is a more general problem though.
ei_cache_friendly_product_colmajor_times_vector(
IsLower ? size-endBlock : endBlock+1,
&(lhs.const_cast_derived().coeffRef(IsLower ? endBlock : 0, IsLower ? startBlock : endBlock+1)),
IsLowerTriangular ? size-endBlock : endBlock+1,
&(lhs.const_cast_derived().coeffRef(IsLowerTriangular ? endBlock : 0, IsLowerTriangular ? startBlock : endBlock+1)),
lhs.stride(),
btmp, &(other.coeffRef(IsLower ? endBlock : 0, c)));
// if (IsLower)
btmp, &(other.coeffRef(IsLowerTriangular ? endBlock : 0, c)));
// if (IsLowerTriangular)
// other.col(c).end(size-endBlock) += (lhs.block(endBlock, startBlock, size-endBlock, endBlock-startBlock)
// * other.col(c).block(startBlock,endBlock-startBlock)).lazy();
// else
@@ -201,7 +201,7 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,ColMajor|IsDense>
/* Now we have to process the remaining part as usual */
int i;
for(i=blockyEnd; IsLower ? i<size-1 : i>0; i += (IsLower ? 1 : -1) )
for(i=blockyEnd; IsLowerTriangular ? i<size-1 : i>0; i += (IsLowerTriangular ? 1 : -1) )
{
if(!(Lhs::Flags & UnitDiagBit))
other.coeffRef(i,c) /= lhs.coeff(i,i);
@@ -209,7 +209,7 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,ColMajor|IsDense>
/* NOTE we cannot use lhs.col(i).end(size-i-1) because Part::coeffRef gets called by .col() to
* get the address of the start of the row
*/
if(IsLower)
if(IsLowerTriangular)
other.col(c).end(size-i-1) -= other.coeffRef(i,c) * Block<Lhs,Dynamic,1>(lhs, i+1,i, size-i-1,1);
else
other.col(c).start(i) -= other.coeffRef(i,c) * Block<Lhs,Dynamic,1>(lhs, 0,i, i, 1);
@@ -236,7 +236,7 @@ void MatrixBase<Derived>::solveTriangularInPlace(MatrixBase<OtherDerived>& other
enum { copy = ei_traits<OtherDerived>::Flags & RowMajorBit };
typedef typename ei_meta_if<copy,
typename ei_eval_to_column_major<OtherDerived>::type, OtherDerived&>::ret OtherCopy;
typename ei_plain_matrix_type_column_major<OtherDerived>::type, OtherDerived&>::ret OtherCopy;
OtherCopy otherCopy(other.derived());
ei_solve_triangular_selector<Derived, typename ei_unref<OtherCopy>::type>::run(derived(), otherCopy);
@@ -278,10 +278,10 @@ void MatrixBase<Derived>::solveTriangularInPlace(MatrixBase<OtherDerived>& other
*/
template<typename Derived>
template<typename OtherDerived>
typename ei_eval_to_column_major<OtherDerived>::type
typename ei_plain_matrix_type_column_major<OtherDerived>::type
MatrixBase<Derived>::solveTriangular(const MatrixBase<OtherDerived>& other) const
{
typename ei_eval_to_column_major<OtherDerived>::type res(other);
typename ei_plain_matrix_type_column_major<OtherDerived>::type res(other);
solveTriangularInPlace(res);
return res;
}

View File

@@ -168,10 +168,10 @@ struct ei_sum_impl<Derived, NoVectorization, NoUnrolling>
ei_assert(mat.rows()>0 && mat.cols()>0 && "you are using a non initialized matrix");
Scalar res;
res = mat.coeff(0, 0);
for(int i = 1; i < mat.rows(); i++)
for(int i = 1; i < mat.rows(); ++i)
res += mat.coeff(i, 0);
for(int j = 1; j < mat.cols(); j++)
for(int i = 0; i < mat.rows(); i++)
for(int j = 1; j < mat.cols(); ++j)
for(int i = 0; i < mat.rows(); ++i)
res += mat.coeff(i, j);
return res;
}
@@ -217,10 +217,10 @@ struct ei_sum_impl<Derived, LinearVectorization, NoUnrolling>
res = Scalar(0);
}
for(int index = 0; index < alignedStart; index++)
for(int index = 0; index < alignedStart; ++index)
res += mat.coeff(index);
for(int index = alignedEnd; index < size; index++)
for(int index = alignedEnd; index < size; ++index)
res += mat.coeff(index);
return res;

View File

@@ -167,7 +167,7 @@ struct ei_inplace_transpose_selector;
template<typename MatrixType>
struct ei_inplace_transpose_selector<MatrixType,true> { // square matrix
static void run(MatrixType& m) {
m.template part<StrictlyUpper>().swap(m.transpose());
m.template part<StrictlyUpperTriangular>().swap(m.transpose());
}
};
@@ -175,7 +175,7 @@ template<typename MatrixType>
struct ei_inplace_transpose_selector<MatrixType,false> { // non square matrix
static void run(MatrixType& m) {
if (m.rows()==m.cols())
m.template part<StrictlyUpper>().swap(m.transpose());
m.template part<StrictlyUpperTriangular>().swap(m.transpose());
else
m.set(m.transpose().eval());
}

View File

@@ -55,10 +55,10 @@ struct ei_visitor_impl<Visitor, Derived, Dynamic>
inline static void run(const Derived& mat, Visitor& visitor)
{
visitor.init(mat.coeff(0,0), 0, 0);
for(int i = 1; i < mat.rows(); i++)
for(int i = 1; i < mat.rows(); ++i)
visitor(mat.coeff(i, 0), i, 0);
for(int j = 1; j < mat.cols(); j++)
for(int i = 0; i < mat.rows(); i++)
for(int j = 1; j < mat.cols(); ++j)
for(int i = 0; i < mat.rows(); ++i)
visitor(mat.coeff(i, j), i, j);
}
};

View File

@@ -37,17 +37,17 @@ template<> struct ei_unpacket_traits<__m128> { typedef float type; enum {size=
template<> struct ei_unpacket_traits<__m128d> { typedef double type; enum {size=2}; };
template<> struct ei_unpacket_traits<__m128i> { typedef int type; enum {size=4}; };
template<> inline __m128 ei_padd(const __m128& a, const __m128& b) { return _mm_add_ps(a,b); }
template<> inline __m128d ei_padd(const __m128d& a, const __m128d& b) { return _mm_add_pd(a,b); }
template<> inline __m128i ei_padd(const __m128i& a, const __m128i& b) { return _mm_add_epi32(a,b); }
template<> EIGEN_STRONG_INLINE __m128 ei_padd<__m128>(const __m128& a, const __m128& b) { return _mm_add_ps(a,b); }
template<> EIGEN_STRONG_INLINE __m128d ei_padd<__m128d>(const __m128d& a, const __m128d& b) { return _mm_add_pd(a,b); }
template<> EIGEN_STRONG_INLINE __m128i ei_padd<__m128i>(const __m128i& a, const __m128i& b) { return _mm_add_epi32(a,b); }
template<> inline __m128 ei_psub(const __m128& a, const __m128& b) { return _mm_sub_ps(a,b); }
template<> inline __m128d ei_psub(const __m128d& a, const __m128d& b) { return _mm_sub_pd(a,b); }
template<> inline __m128i ei_psub(const __m128i& a, const __m128i& b) { return _mm_sub_epi32(a,b); }
template<> EIGEN_STRONG_INLINE __m128 ei_psub<__m128>(const __m128& a, const __m128& b) { return _mm_sub_ps(a,b); }
template<> EIGEN_STRONG_INLINE __m128d ei_psub<__m128d>(const __m128d& a, const __m128d& b) { return _mm_sub_pd(a,b); }
template<> EIGEN_STRONG_INLINE __m128i ei_psub<__m128i>(const __m128i& a, const __m128i& b) { return _mm_sub_epi32(a,b); }
template<> inline __m128 ei_pmul(const __m128& a, const __m128& b) { return _mm_mul_ps(a,b); }
template<> inline __m128d ei_pmul(const __m128d& a, const __m128d& b) { return _mm_mul_pd(a,b); }
template<> inline __m128i ei_pmul(const __m128i& a, const __m128i& b)
template<> EIGEN_STRONG_INLINE __m128 ei_pmul<__m128>(const __m128& a, const __m128& b) { return _mm_mul_ps(a,b); }
template<> EIGEN_STRONG_INLINE __m128d ei_pmul<__m128d>(const __m128d& a, const __m128d& b) { return _mm_mul_pd(a,b); }
template<> EIGEN_STRONG_INLINE __m128i ei_pmul<__m128i>(const __m128i& a, const __m128i& b)
{
return _mm_or_si128(
_mm_and_si128(
@@ -59,108 +59,108 @@ template<> inline __m128i ei_pmul(const __m128i& a, const __m128i& b)
_mm_setr_epi32(0xffffffff,0,0xffffffff,0)), 4));
}
template<> inline __m128 ei_pdiv(const __m128& a, const __m128& b) { return _mm_div_ps(a,b); }
template<> inline __m128d ei_pdiv(const __m128d& a, const __m128d& b) { return _mm_div_pd(a,b); }
template<> inline __m128i ei_pdiv(const __m128i& /*a*/, const __m128i& /*b*/)
template<> EIGEN_STRONG_INLINE __m128 ei_pdiv<__m128>(const __m128& a, const __m128& b) { return _mm_div_ps(a,b); }
template<> EIGEN_STRONG_INLINE __m128d ei_pdiv<__m128d>(const __m128d& a, const __m128d& b) { return _mm_div_pd(a,b); }
template<> EIGEN_STRONG_INLINE __m128i ei_pdiv<__m128i>(const __m128i& /*a*/, const __m128i& /*b*/)
{ ei_assert(false && "packet integer division are not supported by SSE");
__m128i dummy;
return dummy;
}
// for some weird raisons, it has to be overloaded for packet integer
template<> inline __m128i ei_pmadd(const __m128i& a, const __m128i& b, const __m128i& c) { return ei_padd(ei_pmul(a,b), c); }
template<> EIGEN_STRONG_INLINE __m128i ei_pmadd(const __m128i& a, const __m128i& b, const __m128i& c) { return ei_padd(ei_pmul(a,b), c); }
template<> inline __m128 ei_pmin(const __m128& a, const __m128& b) { return _mm_min_ps(a,b); }
template<> inline __m128d ei_pmin(const __m128d& a, const __m128d& b) { return _mm_min_pd(a,b); }
template<> EIGEN_STRONG_INLINE __m128 ei_pmin<__m128>(const __m128& a, const __m128& b) { return _mm_min_ps(a,b); }
template<> EIGEN_STRONG_INLINE __m128d ei_pmin<__m128d>(const __m128d& a, const __m128d& b) { return _mm_min_pd(a,b); }
// FIXME this vectorized min operator is likely to be slower than the standard one
template<> inline __m128i ei_pmin(const __m128i& a, const __m128i& b)
template<> EIGEN_STRONG_INLINE __m128i ei_pmin<__m128i>(const __m128i& a, const __m128i& b)
{
__m128i mask = _mm_cmplt_epi32(a,b);
return _mm_or_si128(_mm_and_si128(mask,a),_mm_andnot_si128(mask,b));
}
template<> inline __m128 ei_pmax(const __m128& a, const __m128& b) { return _mm_max_ps(a,b); }
template<> inline __m128d ei_pmax(const __m128d& a, const __m128d& b) { return _mm_max_pd(a,b); }
template<> EIGEN_STRONG_INLINE __m128 ei_pmax<__m128>(const __m128& a, const __m128& b) { return _mm_max_ps(a,b); }
template<> EIGEN_STRONG_INLINE __m128d ei_pmax<__m128d>(const __m128d& a, const __m128d& b) { return _mm_max_pd(a,b); }
// FIXME this vectorized max operator is likely to be slower than the standard one
template<> inline __m128i ei_pmax(const __m128i& a, const __m128i& b)
template<> EIGEN_STRONG_INLINE __m128i ei_pmax<__m128i>(const __m128i& a, const __m128i& b)
{
__m128i mask = _mm_cmpgt_epi32(a,b);
return _mm_or_si128(_mm_and_si128(mask,a),_mm_andnot_si128(mask,b));
}
template<> inline __m128 ei_pload(const float* from) { return _mm_load_ps(from); }
template<> inline __m128d ei_pload(const double* from) { return _mm_load_pd(from); }
template<> inline __m128i ei_pload(const int* from) { return _mm_load_si128(reinterpret_cast<const __m128i*>(from)); }
template<> EIGEN_STRONG_INLINE __m128 ei_pload<float>(const float* from) { return _mm_load_ps(from); }
template<> EIGEN_STRONG_INLINE __m128d ei_pload<double>(const double* from) { return _mm_load_pd(from); }
template<> EIGEN_STRONG_INLINE __m128i ei_pload<int>(const int* from) { return _mm_load_si128(reinterpret_cast<const __m128i*>(from)); }
template<> inline __m128 ei_ploadu(const float* from) { return _mm_loadu_ps(from); }
// template<> inline __m128 ei_ploadu(const float* from) {
template<> EIGEN_STRONG_INLINE __m128 ei_ploadu<float>(const float* from) { return _mm_loadu_ps(from); }
// template<> EIGEN_STRONG_INLINE __m128 ei_ploadu(const float* from) {
// if (size_t(from)&0xF)
// return _mm_loadu_ps(from);
// else
// return _mm_loadu_ps(from);
// }
template<> inline __m128d ei_ploadu(const double* from) { return _mm_loadu_pd(from); }
template<> inline __m128i ei_ploadu(const int* from) { return _mm_loadu_si128(reinterpret_cast<const __m128i*>(from)); }
template<> EIGEN_STRONG_INLINE __m128d ei_ploadu<double>(const double* from) { return _mm_loadu_pd(from); }
template<> EIGEN_STRONG_INLINE __m128i ei_ploadu<int>(const int* from) { return _mm_loadu_si128(reinterpret_cast<const __m128i*>(from)); }
template<> inline __m128 ei_pset1(const float& from) { return _mm_set1_ps(from); }
template<> inline __m128d ei_pset1(const double& from) { return _mm_set1_pd(from); }
template<> inline __m128i ei_pset1(const int& from) { return _mm_set1_epi32(from); }
template<> EIGEN_STRONG_INLINE __m128 ei_pset1<float>(const float& from) { return _mm_set1_ps(from); }
template<> EIGEN_STRONG_INLINE __m128d ei_pset1<double>(const double& from) { return _mm_set1_pd(from); }
template<> EIGEN_STRONG_INLINE __m128i ei_pset1<int>(const int& from) { return _mm_set1_epi32(from); }
template<> inline void ei_pstore(float* to, const __m128& from) { _mm_store_ps(to, from); }
template<> inline void ei_pstore(double* to, const __m128d& from) { _mm_store_pd(to, from); }
template<> inline void ei_pstore(int* to, const __m128i& from) { _mm_store_si128(reinterpret_cast<__m128i*>(to), from); }
template<> EIGEN_STRONG_INLINE void ei_pstore<float>(float* to, const __m128& from) { _mm_store_ps(to, from); }
template<> EIGEN_STRONG_INLINE void ei_pstore<double>(double* to, const __m128d& from) { _mm_store_pd(to, from); }
template<> EIGEN_STRONG_INLINE void ei_pstore<int>(int* to, const __m128i& from) { _mm_store_si128(reinterpret_cast<__m128i*>(to), from); }
template<> inline void ei_pstoreu(float* to, const __m128& from) { _mm_storeu_ps(to, from); }
template<> inline void ei_pstoreu(double* to, const __m128d& from) { _mm_storeu_pd(to, from); }
template<> inline void ei_pstoreu(int* to, const __m128i& from) { _mm_storeu_si128(reinterpret_cast<__m128i*>(to), from); }
template<> EIGEN_STRONG_INLINE void ei_pstoreu<float>(float* to, const __m128& from) { _mm_storeu_ps(to, from); }
template<> EIGEN_STRONG_INLINE void ei_pstoreu<double>(double* to, const __m128d& from) { _mm_storeu_pd(to, from); }
template<> EIGEN_STRONG_INLINE void ei_pstoreu<int>(int* to, const __m128i& from) { _mm_storeu_si128(reinterpret_cast<__m128i*>(to), from); }
template<> inline float ei_pfirst(const __m128& a) { return _mm_cvtss_f32(a); }
template<> inline double ei_pfirst(const __m128d& a) { return _mm_cvtsd_f64(a); }
template<> inline int ei_pfirst(const __m128i& a) { return _mm_cvtsi128_si32(a); }
template<> EIGEN_STRONG_INLINE float ei_pfirst<__m128>(const __m128& a) { return _mm_cvtss_f32(a); }
template<> EIGEN_STRONG_INLINE double ei_pfirst<__m128d>(const __m128d& a) { return _mm_cvtsd_f64(a); }
template<> EIGEN_STRONG_INLINE int ei_pfirst<__m128i>(const __m128i& a) { return _mm_cvtsi128_si32(a); }
#ifdef __SSE3__
// TODO implement SSE2 versions as well as integer versions
inline __m128 ei_preduxp(const __m128* vecs)
template<> EIGEN_STRONG_INLINE __m128 ei_preduxp<__m128>(const __m128* vecs)
{
return _mm_hadd_ps(_mm_hadd_ps(vecs[0], vecs[1]),_mm_hadd_ps(vecs[2], vecs[3]));
}
inline __m128d ei_preduxp(const __m128d* vecs)
template<> EIGEN_STRONG_INLINE __m128d ei_preduxp<__m128d>(const __m128d* vecs)
{
return _mm_hadd_pd(vecs[0], vecs[1]);
}
// SSSE3 version:
// inline __m128i ei_preduxp(const __m128i* vecs)
// EIGEN_STRONG_INLINE __m128i ei_preduxp(const __m128i* vecs)
// {
// return _mm_hadd_epi32(_mm_hadd_epi32(vecs[0], vecs[1]),_mm_hadd_epi32(vecs[2], vecs[3]));
// }
inline float ei_predux(const __m128& a)
template<> EIGEN_STRONG_INLINE float ei_predux<__m128>(const __m128& a)
{
__m128 tmp0 = _mm_hadd_ps(a,a);
return ei_pfirst(_mm_hadd_ps(tmp0, tmp0));
}
inline double ei_predux(const __m128d& a) { return ei_pfirst(_mm_hadd_pd(a, a)); }
template<> EIGEN_STRONG_INLINE double ei_predux<__m128d>(const __m128d& a) { return ei_pfirst(_mm_hadd_pd(a, a)); }
// SSSE3 version:
// inline float ei_predux(const __m128i& a)
// EIGEN_STRONG_INLINE float ei_predux(const __m128i& a)
// {
// __m128i tmp0 = _mm_hadd_epi32(a,a);
// return ei_pfirst(_mm_hadd_epi32(tmp0, tmp0));
// }
#else
// SSE2 versions
inline float ei_predux(const __m128& a)
template<> EIGEN_STRONG_INLINE float ei_predux<__m128>(const __m128& a)
{
__m128 tmp = _mm_add_ps(a, _mm_movehl_ps(a,a));
return ei_pfirst(_mm_add_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1)));
}
inline double ei_predux(const __m128d& a)
template<> EIGEN_STRONG_INLINE double ei_predux<__m128d>(const __m128d& a)
{
return ei_pfirst(_mm_add_sd(a, _mm_unpackhi_pd(a,a)));
}
inline __m128 ei_preduxp(const __m128* vecs)
template<> EIGEN_STRONG_INLINE __m128 ei_preduxp<__m128>(const __m128* vecs)
{
__m128 tmp0, tmp1, tmp2;
tmp0 = _mm_unpacklo_ps(vecs[0], vecs[1]);
@@ -174,19 +174,19 @@ inline __m128 ei_preduxp(const __m128* vecs)
return _mm_add_ps(tmp0, tmp2);
}
inline __m128d ei_preduxp(const __m128d* vecs)
template<> EIGEN_STRONG_INLINE __m128d ei_preduxp<__m128d>(const __m128d* vecs)
{
return _mm_add_pd(_mm_unpacklo_pd(vecs[0], vecs[1]), _mm_unpackhi_pd(vecs[0], vecs[1]));
}
#endif // SSE3
inline int ei_predux(const __m128i& a)
template<> EIGEN_STRONG_INLINE int ei_predux<__m128i>(const __m128i& a)
{
__m128i tmp = _mm_add_epi32(a, _mm_unpackhi_epi64(a,a));
return ei_pfirst(tmp) + ei_pfirst(_mm_shuffle_epi32(tmp, 1));
}
inline __m128i ei_preduxp(const __m128i* vecs)
template<> EIGEN_STRONG_INLINE __m128i ei_preduxp<__m128i>(const __m128i* vecs)
{
__m128i tmp0, tmp1, tmp2;
tmp0 = _mm_unpacklo_epi32(vecs[0], vecs[1]);
@@ -201,13 +201,13 @@ inline __m128i ei_preduxp(const __m128i* vecs)
}
#if (defined __GNUC__)
// template <> inline __m128 ei_pmadd(const __m128& a, const __m128& b, const __m128& c)
// template <> EIGEN_STRONG_INLINE __m128 ei_pmadd(const __m128& a, const __m128& b, const __m128& c)
// {
// __m128 res = b;
// asm("mulps %[a], %[b] \n\taddps %[c], %[b]" : [b] "+x" (res) : [a] "x" (a), [c] "x" (c));
// return res;
// }
// inline __m128i _mm_alignr_epi8(const __m128i& a, const __m128i& b, const int i)
// EIGEN_STRONG_INLINE __m128i _mm_alignr_epi8(const __m128i& a, const __m128i& b, const int i)
// {
// __m128i res = a;
// asm("palignr %[i], %[a], %[b] " : [b] "+x" (res) : [a] "x" (a), [i] "i" (i));
@@ -220,7 +220,7 @@ inline __m128i ei_preduxp(const __m128i* vecs)
template<int Offset>
struct ei_palign_impl<Offset,__m128>
{
inline static void run(__m128& first, const __m128& second)
EIGEN_STRONG_INLINE static void run(__m128& first, const __m128& second)
{
if (Offset!=0)
first = _mm_castsi128_ps(_mm_alignr_epi8(_mm_castps_si128(second), _mm_castps_si128(first), Offset*4));
@@ -230,7 +230,7 @@ struct ei_palign_impl<Offset,__m128>
template<int Offset>
struct ei_palign_impl<Offset,__m128i>
{
inline static void run(__m128i& first, const __m128i& second)
EIGEN_STRONG_INLINE static void run(__m128i& first, const __m128i& second)
{
if (Offset!=0)
first = _mm_alignr_epi8(second,first, Offset*4);
@@ -240,7 +240,7 @@ struct ei_palign_impl<Offset,__m128i>
template<int Offset>
struct ei_palign_impl<Offset,__m128d>
{
inline static void run(__m128d& first, const __m128d& second)
EIGEN_STRONG_INLINE static void run(__m128d& first, const __m128d& second)
{
if (Offset==1)
first = _mm_castsi128_pd(_mm_alignr_epi8(_mm_castpd_si128(second), _mm_castpd_si128(first), 8));
@@ -251,7 +251,7 @@ struct ei_palign_impl<Offset,__m128d>
template<int Offset>
struct ei_palign_impl<Offset,__m128>
{
inline static void run(__m128& first, const __m128& second)
EIGEN_STRONG_INLINE static void run(__m128& first, const __m128& second)
{
if (Offset==1)
{
@@ -274,7 +274,7 @@ struct ei_palign_impl<Offset,__m128>
template<int Offset>
struct ei_palign_impl<Offset,__m128i>
{
inline static void run(__m128i& first, const __m128i& second)
EIGEN_STRONG_INLINE static void run(__m128i& first, const __m128i& second)
{
if (Offset==1)
{
@@ -297,7 +297,7 @@ struct ei_palign_impl<Offset,__m128i>
template<int Offset>
struct ei_palign_impl<Offset,__m128d>
{
inline static void run(__m128d& first, const __m128d& second)
EIGEN_STRONG_INLINE static void run(__m128d& first, const __m128d& second)
{
if (Offset==1)
{

View File

@@ -185,16 +185,16 @@ const unsigned int HereditaryBits = RowMajorBit
| SparseBit;
// Possible values for the Mode parameter of part() and of extract()
const unsigned int Upper = UpperTriangularBit;
const unsigned int StrictlyUpper = UpperTriangularBit | ZeroDiagBit;
const unsigned int Lower = LowerTriangularBit;
const unsigned int StrictlyLower = LowerTriangularBit | ZeroDiagBit;
const unsigned int UpperTriangular = UpperTriangularBit;
const unsigned int StrictlyUpperTriangular = UpperTriangularBit | ZeroDiagBit;
const unsigned int LowerTriangular = LowerTriangularBit;
const unsigned int StrictlyLowerTriangular = LowerTriangularBit | ZeroDiagBit;
const unsigned int SelfAdjoint = SelfAdjointBit;
// additional possible values for the Mode parameter of extract()
const unsigned int UnitUpper = UpperTriangularBit | UnitDiagBit;
const unsigned int UnitLower = LowerTriangularBit | UnitDiagBit;
const unsigned int Diagonal = Upper | Lower;
const unsigned int UnitUpperTriangular = UpperTriangularBit | UnitDiagBit;
const unsigned int UnitLowerTriangular = LowerTriangularBit | UnitDiagBit;
const unsigned int Diagonal = UpperTriangular | LowerTriangular;
enum { Aligned, Unaligned };
enum { ForceAligned, AsRequested };

View File

@@ -0,0 +1,9 @@
#ifndef EIGEN_DISABLEMSVCWARNINGS_H
#define EIGEN_DISABLEMSVCWARNINGS_H
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable : 4181 4244 4127 4211 )
#endif
#endif // EIGEN_DISABLEMSVCWARNINGS_H

View File

@@ -0,0 +1,8 @@
#ifndef EIGEN_ENABLEMSVCWARNINGS_H
#define EIGEN_ENABLEMSVCWARNINGS_H
#ifdef _MSC_VER
#pragma warning( pop )
#endif
#endif // EIGEN_ENABLEMSVCWARNINGS_H

View File

@@ -84,36 +84,61 @@ using Eigen::ei_cos;
#define EIGEN_ONLY_USED_FOR_DEBUG(x)
#endif
// EIGEN_ALWAYS_INLINE_ATTRIB should be use in the declaration of function
// which should be inlined even in debug mode.
// FIXME with the always_inline attribute,
// gcc 3.4.x reports the following compilation error:
// Eval.h:91: sorry, unimplemented: inlining failed in call to 'const Eigen::Eval<Derived> Eigen::MatrixBase<Scalar, Derived>::eval() const'
// : function body not available
#if EIGEN_GNUC_AT_LEAST(4,0)
#define EIGEN_ALWAYS_INLINE __attribute__((always_inline)) inline
#define EIGEN_ALWAYS_INLINE_ATTRIB __attribute__((always_inline))
#else
#define EIGEN_ALWAYS_INLINE inline
#define EIGEN_ALWAYS_INLINE_ATTRIB
#endif
// EIGEN_FORCE_INLINE means "inline as much as possible"
#if (defined _MSC_VER)
#define EIGEN_STRONG_INLINE __forceinline
#else
#define EIGEN_STRONG_INLINE inline
#endif
#if (defined __GNUC__)
#define EIGEN_DONT_INLINE __attribute__((noinline))
#elif (defined _MSC_VER)
#define EIGEN_DONT_INLINE __declspec(noinline)
#else
#define EIGEN_DONT_INLINE
#endif
#if (defined __GNUC__)
#define EIGEN_DEPRECATED __attribute__((deprecated))
#elif (defined _MSC_VER)
#define EIGEN_DEPRECATED __declspec(deprecated)
#else
#define EIGEN_DEPRECATED
#endif
/* EIGEN_ALIGN_128 forces data to be 16-byte aligned, EVEN if vectorization (EIGEN_VECTORIZE) is disabled,
* so that vectorization doesn't affect binary compatibility.
*
* If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link
* vectorized and non-vectorized code.
*/
#if (defined __GNUC__)
#define EIGEN_ALIGN_128 __attribute__ ((aligned(16)))
#define EIGEN_ALIGN_128 __attribute__((aligned(16)))
#elif (defined _MSC_VER)
#define EIGEN_ALIGN_128 __declspec(align(16))
#else
#define EIGEN_ALIGN_128
#endif
#define EIGEN_RESTRICT __restrict
#ifndef EIGEN_STACK_ALLOCATION_LIMIT
#define EIGEN_STACK_ALLOCATION_LIMIT 16000000
#endif
#ifndef EIGEN_DEFAULT_IO_FORMAT
#define EIGEN_DEFAULT_IO_FORMAT Eigen::IOFormat()
#endif
@@ -124,18 +149,18 @@ using Eigen::ei_cos;
#define EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, Op) \
template<typename OtherDerived> \
Derived& operator Op(const Eigen::MatrixBase<OtherDerived>& other) \
EIGEN_STRONG_INLINE Derived& operator Op(const Eigen::MatrixBase<OtherDerived>& other) \
{ \
return Eigen::MatrixBase<Derived>::operator Op(other.derived()); \
} \
Derived& operator Op(const Derived& other) \
EIGEN_STRONG_INLINE Derived& operator Op(const Derived& other) \
{ \
return Eigen::MatrixBase<Derived>::operator Op(other); \
}
#define EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, Op) \
template<typename Other> \
Derived& operator Op(const Other& scalar) \
EIGEN_STRONG_INLINE Derived& operator Op(const Other& scalar) \
{ \
return Eigen::MatrixBase<Derived>::operator Op(scalar); \
}
@@ -153,7 +178,6 @@ typedef typename Eigen::ei_traits<Derived>::Scalar Scalar; \
typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; \
typedef typename Base::PacketScalar PacketScalar; \
typedef typename Eigen::ei_nested<Derived>::type Nested; \
typedef typename Eigen::ei_eval<Derived>::type Eval; \
enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \
ColsAtCompileTime = Eigen::ei_traits<Derived>::ColsAtCompileTime, \
MaxRowsAtCompileTime = Eigen::ei_traits<Derived>::MaxRowsAtCompileTime, \

View File

@@ -26,7 +26,7 @@
#ifndef EIGEN_MEMORY_H
#define EIGEN_MEMORY_H
#ifdef EIGEN_VECTORIZE
#if defined(EIGEN_VECTORIZE) && !defined(_MSC_VER)
// it seems we cannot assume posix_memalign is defined in the stdlib header
extern "C" int posix_memalign (void **, size_t, size_t) throw ();
#endif
@@ -40,8 +40,13 @@ template <typename T, int Size, bool Align> struct ei_aligned_array
ei_aligned_array()
{
ei_assert((reinterpret_cast<unsigned int>(array) & 0xf) == 0
#ifdef EIGEN_VECTORIZE // we only want this assertion if EIGEN_VECTORIZE is defined.
// indeed, if it's not defined then WithAlignedOperatorNew is empty and hence there's not much point
// requiring the user to inherit it! Would be best practice, but we already decided at several places
// to only do special alignment if vectorization is enabled.
ei_assert((reinterpret_cast<size_t>(array) & 0xf) == 0
&& "this assertion is explained here: http://eigen.tuxfamily.org/api/UnalignedArrayAssert.html **** READ THIS WEB PAGE !!! ****");
#endif
}
};
@@ -50,22 +55,55 @@ template <typename T, int Size> struct ei_aligned_array<T,Size,false>
T array[Size];
};
/** \internal allocates \a size * sizeof(\a T) bytes with 16 bytes alignment */
struct ei_byte_forcing_aligned_malloc
{
unsigned char c; // sizeof must be 1.
};
template<typename T> struct ei_force_aligned_malloc { enum { ret = 0 }; };
template<> struct ei_force_aligned_malloc<ei_byte_forcing_aligned_malloc> { enum { ret = 1 }; };
/** \internal allocates \a size * sizeof(\a T) bytes. If vectorization is enabled and T is such that a packet
* containts more than one T, then the returned pointer is guaranteed to have 16 bytes alignment.
* On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown.
*/
template<typename T>
inline T* ei_aligned_malloc(size_t size)
{
T* result;
#ifdef EIGEN_VECTORIZE
if (ei_packet_traits<T>::size>1)
if(ei_packet_traits<T>::size>1 || ei_force_aligned_malloc<T>::ret)
{
void* ptr;
if (posix_memalign(&ptr, 16, size*sizeof(T))==0)
return static_cast<T*>(ptr);
else
return 0;
#ifdef __linux
#ifdef EIGEN_EXCEPTIONS
const int failed =
#endif
posix_memalign(reinterpret_cast<void**>(&result), 16, size*sizeof(T));
#else
#ifdef _MSC_VER
result = static_cast<T*>(_aligned_malloc(size*sizeof(T), 16));
#else
result = static_cast<T*>(_mm_malloc(size*sizeof(T),16));
#endif
#ifdef EIGEN_EXCEPTIONS
const int failed = (result == 0);
#endif
#endif
#ifdef EIGEN_EXCEPTIONS
if(failed)
throw std::bad_alloc();
#endif
}
else
#endif
return new T[size];
result = new T[size]; // here we really want a new, not a malloc. Justification: if the user uses Eigen on
// some fancy scalar type such as multiple-precision numbers, and this type has a custom operator new,
// then we want to honor this operator new! Anyway this type won't have vectorization so the vectorizing path
// is irrelevant here. Yes, we should say somewhere in the docs that if the user uses a custom scalar type then
// he can't have both vectorization and a custom operator new on his scalar type.
return result;
}
/** \internal free memory allocated with ei_aligned_malloc */
@@ -73,9 +111,15 @@ template<typename T>
inline void ei_aligned_free(T* ptr)
{
#ifdef EIGEN_VECTORIZE
if (ei_packet_traits<T>::size>1)
free(ptr);
else
if (ei_packet_traits<T>::size>1 || ei_force_aligned_malloc<T>::ret)
#if defined(__linux)
free(ptr);
#elif defined(_MSC_VER)
_aligned_free(ptr);
#else
_mm_free(ptr);
#endif
else
#endif
delete[] ptr;
}
@@ -89,7 +133,7 @@ inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset)
const int PacketAlignedMask = PacketSize-1;
const bool Vectorized = PacketSize>1;
return Vectorized
? std::min<int>( (PacketSize - ((size_t(ptr)/sizeof(Scalar)) & PacketAlignedMask))
? std::min<int>( (PacketSize - (int((size_t(ptr)/sizeof(Scalar))) & PacketAlignedMask))
& PacketAlignedMask, maxOffset)
: 0;
}
@@ -105,11 +149,12 @@ inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset)
* \endcode
*/
#ifdef __linux__
# define ei_alloc_stack(TYPE,SIZE) ((sizeof(TYPE)*(SIZE)>16000000) ? new TYPE[SIZE] : (TYPE*)alloca(sizeof(TYPE)*(SIZE)))
# define ei_free_stack(PTR,TYPE,SIZE) if (sizeof(TYPE)*SIZE>16000000) delete[] PTR
#define ei_alloc_stack(TYPE,SIZE) ((sizeof(TYPE)*(SIZE)>EIGEN_STACK_ALLOCATION_LIMIT) ? \
new TYPE[SIZE] : (TYPE*)alloca(sizeof(TYPE)*(SIZE)))
#define ei_free_stack(PTR,TYPE,SIZE) if (sizeof(TYPE)*SIZE>EIGEN_STACK_ALLOCATION_LIMIT) delete[] PTR
#else
# define ei_alloc_stack(TYPE,SIZE) new TYPE[SIZE]
# define ei_free_stack(PTR,TYPE,SIZE) delete[] PTR
#define ei_alloc_stack(TYPE,SIZE) new TYPE[SIZE]
#define ei_free_stack(PTR,TYPE,SIZE) delete[] PTR
#endif
/** \class WithAlignedOperatorNew
@@ -157,24 +202,16 @@ struct WithAlignedOperatorNew
void *operator new(size_t size) throw()
{
void* ptr = 0;
if (posix_memalign(&ptr, 16, size)==0)
return ptr;
else
return 0;
return ei_aligned_malloc<ei_byte_forcing_aligned_malloc>(size);
}
void *operator new[](size_t size) throw()
{
void* ptr = 0;
if (posix_memalign(&ptr, 16, size)==0)
return ptr;
else
return 0;
return ei_aligned_malloc<ei_byte_forcing_aligned_malloc>(size);
}
void operator delete(void * ptr) { free(ptr); }
void operator delete[](void * ptr) { free(ptr); }
void operator delete(void * ptr) { ei_aligned_free(static_cast<ei_byte_forcing_aligned_malloc *>(ptr)); }
void operator delete[](void * ptr) { ei_aligned_free(static_cast<ei_byte_forcing_aligned_malloc *>(ptr)); }
#endif
};

View File

@@ -69,7 +69,7 @@ template<typename T> struct ei_cleantype<T*> { typedef typename ei_cleant
*
* It supports both the current STL mechanism (using the result_type member) as well as
* upcoming next STL generation (using a templated result member).
* If none of these members is provided, then the type of the first argument is returned.
* If none of these members is provided, then the type of the first argument is returned. FIXME, that behavior is a pretty bad hack.
*/
template<typename T> struct ei_result_of {};
@@ -146,4 +146,38 @@ class ei_meta_sqrt
template<int Y, int InfX, int SupX>
class ei_meta_sqrt<Y, InfX, SupX, true> { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; };
/** \internal determines whether the product of two numeric types is allowed and what the return type is */
template<typename T, typename U> struct ei_scalar_product_traits
{
// dummy general case where T and U aren't compatible -- not allowed anyway but we catch it elsewhere
//enum { Cost = NumTraits<T>::MulCost };
typedef T ReturnType;
};
template<typename T> struct ei_scalar_product_traits<T,T>
{
//enum { Cost = NumTraits<T>::MulCost };
typedef T ReturnType;
};
template<typename T> struct ei_scalar_product_traits<T,std::complex<T> >
{
//enum { Cost = 2*NumTraits<T>::MulCost };
typedef std::complex<T> ReturnType;
};
template<typename T> struct ei_scalar_product_traits<std::complex<T>, T>
{
//enum { Cost = 2*NumTraits<T>::MulCost };
typedef std::complex<T> ReturnType;
};
// FIXME quick workaround around current limitation of ei_result_of
template<typename Scalar, typename ArgType0, typename ArgType1>
struct ei_result_of<ei_scalar_product_op<Scalar>(ArgType0,ArgType1)> {
typedef typename ei_scalar_product_traits<typename ei_cleantype<ArgType0>::type, typename ei_cleantype<ArgType1>::type>::ReturnType type;
};
#endif // EIGEN_META_H

View File

@@ -55,27 +55,39 @@
struct ei_static_assert<true>
{
enum {
you_tried_calling_a_vector_method_on_a_matrix,
you_mixed_vectors_of_different_sizes,
you_mixed_matrices_of_different_sizes,
this_method_is_only_for_vectors_of_a_specific_size,
this_method_is_only_for_matrices_of_a_specific_size,
you_made_a_programming_mistake,
you_called_a_fixed_size_method_on_a_dynamic_size_matrix_or_vector,
unaligned_load_and_store_operations_unimplemented_on_AltiVec,
numeric_type_must_be_floating_point,
coefficient_write_access_to_selfadjoint_not_supported,
writing_to_triangular_part_with_unit_diagonal_is_not_supported,
this_method_is_only_for_fixed_size,
invalid_matrix_product,
invalid_vector_vector_product__if_you_wanted_a_dot_or_coeff_wise_product_you_must_use_the_explicit_functions,
invalid_matrix_product__if_you_wanted_a_coeff_wise_product_you_must_use_the_explicit_function,
you_mixed_different_numeric_types__you_need_to_use_the_cast_method_of_MatrixBase_to_cast_numeric_types_explicitly
YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX,
YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES,
YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES,
THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE,
THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE,
YOU_MADE_A_PROGRAMMING_MISTAKE,
YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR,
UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC,
NUMERIC_TYPE_MUST_BE_FLOATING_POINT,
COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED,
WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED,
THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE,
INVALID_MATRIX_PRODUCT,
INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS,
INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION,
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY
};
};
#define EIGEN_STATIC_ASSERT(CONDITION,MSG) \
if (Eigen::ei_static_assert<CONDITION ? true : false>::MSG) {}
// Specialized implementation for MSVC to avoid "conditional
// expression is constant" warnings. This implementation doesn't
// appear to work under GCC, hence the multiple implementations.
#ifdef _MSC_VER
#define EIGEN_STATIC_ASSERT(CONDITION,MSG) \
{Eigen::ei_static_assert<CONDITION ? true : false>::MSG;}
#else
#define EIGEN_STATIC_ASSERT(CONDITION,MSG) \
if (Eigen::ei_static_assert<CONDITION ? true : false>::MSG) {}
#endif
#endif // not CXX0X
@@ -89,22 +101,22 @@
// static assertion failing if the type \a TYPE is not a vector type
#define EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE) \
EIGEN_STATIC_ASSERT(TYPE::IsVectorAtCompileTime, \
you_tried_calling_a_vector_method_on_a_matrix)
YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX)
// static assertion failing if the type \a TYPE is not fixed-size
#define EIGEN_STATIC_ASSERT_FIXED_SIZE(TYPE) \
EIGEN_STATIC_ASSERT(TYPE::SizeAtCompileTime!=Eigen::Dynamic, \
you_called_a_fixed_size_method_on_a_dynamic_size_matrix_or_vector)
YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR)
// static assertion failing if the type \a TYPE is not a vector type of the given size
#define EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(TYPE, SIZE) \
EIGEN_STATIC_ASSERT(TYPE::IsVectorAtCompileTime && TYPE::SizeAtCompileTime==SIZE, \
this_method_is_only_for_vectors_of_a_specific_size)
THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE)
// static assertion failing if the type \a TYPE is not a vector type of the given size
#define EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(TYPE, ROWS, COLS) \
EIGEN_STATIC_ASSERT(TYPE::RowsAtCompileTime==ROWS && TYPE::ColsAtCompileTime==COLS, \
this_method_is_only_for_matrices_of_a_specific_size)
THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE)
// static assertion failing if the two vector expression types are not compatible (same fixed-size or dynamic size)
#define EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(TYPE0,TYPE1) \
@@ -112,7 +124,7 @@
(int(TYPE0::SizeAtCompileTime)==Eigen::Dynamic \
|| int(TYPE1::SizeAtCompileTime)==Eigen::Dynamic \
|| int(TYPE0::SizeAtCompileTime)==int(TYPE1::SizeAtCompileTime)),\
you_mixed_vectors_of_different_sizes)
YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES)
#define EIGEN_PREDICATE_SAME_MATRIX_SIZE(TYPE0,TYPE1) \
((int(TYPE0::RowsAtCompileTime)==Eigen::Dynamic \
@@ -126,6 +138,6 @@
#define EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(TYPE0,TYPE1) \
EIGEN_STATIC_ASSERT( \
EIGEN_PREDICATE_SAME_MATRIX_SIZE(TYPE0,TYPE1),\
you_mixed_matrices_of_different_sizes)
YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES)
#endif // EIGEN_STATIC_ASSERT_H

View File

@@ -112,6 +112,10 @@ template<int _Rows, int _Cols> struct ei_size_at_compile_time
enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
};
/* ei_eval : the return type of eval(). For matrices, this is just a const reference
* in order to avoid a useless copy
*/
template<typename T, int Sparseness = ei_traits<T>::Flags&SparseBit> class ei_eval;
template<typename T> struct ei_eval<T,IsDense>
@@ -125,8 +129,30 @@ template<typename T> struct ei_eval<T,IsDense>
> type;
};
// for matrices, no need to evaluate, just use a const reference to avoid a useless copy
template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols>
struct ei_eval<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>, IsDense>
{
typedef const Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>& type;
};
template<typename T> struct ei_eval_to_column_major
/* ei_plain_matrix_type : the difference from ei_eval is that ei_plain_matrix_type is always a plain matrix type,
* whereas ei_eval is a const reference in the case of a matrix
*/
template<typename T> struct ei_plain_matrix_type
{
typedef Matrix<typename ei_traits<T>::Scalar,
ei_traits<T>::RowsAtCompileTime,
ei_traits<T>::ColsAtCompileTime,
ei_traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor,
ei_traits<T>::MaxRowsAtCompileTime,
ei_traits<T>::MaxColsAtCompileTime
> type;
};
/* ei_plain_matrix_type_column_major : same as ei_plain_matrix_type but guaranteed to be column-major
*/
template<typename T> struct ei_plain_matrix_type_column_major
{
typedef Matrix<typename ei_traits<T>::Scalar,
ei_traits<T>::RowsAtCompileTime,
@@ -158,7 +184,7 @@ template<typename T> struct ei_must_nest_by_value<NestByValue<T> > { enum { ret
* 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 EvalType = typename ei_eval<T>::type> struct ei_nested
template<typename T, int n=1, typename PlainMatrixType = typename ei_eval<T>::type> struct ei_nested
{
enum {
CostEval = (n+1) * int(NumTraits<typename ei_traits<T>::Scalar>::ReadCost),
@@ -170,7 +196,7 @@ template<typename T, int n=1, typename EvalType = typename ei_eval<T>::type> str
typename ei_meta_if<
(int(ei_traits<T>::Flags) & EvalBeforeNestingBit)
|| ( int(CostEval) <= int(CostNoEval) ),
EvalType,
PlainMatrixType,
const T&
>::ret
>::ret type;

View File

@@ -142,8 +142,8 @@ public:
template<typename OtherScalarType>
inline explicit AlignedBox(const AlignedBox<OtherScalarType,AmbientDimAtCompileTime>& other)
{
m_min = other.min().template cast<OtherScalarType>();
m_max = other.max().template cast<OtherScalarType>();
m_min = other.min().template cast<Scalar>();
m_max = other.max().template cast<Scalar>();
}
/** \returns \c true if \c *this is approximately equal to \a other, within the precision

View File

@@ -146,7 +146,7 @@ public:
template<typename OtherScalarType>
inline explicit AngleAxis(const AngleAxis<OtherScalarType>& other)
{
m_axis = other.axis().template cast<OtherScalarType>();
m_axis = other.axis().template cast<Scalar>();
m_angle = other.angle();
}

View File

@@ -70,7 +70,7 @@ public:
/** Construct a plane from its normal \a n and a point \a e onto the plane.
* \warning the vector normal is assumed to be normalized.
*/
inline Hyperplane(const VectorType& n, const VectorType e)
inline Hyperplane(const VectorType& n, const VectorType& e)
: m_coeffs(n.size()+1)
{
normal() = n;
@@ -254,7 +254,7 @@ public:
/** Copy constructor with scalar type conversion */
template<typename OtherScalarType>
inline explicit Hyperplane(const Hyperplane<OtherScalarType,AmbientDimAtCompileTime>& other)
{ m_coeffs = other.coeffs().template cast<OtherScalarType>(); }
{ m_coeffs = other.coeffs().template cast<Scalar>(); }
/** \returns \c true if \c *this is approximately equal to \a other, within the precision
* determined by \a prec.

View File

@@ -34,7 +34,7 @@
*/
template<typename Derived>
template<typename OtherDerived>
inline typename MatrixBase<Derived>::EvalType
inline typename MatrixBase<Derived>::PlainMatrixType
MatrixBase<Derived>::cross(const MatrixBase<OtherDerived>& other) const
{
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived,3)
@@ -43,7 +43,7 @@ MatrixBase<Derived>::cross(const MatrixBase<OtherDerived>& other) const
// optimize such a small temporary very well (even within a complex expression)
const typename ei_nested<Derived,2>::type lhs(derived());
const typename ei_nested<OtherDerived,2>::type rhs(other.derived());
return typename ei_eval<Derived>::type(
return typename ei_plain_matrix_type<Derived>::type(
lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1),
lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2),
lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0)
@@ -53,7 +53,7 @@ MatrixBase<Derived>::cross(const MatrixBase<OtherDerived>& other) const
template<typename Derived, int Size = Derived::SizeAtCompileTime>
struct ei_unitOrthogonal_selector
{
typedef typename ei_eval<Derived>::type VectorType;
typedef typename ei_plain_matrix_type<Derived>::type VectorType;
typedef typename ei_traits<Derived>::Scalar Scalar;
typedef typename NumTraits<Scalar>::Real RealScalar;
inline static VectorType run(const Derived& src)
@@ -96,7 +96,7 @@ struct ei_unitOrthogonal_selector
template<typename Derived>
struct ei_unitOrthogonal_selector<Derived,2>
{
typedef typename ei_eval<Derived>::type VectorType;
typedef typename ei_plain_matrix_type<Derived>::type VectorType;
inline static VectorType run(const Derived& src)
{ return VectorType(-ei_conj(src.y()), ei_conj(src.x())).normalized(); }
};
@@ -109,7 +109,7 @@ struct ei_unitOrthogonal_selector<Derived,2>
* \sa cross()
*/
template<typename Derived>
typename MatrixBase<Derived>::EvalType
typename MatrixBase<Derived>::PlainMatrixType
MatrixBase<Derived>::unitOrthogonal() const
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)

View File

@@ -118,8 +118,8 @@ public:
template<typename OtherScalarType>
inline explicit ParametrizedLine(const ParametrizedLine<OtherScalarType,AmbientDimAtCompileTime>& other)
{
m_origin = other.origin().template cast<OtherScalarType>();
m_direction = other.direction().template cast<OtherScalarType>();
m_origin = other.origin().template cast<Scalar>();
m_direction = other.direction().template cast<Scalar>();
}
/** \returns \c true if \c *this is approximately equal to \a other, within the precision

View File

@@ -207,7 +207,7 @@ public:
/** Copy constructor with scalar type conversion */
template<typename OtherScalarType>
inline explicit Quaternion(const Quaternion<OtherScalarType>& other)
{ m_coeffs = other.coeffs().template cast<OtherScalarType>(); }
{ m_coeffs = other.coeffs().template cast<Scalar>(); }
/** \returns \c true if \c *this is approximately equal to \a other, within the precision
* determined by \a prec.
@@ -279,7 +279,7 @@ inline Quaternion<Scalar>& Quaternion<Scalar>::operator=(const Quaternion& other
template<typename Scalar>
inline Quaternion<Scalar>& Quaternion<Scalar>::operator=(const AngleAxisType& aa)
{
Scalar ha = 0.5*aa.angle();
Scalar ha = Scalar(0.5)*aa.angle(); // Scalar(0.5) to suppress precision loss warnings
this->w() = ei_cos(ha);
this->vec() = ei_sin(ha) * aa.axis();
return *this;

View File

@@ -140,7 +140,7 @@ template<typename Scalar>
template<typename Derived>
Rotation2D<Scalar>& Rotation2D<Scalar>::fromRotationMatrix(const MatrixBase<Derived>& mat)
{
EIGEN_STATIC_ASSERT(Derived::RowsAtCompileTime==2 && Derived::ColsAtCompileTime==2,you_made_a_programming_mistake)
EIGEN_STATIC_ASSERT(Derived::RowsAtCompileTime==2 && Derived::ColsAtCompileTime==2,YOU_MADE_A_PROGRAMMING_MISTAKE)
m_angle = ei_atan2(mat.coeff(1,0), mat.coeff(0,0));
return *this;
}

View File

@@ -116,7 +116,7 @@ Matrix<_Scalar, _Rows, _Cols, _Storage, _MaxRows, _MaxCols>
template<typename Scalar, int Dim>
inline static Matrix<Scalar,2,2> ei_toRotationMatrix(const Scalar& s)
{
EIGEN_STATIC_ASSERT(Dim==2,you_made_a_programming_mistake)
EIGEN_STATIC_ASSERT(Dim==2,YOU_MADE_A_PROGRAMMING_MISTAKE)
return Rotation2D<Scalar>(s).toRotationMatrix();
}
@@ -130,7 +130,7 @@ template<typename Scalar, int Dim, typename OtherDerived>
inline static const MatrixBase<OtherDerived>& ei_toRotationMatrix(const MatrixBase<OtherDerived>& mat)
{
EIGEN_STATIC_ASSERT(OtherDerived::RowsAtCompileTime==Dim && OtherDerived::ColsAtCompileTime==Dim,
you_made_a_programming_mistake)
YOU_MADE_A_PROGRAMMING_MISTAKE)
return mat;
}

View File

@@ -140,7 +140,7 @@ public:
/** Copy constructor with scalar type conversion */
template<typename OtherScalarType>
inline explicit Scaling(const Scaling<OtherScalarType,Dim>& other)
{ m_coeffs = other.coeffs().template cast<OtherScalarType>(); }
{ m_coeffs = other.coeffs().template cast<Scalar>(); }
/** \returns \c true if \c *this is approximately equal to \a other, within the precision
* determined by \a prec.

View File

@@ -184,10 +184,17 @@ public:
operator * (const MatrixBase<OtherDerived> &other) const
{ return ei_transform_product_impl<OtherDerived,Dim,HDim>::run(*this,other.derived()); }
/** \returns the product expression of a transformation matrix \a a times a transform \a b
* The transformation matrix \a a must have a Dim+1 x Dim+1 sizes. */
template<typename OtherDerived>
friend inline const typename ProductReturnType<OtherDerived,MatrixType>::Type
operator * (const MatrixBase<OtherDerived> &a, const Transform &b)
{ return a.derived() * b.matrix(); }
/** Contatenates two transformations */
inline const typename ProductReturnType<MatrixType,MatrixType>::Type
inline const Transform
operator * (const Transform& other) const
{ return m_matrix * other.matrix(); }
{ return Transform(m_matrix * other.matrix()); }
/** \sa MatrixBase::setIdentity() */
void setIdentity() { m_matrix.setIdentity(); }
@@ -238,7 +245,8 @@ public:
template<typename Derived>
inline Transform operator*(const RotationBase<Derived,Dim>& r) const;
LinearMatrixType extractRotation(TransformTraits traits = Affine) const;
EIGEN_DEPRECATED LinearMatrixType extractRotation(TransformTraits traits = Affine) const { return rotation(traits); }
LinearMatrixType rotation(TransformTraits traits = Affine) const;
template<typename PositionDerived, typename OrientationType, typename ScaleDerived>
Transform& fromPositionOrientationScale(const MatrixBase<PositionDerived> &position,
@@ -263,7 +271,7 @@ public:
/** Copy constructor with scalar type conversion */
template<typename OtherScalarType>
inline explicit Transform(const Transform<OtherScalarType,Dim>& other)
{ m_matrix = other.matrix().template cast<OtherScalarType>(); }
{ m_matrix = other.matrix().template cast<Scalar>(); }
/** \returns \c true if \c *this is approximately equal to \a other, within the precision
* determined by \a prec.
@@ -307,7 +315,7 @@ Transform<Scalar,Dim>::Transform(const QMatrix& other)
template<typename Scalar, int Dim>
Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const QMatrix& other)
{
EIGEN_STATIC_ASSERT(Dim==2, you_made_a_programming_mistake)
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
m_matrix << other.m11(), other.m21(), other.dx(),
other.m12(), other.m22(), other.dy(),
0, 0, 1;
@@ -323,7 +331,7 @@ Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const QMatrix& other)
template<typename Scalar, int Dim>
QMatrix Transform<Scalar,Dim>::toQMatrix(void) const
{
EIGEN_STATIC_ASSERT(Dim==2, you_made_a_programming_mistake)
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
return QMatrix(other.coeffRef(0,0), other.coeffRef(1,0),
other.coeffRef(0,1), other.coeffRef(1,1),
other.coeffRef(0,2), other.coeffRef(1,2));
@@ -346,7 +354,7 @@ Transform<Scalar,Dim>::Transform(const QTransform& other)
template<typename Scalar, int Dim>
Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const QTransform& other)
{
EIGEN_STATIC_ASSERT(Dim==2, you_made_a_programming_mistake)
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
m_matrix << other.m11(), other.m21(), other.dx(),
other.m12(), other.m22(), other.dy(),
other.m13(), other.m23(), other.m33();
@@ -360,7 +368,7 @@ Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const QTransform& other)
template<typename Scalar, int Dim>
QMatrix Transform<Scalar,Dim>::toQTransform(void) const
{
EIGEN_STATIC_ASSERT(Dim==2, you_made_a_programming_mistake)
EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
return QTransform(other.coeffRef(0,0), other.coeffRef(1,0), other.coeffRef(2,0)
other.coeffRef(0,1), other.coeffRef(1,1), other.coeffRef(2,1)
other.coeffRef(0,2), other.coeffRef(1,2), other.coeffRef(2,2);
@@ -501,7 +509,7 @@ template<typename Scalar, int Dim>
Transform<Scalar,Dim>&
Transform<Scalar,Dim>::shear(Scalar sx, Scalar sy)
{
EIGEN_STATIC_ASSERT(int(Dim)==2, you_made_a_programming_mistake)
EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
VectorType tmp = linear().col(0)*sy + linear().col(1);
linear() << linear().col(0) + linear().col(1)*sx, tmp;
return *this;
@@ -516,7 +524,7 @@ template<typename Scalar, int Dim>
Transform<Scalar,Dim>&
Transform<Scalar,Dim>::preshear(Scalar sx, Scalar sy)
{
EIGEN_STATIC_ASSERT(int(Dim)==2, you_made_a_programming_mistake)
EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
m_matrix.template block<Dim,HDim>(0,0) = LinearMatrixType(1, sx, sy, 1) * m_matrix.template block<Dim,HDim>(0,0);
return *this;
}
@@ -528,7 +536,7 @@ Transform<Scalar,Dim>::preshear(Scalar sx, Scalar sy)
template<typename Scalar, int Dim>
inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const TranslationType& t)
{
linear().setIdentity;
linear().setIdentity();
translation() = t.vector();
m_matrix.template block<1,Dim>(Dim,0).setZero();
m_matrix(Dim,Dim) = Scalar(1);
@@ -548,7 +556,7 @@ inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const ScalingType
{
m_matrix.setZero();
linear().diagonal() = s.coeffs();
m_matrix(Dim,Dim) = Scalar(1);
m_matrix.coeffRef(Dim,Dim) = Scalar(1);
return *this;
}
@@ -567,7 +575,7 @@ inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const RotationBas
linear() = ei_toRotationMatrix<Scalar,Dim>(r);
translation().setZero();
m_matrix.template block<1,Dim>(Dim,0).setZero();
m_matrix(Dim,Dim) = Scalar(1);
m_matrix.coeffRef(Dim,Dim) = Scalar(1);
return *this;
}
@@ -600,7 +608,7 @@ inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const RotationBase
*/
template<typename Scalar, int Dim>
typename Transform<Scalar,Dim>::LinearMatrixType
Transform<Scalar,Dim>::extractRotation(TransformTraits traits) const
Transform<Scalar,Dim>::rotation(TransformTraits traits) const
{
ei_assert(traits!=Projective && "you cannot extract a rotation from a non affine transformation");
if (traits == Affine)
@@ -610,7 +618,7 @@ Transform<Scalar,Dim>::extractRotation(TransformTraits traits) const
LinearMatrixType matQ = qr.matrixQ();
LinearMatrixType matR = qr.matrixR();
for (int i=0 ; i<Dim; ++i)
if (matR(i,i)<0)
if (matR.coeff(i,i)<0)
matQ.col(i) = -matQ.col(i);
return matQ;
}

View File

@@ -143,7 +143,7 @@ public:
/** Copy constructor with scalar type conversion */
template<typename OtherScalarType>
inline explicit Translation(const Translation<OtherScalarType,Dim>& other)
{ m_coeffs = other.vector().template cast<OtherScalarType>(); }
{ m_coeffs = other.vector().template cast<Scalar>(); }
/** \returns \c true if \c *this is approximately equal to \a other, within the precision
* determined by \a prec.

View File

@@ -92,7 +92,7 @@ bool ei_compute_inverse_in_size4_case_helper(const MatrixType& matrix, MatrixTyp
* R' = -S' * (R*P_inverse)
*/
typedef Block<MatrixType,2,2> XprBlock22;
typedef typename XprBlock22::Eval Block22;
typedef typename MatrixBase<XprBlock22>::PlainMatrixType Block22;
Block22 P_inverse;
if(ei_compute_inverse_in_size2_case_with_check(matrix.template block<2,2>(0,0), &P_inverse))
{
@@ -216,12 +216,11 @@ struct ei_compute_inverse<MatrixType, 4>
* \sa inverse()
*/
template<typename Derived>
inline void MatrixBase<Derived>::computeInverse(EvalType *result) const
inline void MatrixBase<Derived>::computeInverse(PlainMatrixType *result) const
{
typedef typename ei_eval<Derived>::type MatrixType;
ei_assert(rows() == cols());
EIGEN_STATIC_ASSERT(NumTraits<Scalar>::HasFloatingPoint,numeric_type_must_be_floating_point)
ei_compute_inverse<MatrixType>::run(eval(), result);
EIGEN_STATIC_ASSERT(NumTraits<Scalar>::HasFloatingPoint,NUMERIC_TYPE_MUST_BE_FLOATING_POINT)
ei_compute_inverse<PlainMatrixType>::run(eval(), result);
}
/** \lu_module
@@ -239,9 +238,9 @@ inline void MatrixBase<Derived>::computeInverse(EvalType *result) const
* \sa computeInverse()
*/
template<typename Derived>
inline const typename MatrixBase<Derived>::EvalType MatrixBase<Derived>::inverse() const
inline const typename MatrixBase<Derived>::PlainMatrixType MatrixBase<Derived>::inverse() const
{
EvalType result(rows(), cols());
PlainMatrixType result(rows(), cols());
computeInverse(&result);
return result;
}

View File

@@ -35,8 +35,9 @@
*
* This class represents a LU decomposition of any matrix, with complete pivoting: the matrix A
* is decomposed as A = PLUQ where L is unit-lower-triangular, U is upper-triangular, and P and Q
* are permutation matrices. This is a rank-revealing LU decomposition. The eigenvalues of U are
* in non-increasing order.
* are permutation matrices. This is a rank-revealing LU decomposition. The eigenvalues (diagonal
* coefficients) of U are sorted in such a way that any zeros are at the end, so that the rank
* of A is the index of the first zero on the diagonal of U (with indices starting at 0) if any.
*
* This decomposition provides the generic approach to solving systems of linear equations, computing
* the rank, invertibility, inverse, kernel, and determinant.
@@ -71,9 +72,24 @@ template<typename MatrixType> class LU
MatrixType::MaxRowsAtCompileTime)
};
typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, Dynamic,
MatrixType::Flags&RowMajorBit,
MatrixType::MaxColsAtCompileTime, MaxSmallDimAtCompileTime> KernelResultType;
typedef Matrix<typename MatrixType::Scalar,
MatrixType::ColsAtCompileTime, // the number of rows in the "kernel matrix" is the number of cols of the original matrix
// so that the product "matrix * kernel = zero" makes sense
Dynamic, // we don't know at compile-time the dimension of the kernel
MatrixType::Flags&RowMajorBit,
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
> KernelResultType;
typedef Matrix<typename MatrixType::Scalar,
MatrixType::RowsAtCompileTime, // the image is a subspace of the destination space, whose dimension is the number
// of rows of the original matrix
Dynamic, // we don't know at compile time the dimension of the image (the rank)
MatrixType::Flags,
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.
> ImageResultType;
/** Constructor.
*
@@ -98,18 +114,16 @@ template<typename MatrixType> class LU
*
* \sa matrixLU(), matrixU()
*/
inline const Part<MatrixType, UnitLower> matrixL() const
inline const Part<MatrixType, UnitLowerTriangular> matrixL() const
{
return m_lu;
}
/** \returns an expression of the U matrix, i.e. the upper-triangular part of the LU matrix.
*
* \note The eigenvalues of U are sorted in non-increasing order.
*
* \sa matrixLU(), matrixL()
*/
inline const Part<MatrixType, Upper> matrixU() const
inline const Part<MatrixType, UpperTriangular> matrixU() const
{
return m_lu;
}
@@ -136,10 +150,10 @@ template<typename MatrixType> class LU
return m_q;
}
/** Computes the kernel of the matrix.
/** Computes a basis of the kernel of the matrix, also called the null-space of the matrix.
*
* \note: this method is only allowed on non-invertible matrices, as determined by
* isInvertible(). Calling it on an invertible matrice will make an assertion fail.
* \note This method is only allowed on non-invertible matrices, as determined by
* isInvertible(). Calling it on an invertible matrix will make an assertion fail.
*
* \param result a pointer to the matrix in which to store the kernel. The columns of this
* matrix will be set to form a basis of the kernel (it will be resized
@@ -148,15 +162,32 @@ template<typename MatrixType> class LU
* Example: \include LU_computeKernel.cpp
* Output: \verbinclude LU_computeKernel.out
*
* \sa kernel()
* \sa kernel(), computeImage(), image()
*/
void computeKernel(KernelResultType *result) const;
template<typename KernelMatrixType>
void computeKernel(KernelMatrixType *result) const;
/** \returns the kernel of the matrix. The columns of the returned matrix
/** Computes a basis of the image of the matrix, also called the column-space or range of he matrix.
*
* \note Calling this method on the zero matrix will make an assertion fail.
*
* \param result a pointer to the matrix in which to store the image. The columns of this
* matrix will be set to form a basis of the image (it will be resized
* if necessary).
*
* Example: \include LU_computeImage.cpp
* Output: \verbinclude LU_computeImage.out
*
* \sa image(), computeKernel(), kernel()
*/
template<typename ImageMatrixType>
void computeImage(ImageMatrixType *result) const;
/** \returns the kernel of the matrix, also called its null-space. The columns of the returned matrix
* will form a basis of the kernel.
*
* \note: this method is only allowed on non-invertible matrices, as determined by
* isInvertible(). Calling it on an invertible matrice will make an assertion fail.
* isInvertible(). Calling it on an invertible matrix will make an assertion fail.
*
* \note: this method returns a matrix by value, which induces some inefficiency.
* If you prefer to avoid this overhead, use computeKernel() instead.
@@ -164,10 +195,25 @@ template<typename MatrixType> class LU
* Example: \include LU_kernel.cpp
* Output: \verbinclude LU_kernel.out
*
* \sa computeKernel()
* \sa computeKernel(), image()
*/
const KernelResultType kernel() const;
/** \returns the image of the matrix, also called its column-space. The columns of the returned matrix
* will form a basis of the kernel.
*
* \note: Calling this method on the zero matrix will make an assertion fail.
*
* \note: this method returns a matrix by value, which induces some inefficiency.
* If you prefer to avoid this overhead, use computeImage() instead.
*
* Example: \include LU_image.cpp
* Output: \verbinclude LU_image.out
*
* \sa computeImage(), kernel()
*/
const ImageResultType image() const;
/** This method finds a solution x to the equation Ax=b, where A is the matrix of which
* *this is the LU decomposition, if any exists.
*
@@ -290,6 +336,7 @@ template<typename MatrixType> class LU
}
protected:
const MatrixType& m_originalMatrix;
MatrixType m_lu;
IntColVectorType m_p;
IntRowVectorType m_q;
@@ -299,7 +346,8 @@ template<typename MatrixType> class LU
template<typename MatrixType>
LU<MatrixType>::LU(const MatrixType& matrix)
: m_lu(matrix),
: m_originalMatrix(matrix),
m_lu(matrix),
m_p(matrix.rows()),
m_q(matrix.cols())
{
@@ -312,7 +360,7 @@ LU<MatrixType>::LU(const MatrixType& matrix)
int number_of_transpositions = 0;
RealScalar biggest = RealScalar(0);
for(int k = 0; k < size; k++)
for(int k = 0; k < size; ++k)
{
int row_of_biggest_in_corner, col_of_biggest_in_corner;
RealScalar biggest_in_corner;
@@ -326,11 +374,11 @@ LU<MatrixType>::LU(const MatrixType& matrix)
cols_transpositions.coeffRef(k) = col_of_biggest_in_corner;
if(k != row_of_biggest_in_corner) {
m_lu.row(k).swap(m_lu.row(row_of_biggest_in_corner));
number_of_transpositions++;
++number_of_transpositions;
}
if(k != col_of_biggest_in_corner) {
m_lu.col(k).swap(m_lu.col(col_of_biggest_in_corner));
number_of_transpositions++;
++number_of_transpositions;
}
if(k==0) biggest = biggest_in_corner;
@@ -339,21 +387,21 @@ LU<MatrixType>::LU(const MatrixType& matrix)
if(k<rows-1)
m_lu.col(k).end(rows-k-1) /= lu_k_k;
if(k<size-1)
for( int col = k + 1; col < cols; col++ )
for(int col = k + 1; col < cols; ++col)
m_lu.col(col).end(rows-k-1) -= m_lu.col(k).end(rows-k-1) * m_lu.coeff(k,col);
}
for(int k = 0; k < matrix.rows(); k++) m_p.coeffRef(k) = k;
for(int k = size-1; k >= 0; k--)
for(int k = 0; k < matrix.rows(); ++k) m_p.coeffRef(k) = k;
for(int k = size-1; k >= 0; --k)
std::swap(m_p.coeffRef(k), m_p.coeffRef(rows_transpositions.coeff(k)));
for(int k = 0; k < matrix.cols(); k++) m_q.coeffRef(k) = k;
for(int k = 0; k < size; k++)
for(int k = 0; k < matrix.cols(); ++k) m_q.coeffRef(k) = k;
for(int k = 0; k < size; ++k)
std::swap(m_q.coeffRef(k), m_q.coeffRef(cols_transpositions.coeff(k)));
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
for(m_rank = 0; m_rank < size; m_rank++)
for(m_rank = 0; m_rank < size; ++m_rank)
if(ei_isMuchSmallerThan(m_lu.diagonal().coeff(m_rank), m_lu.diagonal().coeff(0)))
break;
}
@@ -365,7 +413,8 @@ typename ei_traits<MatrixType>::Scalar LU<MatrixType>::determinant() const
}
template<typename MatrixType>
void LU<MatrixType>::computeKernel(KernelResultType *result) const
template<typename KernelMatrixType>
void LU<MatrixType>::computeKernel(KernelMatrixType *result) const
{
ei_assert(!isInvertible());
const int dimker = dimensionOfKernel(), cols = m_lu.cols();
@@ -374,31 +423,31 @@ void LU<MatrixType>::computeKernel(KernelResultType *result) const
/* Let us use the following lemma:
*
* Lemma: If the matrix A has the LU decomposition PAQ = LU,
* then Ker A = Q( Ker U ).
* then Ker A = Q(Ker U).
*
* Proof: trivial: just keep in mind that P, Q, L are invertible.
*/
/* Thus, all we need to do is to compute Ker U, and then apply Q.
*
* U is upper triangular, with eigenvalues sorted in decreasing order of
* absolute value. Thus, the diagonal of U ends with exactly
* U is upper triangular, with eigenvalues sorted so that any zeros appear at the end.
* Thus, the diagonal of U ends with exactly
* m_dimKer zero's. Let us use that to construct m_dimKer linearly
* independent vectors in Ker U.
*/
Matrix<Scalar, Dynamic, Dynamic, MatrixType::Flags&RowMajorBit,
MatrixType::MaxColsAtCompileTime, MaxSmallDimAtCompileTime>
MatrixType::MaxColsAtCompileTime, MatrixType::MaxColsAtCompileTime>
y(-m_lu.corner(TopRight, m_rank, dimker));
m_lu.corner(TopLeft, m_rank, m_rank)
.template marked<Upper>()
.template marked<UpperTriangular>()
.solveTriangularInPlace(y);
for(int i = 0; i < m_rank; i++)
for(int i = 0; i < m_rank; ++i)
result->row(m_q.coeff(i)) = y.row(i);
for(int i = m_rank; i < cols; i++) result->row(m_q.coeff(i)).setZero();
for(int k = 0; k < dimker; k++) result->coeffRef(m_q.coeff(m_rank+k), k) = Scalar(1);
for(int i = m_rank; i < cols; ++i) result->row(m_q.coeff(i)).setZero();
for(int k = 0; k < dimker; ++k) result->coeffRef(m_q.coeff(m_rank+k), k) = Scalar(1);
}
template<typename MatrixType>
@@ -410,6 +459,25 @@ LU<MatrixType>::kernel() const
return result;
}
template<typename MatrixType>
template<typename ImageMatrixType>
void LU<MatrixType>::computeImage(ImageMatrixType *result) const
{
ei_assert(m_rank > 0);
result->resize(m_originalMatrix.rows(), m_rank);
for(int i = 0; i < m_rank; ++i)
result->col(i) = m_originalMatrix.col(m_q.coeff(i));
}
template<typename MatrixType>
const typename LU<MatrixType>::ImageResultType
LU<MatrixType>::image() const
{
ImageResultType result(m_originalMatrix.rows(), m_rank);
computeImage(&result);
return result;
}
template<typename MatrixType>
template<typename OtherDerived, typename ResultType>
bool LU<MatrixType>::solve(
@@ -429,10 +497,10 @@ bool LU<MatrixType>::solve(
ei_assert(b.rows() == rows);
const int smalldim = std::min(rows, m_lu.cols());
typename OtherDerived::Eval c(b.rows(), b.cols());
typename OtherDerived::PlainMatrixType c(b.rows(), b.cols());
// Step 1
for(int i = 0; i < rows; i++) c.row(m_p.coeff(i)) = b.row(i);
for(int i = 0; i < rows; ++i) c.row(m_p.coeff(i)) = b.row(i);
// Step 2
Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime,
@@ -442,15 +510,15 @@ bool LU<MatrixType>::solve(
l.setZero();
l.corner(Eigen::TopLeft,rows,smalldim)
= m_lu.corner(Eigen::TopLeft,rows,smalldim);
l.template marked<UnitLower>().solveTriangularInPlace(c);
l.template marked<UnitLowerTriangular>().solveTriangularInPlace(c);
// Step 3
if(!isSurjective())
{
// is c is in the image of U ?
RealScalar biggest_in_c = c.corner(TopLeft, m_rank, c.cols()).cwise().abs().maxCoeff();
for(int col = 0; col < c.cols(); col++)
for(int row = m_rank; row < c.rows(); row++)
for(int col = 0; col < c.cols(); ++col)
for(int row = m_rank; row < c.rows(); ++row)
if(!ei_isMuchSmallerThan(c.coeff(row,col), biggest_in_c))
return false;
}
@@ -459,13 +527,13 @@ bool LU<MatrixType>::solve(
MatrixType::MaxRowsAtCompileTime, OtherDerived::MaxColsAtCompileTime>
d(c.corner(TopLeft, m_rank, c.cols()));
m_lu.corner(TopLeft, m_rank, m_rank)
.template marked<Upper>()
.template marked<UpperTriangular>()
.solveTriangularInPlace(d);
// Step 4
result->resize(m_lu.cols(), b.cols());
for(int i = 0; i < m_rank; i++) result->row(m_q.coeff(i)) = d.row(i);
for(int i = m_rank; i < m_lu.cols(); i++) result->row(m_q.coeff(i)).setZero();
for(int i = 0; i < m_rank; ++i) result->row(m_q.coeff(i)) = d.row(i);
for(int i = m_rank; i < m_lu.cols(); ++i) result->row(m_q.coeff(i)).setZero();
return true;
}
@@ -476,10 +544,10 @@ bool LU<MatrixType>::solve(
* \sa class LU
*/
template<typename Derived>
inline const LU<typename MatrixBase<Derived>::EvalType>
inline const LU<typename MatrixBase<Derived>::PlainMatrixType>
MatrixBase<Derived>::lu() const
{
return eval();
return LU<PlainMatrixType>(eval());
}
#endif // EIGEN_LU_H

View File

@@ -122,7 +122,7 @@ MatrixType EigenSolver<MatrixType>::pseudoEigenvalueMatrix() const
{
int n = m_eivec.cols();
MatrixType matD = MatrixType::Zero(n,n);
for (int i=0; i<n; i++)
for (int i=0; i<n; ++i)
{
if (ei_isMuchSmallerThan(ei_imag(m_eivalues.coeff(i)), ei_real(m_eivalues.coeff(i))))
matD.coeffRef(i,i) = ei_real(m_eivalues.coeff(i));
@@ -130,7 +130,7 @@ MatrixType EigenSolver<MatrixType>::pseudoEigenvalueMatrix() const
{
matD.template block<2,2>(i,i) << ei_real(m_eivalues.coeff(i)), ei_imag(m_eivalues.coeff(i)),
-ei_imag(m_eivalues.coeff(i)), ei_real(m_eivalues.coeff(i));
i++;
++i;
}
}
return matD;
@@ -145,24 +145,24 @@ typename EigenSolver<MatrixType>::EigenvectorType EigenSolver<MatrixType>::eigen
{
int n = m_eivec.cols();
EigenvectorType matV(n,n);
for (int j=0; j<n; j++)
for (int j=0; j<n; ++j)
{
if (ei_isMuchSmallerThan(ei_abs(ei_imag(m_eivalues.coeff(j))), ei_abs(ei_real(m_eivalues.coeff(j)))))
{
// we have a real eigen value
matV.col(j) = m_eivec.col(j);
matV.col(j) = m_eivec.col(j).template cast<Complex>();
}
else
{
// we have a pair of complex eigen values
for (int i=0; i<n; i++)
for (int i=0; i<n; ++i)
{
matV.coeffRef(i,j) = Complex(m_eivec.coeff(i,j), m_eivec.coeff(i,j+1));
matV.coeffRef(i,j+1) = Complex(m_eivec.coeff(i,j), -m_eivec.coeff(i,j+1));
}
matV.col(j).normalize();
matV.col(j+1).normalize();
j++;
++j;
}
}
return matV;
@@ -198,7 +198,7 @@ void EigenSolver<MatrixType>::orthes(MatrixType& matH, RealVectorType& ort)
int low = 0;
int high = n-1;
for (int m = low+1; m <= high-1; m++)
for (int m = low+1; m <= high-1; ++m)
{
// Scale column.
RealScalar scale = matH.block(m, m-1, high-m+1, 1).cwise().abs().sum();
@@ -290,13 +290,12 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
// FIXME to be efficient the following would requires a triangular reduxion code
// Scalar norm = matH.upper().cwise().abs().sum() + matH.corner(BottomLeft,n,n).diagonal().cwise().abs().sum();
Scalar norm = 0.0;
for (int j = 0; j < nn; j++)
for (int j = 0; j < nn; ++j)
{
// FIXME what's the purpose of the following since the condition is always false
if ((j < low) || (j > high))
{
m_eivalues.coeffRef(j).real() = matH.coeff(j,j);
m_eivalues.coeffRef(j).imag() = 0.0;
m_eivalues.coeffRef(j) = Complex(matH.coeff(j,j), 0.0);
}
norm += matH.row(j).segment(std::max(j-1,0), nn-std::max(j-1,0)).cwise().abs().sum();
}
@@ -322,8 +321,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
if (l == n)
{
matH.coeffRef(n,n) = matH.coeff(n,n) + exshift;
m_eivalues.coeffRef(n).real() = matH.coeff(n,n);
m_eivalues.coeffRef(n).imag() = 0.0;
m_eivalues.coeffRef(n) = Complex(matH.coeff(n,n), 0.0);
n--;
iter = 0;
}
@@ -345,13 +343,9 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
else
z = p - z;
m_eivalues.coeffRef(n-1).real() = x + z;
m_eivalues.coeffRef(n).real() = m_eivalues.coeff(n-1).real();
if (z != 0.0)
m_eivalues.coeffRef(n).real() = x - w / z;
m_eivalues.coeffRef(n-1) = Complex(x + z, 0.0);
m_eivalues.coeffRef(n) = Complex(z!=0.0 ? x - w / z : m_eivalues.coeff(n-1).real(), 0.0);
m_eivalues.coeffRef(n-1).imag() = 0.0;
m_eivalues.coeffRef(n).imag() = 0.0;
x = matH.coeff(n,n-1);
s = ei_abs(x) + ei_abs(z);
p = x / s;
@@ -361,7 +355,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
q = q / r;
// Row modification
for (int j = n-1; j < nn; j++)
for (int j = n-1; j < nn; ++j)
{
z = matH.coeff(n-1,j);
matH.coeffRef(n-1,j) = q * z + p * matH.coeff(n,j);
@@ -369,7 +363,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
}
// Column modification
for (int i = 0; i <= n; i++)
for (int i = 0; i <= n; ++i)
{
z = matH.coeff(i,n-1);
matH.coeffRef(i,n-1) = q * z + p * matH.coeff(i,n);
@@ -377,7 +371,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
}
// Accumulate transformations
for (int i = low; i <= high; i++)
for (int i = low; i <= high; ++i)
{
z = m_eivec.coeff(i,n-1);
m_eivec.coeffRef(i,n-1) = q * z + p * m_eivec.coeff(i,n);
@@ -386,10 +380,8 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
}
else // Complex pair
{
m_eivalues.coeffRef(n-1).real() = x + p;
m_eivalues.coeffRef(n).real() = x + p;
m_eivalues.coeffRef(n-1).imag() = z;
m_eivalues.coeffRef(n).imag() = -z;
m_eivalues.coeffRef(n-1) = Complex(x + p, z);
m_eivalues.coeffRef(n) = Complex(x + p, -z);
}
n = n - 2;
iter = 0;
@@ -410,7 +402,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
if (iter == 10)
{
exshift += x;
for (int i = low; i <= n; i++)
for (int i = low; i <= n; ++i)
matH.coeffRef(i,i) -= x;
s = ei_abs(matH.coeff(n,n-1)) + ei_abs(matH.coeff(n-1,n-2));
x = y = 0.75 * s;
@@ -428,7 +420,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
if (y < x)
s = -s;
s = x - w / ((y - x) / 2.0 + s);
for (int i = low; i <= n; i++)
for (int i = low; i <= n; ++i)
matH.coeffRef(i,i) -= s;
exshift += s;
x = y = w = 0.964;
@@ -463,7 +455,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
m--;
}
for (int i = m+2; i <= n; i++)
for (int i = m+2; i <= n; ++i)
{
matH.coeffRef(i,i-2) = 0.0;
if (i > m+2)
@@ -471,7 +463,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
}
// Double QR step involving rows l:n and columns m:n
for (int k = m; k <= n-1; k++)
for (int k = m; k <= n-1; ++k)
{
int notlast = (k != n-1);
if (k != m) {
@@ -510,7 +502,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
r = r / p;
// Row modification
for (int j = k; j < nn; j++)
for (int j = k; j < nn; ++j)
{
p = matH.coeff(k,j) + q * matH.coeff(k+1,j);
if (notlast)
@@ -523,7 +515,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
}
// Column modification
for (int i = 0; i <= std::min(n,k+3); i++)
for (int i = 0; i <= std::min(n,k+3); ++i)
{
p = x * matH.coeff(i,k) + y * matH.coeff(i,k+1);
if (notlast)
@@ -536,7 +528,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
}
// Accumulate transformations
for (int i = low; i <= high; i++)
for (int i = low; i <= high; ++i)
{
p = x * m_eivec.coeff(i,k) + y * m_eivec.coeff(i,k+1);
if (notlast)
@@ -686,7 +678,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH)
}
// Vectors of isolated roots
for (int i = 0; i < nn; i++)
for (int i = 0; i < nn; ++i)
{
// FIXME again what's the purpose of this test ?
// in this algo low==0 and high==nn-1 !!

View File

@@ -243,7 +243,7 @@ HessenbergDecomposition<MatrixType>::matrixH(void) const
int n = m_matrix.rows();
MatrixType matH = m_matrix;
if (n>2)
matH.corner(BottomLeft,n-2, n-2).template part<Lower>().setZero();
matH.corner(BottomLeft,n-2, n-2).template part<LowerTriangular>().setZero();
return matH;
}

View File

@@ -60,11 +60,11 @@ template<typename MatrixType> class QR
bool isFullRank() const { return ei_isMuchSmallerThan(m_hCoeffs.cwise().abs().minCoeff(), Scalar(1)); }
/** \returns a read-only expression of the matrix R of the actual the QR decomposition */
const Part<NestByValue<MatrixRBlockType>, Upper>
const Part<NestByValue<MatrixRBlockType>, UpperTriangular>
matrixR(void) const
{
int cols = m_qr.cols();
return MatrixRBlockType(m_qr, 0, 0, cols, cols).nestByValue().template part<Upper>();
return MatrixRBlockType(m_qr, 0, 0, cols, cols).nestByValue().template part<UpperTriangular>();
}
MatrixType matrixQ(void) const;
@@ -87,7 +87,7 @@ void QR<MatrixType>::_compute(const MatrixType& matrix)
int rows = matrix.rows();
int cols = matrix.cols();
for (int k = 0; k < cols; k++)
for (int k = 0; k < cols; ++k)
{
int remainingSize = rows-k;
@@ -169,10 +169,10 @@ MatrixType QR<MatrixType>::matrixQ(void) const
* \sa class QR
*/
template<typename Derived>
const QR<typename MatrixBase<Derived>::EvalType>
const QR<typename MatrixBase<Derived>::PlainMatrixType>
MatrixBase<Derived>::qr() const
{
return eval();
return QR<PlainMatrixType>(eval());
}

View File

@@ -105,6 +105,25 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
/** \returns the computed eigen values */
RealVectorType eigenvalues(void) const { return m_eivalues; }
/** \returns the positive square root of the matrix
*
* \note the matrix itself must be positive in order for this to make sense.
*/
MatrixType operatorSqrt() const
{
return m_eivec * m_eivalues.cwise().sqrt().asDiagonal() * m_eivec.adjoint();
}
/** \returns the positive inverse square root of the matrix
*
* \note the matrix itself must be positive definite in order for this to make sense.
*/
MatrixType operatorInverseSqrt() const
{
return m_eivec * m_eivalues.cwise().inverse().cwise().sqrt().asDiagonal() * m_eivec.adjoint();
}
protected:
MatrixType m_eivec;
RealVectorType m_eivalues;
@@ -202,7 +221,7 @@ void SelfAdjointEigenSolver<MatrixType>::compute(const MatrixType& matrix, bool
// Sort eigenvalues and corresponding vectors.
// TODO make the sort optional ?
// TODO use a better sort algorithm !!
for (int i = 0; i < n-1; i++)
for (int i = 0; i < n-1; ++i)
{
int k;
m_eivalues.segment(i,n-i).minCoeff(&k);
@@ -235,22 +254,22 @@ compute(const MatrixType& matA, const MatrixType& matB, bool computeEigenvectors
cholB.matrixL().solveTriangularInPlace(matC);
// FIXME since we currently do not support A * inv(L'), let's do (inv(L) A')' :
matC = matC.adjoint().eval();
cholB.matrixL().template marked<Lower>().solveTriangularInPlace(matC);
cholB.matrixL().template marked<LowerTriangular>().solveTriangularInPlace(matC);
matC = matC.adjoint().eval();
// this version works too:
// matC = matC.transpose();
// cholB.matrixL().conjugate().template marked<Lower>().solveTriangularInPlace(matC);
// cholB.matrixL().conjugate().template marked<LowerTriangular>().solveTriangularInPlace(matC);
// matC = matC.transpose();
// FIXME: this should work: (currently it only does for small matrices)
// Transpose<MatrixType> trMatC(matC);
// cholB.matrixL().conjugate().eval().template marked<Lower>().solveTriangularInPlace(trMatC);
// cholB.matrixL().conjugate().eval().template marked<LowerTriangular>().solveTriangularInPlace(trMatC);
compute(matC, computeEigenvectors);
if (computeEigenvectors)
{
// transform back the eigen vectors: evecs = inv(U) * evecs
cholB.matrixL().adjoint().template marked<Upper>().solveTriangularInPlace(m_eivec);
cholB.matrixL().adjoint().template marked<UpperTriangular>().solveTriangularInPlace(m_eivec);
for (int i=0; i<m_eivec.cols(); ++i)
m_eivec.col(i) = m_eivec.col(i).normalized();
}
@@ -267,7 +286,7 @@ inline Matrix<typename NumTraits<typename ei_traits<Derived>::Scalar>::Real, ei_
MatrixBase<Derived>::eigenvalues() const
{
ei_assert(Flags&SelfAdjointBit);
return SelfAdjointEigenSolver<typename Derived::Eval>(eval(),false).eigenvalues();
return SelfAdjointEigenSolver<typename Derived::PlainMatrixType>(eval(),false).eigenvalues();
}
template<typename Derived, bool IsSelfAdjoint>
@@ -287,7 +306,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::Eval m_eval(m);
typename Derived::PlainMatrixType 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(

View File

@@ -164,11 +164,11 @@ Tridiagonalization<MatrixType>::matrixT(void) const
// and fill it ? (to avoid temporaries)
int n = m_matrix.rows();
MatrixType matT = m_matrix;
matT.corner(TopRight,n-1, n-1).diagonal() = subDiagonal().conjugate();
matT.corner(TopRight,n-1, n-1).diagonal() = subDiagonal().template cast<Scalar>().conjugate();
if (n>2)
{
matT.corner(TopRight,n-2, n-2).template part<Upper>().setZero();
matT.corner(BottomLeft,n-2, n-2).template part<Lower>().setZero();
matT.corner(TopRight,n-2, n-2).template part<UpperTriangular>().setZero();
matT.corner(BottomLeft,n-2, n-2).template part<LowerTriangular>().setZero();
}
return matT;
}
@@ -223,17 +223,17 @@ void Tridiagonalization<MatrixType>::_compute(MatrixType& matA, CoeffVectorType&
/* This is the initial algorithm which minimize operation counts and maximize
* the use of Eigen's expression. Unfortunately, the first matrix-vector product
* using Part<Lower|Selfadjoint> is very very slow */
* using Part<LowerTriangular|Selfadjoint> is very very slow */
#ifdef EIGEN_NEVER_DEFINED
// matrix - vector product
hCoeffs.end(n-i-1) = (matA.corner(BottomRight,n-i-1,n-i-1).template part<Lower|SelfAdjoint>()
hCoeffs.end(n-i-1) = (matA.corner(BottomRight,n-i-1,n-i-1).template part<LowerTriangular|SelfAdjoint>()
* (h * matA.col(i).end(n-i-1))).lazy();
// simple axpy
hCoeffs.end(n-i-1) += (h * Scalar(-0.5) * matA.col(i).end(n-i-1).dot(hCoeffs.end(n-i-1)))
* matA.col(i).end(n-i-1);
// rank-2 update
//Block<MatrixType,Dynamic,1> B(matA,i+1,i,n-i-1,1);
matA.corner(BottomRight,n-i-1,n-i-1).template part<Lower>() -=
matA.corner(BottomRight,n-i-1,n-i-1).template part<LowerTriangular>() -=
(matA.col(i).end(n-i-1) * hCoeffs.end(n-i-1).adjoint()).lazy()
+ (hCoeffs.end(n-i-1) * matA.col(i).end(n-i-1).adjoint()).lazy();
#endif
@@ -256,7 +256,7 @@ void Tridiagonalization<MatrixType>::_compute(MatrixType& matA, CoeffVectorType&
Block<MatrixType,Dynamic,4>(matA,b+4,b,n-b-4,4).adjoint() * Block<MatrixType,Dynamic,1>(matA,b+4,i,n-b-4,1);
// the 4x4 block diagonal:
Block<CoeffVectorType,4,1>(hCoeffs, b, 0, 4,1) +=
(Block<MatrixType,4,4>(matA,b,b,4,4).template part<Lower|SelfAdjoint>()
(Block<MatrixType,4,4>(matA,b,b,4,4).template part<LowerTriangular|SelfAdjoint>()
* (h * Block<MatrixType,4,1>(matA,b,i,4,1))).lazy();
}
#endif
@@ -268,7 +268,7 @@ void Tridiagonalization<MatrixType>::_compute(MatrixType& matA, CoeffVectorType&
* if we remove the specialization of Block for Matrix then it is even worse, much worse ! */
#ifdef EIGEN_NEVER_DEFINED
for (int j1=i+1; j1<n; ++j1)
for (int i1=j1; i1<n; i1++)
for (int i1=j1; i1<n; ++i1)
matA.coeffRef(i1,j1) -= matA.coeff(i1,i)*ei_conj(hCoeffs.coeff(j1-1))
+ hCoeffs.coeff(i1-1)*ei_conj(matA.coeff(j1,i));
#endif

View File

@@ -111,18 +111,18 @@ void linearRegression(int numPoints,
Dynamic, VectorType::MaxSizeAtCompileTime, RowMajorBit>
m(numPoints, size);
if(funcOfOthers>0)
for(int i = 0; i < numPoints; i++)
for(int i = 0; i < numPoints; ++i)
m.row(i).start(funcOfOthers) = points[i]->start(funcOfOthers);
if(funcOfOthers<size-1)
for(int i = 0; i < numPoints; i++)
for(int i = 0; i < numPoints; ++i)
m.row(i).block(funcOfOthers, size-funcOfOthers-1)
= points[i]->end(size-funcOfOthers-1);
for(int i = 0; i < numPoints; i++)
for(int i = 0; i < numPoints; ++i)
m.row(i).coeffRef(size-1) = Scalar(1);
VectorType v(size);
v.setZero();
for(int i = 0; i < numPoints; i++)
for(int i = 0; i < numPoints; ++i)
v += m.row(i).adjoint() * points[i]->coeff(funcOfOthers);
ei_assert((m.adjoint()*m).lu().solve(v, result));
@@ -170,14 +170,14 @@ void fitHyperplane(int numPoints,
// compute the mean of the data
VectorType mean = VectorType::Zero(size);
for(int i = 0; i < numPoints; i++)
for(int i = 0; i < numPoints; ++i)
mean += *(points[i]);
mean /= numPoints;
// compute the covariance matrix
CovMatrixType covMat = CovMatrixType::Zero(size, size);
VectorType remean = VectorType::Zero(size);
for(int i = 0; i < numPoints; i++)
for(int i = 0; i < numPoints; ++i)
{
VectorType diff = (*(points[i]) - mean).conjugate();
covMat += diff * diff.adjoint();

View File

@@ -115,7 +115,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
// in s and the super-diagonal elements in e.
int nct = std::min(m-1,n);
int nrt = std::max(0,std::min(n-2,m));
for (k = 0; k < std::max(nct,nrt); k++)
for (k = 0; k < std::max(nct,nrt); ++k)
{
if (k < nct)
{
@@ -132,7 +132,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
m_sigma[k] = -m_sigma[k];
}
for (j = k+1; j < n; j++)
for (j = k+1; j < n; ++j)
{
if ((k < nct) && (m_sigma[k] != 0.0))
{
@@ -168,7 +168,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
{
// Apply the transformation.
work.end(m-k-1) = matA.corner(BottomRight,m-k-1,n-k-1) * e.end(n-k-1);
for (j = k+1; j < n; j++)
for (j = k+1; j < n; ++j)
matA.col(j).end(m-k-1) += (-e[j]/e[k+1]) * work.end(m-k-1);
}
@@ -192,7 +192,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
// If required, generate U.
if (wantu)
{
for (j = nct; j < nu; j++)
for (j = nct; j < nu; ++j)
{
m_matU.col(j).setZero();
m_matU(j,j) = 1.0;
@@ -201,7 +201,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
{
if (m_sigma[k] != 0.0)
{
for (j = k+1; j < nu; j++)
for (j = k+1; j < nu; ++j)
{
Scalar t = m_matU.col(k).end(m-k).dot(m_matU.col(j).end(m-k)); // FIXME is it really a dot product we want ?
t = -t/m_matU(k,k);
@@ -227,7 +227,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
{
if ((k < nrt) & (e[k] != 0.0))
{
for (j = k+1; j < nu; j++)
for (j = k+1; j < nu; ++j)
{
Scalar t = m_matV.col(k).end(n-k-1).dot(m_matV.col(j).end(n-k-1)); // FIXME is it really a dot product we want ?
t = -t/m_matV(k+1,k);
@@ -302,7 +302,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
k = ks;
}
}
k++;
++k;
// Perform the task indicated by kase.
switch (kase)
@@ -326,7 +326,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
}
if (wantv)
{
for (i = 0; i < n; i++)
for (i = 0; i < n; ++i)
{
t = cs*m_matV(i,j) + sn*m_matV(i,p-1);
m_matV(i,p-1) = -sn*m_matV(i,j) + cs*m_matV(i,p-1);
@@ -342,7 +342,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
{
Scalar f(e[k-1]);
e[k-1] = 0.0;
for (j = k; j < p; j++)
for (j = k; j < p; ++j)
{
Scalar t(hypot(m_sigma[j],f));
Scalar cs( m_sigma[j]/t);
@@ -352,7 +352,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
e[j] = cs*e[j];
if (wantu)
{
for (i = 0; i < m; i++)
for (i = 0; i < m; ++i)
{
t = cs*m_matU(i,j) + sn*m_matU(i,k-1);
m_matU(i,k-1) = -sn*m_matU(i,j) + cs*m_matU(i,k-1);
@@ -390,7 +390,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
// Chase zeros.
for (j = k; j < p-1; j++)
for (j = k; j < p-1; ++j)
{
Scalar t = hypot(f,g);
Scalar cs = f/t;
@@ -403,7 +403,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
m_sigma[j+1] = cs*m_sigma[j+1];
if (wantv)
{
for (i = 0; i < n; i++)
for (i = 0; i < n; ++i)
{
t = cs*m_matV(i,j) + sn*m_matV(i,j+1);
m_matV(i,j+1) = -sn*m_matV(i,j) + cs*m_matV(i,j+1);
@@ -420,7 +420,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
e[j+1] = cs*e[j+1];
if (wantu && (j < m-1))
{
for (i = 0; i < m; i++)
for (i = 0; i < m; ++i)
{
t = cs*m_matU(i,j) + sn*m_matU(i,j+1);
m_matU(i,j+1) = -sn*m_matU(i,j) + cs*m_matU(i,j+1);
@@ -456,7 +456,7 @@ void SVD<MatrixType>::compute(const MatrixType& matrix)
m_matV.col(k).swap(m_matV.col(k+1));
if (wantu && (k < m-1))
m_matU.col(k).swap(m_matU.col(k+1));
k++;
++k;
}
iter = 0;
p--;
@@ -473,12 +473,12 @@ SVD<MatrixType>& SVD<MatrixType>::sort()
int mv = m_matV.rows();
int n = m_matU.cols();
for (int i=0; i<n; i++)
for (int i=0; i<n; ++i)
{
int k = i;
Scalar p = m_sigma.coeff(i);
for (int j=i+1; j<n; j++)
for (int j=i+1; j<n; ++j)
{
if (m_sigma.coeff(j) > p)
{
@@ -520,7 +520,7 @@ bool SVD<MatrixType>::solve(const MatrixBase<OtherDerived> &b, ResultType* resul
{
Matrix<Scalar,MatrixUType::RowsAtCompileTime,1> aux = m_matU.transpose() * b.col(j);
for (int i = 0; i <m_matU.cols(); i++)
for (int i = 0; i <m_matU.cols(); ++i)
{
Scalar si = m_sigma.coeff(i);
if (ei_isMuchSmallerThan(ei_abs(si),maxVal))
@@ -538,10 +538,10 @@ bool SVD<MatrixType>::solve(const MatrixBase<OtherDerived> &b, ResultType* resul
* \returns the SVD decomposition of \c *this
*/
template<typename Derived>
inline SVD<typename MatrixBase<Derived>::EvalType>
inline SVD<typename MatrixBase<Derived>::PlainMatrixType>
MatrixBase<Derived>::svd() const
{
return SVD<typename ei_eval<Derived>::type>(derived());
return SVD<PlainMatrixType>(derived());
}
#endif // EIGEN_SVD_H

View File

@@ -202,7 +202,7 @@ Scalar& AmbiVector<Scalar>::coeffRef(int i)
// this is the first element
m_llStart = 0;
m_llCurrent = 0;
m_llSize++;
++m_llSize;
llElements[0].value = Scalar(0);
llElements[0].index = i;
llElements[0].next = -1;
@@ -216,7 +216,7 @@ Scalar& AmbiVector<Scalar>::coeffRef(int i)
el.index = i;
el.next = m_llStart;
m_llStart = m_llSize;
m_llSize++;
++m_llSize;
m_llCurrent = m_llStart;
return el.value;
}
@@ -246,7 +246,7 @@ Scalar& AmbiVector<Scalar>::coeffRef(int i)
el.index = i;
el.next = llElements[m_llCurrent].next;
llElements[m_llCurrent].next = m_llSize;
m_llSize++;
++m_llSize;
return el.value;
}
}
@@ -332,7 +332,7 @@ class AmbiVector<_Scalar>::Iterator
if (m_isDense)
{
do {
m_cachedIndex++;
++m_cachedIndex;
} while (m_cachedIndex<m_vector.m_end && ei_abs(m_vector.m_buffer[m_cachedIndex])<m_epsilon);
if (m_cachedIndex<m_vector.m_end)
m_cachedValue = m_vector.m_buffer[m_cachedIndex];

View File

@@ -69,9 +69,9 @@ cholmod_sparse SparseMatrix<Scalar,Flags>::asCholmodMatrix()
if (Flags & SelfAdjoint)
{
if (Flags & Upper)
if (Flags & UpperTriangular)
res.stype = 1;
else if (Flags & Lower)
else if (Flags & LowerTriangular)
res.stype = -1;
else
res.stype = 0;

View File

@@ -140,7 +140,7 @@ class RandomSetter
m_keyBitsOffset = 0;
while (aux)
{
m_keyBitsOffset++;
++m_keyBitsOffset;
aux = aux >> 1;
}
KeyType ik = (1<<(OuterPacketBits+m_keyBitsOffset));
@@ -183,7 +183,7 @@ class RandomSetter
for (typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=end; ++it)
{
const int outer = it->first & keyBitsMask;
positions[outer]++;
++positions[outer];
}
}
// prefix sum

View File

@@ -59,7 +59,7 @@ public:
: m_matrix(matrix), m_startRow(startRow), m_startCol(startCol),
m_blockRows(matrix.rows()), m_blockCols(matrix.cols())
{
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && RowsAtCompileTime!=Dynamic,this_method_is_only_for_fixed_size)
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && RowsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
ei_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= matrix.rows()
&& startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= matrix.cols());
}

View File

@@ -79,7 +79,7 @@ class SparseLDLT
protected:
typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
typedef SparseMatrix<Scalar,Lower|UnitDiagBit> CholMatrixType;
typedef SparseMatrix<Scalar,LowerTriangular|UnitDiagBit> CholMatrixType;
typedef Matrix<Scalar,MatrixType::ColsAtCompileTime,1> VectorType;
enum {
@@ -203,10 +203,10 @@ void SparseLDLT<MatrixType,Backend>::_symbolic(const MatrixType& a)
if (P)
{
/* If P is present then compute Pinv, the inverse of P */
for (int k = 0; k < size; k++)
for (int k = 0; k < size; ++k)
Pinv[P[k]] = k;
}
for (int k = 0; k < size; k++)
for (int k = 0; k < size; ++k)
{
/* L(k,:) pattern: all nodes reachable in etree from nz in A(0:k-1,k) */
m_parent[k] = -1; /* parent of k is not yet known */
@@ -214,7 +214,7 @@ void SparseLDLT<MatrixType,Backend>::_symbolic(const MatrixType& a)
m_nonZerosPerCol[k] = 0; /* count of nonzeros in column k of L */
int kk = P ? P[k] : k; /* kth original, or permuted, column */
int p2 = Ap[kk+1];
for (int p = Ap[kk]; p < p2; p++)
for (int p = Ap[kk]; p < p2; ++p)
{
/* A (i,k) is nonzero (original or permuted A) */
int i = Pinv ? Pinv[Ai[p]] : Ai[p];
@@ -226,7 +226,7 @@ void SparseLDLT<MatrixType,Backend>::_symbolic(const MatrixType& a)
/* find parent of i if not yet determined */
if (m_parent[i] == -1)
m_parent[i] = k;
m_nonZerosPerCol[i]++; /* L (k,i) is nonzero */
++m_nonZerosPerCol[i]; /* L (k,i) is nonzero */
tags[i] = k; /* mark i as visited */
}
}
@@ -234,7 +234,7 @@ void SparseLDLT<MatrixType,Backend>::_symbolic(const MatrixType& a)
}
/* construct Lp index array from m_nonZerosPerCol column counts */
Lp[0] = 0;
for (int k = 0; k < size; k++)
for (int k = 0; k < size; ++k)
Lp[k+1] = Lp[k] + m_nonZerosPerCol[k];
m_matrix.resizeNonZeros(Lp[size]);
@@ -265,7 +265,7 @@ bool SparseLDLT<MatrixType,Backend>::_numeric(const MatrixType& a)
const int* Pinv = 0;
bool ok = true;
for (int k = 0; k < size; k++)
for (int k = 0; k < size; ++k)
{
/* compute nonzero pattern of kth row of L, in topological order */
y[k] = 0.0; /* Y(0:k) is now all zero */
@@ -274,7 +274,7 @@ bool SparseLDLT<MatrixType,Backend>::_numeric(const MatrixType& a)
m_nonZerosPerCol[k] = 0; /* count of nonzeros in column k of L */
int kk = (P) ? (P[k]) : (k); /* kth original, or permuted, column */
int p2 = Ap[kk+1];
for (int p = Ap[kk]; p < p2; p++)
for (int p = Ap[kk]; p < p2; ++p)
{
int i = Pinv ? Pinv[Ai[p]] : Ai[p]; /* get A(i,k) */
if (i <= k)
@@ -293,20 +293,20 @@ bool SparseLDLT<MatrixType,Backend>::_numeric(const MatrixType& a)
/* compute numerical values kth row of L (a sparse triangular solve) */
m_diag[k] = y[k]; /* get D(k,k) and clear Y(k) */
y[k] = 0.0;
for (; top < size; top++)
for (; top < size; ++top)
{
int i = pattern[top]; /* pattern[top:n-1] is pattern of L(:,k) */
Scalar yi = y[i]; /* get and clear Y(i) */
y[i] = 0.0;
int p2 = Lp[i] + m_nonZerosPerCol[i];
int p;
for (p = Lp[i]; p < p2; p++)
for (p = Lp[i]; p < p2; ++p)
y[Li[p]] -= Lx[p] * yi;
Scalar l_ki = yi / m_diag[i]; /* the nonzero entry L(k,i) */
m_diag[k] -= l_ki * yi;
Li[p] = k; /* store L(k,i) in column form of L */
Lx[p] = l_ki;
m_nonZerosPerCol[i]++; /* increment count of nonzeros in col i */
++m_nonZerosPerCol[i]; /* increment count of nonzeros in col i */
}
if (m_diag[k] == 0.0)
{

View File

@@ -41,7 +41,7 @@ class SparseLLT
protected:
typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
typedef SparseMatrix<Scalar,Lower> CholMatrixType;
typedef SparseMatrix<Scalar,LowerTriangular> CholMatrixType;
enum {
SupernodalFactorIsDirty = 0x10000,

View File

@@ -41,7 +41,7 @@ class SparseLU
protected:
typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
typedef SparseMatrix<Scalar,Lower> LUMatrixType;
typedef SparseMatrix<Scalar,LowerTriangular> LUMatrixType;
enum {
MatrixLUIsDirty = 0x10000

View File

@@ -128,24 +128,41 @@ class SparseMatrix
class InnerIterator;
inline void setZero()
{
m_data.clear();
//if (m_outerSize)
memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(int));
// for (int i=0; i<m_outerSize; ++i)
// m_outerIndex[i] = 0;
// if (m_outerSize)
// m_outerIndex[i] = 0;
}
/** \returns the number of non zero coefficients */
inline int nonZeros() const { return m_data.size(); }
/** Initializes the filling process of \c *this.
* \param reserveSize approximate number of nonzeros
* Note that the matrix \c *this is zero-ed.
*/
inline void startFill(int reserveSize = 1000)
{
m_data.clear();
std::cerr << this << " startFill\n";
setZero();
m_data.reserve(reserveSize);
for (int i=0; i<=m_outerSize; ++i)
m_outerIndex[i] = 0;
}
/**
*/
inline Scalar& fill(int row, int col)
{
const int outer = RowMajor ? row : col;
const int inner = RowMajor ? col : row;
// std::cout << " fill " << outer << "," << inner << "\n";
if (m_outerIndex[outer+1]==0)
{
// we start a new inner vector
int i = outer;
while (i>=0 && m_outerIndex[i]==0)
{
@@ -156,20 +173,62 @@ class SparseMatrix
}
assert(m_outerIndex[outer+1] == m_data.size());
int id = m_outerIndex[outer+1];
m_outerIndex[outer+1]++;
++m_outerIndex[outer+1];
m_data.append(0, inner);
return m_data.value(id);
}
/** Like fill() but with random inner coordinates.
*/
inline Scalar& fillrand(int row, int col)
{
const int outer = RowMajor ? row : col;
const int inner = RowMajor ? col : row;
if (m_outerIndex[outer+1]==0)
{
// we start a new inner vector
// nothing special to do here
int i = outer;
while (i>=0 && m_outerIndex[i]==0)
{
m_outerIndex[i] = m_data.size();
--i;
}
m_outerIndex[outer+1] = m_outerIndex[outer];
}
// std::cerr << this << " " << outer << " " << inner << " - " << m_outerIndex[outer] << " " << m_outerIndex[outer+1] << "\n";
assert(m_outerIndex[outer+1] == m_data.size() && "invalid outer index");
int startId = m_outerIndex[outer];
int id = m_outerIndex[outer+1]-1;
++m_outerIndex[outer+1];
m_data.resize(id+2);
while ( (id >= startId) && (m_data.index(id) > inner) )
{
m_data.index(id+1) = m_data.index(id);
m_data.value(id+1) = m_data.value(id);
--id;
}
m_data.index(id+1) = inner;
//return (m_data.value(id+1) = 0);
m_data.value(id+1) = 0;
std::cerr << m_outerIndex[outer] << " " << m_outerIndex[outer+1] << "\n";
return m_data.value(id+1);
}
// inline void
inline void endFill()
{
std::cerr << this << " endFill\n";
int size = m_data.size();
int i = m_outerSize;
// find the last filled column
while (i>=0 && m_outerIndex[i]==0)
--i;
i++;
++i;
while (i<=m_outerSize)
{
m_outerIndex[i] = size;
@@ -179,6 +238,7 @@ class SparseMatrix
void resize(int rows, int cols)
{
std::cerr << this << " resize " << rows << "x" << cols << "\n";
const int outerSize = RowMajor ? rows : cols;
m_innerSize = RowMajor ? cols : rows;
m_data.clear();
@@ -195,8 +255,10 @@ class SparseMatrix
}
inline SparseMatrix()
: m_outerSize(0), m_innerSize(0), m_outerIndex(0)
{}
: m_outerSize(-1), m_innerSize(0), m_outerIndex(0)
{
resize(0, 0);
}
inline SparseMatrix(int rows, int cols)
: m_outerSize(0), m_innerSize(0), m_outerIndex(0)
@@ -256,7 +318,7 @@ class SparseMatrix
// FIXME the above copy could be merged with that pass
for (int j=0; j<otherCopy.outerSize(); ++j)
for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
m_outerIndex[it.index()]++;
++m_outerIndex[it.index()];
// prefix sum
int count = 0;
@@ -293,14 +355,14 @@ class SparseMatrix
{
EIGEN_DBG_SPARSE(
s << "Nonzero entries:\n";
for (uint i=0; i<m.nonZeros(); ++i)
for (unsigned int i=0; i<m.nonZeros(); ++i)
{
s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") ";
}
s << std::endl;
s << std::endl;
s << "Column pointers:\n";
for (uint i=0; i<m.cols(); ++i)
for (unsigned int i=0; i<m.cols(); ++i)
{
s << m.m_outerIndex[i] << " ";
}

View File

@@ -63,8 +63,8 @@ class SparseMatrixBase : public MatrixBase<Derived>
inline Derived& operator=(const MatrixBase<OtherDerived>& other)
{
// std::cout << "Derived& operator=(const MatrixBase<OtherDerived>& other)\n";
const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
ei_assert((!transpose) && "the transpose operation is supposed to be handled in SparseMatrix::operator=");
//const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
ei_assert((!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit))) && "the transpose operation is supposed to be handled in SparseMatrix::operator=");
const int outerSize = other.outerSize();
//typedef typename ei_meta_if<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::ret TempType;
// thanks to shallow copies, we always eval to a tempary

View File

@@ -138,8 +138,8 @@ struct ei_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,ColMajor,ColMajor>
// make sure to call innerSize/outerSize since we fake the storage order.
int rows = lhs.innerSize();
int cols = rhs.outerSize();
int size = lhs.outerSize();
ei_assert(size == rhs.innerSize());
//int size = lhs.outerSize();
ei_assert(lhs.outerSize() == rhs.innerSize());
// allocate a temporary buffer
AmbiVector<Scalar> tempVector(rows);

View File

@@ -162,9 +162,9 @@ struct SluMatrixMapHelper<SparseMatrix<Scalar,Flags> >
res.setScalarType<Scalar>();
// FIXME the following is not very accurate
if (Flags & Upper)
if (Flags & UpperTriangular)
res.Mtype = SLU_TRU;
if (Flags & Lower)
if (Flags & LowerTriangular)
res.Mtype = SLU_TRL;
if (Flags & SelfAdjoint)
ei_assert(false && "SelfAdjoint matrix shape not supported by SuperLU");
@@ -213,8 +213,8 @@ class SparseLU<MatrixType,SuperLU> : public SparseLU<MatrixType>
typedef Matrix<Scalar,Dynamic,1> Vector;
typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
typedef SparseMatrix<Scalar,Lower|UnitDiagBit> LMatrixType;
typedef SparseMatrix<Scalar,Upper> UMatrixType;
typedef SparseMatrix<Scalar,LowerTriangular|UnitDiagBit> LMatrixType;
typedef SparseMatrix<Scalar,UpperTriangular> UMatrixType;
using Base::m_flags;
using Base::m_status;

View File

@@ -50,13 +50,13 @@ taucs_ccs_matrix SparseMatrix<Scalar,Flags>::asTaucsMatrix()
ei_assert(false && "Scalar type not supported by TAUCS");
}
if (Flags & Upper)
if (Flags & UpperTriangular)
res.flags |= TAUCS_UPPER;
if (Flags & Lower)
if (Flags & LowerTriangular)
res.flags |= TAUCS_LOWER;
if (Flags & SelfAdjoint)
res.flags |= (NumTraits<Scalar>::IsComplex ? TAUCS_HERMITIAN : TAUCS_SYMMETRIC);
else if ((Flags & Upper) || (Flags & Lower))
else if ((Flags & UpperTriangular) || (Flags & LowerTriangular))
res.flags |= TAUCS_TRIANGULAR;
return res;

View File

@@ -27,7 +27,7 @@
// forward substitution, row-major
template<typename Lhs, typename Rhs>
struct ei_solve_triangular_selector<Lhs,Rhs,Lower,RowMajor|IsSparse>
struct ei_solve_triangular_selector<Lhs,Rhs,LowerTriangular,RowMajor|IsSparse>
{
typedef typename Rhs::Scalar Scalar;
static void run(const Lhs& lhs, Rhs& other)
@@ -59,7 +59,7 @@ struct ei_solve_triangular_selector<Lhs,Rhs,Lower,RowMajor|IsSparse>
// backward substitution, row-major
template<typename Lhs, typename Rhs>
struct ei_solve_triangular_selector<Lhs,Rhs,Upper,RowMajor|IsSparse>
struct ei_solve_triangular_selector<Lhs,Rhs,UpperTriangular,RowMajor|IsSparse>
{
typedef typename Rhs::Scalar Scalar;
static void run(const Lhs& lhs, Rhs& other)
@@ -92,7 +92,7 @@ struct ei_solve_triangular_selector<Lhs,Rhs,Upper,RowMajor|IsSparse>
// forward substitution, col-major
template<typename Lhs, typename Rhs>
struct ei_solve_triangular_selector<Lhs,Rhs,Lower,ColMajor|IsSparse>
struct ei_solve_triangular_selector<Lhs,Rhs,LowerTriangular,ColMajor|IsSparse>
{
typedef typename Rhs::Scalar Scalar;
static void run(const Lhs& lhs, Rhs& other)
@@ -120,7 +120,7 @@ struct ei_solve_triangular_selector<Lhs,Rhs,Lower,ColMajor|IsSparse>
// backward substitution, col-major
template<typename Lhs, typename Rhs>
struct ei_solve_triangular_selector<Lhs,Rhs,Upper,ColMajor|IsSparse>
struct ei_solve_triangular_selector<Lhs,Rhs,UpperTriangular,ColMajor|IsSparse>
{
typedef typename Rhs::Scalar Scalar;
static void run(const Lhs& lhs, Rhs& other)

View File

@@ -127,8 +127,8 @@ class SparseLU<MatrixType,UmfPack> : public SparseLU<MatrixType>
typedef Matrix<Scalar,Dynamic,1> Vector;
typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
typedef SparseMatrix<Scalar,Lower|UnitDiagBit> LMatrixType;
typedef SparseMatrix<Scalar,Upper> UMatrixType;
typedef SparseMatrix<Scalar,LowerTriangular|UnitDiagBit> LMatrixType;
typedef SparseMatrix<Scalar,UpperTriangular> UMatrixType;
using Base::m_flags;
using Base::m_status;

View File

@@ -21,6 +21,16 @@ IF(CMAKE_COMPILER_IS_GNUCXX OR IS_ICPC)
ENDIF(NOT BTL_NOVEC)
ENDIF(CMAKE_COMPILER_IS_GNUCXX OR IS_ICPC)
IF(MSVC)
SET(CMAKE_CXX_FLAGS " /O2 /Ot /GL /fp:fast -DNDEBUG")
# SET(CMAKE_Fortran_FLAGS "-g0 -O3 -DNDEBUG")
IF(NOT BTL_NOVEC)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2")
ELSE(NOT BTL_NOVEC)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEIGEN_DONT_VECTORIZE")
ENDIF(NOT BTL_NOVEC)
ENDIF(MSVC)
if(IS_ICPC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fast")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fast")

View File

@@ -86,9 +86,9 @@ public :
}
BTL_DONT_INLINE void calculate( void ) {
asm("#begin atv");
BTL_ASM_COMMENT("begin atv");
Interface::atv_product(A,B,X,_size);
asm("#end atv");
BTL_ASM_COMMENT("end atv");
}
void check_result( void )

View File

@@ -85,9 +85,9 @@ public :
}
inline void calculate( void ) {
asm("#mybegin axpby");
BTL_ASM_COMMENT("mybegin axpby");
Interface::axpby(_alpha,X,_beta,Y,_size);
asm("#myend axpby");
BTL_ASM_COMMENT("myend axpby");
}
void check_result( void ){

View File

@@ -96,9 +96,9 @@ public :
}
inline void calculate( void ) {
asm("#mybegin axpy");
BTL_ASM_COMMENT("mybegin axpy");
Interface::axpy(_coef,X,Y,_size);
asm("#myend axpy");
BTL_ASM_COMMENT("myend axpy");
}
void check_result( void ){

View File

@@ -103,9 +103,9 @@ public :
}
BTL_DONT_INLINE void calculate( void ) {
asm("#begin matrix_vector_product");
BTL_ASM_COMMENT("#begin matrix_vector_product");
Interface::matrix_vector_product(A,B,X,_size);
asm("#end matrix_vector_product");
BTL_ASM_COMMENT("end matrix_vector_product");
}
BTL_DONT_INLINE void check_result( void ){

View File

@@ -117,9 +117,7 @@ int main( int argc , char *argv[] )
cout << " <TH ALIGN=CENTER> comments </TH>" << endl ;
cout << " </TR>" << endl ;
set<Lib_Mean>::iterator is ;
is=s_lib_mean.begin();
multiset<Lib_Mean>::iterator is = s_lib_mean.begin();
Lib_Mean best(*is);

View File

@@ -38,7 +38,13 @@
#define BTL_DONT_INLINE
#endif
#ifndef __INTEL_COMPILER
#if (defined __GNUC__)
#define BTL_ASM_COMMENT(X) asm("#"X)
#else
#define BTL_ASM_COMMENT(X)
#endif
#if (defined __GNUC__) && (!defined __INTEL_COMPILER)
#define BTL_DISABLE_SSE_EXCEPTIONS() { \
int aux; \
asm( \

View File

@@ -26,10 +26,6 @@
#include <cstdlib>
#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <sys/times.h>
#define USEC_IN_SEC 1000000
@@ -38,38 +34,65 @@
// timer -------------------------------------------------------------------//
// A timer object measures CPU time.
#ifdef _MSC_VER
// class Portable_Timer
// {
// public:
//
// Portable_Timer( void )
// {
// }
//
//
// void start() { m_val = getTime(); }
//
// void stop() { m_val = getTime() - m_val; }
//
// double elapsed() { return m_val; }
//
// double user_time() { return elapsed(); }
//
//
// private:
//
// static inline double getTime(void)
// {
// struct timeval tv;
// struct timezone tz;
// gettimeofday(&tv, &tz);
// return (double)tv.tv_sec + 1.e-6 * (double)tv.tv_usec;
// }
//
// double m_val;
//
// }; // Portable_Timer
#define NOMINMAX
#include <windows.h>
/*#ifndef hr_timer
#include "hr_time.h"
#define hr_timer
#endif*/
class Portable_Timer
{
public:
typedef struct {
LARGE_INTEGER start;
LARGE_INTEGER stop;
} stopWatch;
Portable_Timer()
{
startVal.QuadPart = 0;
stopVal.QuadPart = 0;
QueryPerformanceFrequency(&frequency);
}
void start() { QueryPerformanceCounter(&startVal); }
void stop() { QueryPerformanceCounter(&stopVal); }
double elapsed() {
LARGE_INTEGER time;
time.QuadPart = stopVal.QuadPart - startVal.QuadPart;
return LIToSecs(time);
}
double user_time() { return elapsed(); }
private:
double LIToSecs(LARGE_INTEGER& L) {
return ((double)L.QuadPart /(double)frequency.QuadPart) ;
}
LARGE_INTEGER startVal;
LARGE_INTEGER stopVal;
LARGE_INTEGER frequency;
}; // Portable_Timer
#else
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <sys/times.h>
class Portable_Timer
{
@@ -137,5 +160,6 @@ private:
}; // Portable_Timer
#endif
#endif // PORTABLE_TIMER_HPP

View File

@@ -40,5 +40,5 @@ if (EIGEN2_FOUND)
set_target_properties(btl_tiny_eigen2_novec PROPERTIES COMPILE_FLAGS "-DEIGEN_DONT_VECTORIZE")
endif(BUILD_btl_tiny_eigen2_novec)
ENDIF(NOT BTL_NOVEC)
endif (EIGEN2_FOUND)

View File

@@ -109,7 +109,7 @@ public :
X = (A*A.transpose()).lazy();
}
static inline void matrix_vector_product(const gene_matrix & __restrict__ A, const gene_vector & __restrict__ B, gene_vector & __restrict__ X, int N){
static inline void matrix_vector_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N){
X = (A*B)/*.lazy()*/;
}
@@ -134,11 +134,11 @@ public :
}
static inline void trisolve_lower(const gene_matrix & L, const gene_vector& B, gene_vector& X, int N){
X = L.template marked<Lower>().solveTriangular(B);
X = L.template marked<LowerTriangular>().solveTriangular(B);
}
static inline void trisolve_lower_matrix(const gene_matrix & L, const gene_matrix& B, gene_matrix& X, int N){
X = L.template marked<Lower>().solveTriangular(B);
X = L.template marked<LowerTriangular>().solveTriangular(B);
}
static inline void cholesky(const gene_matrix & X, gene_matrix & C, int N){

View File

@@ -1,4 +1,6 @@
if(CMAKE_MINOR_VERSION GREATER 4)
enable_language(Fortran)
if(NOT MSVC)
enable_language(Fortran)
endif(NOT MSVC)
btl_add_bench(btl_f77 main.cpp dmxv.f smxv.f dmxm.f smxm.f daxpy.f saxpy.f data.f sata.f daat.f saat.f OFF)
endif(CMAKE_MINOR_VERSION GREATER 4)

View File

@@ -37,8 +37,8 @@
X \
} timer.stop(); }
// typedef SparseMatrix<Scalar,Upper> EigenSparseTriMatrix;
typedef SparseMatrix<Scalar,SelfAdjoint|Lower> EigenSparseSelfAdjointMatrix;
// typedef SparseMatrix<Scalar,UpperTriangular> EigenSparseTriMatrix;
typedef SparseMatrix<Scalar,SelfAdjoint|LowerTriangular> EigenSparseSelfAdjointMatrix;
void fillSpdMatrix(float density, int rows, int cols, EigenSparseSelfAdjointMatrix& dst)
{

View File

@@ -34,8 +34,8 @@
X \
} timer.stop(); }
typedef SparseMatrix<Scalar,Upper> EigenSparseTriMatrix;
typedef SparseMatrix<Scalar,RowMajorBit|Upper> EigenSparseTriMatrixRow;
typedef SparseMatrix<Scalar,UpperTriangular> EigenSparseTriMatrix;
typedef SparseMatrix<Scalar,RowMajorBit|UpperTriangular> EigenSparseTriMatrixRow;
void fillMatrix(float density, int rows, int cols, EigenSparseTriMatrix& dst)
{
@@ -83,11 +83,11 @@ int main(int argc, char *argv[])
eiToDense(sm1, m1);
m2 = m1;
BENCH(x = m1.marked<Upper>().solveTriangular(b);)
BENCH(x = m1.marked<UpperTriangular>().solveTriangular(b);)
std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;
// std::cerr << x.transpose() << "\n";
BENCH(x = m2.marked<Upper>().solveTriangular(b);)
BENCH(x = m2.marked<UpperTriangular>().solveTriangular(b);)
std::cout << " rowmajor^-1 * b:\t" << timer.value() << endl;
// std::cerr << x.transpose() << "\n";
}

View File

@@ -1193,7 +1193,8 @@ INCLUDE_FILE_PATTERNS =
PREDEFINED = EIGEN_EMPTY_STRUCT \
EIGEN_PARSED_BY_DOXYGEN \
EIGEN_VECTORIZE \
EIGEN_QT_SUPPORT
EIGEN_QT_SUPPORT \
EIGEN_STRONG_INLINE=inline
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.

View File

@@ -60,7 +60,7 @@ SSE2, like AltiVec, is a set of instructions allowing to perform computations on
However, in the above program, we have chosen size=50, so our vectors consist of 50 float's, and 50 is not a multiple of 4. This means that we cannot hope to do all of that computation using SSE2 instructions. The second best thing, to which we should aim, is to handle the 48 first coefficients with SSE2 instructions, since 48 is the biggest multiple of 4 below 50, and then handle separately, without SSE2, the 49th and 50th coefficients. Something like this:
\code
for(int i = 0; i < size/4; i++) u.packet(i) = v.packet(i) + w.packet(i);
for(int i = 0; i < 4*(size/4); i+=4) u.packet(i) = v.packet(i) + w.packet(i);
for(int i = 4*(size/4); i < size; i++) u[i] = v[i] + w[i];
\endcode

View File

@@ -14,6 +14,7 @@ namespace Eigen {
- \ref TutorialCoreSimpleExampleFixedSize
- \ref TutorialCoreSimpleExampleDynamicSize
- \ref TutorialCoreMatrixTypes
- \ref TutorialCoreCoefficients
- \ref TutorialCoreMatrixInitialization
- \ref TutorialCoreArithmeticOperators
- \ref TutorialCoreReductions
@@ -87,8 +88,23 @@ For example, \c Vector3d is a typedef for \code Matrix<double, 3, 1> \endcode
For dynamic-size, that is in order to left the number of rows or of columns unspecified at compile-time, use the special value Eigen::Dynamic. For example, \c VectorXd is a typedef for \code Matrix<double, Dynamic, 1> \endcode
<a href="#" class="top">top</a>\section TutorialCoreCoefficients Coefficient access
Eigen supports the following syntaxes for read and write coefficient access:
\code
matrix(i,j);
vector(i)
vector[i]
vector.x() // first coefficient
vector.y() // second coefficient
vector.z() // third coefficient
vector.w() // fourth coefficient
\endcode
Notice that these coefficient access methods have assertions checking the ranges. So if you do a lot of coefficient access, these assertion can have an important cost. There are then two possibilities if you want avoid paying this cost:
\li Either you can disable assertions altogether, by defining EIGEN_NO_DEBUG or NDEBUG. Notice that some IDEs like MS Visual Studio define NDEBUG automatically in "Release Mode".
\li Or you can disable the checks on a case-by-case basis by using the coeff() and coeffRef() methods: see MatrixBase::coeff(int,int) const, MatrixBase::coeffRef(int,int), etc.
<a href="#" class="top">top</a>\section TutorialCoreMatrixInitialization Matrix and vector creation and initialization
@@ -513,20 +529,20 @@ Read/write access to special parts of a matrix can be achieved. See \link Matrix
<tr><td>
Extract triangular matrices \n from a given matrix m:
</td><td>\code
m.part<Eigen::Upper>()
m.part<Eigen::StrictlyUpper>()
m.part<Eigen::UnitUpper>()
m.part<Eigen::Lower>()
m.part<Eigen::StrictlyLower>()
m.part<Eigen::UnitLower>()\endcode
m.part<Eigen::UpperTriangular>()
m.part<Eigen::StrictlyUpperTriangular>()
m.part<Eigen::UnitUpperTriangular>()
m.part<Eigen::LowerTriangular>()
m.part<Eigen::StrictlyLowerTriangular>()
m.part<Eigen::UnitLowerTriangular>()\endcode
</td></tr>
<tr><td>
Write to triangular parts \n of a matrix m:
</td><td>\code
m1.part<Eigen::Upper>() = m2;
m1.part<Eigen::StrictlyUpper>() = m2;
m1.part<Eigen::Lower>() = m2;
m1.part<Eigen::StrictlyLower>() = m2;\endcode
m1.part<Eigen::UpperTriangular>() = m2;
m1.part<Eigen::StrictlyUpperTriangular>() = m2;
m1.part<Eigen::LowerTriangular>() = m2;
m1.part<Eigen::StrictlyLowerTriangular>() = m2;\endcode
</td></tr>
<tr><td>
Special: take advantage of symmetry \n (selfadjointness) when copying \n an expression into a matrix

Some files were not shown because too many files have changed in this diff Show More