mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Compare commits
135 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc2f92ba4a | ||
|
|
2eb8b99a32 | ||
|
|
83c726b343 | ||
|
|
473e70e8be | ||
|
|
80e72a2653 | ||
|
|
201a317912 | ||
|
|
2a3680da3d | ||
|
|
4f7baefa81 | ||
|
|
38b9ff8b6f | ||
|
|
87112908be | ||
|
|
d5c2a01031 | ||
|
|
4c8f0cbc1f | ||
|
|
538bc98b33 | ||
|
|
29f5f098cc | ||
|
|
c21f2cde34 | ||
|
|
909747d6b2 | ||
|
|
1cff196837 | ||
|
|
4ecd782c31 | ||
|
|
84a65f996f | ||
|
|
17c40e5524 | ||
|
|
51f763eaba | ||
|
|
f5e01a2cde | ||
|
|
8d16e2aa27 | ||
|
|
547a3c0d28 | ||
|
|
a432b017fb | ||
|
|
b4669f9036 | ||
|
|
4854326ae8 | ||
|
|
ea12669f7a | ||
|
|
b4388ee38b | ||
|
|
04d9fe13c6 | ||
|
|
4bf0765d71 | ||
|
|
0e35730e0b | ||
|
|
2f9b1bf398 | ||
|
|
18a13c65fe | ||
|
|
bd6e042f49 | ||
|
|
b71ee76d8d | ||
|
|
8d4d85161e | ||
|
|
e4ed2566d5 | ||
|
|
8fb4069b2a | ||
|
|
ed48e38578 | ||
|
|
83f2c809ed | ||
|
|
c090c6544b | ||
|
|
bb0fad0c70 | ||
|
|
a87cd61c13 | ||
|
|
3b29688ca2 | ||
|
|
f32ad79b41 | ||
|
|
d039c88096 | ||
|
|
cc26185d91 | ||
|
|
e6fd3fa177 | ||
|
|
249d2f360b | ||
|
|
34da70e0ce | ||
|
|
55565a0da4 | ||
|
|
4daa1292d7 | ||
|
|
c47fb1f35f | ||
|
|
2ee4b8e945 | ||
|
|
81912b3c41 | ||
|
|
efc7c2121a | ||
|
|
f22036f5f8 | ||
|
|
14fcbfb009 | ||
|
|
0b18ffe175 | ||
|
|
0f20aa3073 | ||
|
|
2de7f0f97a | ||
|
|
2c329453b1 | ||
|
|
2beec14503 | ||
|
|
5f35869461 | ||
|
|
c134d75351 | ||
|
|
092681132c | ||
|
|
0d807dce07 | ||
|
|
e8559eaed6 | ||
|
|
ffadb5b9b0 | ||
|
|
fa30d77188 | ||
|
|
7dc0c4e8f6 | ||
|
|
b3b9d7a14c | ||
|
|
32f0c782c3 | ||
|
|
7031f4e783 | ||
|
|
deea165867 | ||
|
|
406a7889b3 | ||
|
|
2f41f887d0 | ||
|
|
b9827c495e | ||
|
|
6056f4404c | ||
|
|
efd484546e | ||
|
|
a92681e0d2 | ||
|
|
47592d31ea | ||
|
|
1a9dda6bfd | ||
|
|
4c1a2b5614 | ||
|
|
c308cb1b24 | ||
|
|
85e9e6e780 | ||
|
|
c030925a66 | ||
|
|
fd074be1a0 | ||
|
|
e685bd7f46 | ||
|
|
e82f507747 | ||
|
|
1eea595550 | ||
|
|
d0980c7706 | ||
|
|
9055400f3d | ||
|
|
acb3c60295 | ||
|
|
f8b88d21a6 | ||
|
|
89a222ce50 | ||
|
|
960ec7aef2 | ||
|
|
e8bd2d49b3 | ||
|
|
f444996a7a | ||
|
|
a7c2e62a52 | ||
|
|
9ff967199a | ||
|
|
dc0ef2cbed | ||
|
|
7aa90a3b0f | ||
|
|
56488ddc0f | ||
|
|
165b69ca74 | ||
|
|
7abf6d02db | ||
|
|
73cb54835c | ||
|
|
cfe315476f | ||
|
|
f1583e86f6 | ||
|
|
4bd69750ed | ||
|
|
d40e32c94e | ||
|
|
a0bf1b4242 | ||
|
|
cf645db95b | ||
|
|
13135a82bd | ||
|
|
769cb99845 | ||
|
|
ba9add3c59 | ||
|
|
ddfb72a92f | ||
|
|
8c7e281c9e | ||
|
|
66c092e44e | ||
|
|
3ec6d38f35 | ||
|
|
96f64441f7 | ||
|
|
5af4d77511 | ||
|
|
88ac8ffad5 | ||
|
|
edb0183e0c | ||
|
|
befa141699 | ||
|
|
5c70b43abd | ||
|
|
6a3797f46f | ||
|
|
c4432aad15 | ||
|
|
ea0168c5a5 | ||
|
|
05fad4959a | ||
|
|
98eedb0c9a | ||
|
|
71424c4bf8 | ||
|
|
e59b246b08 | ||
|
|
4aa7038074 |
@@ -1,6 +1,5 @@
|
||||
project(Eigen)
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.2)
|
||||
cmake_minimum_required(VERSION 2.8.5)
|
||||
|
||||
# guard against in-source builds
|
||||
|
||||
@@ -55,6 +54,7 @@ endif(EIGEN_HG_CHANGESET)
|
||||
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
|
||||
@@ -288,25 +288,26 @@ option(EIGEN_TEST_C++0x "Enables all C++0x features." OFF)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# the user modifiable install path for header files
|
||||
set(EIGEN_INCLUDE_INSTALL_DIR ${EIGEN_INCLUDE_INSTALL_DIR} CACHE PATH "The directory where we install the header files (optional)")
|
||||
|
||||
# set the internal install path for header files which depends on wether the user modifiable
|
||||
# EIGEN_INCLUDE_INSTALL_DIR has been set by the user or not.
|
||||
if(EIGEN_INCLUDE_INSTALL_DIR)
|
||||
set(INCLUDE_INSTALL_DIR
|
||||
${EIGEN_INCLUDE_INSTALL_DIR}
|
||||
CACHE INTERNAL
|
||||
"The directory where we install the header files (internal)"
|
||||
)
|
||||
# Backward compatibility support for EIGEN_INCLUDE_INSTALL_DIR
|
||||
if(EIGEN_INCLUDE_INSTALL_DIR AND NOT INCLUDE_INSTALL_DIR)
|
||||
set(INCLUDE_INSTALL_DIR ${EIGEN_INCLUDE_INSTALL_DIR}
|
||||
CACHE PATH "The directory relative to CMAKE_PREFIX_PATH where Eigen header files are installed")
|
||||
else()
|
||||
set(INCLUDE_INSTALL_DIR
|
||||
"${CMAKE_INSTALL_PREFIX}/include/eigen3"
|
||||
CACHE INTERNAL
|
||||
"The directory where we install the header files (internal)"
|
||||
)
|
||||
"${CMAKE_INSTALL_INCLUDEDIR}/eigen3"
|
||||
CACHE PATH "The directory relative to CMAKE_PREFIX_PATH where Eigen header files are installed"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(CMAKEPACKAGE_INSTALL_DIR
|
||||
"${CMAKE_INSTALL_LIBDIR}/cmake/eigen3"
|
||||
CACHE PATH "The directory relative to CMAKE_PREFIX_PATH where Eigen3Config.cmake is installed"
|
||||
)
|
||||
set(PKGCONFIG_INSTALL_DIR
|
||||
"${CMAKE_INSTALL_DATADIR}/pkgconfig"
|
||||
CACHE PATH "The directory relative to CMAKE_PREFIX_PATH where eigen3.pc is installed"
|
||||
)
|
||||
|
||||
# similar to set_target_properties but append the property instead of overwriting it
|
||||
macro(ei_add_target_property target prop value)
|
||||
|
||||
@@ -324,21 +325,9 @@ install(FILES
|
||||
)
|
||||
|
||||
if(EIGEN_BUILD_PKGCONFIG)
|
||||
SET(path_separator ":")
|
||||
STRING(REPLACE ${path_separator} ";" pkg_config_libdir_search "$ENV{PKG_CONFIG_LIBDIR}")
|
||||
message(STATUS "searching for 'pkgconfig' directory in PKG_CONFIG_LIBDIR ( $ENV{PKG_CONFIG_LIBDIR} ), ${CMAKE_INSTALL_PREFIX}/share, and ${CMAKE_INSTALL_PREFIX}/lib")
|
||||
FIND_PATH(pkg_config_libdir pkgconfig ${pkg_config_libdir_search} ${CMAKE_INSTALL_PREFIX}/share ${CMAKE_INSTALL_PREFIX}/lib ${pkg_config_libdir_search})
|
||||
if(pkg_config_libdir)
|
||||
SET(pkg_config_install_dir ${pkg_config_libdir})
|
||||
message(STATUS "found ${pkg_config_libdir}/pkgconfig" )
|
||||
else(pkg_config_libdir)
|
||||
SET(pkg_config_install_dir ${CMAKE_INSTALL_PREFIX}/share)
|
||||
message(STATUS "pkgconfig not found; installing in ${pkg_config_install_dir}" )
|
||||
endif(pkg_config_libdir)
|
||||
|
||||
configure_file(eigen3.pc.in eigen3.pc)
|
||||
configure_file(eigen3.pc.in eigen3.pc @ONLY)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eigen3.pc
|
||||
DESTINATION ${pkg_config_install_dir}/pkgconfig
|
||||
DESTINATION ${PKGCONFIG_INSTALL_DIR}
|
||||
)
|
||||
endif(EIGEN_BUILD_PKGCONFIG)
|
||||
|
||||
@@ -401,12 +390,15 @@ if(cmake_generator_tolower MATCHES "makefile")
|
||||
message(STATUS "--------------+--------------------------------------------------------------")
|
||||
message(STATUS "Command | Description")
|
||||
message(STATUS "--------------+--------------------------------------------------------------")
|
||||
message(STATUS "make install | Install to ${CMAKE_INSTALL_PREFIX}. To change that:")
|
||||
message(STATUS " | cmake . -DCMAKE_INSTALL_PREFIX=yourpath")
|
||||
message(STATUS " | Eigen headers will then be installed to:")
|
||||
message(STATUS " | ${INCLUDE_INSTALL_DIR}")
|
||||
message(STATUS " | To install Eigen headers to a separate location, do:")
|
||||
message(STATUS " | cmake . -DEIGEN_INCLUDE_INSTALL_DIR=yourpath")
|
||||
message(STATUS "make install | Install Eigen. Headers will be installed to:")
|
||||
message(STATUS " | <CMAKE_INSTALL_PREFIX>/<INCLUDE_INSTALL_DIR>")
|
||||
message(STATUS " | Using the following values:")
|
||||
message(STATUS " | CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
|
||||
message(STATUS " | INCLUDE_INSTALL_DIR: ${INCLUDE_INSTALL_DIR}")
|
||||
message(STATUS " | Change the install location of Eigen headers using:")
|
||||
message(STATUS " | cmake . -DCMAKE_INSTALL_PREFIX=yourprefix")
|
||||
message(STATUS " | Or:")
|
||||
message(STATUS " | cmake . -DINCLUDE_INSTALL_DIR=yourdir")
|
||||
message(STATUS "make doc | Generate the API documentation, requires Doxygen & LaTeX")
|
||||
message(STATUS "make check | Build and run the unit-tests. Read this page:")
|
||||
message(STATUS " | http://eigen.tuxfamily.org/index.php?title=Tests")
|
||||
|
||||
@@ -12,7 +12,7 @@ extern "C" {
|
||||
/** \ingroup Support_modules
|
||||
* \defgroup CholmodSupport_Module CholmodSupport module
|
||||
*
|
||||
* This module provides an interface to the Cholmod library which is part of the <a href="http://www.cise.ufl.edu/research/sparse/SuiteSparse/">suitesparse</a> package.
|
||||
* This module provides an interface to the Cholmod library which is part of the <a href="http://www.suitesparse.com">suitesparse</a> package.
|
||||
* It provides the two following main factorization classes:
|
||||
* - class CholmodSupernodalLLT: a supernodal LLT Cholesky factorization.
|
||||
* - class CholmodDecomposiiton: a general L(D)LT Cholesky factorization with automatic or explicit runtime selection of the underlying factorization method (supernodal or simplicial).
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
/** \ingroup Support_modules
|
||||
* \defgroup SPQRSupport_Module SuiteSparseQR module
|
||||
*
|
||||
* This module provides an interface to the SPQR library, which is part of the <a href="http://www.cise.ufl.edu/research/sparse/SuiteSparse/">suitesparse</a> package.
|
||||
* This module provides an interface to the SPQR library, which is part of the <a href="http://www.suitesparse.com">suitesparse</a> package.
|
||||
*
|
||||
* \code
|
||||
* #include <Eigen/SPQRSupport>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
/**
|
||||
* \defgroup SparseCore_Module SparseCore module
|
||||
*
|
||||
* This module provides a sparse matrix representation, and basic associatd matrix manipulations
|
||||
* This module provides a sparse matrix representation, and basic associated matrix manipulations
|
||||
* and operations.
|
||||
*
|
||||
* See the \ref TutorialSparse "Sparse tutorial"
|
||||
|
||||
@@ -12,7 +12,7 @@ extern "C" {
|
||||
/** \ingroup Support_modules
|
||||
* \defgroup UmfPackSupport_Module UmfPackSupport module
|
||||
*
|
||||
* This module provides an interface to the UmfPack library which is part of the <a href="http://www.cise.ufl.edu/research/sparse/SuiteSparse/">suitesparse</a> package.
|
||||
* This module provides an interface to the UmfPack library which is part of the <a href="http://www.suitesparse.com">suitesparse</a> package.
|
||||
* It provides the following factorization class:
|
||||
* - class UmfPackLU: a multifrontal sequential LU factorization.
|
||||
*
|
||||
|
||||
@@ -464,7 +464,7 @@ LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::compute(const MatrixType& a)
|
||||
*/
|
||||
template<typename MatrixType, int _UpLo>
|
||||
template<typename Derived>
|
||||
LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::rankUpdate(const MatrixBase<Derived>& w, const typename NumTraits<typename MatrixType::Scalar>::Real& sigma)
|
||||
LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::rankUpdate(const MatrixBase<Derived>& w, const typename LDLT<MatrixType,_UpLo>::RealScalar& sigma)
|
||||
{
|
||||
const Index size = w.rows();
|
||||
if (m_isInitialized)
|
||||
|
||||
@@ -289,7 +289,7 @@ template<typename Scalar> struct llt_inplace<Scalar, Lower>
|
||||
return k;
|
||||
mat.coeffRef(k,k) = x = sqrt(x);
|
||||
if (k>0 && rs>0) A21.noalias() -= A20 * A10.adjoint();
|
||||
if (rs>0) A21 *= RealScalar(1)/x;
|
||||
if (rs>0) A21 /= x;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ cholmod_sparse viewAsCholmod(SparseMatrix<_Scalar,_Options,_Index>& mat)
|
||||
{
|
||||
res.itype = CHOLMOD_INT;
|
||||
}
|
||||
else if (internal::is_same<_Index,UF_long>::value)
|
||||
else if (internal::is_same<_Index,SuiteSparse_long>::value)
|
||||
{
|
||||
res.itype = CHOLMOD_LONG;
|
||||
}
|
||||
@@ -395,7 +395,7 @@ class CholmodSimplicialLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimpl
|
||||
CholmodSimplicialLLT(const MatrixType& matrix) : Base()
|
||||
{
|
||||
init();
|
||||
compute(matrix);
|
||||
Base::compute(matrix);
|
||||
}
|
||||
|
||||
~CholmodSimplicialLLT() {}
|
||||
@@ -442,7 +442,7 @@ class CholmodSimplicialLDLT : public CholmodBase<_MatrixType, _UpLo, CholmodSimp
|
||||
CholmodSimplicialLDLT(const MatrixType& matrix) : Base()
|
||||
{
|
||||
init();
|
||||
compute(matrix);
|
||||
Base::compute(matrix);
|
||||
}
|
||||
|
||||
~CholmodSimplicialLDLT() {}
|
||||
@@ -487,7 +487,7 @@ class CholmodSupernodalLLT : public CholmodBase<_MatrixType, _UpLo, CholmodSuper
|
||||
CholmodSupernodalLLT(const MatrixType& matrix) : Base()
|
||||
{
|
||||
init();
|
||||
compute(matrix);
|
||||
Base::compute(matrix);
|
||||
}
|
||||
|
||||
~CholmodSupernodalLLT() {}
|
||||
@@ -534,7 +534,7 @@ class CholmodDecomposition : public CholmodBase<_MatrixType, _UpLo, CholmodDecom
|
||||
CholmodDecomposition(const MatrixType& matrix) : Base()
|
||||
{
|
||||
init();
|
||||
compute(matrix);
|
||||
Base::compute(matrix);
|
||||
}
|
||||
|
||||
~CholmodDecomposition() {}
|
||||
|
||||
@@ -124,6 +124,21 @@ class Array
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_HAVE_RVALUE_REFERENCES
|
||||
Array(Array&& other)
|
||||
: Base(std::move(other))
|
||||
{
|
||||
Base::_check_template_params();
|
||||
if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic)
|
||||
Base::_set_noalias(other);
|
||||
}
|
||||
Array& operator=(Array&& other)
|
||||
{
|
||||
other.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Constructs a vector or row-vector with given dimension. \only_for_vectors
|
||||
*
|
||||
* Note that this is only useful for dynamic-size vectors. For fixed-size vectors,
|
||||
|
||||
@@ -46,9 +46,6 @@ template<typename Derived> class ArrayBase
|
||||
|
||||
typedef ArrayBase Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl;
|
||||
|
||||
using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
|
||||
typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator*;
|
||||
|
||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||
typedef typename internal::traits<Derived>::Index Index;
|
||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||
@@ -56,6 +53,7 @@ template<typename Derived> class ArrayBase
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
|
||||
typedef DenseBase<Derived> Base;
|
||||
using Base::operator*;
|
||||
using Base::RowsAtCompileTime;
|
||||
using Base::ColsAtCompileTime;
|
||||
using Base::SizeAtCompileTime;
|
||||
|
||||
@@ -449,7 +449,7 @@ struct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling, Ve
|
||||
srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment
|
||||
};
|
||||
const Scalar *dst_ptr = &dst.coeffRef(0,0);
|
||||
if((!bool(dstIsAligned)) && (Index(dst_ptr) % sizeof(Scalar))>0)
|
||||
if((!bool(dstIsAligned)) && (size_t(dst_ptr) % sizeof(Scalar))>0)
|
||||
{
|
||||
// the pointer is not aligend-on scalar, so alignment is not possible
|
||||
return assign_impl<Derived1,Derived2,DefaultTraversal,NoUnrolling>::run(dst, src);
|
||||
|
||||
@@ -76,8 +76,11 @@ struct CommaInitializer
|
||||
template<typename OtherDerived>
|
||||
CommaInitializer& operator,(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
if(other.cols()==0 || other.rows()==0)
|
||||
if(other.rows()==0)
|
||||
{
|
||||
m_col += other.cols();
|
||||
return *this;
|
||||
}
|
||||
if (m_col==m_xpr.cols())
|
||||
{
|
||||
m_row+=m_currentBlockRows;
|
||||
@@ -86,7 +89,7 @@ struct CommaInitializer
|
||||
eigen_assert(m_row+m_currentBlockRows<=m_xpr.rows()
|
||||
&& "Too many rows passed to comma initializer (operator<<)");
|
||||
}
|
||||
eigen_assert(m_col<m_xpr.cols()
|
||||
eigen_assert((m_col<m_xpr.cols() || (m_xpr.cols()==0 && m_col==0))
|
||||
&& "Too many coefficients passed to comma initializer (operator<<)");
|
||||
eigen_assert(m_currentBlockRows==other.rows());
|
||||
if (OtherDerived::SizeAtCompileTime != Dynamic)
|
||||
|
||||
@@ -81,7 +81,8 @@ struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||
)
|
||||
),
|
||||
Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit),
|
||||
CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + functor_traits<BinaryOp>::Cost
|
||||
Cost0 = EIGEN_ADD_COST(LhsCoeffReadCost,RhsCoeffReadCost),
|
||||
CoeffReadCost = EIGEN_ADD_COST(Cost0,functor_traits<BinaryOp>::Cost)
|
||||
};
|
||||
};
|
||||
} // end namespace internal
|
||||
|
||||
@@ -47,7 +47,7 @@ struct traits<CwiseUnaryOp<UnaryOp, XprType> >
|
||||
Flags = _XprTypeNested::Flags & (
|
||||
HereditaryBits | LinearAccessBit | AlignedBit
|
||||
| (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0)),
|
||||
CoeffReadCost = _XprTypeNested::CoeffReadCost + functor_traits<UnaryOp>::Cost
|
||||
CoeffReadCost = EIGEN_ADD_COST(_XprTypeNested::CoeffReadCost, functor_traits<UnaryOp>::Cost)
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ struct traits<CwiseUnaryView<ViewOp, MatrixType> >
|
||||
typedef typename remove_all<MatrixTypeNested>::type _MatrixTypeNested;
|
||||
enum {
|
||||
Flags = (traits<_MatrixTypeNested>::Flags & (HereditaryBits | LvalueBit | LinearAccessBit | DirectAccessBit)),
|
||||
CoeffReadCost = traits<_MatrixTypeNested>::CoeffReadCost + functor_traits<ViewOp>::Cost,
|
||||
CoeffReadCost = EIGEN_ADD_COST(traits<_MatrixTypeNested>::CoeffReadCost, functor_traits<ViewOp>::Cost),
|
||||
MatrixTypeInnerStride = inner_stride_at_compile_time<MatrixType>::ret,
|
||||
// need to cast the sizeof's from size_t to int explicitly, otherwise:
|
||||
// "error: no integral type can represent all of the enumerator values
|
||||
|
||||
@@ -40,15 +40,14 @@ static inline void check_DenseIndex_is_signed() {
|
||||
*/
|
||||
template<typename Derived> class DenseBase
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
: public internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
|
||||
typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>
|
||||
: public internal::special_scalar_op_base<Derived, typename internal::traits<Derived>::Scalar,
|
||||
typename NumTraits<typename internal::traits<Derived>::Scalar>::Real,
|
||||
DenseCoeffsBase<Derived> >
|
||||
#else
|
||||
: public DenseCoeffsBase<Derived>
|
||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||
{
|
||||
public:
|
||||
using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
|
||||
typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator*;
|
||||
|
||||
class InnerIterator;
|
||||
|
||||
@@ -63,8 +62,9 @@ template<typename Derived> class DenseBase
|
||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
typedef internal::special_scalar_op_base<Derived,Scalar,RealScalar, DenseCoeffsBase<Derived> > Base;
|
||||
|
||||
typedef DenseCoeffsBase<Derived> Base;
|
||||
using Base::operator*;
|
||||
using Base::derived;
|
||||
using Base::const_cast_derived;
|
||||
using Base::rows;
|
||||
@@ -183,10 +183,6 @@ template<typename Derived> class DenseBase
|
||||
/** \returns the number of nonzero coefficients which is in practice the number
|
||||
* of stored coefficients. */
|
||||
inline Index nonZeros() const { return size(); }
|
||||
/** \returns true if either the number of rows or the number of columns is equal to 1.
|
||||
* In other words, this function returns
|
||||
* \code rows()==1 || cols()==1 \endcode
|
||||
* \sa rows(), cols(), IsVectorAtCompileTime. */
|
||||
|
||||
/** \returns the outer size.
|
||||
*
|
||||
|
||||
@@ -122,33 +122,41 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
|
||||
{
|
||||
internal::plain_array<T,Size,_Options> m_data;
|
||||
public:
|
||||
inline DenseStorage() {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
DenseStorage() {}
|
||||
DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
: m_data(internal::constructor_without_unaligned_array_assert()) {}
|
||||
inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); }
|
||||
static inline DenseIndex rows(void) {return _Rows;}
|
||||
static inline DenseIndex cols(void) {return _Cols;}
|
||||
inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
inline void resize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
inline const T *data() const { return m_data.array; }
|
||||
inline T *data() { return m_data.array; }
|
||||
DenseStorage(const DenseStorage& other) : m_data(other.m_data) {}
|
||||
DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
if (this != &other) m_data = other.m_data;
|
||||
return *this;
|
||||
}
|
||||
DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
void swap(DenseStorage& other) { std::swap(m_data,other.m_data); }
|
||||
static DenseIndex rows(void) {return _Rows;}
|
||||
static DenseIndex cols(void) {return _Cols;}
|
||||
void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
void resize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
const T *data() const { return m_data.array; }
|
||||
T *data() { return m_data.array; }
|
||||
};
|
||||
|
||||
// null matrix
|
||||
template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0, _Rows, _Cols, _Options>
|
||||
{
|
||||
public:
|
||||
inline DenseStorage() {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert) {}
|
||||
inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
inline void swap(DenseStorage& ) {}
|
||||
static inline DenseIndex rows(void) {return _Rows;}
|
||||
static inline DenseIndex cols(void) {return _Cols;}
|
||||
inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
inline void resize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
inline const T *data() const { return 0; }
|
||||
inline T *data() { return 0; }
|
||||
DenseStorage() {}
|
||||
DenseStorage(internal::constructor_without_unaligned_array_assert) {}
|
||||
DenseStorage(const DenseStorage&) {}
|
||||
DenseStorage& operator=(const DenseStorage&) { return *this; }
|
||||
DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
void swap(DenseStorage& ) {}
|
||||
static DenseIndex rows(void) {return _Rows;}
|
||||
static DenseIndex cols(void) {return _Cols;}
|
||||
void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
void resize(DenseIndex,DenseIndex,DenseIndex) {}
|
||||
const T *data() const { return 0; }
|
||||
T *data() { return 0; }
|
||||
};
|
||||
|
||||
// more specializations for null matrices; these are necessary to resolve ambiguities
|
||||
@@ -168,18 +176,29 @@ template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic
|
||||
DenseIndex m_rows;
|
||||
DenseIndex m_cols;
|
||||
public:
|
||||
inline DenseStorage() : m_rows(0), m_cols(0) {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
DenseStorage() : m_rows(0), m_cols(0) {}
|
||||
DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
|
||||
inline DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) : m_rows(nbRows), m_cols(nbCols) {}
|
||||
inline void swap(DenseStorage& other)
|
||||
DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows), m_cols(other.m_cols) {}
|
||||
DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
m_data = other.m_data;
|
||||
m_rows = other.m_rows;
|
||||
m_cols = other.m_cols;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) : m_rows(nbRows), m_cols(nbCols) {}
|
||||
void swap(DenseStorage& other)
|
||||
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
|
||||
inline DenseIndex rows() const {return m_rows;}
|
||||
inline DenseIndex cols() const {return m_cols;}
|
||||
inline void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; }
|
||||
inline void resize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; }
|
||||
inline const T *data() const { return m_data.array; }
|
||||
inline T *data() { return m_data.array; }
|
||||
DenseIndex rows() const {return m_rows;}
|
||||
DenseIndex cols() const {return m_cols;}
|
||||
void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; }
|
||||
void resize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; }
|
||||
const T *data() const { return m_data.array; }
|
||||
T *data() { return m_data.array; }
|
||||
};
|
||||
|
||||
// dynamic-size matrix with fixed-size storage and fixed width
|
||||
@@ -188,17 +207,27 @@ template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Si
|
||||
internal::plain_array<T,Size,_Options> m_data;
|
||||
DenseIndex m_rows;
|
||||
public:
|
||||
inline DenseStorage() : m_rows(0) {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
DenseStorage() : m_rows(0) {}
|
||||
DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
|
||||
inline DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex) : m_rows(nbRows) {}
|
||||
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
||||
inline DenseIndex rows(void) const {return m_rows;}
|
||||
inline DenseIndex cols(void) const {return _Cols;}
|
||||
inline void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; }
|
||||
inline void resize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; }
|
||||
inline const T *data() const { return m_data.array; }
|
||||
inline T *data() { return m_data.array; }
|
||||
DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows) {}
|
||||
DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
m_data = other.m_data;
|
||||
m_rows = other.m_rows;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex) : m_rows(nbRows) {}
|
||||
void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
||||
DenseIndex rows(void) const {return m_rows;}
|
||||
DenseIndex cols(void) const {return _Cols;}
|
||||
void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; }
|
||||
void resize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; }
|
||||
const T *data() const { return m_data.array; }
|
||||
T *data() { return m_data.array; }
|
||||
};
|
||||
|
||||
// dynamic-size matrix with fixed-size storage and fixed height
|
||||
@@ -207,17 +236,27 @@ template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Si
|
||||
internal::plain_array<T,Size,_Options> m_data;
|
||||
DenseIndex m_cols;
|
||||
public:
|
||||
inline DenseStorage() : m_cols(0) {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
DenseStorage() : m_cols(0) {}
|
||||
DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
: m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
|
||||
inline DenseStorage(DenseIndex, DenseIndex, DenseIndex nbCols) : m_cols(nbCols) {}
|
||||
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
||||
inline DenseIndex rows(void) const {return _Rows;}
|
||||
inline DenseIndex cols(void) const {return m_cols;}
|
||||
inline void conservativeResize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; }
|
||||
inline void resize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; }
|
||||
inline const T *data() const { return m_data.array; }
|
||||
inline T *data() { return m_data.array; }
|
||||
DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_cols(other.m_cols) {}
|
||||
DenseStorage& operator=(const DenseStorage& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
m_data = other.m_data;
|
||||
m_cols = other.m_cols;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
DenseStorage(DenseIndex, DenseIndex, DenseIndex nbCols) : m_cols(nbCols) {}
|
||||
void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
||||
DenseIndex rows(void) const {return _Rows;}
|
||||
DenseIndex cols(void) const {return m_cols;}
|
||||
void conservativeResize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; }
|
||||
void resize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; }
|
||||
const T *data() const { return m_data.array; }
|
||||
T *data() { return m_data.array; }
|
||||
};
|
||||
|
||||
// purely dynamic matrix.
|
||||
@@ -227,18 +266,35 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
|
||||
DenseIndex m_rows;
|
||||
DenseIndex m_cols;
|
||||
public:
|
||||
inline DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
|
||||
DenseStorage(internal::constructor_without_unaligned_array_assert)
|
||||
: m_data(0), m_rows(0), m_cols(0) {}
|
||||
inline DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
|
||||
DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
|
||||
: m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(nbRows), m_cols(nbCols)
|
||||
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
|
||||
inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
|
||||
inline void swap(DenseStorage& other)
|
||||
#ifdef EIGEN_HAVE_RVALUE_REFERENCES
|
||||
DenseStorage(DenseStorage&& other)
|
||||
: m_data(std::move(other.m_data))
|
||||
, m_rows(std::move(other.m_rows))
|
||||
, m_cols(std::move(other.m_cols))
|
||||
{
|
||||
other.m_data = nullptr;
|
||||
}
|
||||
DenseStorage& operator=(DenseStorage&& other)
|
||||
{
|
||||
using std::swap;
|
||||
swap(m_data, other.m_data);
|
||||
swap(m_rows, other.m_rows);
|
||||
swap(m_cols, other.m_cols);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
|
||||
void swap(DenseStorage& other)
|
||||
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
|
||||
inline DenseIndex rows(void) const {return m_rows;}
|
||||
inline DenseIndex cols(void) const {return m_cols;}
|
||||
inline void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
|
||||
DenseIndex rows(void) const {return m_rows;}
|
||||
DenseIndex cols(void) const {return m_cols;}
|
||||
void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
|
||||
{
|
||||
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols);
|
||||
m_rows = nbRows;
|
||||
@@ -258,8 +314,11 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
|
||||
m_rows = nbRows;
|
||||
m_cols = nbCols;
|
||||
}
|
||||
inline const T *data() const { return m_data; }
|
||||
inline T *data() { return m_data; }
|
||||
const T *data() const { return m_data; }
|
||||
T *data() { return m_data; }
|
||||
private:
|
||||
DenseStorage(const DenseStorage&);
|
||||
DenseStorage& operator=(const DenseStorage&);
|
||||
};
|
||||
|
||||
// matrix with dynamic width and fixed height (so that matrix has dynamic size).
|
||||
@@ -268,15 +327,30 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
|
||||
T *m_data;
|
||||
DenseIndex m_cols;
|
||||
public:
|
||||
inline DenseStorage() : m_data(0), m_cols(0) {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
|
||||
inline DenseStorage(DenseIndex size, DenseIndex, DenseIndex nbCols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(nbCols)
|
||||
DenseStorage() : m_data(0), m_cols(0) {}
|
||||
DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
|
||||
DenseStorage(DenseIndex size, DenseIndex, DenseIndex nbCols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(nbCols)
|
||||
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
|
||||
inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
|
||||
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
||||
static inline DenseIndex rows(void) {return _Rows;}
|
||||
inline DenseIndex cols(void) const {return m_cols;}
|
||||
inline void conservativeResize(DenseIndex size, DenseIndex, DenseIndex nbCols)
|
||||
#ifdef EIGEN_HAVE_RVALUE_REFERENCES
|
||||
DenseStorage(DenseStorage&& other)
|
||||
: m_data(std::move(other.m_data))
|
||||
, m_cols(std::move(other.m_cols))
|
||||
{
|
||||
other.m_data = nullptr;
|
||||
}
|
||||
DenseStorage& operator=(DenseStorage&& other)
|
||||
{
|
||||
using std::swap;
|
||||
swap(m_data, other.m_data);
|
||||
swap(m_cols, other.m_cols);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
|
||||
void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
|
||||
static DenseIndex rows(void) {return _Rows;}
|
||||
DenseIndex cols(void) const {return m_cols;}
|
||||
void conservativeResize(DenseIndex size, DenseIndex, DenseIndex nbCols)
|
||||
{
|
||||
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols);
|
||||
m_cols = nbCols;
|
||||
@@ -294,8 +368,11 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
|
||||
}
|
||||
m_cols = nbCols;
|
||||
}
|
||||
inline const T *data() const { return m_data; }
|
||||
inline T *data() { return m_data; }
|
||||
const T *data() const { return m_data; }
|
||||
T *data() { return m_data; }
|
||||
private:
|
||||
DenseStorage(const DenseStorage&);
|
||||
DenseStorage& operator=(const DenseStorage&);
|
||||
};
|
||||
|
||||
// matrix with dynamic height and fixed width (so that matrix has dynamic size).
|
||||
@@ -304,15 +381,30 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
|
||||
T *m_data;
|
||||
DenseIndex m_rows;
|
||||
public:
|
||||
inline DenseStorage() : m_data(0), m_rows(0) {}
|
||||
inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
|
||||
inline DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(nbRows)
|
||||
DenseStorage() : m_data(0), m_rows(0) {}
|
||||
DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
|
||||
DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(nbRows)
|
||||
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
|
||||
inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
|
||||
inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
||||
inline DenseIndex rows(void) const {return m_rows;}
|
||||
static inline DenseIndex cols(void) {return _Cols;}
|
||||
inline void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex)
|
||||
#ifdef EIGEN_HAVE_RVALUE_REFERENCES
|
||||
DenseStorage(DenseStorage&& other)
|
||||
: m_data(std::move(other.m_data))
|
||||
, m_rows(std::move(other.m_rows))
|
||||
{
|
||||
other.m_data = nullptr;
|
||||
}
|
||||
DenseStorage& operator=(DenseStorage&& other)
|
||||
{
|
||||
using std::swap;
|
||||
swap(m_data, other.m_data);
|
||||
swap(m_rows, other.m_rows);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
|
||||
void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
|
||||
DenseIndex rows(void) const {return m_rows;}
|
||||
static DenseIndex cols(void) {return _Cols;}
|
||||
void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex)
|
||||
{
|
||||
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols);
|
||||
m_rows = nbRows;
|
||||
@@ -330,8 +422,11 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
|
||||
}
|
||||
m_rows = nbRows;
|
||||
}
|
||||
inline const T *data() const { return m_data; }
|
||||
inline T *data() { return m_data; }
|
||||
const T *data() const { return m_data; }
|
||||
T *data() { return m_data; }
|
||||
private:
|
||||
DenseStorage(const DenseStorage&);
|
||||
DenseStorage& operator=(const DenseStorage&);
|
||||
};
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -44,10 +44,10 @@ class DiagonalBase : public EigenBase<Derived>
|
||||
template<typename DenseDerived>
|
||||
void evalTo(MatrixBase<DenseDerived> &other) const;
|
||||
template<typename DenseDerived>
|
||||
void addTo(MatrixBase<DenseDerived> &other) const
|
||||
inline void addTo(MatrixBase<DenseDerived> &other) const
|
||||
{ other.diagonal() += diagonal(); }
|
||||
template<typename DenseDerived>
|
||||
void subTo(MatrixBase<DenseDerived> &other) const
|
||||
inline void subTo(MatrixBase<DenseDerived> &other) const
|
||||
{ other.diagonal() -= diagonal(); }
|
||||
|
||||
inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); }
|
||||
@@ -98,7 +98,7 @@ class DiagonalBase : public EigenBase<Derived>
|
||||
|
||||
template<typename Derived>
|
||||
template<typename DenseDerived>
|
||||
void DiagonalBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
|
||||
inline void DiagonalBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
|
||||
{
|
||||
other.setZero();
|
||||
other.diagonal() = diagonal();
|
||||
|
||||
@@ -35,7 +35,8 @@ struct traits<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> >
|
||||
_LinearAccessMask = (RowsAtCompileTime==1 || ColsAtCompileTime==1) ? LinearAccessBit : 0,
|
||||
|
||||
Flags = ((HereditaryBits|_LinearAccessMask|AlignedBit) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0),//(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit),
|
||||
CoeffReadCost = NumTraits<Scalar>::MulCost + MatrixType::CoeffReadCost + DiagonalType::DiagonalVectorType::CoeffReadCost
|
||||
Cost0 = EIGEN_ADD_COST(NumTraits<Scalar>::MulCost, MatrixType::CoeffReadCost),
|
||||
CoeffReadCost = EIGEN_ADD_COST(Cost0,DiagonalType::DiagonalVectorType::CoeffReadCost)
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ struct dot_nocheck<T, U, true>
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
typename internal::scalar_product_traits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
|
||||
inline typename internal::scalar_product_traits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
|
||||
MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
|
||||
@@ -205,9 +205,6 @@ class GeneralProduct<Lhs, Rhs, InnerProduct>
|
||||
public:
|
||||
GeneralProduct(const Lhs& lhs, const Rhs& rhs)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::RealScalar, typename Rhs::RealScalar>::value),
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||
|
||||
Base::coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum();
|
||||
}
|
||||
|
||||
@@ -257,15 +254,13 @@ template<typename Lhs, typename Rhs>
|
||||
class GeneralProduct<Lhs, Rhs, OuterProduct>
|
||||
: public ProductBase<GeneralProduct<Lhs,Rhs,OuterProduct>, Lhs, Rhs>
|
||||
{
|
||||
template<typename T> struct IsRowMajor : internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {};
|
||||
template<typename T> struct is_row_major : internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {};
|
||||
|
||||
public:
|
||||
EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct)
|
||||
|
||||
GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::RealScalar, typename Rhs::RealScalar>::value),
|
||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||
}
|
||||
|
||||
struct set { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() = src; } };
|
||||
@@ -281,22 +276,22 @@ class GeneralProduct<Lhs, Rhs, OuterProduct>
|
||||
|
||||
template<typename Dest>
|
||||
inline void evalTo(Dest& dest) const {
|
||||
internal::outer_product_selector_run(*this, dest, set(), IsRowMajor<Dest>());
|
||||
internal::outer_product_selector_run(*this, dest, set(), is_row_major<Dest>());
|
||||
}
|
||||
|
||||
template<typename Dest>
|
||||
inline void addTo(Dest& dest) const {
|
||||
internal::outer_product_selector_run(*this, dest, add(), IsRowMajor<Dest>());
|
||||
internal::outer_product_selector_run(*this, dest, add(), is_row_major<Dest>());
|
||||
}
|
||||
|
||||
template<typename Dest>
|
||||
inline void subTo(Dest& dest) const {
|
||||
internal::outer_product_selector_run(*this, dest, sub(), IsRowMajor<Dest>());
|
||||
internal::outer_product_selector_run(*this, dest, sub(), is_row_major<Dest>());
|
||||
}
|
||||
|
||||
template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
|
||||
{
|
||||
internal::outer_product_selector_run(*this, dest, adds(alpha), IsRowMajor<Dest>());
|
||||
internal::outer_product_selector_run(*this, dest, adds(alpha), is_row_major<Dest>());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -425,15 +420,18 @@ template<> struct gemv_selector<OnTheRight,ColMajor,true>
|
||||
ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs())
|
||||
* RhsBlasTraits::extractScalarFactor(prod.rhs());
|
||||
|
||||
// make sure Dest is a compile-time vector type (bug 1166)
|
||||
typedef typename conditional<Dest::IsVectorAtCompileTime, Dest, typename Dest::ColXpr>::type ActualDest;
|
||||
|
||||
enum {
|
||||
// FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1
|
||||
// on, the other hand it is good for the cache to pack the vector anyways...
|
||||
EvalToDestAtCompileTime = Dest::InnerStrideAtCompileTime==1,
|
||||
EvalToDestAtCompileTime = (ActualDest::InnerStrideAtCompileTime==1),
|
||||
ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex),
|
||||
MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal
|
||||
MightCannotUseDest = (ActualDest::InnerStrideAtCompileTime!=1) || ComplexByReal
|
||||
};
|
||||
|
||||
gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
|
||||
gemv_static_vector_if<ResScalar,ActualDest::SizeAtCompileTime,ActualDest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
|
||||
|
||||
bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
|
||||
bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
|
||||
@@ -522,7 +520,7 @@ template<> struct gemv_selector<OnTheRight,RowMajor,true>
|
||||
actualLhs.rows(), actualLhs.cols(),
|
||||
actualLhs.data(), actualLhs.outerStride(),
|
||||
actualRhsPtr, 1,
|
||||
dest.data(), dest.innerStride(),
|
||||
dest.data(), dest.col(0).innerStride(), //NOTE if dest is not a vector at compile-time, then dest.innerStride() might be wrong. (bug 1166)
|
||||
actualAlpha);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -123,7 +123,7 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||
return internal::ploadt<PacketScalar, LoadMode>(m_data + index * innerStride());
|
||||
}
|
||||
|
||||
inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
|
||||
explicit inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||
checkSanity();
|
||||
@@ -149,6 +149,10 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||
checkSanity();
|
||||
}
|
||||
|
||||
#ifdef EIGEN_MAPBASE_PLUGIN
|
||||
#include EIGEN_MAPBASE_PLUGIN
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
void checkSanity() const
|
||||
|
||||
@@ -218,8 +218,8 @@ struct conj_retval
|
||||
* Implementation of abs2 *
|
||||
****************************************************************************/
|
||||
|
||||
template<typename Scalar>
|
||||
struct abs2_impl
|
||||
template<typename Scalar,bool IsComplex>
|
||||
struct abs2_impl_default
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
static inline RealScalar run(const Scalar& x)
|
||||
@@ -228,15 +228,26 @@ struct abs2_impl
|
||||
}
|
||||
};
|
||||
|
||||
template<typename RealScalar>
|
||||
struct abs2_impl<std::complex<RealScalar> >
|
||||
template<typename Scalar>
|
||||
struct abs2_impl_default<Scalar, true> // IsComplex
|
||||
{
|
||||
static inline RealScalar run(const std::complex<RealScalar>& x)
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
static inline RealScalar run(const Scalar& x)
|
||||
{
|
||||
return real(x)*real(x) + imag(x)*imag(x);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Scalar>
|
||||
struct abs2_impl
|
||||
{
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
static inline RealScalar run(const Scalar& x)
|
||||
{
|
||||
return abs2_impl_default<Scalar,NumTraits<Scalar>::IsComplex>::run(x);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Scalar>
|
||||
struct abs2_retval
|
||||
{
|
||||
@@ -294,7 +305,7 @@ struct hypot_impl
|
||||
RealScalar _x = abs(x);
|
||||
RealScalar _y = abs(y);
|
||||
RealScalar p = (max)(_x, _y);
|
||||
if(p==RealScalar(0)) return 0;
|
||||
if(p==RealScalar(0)) return RealScalar(0);
|
||||
RealScalar q = (min)(_x, _y);
|
||||
RealScalar qp = q/p;
|
||||
return p * sqrt(RealScalar(1) + qp*qp);
|
||||
@@ -707,21 +718,21 @@ struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::
|
||||
|
||||
template<typename Scalar, typename OtherScalar>
|
||||
inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y,
|
||||
typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
|
||||
const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
|
||||
{
|
||||
return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
inline bool isApprox(const Scalar& x, const Scalar& y,
|
||||
typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
|
||||
const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
|
||||
{
|
||||
return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y,
|
||||
typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
|
||||
const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
|
||||
{
|
||||
return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
|
||||
}
|
||||
|
||||
@@ -211,6 +211,21 @@ class Matrix
|
||||
: Base(internal::constructor_without_unaligned_array_assert())
|
||||
{ Base::_check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
|
||||
|
||||
#ifdef EIGEN_HAVE_RVALUE_REFERENCES
|
||||
Matrix(Matrix&& other)
|
||||
: Base(std::move(other))
|
||||
{
|
||||
Base::_check_template_params();
|
||||
if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic)
|
||||
Base::_set_noalias(other);
|
||||
}
|
||||
Matrix& operator=(Matrix&& other)
|
||||
{
|
||||
other.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \brief Constructs a vector or row-vector with given dimension. \only_for_vectors
|
||||
*
|
||||
* Note that this is only useful for dynamic-size vectors. For fixed-size vectors,
|
||||
|
||||
@@ -440,6 +440,15 @@ template<typename Derived> class MatrixBase
|
||||
template<typename OtherScalar>
|
||||
void applyOnTheRight(Index p, Index q, const JacobiRotation<OtherScalar>& j);
|
||||
|
||||
///////// SparseCore module /////////
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE const typename SparseMatrixBase<OtherDerived>::template CwiseProductDenseReturnType<Derived>::Type
|
||||
cwiseProduct(const SparseMatrixBase<OtherDerived> &other) const
|
||||
{
|
||||
return other.cwiseProduct(derived());
|
||||
}
|
||||
|
||||
///////// MatrixFunctions module /////////
|
||||
|
||||
typedef typename internal::stem_function<Scalar>::type StemFunction;
|
||||
|
||||
@@ -584,10 +584,11 @@ struct permut_matrix_product_retval
|
||||
const Index n = Side==OnTheLeft ? rows() : cols();
|
||||
// FIXME we need an is_same for expression that is not sensitive to constness. For instance
|
||||
// is_same_xpr<Block<const Matrix>, Block<Matrix> >::value should be true.
|
||||
const typename Dest::Scalar *dst_data = internal::extract_data(dst);
|
||||
if( is_same<MatrixTypeNestedCleaned,Dest>::value
|
||||
&& blas_traits<MatrixTypeNestedCleaned>::HasUsableDirectAccess
|
||||
&& blas_traits<Dest>::HasUsableDirectAccess
|
||||
&& extract_data(dst) == extract_data(m_matrix))
|
||||
&& dst_data!=0 && dst_data == extract_data(m_matrix))
|
||||
{
|
||||
// apply the permutation inplace
|
||||
Matrix<bool,PermutationType::RowsAtCompileTime,1,0,PermutationType::MaxRowsAtCompileTime> mask(m_permutation.size());
|
||||
|
||||
@@ -315,8 +315,8 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
|
||||
{
|
||||
const OtherDerived& other = _other.derived();
|
||||
internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.rows(), other.cols());
|
||||
const Index othersize = other.rows()*other.cols();
|
||||
internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(Index(other.rows()), Index(other.cols()));
|
||||
const Index othersize = Index(other.rows())*Index(other.cols());
|
||||
if(RowsAtCompileTime == 1)
|
||||
{
|
||||
eigen_assert(other.rows() == 1 || other.cols() == 1);
|
||||
@@ -437,6 +437,36 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_HAVE_RVALUE_REFERENCES
|
||||
PlainObjectBase(PlainObjectBase&& other)
|
||||
: m_storage( std::move(other.m_storage) )
|
||||
{
|
||||
}
|
||||
|
||||
PlainObjectBase& operator=(PlainObjectBase&& other)
|
||||
{
|
||||
using std::swap;
|
||||
swap(m_storage, other.m_storage);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Copy constructor */
|
||||
EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other)
|
||||
: m_storage()
|
||||
{
|
||||
_check_template_params();
|
||||
lazyAssign(other);
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other)
|
||||
: m_storage()
|
||||
{
|
||||
_check_template_params();
|
||||
lazyAssign(other);
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE PlainObjectBase(Index a_size, Index nbRows, Index nbCols)
|
||||
: m_storage(a_size, nbRows, nbCols)
|
||||
{
|
||||
@@ -457,7 +487,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
||||
/** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
|
||||
: m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
|
||||
: m_storage(Index(other.derived().rows()) * Index(other.derived().cols()), other.derived().rows(), other.derived().cols())
|
||||
{
|
||||
_check_template_params();
|
||||
internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.derived().rows(), other.derived().cols());
|
||||
|
||||
@@ -247,8 +247,9 @@ struct redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling>
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Func, typename Derived>
|
||||
struct redux_impl<Func, Derived, SliceVectorizedTraversal, NoUnrolling>
|
||||
// NOTE: for SliceVectorizedTraversal we simply bypass unrolling
|
||||
template<typename Func, typename Derived, int Unrolling>
|
||||
struct redux_impl<Func, Derived, SliceVectorizedTraversal, Unrolling>
|
||||
{
|
||||
typedef typename Derived::Scalar Scalar;
|
||||
typedef typename packet_traits<Scalar>::type PacketScalar;
|
||||
|
||||
@@ -244,6 +244,15 @@ template<typename TPlainObjectType, int Options, typename StrideType> class Ref<
|
||||
// std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n";
|
||||
construct(expr.derived(), typename Traits::template match<Derived>::type());
|
||||
}
|
||||
|
||||
inline Ref(const Ref& other) : Base(other) {
|
||||
// copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
|
||||
}
|
||||
|
||||
template<typename OtherRef>
|
||||
inline Ref(const RefBase<OtherRef>& other) {
|
||||
construct(other.derived(), typename Traits::template match<OtherRef>::type());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -180,15 +180,9 @@ inline Derived& DenseBase<Derived>::operator*=(const Scalar& other)
|
||||
template<typename Derived>
|
||||
inline Derived& DenseBase<Derived>::operator/=(const Scalar& other)
|
||||
{
|
||||
typedef typename internal::conditional<NumTraits<Scalar>::IsInteger,
|
||||
internal::scalar_quotient_op<Scalar>,
|
||||
internal::scalar_product_op<Scalar> >::type BinOp;
|
||||
typedef typename Derived::PlainObject PlainObject;
|
||||
SelfCwiseBinaryOp<BinOp, Derived, typename PlainObject::ConstantReturnType> tmp(derived());
|
||||
Scalar actual_other;
|
||||
if(NumTraits<Scalar>::IsInteger) actual_other = other;
|
||||
else actual_other = Scalar(1)/other;
|
||||
tmp = PlainObject::Constant(rows(),cols(), actual_other);
|
||||
SelfCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, Derived, typename PlainObject::ConstantReturnType> tmp(derived());
|
||||
tmp = PlainObject::Constant(rows(),cols(), other);
|
||||
return derived();
|
||||
}
|
||||
|
||||
|
||||
@@ -116,17 +116,17 @@ template<typename Lhs, typename Rhs, int Mode, int Index, int Size>
|
||||
struct triangular_solver_unroller<Lhs,Rhs,Mode,Index,Size,false> {
|
||||
enum {
|
||||
IsLower = ((Mode&Lower)==Lower),
|
||||
I = IsLower ? Index : Size - Index - 1,
|
||||
S = IsLower ? 0 : I+1
|
||||
RowIndex = IsLower ? Index : Size - Index - 1,
|
||||
S = IsLower ? 0 : RowIndex+1
|
||||
};
|
||||
static void run(const Lhs& lhs, Rhs& rhs)
|
||||
{
|
||||
if (Index>0)
|
||||
rhs.coeffRef(I) -= lhs.row(I).template segment<Index>(S).transpose()
|
||||
rhs.coeffRef(RowIndex) -= lhs.row(RowIndex).template segment<Index>(S).transpose()
|
||||
.cwiseProduct(rhs.template segment<Index>(S)).sum();
|
||||
|
||||
if(!(Mode & UnitDiag))
|
||||
rhs.coeffRef(I) /= lhs.coeff(I,I);
|
||||
rhs.coeffRef(RowIndex) /= lhs.coeff(RowIndex,RowIndex);
|
||||
|
||||
triangular_solver_unroller<Lhs,Rhs,Mode,Index+1,Size>::run(lhs,rhs);
|
||||
}
|
||||
@@ -243,7 +243,8 @@ template<int Side, typename TriangularType, typename Rhs> struct triangular_solv
|
||||
|
||||
template<typename Dest> inline void evalTo(Dest& dst) const
|
||||
{
|
||||
if(!(is_same<RhsNestedCleaned,Dest>::value && extract_data(dst) == extract_data(m_rhs)))
|
||||
const typename Dest::Scalar *dst_data = internal::extract_data(dst);
|
||||
if(!(is_same<RhsNestedCleaned,Dest>::value && dst_data!=0 && extract_data(dst) == extract_data(m_rhs)))
|
||||
dst = m_rhs;
|
||||
m_triangularMatrix.template solveInPlace<Side>(dst);
|
||||
}
|
||||
|
||||
@@ -331,11 +331,11 @@ inline void MatrixBase<Derived>::adjointInPlace()
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename BinOp,typename NestedXpr,typename Rhs>
|
||||
struct blas_traits<SelfCwiseBinaryOp<BinOp,NestedXpr,Rhs> >
|
||||
: blas_traits<NestedXpr>
|
||||
template<typename BinOp,typename Xpr,typename Rhs>
|
||||
struct blas_traits<SelfCwiseBinaryOp<BinOp,Xpr,Rhs> >
|
||||
: blas_traits<typename internal::remove_all<typename Xpr::Nested>::type>
|
||||
{
|
||||
typedef SelfCwiseBinaryOp<BinOp,NestedXpr,Rhs> XprType;
|
||||
typedef SelfCwiseBinaryOp<BinOp,Xpr,Rhs> XprType;
|
||||
static inline const XprType extract(const XprType& x) { return x; }
|
||||
};
|
||||
|
||||
@@ -392,7 +392,6 @@ struct checkTransposeAliasing_impl
|
||||
::run(extract_data(dst), other))
|
||||
&& "aliasing detected during transposition, use transposeInPlace() "
|
||||
"or evaluate the rhs into a temporary using .eval()");
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -376,7 +376,8 @@ struct transposition_matrix_product_retval
|
||||
const int size = m_transpositions.size();
|
||||
Index j = 0;
|
||||
|
||||
if(!(is_same<MatrixTypeNestedCleaned,Dest>::value && extract_data(dst) == extract_data(m_matrix)))
|
||||
const typename Dest::Scalar *dst_data = internal::extract_data(dst);
|
||||
if(!(is_same<MatrixTypeNestedCleaned,Dest>::value && dst_data!=0 && dst_data == extract_data(m_matrix)))
|
||||
dst = m_matrix;
|
||||
|
||||
for(int k=(Transposed?size-1:0) ; Transposed?k>=0:k<size ; Transposed?--k:++k)
|
||||
|
||||
@@ -76,14 +76,17 @@ template<typename Derived>
|
||||
template<typename Visitor>
|
||||
void DenseBase<Derived>::visit(Visitor& visitor) const
|
||||
{
|
||||
typedef typename internal::remove_all<typename Derived::Nested>::type ThisNested;
|
||||
typename Derived::Nested thisNested(derived());
|
||||
|
||||
enum { unroll = SizeAtCompileTime != Dynamic
|
||||
&& CoeffReadCost != Dynamic
|
||||
&& (SizeAtCompileTime == 1 || internal::functor_traits<Visitor>::Cost != Dynamic)
|
||||
&& SizeAtCompileTime * CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost
|
||||
<= EIGEN_UNROLLING_LIMIT };
|
||||
return internal::visitor_impl<Visitor, Derived,
|
||||
return internal::visitor_impl<Visitor, ThisNested,
|
||||
unroll ? int(SizeAtCompileTime) : Dynamic
|
||||
>::run(derived(), visitor);
|
||||
>::run(thisNested, visitor);
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
@@ -384,6 +384,7 @@ template<> EIGEN_STRONG_INLINE int predux_max<Packet4i>(const Packet4i& a)
|
||||
a_lo = vget_low_s32(a);
|
||||
a_hi = vget_high_s32(a);
|
||||
max = vpmax_s32(a_lo, a_hi);
|
||||
max = vpmax_s32(max, max);
|
||||
|
||||
return vget_lane_s32(max, 0);
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ Packet4f pexp<Packet4f>(const Packet4f& _x)
|
||||
_EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p4, 1.6666665459E-1f);
|
||||
_EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p5, 5.0000001201E-1f);
|
||||
|
||||
Packet4f tmp = _mm_setzero_ps(), fx;
|
||||
Packet4f tmp, fx;
|
||||
Packet4i emm0;
|
||||
|
||||
// clamp x
|
||||
@@ -195,7 +195,7 @@ Packet2d pexp<Packet2d>(const Packet2d& _x)
|
||||
_EIGEN_DECLARE_CONST_Packet2d(cephes_exp_C2, 1.42860682030941723212e-6);
|
||||
static const __m128i p4i_1023_0 = _mm_setr_epi32(1023, 1023, 0, 0);
|
||||
|
||||
Packet2d tmp = _mm_setzero_pd(), fx;
|
||||
Packet2d tmp, fx;
|
||||
Packet4i emm0;
|
||||
|
||||
// clamp x
|
||||
@@ -279,7 +279,7 @@ Packet4f psin<Packet4f>(const Packet4f& _x)
|
||||
_EIGEN_DECLARE_CONST_Packet4f(coscof_p2, 4.166664568298827E-002f);
|
||||
_EIGEN_DECLARE_CONST_Packet4f(cephes_FOPI, 1.27323954473516f); // 4 / M_PI
|
||||
|
||||
Packet4f xmm1, xmm2 = _mm_setzero_ps(), xmm3, sign_bit, y;
|
||||
Packet4f xmm1, xmm2, xmm3, sign_bit, y;
|
||||
|
||||
Packet4i emm0, emm2;
|
||||
sign_bit = x;
|
||||
@@ -378,7 +378,7 @@ Packet4f pcos<Packet4f>(const Packet4f& _x)
|
||||
_EIGEN_DECLARE_CONST_Packet4f(coscof_p2, 4.166664568298827E-002f);
|
||||
_EIGEN_DECLARE_CONST_Packet4f(cephes_FOPI, 1.27323954473516f); // 4 / M_PI
|
||||
|
||||
Packet4f xmm1, xmm2 = _mm_setzero_ps(), xmm3, y;
|
||||
Packet4f xmm1, xmm2, xmm3, y;
|
||||
Packet4i emm0, emm2;
|
||||
|
||||
x = pabs(x);
|
||||
|
||||
@@ -235,63 +235,27 @@ template<> EIGEN_STRONG_INLINE Packet4i pload<Packet4i>(const int* from) { E
|
||||
return _mm_loadu_ps(from);
|
||||
#endif
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet2d ploadu<Packet2d>(const double* from) { EIGEN_DEBUG_UNALIGNED_LOAD return _mm_loadu_pd(from); }
|
||||
template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int* from) { EIGEN_DEBUG_UNALIGNED_LOAD return _mm_loadu_si128(reinterpret_cast<const Packet4i*>(from)); }
|
||||
#else
|
||||
// Fast unaligned loads. Note that here we cannot directly use intrinsics: this would
|
||||
// require pointer casting to incompatible pointer types and leads to invalid code
|
||||
// because of the strict aliasing rule. The "dummy" stuff are required to enforce
|
||||
// a correct instruction dependency.
|
||||
// TODO: do the same for MSVC (ICC is compatible)
|
||||
// NOTE: with the code below, MSVC's compiler crashes!
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
// bug 195: gcc/i386 emits weird x87 fldl/fstpl instructions for _mm_load_sd
|
||||
#define EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS 1
|
||||
#elif defined(__clang__)
|
||||
// bug 201: Segfaults in __mm_loadh_pd with clang 2.8
|
||||
#define EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS 1
|
||||
#else
|
||||
#define EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS 0
|
||||
#endif
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f ploadu<Packet4f>(const float* from)
|
||||
{
|
||||
EIGEN_DEBUG_UNALIGNED_LOAD
|
||||
#if EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS
|
||||
return _mm_loadu_ps(from);
|
||||
#else
|
||||
__m128d res;
|
||||
res = _mm_load_sd((const double*)(from)) ;
|
||||
res = _mm_loadh_pd(res, (const double*)(from+2)) ;
|
||||
return _mm_castpd_ps(res);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet2d ploadu<Packet2d>(const double* from)
|
||||
{
|
||||
EIGEN_DEBUG_UNALIGNED_LOAD
|
||||
#if EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS
|
||||
return _mm_loadu_pd(from);
|
||||
#else
|
||||
__m128d res;
|
||||
res = _mm_load_sd(from) ;
|
||||
res = _mm_loadh_pd(res,from+1);
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int* from)
|
||||
{
|
||||
EIGEN_DEBUG_UNALIGNED_LOAD
|
||||
#if EIGEN_AVOID_CUSTOM_UNALIGNED_LOADS
|
||||
return _mm_loadu_si128(reinterpret_cast<const Packet4i*>(from));
|
||||
#else
|
||||
__m128d res;
|
||||
res = _mm_load_sd((const double*)(from)) ;
|
||||
res = _mm_loadh_pd(res, (const double*)(from+2)) ;
|
||||
return _mm_castpd_si128(res);
|
||||
#endif
|
||||
return _mm_loadu_si128(reinterpret_cast<const __m128i*>(from));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
template<> EIGEN_STRONG_INLINE Packet4f ploaddup<Packet4f>(const float* from)
|
||||
{
|
||||
|
||||
@@ -140,8 +140,10 @@ static void run(Index rows, Index cols, Index depth,
|
||||
// Release all the sub blocks B'_j of B' for the current thread,
|
||||
// i.e., we simply decrement the number of users by 1
|
||||
for(Index j=0; j<threads; ++j)
|
||||
{
|
||||
#pragma omp atomic
|
||||
--(info[j].users);
|
||||
info[j].users -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -390,13 +392,17 @@ class GeneralProduct<Lhs, Rhs, GemmProduct>
|
||||
|
||||
GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
|
||||
{
|
||||
#if !(defined(EIGEN_NO_STATIC_ASSERT) && defined(EIGEN_NO_DEBUG))
|
||||
typedef internal::scalar_product_op<LhsScalar,RhsScalar> BinOp;
|
||||
EIGEN_CHECK_BINARY_COMPATIBILIY(BinOp,LhsScalar,RhsScalar);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
|
||||
{
|
||||
eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
|
||||
if(m_lhs.cols()==0 || m_lhs.rows()==0 || m_rhs.cols()==0)
|
||||
return;
|
||||
|
||||
typename internal::add_const_on_value_type<ActualLhsType>::type lhs = LhsBlasTraits::extract(m_lhs);
|
||||
typename internal::add_const_on_value_type<ActualRhsType>::type rhs = RhsBlasTraits::extract(m_rhs);
|
||||
|
||||
@@ -109,7 +109,7 @@ struct product_triangular_matrix_matrix_trmm<EIGTYPE,Index,Mode,true, \
|
||||
/* Non-square case - doesn't fit to MKL ?TRMM. Fall to default triangular product or call MKL ?GEMM*/ \
|
||||
if (rows != depth) { \
|
||||
\
|
||||
int nthr = mkl_domain_get_max_threads(MKL_BLAS); \
|
||||
int nthr = mkl_domain_get_max_threads(EIGEN_MKL_DOMAIN_BLAS); \
|
||||
\
|
||||
if (((nthr==1) && (((std::max)(rows,depth)-diagSize)/(double)diagSize < 0.5))) { \
|
||||
/* Most likely no benefit to call TRMM or GEMM from MKL*/ \
|
||||
@@ -223,7 +223,7 @@ struct product_triangular_matrix_matrix_trmm<EIGTYPE,Index,Mode,false, \
|
||||
/* Non-square case - doesn't fit to MKL ?TRMM. Fall to default triangular product or call MKL ?GEMM*/ \
|
||||
if (cols != depth) { \
|
||||
\
|
||||
int nthr = mkl_domain_get_max_threads(MKL_BLAS); \
|
||||
int nthr = mkl_domain_get_max_threads(EIGEN_MKL_DOMAIN_BLAS); \
|
||||
\
|
||||
if ((nthr==1) && (((std::max)(cols,depth)-diagSize)/(double)diagSize < 0.5)) { \
|
||||
/* Most likely no benefit to call TRMM or GEMM from MKL*/ \
|
||||
|
||||
@@ -81,7 +81,7 @@ EIGEN_DONT_INLINE void triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conju
|
||||
// coherence when accessing the rhs elements
|
||||
std::ptrdiff_t l1, l2;
|
||||
manage_caching_sizes(GetAction, &l1, &l2);
|
||||
Index subcols = cols>0 ? l2/(4 * sizeof(Scalar) * otherStride) : 0;
|
||||
Index subcols = cols>0 ? l2/(4 * sizeof(Scalar) * std::max<Index>(otherStride,size)) : 0;
|
||||
subcols = std::max<Index>((subcols/Traits::nr)*Traits::nr, Traits::nr);
|
||||
|
||||
for(Index k2=IsLower ? 0 : size;
|
||||
@@ -115,8 +115,9 @@ EIGEN_DONT_INLINE void triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conju
|
||||
{
|
||||
// TODO write a small kernel handling this (can be shared with trsv)
|
||||
Index i = IsLower ? k2+k1+k : k2-k1-k-1;
|
||||
Index s = IsLower ? k2+k1 : i+1;
|
||||
Index rs = actualPanelWidth - k - 1; // remaining size
|
||||
Index s = TriStorageOrder==RowMajor ? (IsLower ? k2+k1 : i+1)
|
||||
: IsLower ? i+1 : i-rs;
|
||||
|
||||
Scalar a = (Mode & UnitDiag) ? Scalar(1) : Scalar(1)/conj(tri(i,i));
|
||||
for (Index j=j2; j<j2+actual_cols; ++j)
|
||||
@@ -133,7 +134,6 @@ EIGEN_DONT_INLINE void triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conju
|
||||
}
|
||||
else
|
||||
{
|
||||
Index s = IsLower ? i+1 : i-rs;
|
||||
Scalar b = (other(i,j) *= a);
|
||||
Scalar* r = &other(s,j);
|
||||
const Scalar* l = &tri(s,i);
|
||||
@@ -302,9 +302,12 @@ EIGEN_DONT_INLINE void triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conj
|
||||
for (Index i=0; i<actual_mc; ++i)
|
||||
r[i] -= a[i] * b;
|
||||
}
|
||||
Scalar b = (Mode & UnitDiag) ? Scalar(1) : Scalar(1)/conj(rhs(j,j));
|
||||
for (Index i=0; i<actual_mc; ++i)
|
||||
r[i] *= b;
|
||||
if((Mode & UnitDiag)==0)
|
||||
{
|
||||
Scalar b = conj(rhs(j,j));
|
||||
for (Index i=0; i<actual_mc; ++i)
|
||||
r[i] /= b;
|
||||
}
|
||||
}
|
||||
|
||||
// pack the just computed part of lhs to A
|
||||
|
||||
@@ -171,12 +171,13 @@ template<typename XprType> struct blas_traits
|
||||
};
|
||||
|
||||
// pop conjugate
|
||||
template<typename Scalar, typename NestedXpr>
|
||||
struct blas_traits<CwiseUnaryOp<scalar_conjugate_op<Scalar>, NestedXpr> >
|
||||
: blas_traits<NestedXpr>
|
||||
template<typename Scalar, typename Xpr>
|
||||
struct blas_traits<CwiseUnaryOp<scalar_conjugate_op<Scalar>, Xpr> >
|
||||
: blas_traits<typename internal::remove_all<typename Xpr::Nested>::type>
|
||||
{
|
||||
typedef typename internal::remove_all<typename Xpr::Nested>::type NestedXpr;
|
||||
typedef blas_traits<NestedXpr> Base;
|
||||
typedef CwiseUnaryOp<scalar_conjugate_op<Scalar>, NestedXpr> XprType;
|
||||
typedef CwiseUnaryOp<scalar_conjugate_op<Scalar>, Xpr> XprType;
|
||||
typedef typename Base::ExtractType ExtractType;
|
||||
|
||||
enum {
|
||||
@@ -188,12 +189,13 @@ struct blas_traits<CwiseUnaryOp<scalar_conjugate_op<Scalar>, NestedXpr> >
|
||||
};
|
||||
|
||||
// pop scalar multiple
|
||||
template<typename Scalar, typename NestedXpr>
|
||||
struct blas_traits<CwiseUnaryOp<scalar_multiple_op<Scalar>, NestedXpr> >
|
||||
: blas_traits<NestedXpr>
|
||||
template<typename Scalar, typename Xpr>
|
||||
struct blas_traits<CwiseUnaryOp<scalar_multiple_op<Scalar>, Xpr> >
|
||||
: blas_traits<typename internal::remove_all<typename Xpr::Nested>::type>
|
||||
{
|
||||
typedef typename internal::remove_all<typename Xpr::Nested>::type NestedXpr;
|
||||
typedef blas_traits<NestedXpr> Base;
|
||||
typedef CwiseUnaryOp<scalar_multiple_op<Scalar>, NestedXpr> XprType;
|
||||
typedef CwiseUnaryOp<scalar_multiple_op<Scalar>, Xpr> XprType;
|
||||
typedef typename Base::ExtractType ExtractType;
|
||||
static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
|
||||
static inline Scalar extractScalarFactor(const XprType& x)
|
||||
@@ -201,12 +203,13 @@ struct blas_traits<CwiseUnaryOp<scalar_multiple_op<Scalar>, NestedXpr> >
|
||||
};
|
||||
|
||||
// pop opposite
|
||||
template<typename Scalar, typename NestedXpr>
|
||||
struct blas_traits<CwiseUnaryOp<scalar_opposite_op<Scalar>, NestedXpr> >
|
||||
: blas_traits<NestedXpr>
|
||||
template<typename Scalar, typename Xpr>
|
||||
struct blas_traits<CwiseUnaryOp<scalar_opposite_op<Scalar>, Xpr> >
|
||||
: blas_traits<typename internal::remove_all<typename Xpr::Nested>::type>
|
||||
{
|
||||
typedef typename internal::remove_all<typename Xpr::Nested>::type NestedXpr;
|
||||
typedef blas_traits<NestedXpr> Base;
|
||||
typedef CwiseUnaryOp<scalar_opposite_op<Scalar>, NestedXpr> XprType;
|
||||
typedef CwiseUnaryOp<scalar_opposite_op<Scalar>, Xpr> XprType;
|
||||
typedef typename Base::ExtractType ExtractType;
|
||||
static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
|
||||
static inline Scalar extractScalarFactor(const XprType& x)
|
||||
@@ -214,13 +217,14 @@ struct blas_traits<CwiseUnaryOp<scalar_opposite_op<Scalar>, NestedXpr> >
|
||||
};
|
||||
|
||||
// pop/push transpose
|
||||
template<typename NestedXpr>
|
||||
struct blas_traits<Transpose<NestedXpr> >
|
||||
: blas_traits<NestedXpr>
|
||||
template<typename Xpr>
|
||||
struct blas_traits<Transpose<Xpr> >
|
||||
: blas_traits<typename internal::remove_all<typename Xpr::Nested>::type>
|
||||
{
|
||||
typedef typename internal::remove_all<typename Xpr::Nested>::type NestedXpr;
|
||||
typedef typename NestedXpr::Scalar Scalar;
|
||||
typedef blas_traits<NestedXpr> Base;
|
||||
typedef Transpose<NestedXpr> XprType;
|
||||
typedef Transpose<Xpr> XprType;
|
||||
typedef Transpose<const typename Base::_ExtractType> ExtractType; // const to get rid of a compile error; anyway blas traits are only used on the RHS
|
||||
typedef Transpose<const typename Base::_ExtractType> _ExtractType;
|
||||
typedef typename conditional<bool(Base::HasUsableDirectAccess),
|
||||
|
||||
@@ -162,7 +162,7 @@ const unsigned int HereditaryBits = RowMajorBit
|
||||
/** \ingroup enums
|
||||
* Enum containing possible values for the \p Mode parameter of
|
||||
* MatrixBase::selfadjointView() and MatrixBase::triangularView(). */
|
||||
enum {
|
||||
enum UpLoType {
|
||||
/** View matrix as a lower triangular matrix. */
|
||||
Lower=0x1,
|
||||
/** View matrix as an upper triangular matrix. */
|
||||
@@ -187,7 +187,7 @@ enum {
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum for indicating whether an object is aligned or not. */
|
||||
enum {
|
||||
enum AlignmentType {
|
||||
/** Object is not correctly aligned for vectorization. */
|
||||
Unaligned=0,
|
||||
/** Object is aligned for vectorization. */
|
||||
@@ -217,7 +217,7 @@ enum DirectionType {
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Enum to specify how to traverse the entries of a matrix. */
|
||||
enum {
|
||||
enum TraversalType {
|
||||
/** \internal Default traversal, no vectorization, no index-based access */
|
||||
DefaultTraversal,
|
||||
/** \internal No vectorization, use index-based access to have only one for loop instead of 2 nested loops */
|
||||
@@ -239,7 +239,7 @@ enum {
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Enum to specify whether to unroll loops when traversing over the entries of a matrix. */
|
||||
enum {
|
||||
enum UnrollingType {
|
||||
/** \internal Do not unroll loops. */
|
||||
NoUnrolling,
|
||||
/** \internal Unroll only the inner loop, but not the outer loop. */
|
||||
@@ -251,7 +251,7 @@ enum {
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Enum to specify whether to use the default (built-in) implementation or the specialization. */
|
||||
enum {
|
||||
enum SpecializedType {
|
||||
Specialized,
|
||||
BuiltIn
|
||||
};
|
||||
@@ -259,7 +259,7 @@ enum {
|
||||
/** \ingroup enums
|
||||
* Enum containing possible values for the \p _Options template parameter of
|
||||
* Matrix, Array and BandMatrix. */
|
||||
enum {
|
||||
enum StorageOptions {
|
||||
/** Storage order is column major (see \ref TopicStorageOrders). */
|
||||
ColMajor = 0,
|
||||
/** Storage order is row major (see \ref TopicStorageOrders). */
|
||||
@@ -272,7 +272,7 @@ enum {
|
||||
|
||||
/** \ingroup enums
|
||||
* Enum for specifying whether to apply or solve on the left or right. */
|
||||
enum {
|
||||
enum SideType {
|
||||
/** Apply transformation on the left. */
|
||||
OnTheLeft = 1,
|
||||
/** Apply transformation on the right. */
|
||||
@@ -418,7 +418,7 @@ namespace Architecture
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Enum used as template parameter in GeneralProduct. */
|
||||
enum { CoeffBasedProductMode, LazyCoeffBasedProductMode, OuterProduct, InnerProduct, GemvProduct, GemmProduct };
|
||||
enum ProductImplType { CoeffBasedProductMode, LazyCoeffBasedProductMode, OuterProduct, InnerProduct, GemvProduct, GemmProduct };
|
||||
|
||||
/** \internal \ingroup enums
|
||||
* Enum used in experimental parallel implementation. */
|
||||
|
||||
@@ -35,6 +35,14 @@
|
||||
#pragma clang diagnostic push
|
||||
#endif
|
||||
#pragma clang diagnostic ignored "-Wconstant-logical-operand"
|
||||
|
||||
#elif defined __GNUC__ && __GNUC__>=6
|
||||
|
||||
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#pragma GCC diagnostic ignored "-Wignored-attributes"
|
||||
|
||||
#endif
|
||||
|
||||
#endif // not EIGEN_WARNINGS_DISABLED
|
||||
|
||||
@@ -235,6 +235,9 @@ template<typename Scalar> class Rotation2D;
|
||||
template<typename Scalar> class AngleAxis;
|
||||
template<typename Scalar,int Dim> class Translation;
|
||||
|
||||
// Sparse module:
|
||||
template<typename Derived> class SparseMatrixBase;
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
template<typename Derived, int _Dim> class eigen2_RotationBase;
|
||||
template<typename Lhs, typename Rhs> class eigen2_Cross;
|
||||
|
||||
@@ -76,6 +76,38 @@
|
||||
#include <mkl_lapacke.h>
|
||||
#define EIGEN_MKL_VML_THRESHOLD 128
|
||||
|
||||
/* MKL_DOMAIN_BLAS, etc are defined only in 10.3 update 7 */
|
||||
/* MKL_BLAS, etc are not defined in 11.2 */
|
||||
#ifdef MKL_DOMAIN_ALL
|
||||
#define EIGEN_MKL_DOMAIN_ALL MKL_DOMAIN_ALL
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_ALL MKL_ALL
|
||||
#endif
|
||||
|
||||
#ifdef MKL_DOMAIN_BLAS
|
||||
#define EIGEN_MKL_DOMAIN_BLAS MKL_DOMAIN_BLAS
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_BLAS MKL_BLAS
|
||||
#endif
|
||||
|
||||
#ifdef MKL_DOMAIN_FFT
|
||||
#define EIGEN_MKL_DOMAIN_FFT MKL_DOMAIN_FFT
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_FFT MKL_FFT
|
||||
#endif
|
||||
|
||||
#ifdef MKL_DOMAIN_VML
|
||||
#define EIGEN_MKL_DOMAIN_VML MKL_DOMAIN_VML
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_VML MKL_VML
|
||||
#endif
|
||||
|
||||
#ifdef MKL_DOMAIN_PARDISO
|
||||
#define EIGEN_MKL_DOMAIN_PARDISO MKL_DOMAIN_PARDISO
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_PARDISO MKL_PARDISO
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
typedef std::complex<double> dcomplex;
|
||||
|
||||
@@ -13,23 +13,292 @@
|
||||
|
||||
#define EIGEN_WORLD_VERSION 3
|
||||
#define EIGEN_MAJOR_VERSION 2
|
||||
#define EIGEN_MINOR_VERSION 5
|
||||
#define EIGEN_MINOR_VERSION 9
|
||||
|
||||
#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))))
|
||||
|
||||
|
||||
// Compiler identification, EIGEN_COMP_*
|
||||
|
||||
/// \internal EIGEN_COMP_GNUC set to 1 for all compilers compatible with GCC
|
||||
#ifdef __GNUC__
|
||||
#define EIGEN_COMP_GNUC 1
|
||||
#else
|
||||
#define EIGEN_COMP_GNUC 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_CLANG set to 1 if the compiler is clang (alias for __clang__)
|
||||
#if defined(__clang__)
|
||||
#define EIGEN_COMP_CLANG 1
|
||||
#else
|
||||
#define EIGEN_COMP_CLANG 0
|
||||
#endif
|
||||
|
||||
|
||||
/// \internal EIGEN_COMP_LLVM set to 1 if the compiler backend is llvm
|
||||
#if defined(__llvm__)
|
||||
#define EIGEN_COMP_LLVM 1
|
||||
#else
|
||||
#define EIGEN_COMP_LLVM 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_ICC set to __INTEL_COMPILER if the compiler is Intel compiler, 0 otherwise
|
||||
#if defined(__INTEL_COMPILER)
|
||||
#define EIGEN_COMP_ICC __INTEL_COMPILER
|
||||
#else
|
||||
#define EIGEN_COMP_ICC 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_MINGW set to 1 if the compiler is mingw
|
||||
#if defined(__MINGW32__)
|
||||
#define EIGEN_COMP_MINGW 1
|
||||
#else
|
||||
#define EIGEN_COMP_MINGW 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_SUNCC set to 1 if the compiler is Solaris Studio
|
||||
#if defined(__SUNPRO_CC)
|
||||
#define EIGEN_COMP_SUNCC 1
|
||||
#else
|
||||
#define EIGEN_COMP_SUNCC 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_MSVC set to _MSC_VER if the compiler is Microsoft Visual C++, 0 otherwise.
|
||||
#if defined(_MSC_VER)
|
||||
#define EIGEN_COMP_MSVC _MSC_VER
|
||||
#else
|
||||
#define EIGEN_COMP_MSVC 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_MSVC_STRICT set to 1 if the compiler is really Microsoft Visual C++ and not ,e.g., ICC
|
||||
#if EIGEN_COMP_MSVC && !(EIGEN_COMP_ICC)
|
||||
#define EIGEN_COMP_MSVC_STRICT _MSC_VER
|
||||
#else
|
||||
#define EIGEN_COMP_MSVC_STRICT 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_IBM set to 1 if the compiler is IBM XL C++
|
||||
#if defined(__IBMCPP__) || defined(__xlc__)
|
||||
#define EIGEN_COMP_IBM 1
|
||||
#else
|
||||
#define EIGEN_COMP_IBM 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_PGI set to 1 if the compiler is Portland Group Compiler
|
||||
#if defined(__PGI)
|
||||
#define EIGEN_COMP_PGI 1
|
||||
#else
|
||||
#define EIGEN_COMP_PGI 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_COMP_ARM set to 1 if the compiler is ARM Compiler
|
||||
#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
|
||||
#define EIGEN_COMP_ARM 1
|
||||
#else
|
||||
#define EIGEN_COMP_ARM 0
|
||||
#endif
|
||||
|
||||
|
||||
/// \internal EIGEN_GNUC_STRICT set to 1 if the compiler is really GCC and not a compatible compiler (e.g., ICC, clang, mingw, etc.)
|
||||
#if EIGEN_COMP_GNUC && !(EIGEN_COMP_CLANG || EIGEN_COMP_ICC || EIGEN_COMP_MINGW || EIGEN_COMP_PGI || EIGEN_COMP_IBM || EIGEN_COMP_ARM )
|
||||
#define EIGEN_COMP_GNUC_STRICT 1
|
||||
#else
|
||||
#define EIGEN_COMP_GNUC_STRICT 0
|
||||
#endif
|
||||
|
||||
|
||||
#if EIGEN_COMP_GNUC
|
||||
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__==x && __GNUC_MINOR__>=y) || __GNUC__>x)
|
||||
#define EIGEN_GNUC_AT_MOST(x,y) ((__GNUC__==x && __GNUC_MINOR__<=y) || __GNUC__<x)
|
||||
#define EIGEN_GNUC_AT(x,y) ( __GNUC__==x && __GNUC_MINOR__==y )
|
||||
#else
|
||||
#define EIGEN_GNUC_AT_LEAST(x,y) 0
|
||||
#define EIGEN_GNUC_AT_MOST(x,y) 0
|
||||
#define EIGEN_GNUC_AT(x,y) 0
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define EIGEN_GNUC_AT_MOST(x,y) ((__GNUC__==x && __GNUC_MINOR__<=y) || __GNUC__<x)
|
||||
|
||||
// FIXME: could probably be removed as we do not support gcc 3.x anymore
|
||||
#if EIGEN_COMP_GNUC && (__GNUC__ <= 3)
|
||||
#define EIGEN_GCC3_OR_OLDER 1
|
||||
#else
|
||||
#define EIGEN_GNUC_AT_MOST(x,y) 0
|
||||
#define EIGEN_GCC3_OR_OLDER 0
|
||||
#endif
|
||||
|
||||
|
||||
// Architecture identification, EIGEN_ARCH_*
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64) || defined(__amd64)
|
||||
#define EIGEN_ARCH_x86_64 1
|
||||
#else
|
||||
#define EIGEN_ARCH_x86_64 0
|
||||
#endif
|
||||
|
||||
#if defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__i386)
|
||||
#define EIGEN_ARCH_i386 1
|
||||
#else
|
||||
#define EIGEN_ARCH_i386 0
|
||||
#endif
|
||||
|
||||
#if EIGEN_ARCH_x86_64 || EIGEN_ARCH_i386
|
||||
#define EIGEN_ARCH_i386_OR_x86_64 1
|
||||
#else
|
||||
#define EIGEN_ARCH_i386_OR_x86_64 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_ARCH_ARM set to 1 if the architecture is ARM
|
||||
#if defined(__arm__)
|
||||
#define EIGEN_ARCH_ARM 1
|
||||
#else
|
||||
#define EIGEN_ARCH_ARM 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_ARCH_ARM64 set to 1 if the architecture is ARM64
|
||||
#if defined(__aarch64__)
|
||||
#define EIGEN_ARCH_ARM64 1
|
||||
#else
|
||||
#define EIGEN_ARCH_ARM64 0
|
||||
#endif
|
||||
|
||||
#if EIGEN_ARCH_ARM || EIGEN_ARCH_ARM64
|
||||
#define EIGEN_ARCH_ARM_OR_ARM64 1
|
||||
#else
|
||||
#define EIGEN_ARCH_ARM_OR_ARM64 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_ARCH_MIPS set to 1 if the architecture is MIPS
|
||||
#if defined(__mips__) || defined(__mips)
|
||||
#define EIGEN_ARCH_MIPS 1
|
||||
#else
|
||||
#define EIGEN_ARCH_MIPS 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_ARCH_SPARC set to 1 if the architecture is SPARC
|
||||
#if defined(__sparc__) || defined(__sparc)
|
||||
#define EIGEN_ARCH_SPARC 1
|
||||
#else
|
||||
#define EIGEN_ARCH_SPARC 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_ARCH_IA64 set to 1 if the architecture is Intel Itanium
|
||||
#if defined(__ia64__)
|
||||
#define EIGEN_ARCH_IA64 1
|
||||
#else
|
||||
#define EIGEN_ARCH_IA64 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_ARCH_PPC set to 1 if the architecture is PowerPC
|
||||
#if defined(__powerpc__) || defined(__ppc__) || defined(_M_PPC)
|
||||
#define EIGEN_ARCH_PPC 1
|
||||
#else
|
||||
#define EIGEN_ARCH_PPC 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Operating system identification, EIGEN_OS_*
|
||||
|
||||
/// \internal EIGEN_OS_UNIX set to 1 if the OS is a unix variant
|
||||
#if defined(__unix__) || defined(__unix)
|
||||
#define EIGEN_OS_UNIX 1
|
||||
#else
|
||||
#define EIGEN_OS_UNIX 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_LINUX set to 1 if the OS is based on Linux kernel
|
||||
#if defined(__linux__)
|
||||
#define EIGEN_OS_LINUX 1
|
||||
#else
|
||||
#define EIGEN_OS_LINUX 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_ANDROID set to 1 if the OS is Android
|
||||
// note: ANDROID is defined when using ndk_build, __ANDROID__ is defined when using a standalone toolchain.
|
||||
#if defined(__ANDROID__) || defined(ANDROID)
|
||||
#define EIGEN_OS_ANDROID 1
|
||||
#else
|
||||
#define EIGEN_OS_ANDROID 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_GNULINUX set to 1 if the OS is GNU Linux and not Linux-based OS (e.g., not android)
|
||||
#if defined(__gnu_linux__) && !(EIGEN_OS_ANDROID)
|
||||
#define EIGEN_OS_GNULINUX 1
|
||||
#else
|
||||
#define EIGEN_OS_GNULINUX 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_BSD set to 1 if the OS is a BSD variant
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__)
|
||||
#define EIGEN_OS_BSD 1
|
||||
#else
|
||||
#define EIGEN_OS_BSD 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_MAC set to 1 if the OS is MacOS
|
||||
#if defined(__APPLE__)
|
||||
#define EIGEN_OS_MAC 1
|
||||
#else
|
||||
#define EIGEN_OS_MAC 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_QNX set to 1 if the OS is QNX
|
||||
#if defined(__QNX__)
|
||||
#define EIGEN_OS_QNX 1
|
||||
#else
|
||||
#define EIGEN_OS_QNX 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_WIN set to 1 if the OS is Windows based
|
||||
#if defined(_WIN32)
|
||||
#define EIGEN_OS_WIN 1
|
||||
#else
|
||||
#define EIGEN_OS_WIN 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_WIN64 set to 1 if the OS is Windows 64bits
|
||||
#if defined(_WIN64)
|
||||
#define EIGEN_OS_WIN64 1
|
||||
#else
|
||||
#define EIGEN_OS_WIN64 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_WINCE set to 1 if the OS is Windows CE
|
||||
#if defined(_WIN32_WCE)
|
||||
#define EIGEN_OS_WINCE 1
|
||||
#else
|
||||
#define EIGEN_OS_WINCE 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_CYGWIN set to 1 if the OS is Windows/Cygwin
|
||||
#if defined(__CYGWIN__)
|
||||
#define EIGEN_OS_CYGWIN 1
|
||||
#else
|
||||
#define EIGEN_OS_CYGWIN 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_WIN_STRICT set to 1 if the OS is really Windows and not some variants
|
||||
#if EIGEN_OS_WIN && !( EIGEN_OS_WINCE || EIGEN_OS_CYGWIN )
|
||||
#define EIGEN_OS_WIN_STRICT 1
|
||||
#else
|
||||
#define EIGEN_OS_WIN_STRICT 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_SUN set to 1 if the OS is SUN
|
||||
#if (defined(sun) || defined(__sun)) && !(defined(__SVR4) || defined(__svr4__))
|
||||
#define EIGEN_OS_SUN 1
|
||||
#else
|
||||
#define EIGEN_OS_SUN 0
|
||||
#endif
|
||||
|
||||
/// \internal EIGEN_OS_SOLARIS set to 1 if the OS is Solaris
|
||||
#if (defined(sun) || defined(__sun)) && (defined(__SVR4) || defined(__svr4__))
|
||||
#define EIGEN_OS_SOLARIS 1
|
||||
#else
|
||||
#define EIGEN_OS_SOLARIS 0
|
||||
#endif
|
||||
|
||||
|
||||
#if EIGEN_GNUC_AT_MOST(4,3) && !defined(__clang__)
|
||||
// see bug 89
|
||||
#define EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO 0
|
||||
@@ -37,12 +306,6 @@
|
||||
#define EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO 1
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ <= 3)
|
||||
#define EIGEN_GCC3_OR_OLDER 1
|
||||
#else
|
||||
#define EIGEN_GCC3_OR_OLDER 0
|
||||
#endif
|
||||
|
||||
// 16 byte alignment is only useful for vectorization. Since it affects the ABI, we need to enable
|
||||
// 16 byte alignment on all platforms where vectorization might be enabled. In theory we could always
|
||||
// enable alignment, but it can be a cause of problems on some platforms, so we just disable it in
|
||||
@@ -96,6 +359,20 @@
|
||||
#define EIGEN_DEFAULT_DENSE_INDEX_TYPE std::ptrdiff_t
|
||||
#endif
|
||||
|
||||
// A Clang feature extension to determine compiler features.
|
||||
// We use it to determine 'cxx_rvalue_references'
|
||||
#ifndef __has_feature
|
||||
# define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
// Do we support r-value references?
|
||||
#if (__has_feature(cxx_rvalue_references) || \
|
||||
(defined(__cplusplus) && __cplusplus >= 201103L) || \
|
||||
(defined(_MSC_VER) && _MSC_VER >= 1600))
|
||||
#define EIGEN_HAVE_RVALUE_REFERENCES
|
||||
#endif
|
||||
|
||||
|
||||
// Cross compiler wrapper around LLVM's __has_builtin
|
||||
#ifdef __has_builtin
|
||||
# define EIGEN_HAS_BUILTIN(x) __has_builtin(x)
|
||||
@@ -314,7 +591,7 @@ namespace Eigen {
|
||||
// just an empty macro !
|
||||
#define EIGEN_EMPTY
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1800) && (!defined(__INTEL_COMPILER))
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900) && (!defined(__INTEL_COMPILER))
|
||||
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
|
||||
using Base::operator =;
|
||||
#elif defined(__clang__) // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)
|
||||
@@ -409,6 +686,8 @@ namespace Eigen {
|
||||
#define EIGEN_SIZE_MAX(a,b) (((int)a == Dynamic || (int)b == Dynamic) ? Dynamic \
|
||||
: ((int)a >= (int)b) ? (int)a : (int)b)
|
||||
|
||||
#define EIGEN_ADD_COST(a,b) int(a)==Dynamic || int(b)==Dynamic ? Dynamic : int(a)+int(b)
|
||||
|
||||
#define EIGEN_LOGICAL_XOR(a,b) (((a) || (b)) && !((a) && (b)))
|
||||
|
||||
#define EIGEN_IMPLIES(a,b) (!(a) || (b))
|
||||
|
||||
@@ -507,7 +507,12 @@ template<typename T> void smart_copy(const T* start, const T* end, T* target)
|
||||
|
||||
template<typename T> struct smart_copy_helper<T,true> {
|
||||
static inline void run(const T* start, const T* end, T* target)
|
||||
{ memcpy(target, start, std::ptrdiff_t(end)-std::ptrdiff_t(start)); }
|
||||
{
|
||||
std::ptrdiff_t size = std::ptrdiff_t(end)-std::ptrdiff_t(start);
|
||||
if(size==0) return;
|
||||
eigen_internal_assert(start!=0 && end!=0 && target!=0);
|
||||
memcpy(target, start, size);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct smart_copy_helper<T,false> {
|
||||
@@ -515,7 +520,6 @@ template<typename T> struct smart_copy_helper<T,false> {
|
||||
{ std::copy(start, end, target); }
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*** Implementation of runtime stack allocation (falling back to malloc) ***
|
||||
*****************************************************************************/
|
||||
@@ -630,6 +634,8 @@ template<typename T> class aligned_stack_memory_handler
|
||||
} \
|
||||
void operator delete(void * ptr) throw() { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
|
||||
void operator delete[](void * ptr) throw() { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
|
||||
void operator delete(void * ptr, std::size_t /* sz */) throw() { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
|
||||
void operator delete[](void * ptr, std::size_t /* sz */) throw() { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
|
||||
/* in-place new and delete. since (at least afaik) there is no actual */ \
|
||||
/* memory allocated we can safely let the default implementation handle */ \
|
||||
/* this particular case. */ \
|
||||
@@ -653,99 +659,60 @@ template<typename T> class aligned_stack_memory_handler
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
/** \class aligned_allocator
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* \brief STL compatible allocator to use with with 16 byte aligned types
|
||||
*
|
||||
* Example:
|
||||
* \code
|
||||
* // Matrix4f requires 16 bytes alignment:
|
||||
* std::map< int, Matrix4f, std::less<int>,
|
||||
* aligned_allocator<std::pair<const int, Matrix4f> > > my_map_mat4;
|
||||
* // Vector3f does not require 16 bytes alignment, no need to use Eigen's allocator:
|
||||
* std::map< int, Vector3f > my_map_vec3;
|
||||
* \endcode
|
||||
*
|
||||
* \sa \ref TopicStlContainers.
|
||||
*/
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* \brief STL compatible allocator to use with with 16 byte aligned types
|
||||
*
|
||||
* Example:
|
||||
* \code
|
||||
* // Matrix4f requires 16 bytes alignment:
|
||||
* std::map< int, Matrix4f, std::less<int>,
|
||||
* aligned_allocator<std::pair<const int, Matrix4f> > > my_map_mat4;
|
||||
* // Vector3f does not require 16 bytes alignment, no need to use Eigen's allocator:
|
||||
* std::map< int, Vector3f > my_map_vec3;
|
||||
* \endcode
|
||||
*
|
||||
* \sa \blank \ref TopicStlContainers.
|
||||
*/
|
||||
template<class T>
|
||||
class aligned_allocator
|
||||
class aligned_allocator : public std::allocator<T>
|
||||
{
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T value_type;
|
||||
typedef size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T value_type;
|
||||
|
||||
template<class U>
|
||||
struct rebind
|
||||
{
|
||||
typedef aligned_allocator<U> other;
|
||||
};
|
||||
template<class U>
|
||||
struct rebind
|
||||
{
|
||||
typedef aligned_allocator<U> other;
|
||||
};
|
||||
|
||||
pointer address( reference value ) const
|
||||
{
|
||||
return &value;
|
||||
}
|
||||
aligned_allocator() : std::allocator<T>() {}
|
||||
|
||||
const_pointer address( const_reference value ) const
|
||||
{
|
||||
return &value;
|
||||
}
|
||||
aligned_allocator(const aligned_allocator& other) : std::allocator<T>(other) {}
|
||||
|
||||
aligned_allocator()
|
||||
{
|
||||
}
|
||||
template<class U>
|
||||
aligned_allocator(const aligned_allocator<U>& other) : std::allocator<T>(other) {}
|
||||
|
||||
aligned_allocator( const aligned_allocator& )
|
||||
{
|
||||
}
|
||||
~aligned_allocator() {}
|
||||
|
||||
template<class U>
|
||||
aligned_allocator( const aligned_allocator<U>& )
|
||||
{
|
||||
}
|
||||
pointer allocate(size_type num, const void* /*hint*/ = 0)
|
||||
{
|
||||
internal::check_size_for_overflow<T>(num);
|
||||
return static_cast<pointer>( internal::aligned_malloc(num * sizeof(T)) );
|
||||
}
|
||||
|
||||
~aligned_allocator()
|
||||
{
|
||||
}
|
||||
|
||||
size_type max_size() const
|
||||
{
|
||||
return (std::numeric_limits<size_type>::max)();
|
||||
}
|
||||
|
||||
pointer allocate( size_type num, const void* hint = 0 )
|
||||
{
|
||||
EIGEN_UNUSED_VARIABLE(hint);
|
||||
internal::check_size_for_overflow<T>(num);
|
||||
return static_cast<pointer>( internal::aligned_malloc( num * sizeof(T) ) );
|
||||
}
|
||||
|
||||
void construct( pointer p, const T& value )
|
||||
{
|
||||
::new( p ) T( value );
|
||||
}
|
||||
|
||||
void destroy( pointer p )
|
||||
{
|
||||
p->~T();
|
||||
}
|
||||
|
||||
void deallocate( pointer p, size_type /*num*/ )
|
||||
{
|
||||
internal::aligned_free( p );
|
||||
}
|
||||
|
||||
bool operator!=(const aligned_allocator<T>& ) const
|
||||
{ return false; }
|
||||
|
||||
bool operator==(const aligned_allocator<T>& ) const
|
||||
{ return true; }
|
||||
void deallocate(pointer p, size_type /*num*/)
|
||||
{
|
||||
internal::aligned_free(p);
|
||||
}
|
||||
};
|
||||
|
||||
//---------- Cache sizes ----------
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
#pragma warning pop
|
||||
#elif defined __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined __GNUC__ && __GNUC__>=6
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // EIGEN_WARNINGS_DISABLED
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#ifndef EIGEN_NO_STATIC_ASSERT
|
||||
|
||||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(_MSC_VER) && (_MSC_VER >= 1600))
|
||||
#if __has_feature(cxx_static_assert) || (defined(__cplusplus) && __cplusplus >= 201103L) || (EIGEN_COMP_MSVC >= 1600)
|
||||
|
||||
// if native static_assert is enabled, let's use it
|
||||
#define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
|
||||
|
||||
@@ -366,17 +366,17 @@ struct dense_xpr_base<Derived, ArrayXpr>
|
||||
|
||||
/** \internal Helper base class to add a scalar multiple operator
|
||||
* overloads for complex types */
|
||||
template<typename Derived,typename Scalar,typename OtherScalar,
|
||||
template<typename Derived, typename Scalar, typename OtherScalar, typename BaseType,
|
||||
bool EnableIt = !is_same<Scalar,OtherScalar>::value >
|
||||
struct special_scalar_op_base : public DenseCoeffsBase<Derived>
|
||||
struct special_scalar_op_base : public BaseType
|
||||
{
|
||||
// dummy operator* so that the
|
||||
// "using special_scalar_op_base::operator*" compiles
|
||||
void operator*() const;
|
||||
};
|
||||
|
||||
template<typename Derived,typename Scalar,typename OtherScalar>
|
||||
struct special_scalar_op_base<Derived,Scalar,OtherScalar,true> : public DenseCoeffsBase<Derived>
|
||||
template<typename Derived,typename Scalar,typename OtherScalar, typename BaseType>
|
||||
struct special_scalar_op_base<Derived,Scalar,OtherScalar,BaseType,true> : public BaseType
|
||||
{
|
||||
const CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, Derived>
|
||||
operator*(const OtherScalar& scalar) const
|
||||
|
||||
@@ -45,7 +45,6 @@ ComplexSchur<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >& \
|
||||
ComplexSchur<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >::compute(const Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW>& matrix, bool computeU) \
|
||||
{ \
|
||||
typedef Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> MatrixType; \
|
||||
typedef MatrixType::Scalar Scalar; \
|
||||
typedef MatrixType::RealScalar RealScalar; \
|
||||
typedef std::complex<RealScalar> ComplexScalar; \
|
||||
\
|
||||
|
||||
@@ -327,13 +327,33 @@ GeneralizedEigenSolver<MatrixType>::compute(const MatrixType& A, const MatrixTyp
|
||||
}
|
||||
else
|
||||
{
|
||||
Scalar p = Scalar(0.5) * (m_matS.coeff(i, i) - m_matS.coeff(i+1, i+1));
|
||||
Scalar z = sqrt(abs(p * p + m_matS.coeff(i+1, i) * m_matS.coeff(i, i+1)));
|
||||
m_alphas.coeffRef(i) = ComplexScalar(m_matS.coeff(i+1, i+1) + p, z);
|
||||
m_alphas.coeffRef(i+1) = ComplexScalar(m_matS.coeff(i+1, i+1) + p, -z);
|
||||
// We need to extract the generalized eigenvalues of the pair of a general 2x2 block S and a triangular 2x2 block T
|
||||
// From the eigen decomposition of T = U * E * U^-1,
|
||||
// we can extract the eigenvalues of (U^-1 * S * U) / E
|
||||
// Here, we can take advantage that E = diag(T), and U = [ 1 T_01 ; 0 T_11-T_00], and U^-1 = [1 -T_11/(T_11-T_00) ; 0 1/(T_11-T_00)].
|
||||
// Then taking beta=T_00*T_11*(T_11-T_00), we can avoid any division, and alpha is the eigenvalues of A = (U^-1 * S * U) * diag(T_11,T_00) * (T_11-T_00):
|
||||
|
||||
// T = [a b ; 0 c]
|
||||
// S = [e f ; g h]
|
||||
RealScalar a = m_realQZ.matrixT().coeff(i, i), b = m_realQZ.matrixT().coeff(i, i+1), c = m_realQZ.matrixT().coeff(i+1, i+1);
|
||||
RealScalar e = m_matS.coeff(i, i), f = m_matS.coeff(i, i+1), g = m_matS.coeff(i+1, i), h = m_matS.coeff(i+1, i+1);
|
||||
RealScalar d = c-a;
|
||||
RealScalar gb = g*b;
|
||||
Matrix<RealScalar,2,2> A;
|
||||
A << (e*d-gb)*c, ((e*b+f*d-h*b)*d-gb*b)*a,
|
||||
g*c , (gb+h*d)*a;
|
||||
|
||||
// NOTE, we could also compute the SVD of T's block during the QZ factorization so that the respective T block is guaranteed to be diagonal,
|
||||
// and then we could directly apply the formula below (while taking care of scaling S columns by T11,T00):
|
||||
|
||||
Scalar p = Scalar(0.5) * (A.coeff(i, i) - A.coeff(i+1, i+1));
|
||||
Scalar z = sqrt(abs(p * p + A.coeff(i+1, i) * A.coeff(i, i+1)));
|
||||
m_alphas.coeffRef(i) = ComplexScalar(A.coeff(i+1, i+1) + p, z);
|
||||
m_alphas.coeffRef(i+1) = ComplexScalar(A.coeff(i+1, i+1) + p, -z);
|
||||
|
||||
m_betas.coeffRef(i) =
|
||||
m_betas.coeffRef(i+1) = a*c*d;
|
||||
|
||||
m_betas.coeffRef(i) = m_realQZ.matrixT().coeff(i,i);
|
||||
m_betas.coeffRef(i+1) = m_realQZ.matrixT().coeff(i,i);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,10 +44,6 @@ template<> inline \
|
||||
RealSchur<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >& \
|
||||
RealSchur<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >::compute(const Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW>& matrix, bool computeU) \
|
||||
{ \
|
||||
typedef Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> MatrixType; \
|
||||
typedef MatrixType::Scalar Scalar; \
|
||||
typedef MatrixType::RealScalar RealScalar; \
|
||||
\
|
||||
eigen_assert(matrix.cols() == matrix.rows()); \
|
||||
\
|
||||
lapack_int n = matrix.cols(), sdim, info; \
|
||||
|
||||
@@ -80,6 +80,8 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
||||
/** \brief Scalar type for matrices of type \p _MatrixType. */
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
|
||||
typedef Matrix<Scalar,Size,Size,ColMajor,MaxColsAtCompileTime,MaxColsAtCompileTime> EigenvectorsType;
|
||||
|
||||
/** \brief Real scalar type for \p _MatrixType.
|
||||
*
|
||||
@@ -225,7 +227,7 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
||||
*
|
||||
* \sa eigenvalues()
|
||||
*/
|
||||
const MatrixType& eigenvectors() const
|
||||
const EigenvectorsType& eigenvectors() const
|
||||
{
|
||||
eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
|
||||
eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
|
||||
@@ -356,7 +358,7 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
}
|
||||
|
||||
MatrixType m_eivec;
|
||||
EigenvectorsType m_eivec;
|
||||
RealVectorType m_eivalues;
|
||||
typename TridiagonalizationType::SubDiagonalType m_subdiag;
|
||||
ComputationInfo m_info;
|
||||
@@ -381,7 +383,7 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
||||
* "implicit symmetric QR step with Wilkinson shift"
|
||||
*/
|
||||
namespace internal {
|
||||
template<int StorageOrder,typename RealScalar, typename Scalar, typename Index>
|
||||
template<typename RealScalar, typename Scalar, typename Index>
|
||||
static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n);
|
||||
}
|
||||
|
||||
@@ -413,7 +415,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
|
||||
|
||||
// declare some aliases
|
||||
RealVectorType& diag = m_eivalues;
|
||||
MatrixType& mat = m_eivec;
|
||||
EigenvectorsType& mat = m_eivec;
|
||||
|
||||
// map the matrix coefficients to [-1:1] to avoid over- and underflow.
|
||||
mat = matrix.template triangularView<Lower>();
|
||||
@@ -449,7 +451,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
|
||||
while (start>0 && m_subdiag[start-1]!=0)
|
||||
start--;
|
||||
|
||||
internal::tridiagonal_qr_step<MatrixType::Flags&RowMajorBit ? RowMajor : ColMajor>(diag.data(), m_subdiag.data(), start, end, computeEigenvectors ? m_eivec.data() : (Scalar*)0, n);
|
||||
internal::tridiagonal_qr_step(diag.data(), m_subdiag.data(), start, end, computeEigenvectors ? m_eivec.data() : (Scalar*)0, n);
|
||||
}
|
||||
|
||||
if (iter <= m_maxIterations * n)
|
||||
@@ -498,6 +500,7 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,3
|
||||
typedef typename SolverType::RealVectorType VectorType;
|
||||
typedef typename SolverType::Scalar Scalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
typedef typename SolverType::EigenvectorsType EigenvectorsType;
|
||||
|
||||
/** \internal
|
||||
* Computes the roots of the characteristic polynomial of \a m.
|
||||
@@ -570,7 +573,7 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,3
|
||||
&& "invalid option parameter");
|
||||
bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors;
|
||||
|
||||
MatrixType& eivecs = solver.m_eivec;
|
||||
EigenvectorsType& eivecs = solver.m_eivec;
|
||||
VectorType& eivals = solver.m_eivalues;
|
||||
|
||||
// Shift the matrix to the mean eigenvalue and map the matrix coefficients to [-1:1] to avoid over- and underflow.
|
||||
@@ -652,6 +655,7 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,2
|
||||
typedef typename SolverType::MatrixType MatrixType;
|
||||
typedef typename SolverType::RealVectorType VectorType;
|
||||
typedef typename SolverType::Scalar Scalar;
|
||||
typedef typename SolverType::EigenvectorsType EigenvectorsType;
|
||||
|
||||
static inline void computeRoots(const MatrixType& m, VectorType& roots)
|
||||
{
|
||||
@@ -673,7 +677,7 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,2
|
||||
&& "invalid option parameter");
|
||||
bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors;
|
||||
|
||||
MatrixType& eivecs = solver.m_eivec;
|
||||
EigenvectorsType& eivecs = solver.m_eivec;
|
||||
VectorType& eivals = solver.m_eivalues;
|
||||
|
||||
// map the matrix coefficients to [-1:1] to avoid over- and underflow.
|
||||
@@ -732,7 +736,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
template<int StorageOrder,typename RealScalar, typename Scalar, typename Index>
|
||||
template<typename RealScalar, typename Scalar, typename Index>
|
||||
static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n)
|
||||
{
|
||||
using std::abs;
|
||||
@@ -784,8 +788,7 @@ static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index sta
|
||||
// apply the givens rotation to the unit matrix Q = Q * G
|
||||
if (matrixQ)
|
||||
{
|
||||
// FIXME if StorageOrder == RowMajor this operation is not very efficient
|
||||
Map<Matrix<Scalar,Dynamic,Dynamic,StorageOrder> > q(matrixQ,n,n);
|
||||
Map<Matrix<Scalar,Dynamic,Dynamic,ColMajor> > q(matrixQ,n,n);
|
||||
q.applyOnTheRight(k,k+1,rot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,10 +367,10 @@ void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs)
|
||||
hCoeffs.tail(n-i-1).noalias() = (matA.bottomRightCorner(remainingSize,remainingSize).template selfadjointView<Lower>()
|
||||
* (conj(h) * matA.col(i).tail(remainingSize)));
|
||||
|
||||
hCoeffs.tail(n-i-1) += (conj(h)*Scalar(-0.5)*(hCoeffs.tail(remainingSize).dot(matA.col(i).tail(remainingSize)))) * matA.col(i).tail(n-i-1);
|
||||
hCoeffs.tail(n-i-1) += (conj(h)*RealScalar(-0.5)*(hCoeffs.tail(remainingSize).dot(matA.col(i).tail(remainingSize)))) * matA.col(i).tail(n-i-1);
|
||||
|
||||
matA.bottomRightCorner(remainingSize, remainingSize).template selfadjointView<Lower>()
|
||||
.rankUpdate(matA.col(i).tail(remainingSize), hCoeffs.tail(remainingSize), -1);
|
||||
.rankUpdate(matA.col(i).tail(remainingSize), hCoeffs.tail(remainingSize), Scalar(-1));
|
||||
|
||||
matA.col(i).coeffRef(i+1) = beta;
|
||||
hCoeffs.coeffRef(i) = h;
|
||||
|
||||
@@ -163,7 +163,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
|
||||
* a uniform distribution */
|
||||
inline VectorType sample() const
|
||||
{
|
||||
VectorType r;
|
||||
VectorType r(dim());
|
||||
for(Index d=0; d<dim(); ++d)
|
||||
{
|
||||
if(!ScalarTraits::IsInteger)
|
||||
|
||||
@@ -83,10 +83,17 @@ public:
|
||||
template<typename Derived>
|
||||
inline explicit AngleAxis(const MatrixBase<Derived>& m) { *this = m; }
|
||||
|
||||
/** \returns the value of the rotation angle in radian */
|
||||
Scalar angle() const { return m_angle; }
|
||||
/** \returns a read-write reference to the stored angle in radian */
|
||||
Scalar& angle() { return m_angle; }
|
||||
|
||||
/** \returns the rotation axis */
|
||||
const Vector3& axis() const { return m_axis; }
|
||||
/** \returns a read-write reference to the stored rotation axis.
|
||||
*
|
||||
* \warning The rotation axis must remain a \b unit vector.
|
||||
*/
|
||||
Vector3& axis() { return m_axis; }
|
||||
|
||||
/** Concatenates two rotations */
|
||||
@@ -131,7 +138,7 @@ public:
|
||||
m_angle = Scalar(other.angle());
|
||||
}
|
||||
|
||||
static inline const AngleAxis Identity() { return AngleAxis(0, Vector3::UnitX()); }
|
||||
static inline const AngleAxis Identity() { return AngleAxis(Scalar(0), Vector3::UnitX()); }
|
||||
|
||||
/** \returns \c true if \c *this is approximately equal to \a other, within the precision
|
||||
* determined by \a prec.
|
||||
@@ -165,8 +172,8 @@ AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived
|
||||
Scalar n2 = q.vec().squaredNorm();
|
||||
if (n2 < NumTraits<Scalar>::dummy_precision()*NumTraits<Scalar>::dummy_precision())
|
||||
{
|
||||
m_angle = 0;
|
||||
m_axis << 1, 0, 0;
|
||||
m_angle = Scalar(0);
|
||||
m_axis << Scalar(1), Scalar(0), Scalar(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -75,7 +75,7 @@ template<typename MatrixType,int _Direction> class Homogeneous
|
||||
inline Index rows() const { return m_matrix.rows() + (int(Direction)==Vertical ? 1 : 0); }
|
||||
inline Index cols() const { return m_matrix.cols() + (int(Direction)==Horizontal ? 1 : 0); }
|
||||
|
||||
inline Scalar coeff(Index row, Index col) const
|
||||
inline Scalar coeff(Index row, Index col=0) const
|
||||
{
|
||||
if( (int(Direction)==Vertical && row==m_matrix.rows())
|
||||
|| (int(Direction)==Horizontal && col==m_matrix.cols()))
|
||||
|
||||
@@ -129,7 +129,7 @@ public:
|
||||
* determined by \a prec.
|
||||
*
|
||||
* \sa MatrixBase::isApprox() */
|
||||
bool isApprox(const ParametrizedLine& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
|
||||
bool isApprox(const ParametrizedLine& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const
|
||||
{ return m_origin.isApprox(other.m_origin, prec) && m_direction.isApprox(other.m_direction, prec); }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -102,11 +102,11 @@ public:
|
||||
/** \returns a quaternion representing an identity rotation
|
||||
* \sa MatrixBase::Identity()
|
||||
*/
|
||||
static inline Quaternion<Scalar> Identity() { return Quaternion<Scalar>(1, 0, 0, 0); }
|
||||
static inline Quaternion<Scalar> Identity() { return Quaternion<Scalar>(Scalar(1), Scalar(0), Scalar(0), Scalar(0)); }
|
||||
|
||||
/** \sa QuaternionBase::Identity(), MatrixBase::setIdentity()
|
||||
*/
|
||||
inline QuaternionBase& setIdentity() { coeffs() << 0, 0, 0, 1; return *this; }
|
||||
inline QuaternionBase& setIdentity() { coeffs() << Scalar(0), Scalar(0), Scalar(0), Scalar(1); return *this; }
|
||||
|
||||
/** \returns the squared norm of the quaternion's coefficients
|
||||
* \sa QuaternionBase::norm(), MatrixBase::squaredNorm()
|
||||
@@ -276,7 +276,7 @@ public:
|
||||
inline Coefficients& coeffs() { return m_coeffs;}
|
||||
inline const Coefficients& coeffs() const { return m_coeffs;}
|
||||
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(IsAligned)
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(bool(IsAligned))
|
||||
|
||||
protected:
|
||||
Coefficients m_coeffs;
|
||||
|
||||
@@ -102,15 +102,15 @@ template<int Mode> struct transform_make_affine;
|
||||
*
|
||||
* However, unlike a plain matrix, the Transform class provides many features
|
||||
* simplifying both its assembly and usage. In particular, it can be composed
|
||||
* with any other transformations (Transform,Translation,RotationBase,Matrix)
|
||||
* with any other transformations (Transform,Translation,RotationBase,DiagonalMatrix)
|
||||
* and can be directly used to transform implicit homogeneous vectors. All these
|
||||
* operations are handled via the operator*. For the composition of transformations,
|
||||
* its principle consists to first convert the right/left hand sides of the product
|
||||
* to a compatible (Dim+1)^2 matrix and then perform a pure matrix product.
|
||||
* Of course, internally, operator* tries to perform the minimal number of operations
|
||||
* according to the nature of each terms. Likewise, when applying the transform
|
||||
* to non homogeneous vectors, the latters are automatically promoted to homogeneous
|
||||
* one before doing the matrix product. The convertions to homogeneous representations
|
||||
* to points, the latters are automatically promoted to homogeneous vectors
|
||||
* before doing the matrix product. The conventions to homogeneous representations
|
||||
* are performed as follow:
|
||||
*
|
||||
* \b Translation t (Dim)x(1):
|
||||
@@ -124,7 +124,7 @@ template<int Mode> struct transform_make_affine;
|
||||
* R & 0\\
|
||||
* 0\,...\,0 & 1
|
||||
* \end{array} \right) \f$
|
||||
*
|
||||
*<!--
|
||||
* \b Linear \b Matrix L (Dim)x(Dim):
|
||||
* \f$ \left( \begin{array}{cc}
|
||||
* L & 0\\
|
||||
@@ -136,14 +136,20 @@ template<int Mode> struct transform_make_affine;
|
||||
* A\\
|
||||
* 0\,...\,0\,1
|
||||
* \end{array} \right) \f$
|
||||
*-->
|
||||
* \b Scaling \b DiagonalMatrix S (Dim)x(Dim):
|
||||
* \f$ \left( \begin{array}{cc}
|
||||
* S & 0\\
|
||||
* 0\,...\,0 & 1
|
||||
* \end{array} \right) \f$
|
||||
*
|
||||
* \b Column \b vector v (Dim)x(1):
|
||||
* \b Column \b point v (Dim)x(1):
|
||||
* \f$ \left( \begin{array}{c}
|
||||
* v\\
|
||||
* 1
|
||||
* \end{array} \right) \f$
|
||||
*
|
||||
* \b Set \b of \b column \b vectors V1...Vn (Dim)x(n):
|
||||
* \b Set \b of \b column \b points V1...Vn (Dim)x(n):
|
||||
* \f$ \left( \begin{array}{ccc}
|
||||
* v_1 & ... & v_n\\
|
||||
* 1 & ... & 1
|
||||
@@ -384,26 +390,39 @@ public:
|
||||
/** \returns a writable expression of the translation vector of the transformation */
|
||||
inline TranslationPart translation() { return TranslationPart(m_matrix,0,Dim); }
|
||||
|
||||
/** \returns an expression of the product between the transform \c *this and a matrix expression \a other
|
||||
/** \returns an expression of the product between the transform \c *this and a matrix expression \a other.
|
||||
*
|
||||
* The right hand side \a other might be either:
|
||||
* \li a vector of size Dim,
|
||||
* The right-hand-side \a other can be either:
|
||||
* \li an homogeneous vector of size Dim+1,
|
||||
* \li a set of vectors of size Dim x Dynamic,
|
||||
* \li a set of homogeneous vectors of size Dim+1 x Dynamic,
|
||||
* \li a linear transformation matrix of size Dim x Dim,
|
||||
* \li an affine transformation matrix of size Dim x Dim+1,
|
||||
* \li a set of homogeneous vectors of size Dim+1 x N,
|
||||
* \li a transformation matrix of size Dim+1 x Dim+1.
|
||||
*
|
||||
* Moreover, if \c *this represents an affine transformation (i.e., Mode!=Projective), then \a other can also be:
|
||||
* \li a point of size Dim (computes: \code this->linear() * other + this->translation()\endcode),
|
||||
* \li a set of N points as a Dim x N matrix (computes: \code (this->linear() * other).colwise() + this->translation()\endcode),
|
||||
*
|
||||
* In all cases, the return type is a matrix or vector of same sizes as the right-hand-side \a other.
|
||||
*
|
||||
* If you want to interpret \a other as a linear or affine transformation, then first convert it to a Transform<> type,
|
||||
* or do your own cooking.
|
||||
*
|
||||
* Finally, if you want to apply Affine transformations to vectors, then explicitly apply the linear part only:
|
||||
* \code
|
||||
* Affine3f A;
|
||||
* Vector3f v1, v2;
|
||||
* v2 = A.linear() * v1;
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
// note: this function is defined here because some compilers cannot find the respective declaration
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE const typename internal::transform_right_product_impl<Transform, OtherDerived>::ResultType
|
||||
EIGEN_STRONG_INLINE const typename OtherDerived::PlainObject
|
||||
operator * (const EigenBase<OtherDerived> &other) const
|
||||
{ return internal::transform_right_product_impl<Transform, OtherDerived>::run(*this,other.derived()); }
|
||||
|
||||
/** \returns the product expression of a transformation matrix \a a times a transform \a b
|
||||
*
|
||||
* The left hand side \a other might be either:
|
||||
* The left hand side \a other can be either:
|
||||
* \li a linear transformation matrix of size Dim x Dim,
|
||||
* \li an affine transformation matrix of size Dim x Dim+1,
|
||||
* \li a general transformation matrix of size Dim+1 x Dim+1.
|
||||
|
||||
@@ -162,7 +162,7 @@ public:
|
||||
* determined by \a prec.
|
||||
*
|
||||
* \sa MatrixBase::isApprox() */
|
||||
bool isApprox(const Translation& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
|
||||
bool isApprox(const Translation& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const
|
||||
{ return m_coeffs.isApprox(other.m_coeffs, prec); }
|
||||
|
||||
};
|
||||
|
||||
@@ -75,8 +75,9 @@ void MatrixBase<Derived>::makeHouseholder(
|
||||
|
||||
RealScalar tailSqNorm = size()==1 ? RealScalar(0) : tail.squaredNorm();
|
||||
Scalar c0 = coeff(0);
|
||||
const RealScalar tol = (std::numeric_limits<RealScalar>::min)();
|
||||
|
||||
if(tailSqNorm == RealScalar(0) && numext::imag(c0)==RealScalar(0))
|
||||
if(tailSqNorm <= tol && numext::abs2(numext::imag(c0))<=tol)
|
||||
{
|
||||
tau = RealScalar(0);
|
||||
beta = numext::real(c0);
|
||||
|
||||
@@ -237,8 +237,9 @@ template<typename VectorsType, typename CoeffsType, int Side> class HouseholderS
|
||||
{
|
||||
workspace.resize(rows());
|
||||
Index vecs = m_length;
|
||||
const typename Dest::Scalar *dst_data = internal::extract_data(dst);
|
||||
if( internal::is_same<typename internal::remove_all<VectorsType>::type,Dest>::value
|
||||
&& internal::extract_data(dst) == internal::extract_data(m_vectors))
|
||||
&& dst_data!=0 && dst_data == internal::extract_data(m_vectors))
|
||||
{
|
||||
// in-place
|
||||
dst.diagonal().setOnes();
|
||||
|
||||
@@ -65,10 +65,10 @@ class DiagonalPreconditioner
|
||||
{
|
||||
typename MatType::InnerIterator it(mat,j);
|
||||
while(it && it.index()!=j) ++it;
|
||||
if(it && it.index()==j)
|
||||
if(it && it.index()==j && it.value()!=Scalar(0))
|
||||
m_invdiag(j) = Scalar(1)/it.value();
|
||||
else
|
||||
m_invdiag(j) = 0;
|
||||
m_invdiag(j) = Scalar(1);
|
||||
}
|
||||
m_isInitialized = true;
|
||||
return *this;
|
||||
|
||||
@@ -186,7 +186,8 @@ public:
|
||||
* this class becomes invalid. Call compute() to update it with the new
|
||||
* matrix A, or modify a copy of A.
|
||||
*/
|
||||
BiCGSTAB(const MatrixType& A) : Base(A) {}
|
||||
template<typename MatrixDerived>
|
||||
explicit BiCGSTAB(const EigenBase<MatrixDerived>& A) : Base(A.derived()) {}
|
||||
|
||||
~BiCGSTAB() {}
|
||||
|
||||
|
||||
@@ -139,6 +139,8 @@ struct traits<ConjugateGradient<_MatrixType,_UpLo,_Preconditioner> >
|
||||
* By default the iterations start with x=0 as an initial guess of the solution.
|
||||
* One can control the start using the solveWithGuess() method.
|
||||
*
|
||||
* ConjugateGradient can also be used in a matrix-free context, see the following \link MatrixfreeSolverExample example \endlink.
|
||||
*
|
||||
* \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner
|
||||
*/
|
||||
template< typename _MatrixType, int _UpLo, typename _Preconditioner>
|
||||
@@ -176,7 +178,8 @@ public:
|
||||
* this class becomes invalid. Call compute() to update it with the new
|
||||
* matrix A, or modify a copy of A.
|
||||
*/
|
||||
ConjugateGradient(const MatrixType& A) : Base(A) {}
|
||||
template<typename MatrixDerived>
|
||||
explicit ConjugateGradient(const EigenBase<MatrixDerived>& A) : Base(A.derived()) {}
|
||||
|
||||
~ConjugateGradient() {}
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ class IncompleteLUT : internal::noncopyable
|
||||
template<typename Rhs, typename Dest>
|
||||
void _solve(const Rhs& b, Dest& x) const
|
||||
{
|
||||
x = m_Pinv * b;
|
||||
x = m_Pinv * b;
|
||||
x = m_lu.template triangularView<UnitLower>().solve(x);
|
||||
x = m_lu.template triangularView<Upper>().solve(x);
|
||||
x = m_P * x;
|
||||
@@ -222,16 +222,25 @@ template<typename _MatrixType>
|
||||
void IncompleteLUT<Scalar>::analyzePattern(const _MatrixType& amat)
|
||||
{
|
||||
// Compute the Fill-reducing permutation
|
||||
// Since ILUT does not perform any numerical pivoting,
|
||||
// it is highly preferable to keep the diagonal through symmetric permutations.
|
||||
#ifndef EIGEN_MPL2_ONLY
|
||||
// To this end, let's symmetrize the pattern and perform AMD on it.
|
||||
SparseMatrix<Scalar,ColMajor, Index> mat1 = amat;
|
||||
SparseMatrix<Scalar,ColMajor, Index> mat2 = amat.transpose();
|
||||
// Symmetrize the pattern
|
||||
// FIXME for a matrix with nearly symmetric pattern, mat2+mat1 is the appropriate choice.
|
||||
// on the other hand for a really non-symmetric pattern, mat2*mat1 should be prefered...
|
||||
SparseMatrix<Scalar,ColMajor, Index> AtA = mat2 + mat1;
|
||||
AtA.prune(keep_diag());
|
||||
internal::minimum_degree_ordering<Scalar, Index>(AtA, m_P); // Then compute the AMD ordering...
|
||||
|
||||
m_Pinv = m_P.inverse(); // ... and the inverse permutation
|
||||
AMDOrdering<Index> ordering;
|
||||
ordering(AtA,m_P);
|
||||
m_Pinv = m_P.inverse(); // cache the inverse permutation
|
||||
#else
|
||||
// If AMD is not available, (MPL2-only), then let's use the slower COLAMD routine.
|
||||
SparseMatrix<Scalar,ColMajor, Index> mat1 = amat;
|
||||
COLAMDOrdering<Index> ordering;
|
||||
ordering(mat1,m_Pinv);
|
||||
m_P = m_Pinv.inverse();
|
||||
#endif
|
||||
|
||||
m_analysisIsOk = true;
|
||||
m_factorizationIsOk = false;
|
||||
|
||||
@@ -49,10 +49,11 @@ public:
|
||||
* this class becomes invalid. Call compute() to update it with the new
|
||||
* matrix A, or modify a copy of A.
|
||||
*/
|
||||
IterativeSolverBase(const MatrixType& A)
|
||||
template<typename InputDerived>
|
||||
IterativeSolverBase(const EigenBase<InputDerived>& A)
|
||||
{
|
||||
init();
|
||||
compute(A);
|
||||
compute(A.derived());
|
||||
}
|
||||
|
||||
~IterativeSolverBase() {}
|
||||
@@ -62,9 +63,11 @@ public:
|
||||
* Currently, this function mostly call analyzePattern on the preconditioner. In the future
|
||||
* we might, for instance, implement column reodering for faster matrix vector products.
|
||||
*/
|
||||
Derived& analyzePattern(const MatrixType& A)
|
||||
template<typename InputDerived>
|
||||
Derived& analyzePattern(const EigenBase<InputDerived>& A)
|
||||
{
|
||||
m_preconditioner.analyzePattern(A);
|
||||
grabInput(A.derived());
|
||||
m_preconditioner.analyzePattern(*mp_matrix);
|
||||
m_isInitialized = true;
|
||||
m_analysisIsOk = true;
|
||||
m_info = Success;
|
||||
@@ -80,11 +83,12 @@ public:
|
||||
* this class becomes invalid. Call compute() to update it with the new
|
||||
* matrix A, or modify a copy of A.
|
||||
*/
|
||||
Derived& factorize(const MatrixType& A)
|
||||
template<typename InputDerived>
|
||||
Derived& factorize(const EigenBase<InputDerived>& A)
|
||||
{
|
||||
grabInput(A.derived());
|
||||
eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
|
||||
mp_matrix = &A;
|
||||
m_preconditioner.factorize(A);
|
||||
m_preconditioner.factorize(*mp_matrix);
|
||||
m_factorizationIsOk = true;
|
||||
m_info = Success;
|
||||
return derived();
|
||||
@@ -100,10 +104,11 @@ public:
|
||||
* this class becomes invalid. Call compute() to update it with the new
|
||||
* matrix A, or modify a copy of A.
|
||||
*/
|
||||
Derived& compute(const MatrixType& A)
|
||||
template<typename InputDerived>
|
||||
Derived& compute(const EigenBase<InputDerived>& A)
|
||||
{
|
||||
mp_matrix = &A;
|
||||
m_preconditioner.compute(A);
|
||||
grabInput(A.derived());
|
||||
m_preconditioner.compute(*mp_matrix);
|
||||
m_isInitialized = true;
|
||||
m_analysisIsOk = true;
|
||||
m_factorizationIsOk = true;
|
||||
@@ -212,6 +217,28 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
template<typename InputDerived>
|
||||
void grabInput(const EigenBase<InputDerived>& A)
|
||||
{
|
||||
// we const cast to prevent the creation of a MatrixType temporary by the compiler.
|
||||
grabInput_impl(A.const_cast_derived());
|
||||
}
|
||||
|
||||
template<typename InputDerived>
|
||||
void grabInput_impl(const EigenBase<InputDerived>& A)
|
||||
{
|
||||
m_copyMatrix = A;
|
||||
mp_matrix = &m_copyMatrix;
|
||||
}
|
||||
|
||||
void grabInput_impl(MatrixType& A)
|
||||
{
|
||||
if(MatrixType::RowsAtCompileTime==Dynamic && MatrixType::ColsAtCompileTime==Dynamic)
|
||||
m_copyMatrix.resize(0,0);
|
||||
mp_matrix = &A;
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
m_isInitialized = false;
|
||||
@@ -220,6 +247,7 @@ protected:
|
||||
m_maxIterations = -1;
|
||||
m_tolerance = NumTraits<Scalar>::epsilon();
|
||||
}
|
||||
MatrixType m_copyMatrix;
|
||||
const MatrixType* mp_matrix;
|
||||
Preconditioner m_preconditioner;
|
||||
|
||||
|
||||
@@ -688,7 +688,7 @@ struct solve_retval<FullPivLU<_MatrixType>, Rhs>
|
||||
*/
|
||||
|
||||
const Index rows = dec().rows(), cols = dec().cols(),
|
||||
nonzero_pivots = dec().nonzeroPivots();
|
||||
nonzero_pivots = dec().rank();
|
||||
eigen_assert(rhs().rows() == rows);
|
||||
const Index smalldim = (std::min)(rows, cols);
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ struct inverse_impl : public ReturnByValue<inverse_impl<MatrixType> >
|
||||
{
|
||||
const int Size = EIGEN_PLAIN_ENUM_MIN(MatrixType::ColsAtCompileTime,Dest::ColsAtCompileTime);
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(Size);
|
||||
eigen_assert(( (Size<=1) || (Size>4) || (extract_data(m_matrix)!=extract_data(dst)))
|
||||
eigen_assert(( (Size<=1) || (Size>4) || (extract_data(m_matrix)!=0 && extract_data(m_matrix)!=extract_data(dst)))
|
||||
&& "Aliasing problem detected in inverse(), you need to do inverse().eval() here.");
|
||||
|
||||
compute_inverse<MatrixTypeNestedCleaned, Dest>::run(m_matrix, dst);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
NOTE: this routine has been adapted from the CSparse library:
|
||||
|
||||
Copyright (c) 2006, Timothy A. Davis.
|
||||
http://www.cise.ufl.edu/research/sparse/CSparse
|
||||
http://www.suitesparse.com
|
||||
|
||||
CSparse is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
@@ -137,9 +137,6 @@ void minimum_degree_ordering(SparseMatrix<Scalar,ColMajor,Index>& C, Permutation
|
||||
degree[i] = len[i]; // degree of node i
|
||||
}
|
||||
mark = internal::cs_wclear<Index>(0, 0, w, n); /* clear w */
|
||||
elen[n] = -2; /* n is a dead element */
|
||||
Cp[n] = -1; /* n is a root of assembly tree */
|
||||
w[n] = 0; /* n is a dead element */
|
||||
|
||||
/* --- Initialize degree lists ------------------------------------------ */
|
||||
for(i = 0; i < n; i++)
|
||||
@@ -153,7 +150,7 @@ void minimum_degree_ordering(SparseMatrix<Scalar,ColMajor,Index>& C, Permutation
|
||||
}
|
||||
|
||||
d = degree[i];
|
||||
if(d == 1) /* node i is empty */
|
||||
if(d == 1 && has_diag) /* node i is empty */
|
||||
{
|
||||
elen[i] = -2; /* element i is dead */
|
||||
nel++;
|
||||
|
||||
@@ -41,12 +41,8 @@
|
||||
//
|
||||
// The colamd/symamd library is available at
|
||||
//
|
||||
// http://www.cise.ufl.edu/research/sparse/colamd/
|
||||
// http://www.suitesparse.com
|
||||
|
||||
// This is the http://www.cise.ufl.edu/research/sparse/colamd/colamd.h
|
||||
// file. It is required by the colamd.c, colamdmex.c, and symamdmex.c
|
||||
// files, and by any C code that calls the routines whose prototypes are
|
||||
// listed below, or that uses the colamd/symamd definitions listed below.
|
||||
|
||||
#ifndef EIGEN_COLAMD_H
|
||||
#define EIGEN_COLAMD_H
|
||||
@@ -102,9 +98,6 @@ namespace internal {
|
||||
/* === Definitions ========================================================== */
|
||||
/* ========================================================================== */
|
||||
|
||||
#define COLAMD_MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#define COLAMD_MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#define ONES_COMPLEMENT(r) (-(r)-1)
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@@ -516,7 +509,7 @@ static Index init_rows_cols /* returns true if OK, or false otherwise */
|
||||
Col [col].start = p [col] ;
|
||||
Col [col].length = p [col+1] - p [col] ;
|
||||
|
||||
if (Col [col].length < 0)
|
||||
if ((Col [col].length) < 0) // extra parentheses to work-around gcc bug 10200
|
||||
{
|
||||
/* column pointers must be non-decreasing */
|
||||
stats [COLAMD_STATUS] = COLAMD_ERROR_col_length_negative ;
|
||||
@@ -739,8 +732,8 @@ static void init_scoring
|
||||
|
||||
/* === Extract knobs ==================================================== */
|
||||
|
||||
dense_row_count = COLAMD_MAX (0, COLAMD_MIN (knobs [COLAMD_DENSE_ROW] * n_col, n_col)) ;
|
||||
dense_col_count = COLAMD_MAX (0, COLAMD_MIN (knobs [COLAMD_DENSE_COL] * n_row, n_row)) ;
|
||||
dense_row_count = std::max<Index>(0, (std::min)(Index(knobs [COLAMD_DENSE_ROW] * n_col), n_col)) ;
|
||||
dense_col_count = std::max<Index>(0, (std::min)(Index(knobs [COLAMD_DENSE_COL] * n_row), n_row)) ;
|
||||
COLAMD_DEBUG1 (("colamd: densecount: %d %d\n", dense_row_count, dense_col_count)) ;
|
||||
max_deg = 0 ;
|
||||
n_col2 = n_col ;
|
||||
@@ -804,7 +797,7 @@ static void init_scoring
|
||||
else
|
||||
{
|
||||
/* keep track of max degree of remaining rows */
|
||||
max_deg = COLAMD_MAX (max_deg, deg) ;
|
||||
max_deg = (std::max)(max_deg, deg) ;
|
||||
}
|
||||
}
|
||||
COLAMD_DEBUG1 (("colamd: Dense and null rows killed: %d\n", n_row - n_row2)) ;
|
||||
@@ -842,7 +835,7 @@ static void init_scoring
|
||||
/* add row's external degree */
|
||||
score += Row [row].shared1.degree - 1 ;
|
||||
/* guard against integer overflow */
|
||||
score = COLAMD_MIN (score, n_col) ;
|
||||
score = (std::min)(score, n_col) ;
|
||||
}
|
||||
/* determine pruned column length */
|
||||
col_length = (Index) (new_cp - &A [Col [c].start]) ;
|
||||
@@ -914,7 +907,7 @@ static void init_scoring
|
||||
head [score] = c ;
|
||||
|
||||
/* see if this score is less than current min */
|
||||
min_score = COLAMD_MIN (min_score, score) ;
|
||||
min_score = (std::min)(min_score, score) ;
|
||||
|
||||
|
||||
}
|
||||
@@ -1040,7 +1033,7 @@ static Index find_ordering /* return the number of garbage collections */
|
||||
|
||||
/* === Garbage_collection, if necessary ============================= */
|
||||
|
||||
needed_memory = COLAMD_MIN (pivot_col_score, n_col - k) ;
|
||||
needed_memory = (std::min)(pivot_col_score, n_col - k) ;
|
||||
if (pfree + needed_memory >= Alen)
|
||||
{
|
||||
pfree = Eigen::internal::garbage_collection (n_row, n_col, Row, Col, A, &A [pfree]) ;
|
||||
@@ -1099,7 +1092,7 @@ static Index find_ordering /* return the number of garbage collections */
|
||||
|
||||
/* clear tag on pivot column */
|
||||
Col [pivot_col].shared1.thickness = pivot_col_thickness ;
|
||||
max_deg = COLAMD_MAX (max_deg, pivot_row_degree) ;
|
||||
max_deg = (std::max)(max_deg, pivot_row_degree) ;
|
||||
|
||||
|
||||
/* === Kill all rows used to construct pivot row ==================== */
|
||||
@@ -1273,7 +1266,7 @@ static Index find_ordering /* return the number of garbage collections */
|
||||
/* add set difference */
|
||||
cur_score += row_mark - tag_mark ;
|
||||
/* integer overflow... */
|
||||
cur_score = COLAMD_MIN (cur_score, n_col) ;
|
||||
cur_score = (std::min)(cur_score, n_col) ;
|
||||
}
|
||||
|
||||
/* recompute the column's length */
|
||||
@@ -1386,7 +1379,7 @@ static Index find_ordering /* return the number of garbage collections */
|
||||
cur_score -= Col [col].shared1.thickness ;
|
||||
|
||||
/* make sure score is less or equal than the max score */
|
||||
cur_score = COLAMD_MIN (cur_score, max_score) ;
|
||||
cur_score = (std::min)(cur_score, max_score) ;
|
||||
COLAMD_ASSERT (cur_score >= 0) ;
|
||||
|
||||
/* store updated score */
|
||||
@@ -1409,7 +1402,7 @@ static Index find_ordering /* return the number of garbage collections */
|
||||
head [cur_score] = col ;
|
||||
|
||||
/* see if this score is less than current min */
|
||||
min_score = COLAMD_MIN (min_score, cur_score) ;
|
||||
min_score = (std::min)(min_score, cur_score) ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,14 @@
|
||||
#ifndef EIGEN_PASTIXSUPPORT_H
|
||||
#define EIGEN_PASTIXSUPPORT_H
|
||||
|
||||
#if defined(DCOMPLEX)
|
||||
#define PASTIX_COMPLEX COMPLEX
|
||||
#define PASTIX_DCOMPLEX DCOMPLEX
|
||||
#else
|
||||
#define PASTIX_COMPLEX std::complex<float>
|
||||
#define PASTIX_DCOMPLEX std::complex<double>
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \ingroup PaStiXSupport_Module
|
||||
@@ -74,14 +82,14 @@ namespace internal
|
||||
{
|
||||
if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; }
|
||||
if (nbrhs == 0) {x = NULL; nbrhs=1;}
|
||||
c_pastix(pastix_data, pastix_comm, n, ptr, idx, reinterpret_cast<COMPLEX*>(vals), perm, invp, reinterpret_cast<COMPLEX*>(x), nbrhs, iparm, dparm);
|
||||
c_pastix(pastix_data, pastix_comm, n, ptr, idx, reinterpret_cast<PASTIX_COMPLEX*>(vals), perm, invp, reinterpret_cast<PASTIX_COMPLEX*>(x), nbrhs, iparm, dparm);
|
||||
}
|
||||
|
||||
void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, std::complex<double> *vals, int *perm, int * invp, std::complex<double> *x, int nbrhs, int *iparm, double *dparm)
|
||||
{
|
||||
if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; }
|
||||
if (nbrhs == 0) {x = NULL; nbrhs=1;}
|
||||
z_pastix(pastix_data, pastix_comm, n, ptr, idx, reinterpret_cast<DCOMPLEX*>(vals), perm, invp, reinterpret_cast<DCOMPLEX*>(x), nbrhs, iparm, dparm);
|
||||
z_pastix(pastix_data, pastix_comm, n, ptr, idx, reinterpret_cast<PASTIX_DCOMPLEX*>(vals), perm, invp, reinterpret_cast<PASTIX_DCOMPLEX*>(x), nbrhs, iparm, dparm);
|
||||
}
|
||||
|
||||
// Convert the matrix to Fortran-style Numbering
|
||||
|
||||
@@ -221,11 +221,11 @@ class PardisoImpl
|
||||
m_type = type;
|
||||
bool symmetric = std::abs(m_type) < 10;
|
||||
m_iparm[0] = 1; // No solver default
|
||||
m_iparm[1] = 3; // use Metis for the ordering
|
||||
m_iparm[2] = 1; // Numbers of processors, value of OMP_NUM_THREADS
|
||||
m_iparm[1] = 2; // use Metis for the ordering
|
||||
m_iparm[2] = 0; // Reserved. Set to zero. (??Numbers of processors, value of OMP_NUM_THREADS??)
|
||||
m_iparm[3] = 0; // No iterative-direct algorithm
|
||||
m_iparm[4] = 0; // No user fill-in reducing permutation
|
||||
m_iparm[5] = 0; // Write solution into x
|
||||
m_iparm[5] = 0; // Write solution into x, b is left unchanged
|
||||
m_iparm[6] = 0; // Not in use
|
||||
m_iparm[7] = 2; // Max numbers of iterative refinement steps
|
||||
m_iparm[8] = 0; // Not in use
|
||||
@@ -246,7 +246,10 @@ class PardisoImpl
|
||||
m_iparm[26] = 0; // No matrix checker
|
||||
m_iparm[27] = (sizeof(RealScalar) == 4) ? 1 : 0;
|
||||
m_iparm[34] = 1; // C indexing
|
||||
m_iparm[59] = 1; // Automatic switch between In-Core and Out-of-Core modes
|
||||
m_iparm[36] = 0; // CSR
|
||||
m_iparm[59] = 0; // 0 - In-Core ; 1 - Automatic switch between In-Core and Out-of-Core modes ; 2 - Out-of-Core
|
||||
|
||||
memset(m_pt, 0, sizeof(m_pt));
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -384,7 +387,6 @@ bool PardisoImpl<Base>::_solve(const MatrixBase<BDerived> &b, MatrixBase<XDerive
|
||||
m_matrix.valuePtr(), m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(),
|
||||
m_perm.data(), nrhs, m_iparm.data(), m_msglvl,
|
||||
rhs_ptr, x.derived().data());
|
||||
|
||||
return error==0;
|
||||
}
|
||||
|
||||
@@ -397,6 +399,9 @@ bool PardisoImpl<Base>::_solve(const MatrixBase<BDerived> &b, MatrixBase<XDerive
|
||||
* using the Intel MKL PARDISO library. The sparse matrix A must be squared and invertible.
|
||||
* The vectors or matrices X and B can be either dense or sparse.
|
||||
*
|
||||
* By default, it runs in in-core mode. To enable PARDISO's out-of-core feature, set:
|
||||
* \code solver.pardisoParameterArray()[59] = 1; \endcode
|
||||
*
|
||||
* \tparam _MatrixType the type of the sparse matrix A, it must be a SparseMatrix<>
|
||||
*
|
||||
* \sa \ref TutorialSparseDirectSolvers
|
||||
@@ -447,6 +452,9 @@ class PardisoLU : public PardisoImpl< PardisoLU<MatrixType> >
|
||||
* using the Intel MKL PARDISO library. The sparse matrix A must be selfajoint and positive definite.
|
||||
* The vectors or matrices X and B can be either dense or sparse.
|
||||
*
|
||||
* By default, it runs in in-core mode. To enable PARDISO's out-of-core feature, set:
|
||||
* \code solver.pardisoParameterArray()[59] = 1; \endcode
|
||||
*
|
||||
* \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<>
|
||||
* \tparam UpLo can be any bitwise combination of Upper, Lower. The default is Upper, meaning only the upper triangular part has to be used.
|
||||
* Upper|Lower can be used to tell both triangular parts can be used as input.
|
||||
@@ -507,6 +515,9 @@ class PardisoLLT : public PardisoImpl< PardisoLLT<MatrixType,_UpLo> >
|
||||
* For complex matrices, A can also be symmetric only, see the \a Options template parameter.
|
||||
* The vectors or matrices X and B can be either dense or sparse.
|
||||
*
|
||||
* By default, it runs in in-core mode. To enable PARDISO's out-of-core feature, set:
|
||||
* \code solver.pardisoParameterArray()[59] = 1; \endcode
|
||||
*
|
||||
* \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<>
|
||||
* \tparam Options can be any bitwise combination of Upper, Lower, and Symmetric. The default is Upper, meaning only the upper triangular part has to be used.
|
||||
* Symmetric can be used for symmetric, non-selfadjoint complex matrices, the default being to assume a selfadjoint matrix.
|
||||
|
||||
@@ -49,7 +49,6 @@ ColPivHouseholderQR<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynami
|
||||
{ \
|
||||
using std::abs; \
|
||||
typedef Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic> MatrixType; \
|
||||
typedef MatrixType::Scalar Scalar; \
|
||||
typedef MatrixType::RealScalar RealScalar; \
|
||||
Index rows = matrix.rows();\
|
||||
Index cols = matrix.cols();\
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Eigen {
|
||||
* You can then apply it to a vector.
|
||||
*
|
||||
* R is the sparse triangular factor. Use matrixQR() to get it as SparseMatrix.
|
||||
* NOTE : The Index type of R is always UF_long. You can get it with SPQR::Index
|
||||
* NOTE : The Index type of R is always SuiteSparse_long. You can get it with SPQR::Index
|
||||
*
|
||||
* \tparam _MatrixType The type of the sparse matrix A, must be a column-major SparseMatrix<>
|
||||
* NOTE
|
||||
@@ -59,7 +59,7 @@ class SPQR
|
||||
public:
|
||||
typedef typename _MatrixType::Scalar Scalar;
|
||||
typedef typename _MatrixType::RealScalar RealScalar;
|
||||
typedef UF_long Index ;
|
||||
typedef SuiteSparse_long Index ;
|
||||
typedef SparseMatrix<Scalar, ColMajor, Index> MatrixType;
|
||||
typedef PermutationMatrix<Dynamic, Dynamic> PermutationType;
|
||||
public:
|
||||
|
||||
@@ -359,29 +359,42 @@ struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, false
|
||||
{
|
||||
typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
|
||||
typedef typename SVD::Index Index;
|
||||
static void run(typename SVD::WorkMatrixType&, SVD&, Index, Index) {}
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
static bool run(typename SVD::WorkMatrixType&, SVD&, Index, Index, RealScalar&) { return true; }
|
||||
};
|
||||
|
||||
template<typename MatrixType, int QRPreconditioner>
|
||||
struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, true>
|
||||
{
|
||||
typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
|
||||
typedef typename SVD::Index Index;
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::RealScalar RealScalar;
|
||||
typedef typename SVD::Index Index;
|
||||
static void run(typename SVD::WorkMatrixType& work_matrix, SVD& svd, Index p, Index q)
|
||||
static bool run(typename SVD::WorkMatrixType& work_matrix, SVD& svd, Index p, Index q, RealScalar& maxDiagEntry)
|
||||
{
|
||||
using std::sqrt;
|
||||
using std::abs;
|
||||
using std::max;
|
||||
Scalar z;
|
||||
JacobiRotation<Scalar> rot;
|
||||
RealScalar n = sqrt(numext::abs2(work_matrix.coeff(p,p)) + numext::abs2(work_matrix.coeff(q,p)));
|
||||
|
||||
|
||||
const RealScalar considerAsZero = (std::numeric_limits<RealScalar>::min)();
|
||||
const RealScalar precision = NumTraits<Scalar>::epsilon();
|
||||
|
||||
if(n==0)
|
||||
{
|
||||
z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
|
||||
work_matrix.row(p) *= z;
|
||||
if(svd.computeU()) svd.m_matrixU.col(p) *= conj(z);
|
||||
if(work_matrix.coeff(q,q)!=Scalar(0))
|
||||
// make sure first column is zero
|
||||
work_matrix.coeffRef(p,p) = work_matrix.coeffRef(q,p) = Scalar(0);
|
||||
|
||||
if(abs(numext::imag(work_matrix.coeff(p,q)))>considerAsZero)
|
||||
{
|
||||
// work_matrix.coeff(p,q) can be zero if work_matrix.coeff(q,p) is not zero but small enough to underflow when computing n
|
||||
z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
|
||||
work_matrix.row(p) *= z;
|
||||
if(svd.computeU()) svd.m_matrixU.col(p) *= conj(z);
|
||||
}
|
||||
if(abs(numext::imag(work_matrix.coeff(q,q)))>considerAsZero)
|
||||
{
|
||||
z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
|
||||
work_matrix.row(q) *= z;
|
||||
@@ -395,19 +408,25 @@ struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, true>
|
||||
rot.s() = work_matrix.coeff(q,p) / n;
|
||||
work_matrix.applyOnTheLeft(p,q,rot);
|
||||
if(svd.computeU()) svd.m_matrixU.applyOnTheRight(p,q,rot.adjoint());
|
||||
if(work_matrix.coeff(p,q) != Scalar(0))
|
||||
if(abs(numext::imag(work_matrix.coeff(p,q)))>considerAsZero)
|
||||
{
|
||||
Scalar z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
|
||||
z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
|
||||
work_matrix.col(q) *= z;
|
||||
if(svd.computeV()) svd.m_matrixV.col(q) *= z;
|
||||
}
|
||||
if(work_matrix.coeff(q,q) != Scalar(0))
|
||||
if(abs(numext::imag(work_matrix.coeff(q,q)))>considerAsZero)
|
||||
{
|
||||
z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
|
||||
work_matrix.row(q) *= z;
|
||||
if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z);
|
||||
}
|
||||
}
|
||||
|
||||
// update largest diagonal entry
|
||||
maxDiagEntry = max EIGEN_EMPTY (maxDiagEntry,max EIGEN_EMPTY (abs(work_matrix.coeff(p,p)), abs(work_matrix.coeff(q,q))));
|
||||
// and check whether the 2x2 block is already diagonal
|
||||
RealScalar threshold = max EIGEN_EMPTY (considerAsZero, precision * maxDiagEntry);
|
||||
return abs(work_matrix.coeff(p,q))>threshold || abs(work_matrix.coeff(q,p)) > threshold;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -424,22 +443,23 @@ void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q,
|
||||
JacobiRotation<RealScalar> rot1;
|
||||
RealScalar t = m.coeff(0,0) + m.coeff(1,1);
|
||||
RealScalar d = m.coeff(1,0) - m.coeff(0,1);
|
||||
if(t == RealScalar(0))
|
||||
if(d == RealScalar(0))
|
||||
{
|
||||
rot1.c() = RealScalar(0);
|
||||
rot1.s() = d > RealScalar(0) ? RealScalar(1) : RealScalar(-1);
|
||||
rot1.s() = RealScalar(0);
|
||||
rot1.c() = RealScalar(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
RealScalar t2d2 = numext::hypot(t,d);
|
||||
rot1.c() = abs(t)/t2d2;
|
||||
rot1.s() = d/t2d2;
|
||||
if(t<RealScalar(0))
|
||||
rot1.s() = -rot1.s();
|
||||
// If d!=0, then t/d cannot overflow because the magnitude of the
|
||||
// entries forming d are not too small compared to the ones forming t.
|
||||
RealScalar u = t / d;
|
||||
RealScalar tmp = sqrt(RealScalar(1) + numext::abs2(u));
|
||||
rot1.s() = RealScalar(1) / tmp;
|
||||
rot1.c() = u / tmp;
|
||||
}
|
||||
m.applyOnTheLeft(0,1,rot1);
|
||||
j_right->makeJacobi(m,0,1);
|
||||
*j_left = rot1 * j_right->transpose();
|
||||
*j_left = rot1 * j_right->transpose();
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
@@ -816,7 +836,7 @@ void JacobiSVD<MatrixType, QRPreconditioner>::allocate(Index rows, Index cols, u
|
||||
|
||||
if(m_cols>m_rows) m_qr_precond_morecols.allocate(*this);
|
||||
if(m_rows>m_cols) m_qr_precond_morerows.allocate(*this);
|
||||
if(m_cols!=m_cols) m_scaledMatrix.resize(rows,cols);
|
||||
if(m_rows!=m_cols) m_scaledMatrix.resize(rows,cols);
|
||||
}
|
||||
|
||||
template<typename MatrixType, int QRPreconditioner>
|
||||
@@ -826,6 +846,7 @@ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsig
|
||||
check_template_parameters();
|
||||
|
||||
using std::abs;
|
||||
using std::max;
|
||||
allocate(matrix.rows(), matrix.cols(), computationOptions);
|
||||
|
||||
// currently we stop when we reach precision 2*epsilon as the last bit of precision can require an unreasonable number of iterations,
|
||||
@@ -857,6 +878,7 @@ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsig
|
||||
}
|
||||
|
||||
/*** step 2. The main Jacobi SVD iteration. ***/
|
||||
RealScalar maxDiagEntry = m_workMatrix.cwiseAbs().diagonal().maxCoeff();
|
||||
|
||||
bool finished = false;
|
||||
while(!finished)
|
||||
@@ -872,25 +894,27 @@ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsig
|
||||
// if this 2x2 sub-matrix is not diagonal already...
|
||||
// notice that this comparison will evaluate to false if any NaN is involved, ensuring that NaN's don't
|
||||
// keep us iterating forever. Similarly, small denormal numbers are considered zero.
|
||||
using std::max;
|
||||
RealScalar threshold = (max)(considerAsZero, precision * (max)(abs(m_workMatrix.coeff(p,p)),
|
||||
abs(m_workMatrix.coeff(q,q))));
|
||||
// We compare both values to threshold instead of calling max to be robust to NaN (See bug 791)
|
||||
RealScalar threshold = max EIGEN_EMPTY (considerAsZero, precision * maxDiagEntry);
|
||||
if(abs(m_workMatrix.coeff(p,q))>threshold || abs(m_workMatrix.coeff(q,p)) > threshold)
|
||||
{
|
||||
finished = false;
|
||||
|
||||
// perform SVD decomposition of 2x2 sub-matrix corresponding to indices p,q to make it diagonal
|
||||
internal::svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner>::run(m_workMatrix, *this, p, q);
|
||||
JacobiRotation<RealScalar> j_left, j_right;
|
||||
internal::real_2x2_jacobi_svd(m_workMatrix, p, q, &j_left, &j_right);
|
||||
// the complex to real operation returns true is the updated 2x2 block is not already diagonal
|
||||
if(internal::svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner>::run(m_workMatrix, *this, p, q, maxDiagEntry))
|
||||
{
|
||||
JacobiRotation<RealScalar> j_left, j_right;
|
||||
internal::real_2x2_jacobi_svd(m_workMatrix, p, q, &j_left, &j_right);
|
||||
|
||||
// accumulate resulting Jacobi rotations
|
||||
m_workMatrix.applyOnTheLeft(p,q,j_left);
|
||||
if(computeU()) m_matrixU.applyOnTheRight(p,q,j_left.transpose());
|
||||
// accumulate resulting Jacobi rotations
|
||||
m_workMatrix.applyOnTheLeft(p,q,j_left);
|
||||
if(computeU()) m_matrixU.applyOnTheRight(p,q,j_left.transpose());
|
||||
|
||||
m_workMatrix.applyOnTheRight(p,q,j_right);
|
||||
if(computeV()) m_matrixV.applyOnTheRight(p,q,j_right);
|
||||
m_workMatrix.applyOnTheRight(p,q,j_right);
|
||||
if(computeV()) m_matrixV.applyOnTheRight(p,q,j_right);
|
||||
|
||||
// keep track of the largest diagonal coefficient
|
||||
maxDiagEntry = max EIGEN_EMPTY (maxDiagEntry,max EIGEN_EMPTY (abs(m_workMatrix.coeff(p,p)), abs(m_workMatrix.coeff(q,q))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ JacobiSVD<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic>, ColPiv
|
||||
JacobiSVD<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic>, ColPivHouseholderQRPreconditioner>::compute(const Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic>& matrix, unsigned int computationOptions) \
|
||||
{ \
|
||||
typedef Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic> MatrixType; \
|
||||
typedef MatrixType::Scalar Scalar; \
|
||||
typedef MatrixType::RealScalar RealScalar; \
|
||||
/*typedef MatrixType::Scalar Scalar;*/ \
|
||||
/*typedef MatrixType::RealScalar RealScalar;*/ \
|
||||
allocate(matrix.rows(), matrix.cols(), computationOptions); \
|
||||
\
|
||||
/*const RealScalar precision = RealScalar(2) * NumTraits<Scalar>::epsilon();*/ \
|
||||
|
||||
@@ -102,6 +102,11 @@ class CompressedStorage
|
||||
inline size_t allocatedSize() const { return m_allocatedSize; }
|
||||
inline void clear() { m_size = 0; }
|
||||
|
||||
const Scalar* valuePtr() const { return m_values; }
|
||||
Scalar* valuePtr() { return m_values; }
|
||||
const Index* indexPtr() const { return m_indices; }
|
||||
Index* indexPtr() { return m_indices; }
|
||||
|
||||
inline Scalar& value(size_t i) { return m_values[i]; }
|
||||
inline const Scalar& value(size_t i) const { return m_values[i]; }
|
||||
|
||||
@@ -208,8 +213,10 @@ class CompressedStorage
|
||||
Index* newIndices = new Index[size];
|
||||
size_t copySize = (std::min)(size, m_size);
|
||||
// copy
|
||||
internal::smart_copy(m_values, m_values+copySize, newValues);
|
||||
internal::smart_copy(m_indices, m_indices+copySize, newIndices);
|
||||
if (copySize>0) {
|
||||
internal::smart_copy(m_values, m_values+copySize, newValues);
|
||||
internal::smart_copy(m_indices, m_indices+copySize, newIndices);
|
||||
}
|
||||
// delete old stuff
|
||||
delete[] m_values;
|
||||
delete[] m_indices;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -55,10 +55,9 @@ class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Sparse>
|
||||
EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
|
||||
CwiseBinaryOpImpl()
|
||||
{
|
||||
typedef typename internal::traits<Lhs>::StorageKind LhsStorageKind;
|
||||
typedef typename internal::traits<Rhs>::StorageKind RhsStorageKind;
|
||||
EIGEN_STATIC_ASSERT((
|
||||
(!internal::is_same<LhsStorageKind,RhsStorageKind>::value)
|
||||
(!internal::is_same<typename internal::traits<Lhs>::StorageKind,
|
||||
typename internal::traits<Rhs>::StorageKind>::value)
|
||||
|| ((Lhs::Flags&RowMajorBit) == (Rhs::Flags&RowMajorBit))),
|
||||
THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH);
|
||||
}
|
||||
@@ -314,10 +313,10 @@ SparseMatrixBase<Derived>::operator+=(const SparseMatrixBase<OtherDerived>& othe
|
||||
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
|
||||
EIGEN_STRONG_INLINE const typename SparseMatrixBase<Derived>::template CwiseProductDenseReturnType<OtherDerived>::Type
|
||||
SparseMatrixBase<Derived>::cwiseProduct(const MatrixBase<OtherDerived> &other) const
|
||||
{
|
||||
return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(derived(), other.derived());
|
||||
return typename CwiseProductDenseReturnType<OtherDerived>::Type(derived(), other.derived());
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -128,20 +128,20 @@ class SparseMatrix
|
||||
/** \returns a const pointer to the array of values.
|
||||
* This function is aimed at interoperability with other libraries.
|
||||
* \sa innerIndexPtr(), outerIndexPtr() */
|
||||
inline const Scalar* valuePtr() const { return &m_data.value(0); }
|
||||
inline const Scalar* valuePtr() const { return m_data.valuePtr(); }
|
||||
/** \returns a non-const pointer to the array of values.
|
||||
* This function is aimed at interoperability with other libraries.
|
||||
* \sa innerIndexPtr(), outerIndexPtr() */
|
||||
inline Scalar* valuePtr() { return &m_data.value(0); }
|
||||
inline Scalar* valuePtr() { return m_data.valuePtr(); }
|
||||
|
||||
/** \returns a const pointer to the array of inner indices.
|
||||
* This function is aimed at interoperability with other libraries.
|
||||
* \sa valuePtr(), outerIndexPtr() */
|
||||
inline const Index* innerIndexPtr() const { return &m_data.index(0); }
|
||||
inline const Index* innerIndexPtr() const { return m_data.indexPtr(); }
|
||||
/** \returns a non-const pointer to the array of inner indices.
|
||||
* This function is aimed at interoperability with other libraries.
|
||||
* \sa valuePtr(), outerIndexPtr() */
|
||||
inline Index* innerIndexPtr() { return &m_data.index(0); }
|
||||
inline Index* innerIndexPtr() { return m_data.indexPtr(); }
|
||||
|
||||
/** \returns a const pointer to the array of the starting positions of the inner vectors.
|
||||
* This function is aimed at interoperability with other libraries.
|
||||
@@ -691,14 +691,17 @@ class SparseMatrix
|
||||
m_data.swap(other.m_data);
|
||||
}
|
||||
|
||||
/** Sets *this to the identity matrix */
|
||||
/** Sets *this to the identity matrix.
|
||||
* This function also turns the matrix into compressed mode, and drop any reserved memory. */
|
||||
inline void setIdentity()
|
||||
{
|
||||
eigen_assert(rows() == cols() && "ONLY FOR SQUARED MATRICES");
|
||||
this->m_data.resize(rows());
|
||||
Eigen::Map<Matrix<Index, Dynamic, 1> >(&this->m_data.index(0), rows()).setLinSpaced(0, rows()-1);
|
||||
Eigen::Map<Matrix<Scalar, Dynamic, 1> >(&this->m_data.value(0), rows()).setOnes();
|
||||
Eigen::Map<Matrix<Index, Dynamic, 1> >(this->m_data.indexPtr(), rows()).setLinSpaced(0, rows()-1);
|
||||
Eigen::Map<Matrix<Scalar, Dynamic, 1> >(this->m_data.valuePtr(), rows()).setOnes();
|
||||
Eigen::Map<Matrix<Index, Dynamic, 1> >(this->m_outerIndex, rows()+1).setLinSpaced(0, rows());
|
||||
std::free(m_innerNonZeros);
|
||||
m_innerNonZeros = 0;
|
||||
}
|
||||
inline SparseMatrix& operator=(const SparseMatrix& other)
|
||||
{
|
||||
|
||||
@@ -23,7 +23,14 @@ namespace Eigen {
|
||||
* This class can be extended with the help of the plugin mechanism described on the page
|
||||
* \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_SPARSEMATRIXBASE_PLUGIN.
|
||||
*/
|
||||
template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
|
||||
template<typename Derived> class SparseMatrixBase
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
: public internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
|
||||
typename NumTraits<typename internal::traits<Derived>::Scalar>::Real,
|
||||
EigenBase<Derived> >
|
||||
#else
|
||||
: public EigenBase<Derived>
|
||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -31,12 +38,12 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
|
||||
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
|
||||
typedef typename internal::traits<Derived>::StorageKind StorageKind;
|
||||
typedef typename internal::traits<Derived>::Index Index;
|
||||
typedef typename internal::traits<Derived>::Index StorageIndex;
|
||||
typedef typename internal::add_const_on_value_type_if_arithmetic<
|
||||
typename internal::packet_traits<Scalar>::type
|
||||
>::type PacketReturnType;
|
||||
|
||||
typedef SparseMatrixBase StorageBaseType;
|
||||
typedef EigenBase<Derived> Base;
|
||||
|
||||
template<typename OtherDerived>
|
||||
Derived& operator=(const EigenBase<OtherDerived> &other)
|
||||
@@ -132,6 +139,9 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
|
||||
inline Derived& derived() { return *static_cast<Derived*>(this); }
|
||||
inline Derived& const_cast_derived() const
|
||||
{ return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); }
|
||||
|
||||
typedef internal::special_scalar_op_base<Derived, Scalar, RealScalar, EigenBase<Derived> > Base;
|
||||
using Base::operator*;
|
||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase
|
||||
@@ -317,20 +327,18 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
|
||||
Derived& operator*=(const Scalar& other);
|
||||
Derived& operator/=(const Scalar& other);
|
||||
|
||||
#define EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE \
|
||||
CwiseBinaryOp< \
|
||||
internal::scalar_product_op< \
|
||||
typename internal::scalar_product_traits< \
|
||||
typename internal::traits<Derived>::Scalar, \
|
||||
typename internal::traits<OtherDerived>::Scalar \
|
||||
>::ReturnType \
|
||||
>, \
|
||||
const Derived, \
|
||||
const OtherDerived \
|
||||
>
|
||||
template<typename OtherDerived> struct CwiseProductDenseReturnType {
|
||||
typedef CwiseBinaryOp<internal::scalar_product_op<typename internal::scalar_product_traits<
|
||||
typename internal::traits<Derived>::Scalar,
|
||||
typename internal::traits<OtherDerived>::Scalar
|
||||
>::ReturnType>,
|
||||
const Derived,
|
||||
const OtherDerived
|
||||
> Type;
|
||||
};
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
|
||||
EIGEN_STRONG_INLINE const typename CwiseProductDenseReturnType<OtherDerived>::Type
|
||||
cwiseProduct(const MatrixBase<OtherDerived> &other) const;
|
||||
|
||||
// sparse * sparse
|
||||
|
||||
@@ -29,7 +29,10 @@ typename internal::traits<SparseMatrix<_Scalar,_Options,_Index> >::Scalar
|
||||
SparseMatrix<_Scalar,_Options,_Index>::sum() const
|
||||
{
|
||||
eigen_assert(rows()>0 && cols()>0 && "you are using a non initialized matrix");
|
||||
return Matrix<Scalar,1,Dynamic>::Map(&m_data.value(0), m_data.size()).sum();
|
||||
if(this->isCompressed())
|
||||
return Matrix<Scalar,1,Dynamic>::Map(m_data.valuePtr(), m_data.size()).sum();
|
||||
else
|
||||
return Base::sum();
|
||||
}
|
||||
|
||||
template<typename _Scalar, int _Options, typename _Index>
|
||||
@@ -37,7 +40,7 @@ typename internal::traits<SparseVector<_Scalar,_Options, _Index> >::Scalar
|
||||
SparseVector<_Scalar,_Options,_Index>::sum() const
|
||||
{
|
||||
eigen_assert(rows()>0 && cols()>0 && "you are using a non initialized matrix");
|
||||
return Matrix<Scalar,1,Dynamic>::Map(&m_data.value(0), m_data.size()).sum();
|
||||
return Matrix<Scalar,1,Dynamic>::Map(m_data.valuePtr(), m_data.size()).sum();
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -48,7 +48,7 @@ static void sparse_sparse_product_with_pruning_impl(const Lhs& lhs, const Rhs& r
|
||||
res.resize(rows, cols);
|
||||
|
||||
res.reserve(estimated_nnz_prod);
|
||||
double ratioColRes = double(estimated_nnz_prod)/double(lhs.rows()*rhs.cols());
|
||||
double ratioColRes = double(estimated_nnz_prod)/(double(lhs.rows())*double(rhs.cols()));
|
||||
for (Index j=0; j<cols; ++j)
|
||||
{
|
||||
// FIXME:
|
||||
|
||||
@@ -67,7 +67,6 @@ const int InnerRandomAccessPattern = 0x2 | CoherentAccessPattern;
|
||||
const int OuterRandomAccessPattern = 0x4 | CoherentAccessPattern;
|
||||
const int RandomAccessPattern = 0x8 | OuterRandomAccessPattern | InnerRandomAccessPattern;
|
||||
|
||||
template<typename Derived> class SparseMatrixBase;
|
||||
template<typename _Scalar, int _Flags = 0, typename _Index = int> class SparseMatrix;
|
||||
template<typename _Scalar, int _Flags = 0, typename _Index = int> class DynamicSparseMatrix;
|
||||
template<typename _Scalar, int _Flags = 0, typename _Index = int> class SparseVector;
|
||||
|
||||
@@ -84,12 +84,12 @@ class SparseVector
|
||||
EIGEN_STRONG_INLINE Index innerSize() const { return m_size; }
|
||||
EIGEN_STRONG_INLINE Index outerSize() const { return 1; }
|
||||
|
||||
EIGEN_STRONG_INLINE const Scalar* valuePtr() const { return &m_data.value(0); }
|
||||
EIGEN_STRONG_INLINE Scalar* valuePtr() { return &m_data.value(0); }
|
||||
EIGEN_STRONG_INLINE const Scalar* valuePtr() const { return m_data.valuePtr(); }
|
||||
EIGEN_STRONG_INLINE Scalar* valuePtr() { return m_data.valuePtr(); }
|
||||
|
||||
EIGEN_STRONG_INLINE const Index* innerIndexPtr() const { return m_data.indexPtr(); }
|
||||
EIGEN_STRONG_INLINE Index* innerIndexPtr() { return m_data.indexPtr(); }
|
||||
|
||||
EIGEN_STRONG_INLINE const Index* innerIndexPtr() const { return &m_data.index(0); }
|
||||
EIGEN_STRONG_INLINE Index* innerIndexPtr() { return &m_data.index(0); }
|
||||
|
||||
/** \internal */
|
||||
inline Storage& data() { return m_data; }
|
||||
/** \internal */
|
||||
@@ -158,6 +158,7 @@ class SparseVector
|
||||
|
||||
Index inner = IsColVector ? row : col;
|
||||
Index outer = IsColVector ? col : row;
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(outer);
|
||||
eigen_assert(outer==0);
|
||||
return insert(inner);
|
||||
}
|
||||
|
||||
@@ -35,9 +35,9 @@ class SparseView : public SparseMatrixBase<SparseView<MatrixType> >
|
||||
public:
|
||||
EIGEN_SPARSE_PUBLIC_INTERFACE(SparseView)
|
||||
|
||||
SparseView(const MatrixType& mat, const Scalar& m_reference = Scalar(0),
|
||||
typename NumTraits<Scalar>::Real m_epsilon = NumTraits<Scalar>::dummy_precision()) :
|
||||
m_matrix(mat), m_reference(m_reference), m_epsilon(m_epsilon) {}
|
||||
explicit SparseView(const MatrixType& mat, const Scalar& reference = Scalar(0),
|
||||
const RealScalar &epsilon = NumTraits<Scalar>::dummy_precision())
|
||||
: m_matrix(mat), m_reference(reference), m_epsilon(epsilon) {}
|
||||
|
||||
class InnerIterator;
|
||||
|
||||
|
||||
@@ -749,8 +749,8 @@ struct SparseLUMatrixUReturnType : internal::no_assignment_operator
|
||||
}
|
||||
else
|
||||
{
|
||||
Map<const Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A( &(m_mapL.valuePtr()[luptr]), nsupc, nsupc, OuterStride<>(lda) );
|
||||
Map< Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) );
|
||||
Map<const Matrix<Scalar,Dynamic,Dynamic, ColMajor>, 0, OuterStride<> > A( &(m_mapL.valuePtr()[luptr]), nsupc, nsupc, OuterStride<>(lda) );
|
||||
Map< Matrix<Scalar,Dynamic,Dynamic, ColMajor>, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) );
|
||||
U = A.template triangularView<Upper>().solve(U);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ class SparseLUImpl
|
||||
{
|
||||
public:
|
||||
typedef Matrix<Scalar,Dynamic,1> ScalarVector;
|
||||
typedef Matrix<Scalar,Dynamic,Dynamic,ColMajor> ScalarMatrix;
|
||||
typedef Map<ScalarMatrix, 0, OuterStride<> > MappedMatrixBlock;
|
||||
typedef Matrix<Index,Dynamic,1> IndexVector;
|
||||
typedef typename ScalarVector::RealScalar RealScalar;
|
||||
typedef Ref<Matrix<Scalar,Dynamic,1> > BlockScalarVector;
|
||||
|
||||
@@ -153,8 +153,8 @@ Index SparseLUImpl<Scalar,Index>::memInit(Index m, Index n, Index annz, Index lw
|
||||
{
|
||||
Index& num_expansions = glu.num_expansions; //No memory expansions so far
|
||||
num_expansions = 0;
|
||||
glu.nzumax = glu.nzlumax = (std::min)(fillratio * annz / n, m) * n; // estimated number of nonzeros in U
|
||||
glu.nzlmax = (std::max)(Index(4), fillratio) * annz / 4; // estimated nnz in L factor
|
||||
glu.nzumax = glu.nzlumax = (std::min)(fillratio * (annz+1) / n, m) * n; // estimated number of nonzeros in U
|
||||
glu.nzlmax = (std::max)(Index(4), fillratio) * (annz+1) / 4; // estimated nnz in L factor
|
||||
// Return the estimated size to the user if necessary
|
||||
Index tempSpace;
|
||||
tempSpace = (2*panel_size + 4 + LUNoMarker) * m * sizeof(Index) + (panel_size + 1) * m * sizeof(Scalar);
|
||||
|
||||
@@ -236,7 +236,7 @@ void MappedSuperNodalMatrix<Scalar,Index>::solveInPlace( MatrixBase<Dest>&X) con
|
||||
Index n = X.rows();
|
||||
Index nrhs = X.cols();
|
||||
const Scalar * Lval = valuePtr(); // Nonzero values
|
||||
Matrix<Scalar,Dynamic,Dynamic> work(n, nrhs); // working vector
|
||||
Matrix<Scalar,Dynamic,Dynamic, ColMajor> work(n, nrhs); // working vector
|
||||
work.setZero();
|
||||
for (Index k = 0; k <= nsuper(); k ++)
|
||||
{
|
||||
@@ -267,12 +267,12 @@ void MappedSuperNodalMatrix<Scalar,Index>::solveInPlace( MatrixBase<Dest>&X) con
|
||||
Index lda = colIndexPtr()[fsupc+1] - luptr;
|
||||
|
||||
// Triangular solve
|
||||
Map<const Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A( &(Lval[luptr]), nsupc, nsupc, OuterStride<>(lda) );
|
||||
Map< Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) );
|
||||
Map<const Matrix<Scalar,Dynamic,Dynamic, ColMajor>, 0, OuterStride<> > A( &(Lval[luptr]), nsupc, nsupc, OuterStride<>(lda) );
|
||||
Map< Matrix<Scalar,Dynamic,Dynamic, ColMajor>, 0, OuterStride<> > U (&(X(fsupc,0)), nsupc, nrhs, OuterStride<>(n) );
|
||||
U = A.template triangularView<UnitLower>().solve(U);
|
||||
|
||||
// Matrix-vector product
|
||||
new (&A) Map<const Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > ( &(Lval[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) );
|
||||
new (&A) Map<const Matrix<Scalar,Dynamic,Dynamic, ColMajor>, 0, OuterStride<> > ( &(Lval[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) );
|
||||
work.block(0, 0, nrow, nrhs) = A * U;
|
||||
|
||||
//Begin Scatter
|
||||
|
||||
@@ -162,11 +162,11 @@ Index SparseLUImpl<Scalar,Index>::column_bmod(const Index jcol, const Index nseg
|
||||
// points to the beginning of jcol in snode L\U(jsupno)
|
||||
ufirst = glu.xlusup(jcol) + d_fsupc;
|
||||
Index lda = glu.xlusup(jcol+1) - glu.xlusup(jcol);
|
||||
Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A( &(glu.lusup.data()[luptr]), nsupc, nsupc, OuterStride<>(lda) );
|
||||
MappedMatrixBlock A( &(glu.lusup.data()[luptr]), nsupc, nsupc, OuterStride<>(lda) );
|
||||
VectorBlock<ScalarVector> u(glu.lusup, ufirst, nsupc);
|
||||
u = A.template triangularView<UnitLower>().solve(u);
|
||||
|
||||
new (&A) Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > ( &(glu.lusup.data()[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) );
|
||||
new (&A) MappedMatrixBlock ( &(glu.lusup.data()[luptr+nsupc]), nrow, nsupc, OuterStride<>(lda) );
|
||||
VectorBlock<ScalarVector> l(glu.lusup, ufirst+nsupc, nrow);
|
||||
l.noalias() -= A * u;
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ EIGEN_DONT_INLINE void LU_kernel_bmod<SegSizeAtCompileTime>::run(const int segsi
|
||||
// Dense triangular solve -- start effective triangle
|
||||
luptr += lda * no_zeros + no_zeros;
|
||||
// Form Eigen matrix and vector
|
||||
Map<Matrix<Scalar,SegSizeAtCompileTime,SegSizeAtCompileTime>, 0, OuterStride<> > A( &(lusup.data()[luptr]), segsize, segsize, OuterStride<>(lda) );
|
||||
Map<Matrix<Scalar,SegSizeAtCompileTime,SegSizeAtCompileTime, ColMajor>, 0, OuterStride<> > A( &(lusup.data()[luptr]), segsize, segsize, OuterStride<>(lda) );
|
||||
Map<Matrix<Scalar,SegSizeAtCompileTime,1> > u(tempv.data(), segsize);
|
||||
|
||||
u = A.template triangularView<UnitLower>().solve(u);
|
||||
@@ -65,7 +65,7 @@ EIGEN_DONT_INLINE void LU_kernel_bmod<SegSizeAtCompileTime>::run(const int segsi
|
||||
luptr += segsize;
|
||||
const Index PacketSize = internal::packet_traits<Scalar>::size;
|
||||
Index ldl = internal::first_multiple(nrow, PacketSize);
|
||||
Map<Matrix<Scalar,Dynamic,SegSizeAtCompileTime>, 0, OuterStride<> > B( &(lusup.data()[luptr]), nrow, segsize, OuterStride<>(lda) );
|
||||
Map<Matrix<Scalar,Dynamic,SegSizeAtCompileTime, ColMajor>, 0, OuterStride<> > B( &(lusup.data()[luptr]), nrow, segsize, OuterStride<>(lda) );
|
||||
Index aligned_offset = internal::first_aligned(tempv.data()+segsize, PacketSize);
|
||||
Index aligned_with_B_offset = (PacketSize-internal::first_aligned(B.data(), PacketSize))%PacketSize;
|
||||
Map<Matrix<Scalar,Dynamic,1>, 0, OuterStride<> > l(tempv.data()+segsize+aligned_offset+aligned_with_B_offset, nrow, OuterStride<>(ldl) );
|
||||
|
||||
@@ -102,7 +102,7 @@ void SparseLUImpl<Scalar,Index>::panel_bmod(const Index m, const Index w, const
|
||||
if(nsupc >= 2)
|
||||
{
|
||||
Index ldu = internal::first_multiple<Index>(u_rows, PacketSize);
|
||||
Map<Matrix<Scalar,Dynamic,Dynamic>, Aligned, OuterStride<> > U(tempv.data(), u_rows, u_cols, OuterStride<>(ldu));
|
||||
Map<ScalarMatrix, Aligned, OuterStride<> > U(tempv.data(), u_rows, u_cols, OuterStride<>(ldu));
|
||||
|
||||
// gather U
|
||||
Index u_col = 0;
|
||||
@@ -136,17 +136,17 @@ void SparseLUImpl<Scalar,Index>::panel_bmod(const Index m, const Index w, const
|
||||
Index lda = glu.xlusup(fsupc+1) - glu.xlusup(fsupc);
|
||||
no_zeros = (krep - u_rows + 1) - fsupc;
|
||||
luptr += lda * no_zeros + no_zeros;
|
||||
Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > A(glu.lusup.data()+luptr, u_rows, u_rows, OuterStride<>(lda) );
|
||||
MappedMatrixBlock A(glu.lusup.data()+luptr, u_rows, u_rows, OuterStride<>(lda) );
|
||||
U = A.template triangularView<UnitLower>().solve(U);
|
||||
|
||||
// update
|
||||
luptr += u_rows;
|
||||
Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > B(glu.lusup.data()+luptr, nrow, u_rows, OuterStride<>(lda) );
|
||||
MappedMatrixBlock B(glu.lusup.data()+luptr, nrow, u_rows, OuterStride<>(lda) );
|
||||
eigen_assert(tempv.size()>w*ldu + nrow*w + 1);
|
||||
|
||||
Index ldl = internal::first_multiple<Index>(nrow, PacketSize);
|
||||
Index offset = (PacketSize-internal::first_aligned(B.data(), PacketSize)) % PacketSize;
|
||||
Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<> > L(tempv.data()+w*ldu+offset, nrow, u_cols, OuterStride<>(ldl));
|
||||
MappedMatrixBlock L(tempv.data()+w*ldu+offset, nrow, u_cols, OuterStride<>(ldl));
|
||||
|
||||
L.setZero();
|
||||
internal::sparselu_gemm<Scalar>(L.rows(), L.cols(), B.cols(), B.data(), B.outerStride(), U.data(), U.outerStride(), L.data(), L.outerStride());
|
||||
|
||||
@@ -71,7 +71,7 @@ Index SparseLUImpl<Scalar,Index>::pivotL(const Index jcol, const RealScalar& dia
|
||||
|
||||
// Determine the largest abs numerical value for partial pivoting
|
||||
Index diagind = iperm_c(jcol); // diagonal index
|
||||
RealScalar pivmax = 0.0;
|
||||
RealScalar pivmax(-1.0);
|
||||
Index pivptr = nsupc;
|
||||
Index diag = emptyIdxLU;
|
||||
RealScalar rtemp;
|
||||
@@ -87,8 +87,9 @@ Index SparseLUImpl<Scalar,Index>::pivotL(const Index jcol, const RealScalar& dia
|
||||
}
|
||||
|
||||
// Test for singularity
|
||||
if ( pivmax == 0.0 ) {
|
||||
pivrow = lsub_ptr[pivptr];
|
||||
if ( pivmax <= RealScalar(0.0) ) {
|
||||
// if pivmax == -1, the column is structurally empty, otherwise it is only numerically zero
|
||||
pivrow = pivmax < RealScalar(0.0) ? diagind : lsub_ptr[pivptr];
|
||||
perm_r(pivrow) = jcol;
|
||||
return (jcol+1);
|
||||
}
|
||||
|
||||
@@ -13,32 +13,24 @@
|
||||
|
||||
#include "details.h"
|
||||
|
||||
// Define the explicit instantiation (e.g. necessary for the Intel compiler)
|
||||
#if defined(__INTEL_COMPILER) || defined(__GNUC__)
|
||||
#define EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(...) template class std::deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> >;
|
||||
#else
|
||||
#define EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(...)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This section contains a convenience MACRO which allows an easy specialization of
|
||||
* std::deque such that for data types with alignment issues the correct allocator
|
||||
* is used automatically.
|
||||
*/
|
||||
#define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...) \
|
||||
EIGEN_EXPLICIT_STL_DEQUE_INSTANTIATION(__VA_ARGS__) \
|
||||
namespace std \
|
||||
{ \
|
||||
template<typename _Ay> \
|
||||
class deque<__VA_ARGS__, _Ay> \
|
||||
template<> \
|
||||
class deque<__VA_ARGS__, std::allocator<__VA_ARGS__> > \
|
||||
: public deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \
|
||||
{ \
|
||||
typedef deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > deque_base; \
|
||||
public: \
|
||||
typedef __VA_ARGS__ value_type; \
|
||||
typedef typename deque_base::allocator_type allocator_type; \
|
||||
typedef typename deque_base::size_type size_type; \
|
||||
typedef typename deque_base::iterator iterator; \
|
||||
typedef deque_base::allocator_type allocator_type; \
|
||||
typedef deque_base::size_type size_type; \
|
||||
typedef deque_base::iterator iterator; \
|
||||
explicit deque(const allocator_type& a = allocator_type()) : deque_base(a) {} \
|
||||
template<typename InputIterator> \
|
||||
deque(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : deque_base(first, last, a) {} \
|
||||
|
||||
@@ -12,32 +12,24 @@
|
||||
|
||||
#include "details.h"
|
||||
|
||||
// Define the explicit instantiation (e.g. necessary for the Intel compiler)
|
||||
#if defined(__INTEL_COMPILER) || defined(__GNUC__)
|
||||
#define EIGEN_EXPLICIT_STL_LIST_INSTANTIATION(...) template class std::list<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> >;
|
||||
#else
|
||||
#define EIGEN_EXPLICIT_STL_LIST_INSTANTIATION(...)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This section contains a convenience MACRO which allows an easy specialization of
|
||||
* std::list such that for data types with alignment issues the correct allocator
|
||||
* is used automatically.
|
||||
*/
|
||||
#define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...) \
|
||||
EIGEN_EXPLICIT_STL_LIST_INSTANTIATION(__VA_ARGS__) \
|
||||
namespace std \
|
||||
{ \
|
||||
template<typename _Ay> \
|
||||
class list<__VA_ARGS__, _Ay> \
|
||||
template<> \
|
||||
class list<__VA_ARGS__, std::allocator<__VA_ARGS__> > \
|
||||
: public list<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \
|
||||
{ \
|
||||
typedef list<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > list_base; \
|
||||
public: \
|
||||
typedef __VA_ARGS__ value_type; \
|
||||
typedef typename list_base::allocator_type allocator_type; \
|
||||
typedef typename list_base::size_type size_type; \
|
||||
typedef typename list_base::iterator iterator; \
|
||||
typedef list_base::allocator_type allocator_type; \
|
||||
typedef list_base::size_type size_type; \
|
||||
typedef list_base::iterator iterator; \
|
||||
explicit list(const allocator_type& a = allocator_type()) : list_base(a) {} \
|
||||
template<typename InputIterator> \
|
||||
list(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : list_base(first, last, a) {} \
|
||||
|
||||
@@ -44,15 +44,10 @@
|
||||
#define BTL_ASM_COMMENT(X)
|
||||
#endif
|
||||
|
||||
#if (defined __GNUC__) && (!defined __INTEL_COMPILER) && !defined(__arm__) && !defined(__powerpc__)
|
||||
#define BTL_DISABLE_SSE_EXCEPTIONS() { \
|
||||
int aux; \
|
||||
asm( \
|
||||
"stmxcsr %[aux] \n\t" \
|
||||
"orl $32832, %[aux] \n\t" \
|
||||
"ldmxcsr %[aux] \n\t" \
|
||||
: : [aux] "m" (aux)); \
|
||||
}
|
||||
#ifdef __SSE__
|
||||
#include "xmmintrin.h"
|
||||
// This enables flush to zero (FTZ) and denormals are zero (DAZ) modes:
|
||||
#define BTL_DISABLE_SSE_EXCEPTIONS() { _mm_setcsr(_mm_getcsr() | 0x8040); }
|
||||
#else
|
||||
#define BTL_DISABLE_SSE_EXCEPTIONS()
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user