mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3de311f497 | ||
|
|
06fd84cdb1 | ||
|
|
0e5c640563 | ||
|
|
be64619ab6 | ||
|
|
269bf67796 | ||
|
|
15ca6659ac | ||
|
|
d9e5fd393a | ||
|
|
fd7eba3394 | ||
|
|
d671205755 | ||
|
|
3958e7f751 | ||
|
|
164f410bb5 | ||
|
|
a2782964c1 | ||
|
|
ce3984844d | ||
|
|
361225068d | ||
|
|
6f158fb7fc | ||
|
|
789ea9d676 | ||
|
|
4336cf3833 | ||
|
|
f5a05e7ed1 | ||
|
|
9e00d94543 | ||
|
|
21ab65e4b3 | ||
|
|
ebf906a23a | ||
|
|
df4bd5e46f | ||
|
|
a3fad2e3c3 | ||
|
|
5f6fbaa0e7 | ||
|
|
8679d895d3 | ||
|
|
22875683b9 | ||
|
|
e4980616fd | ||
|
|
84bb868f07 | ||
|
|
f34a4fa335 | ||
|
|
8106d35408 | ||
|
|
fabaa6915b | ||
|
|
b27a3644a2 | ||
|
|
93f8d56789 | ||
|
|
15d72d3f9a | ||
|
|
9084e2a216 | ||
|
|
6e138d0069 | ||
|
|
4cb63808d4 | ||
|
|
c98fe0185e | ||
|
|
5f582aa4e8 | ||
|
|
c22d10f94c | ||
|
|
e3a8431a4a | ||
|
|
89f468671d | ||
|
|
2110cca431 | ||
|
|
38b83b4157 | ||
|
|
50105c3ed6 | ||
|
|
0a220721d1 | ||
|
|
1ad751b991 | ||
|
|
55b603e457 | ||
|
|
763f0a2434 | ||
|
|
9b1a3d6e19 | ||
|
|
dd139b92b4 | ||
|
|
11c8a6bf63 | ||
|
|
703951d5cd | ||
|
|
d11c8704e0 | ||
|
|
a164646c77 | ||
|
|
936eaf600a | ||
|
|
ef0cd3a289 | ||
|
|
1ed17b037d | ||
|
|
5015e48361 | ||
|
|
beabf008b0 | ||
|
|
ba9a53f9c6 | ||
|
|
52a30c1d54 |
@@ -1,10 +1,13 @@
|
||||
project(Eigen)
|
||||
set(EIGEN_VERSION_NUMBER "2.0-beta2")
|
||||
set(EIGEN_VERSION_NUMBER "2.0-beta4")
|
||||
|
||||
#if the svnversion program is absent, this will leave the SVN_REVISION string empty,
|
||||
#but won't stop CMake.
|
||||
execute_process(COMMAND svnversion -n ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE EIGEN_SVN_REVISION)
|
||||
OUTPUT_VARIABLE EIGEN_SVNVERSION_OUTPUT)
|
||||
|
||||
#we only want EIGEN_SVN_REVISION if it is an actual revision number, not a string like "exported"
|
||||
string(REGEX MATCH "^[0-9]+.*" EIGEN_SVN_REVISION "${EIGEN_SVNVERSION_OUTPUT}")
|
||||
|
||||
if(EIGEN_SVN_REVISION)
|
||||
set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER} (SVN revision ${EIGEN_SVN_REVISION})")
|
||||
@@ -12,7 +15,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.2)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
|
||||
@@ -31,29 +34,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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
48
Eigen/Core
48
Eigen/Core
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
4
Eigen/LU
4
Eigen/LU
@@ -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
|
||||
|
||||
28
Eigen/LeastSquares
Normal file
28
Eigen/LeastSquares
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef EIGEN_REGRESSION_MODULE_H
|
||||
#define EIGEN_REGRESSION_MODULE_H
|
||||
|
||||
#include "Core"
|
||||
|
||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
||||
|
||||
#include "LU"
|
||||
#include "QR"
|
||||
#include "Geometry"
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \defgroup Regression_Module Regression module
|
||||
* This module provides linear regression and related features.
|
||||
*
|
||||
* \code
|
||||
* #include <Eigen/Regression>
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
#include "src/Regression/Regression.h"
|
||||
|
||||
} // namespace Eigen
|
||||
|
||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
||||
|
||||
#endif // EIGEN_REGRESSION_MODULE_H
|
||||
5
Eigen/QR
5
Eigen/QR
@@ -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
|
||||
|
||||
@@ -1,22 +1,5 @@
|
||||
#ifndef EIGEN_REGRESSION_MODULE_H
|
||||
#define EIGEN_REGRESSION_MODULE_H
|
||||
#ifdef __GNUC__
|
||||
#warning "The Eigen/Regression header file has been renamed to Eigen/LeastSquares. The old name is deprecated, please update your code."
|
||||
#endif
|
||||
|
||||
#include "LU"
|
||||
#include "QR"
|
||||
#include "Geometry"
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \defgroup Regression_Module Regression module
|
||||
* This module provides linear regression and related features.
|
||||
*
|
||||
* \code
|
||||
* #include <Eigen/Regression>
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
#include "src/Regression/Regression.h"
|
||||
|
||||
} // namespace Eigen
|
||||
|
||||
#endif // EIGEN_REGRESSION_MODULE_H
|
||||
#include "LeastSquares"
|
||||
@@ -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
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#define EIGEN_SPARSE_MODULE_H
|
||||
|
||||
#include "Core"
|
||||
|
||||
#include "src/Core/util/DisableMSVCWarnings.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <cstdlib>
|
||||
@@ -74,10 +77,8 @@ namespace Eigen {
|
||||
#include "src/Sparse/RandomSetter.h"
|
||||
#include "src/Sparse/SparseBlock.h"
|
||||
#include "src/Sparse/SparseMatrix.h"
|
||||
//#include "src/Sparse/HashMatrix.h"
|
||||
//#include "src/Sparse/LinkedVectorMatrix.h"
|
||||
#include "src/Sparse/SparseVector.h"
|
||||
#include "src/Sparse/CoreIterators.h"
|
||||
//#include "src/Sparse/SparseSetter.h"
|
||||
#include "src/Sparse/SparseProduct.h"
|
||||
#include "src/Sparse/TriangularSolver.h"
|
||||
#include "src/Sparse/SparseLLT.h"
|
||||
@@ -102,4 +103,6 @@ namespace Eigen {
|
||||
|
||||
} // namespace Eigen
|
||||
|
||||
#include "src/Core/util/EnableMSVCWarnings.h"
|
||||
|
||||
#endif // EIGEN_SPARSE_MODULE_H
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -95,9 +95,9 @@ static void ei_cache_friendly_product(
|
||||
const bool needRhsCopy = (PacketSize>1) && ((rhsStride%PacketSize!=0) || (size_t(rhs)%16!=0));
|
||||
Scalar* EIGEN_RESTRICT block = 0;
|
||||
const int allocBlockSize = l2BlockRows*size;
|
||||
block = ei_alloc_stack(Scalar, allocBlockSize);
|
||||
block = ei_aligned_stack_alloc(Scalar, allocBlockSize);
|
||||
Scalar* EIGEN_RESTRICT rhsCopy
|
||||
= ei_alloc_stack(Scalar, l2BlockSizeAligned*l2BlockSizeAligned);
|
||||
= ei_aligned_stack_alloc(Scalar, l2BlockSizeAligned*l2BlockSizeAligned);
|
||||
|
||||
// loops on each L2 cache friendly blocks of the result
|
||||
for(int l2i=0; l2i<rows; l2i+=l2BlockRows)
|
||||
@@ -338,8 +338,8 @@ static void ei_cache_friendly_product(
|
||||
}
|
||||
}
|
||||
|
||||
ei_free_stack(block, Scalar, allocBlockSize);
|
||||
ei_free_stack(rhsCopy, Scalar, l2BlockSizeAligned*l2BlockSizeAligned);
|
||||
ei_aligned_stack_free(block, Scalar, allocBlockSize);
|
||||
ei_aligned_stack_free(rhsCopy, Scalar, l2BlockSizeAligned*l2BlockSizeAligned);
|
||||
}
|
||||
|
||||
#endif // EIGEN_EXTERN_INSTANTIATIONS
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -40,7 +40,10 @@
|
||||
* \param _Cols Number of columns, or \b Dynamic
|
||||
*
|
||||
* The remaining template parameters are optional -- in most cases you don't have to worry about them.
|
||||
* \param _StorageOrder Either \b RowMajor or \b ColMajor. The default is \b ColMajor.
|
||||
* \param _Options A combination of either \b Matrix_RowMajor or \b Matrix_ColMajor, and of either
|
||||
* \b Matrix_AutoAlign or \b Matrix_DontAlign.
|
||||
* The former controls storage order, and defaults to column-major. The latter controls alignment, which is required
|
||||
* for vectorization. It defaults to aligning matrices except for fixed sizes that aren't a multiple of the packet size.
|
||||
* \param _MaxRows Maximum number of rows. Defaults to \a _Rows (\ref maxrows "note").
|
||||
* \param _MaxCols Maximum number of columns. Defaults to \a _Cols (\ref maxrows "note").
|
||||
*
|
||||
@@ -85,7 +88,7 @@
|
||||
* to 16x16. Larger matrices should be declared as dynamic-size even if one happens to know their size at compile-time.
|
||||
*
|
||||
* Dynamic-size means that the numbers of rows or columns are not necessarily known at compile-time. In this case they are runtime
|
||||
* variables, and the array of coefficients is allocated dynamically, typically on the heap (\ref alloca "note").
|
||||
* variables, and the array of coefficients is allocated dynamically on the heap.
|
||||
*
|
||||
* Note that \em dense matrices, be they Fixed-size or Dynamic-size, <em>do not</em> expand dynamically in the sense of a std::map.
|
||||
* If you want this behavior, see the Sparse module.</dd>
|
||||
@@ -97,15 +100,10 @@
|
||||
* exceed a certain value. This happens when taking dynamic-size blocks inside fixed-size matrices: in this case _MaxRows and _MaxCols
|
||||
* are the dimensions of the original matrix, while _Rows and _Cols are Dynamic.</dd>
|
||||
*
|
||||
* <dt><b>\anchor alloca Usage of alloca():</b></dt>
|
||||
* <dd>On the Linux platform, for small enough arrays, Eigen will avoid heap allocation and instead will use alloca() to perform a dynamic
|
||||
* allocation on the stack.</dd>
|
||||
* </dl>
|
||||
*
|
||||
* \see MatrixBase for the majority of the API methods for matrices
|
||||
*/
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols>
|
||||
struct ei_traits<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols> >
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||
struct ei_traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
||||
{
|
||||
typedef _Scalar Scalar;
|
||||
enum {
|
||||
@@ -113,35 +111,41 @@ struct ei_traits<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols
|
||||
ColsAtCompileTime = _Cols,
|
||||
MaxRowsAtCompileTime = _MaxRows,
|
||||
MaxColsAtCompileTime = _MaxCols,
|
||||
Flags = ei_compute_matrix_flags<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>::ret,
|
||||
Flags = ei_compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret,
|
||||
CoeffReadCost = NumTraits<Scalar>::ReadCost,
|
||||
SupportedAccessPatterns = RandomAccessPattern
|
||||
};
|
||||
};
|
||||
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols>
|
||||
template<typename T, int Rows, int Cols, int Options,
|
||||
bool NeedsToAlign = ((Options&Matrix_AutoAlign) == Matrix_AutoAlign) && Rows!=Dynamic && Cols!=Dynamic && ((sizeof(T)*Rows*Cols)%16==0)>
|
||||
struct ei_matrix_with_aligned_operator_new : WithAlignedOperatorNew {};
|
||||
|
||||
template<typename T, int Rows, int Cols, int Options>
|
||||
struct ei_matrix_with_aligned_operator_new<T, Rows, Cols, Options, false> {};
|
||||
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||
class Matrix
|
||||
: public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols> >
|
||||
#ifdef EIGEN_VECTORIZE
|
||||
, public ei_with_aligned_operator_new<_Scalar,ei_size_at_compile_time<_Rows,_Cols>::ret>
|
||||
#endif
|
||||
: public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
||||
, public ei_matrix_with_aligned_operator_new<_Scalar, _Rows, _Cols, _Options>
|
||||
{
|
||||
public:
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix)
|
||||
enum { Options = _Options };
|
||||
friend class Eigen::Map<Matrix, Unaligned>;
|
||||
typedef class Eigen::Map<Matrix, Unaligned> UnalignedMapType;
|
||||
friend class Eigen::Map<Matrix, Aligned>;
|
||||
typedef class Eigen::Map<Matrix, Aligned> AlignedMapType;
|
||||
|
||||
protected:
|
||||
ei_matrix_storage<Scalar, MaxSizeAtCompileTime, RowsAtCompileTime, ColsAtCompileTime> m_storage;
|
||||
ei_matrix_storage<Scalar, MaxSizeAtCompileTime, RowsAtCompileTime, ColsAtCompileTime, Options> m_storage;
|
||||
|
||||
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 +153,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 +161,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 +174,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 +189,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 +204,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 +264,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 +301,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 +336,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 +347,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 +365,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 +380,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 +402,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 +415,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 +430,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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -26,6 +26,27 @@
|
||||
#ifndef EIGEN_MATRIXSTORAGE_H
|
||||
#define EIGEN_MATRIXSTORAGE_H
|
||||
|
||||
/** \internal
|
||||
* Static array automatically aligned if the total byte size is a multiple of 16 and the matrix options require auto alignment
|
||||
*/
|
||||
template <typename T, int Size, int MatrixOptions,
|
||||
bool Align = (MatrixOptions&Matrix_AutoAlign) && (((Size*sizeof(T))&0xf)==0)
|
||||
> struct ei_matrix_array
|
||||
{
|
||||
EIGEN_ALIGN_128 T array[Size];
|
||||
|
||||
ei_matrix_array()
|
||||
{
|
||||
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 !!! ****");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int Size, int MatrixOptions> struct ei_matrix_array<T,Size,MatrixOptions,false>
|
||||
{
|
||||
T array[Size];
|
||||
};
|
||||
|
||||
/** \internal
|
||||
*
|
||||
* \class ei_matrix_storage
|
||||
@@ -37,12 +58,12 @@
|
||||
*
|
||||
* \sa Matrix
|
||||
*/
|
||||
template<typename T, int Size, int _Rows, int _Cols> class ei_matrix_storage;
|
||||
template<typename T, int Size, int _Rows, int _Cols, int _Options> class ei_matrix_storage;
|
||||
|
||||
// purely fixed-size matrix
|
||||
template<typename T, int Size, int _Rows, int _Cols> class ei_matrix_storage
|
||||
template<typename T, int Size, int _Rows, int _Cols, int _Options> class ei_matrix_storage
|
||||
{
|
||||
ei_aligned_array<T,Size,((Size*sizeof(T))%16)==0> m_data;
|
||||
ei_matrix_array<T,Size,_Options> m_data;
|
||||
public:
|
||||
inline explicit ei_matrix_storage() {}
|
||||
inline ei_matrix_storage(int,int,int) {}
|
||||
@@ -55,9 +76,9 @@ template<typename T, int Size, int _Rows, int _Cols> class ei_matrix_storage
|
||||
};
|
||||
|
||||
// dynamic-size matrix with fixed-size storage
|
||||
template<typename T, int Size> class ei_matrix_storage<T, Size, Dynamic, Dynamic>
|
||||
template<typename T, int Size, int _Options> class ei_matrix_storage<T, Size, Dynamic, Dynamic, _Options>
|
||||
{
|
||||
ei_aligned_array<T,Size,((Size*sizeof(T))%16)==0> m_data;
|
||||
ei_matrix_array<T,Size,_Options> m_data;
|
||||
int m_rows;
|
||||
int m_cols;
|
||||
public:
|
||||
@@ -78,9 +99,9 @@ template<typename T, int Size> class ei_matrix_storage<T, Size, Dynamic, Dynamic
|
||||
};
|
||||
|
||||
// dynamic-size matrix with fixed-size storage and fixed width
|
||||
template<typename T, int Size, int _Cols> class ei_matrix_storage<T, Size, Dynamic, _Cols>
|
||||
template<typename T, int Size, int _Cols, int _Options> class ei_matrix_storage<T, Size, Dynamic, _Cols, _Options>
|
||||
{
|
||||
ei_aligned_array<T,Size,((Size*sizeof(T))%16)==0> m_data;
|
||||
ei_matrix_array<T,Size,_Options> m_data;
|
||||
int m_rows;
|
||||
public:
|
||||
inline explicit ei_matrix_storage() : m_rows(0) {}
|
||||
@@ -98,9 +119,9 @@ template<typename T, int Size, int _Cols> class ei_matrix_storage<T, Size, Dynam
|
||||
};
|
||||
|
||||
// dynamic-size matrix with fixed-size storage and fixed height
|
||||
template<typename T, int Size, int _Rows> class ei_matrix_storage<T, Size, _Rows, Dynamic>
|
||||
template<typename T, int Size, int _Rows, int _Options> class ei_matrix_storage<T, Size, _Rows, Dynamic, _Options>
|
||||
{
|
||||
ei_aligned_array<T,Size,((Size*sizeof(T))%16)==0> m_data;
|
||||
ei_matrix_array<T,Size,_Options> m_data;
|
||||
int m_cols;
|
||||
public:
|
||||
inline explicit ei_matrix_storage() : m_cols(0) {}
|
||||
@@ -109,7 +130,7 @@ template<typename T, int Size, int _Rows> class ei_matrix_storage<T, Size, _Rows
|
||||
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
||||
inline int rows(void) const {return _Rows;}
|
||||
inline int cols(void) const {return m_cols;}
|
||||
inline void resize(int size, int, int cols)
|
||||
inline void resize(int, int, int cols)
|
||||
{
|
||||
m_cols = cols;
|
||||
}
|
||||
@@ -118,7 +139,7 @@ template<typename T, int Size, int _Rows> class ei_matrix_storage<T, Size, _Rows
|
||||
};
|
||||
|
||||
// purely dynamic matrix.
|
||||
template<typename T> class ei_matrix_storage<T, Dynamic, Dynamic, Dynamic>
|
||||
template<typename T, int _Options> class ei_matrix_storage<T, Dynamic, Dynamic, Dynamic, _Options>
|
||||
{
|
||||
T *m_data;
|
||||
int m_rows;
|
||||
@@ -127,7 +148,7 @@ template<typename T> class ei_matrix_storage<T, Dynamic, Dynamic, Dynamic>
|
||||
inline explicit ei_matrix_storage() : m_data(0), m_rows(0), m_cols(0) {}
|
||||
inline ei_matrix_storage(int size, int rows, int cols)
|
||||
: m_data(ei_aligned_malloc<T>(size)), m_rows(rows), m_cols(cols) {}
|
||||
inline ~ei_matrix_storage() { ei_aligned_free(m_data); }
|
||||
inline ~ei_matrix_storage() { ei_aligned_free(m_data, m_rows*m_cols); }
|
||||
inline void swap(ei_matrix_storage& other)
|
||||
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
|
||||
inline int rows(void) const {return m_rows;}
|
||||
@@ -136,7 +157,7 @@ template<typename T> class ei_matrix_storage<T, Dynamic, Dynamic, Dynamic>
|
||||
{
|
||||
if(size != m_rows*m_cols)
|
||||
{
|
||||
ei_aligned_free(m_data);
|
||||
ei_aligned_free(m_data, m_rows*m_cols);
|
||||
m_data = ei_aligned_malloc<T>(size);
|
||||
}
|
||||
m_rows = rows;
|
||||
@@ -147,14 +168,14 @@ template<typename T> class ei_matrix_storage<T, Dynamic, Dynamic, Dynamic>
|
||||
};
|
||||
|
||||
// matrix with dynamic width and fixed height (so that matrix has dynamic size).
|
||||
template<typename T, int _Rows> class ei_matrix_storage<T, Dynamic, _Rows, Dynamic>
|
||||
template<typename T, int _Rows, int _Options> class ei_matrix_storage<T, Dynamic, _Rows, Dynamic, _Options>
|
||||
{
|
||||
T *m_data;
|
||||
int m_cols;
|
||||
public:
|
||||
inline explicit ei_matrix_storage() : m_data(0), m_cols(0) {}
|
||||
inline ei_matrix_storage(int size, int, int cols) : m_data(ei_aligned_malloc<T>(size)), m_cols(cols) {}
|
||||
inline ~ei_matrix_storage() { ei_aligned_free(m_data); }
|
||||
inline ~ei_matrix_storage() { ei_aligned_free(m_data, _Rows*m_cols); }
|
||||
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
||||
inline static int rows(void) {return _Rows;}
|
||||
inline int cols(void) const {return m_cols;}
|
||||
@@ -162,7 +183,7 @@ template<typename T, int _Rows> class ei_matrix_storage<T, Dynamic, _Rows, Dynam
|
||||
{
|
||||
if(size != _Rows*m_cols)
|
||||
{
|
||||
ei_aligned_free(m_data);
|
||||
ei_aligned_free(m_data, _Rows*m_cols);
|
||||
m_data = ei_aligned_malloc<T>(size);
|
||||
}
|
||||
m_cols = cols;
|
||||
@@ -172,14 +193,14 @@ template<typename T, int _Rows> class ei_matrix_storage<T, Dynamic, _Rows, Dynam
|
||||
};
|
||||
|
||||
// matrix with dynamic height and fixed width (so that matrix has dynamic size).
|
||||
template<typename T, int _Cols> class ei_matrix_storage<T, Dynamic, Dynamic, _Cols>
|
||||
template<typename T, int _Cols, int _Options> class ei_matrix_storage<T, Dynamic, Dynamic, _Cols, _Options>
|
||||
{
|
||||
T *m_data;
|
||||
int m_rows;
|
||||
public:
|
||||
inline explicit ei_matrix_storage() : m_data(0), m_rows(0) {}
|
||||
inline ei_matrix_storage(int size, int rows, int) : m_data(ei_aligned_malloc<T>(size)), m_rows(rows) {}
|
||||
inline ~ei_matrix_storage() { ei_aligned_free(m_data); }
|
||||
inline ~ei_matrix_storage() { ei_aligned_free(m_data, _Cols*m_rows); }
|
||||
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
||||
inline int rows(void) const {return m_rows;}
|
||||
inline static int cols(void) {return _Cols;}
|
||||
@@ -187,7 +208,7 @@ template<typename T, int _Cols> class ei_matrix_storage<T, Dynamic, Dynamic, _Co
|
||||
{
|
||||
if(size != m_rows*_Cols)
|
||||
{
|
||||
ei_aligned_free(m_data);
|
||||
ei_aligned_free(m_data, _Cols*m_rows);
|
||||
m_data = ei_aligned_malloc<T>(size);
|
||||
}
|
||||
m_rows = rows;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -87,11 +89,12 @@ template<typename Lhs, typename Rhs> struct ei_product_mode
|
||||
? DiagonalProduct
|
||||
: (Rhs::Flags & Lhs::Flags & SparseBit)
|
||||
? SparseProduct
|
||||
: Lhs::MaxColsAtCompileTime >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
|
||||
&& ( Lhs::MaxRowsAtCompileTime >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
|
||||
|| Rhs::MaxColsAtCompileTime >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD )
|
||||
: Lhs::MaxColsAtCompileTime == Dynamic
|
||||
&& ( Lhs::MaxRowsAtCompileTime == Dynamic
|
||||
|| Rhs::MaxColsAtCompileTime == Dynamic )
|
||||
&& (!(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);
|
||||
}
|
||||
};
|
||||
@@ -569,7 +573,7 @@ struct ei_cache_friendly_product_selector<ProductType,LhsRows,ColMajor,HasDirect
|
||||
_res = &res.coeffRef(0);
|
||||
else
|
||||
{
|
||||
_res = ei_alloc_stack(Scalar,res.size());
|
||||
_res = ei_aligned_stack_alloc(Scalar,res.size());
|
||||
Map<Matrix<Scalar,DestDerived::RowsAtCompileTime,1> >(_res, res.size()) = res;
|
||||
}
|
||||
ei_cache_friendly_product_colmajor_times_vector(res.size(),
|
||||
@@ -579,7 +583,7 @@ struct ei_cache_friendly_product_selector<ProductType,LhsRows,ColMajor,HasDirect
|
||||
if (!EvalToRes)
|
||||
{
|
||||
res = Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1> >(_res, res.size());
|
||||
ei_free_stack(_res, Scalar, res.size());
|
||||
ei_aligned_stack_free(_res, Scalar, res.size());
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -615,7 +619,7 @@ struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCo
|
||||
_res = &res.coeffRef(0);
|
||||
else
|
||||
{
|
||||
_res = ei_alloc_stack(Scalar, res.size());
|
||||
_res = ei_aligned_stack_alloc(Scalar, res.size());
|
||||
Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1> >(_res, res.size()) = res;
|
||||
}
|
||||
ei_cache_friendly_product_colmajor_times_vector(res.size(),
|
||||
@@ -625,7 +629,7 @@ struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCo
|
||||
if (!EvalToRes)
|
||||
{
|
||||
res = Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1> >(_res, res.size());
|
||||
ei_free_stack(_res, Scalar, res.size());
|
||||
ei_aligned_stack_free(_res, Scalar, res.size());
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -648,13 +652,13 @@ struct ei_cache_friendly_product_selector<ProductType,LhsRows,RowMajor,HasDirect
|
||||
_rhs = &product.rhs().const_cast_derived().coeffRef(0);
|
||||
else
|
||||
{
|
||||
_rhs = ei_alloc_stack(Scalar, product.rhs().size());
|
||||
_rhs = ei_aligned_stack_alloc(Scalar, product.rhs().size());
|
||||
Map<Matrix<Scalar,Rhs::SizeAtCompileTime,1> >(_rhs, product.rhs().size()) = product.rhs();
|
||||
}
|
||||
ei_cache_friendly_product_rowmajor_times_vector(&product.lhs().const_cast_derived().coeffRef(0,0), product.lhs().stride(),
|
||||
_rhs, product.rhs().size(), res);
|
||||
|
||||
if (!UseRhsDirectly) ei_free_stack(_rhs, Scalar, product.rhs().size());
|
||||
if (!UseRhsDirectly) ei_aligned_stack_free(_rhs, Scalar, product.rhs().size());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -676,13 +680,13 @@ struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCo
|
||||
_lhs = &product.lhs().const_cast_derived().coeffRef(0);
|
||||
else
|
||||
{
|
||||
_lhs = ei_alloc_stack(Scalar, product.lhs().size());
|
||||
_lhs = ei_aligned_stack_alloc(Scalar, product.lhs().size());
|
||||
Map<Matrix<Scalar,Lhs::SizeAtCompileTime,1> >(_lhs, product.lhs().size()) = product.lhs();
|
||||
}
|
||||
ei_cache_friendly_product_rowmajor_times_vector(&product.rhs().const_cast_derived().coeffRef(0,0), product.rhs().stride(),
|
||||
_lhs, product.lhs().size(), res);
|
||||
|
||||
if(!UseLhsDirectly) ei_free_stack(_lhs, Scalar, product.lhs().size());
|
||||
if(!UseLhsDirectly) ei_aligned_stack_free(_lhs, Scalar, product.lhs().size());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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 };
|
||||
@@ -223,8 +223,15 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
ColMajor = 0,
|
||||
RowMajor = RowMajorBit
|
||||
Matrix_ColMajor = 0,
|
||||
Matrix_RowMajor = 0x1, // it is only a coincidence that this is equal to RowMajorBit -- don't rely on that
|
||||
/** \internal Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be
|
||||
requested to be aligned) */
|
||||
ColMajor = Matrix_ColMajor, // deprecated
|
||||
RowMajor = Matrix_RowMajor, // deprecated
|
||||
Matrix_DontAlign = 0,
|
||||
/** \internal Align the matrix itself */
|
||||
Matrix_AutoAlign = 0x2
|
||||
};
|
||||
|
||||
enum {
|
||||
|
||||
9
Eigen/src/Core/util/DisableMSVCWarnings.h
Normal file
9
Eigen/src/Core/util/DisableMSVCWarnings.h
Normal 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
|
||||
8
Eigen/src/Core/util/EnableMSVCWarnings.h
Normal file
8
Eigen/src/Core/util/EnableMSVCWarnings.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef EIGEN_ENABLEMSVCWARNINGS_H
|
||||
#define EIGEN_ENABLEMSVCWARNINGS_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
#endif // EIGEN_ENABLEMSVCWARNINGS_H
|
||||
@@ -28,7 +28,8 @@
|
||||
template<typename T> struct ei_traits;
|
||||
template<typename T> struct NumTraits;
|
||||
|
||||
template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder = ColMajor,
|
||||
template<typename _Scalar, int _Rows, int _Cols,
|
||||
int _Options = EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION | Matrix_AutoAlign,
|
||||
int _MaxRows = _Rows, int _MaxCols = _Cols> class Matrix;
|
||||
|
||||
template<typename ExpressionType, unsigned int Added, unsigned int Removed> class Flagged;
|
||||
|
||||
@@ -28,6 +28,20 @@
|
||||
|
||||
#undef minor
|
||||
|
||||
#define EIGEN_WORLD_VERSION 2
|
||||
#define EIGEN_MAJOR_VERSION 0
|
||||
#define EIGEN_MINOR_VERSION 0
|
||||
|
||||
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
|
||||
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
|
||||
EIGEN_MINOR_VERSION>=z))))
|
||||
|
||||
#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
|
||||
#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION Matrix_RowMajor
|
||||
#else
|
||||
#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION Matrix_ColMajor
|
||||
#endif
|
||||
|
||||
/** \internal Defines the maximal loop size to enable meta unrolling of loops.
|
||||
* Note that the value here is expressed in Eigen's own notion of "number of FLOPS",
|
||||
* it does not correspond to the number of iterations or the number of instructions
|
||||
@@ -84,36 +98,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 +163,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 +192,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, \
|
||||
|
||||
@@ -26,58 +26,83 @@
|
||||
#ifndef EIGEN_MEMORY_H
|
||||
#define EIGEN_MEMORY_H
|
||||
|
||||
#ifdef EIGEN_VECTORIZE
|
||||
#ifdef __linux
|
||||
// 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
|
||||
|
||||
/** \internal
|
||||
* Static array automatically aligned if the total byte size is a multiple of 16
|
||||
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, int Size, bool Align> struct ei_aligned_array
|
||||
{
|
||||
EIGEN_ALIGN_128 T array[Size];
|
||||
|
||||
ei_aligned_array()
|
||||
{
|
||||
ei_assert((reinterpret_cast<unsigned int>(array) & 0xf) == 0
|
||||
&& "this assertion is explained here: http://eigen.tuxfamily.org/api/UnalignedArrayAssert.html **** READ THIS WEB PAGE !!! ****");
|
||||
}
|
||||
};
|
||||
|
||||
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 */
|
||||
template<typename T>
|
||||
inline T* ei_aligned_malloc(size_t size)
|
||||
{
|
||||
#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;
|
||||
void *void_result;
|
||||
#ifdef __linux
|
||||
#ifdef EIGEN_EXCEPTIONS
|
||||
const int failed =
|
||||
#endif
|
||||
posix_memalign(&void_result, 16, size*sizeof(T));
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
void_result = _aligned_malloc(size*sizeof(T), 16);
|
||||
#else
|
||||
void_result = _mm_malloc(size*sizeof(T), 16);
|
||||
#endif
|
||||
#ifdef EIGEN_EXCEPTIONS
|
||||
const int failed = (void_result == 0);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef EIGEN_EXCEPTIONS
|
||||
if(failed)
|
||||
throw std::bad_alloc();
|
||||
#endif
|
||||
// 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!
|
||||
// so when we use C functions to allocate memory, we must be careful to call manually the constructor using
|
||||
// the special placement-new syntax.
|
||||
return new(void_result) T[size];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return new T[size];
|
||||
return 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.
|
||||
}
|
||||
|
||||
/** \internal free memory allocated with ei_aligned_malloc */
|
||||
/** \internal free memory allocated with ei_aligned_malloc
|
||||
* The \a size parameter is used to determine on how many elements to call the destructor. If you don't
|
||||
* want any destructor to be called, just pass 0.
|
||||
*/
|
||||
template<typename T>
|
||||
inline void ei_aligned_free(T* ptr)
|
||||
inline void ei_aligned_free(T* ptr, size_t size)
|
||||
{
|
||||
#ifdef EIGEN_VECTORIZE
|
||||
if (ei_packet_traits<T>::size>1)
|
||||
free(ptr);
|
||||
else
|
||||
#endif
|
||||
delete[] ptr;
|
||||
if (ei_packet_traits<T>::size>1 || ei_force_aligned_malloc<T>::ret)
|
||||
{
|
||||
// need to call manually the dtor in case T is some user-defined fancy numeric type.
|
||||
// always destruct an array starting from the end.
|
||||
while(size) ptr[--size].~T();
|
||||
#if defined(__linux)
|
||||
free(ptr);
|
||||
#elif defined(_MSC_VER)
|
||||
_aligned_free(ptr);
|
||||
#else
|
||||
_mm_free(ptr);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
delete[] ptr;
|
||||
}
|
||||
|
||||
/** \internal \returns the number of elements which have to be skipped such that data are 16 bytes aligned */
|
||||
@@ -89,27 +114,30 @@ 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;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* ei_alloc_stack(TYPE,SIZE) allocates sizeof(TYPE)*SIZE bytes on the stack if sizeof(TYPE)*SIZE is
|
||||
* smaller than EIGEN_STACK_ALLOCATION_LIMIT. Otherwise the memory is allocated using the operator new.
|
||||
* Data allocated with ei_alloc_stack \b must be freed by calling ei_free_stack(PTR,TYPE,SIZE).
|
||||
* ei_aligned_stack_alloc(TYPE,SIZE) allocates an aligned buffer of sizeof(TYPE)*SIZE bytes
|
||||
* on the stack if sizeof(TYPE)*SIZE is smaller than EIGEN_STACK_ALLOCATION_LIMIT.
|
||||
* Otherwise the memory is allocated on the heap.
|
||||
* Data allocated with ei_aligned_stack_alloc \b must be freed by calling ei_aligned_stack_free(PTR,TYPE,SIZE).
|
||||
* \code
|
||||
* float * data = ei_alloc_stack(float,array.size());
|
||||
* float * data = ei_aligned_stack_alloc(float,array.size());
|
||||
* // ...
|
||||
* ei_free_stack(data,float,array.size());
|
||||
* ei_aligned_stack_free(data,float,array.size());
|
||||
* \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_aligned_stack_alloc(TYPE,SIZE) ((sizeof(TYPE)*(SIZE)>EIGEN_STACK_ALLOCATION_LIMIT) \
|
||||
? ei_aligned_malloc<TYPE>(SIZE) \
|
||||
: (TYPE*)alloca(sizeof(TYPE)*(SIZE)))
|
||||
#define ei_aligned_stack_free(PTR,TYPE,SIZE) if (sizeof(TYPE)*SIZE>EIGEN_STACK_ALLOCATION_LIMIT) ei_aligned_free(PTR,SIZE)
|
||||
#else
|
||||
# define ei_alloc_stack(TYPE,SIZE) new TYPE[SIZE]
|
||||
# define ei_free_stack(PTR,TYPE,SIZE) delete[] PTR
|
||||
#define ei_aligned_stack_alloc(TYPE,SIZE) ei_aligned_malloc<TYPE>(SIZE)
|
||||
#define ei_aligned_stack_free(PTR,TYPE,SIZE) ei_aligned_free(PTR,SIZE)
|
||||
#endif
|
||||
|
||||
/** \class WithAlignedOperatorNew
|
||||
@@ -153,30 +181,18 @@ inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset)
|
||||
*/
|
||||
struct WithAlignedOperatorNew
|
||||
{
|
||||
#ifdef EIGEN_VECTORIZE
|
||||
|
||||
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); }
|
||||
|
||||
#endif
|
||||
void operator delete(void * ptr) { ei_aligned_free(static_cast<ei_byte_forcing_aligned_malloc *>(ptr), 0); }
|
||||
void operator delete[](void * ptr) { ei_aligned_free(static_cast<ei_byte_forcing_aligned_malloc *>(ptr), 0); }
|
||||
};
|
||||
|
||||
template<typename T, int SizeAtCompileTime,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -55,27 +55,40 @@
|
||||
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,
|
||||
THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES
|
||||
};
|
||||
};
|
||||
|
||||
#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 +102,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 +125,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 +139,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
|
||||
|
||||
@@ -85,22 +85,16 @@ template<typename T> struct ei_unpacket_traits
|
||||
enum {size=1};
|
||||
};
|
||||
|
||||
|
||||
template<typename Scalar, int Rows, int Cols, int StorageOrder, int MaxRows, int MaxCols>
|
||||
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
||||
class ei_compute_matrix_flags
|
||||
{
|
||||
enum {
|
||||
row_major_bit = (Rows != 1 && Cols != 1) // if this is not a vector,
|
||||
// then the storage order really matters,
|
||||
// so let us strictly honor the user's choice.
|
||||
? StorageOrder
|
||||
: Cols > 1 ? RowMajorBit : 0,
|
||||
row_major_bit = Options&Matrix_RowMajor ? RowMajorBit : 0,
|
||||
inner_max_size = row_major_bit ? MaxCols : MaxRows,
|
||||
is_big = inner_max_size == Dynamic,
|
||||
is_packet_size_multiple = (Cols * Rows)%ei_packet_traits<Scalar>::size==0,
|
||||
packet_access_bit = ei_packet_traits<Scalar>::size > 1
|
||||
&& (is_big || is_packet_size_multiple) ? PacketAccessBit : 0,
|
||||
aligned_bit = packet_access_bit && (is_big || is_packet_size_multiple) ? AlignedBit : 0
|
||||
is_packet_size_multiple = (Cols*Rows) % ei_packet_traits<Scalar>::size == 0,
|
||||
aligned_bit = ((Options&Matrix_AutoAlign) && (is_big || is_packet_size_multiple)) ? AlignedBit : 0,
|
||||
packet_access_bit = ei_packet_traits<Scalar>::size > 1 && aligned_bit ? PacketAccessBit : 0
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -112,6 +106,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>
|
||||
@@ -119,19 +117,41 @@ template<typename T> struct ei_eval<T,IsDense>
|
||||
typedef Matrix<typename ei_traits<T>::Scalar,
|
||||
ei_traits<T>::RowsAtCompileTime,
|
||||
ei_traits<T>::ColsAtCompileTime,
|
||||
ei_traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor,
|
||||
Matrix_AutoAlign | (ei_traits<T>::Flags&RowMajorBit ? Matrix_RowMajor : Matrix_ColMajor),
|
||||
ei_traits<T>::MaxRowsAtCompileTime,
|
||||
ei_traits<T>::MaxColsAtCompileTime
|
||||
> 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,
|
||||
ColMajor,
|
||||
Matrix_AutoAlign | (ei_traits<T>::Flags&RowMajorBit ? Matrix_RowMajor : Matrix_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,
|
||||
ei_traits<T>::ColsAtCompileTime,
|
||||
Matrix_AutoAlign | Matrix_ColMajor,
|
||||
ei_traits<T>::MaxRowsAtCompileTime,
|
||||
ei_traits<T>::MaxColsAtCompileTime
|
||||
> type;
|
||||
@@ -158,7 +178,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 +190,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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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::Options,
|
||||
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::Options,
|
||||
MatrixType::MaxRowsAtCompileTime, // the image matrix will consist of columns from the original matrix,
|
||||
MatrixType::MaxColsAtCompileTime // so it has the same number of rows and at most as many columns.
|
||||
> 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>
|
||||
Matrix<Scalar, Dynamic, Dynamic, MatrixType::Options,
|
||||
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,43 +497,43 @@ 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,
|
||||
MatrixType::Flags&RowMajorBit,
|
||||
MatrixType::Options,
|
||||
MatrixType::MaxRowsAtCompileTime,
|
||||
MatrixType::MaxRowsAtCompileTime> l(rows, rows);
|
||||
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;
|
||||
}
|
||||
Matrix<Scalar, Dynamic, OtherDerived::ColsAtCompileTime,
|
||||
MatrixType::Flags&RowMajorBit,
|
||||
MatrixType::Options,
|
||||
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
|
||||
|
||||
@@ -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 !!
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -25,6 +25,35 @@
|
||||
#ifndef EIGEN_CHOLMODSUPPORT_H
|
||||
#define EIGEN_CHOLMODSUPPORT_H
|
||||
|
||||
template<typename Scalar, typename CholmodType>
|
||||
void ei_cholmod_configure_matrix(CholmodType& mat)
|
||||
{
|
||||
if (ei_is_same_type<Scalar,float>::ret)
|
||||
{
|
||||
mat.xtype = CHOLMOD_REAL;
|
||||
mat.dtype = 1;
|
||||
}
|
||||
else if (ei_is_same_type<Scalar,double>::ret)
|
||||
{
|
||||
mat.xtype = CHOLMOD_REAL;
|
||||
mat.dtype = 0;
|
||||
}
|
||||
else if (ei_is_same_type<Scalar,std::complex<float> >::ret)
|
||||
{
|
||||
mat.xtype = CHOLMOD_COMPLEX;
|
||||
mat.dtype = 1;
|
||||
}
|
||||
else if (ei_is_same_type<Scalar,std::complex<double> >::ret)
|
||||
{
|
||||
mat.xtype = CHOLMOD_COMPLEX;
|
||||
mat.dtype = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ei_assert(false && "Scalar type not supported by CHOLMOD");
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Scalar, int Flags>
|
||||
cholmod_sparse SparseMatrix<Scalar,Flags>::asCholmodMatrix()
|
||||
{
|
||||
@@ -42,36 +71,13 @@ cholmod_sparse SparseMatrix<Scalar,Flags>::asCholmodMatrix()
|
||||
res.dtype = 0;
|
||||
res.stype = -1;
|
||||
|
||||
if (ei_is_same_type<Scalar,float>::ret)
|
||||
{
|
||||
res.xtype = CHOLMOD_REAL;
|
||||
res.dtype = 1;
|
||||
}
|
||||
else if (ei_is_same_type<Scalar,double>::ret)
|
||||
{
|
||||
res.xtype = CHOLMOD_REAL;
|
||||
res.dtype = 0;
|
||||
}
|
||||
else if (ei_is_same_type<Scalar,std::complex<float> >::ret)
|
||||
{
|
||||
res.xtype = CHOLMOD_COMPLEX;
|
||||
res.dtype = 1;
|
||||
}
|
||||
else if (ei_is_same_type<Scalar,std::complex<double> >::ret)
|
||||
{
|
||||
res.xtype = CHOLMOD_COMPLEX;
|
||||
res.dtype = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ei_assert(false && "Scalar type not supported by CHOLMOD");
|
||||
}
|
||||
ei_cholmod_configure_matrix<Scalar>(res);
|
||||
|
||||
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;
|
||||
@@ -82,6 +88,25 @@ cholmod_sparse SparseMatrix<Scalar,Flags>::asCholmodMatrix()
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
cholmod_dense ei_cholmod_map_eigen_to_dense(MatrixBase<Derived>& mat)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((ei_traits<Derived>::Flags&RowMajorBit)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
|
||||
cholmod_dense res;
|
||||
res.nrow = mat.rows();
|
||||
res.ncol = mat.cols();
|
||||
res.nzmax = res.nrow * res.ncol;
|
||||
res.d = mat.derived().stride();
|
||||
res.x = mat.derived().data();
|
||||
res.z = 0;
|
||||
|
||||
ei_cholmod_configure_matrix<Scalar>(res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename Scalar, int Flags>
|
||||
SparseMatrix<Scalar,Flags> SparseMatrix<Scalar,Flags>::Map(cholmod_sparse& cm)
|
||||
{
|
||||
@@ -103,7 +128,7 @@ class SparseLLT<MatrixType,Cholmod> : public SparseLLT<MatrixType>
|
||||
{
|
||||
protected:
|
||||
typedef SparseLLT<MatrixType> Base;
|
||||
using Base::Scalar;
|
||||
using typename Base::Scalar;
|
||||
using Base::RealScalar;
|
||||
using Base::MatrixLIsDirty;
|
||||
using Base::SupernodalFactorIsDirty;
|
||||
@@ -155,11 +180,12 @@ void SparseLLT<MatrixType,Cholmod>::compute(const MatrixType& a)
|
||||
}
|
||||
|
||||
cholmod_sparse A = const_cast<MatrixType&>(a).asCholmodMatrix();
|
||||
m_cholmod.supernodal = CHOLMOD_AUTO;
|
||||
// TODO
|
||||
if (m_flags&IncompleteFactorization)
|
||||
{
|
||||
m_cholmod.nmethods = 1;
|
||||
m_cholmod.method [0].ordering = CHOLMOD_NATURAL;
|
||||
m_cholmod.method[0].ordering = CHOLMOD_NATURAL;
|
||||
m_cholmod.postorder = 0;
|
||||
}
|
||||
else
|
||||
@@ -196,13 +222,19 @@ template<typename MatrixType>
|
||||
template<typename Derived>
|
||||
void SparseLLT<MatrixType,Cholmod>::solveInPlace(MatrixBase<Derived> &b) const
|
||||
{
|
||||
if (m_status & MatrixLIsDirty)
|
||||
matrixL();
|
||||
|
||||
const int size = m_matrix.rows();
|
||||
const int size = m_cholmodFactor->n;
|
||||
ei_assert(size==b.rows());
|
||||
|
||||
Base::solveInPlace(b);
|
||||
// this uses Eigen's triangular sparse solver
|
||||
// if (m_status & MatrixLIsDirty)
|
||||
// matrixL();
|
||||
// Base::solveInPlace(b);
|
||||
// as long as our own triangular sparse solver is not fully optimal,
|
||||
// let's use CHOLMOD's one:
|
||||
cholmod_dense cdb = ei_cholmod_map_eigen_to_dense(b);
|
||||
cholmod_dense* x = cholmod_solve(CHOLMOD_LDLt, m_cholmodFactor, &cdb, &m_cholmod);
|
||||
b = Matrix<typename Base::Scalar,Dynamic,1>::Map(reinterpret_cast<typename Base::Scalar*>(x->x),b.rows());
|
||||
cholmod_free_dense(&x, &m_cholmod);
|
||||
}
|
||||
|
||||
#endif // EIGEN_CHOLMODSUPPORT_H
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
@@ -192,7 +192,7 @@ void SparseLDLT<MatrixType,Backend>::_symbolic(const MatrixType& a)
|
||||
m_matrix.resize(size, size);
|
||||
m_parent.resize(size);
|
||||
m_nonZerosPerCol.resize(size);
|
||||
int * tags = ei_alloc_stack(int, size);
|
||||
int * tags = ei_aligned_stack_alloc(int, size);
|
||||
|
||||
const int* Ap = a._outerIndexPtr();
|
||||
const int* Ai = a._innerIndexPtr();
|
||||
@@ -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,11 +234,11 @@ 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]);
|
||||
ei_free_stack(tags, int, size);
|
||||
ei_aligned_stack_free(tags, int, size);
|
||||
}
|
||||
|
||||
template<typename MatrixType, int Backend>
|
||||
@@ -257,15 +257,15 @@ bool SparseLDLT<MatrixType,Backend>::_numeric(const MatrixType& a)
|
||||
Scalar* Lx = m_matrix._valuePtr();
|
||||
m_diag.resize(size);
|
||||
|
||||
Scalar * y = ei_alloc_stack(Scalar, size);
|
||||
int * pattern = ei_alloc_stack(int, size);
|
||||
int * tags = ei_alloc_stack(int, size);
|
||||
Scalar * y = ei_aligned_stack_alloc(Scalar, size);
|
||||
int * pattern = ei_aligned_stack_alloc(int, size);
|
||||
int * tags = ei_aligned_stack_alloc(int, size);
|
||||
|
||||
const int* P = 0;
|
||||
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)
|
||||
{
|
||||
@@ -315,9 +315,9 @@ bool SparseLDLT<MatrixType,Backend>::_numeric(const MatrixType& a)
|
||||
}
|
||||
}
|
||||
|
||||
ei_free_stack(y, Scalar, size);
|
||||
ei_free_stack(pattern, int, size);
|
||||
ei_free_stack(tags, int, size);
|
||||
ei_aligned_stack_free(y, Scalar, size);
|
||||
ei_aligned_stack_free(pattern, int, size);
|
||||
ei_aligned_stack_free(tags, int, size);
|
||||
|
||||
return ok; /* success, diagonal of D is all nonzero */
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
@@ -190,8 +190,14 @@ bool SparseLLT<MatrixType, Backend>::solveInPlace(MatrixBase<Derived> &b) const
|
||||
ei_assert(size==b.rows());
|
||||
|
||||
m_matrix.solveTriangularInPlace(b);
|
||||
// FIXME should be .adjoint() but it fails to compile...
|
||||
m_matrix.transpose().solveTriangularInPlace(b);
|
||||
// FIXME should be simply .adjoint() but it fails to compile...
|
||||
if (NumTraits<Scalar>::IsComplex)
|
||||
{
|
||||
CholMatrixType aux = m_matrix.conjugate();
|
||||
aux.transpose().solveTriangularInPlace(b);
|
||||
}
|
||||
else
|
||||
m_matrix.transpose().solveTriangularInPlace(b);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -211,6 +273,12 @@ class SparseMatrix
|
||||
*this = other.derived();
|
||||
}
|
||||
|
||||
inline SparseMatrix(const SparseMatrix& other)
|
||||
: m_outerSize(0), m_innerSize(0), m_outerIndex(0)
|
||||
{
|
||||
*this = other.derived();
|
||||
}
|
||||
|
||||
inline void swap(SparseMatrix& other)
|
||||
{
|
||||
//EIGEN_DBG_SPARSE(std::cout << "SparseMatrix:: swap\n");
|
||||
@@ -256,7 +324,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 +361,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] << " ";
|
||||
}
|
||||
@@ -347,13 +415,13 @@ class SparseMatrix<Scalar,_Flags>::InnerIterator
|
||||
m_start(m_id), m_end(m_matrix.m_outerIndex[outer+1])
|
||||
{}
|
||||
|
||||
InnerIterator& operator++() { m_id++; return *this; }
|
||||
inline InnerIterator& operator++() { m_id++; return *this; }
|
||||
|
||||
Scalar value() const { return m_matrix.m_data.value(m_id); }
|
||||
inline Scalar value() const { return m_matrix.m_data.value(m_id); }
|
||||
|
||||
int index() const { return m_matrix.m_data.index(m_id); }
|
||||
inline int index() const { return m_matrix.m_data.index(m_id); }
|
||||
|
||||
operator bool() const { return (m_id < m_end) && (m_id>=m_start); }
|
||||
inline operator bool() const { return (m_id < m_end) && (m_id>=m_start); }
|
||||
|
||||
protected:
|
||||
const SparseMatrix& m_matrix;
|
||||
|
||||
@@ -32,6 +32,7 @@ class SparseMatrixBase : public MatrixBase<Derived>
|
||||
|
||||
typedef MatrixBase<Derived> Base;
|
||||
typedef typename Base::Scalar Scalar;
|
||||
typedef typename Base::RealScalar RealScalar;
|
||||
enum {
|
||||
Flags = Base::Flags,
|
||||
RowMajor = ei_traits<Derived>::Flags&RowMajorBit ? 1 : 0
|
||||
@@ -63,8 +64,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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -62,8 +62,7 @@ enum {
|
||||
|
||||
template<typename Derived> class SparseMatrixBase;
|
||||
template<typename _Scalar, int _Flags = 0> class SparseMatrix;
|
||||
template<typename _Scalar, int _Flags = 0> class HashMatrix;
|
||||
template<typename _Scalar, int _Flags = 0> class LinkedVectorMatrix;
|
||||
template<typename _Scalar, int _Flags = 0> class SparseVector;
|
||||
|
||||
const int AccessPatternNotSupported = 0x0;
|
||||
const int AccessPatternSupported = 0x1;
|
||||
|
||||
308
Eigen/src/Sparse/SparseVector.h
Normal file
308
Eigen/src/Sparse/SparseVector.h
Normal file
@@ -0,0 +1,308 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra. Eigen itself is part of the KDE project.
|
||||
//
|
||||
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
||||
//
|
||||
// Eigen is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// Alternatively, you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License and a copy of the GNU General Public License along with
|
||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef EIGEN_SPARSEVECTOR_H
|
||||
#define EIGEN_SPARSEVECTOR_H
|
||||
|
||||
/** \class SparseVector
|
||||
*
|
||||
* \brief a sparse vector class
|
||||
*
|
||||
* \param _Scalar the scalar type, i.e. the type of the coefficients
|
||||
*
|
||||
* See http://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme.
|
||||
*
|
||||
*/
|
||||
template<typename _Scalar, int _Flags>
|
||||
struct ei_traits<SparseVector<_Scalar, _Flags> >
|
||||
{
|
||||
typedef _Scalar Scalar;
|
||||
enum {
|
||||
IsColVector = _Flags & RowMajorBit ? 0 : 1,
|
||||
|
||||
RowsAtCompileTime = IsColVector ? Dynamic : 1,
|
||||
ColsAtCompileTime = IsColVector ? 1 : Dynamic,
|
||||
MaxRowsAtCompileTime = RowsAtCompileTime,
|
||||
MaxColsAtCompileTime = ColsAtCompileTime,
|
||||
Flags = SparseBit | _Flags,
|
||||
CoeffReadCost = NumTraits<Scalar>::ReadCost,
|
||||
SupportedAccessPatterns = FullyCoherentAccessPattern
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename _Scalar, int _Flags>
|
||||
class SparseVector
|
||||
: public SparseMatrixBase<SparseVector<_Scalar, _Flags> >
|
||||
{
|
||||
public:
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(SparseVector)
|
||||
|
||||
protected:
|
||||
public:
|
||||
|
||||
typedef SparseMatrixBase<SparseVector> SparseBase;
|
||||
enum {
|
||||
IsColVector = ei_traits<SparseVector>::IsColVector
|
||||
};
|
||||
|
||||
SparseArray<Scalar> m_data;
|
||||
int m_size;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
inline int rows() const { return IsColVector ? m_size : 1; }
|
||||
inline int cols() const { return IsColVector ? 1 : m_size; }
|
||||
inline int innerSize() const { return m_size; }
|
||||
inline int outerSize() const { return 1; }
|
||||
inline int innerNonZeros(int j) const { ei_assert(j==0); return m_size; }
|
||||
|
||||
inline const Scalar* _valuePtr() const { return &m_data.value(0); }
|
||||
inline Scalar* _valuePtr() { return &m_data.value(0); }
|
||||
|
||||
inline const int* _innerIndexPtr() const { return &m_data.index(0); }
|
||||
inline int* _innerIndexPtr() { return &m_data.index(0); }
|
||||
|
||||
inline Scalar coeff(int row, int col) const
|
||||
{
|
||||
ei_assert((IsColVector ? col : row)==0);
|
||||
return coeff(IsColVector ? row : col);
|
||||
}
|
||||
inline Scalar coeff(int i) const
|
||||
{
|
||||
int start = 0;
|
||||
int end = m_data.size();
|
||||
if (start==end)
|
||||
return Scalar(0);
|
||||
else if (end>0 && i==m_data.index(end-1))
|
||||
return m_data.value(end-1);
|
||||
// ^^ optimization: let's first check if it is the last coefficient
|
||||
// (very common in high level algorithms)
|
||||
|
||||
// TODO move this search to ScalarArray
|
||||
const int* r = std::lower_bound(&m_data.index(start),&m_data.index(end-1),i);
|
||||
const int id = r-&m_data.index(0);
|
||||
return ((*r==i) && (id<end)) ? m_data.value(id) : Scalar(0);
|
||||
}
|
||||
|
||||
inline Scalar& coeffRef(int row, int col)
|
||||
{
|
||||
ei_assert((IsColVector ? col : row)==0);
|
||||
return coeff(IsColVector ? row : col);
|
||||
}
|
||||
|
||||
inline Scalar& coeffRef(int i)
|
||||
{
|
||||
int start = 0;
|
||||
int end = m_data.size();
|
||||
ei_assert(end>=start && "you probably called coeffRef on a non finalized vector");
|
||||
ei_assert(end>start && "coeffRef cannot be called on a zero coefficient");
|
||||
int* r = std::lower_bound(&m_data.index(start),&m_data.index(end),i);
|
||||
const int id = r-&m_data.index(0);
|
||||
ei_assert((*r==i) && (id<end) && "coeffRef cannot be called on a zero coefficient");
|
||||
return m_data.value(id);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
class InnerIterator;
|
||||
|
||||
inline void setZero() { m_data.clear(); }
|
||||
|
||||
/** \returns the number of non zero coefficients */
|
||||
inline int nonZeros() const { return m_data.size(); }
|
||||
|
||||
/**
|
||||
*/
|
||||
inline void reserve(int reserveSize) { m_data.reserve(reserveSize); }
|
||||
|
||||
/**
|
||||
*/
|
||||
inline Scalar& fill(int i)
|
||||
{
|
||||
m_data.append(0, i);
|
||||
return m_data.value(m_data.size()-1);
|
||||
}
|
||||
|
||||
/** Like fill() but with random coordinates.
|
||||
*/
|
||||
inline Scalar& fillrand(int i)
|
||||
{
|
||||
int startId = 0;
|
||||
int id = m_data.size() - 1;
|
||||
m_data.resize(id+2);
|
||||
|
||||
while ( (id >= startId) && (m_data.index(id) > i) )
|
||||
{
|
||||
m_data.index(id+1) = m_data.index(id);
|
||||
m_data.value(id+1) = m_data.value(id);
|
||||
--id;
|
||||
}
|
||||
m_data.index(id+1) = i;
|
||||
m_data.value(id+1) = 0;
|
||||
return m_data.value(id+1);
|
||||
}
|
||||
|
||||
void resize(int newSize)
|
||||
{
|
||||
m_size = newSize;
|
||||
m_data.clear();
|
||||
}
|
||||
|
||||
void resizeNonZeros(int size) { m_data.resize(size); }
|
||||
|
||||
inline SparseVector() : m_size(0) { resize(0, 0); }
|
||||
|
||||
inline SparseVector(int size) : m_size(0) { resize(size); }
|
||||
|
||||
template<typename OtherDerived>
|
||||
inline SparseVector(const MatrixBase<OtherDerived>& other)
|
||||
: m_size(0)
|
||||
{
|
||||
*this = other.derived();
|
||||
}
|
||||
|
||||
inline SparseVector(const SparseVector& other)
|
||||
: m_size(0)
|
||||
{
|
||||
*this = other.derived();
|
||||
}
|
||||
|
||||
inline void swap(SparseVector& other)
|
||||
{
|
||||
std::swap(m_size, other.m_size);
|
||||
m_data.swap(other.m_data);
|
||||
}
|
||||
|
||||
inline SparseVector& operator=(const SparseVector& other)
|
||||
{
|
||||
if (other.isRValue())
|
||||
{
|
||||
swap(other.const_cast_derived());
|
||||
}
|
||||
else
|
||||
{
|
||||
resize(other.size());
|
||||
m_data = other.m_data;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// template<typename OtherDerived>
|
||||
// inline SparseVector& operator=(const MatrixBase<OtherDerived>& other)
|
||||
// {
|
||||
// const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
|
||||
// if (needToTranspose)
|
||||
// {
|
||||
// // two passes algorithm:
|
||||
// // 1 - compute the number of coeffs per dest inner vector
|
||||
// // 2 - do the actual copy/eval
|
||||
// // Since each coeff of the rhs has to be evaluated twice, let's evauluate it if needed
|
||||
// typedef typename ei_nested<OtherDerived,2>::type OtherCopy;
|
||||
// OtherCopy otherCopy(other.derived());
|
||||
// typedef typename ei_cleantype<OtherCopy>::type _OtherCopy;
|
||||
//
|
||||
// resize(other.rows(), other.cols());
|
||||
// Eigen::Map<VectorXi>(m_outerIndex,outerSize()).setZero();
|
||||
// // pass 1
|
||||
// // 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()];
|
||||
//
|
||||
// // prefix sum
|
||||
// int count = 0;
|
||||
// VectorXi positions(outerSize());
|
||||
// for (int j=0; j<outerSize(); ++j)
|
||||
// {
|
||||
// int tmp = m_outerIndex[j];
|
||||
// m_outerIndex[j] = count;
|
||||
// positions[j] = count;
|
||||
// count += tmp;
|
||||
// }
|
||||
// m_outerIndex[outerSize()] = count;
|
||||
// // alloc
|
||||
// m_data.resize(count);
|
||||
// // pass 2
|
||||
// for (int j=0; j<otherCopy.outerSize(); ++j)
|
||||
// for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
|
||||
// {
|
||||
// int pos = positions[it.index()]++;
|
||||
// m_data.index(pos) = j;
|
||||
// m_data.value(pos) = it.value();
|
||||
// }
|
||||
//
|
||||
// return *this;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // there is no special optimization
|
||||
// return SparseMatrixBase<SparseMatrix>::operator=(other.derived());
|
||||
// }
|
||||
// }
|
||||
|
||||
friend std::ostream & operator << (std::ostream & s, const SparseVector& m)
|
||||
{
|
||||
for (unsigned int i=0; i<m.nonZeros(); ++i)
|
||||
s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") ";
|
||||
s << std::endl;
|
||||
return s;
|
||||
}
|
||||
|
||||
/** Destructor */
|
||||
inline ~SparseVector() {}
|
||||
};
|
||||
|
||||
template<typename Scalar, int _Flags>
|
||||
class SparseVector<Scalar,_Flags>::InnerIterator
|
||||
{
|
||||
public:
|
||||
InnerIterator(const SparseVector& vec, int outer=0)
|
||||
: m_vector(vec), m_id(0), m_end(vec.nonZeros())
|
||||
{
|
||||
ei_assert(outer==0);
|
||||
}
|
||||
|
||||
template<unsigned int Added, unsigned int Removed>
|
||||
InnerIterator(const Flagged<SparseVector,Added,Removed>& vec, int outer)
|
||||
: m_vector(vec._expression()), m_id(0), m_end(m_vector.nonZeros())
|
||||
{}
|
||||
|
||||
inline InnerIterator& operator++() { m_id++; return *this; }
|
||||
|
||||
inline Scalar value() const { return m_vector.m_data.value(m_id); }
|
||||
|
||||
inline int index() const { return m_vector.m_data.index(m_id); }
|
||||
|
||||
inline operator bool() const { return (m_id < m_end); }
|
||||
|
||||
protected:
|
||||
const SparseVector& m_vector;
|
||||
int m_id;
|
||||
const int m_end;
|
||||
};
|
||||
|
||||
#endif // EIGEN_SPARSEVECTOR_H
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
PROJECT(BTL)
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.2)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
include(MacroOptionalAddSubdirectory)
|
||||
@@ -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")
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 ){
|
||||
|
||||
@@ -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 ){
|
||||
|
||||
@@ -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 ){
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
# - Try to find eigen2 headers
|
||||
# - Try to find Eigen2 lib
|
||||
# Once done this will define
|
||||
#
|
||||
# EIGEN2_FOUND - system has eigen2 lib
|
||||
# EIGEN2_INCLUDE_DIR - the eigen2 include directory
|
||||
#
|
||||
# Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
||||
# Adapted from FindEigen.cmake:
|
||||
# EIGEN2_FOUND - system has eigen lib
|
||||
# EIGEN2_INCLUDE_DIR - the eigen include directory
|
||||
|
||||
# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
@@ -19,12 +17,14 @@ else (EIGEN2_INCLUDE_DIR)
|
||||
|
||||
find_path(EIGEN2_INCLUDE_DIR NAMES Eigen/Core
|
||||
PATHS
|
||||
${Eigen_SOURCE_DIR}/
|
||||
${INCLUDE_INSTALL_DIR}
|
||||
${KDE4_INCLUDE_DIR}
|
||||
PATH_SUFFIXES eigen2
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Eigen2 DEFAULT_MSG EIGEN2_INCLUDE_DIR)
|
||||
find_package_handle_standard_args(Eigen2 DEFAULT_MSG EIGEN2_INCLUDE_DIR )
|
||||
|
||||
|
||||
mark_as_advanced(EIGEN2_INCLUDE_DIR)
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
@@ -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( \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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){
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user