mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-01-18 14:34:17 +08:00
Remove deprecated code not used by evaluators
This commit is contained in:
parent
8b3be4907d
commit
0ca43f7e9a
@ -21,7 +21,6 @@
|
|||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/misc/Solve.h"
|
|
||||||
#include "src/Cholesky/LLT.h"
|
#include "src/Cholesky/LLT.h"
|
||||||
#include "src/Cholesky/LDLT.h"
|
#include "src/Cholesky/LDLT.h"
|
||||||
#ifdef EIGEN_USE_LAPACKE
|
#ifdef EIGEN_USE_LAPACKE
|
||||||
|
@ -33,12 +33,8 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/misc/Solve.h"
|
|
||||||
#include "src/misc/SparseSolve.h"
|
|
||||||
|
|
||||||
#include "src/CholmodSupport/CholmodSupport.h"
|
#include "src/CholmodSupport/CholmodSupport.h"
|
||||||
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_CHOLMODSUPPORT_MODULE_H
|
#endif // EIGEN_CHOLMODSUPPORT_MODULE_H
|
||||||
|
25
Eigen/Core
25
Eigen/Core
@ -11,16 +11,6 @@
|
|||||||
#ifndef EIGEN_CORE_H
|
#ifndef EIGEN_CORE_H
|
||||||
#define EIGEN_CORE_H
|
#define EIGEN_CORE_H
|
||||||
|
|
||||||
// EIGEN_TEST_EVALUATORS => EIGEN_ENABLE_EVALUATORS
|
|
||||||
#ifndef EIGEN_TEST_NO_EVALUATORS
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
#define EIGEN_TEST_EVALUATORS
|
|
||||||
#endif
|
|
||||||
#ifndef EIGEN_ENABLE_EVALUATORS
|
|
||||||
#define EIGEN_ENABLE_EVALUATORS
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// first thing Eigen does: stop the compiler from committing suicide
|
// first thing Eigen does: stop the compiler from committing suicide
|
||||||
#include "src/Core/util/DisableStupidWarnings.h"
|
#include "src/Core/util/DisableStupidWarnings.h"
|
||||||
|
|
||||||
@ -317,11 +307,9 @@ using std::ptrdiff_t;
|
|||||||
#include "src/Core/MatrixBase.h"
|
#include "src/Core/MatrixBase.h"
|
||||||
#include "src/Core/EigenBase.h"
|
#include "src/Core/EigenBase.h"
|
||||||
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
#include "src/Core/Product.h"
|
#include "src/Core/Product.h"
|
||||||
#include "src/Core/CoreEvaluators.h"
|
#include "src/Core/CoreEvaluators.h"
|
||||||
#include "src/Core/AssignEvaluator.h"
|
#include "src/Core/AssignEvaluator.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874
|
#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874
|
||||||
// at least confirmed with Doxygen 1.5.5 and 1.5.6
|
// at least confirmed with Doxygen 1.5.5 and 1.5.6
|
||||||
@ -332,10 +320,10 @@ using std::ptrdiff_t;
|
|||||||
#include "src/Core/util/BlasUtil.h"
|
#include "src/Core/util/BlasUtil.h"
|
||||||
#include "src/Core/DenseStorage.h"
|
#include "src/Core/DenseStorage.h"
|
||||||
#include "src/Core/NestByValue.h"
|
#include "src/Core/NestByValue.h"
|
||||||
#ifndef EIGEN_ENABLE_EVALUATORS
|
|
||||||
#include "src/Core/ForceAlignedAccess.h"
|
// #include "src/Core/ForceAlignedAccess.h"
|
||||||
#include "src/Core/Flagged.h"
|
// #include "src/Core/Flagged.h"
|
||||||
#endif
|
|
||||||
#include "src/Core/ReturnByValue.h"
|
#include "src/Core/ReturnByValue.h"
|
||||||
#include "src/Core/NoAlias.h"
|
#include "src/Core/NoAlias.h"
|
||||||
#include "src/Core/PlainObjectBase.h"
|
#include "src/Core/PlainObjectBase.h"
|
||||||
@ -368,18 +356,13 @@ using std::ptrdiff_t;
|
|||||||
#include "src/Core/CommaInitializer.h"
|
#include "src/Core/CommaInitializer.h"
|
||||||
#include "src/Core/ProductBase.h"
|
#include "src/Core/ProductBase.h"
|
||||||
#include "src/Core/GeneralProduct.h"
|
#include "src/Core/GeneralProduct.h"
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
#include "src/Core/Solve.h"
|
#include "src/Core/Solve.h"
|
||||||
#include "src/Core/Inverse.h"
|
#include "src/Core/Inverse.h"
|
||||||
#endif
|
|
||||||
#include "src/Core/TriangularMatrix.h"
|
#include "src/Core/TriangularMatrix.h"
|
||||||
#include "src/Core/SelfAdjointView.h"
|
#include "src/Core/SelfAdjointView.h"
|
||||||
#include "src/Core/products/GeneralBlockPanelKernel.h"
|
#include "src/Core/products/GeneralBlockPanelKernel.h"
|
||||||
#include "src/Core/products/Parallelizer.h"
|
#include "src/Core/products/Parallelizer.h"
|
||||||
#include "src/Core/products/CoeffBasedProduct.h"
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
#include "src/Core/ProductEvaluators.h"
|
#include "src/Core/ProductEvaluators.h"
|
||||||
#endif
|
|
||||||
#include "src/Core/products/GeneralMatrixVector.h"
|
#include "src/Core/products/GeneralMatrixVector.h"
|
||||||
#include "src/Core/products/GeneralMatrixMatrix.h"
|
#include "src/Core/products/GeneralMatrixMatrix.h"
|
||||||
#include "src/Core/SolveTriangular.h"
|
#include "src/Core/SolveTriangular.h"
|
||||||
|
@ -26,13 +26,7 @@
|
|||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
#include "src/misc/Solve.h"
|
|
||||||
#include "src/misc/SparseSolve.h"
|
|
||||||
#else
|
|
||||||
#include "src/IterativeLinearSolvers/SolveWithGuess.h"
|
#include "src/IterativeLinearSolvers/SolveWithGuess.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "src/IterativeLinearSolvers/IterativeSolverBase.h"
|
#include "src/IterativeLinearSolvers/IterativeSolverBase.h"
|
||||||
#include "src/IterativeLinearSolvers/BasicPreconditioners.h"
|
#include "src/IterativeLinearSolvers/BasicPreconditioners.h"
|
||||||
#include "src/IterativeLinearSolvers/ConjugateGradient.h"
|
#include "src/IterativeLinearSolvers/ConjugateGradient.h"
|
||||||
|
1
Eigen/LU
1
Eigen/LU
@ -16,7 +16,6 @@
|
|||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/misc/Solve.h"
|
|
||||||
#include "src/misc/Kernel.h"
|
#include "src/misc/Kernel.h"
|
||||||
#include "src/misc/Image.h"
|
#include "src/misc/Image.h"
|
||||||
#include "src/LU/FullPivLU.h"
|
#include "src/LU/FullPivLU.h"
|
||||||
|
@ -35,12 +35,8 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/misc/Solve.h"
|
|
||||||
#include "src/misc/SparseSolve.h"
|
|
||||||
|
|
||||||
#include "src/PaStiXSupport/PaStiXSupport.h"
|
#include "src/PaStiXSupport/PaStiXSupport.h"
|
||||||
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_PASTIXSUPPORT_MODULE_H
|
#endif // EIGEN_PASTIXSUPPORT_MODULE_H
|
||||||
|
1
Eigen/QR
1
Eigen/QR
@ -24,7 +24,6 @@
|
|||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/misc/Solve.h"
|
|
||||||
#include "src/QR/HouseholderQR.h"
|
#include "src/QR/HouseholderQR.h"
|
||||||
#include "src/QR/FullPivHouseholderQR.h"
|
#include "src/QR/FullPivHouseholderQR.h"
|
||||||
#include "src/QR/ColPivHouseholderQR.h"
|
#include "src/QR/ColPivHouseholderQR.h"
|
||||||
|
@ -21,8 +21,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/misc/Solve.h"
|
|
||||||
#include "src/misc/SparseSolve.h"
|
|
||||||
#include "src/CholmodSupport/CholmodSupport.h"
|
#include "src/CholmodSupport/CholmodSupport.h"
|
||||||
#include "src/SPQRSupport/SuiteSparseQRSupport.h"
|
#include "src/SPQRSupport/SuiteSparseQRSupport.h"
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/misc/Solve.h"
|
|
||||||
#include "src/SVD/SVDBase.h"
|
#include "src/SVD/SVDBase.h"
|
||||||
#include "src/SVD/JacobiSVD.h"
|
#include "src/SVD/JacobiSVD.h"
|
||||||
#if defined(EIGEN_USE_LAPACKE) && !defined(EIGEN_USE_LAPACKE_STRICT)
|
#if defined(EIGEN_USE_LAPACKE) && !defined(EIGEN_USE_LAPACKE_STRICT)
|
||||||
|
@ -34,11 +34,6 @@
|
|||||||
#error The SparseCholesky module has nothing to offer in MPL2 only mode
|
#error The SparseCholesky module has nothing to offer in MPL2 only mode
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
#include "src/misc/Solve.h"
|
|
||||||
#include "src/misc/SparseSolve.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "src/SparseCholesky/SimplicialCholesky.h"
|
#include "src/SparseCholesky/SimplicialCholesky.h"
|
||||||
|
|
||||||
#ifndef EIGEN_MPL2_ONLY
|
#ifndef EIGEN_MPL2_ONLY
|
||||||
|
@ -20,9 +20,6 @@
|
|||||||
* Please, see the documentation of the SparseLU class for more details.
|
* Please, see the documentation of the SparseLU class for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/misc/Solve.h"
|
|
||||||
#include "src/misc/SparseSolve.h"
|
|
||||||
|
|
||||||
// Ordering interface
|
// Ordering interface
|
||||||
#include "OrderingMethods"
|
#include "OrderingMethods"
|
||||||
|
|
||||||
|
@ -21,9 +21,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/misc/Solve.h"
|
|
||||||
#include "src/misc/SparseSolve.h"
|
|
||||||
|
|
||||||
#include "OrderingMethods"
|
#include "OrderingMethods"
|
||||||
#include "src/SparseCore/SparseColEtree.h"
|
#include "src/SparseCore/SparseColEtree.h"
|
||||||
#include "src/SparseQR/SparseQR.h"
|
#include "src/SparseQR/SparseQR.h"
|
||||||
|
@ -48,12 +48,8 @@ namespace Eigen { struct SluMatrix; }
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/misc/Solve.h"
|
|
||||||
#include "src/misc/SparseSolve.h"
|
|
||||||
|
|
||||||
#include "src/SuperLUSupport/SuperLUSupport.h"
|
#include "src/SuperLUSupport/SuperLUSupport.h"
|
||||||
|
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
|
||||||
#endif // EIGEN_SUPERLUSUPPORT_MODULE_H
|
#endif // EIGEN_SUPERLUSUPPORT_MODULE_H
|
||||||
|
@ -26,9 +26,6 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "src/misc/Solve.h"
|
|
||||||
#include "src/misc/SparseSolve.h"
|
|
||||||
|
|
||||||
#include "src/UmfPackSupport/UmfPackSupport.h"
|
#include "src/UmfPackSupport/UmfPackSupport.h"
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
@ -174,7 +174,6 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
|||||||
*
|
*
|
||||||
* \sa MatrixBase::ldlt(), SelfAdjointView::ldlt()
|
* \sa MatrixBase::ldlt(), SelfAdjointView::ldlt()
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Rhs>
|
template<typename Rhs>
|
||||||
inline const Solve<LDLT, Rhs>
|
inline const Solve<LDLT, Rhs>
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
solve(const MatrixBase<Rhs>& b) const
|
||||||
@ -184,17 +183,6 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
|||||||
&& "LDLT::solve(): invalid number of rows of the right hand side matrix b");
|
&& "LDLT::solve(): invalid number of rows of the right hand side matrix b");
|
||||||
return Solve<LDLT, Rhs>(*this, b.derived());
|
return Solve<LDLT, Rhs>(*this, b.derived());
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::solve_retval<LDLT, Rhs>
|
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "LDLT is not initialized.");
|
|
||||||
eigen_assert(m_matrix.rows()==b.rows()
|
|
||||||
&& "LDLT::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::solve_retval<LDLT, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
bool solveInPlace(MatrixBase<Derived> &bAndX) const;
|
bool solveInPlace(MatrixBase<Derived> &bAndX) const;
|
||||||
@ -524,23 +512,6 @@ void LDLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) cons
|
|||||||
dst = m_transpositions.transpose() * dst;
|
dst = m_transpositions.transpose() * dst;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename _MatrixType, int _UpLo, typename Rhs>
|
|
||||||
struct solve_retval<LDLT<_MatrixType,_UpLo>, Rhs>
|
|
||||||
: solve_retval_base<LDLT<_MatrixType,_UpLo>, Rhs>
|
|
||||||
{
|
|
||||||
typedef LDLT<_MatrixType,_UpLo> LDLTType;
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(LDLTType,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec()._solve_impl(rhs(),dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal use x = ldlt_object.solve(x);
|
/** \internal use x = ldlt_object.solve(x);
|
||||||
*
|
*
|
||||||
|
@ -117,7 +117,6 @@ template<typename _MatrixType, int _UpLo> class LLT
|
|||||||
*
|
*
|
||||||
* \sa solveInPlace(), MatrixBase::llt(), SelfAdjointView::llt()
|
* \sa solveInPlace(), MatrixBase::llt(), SelfAdjointView::llt()
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Rhs>
|
template<typename Rhs>
|
||||||
inline const Solve<LLT, Rhs>
|
inline const Solve<LLT, Rhs>
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
solve(const MatrixBase<Rhs>& b) const
|
||||||
@ -127,17 +126,6 @@ template<typename _MatrixType, int _UpLo> class LLT
|
|||||||
&& "LLT::solve(): invalid number of rows of the right hand side matrix b");
|
&& "LLT::solve(): invalid number of rows of the right hand side matrix b");
|
||||||
return Solve<LLT, Rhs>(*this, b.derived());
|
return Solve<LLT, Rhs>(*this, b.derived());
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::solve_retval<LLT, Rhs>
|
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
|
||||||
eigen_assert(m_matrix.rows()==b.rows()
|
|
||||||
&& "LLT::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::solve_retval<LLT, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
void solveInPlace(MatrixBase<Derived> &bAndX) const;
|
void solveInPlace(MatrixBase<Derived> &bAndX) const;
|
||||||
@ -433,24 +421,6 @@ void LLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) const
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename _MatrixType, int UpLo, typename Rhs>
|
|
||||||
struct solve_retval<LLT<_MatrixType, UpLo>, Rhs>
|
|
||||||
: solve_retval_base<LLT<_MatrixType, UpLo>, Rhs>
|
|
||||||
{
|
|
||||||
typedef LLT<_MatrixType,UpLo> LLTType;
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(LLTType,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dst = rhs();
|
|
||||||
dec().solveInPlace(dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal use x = llt_object.solve(x);
|
/** \internal use x = llt_object.solve(x);
|
||||||
*
|
*
|
||||||
* This is the \em in-place version of solve().
|
* This is the \em in-place version of solve().
|
||||||
|
@ -217,36 +217,6 @@ class CholmodBase : public SparseSolverBase<Derived>
|
|||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
|
||||||
*
|
|
||||||
* \sa compute()
|
|
||||||
*/
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::solve_retval<CholmodBase, Rhs>
|
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
|
||||||
eigen_assert(rows()==b.rows()
|
|
||||||
&& "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::solve_retval<CholmodBase, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
|
||||||
*
|
|
||||||
* \sa compute()
|
|
||||||
*/
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::sparse_solve_retval<CholmodBase, Rhs>
|
|
||||||
solve(const SparseMatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "LLT is not initialized.");
|
|
||||||
eigen_assert(rows()==b.rows()
|
|
||||||
&& "CholmodDecomposition::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::sparse_solve_retval<CholmodBase, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** Performs a symbolic decomposition on the sparsity pattern of \a matrix.
|
/** Performs a symbolic decomposition on the sparsity pattern of \a matrix.
|
||||||
*
|
*
|
||||||
* This function is particularly useful when solving for several problems having the same structure.
|
* This function is particularly useful when solving for several problems having the same structure.
|
||||||
@ -574,38 +544,6 @@ class CholmodDecomposition : public CholmodBase<_MatrixType, _UpLo, CholmodDecom
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename _MatrixType, int _UpLo, typename Derived, typename Rhs>
|
|
||||||
struct solve_retval<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
|
|
||||||
: solve_retval_base<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
|
|
||||||
{
|
|
||||||
typedef CholmodBase<_MatrixType,_UpLo,Derived> Dec;
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec()._solve_impl(rhs(),dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename _MatrixType, int _UpLo, typename Derived, typename Rhs>
|
|
||||||
struct sparse_solve_retval<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
|
|
||||||
: sparse_solve_retval_base<CholmodBase<_MatrixType,_UpLo,Derived>, Rhs>
|
|
||||||
{
|
|
||||||
typedef CholmodBase<_MatrixType,_UpLo,Derived> Dec;
|
|
||||||
EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec()._solve_impl(rhs(),dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_CHOLMODSUPPORT_H
|
#endif // EIGEN_CHOLMODSUPPORT_H
|
||||||
|
@ -64,9 +64,6 @@ template<typename Derived> class ArrayBase
|
|||||||
using Base::MaxSizeAtCompileTime;
|
using Base::MaxSizeAtCompileTime;
|
||||||
using Base::IsVectorAtCompileTime;
|
using Base::IsVectorAtCompileTime;
|
||||||
using Base::Flags;
|
using Base::Flags;
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
using Base::CoeffReadCost;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using Base::derived;
|
using Base::derived;
|
||||||
using Base::const_cast_derived;
|
using Base::const_cast_derived;
|
||||||
@ -123,11 +120,7 @@ template<typename Derived> class ArrayBase
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
Derived& operator=(const ArrayBase& other)
|
Derived& operator=(const ArrayBase& other)
|
||||||
{
|
{
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
|
|
||||||
#else
|
|
||||||
internal::call_assignment(derived(), other.derived());
|
internal::call_assignment(derived(), other.derived());
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@ -183,7 +176,6 @@ template<typename Derived> class ArrayBase
|
|||||||
{EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;}
|
{EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
/** replaces \c *this by \c *this - \a other.
|
/** replaces \c *this by \c *this - \a other.
|
||||||
*
|
*
|
||||||
* \returns a reference to \c *this
|
* \returns a reference to \c *this
|
||||||
@ -235,63 +227,6 @@ ArrayBase<Derived>::operator/=(const ArrayBase<OtherDerived>& other)
|
|||||||
call_assignment(derived(), other.derived(), internal::div_assign_op<Scalar>());
|
call_assignment(derived(), other.derived(), internal::div_assign_op<Scalar>());
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
/** replaces \c *this by \c *this - \a other.
|
|
||||||
*
|
|
||||||
* \returns a reference to \c *this
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_STRONG_INLINE Derived &
|
|
||||||
ArrayBase<Derived>::operator-=(const ArrayBase<OtherDerived> &other)
|
|
||||||
{
|
|
||||||
SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
|
||||||
tmp = other.derived();
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** replaces \c *this by \c *this + \a other.
|
|
||||||
*
|
|
||||||
* \returns a reference to \c *this
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_STRONG_INLINE Derived &
|
|
||||||
ArrayBase<Derived>::operator+=(const ArrayBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
|
||||||
tmp = other.derived();
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** replaces \c *this by \c *this * \a other coefficient wise.
|
|
||||||
*
|
|
||||||
* \returns a reference to \c *this
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_STRONG_INLINE Derived &
|
|
||||||
ArrayBase<Derived>::operator*=(const ArrayBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
SelfCwiseBinaryOp<internal::scalar_product_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
|
||||||
tmp = other.derived();
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** replaces \c *this by \c *this / \a other coefficient wise.
|
|
||||||
*
|
|
||||||
* \returns a reference to \c *this
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_STRONG_INLINE Derived &
|
|
||||||
ArrayBase<Derived>::operator/=(const ArrayBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
SelfCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
|
||||||
tmp = other.derived();
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
@ -13,487 +13,6 @@
|
|||||||
#define EIGEN_ASSIGN_H
|
#define EIGEN_ASSIGN_H
|
||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* Part 1 : the logic deciding a strategy for traversal and unrolling *
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
template <typename Derived, typename OtherDerived>
|
|
||||||
struct assign_traits
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum {
|
|
||||||
DstIsAligned = Derived::Flags & AlignedBit,
|
|
||||||
DstHasDirectAccess = Derived::Flags & DirectAccessBit,
|
|
||||||
SrcIsAligned = OtherDerived::Flags & AlignedBit,
|
|
||||||
JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum {
|
|
||||||
InnerSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::SizeAtCompileTime)
|
|
||||||
: int(Derived::Flags)&RowMajorBit ? int(Derived::ColsAtCompileTime)
|
|
||||||
: int(Derived::RowsAtCompileTime),
|
|
||||||
InnerMaxSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::MaxSizeAtCompileTime)
|
|
||||||
: int(Derived::Flags)&RowMajorBit ? int(Derived::MaxColsAtCompileTime)
|
|
||||||
: int(Derived::MaxRowsAtCompileTime),
|
|
||||||
MaxSizeAtCompileTime = Derived::SizeAtCompileTime,
|
|
||||||
PacketSize = packet_traits<typename Derived::Scalar>::size
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
StorageOrdersAgree = (int(Derived::IsRowMajor) == int(OtherDerived::IsRowMajor)),
|
|
||||||
MightVectorize = StorageOrdersAgree
|
|
||||||
&& (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit),
|
|
||||||
MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0
|
|
||||||
&& int(DstIsAligned) && int(SrcIsAligned),
|
|
||||||
MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit),
|
|
||||||
MayLinearVectorize = MightVectorize && MayLinearize && DstHasDirectAccess
|
|
||||||
&& (DstIsAligned || MaxSizeAtCompileTime == Dynamic),
|
|
||||||
/* If the destination isn't aligned, we have to do runtime checks and we don't unroll,
|
|
||||||
so it's only good for large enough sizes. */
|
|
||||||
MaySliceVectorize = MightVectorize && DstHasDirectAccess
|
|
||||||
&& (int(InnerMaxSize)==Dynamic || int(InnerMaxSize)>=3*PacketSize)
|
|
||||||
/* slice vectorization can be slow, so we only want it if the slices are big, which is
|
|
||||||
indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block
|
|
||||||
in a fixed-size matrix */
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum {
|
|
||||||
Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal)
|
|
||||||
: int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
|
|
||||||
: int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
|
|
||||||
: int(MayLinearize) ? int(LinearTraversal)
|
|
||||||
: int(DefaultTraversal),
|
|
||||||
Vectorized = int(Traversal) == InnerVectorizedTraversal
|
|
||||||
|| int(Traversal) == LinearVectorizedTraversal
|
|
||||||
|| int(Traversal) == SliceVectorizedTraversal
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum {
|
|
||||||
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1),
|
|
||||||
MayUnrollCompletely = int(Derived::SizeAtCompileTime) != Dynamic
|
|
||||||
&& int(OtherDerived::CoeffReadCost) != Dynamic
|
|
||||||
&& int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit),
|
|
||||||
MayUnrollInner = int(InnerSize) != Dynamic
|
|
||||||
&& int(OtherDerived::CoeffReadCost) != Dynamic
|
|
||||||
&& int(InnerSize) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit)
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum {
|
|
||||||
Unrolling = (int(Traversal) == int(InnerVectorizedTraversal) || int(Traversal) == int(DefaultTraversal))
|
|
||||||
? (
|
|
||||||
int(MayUnrollCompletely) ? int(CompleteUnrolling)
|
|
||||||
: int(MayUnrollInner) ? int(InnerUnrolling)
|
|
||||||
: int(NoUnrolling)
|
|
||||||
)
|
|
||||||
: int(Traversal) == int(LinearVectorizedTraversal)
|
|
||||||
? ( bool(MayUnrollCompletely) && bool(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) )
|
|
||||||
: int(Traversal) == int(LinearTraversal)
|
|
||||||
? ( bool(MayUnrollCompletely) ? int(CompleteUnrolling) : int(NoUnrolling) )
|
|
||||||
: int(NoUnrolling)
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef EIGEN_DEBUG_ASSIGN
|
|
||||||
static void debug()
|
|
||||||
{
|
|
||||||
EIGEN_DEBUG_VAR(DstIsAligned)
|
|
||||||
EIGEN_DEBUG_VAR(SrcIsAligned)
|
|
||||||
EIGEN_DEBUG_VAR(JointAlignment)
|
|
||||||
EIGEN_DEBUG_VAR(Derived::SizeAtCompileTime)
|
|
||||||
EIGEN_DEBUG_VAR(OtherDerived::CoeffReadCost)
|
|
||||||
EIGEN_DEBUG_VAR(InnerSize)
|
|
||||||
EIGEN_DEBUG_VAR(InnerMaxSize)
|
|
||||||
EIGEN_DEBUG_VAR(PacketSize)
|
|
||||||
EIGEN_DEBUG_VAR(StorageOrdersAgree)
|
|
||||||
EIGEN_DEBUG_VAR(MightVectorize)
|
|
||||||
EIGEN_DEBUG_VAR(MayLinearize)
|
|
||||||
EIGEN_DEBUG_VAR(MayInnerVectorize)
|
|
||||||
EIGEN_DEBUG_VAR(MayLinearVectorize)
|
|
||||||
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
|
||||||
EIGEN_DEBUG_VAR(Traversal)
|
|
||||||
EIGEN_DEBUG_VAR(UnrollingLimit)
|
|
||||||
EIGEN_DEBUG_VAR(MayUnrollCompletely)
|
|
||||||
EIGEN_DEBUG_VAR(MayUnrollInner)
|
|
||||||
EIGEN_DEBUG_VAR(Unrolling)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* Part 2 : meta-unrollers
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/************************
|
|
||||||
*** Default traversal ***
|
|
||||||
************************/
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Index, int Stop>
|
|
||||||
struct assign_DefaultTraversal_CompleteUnrolling
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
outer = Index / Derived1::InnerSizeAtCompileTime,
|
|
||||||
inner = Index % Derived1::InnerSizeAtCompileTime
|
|
||||||
};
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
dst.copyCoeffByOuterInner(outer, inner, src);
|
|
||||||
assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Stop>
|
|
||||||
struct assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Index, int Stop>
|
|
||||||
struct assign_DefaultTraversal_InnerUnrolling
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer)
|
|
||||||
{
|
|
||||||
dst.copyCoeffByOuterInner(outer, Index, src);
|
|
||||||
assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, outer);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Stop>
|
|
||||||
struct assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Stop, Stop>
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/***********************
|
|
||||||
*** Linear traversal ***
|
|
||||||
***********************/
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Index, int Stop>
|
|
||||||
struct assign_LinearTraversal_CompleteUnrolling
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
dst.copyCoeff(Index, src);
|
|
||||||
assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Stop>
|
|
||||||
struct assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**************************
|
|
||||||
*** Inner vectorization ***
|
|
||||||
**************************/
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Index, int Stop>
|
|
||||||
struct assign_innervec_CompleteUnrolling
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
outer = Index / Derived1::InnerSizeAtCompileTime,
|
|
||||||
inner = Index % Derived1::InnerSizeAtCompileTime,
|
|
||||||
JointAlignment = assign_traits<Derived1,Derived2>::JointAlignment
|
|
||||||
};
|
|
||||||
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
dst.template copyPacketByOuterInner<Derived2, Aligned, JointAlignment>(outer, inner, src);
|
|
||||||
assign_innervec_CompleteUnrolling<Derived1, Derived2,
|
|
||||||
Index+packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Stop>
|
|
||||||
struct assign_innervec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
|
|
||||||
{
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Index, int Stop>
|
|
||||||
struct assign_innervec_InnerUnrolling
|
|
||||||
{
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer)
|
|
||||||
{
|
|
||||||
dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, Index, src);
|
|
||||||
assign_innervec_InnerUnrolling<Derived1, Derived2,
|
|
||||||
Index+packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src, outer);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Stop>
|
|
||||||
struct assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
|
|
||||||
{
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* Part 3 : implementation of all cases
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2,
|
|
||||||
int Traversal = assign_traits<Derived1, Derived2>::Traversal,
|
|
||||||
int Unrolling = assign_traits<Derived1, Derived2>::Unrolling,
|
|
||||||
int Version = Specialized>
|
|
||||||
struct assign_impl;
|
|
||||||
|
|
||||||
/************************
|
|
||||||
*** Default traversal ***
|
|
||||||
************************/
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Unrolling, int Version>
|
|
||||||
struct assign_impl<Derived1, Derived2, InvalidTraversal, Unrolling, Version>
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &, const Derived2 &) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Version>
|
|
||||||
struct assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling, Version>
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
const Index innerSize = dst.innerSize();
|
|
||||||
const Index outerSize = dst.outerSize();
|
|
||||||
for(Index outer = 0; outer < outerSize; ++outer)
|
|
||||||
for(Index inner = 0; inner < innerSize; ++inner)
|
|
||||||
dst.copyCoeffByOuterInner(outer, inner, src);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Version>
|
|
||||||
struct assign_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling, Version>
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
|
|
||||||
::run(dst, src);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Version>
|
|
||||||
struct assign_impl<Derived1, Derived2, DefaultTraversal, InnerUnrolling, Version>
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
const Index outerSize = dst.outerSize();
|
|
||||||
for(Index outer = 0; outer < outerSize; ++outer)
|
|
||||||
assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, 0, Derived1::InnerSizeAtCompileTime>
|
|
||||||
::run(dst, src, outer);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/***********************
|
|
||||||
*** Linear traversal ***
|
|
||||||
***********************/
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Version>
|
|
||||||
struct assign_impl<Derived1, Derived2, LinearTraversal, NoUnrolling, Version>
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
const Index size = dst.size();
|
|
||||||
for(Index i = 0; i < size; ++i)
|
|
||||||
dst.copyCoeff(i, src);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Version>
|
|
||||||
struct assign_impl<Derived1, Derived2, LinearTraversal, CompleteUnrolling, Version>
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
|
|
||||||
::run(dst, src);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**************************
|
|
||||||
*** Inner vectorization ***
|
|
||||||
**************************/
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Version>
|
|
||||||
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, NoUnrolling, Version>
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
const Index innerSize = dst.innerSize();
|
|
||||||
const Index outerSize = dst.outerSize();
|
|
||||||
const Index packetSize = packet_traits<typename Derived1::Scalar>::size;
|
|
||||||
for(Index outer = 0; outer < outerSize; ++outer)
|
|
||||||
for(Index inner = 0; inner < innerSize; inner+=packetSize)
|
|
||||||
dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, inner, src);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Version>
|
|
||||||
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, CompleteUnrolling, Version>
|
|
||||||
{
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
|
|
||||||
::run(dst, src);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Version>
|
|
||||||
struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, InnerUnrolling, Version>
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
const Index outerSize = dst.outerSize();
|
|
||||||
for(Index outer = 0; outer < outerSize; ++outer)
|
|
||||||
assign_innervec_InnerUnrolling<Derived1, Derived2, 0, Derived1::InnerSizeAtCompileTime>
|
|
||||||
::run(dst, src, outer);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************
|
|
||||||
*** Linear vectorization ***
|
|
||||||
***************************/
|
|
||||||
|
|
||||||
template <bool IsAligned = false>
|
|
||||||
struct unaligned_assign_impl
|
|
||||||
{
|
|
||||||
template <typename Derived, typename OtherDerived>
|
|
||||||
static EIGEN_STRONG_INLINE void run(const Derived&, OtherDerived&, typename Derived::Index, typename Derived::Index) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct unaligned_assign_impl<false>
|
|
||||||
{
|
|
||||||
// MSVC must not inline this functions. If it does, it fails to optimize the
|
|
||||||
// packet access path.
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
template <typename Derived, typename OtherDerived>
|
|
||||||
static EIGEN_DONT_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end)
|
|
||||||
#else
|
|
||||||
template <typename Derived, typename OtherDerived>
|
|
||||||
static EIGEN_STRONG_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
for (typename Derived::Index index = start; index < end; ++index)
|
|
||||||
dst.copyCoeff(index, src);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Version>
|
|
||||||
struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling, Version>
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
const Index size = dst.size();
|
|
||||||
typedef packet_traits<typename Derived1::Scalar> PacketTraits;
|
|
||||||
enum {
|
|
||||||
packetSize = PacketTraits::size,
|
|
||||||
dstAlignment = PacketTraits::AlignedOnScalar ? Aligned : int(assign_traits<Derived1,Derived2>::DstIsAligned) ,
|
|
||||||
srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment
|
|
||||||
};
|
|
||||||
const Index alignedStart = assign_traits<Derived1,Derived2>::DstIsAligned ? 0
|
|
||||||
: internal::first_aligned(&dst.coeffRef(0), size);
|
|
||||||
const Index alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize;
|
|
||||||
|
|
||||||
unaligned_assign_impl<assign_traits<Derived1,Derived2>::DstIsAligned!=0>::run(src,dst,0,alignedStart);
|
|
||||||
|
|
||||||
for(Index index = alignedStart; index < alignedEnd; index += packetSize)
|
|
||||||
{
|
|
||||||
dst.template copyPacket<Derived2, dstAlignment, srcAlignment>(index, src);
|
|
||||||
}
|
|
||||||
|
|
||||||
unaligned_assign_impl<>::run(src,dst,alignedEnd,size);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Version>
|
|
||||||
struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling, Version>
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
enum { size = Derived1::SizeAtCompileTime,
|
|
||||||
packetSize = packet_traits<typename Derived1::Scalar>::size,
|
|
||||||
alignedSize = (size/packetSize)*packetSize };
|
|
||||||
|
|
||||||
assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, alignedSize>::run(dst, src);
|
|
||||||
assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, alignedSize, size>::run(dst, src);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**************************
|
|
||||||
*** Slice vectorization ***
|
|
||||||
***************************/
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int Version>
|
|
||||||
struct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling, Version>
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
typedef packet_traits<typename Derived1::Scalar> PacketTraits;
|
|
||||||
enum {
|
|
||||||
packetSize = PacketTraits::size,
|
|
||||||
alignable = PacketTraits::AlignedOnScalar,
|
|
||||||
dstAlignment = alignable ? Aligned : int(assign_traits<Derived1,Derived2>::DstIsAligned) ,
|
|
||||||
srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment
|
|
||||||
};
|
|
||||||
const Index packetAlignedMask = packetSize - 1;
|
|
||||||
const Index innerSize = dst.innerSize();
|
|
||||||
const Index outerSize = dst.outerSize();
|
|
||||||
const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0;
|
|
||||||
Index alignedStart = ((!alignable) || assign_traits<Derived1,Derived2>::DstIsAligned) ? 0
|
|
||||||
: internal::first_aligned(&dst.coeffRef(0,0), innerSize);
|
|
||||||
|
|
||||||
for(Index outer = 0; outer < outerSize; ++outer)
|
|
||||||
{
|
|
||||||
const Index alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask);
|
|
||||||
// do the non-vectorizable part of the assignment
|
|
||||||
for(Index inner = 0; inner<alignedStart ; ++inner)
|
|
||||||
dst.copyCoeffByOuterInner(outer, inner, src);
|
|
||||||
|
|
||||||
// do the vectorizable part of the assignment
|
|
||||||
for(Index inner = alignedStart; inner<alignedEnd; inner+=packetSize)
|
|
||||||
dst.template copyPacketByOuterInner<Derived2, dstAlignment, Unaligned>(outer, inner, src);
|
|
||||||
|
|
||||||
// do the non-vectorizable part of the assignment
|
|
||||||
for(Index inner = alignedEnd; inner<innerSize ; ++inner)
|
|
||||||
dst.copyCoeffByOuterInner(outer, inner, src);
|
|
||||||
|
|
||||||
alignedStart = std::min<Index>((alignedStart+alignedStep)%packetSize, innerSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* Part 4 : implementation of DenseBase methods
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
@ -508,71 +27,12 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
|
|||||||
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
|
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
|
||||||
EIGEN_STATIC_ASSERT(SameType,YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
EIGEN_STATIC_ASSERT(SameType,YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
eigen_assert(rows() == other.rows() && cols() == other.cols());
|
eigen_assert(rows() == other.rows() && cols() == other.cols());
|
||||||
internal::call_assignment_no_alias(derived(),other.derived());
|
internal::call_assignment_no_alias(derived(),other.derived());
|
||||||
|
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
#ifdef EIGEN_DEBUG_ASSIGN
|
|
||||||
internal::assign_traits<Derived, OtherDerived>::debug();
|
|
||||||
#endif
|
|
||||||
eigen_assert(rows() == other.rows() && cols() == other.cols());
|
|
||||||
internal::assign_impl<Derived, OtherDerived, int(SameType) ? int(internal::assign_traits<Derived, OtherDerived>::Traversal)
|
|
||||||
: int(InvalidTraversal)>::run(derived(),other.derived());
|
|
||||||
|
|
||||||
#ifndef EIGEN_NO_DEBUG
|
|
||||||
checkTransposeAliasing(other.derived());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Derived, typename OtherDerived,
|
|
||||||
bool EvalBeforeAssigning = (int(internal::traits<OtherDerived>::Flags) & EvalBeforeAssigningBit) != 0,
|
|
||||||
bool NeedToTranspose = ((int(Derived::RowsAtCompileTime) == 1 && int(OtherDerived::ColsAtCompileTime) == 1)
|
|
||||||
| // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&".
|
|
||||||
// revert to || as soon as not needed anymore.
|
|
||||||
(int(Derived::ColsAtCompileTime) == 1 && int(OtherDerived::RowsAtCompileTime) == 1))
|
|
||||||
&& int(Derived::SizeAtCompileTime) != 1>
|
|
||||||
struct assign_selector;
|
|
||||||
|
|
||||||
template<typename Derived, typename OtherDerived>
|
|
||||||
struct assign_selector<Derived,OtherDerived,false,false> {
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); }
|
|
||||||
template<typename ActualDerived, typename ActualOtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { other.evalTo(dst); return dst; }
|
|
||||||
};
|
|
||||||
template<typename Derived, typename OtherDerived>
|
|
||||||
struct assign_selector<Derived,OtherDerived,true,false> {
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); }
|
|
||||||
};
|
|
||||||
template<typename Derived, typename OtherDerived>
|
|
||||||
struct assign_selector<Derived,OtherDerived,false,true> {
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); }
|
|
||||||
template<typename ActualDerived, typename ActualOtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { Transpose<ActualDerived> dstTrans(dst); other.evalTo(dstTrans); return dst; }
|
|
||||||
};
|
|
||||||
template<typename Derived, typename OtherDerived>
|
|
||||||
struct assign_selector<Derived,OtherDerived,true,true> {
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); }
|
|
||||||
};
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@ -624,53 +84,6 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const ReturnByValue<
|
|||||||
other.derived().evalTo(derived());
|
other.derived().evalTo(derived());
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
return internal::assign_selector<Derived,OtherDerived>::run(derived(), other.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase& other)
|
|
||||||
{
|
|
||||||
return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const MatrixBase& other)
|
|
||||||
{
|
|
||||||
return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
template <typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
return internal::assign_selector<Derived,OtherDerived>::run(derived(), other.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
template <typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const EigenBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
return internal::assign_selector<Derived,OtherDerived,false>::evalTo(derived(), other.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
return internal::assign_selector<Derived,OtherDerived,false>::evalTo(derived(), other.derived());
|
|
||||||
}
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
@ -695,13 +695,7 @@ void call_assignment(const Dst& dst, const Src& src)
|
|||||||
template<typename Dst, typename Src, typename Func>
|
template<typename Dst, typename Src, typename Func>
|
||||||
void call_assignment(Dst& dst, const Src& src, const Func& func, typename enable_if<evaluator_traits<Src>::AssumeAliasing==1, void*>::type = 0)
|
void call_assignment(Dst& dst, const Src& src, const Func& func, typename enable_if<evaluator_traits<Src>::AssumeAliasing==1, void*>::type = 0)
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
typename plain_matrix_type<Src>::type tmp(src);
|
typename plain_matrix_type<Src>::type tmp(src);
|
||||||
#else
|
|
||||||
typename Src::PlainObject tmp(src.rows(), src.cols());
|
|
||||||
call_assignment_no_alias(tmp, src, internal::assign_op<typename Dst::Scalar>());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
call_assignment_no_alias(dst, tmp, func);
|
call_assignment_no_alias(dst, tmp, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,8 +328,6 @@ class TridiagonalMatrix : public BandMatrix<Scalar,Size,Size,Options&SelfAdjoint
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
struct BandShape {};
|
struct BandShape {};
|
||||||
|
|
||||||
template<typename _Scalar, int _Rows, int _Cols, int _Supers, int _Subs, int _Options>
|
template<typename _Scalar, int _Rows, int _Cols, int _Supers, int _Subs, int _Options>
|
||||||
@ -347,8 +345,6 @@ struct evaluator_traits<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<> struct AssignmentKind<DenseShape,BandShape> { typedef EigenBase2EigenBase Kind; };
|
template<> struct AssignmentKind<DenseShape,BandShape> { typedef EigenBase2EigenBase Kind; };
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
|
@ -84,26 +84,11 @@ struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel> > : traits<XprTyp
|
|||||||
// IsAligned is needed by MapBase's assertions
|
// IsAligned is needed by MapBase's assertions
|
||||||
// We can sefely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the respective evaluator
|
// We can sefely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the respective evaluator
|
||||||
IsAligned = 0,
|
IsAligned = 0,
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits<Scalar>::size) == 0)
|
|
||||||
&& (InnerStrideAtCompileTime == 1)
|
|
||||||
? PacketAccessBit : 0,
|
|
||||||
MaskAlignedBit = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % EIGEN_ALIGN_BYTES) == 0)) ? AlignedBit : 0,
|
|
||||||
FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1 || (InnerPanel && (traits<XprType>::Flags&LinearAccessBit))) ? LinearAccessBit : 0,
|
|
||||||
FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
|
|
||||||
FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
|
|
||||||
Flags0 = traits<XprType>::Flags & ( (HereditaryBits & ~RowMajorBit) |
|
|
||||||
DirectAccessBit |
|
|
||||||
MaskPacketAccessBit |
|
|
||||||
MaskAlignedBit),
|
|
||||||
Flags = Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit
|
|
||||||
#else
|
|
||||||
// FIXME, this traits is rather specialized for dense object and it needs to be cleaned further
|
// FIXME, this traits is rather specialized for dense object and it needs to be cleaned further
|
||||||
FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
|
FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
|
||||||
FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
|
FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
|
||||||
Flags = (traits<XprType>::Flags & DirectAccessBit) | FlagsLvalueBit | FlagsRowMajorBit
|
Flags = (traits<XprType>::Flags & DirectAccessBit) | FlagsLvalueBit | FlagsRowMajorBit
|
||||||
// FIXME DirectAccessBit should not be handled by expressions
|
// FIXME DirectAccessBit should not be handled by expressions
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,18 +17,11 @@ namespace internal {
|
|||||||
template<typename Derived, int UnrollCount>
|
template<typename Derived, int UnrollCount>
|
||||||
struct all_unroller
|
struct all_unroller
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
typedef typename Derived::ExpressionTraits Traits;
|
typedef typename Derived::ExpressionTraits Traits;
|
||||||
enum {
|
enum {
|
||||||
col = (UnrollCount-1) / Traits::RowsAtCompileTime,
|
col = (UnrollCount-1) / Traits::RowsAtCompileTime,
|
||||||
row = (UnrollCount-1) % Traits::RowsAtCompileTime
|
row = (UnrollCount-1) % Traits::RowsAtCompileTime
|
||||||
};
|
};
|
||||||
#else
|
|
||||||
enum {
|
|
||||||
col = (UnrollCount-1) / Derived::RowsAtCompileTime,
|
|
||||||
row = (UnrollCount-1) % Derived::RowsAtCompileTime
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline bool run(const Derived &mat)
|
static inline bool run(const Derived &mat)
|
||||||
{
|
{
|
||||||
@ -51,18 +44,11 @@ struct all_unroller<Derived, Dynamic>
|
|||||||
template<typename Derived, int UnrollCount>
|
template<typename Derived, int UnrollCount>
|
||||||
struct any_unroller
|
struct any_unroller
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
typedef typename Derived::ExpressionTraits Traits;
|
typedef typename Derived::ExpressionTraits Traits;
|
||||||
enum {
|
enum {
|
||||||
col = (UnrollCount-1) / Traits::RowsAtCompileTime,
|
col = (UnrollCount-1) / Traits::RowsAtCompileTime,
|
||||||
row = (UnrollCount-1) % Traits::RowsAtCompileTime
|
row = (UnrollCount-1) % Traits::RowsAtCompileTime
|
||||||
};
|
};
|
||||||
#else
|
|
||||||
enum {
|
|
||||||
col = (UnrollCount-1) / Derived::RowsAtCompileTime,
|
|
||||||
row = (UnrollCount-1) % Derived::RowsAtCompileTime
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline bool run(const Derived &mat)
|
static inline bool run(const Derived &mat)
|
||||||
{
|
{
|
||||||
@ -94,7 +80,6 @@ struct any_unroller<Derived, Dynamic>
|
|||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline bool DenseBase<Derived>::all() const
|
inline bool DenseBase<Derived>::all() const
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
typedef typename internal::evaluator<Derived>::type Evaluator;
|
typedef typename internal::evaluator<Derived>::type Evaluator;
|
||||||
enum {
|
enum {
|
||||||
unroll = SizeAtCompileTime != Dynamic
|
unroll = SizeAtCompileTime != Dynamic
|
||||||
@ -112,24 +97,6 @@ inline bool DenseBase<Derived>::all() const
|
|||||||
if (!evaluator.coeff(i, j)) return false;
|
if (!evaluator.coeff(i, j)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
enum {
|
|
||||||
unroll = SizeAtCompileTime != Dynamic
|
|
||||||
&& CoeffReadCost != Dynamic
|
|
||||||
&& NumTraits<Scalar>::AddCost != Dynamic
|
|
||||||
&& SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
|
|
||||||
};
|
|
||||||
|
|
||||||
if(unroll)
|
|
||||||
return internal::all_unroller<Derived, unroll ? int(SizeAtCompileTime) : Dynamic>::run(derived());
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(Index j = 0; j < cols(); ++j)
|
|
||||||
for(Index i = 0; i < rows(); ++i)
|
|
||||||
if (!coeff(i, j)) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns true if at least one coefficient is true
|
/** \returns true if at least one coefficient is true
|
||||||
@ -139,7 +106,6 @@ inline bool DenseBase<Derived>::all() const
|
|||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline bool DenseBase<Derived>::any() const
|
inline bool DenseBase<Derived>::any() const
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
typedef typename internal::evaluator<Derived>::type Evaluator;
|
typedef typename internal::evaluator<Derived>::type Evaluator;
|
||||||
enum {
|
enum {
|
||||||
unroll = SizeAtCompileTime != Dynamic
|
unroll = SizeAtCompileTime != Dynamic
|
||||||
@ -157,23 +123,6 @@ inline bool DenseBase<Derived>::any() const
|
|||||||
if (evaluator.coeff(i, j)) return true;
|
if (evaluator.coeff(i, j)) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
enum {
|
|
||||||
unroll = SizeAtCompileTime != Dynamic
|
|
||||||
&& CoeffReadCost != Dynamic
|
|
||||||
&& NumTraits<Scalar>::AddCost != Dynamic
|
|
||||||
&& SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
|
|
||||||
};
|
|
||||||
if(unroll)
|
|
||||||
return internal::any_unroller<Derived, unroll ? int(SizeAtCompileTime) : Dynamic>::run(derived());
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(Index j = 0; j < cols(); ++j)
|
|
||||||
for(Index i = 0; i < rows(); ++i)
|
|
||||||
if (coeff(i, j)) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the number of coefficients which evaluate to true
|
/** \returns the number of coefficients which evaluate to true
|
||||||
|
@ -66,28 +66,7 @@ struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
|||||||
typedef typename remove_reference<LhsNested>::type _LhsNested;
|
typedef typename remove_reference<LhsNested>::type _LhsNested;
|
||||||
typedef typename remove_reference<RhsNested>::type _RhsNested;
|
typedef typename remove_reference<RhsNested>::type _RhsNested;
|
||||||
enum {
|
enum {
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
LhsFlags = _LhsNested::Flags,
|
|
||||||
RhsFlags = _RhsNested::Flags,
|
|
||||||
SameType = is_same<typename _LhsNested::Scalar,typename _RhsNested::Scalar>::value,
|
|
||||||
StorageOrdersAgree = (int(Lhs::Flags)&RowMajorBit)==(int(Rhs::Flags)&RowMajorBit),
|
|
||||||
Flags0 = (int(LhsFlags) | int(RhsFlags)) & (
|
|
||||||
HereditaryBits
|
|
||||||
| (int(LhsFlags) & int(RhsFlags) &
|
|
||||||
( AlignedBit
|
|
||||||
| (StorageOrdersAgree ? LinearAccessBit : 0)
|
|
||||||
| (functor_traits<BinaryOp>::PacketAccess && StorageOrdersAgree && SameType ? PacketAccessBit : 0)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit),
|
|
||||||
|
|
||||||
LhsCoeffReadCost = _LhsNested::CoeffReadCost,
|
|
||||||
RhsCoeffReadCost = _RhsNested::CoeffReadCost,
|
|
||||||
CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + functor_traits<BinaryOp>::Cost
|
|
||||||
#else
|
|
||||||
Flags = _LhsNested::Flags & RowMajorBit
|
Flags = _LhsNested::Flags & RowMajorBit
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
@ -163,46 +142,6 @@ class CwiseBinaryOp : internal::no_assignment_operator,
|
|||||||
const BinaryOp m_functor;
|
const BinaryOp m_functor;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename BinaryOp, typename Lhs, typename Rhs>
|
|
||||||
class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense>
|
|
||||||
: public internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
|
|
||||||
{
|
|
||||||
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived;
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef typename internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base;
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE( Derived )
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const
|
|
||||||
{
|
|
||||||
return derived().functor()(derived().lhs().coeff(rowId, colId),
|
|
||||||
derived().rhs().coeff(rowId, colId));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
|
|
||||||
{
|
|
||||||
return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(rowId, colId),
|
|
||||||
derived().rhs().template packet<LoadMode>(rowId, colId));
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
|
|
||||||
{
|
|
||||||
return derived().functor()(derived().lhs().coeff(index),
|
|
||||||
derived().rhs().coeff(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
|
|
||||||
{
|
|
||||||
return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(index),
|
|
||||||
derived().rhs().template packet<LoadMode>(index));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
// Generic API dispatcher
|
// Generic API dispatcher
|
||||||
template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
|
template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
|
||||||
class CwiseBinaryOpImpl
|
class CwiseBinaryOpImpl
|
||||||
@ -211,7 +150,6 @@ class CwiseBinaryOpImpl
|
|||||||
public:
|
public:
|
||||||
typedef typename internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base;
|
typedef typename internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
/** replaces \c *this by \c *this - \a other.
|
/** replaces \c *this by \c *this - \a other.
|
||||||
*
|
*
|
||||||
@ -222,12 +160,7 @@ template<typename OtherDerived>
|
|||||||
EIGEN_STRONG_INLINE Derived &
|
EIGEN_STRONG_INLINE Derived &
|
||||||
MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
|
MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar>());
|
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar>());
|
||||||
#else
|
|
||||||
SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
|
||||||
tmp = other.derived();
|
|
||||||
#endif
|
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,12 +173,7 @@ template<typename OtherDerived>
|
|||||||
EIGEN_STRONG_INLINE Derived &
|
EIGEN_STRONG_INLINE Derived &
|
||||||
MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
|
MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar>());
|
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar>());
|
||||||
#else
|
|
||||||
SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived> tmp(derived());
|
|
||||||
tmp = other.derived();
|
|
||||||
#endif
|
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,16 +35,7 @@ template<typename NullaryOp, typename PlainObjectType>
|
|||||||
struct traits<CwiseNullaryOp<NullaryOp, PlainObjectType> > : traits<PlainObjectType>
|
struct traits<CwiseNullaryOp<NullaryOp, PlainObjectType> > : traits<PlainObjectType>
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
Flags = (traits<PlainObjectType>::Flags
|
|
||||||
& ( HereditaryBits
|
|
||||||
| (functor_has_linear_access<NullaryOp>::ret ? LinearAccessBit : 0)
|
|
||||||
| (functor_traits<NullaryOp>::PacketAccess ? PacketAccessBit : 0)))
|
|
||||||
| (functor_traits<NullaryOp>::IsRepeatable ? 0 : EvalBeforeNestingBit),
|
|
||||||
CoeffReadCost = functor_traits<NullaryOp>::Cost
|
|
||||||
#else
|
|
||||||
Flags = traits<PlainObjectType>::Flags & RowMajorBit
|
Flags = traits<PlainObjectType>::Flags & RowMajorBit
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -44,14 +44,7 @@ struct traits<CwiseUnaryOp<UnaryOp, XprType> >
|
|||||||
typedef typename XprType::Nested XprTypeNested;
|
typedef typename XprType::Nested XprTypeNested;
|
||||||
typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
|
typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
|
||||||
enum {
|
enum {
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
Flags = _XprTypeNested::Flags & (
|
|
||||||
HereditaryBits | LinearAccessBit | AlignedBit
|
|
||||||
| (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0)),
|
|
||||||
CoeffReadCost = _XprTypeNested::CoeffReadCost + functor_traits<UnaryOp>::Cost
|
|
||||||
#else
|
|
||||||
Flags = _XprTypeNested::Flags & RowMajorBit
|
Flags = _XprTypeNested::Flags & RowMajorBit
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -97,45 +90,6 @@ class CwiseUnaryOp : internal::no_assignment_operator,
|
|||||||
const UnaryOp m_functor;
|
const UnaryOp m_functor;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
// This is the generic implementation for dense storage.
|
|
||||||
// It can be used for any expression types implementing the dense concept.
|
|
||||||
template<typename UnaryOp, typename XprType>
|
|
||||||
class CwiseUnaryOpImpl<UnaryOp,XprType,Dense>
|
|
||||||
: public internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef CwiseUnaryOp<UnaryOp, XprType> Derived;
|
|
||||||
typedef typename internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const
|
|
||||||
{
|
|
||||||
return derived().functor()(derived().nestedExpression().coeff(rowId, colId));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
|
|
||||||
{
|
|
||||||
return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(rowId, colId));
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
|
|
||||||
{
|
|
||||||
return derived().functor()(derived().nestedExpression().coeff(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
|
|
||||||
{
|
|
||||||
return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(index));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
// Generic API dispatcher
|
// Generic API dispatcher
|
||||||
template<typename UnaryOp, typename XprType, typename StorageKind>
|
template<typename UnaryOp, typename XprType, typename StorageKind>
|
||||||
class CwiseUnaryOpImpl
|
class CwiseUnaryOpImpl
|
||||||
@ -144,7 +98,6 @@ class CwiseUnaryOpImpl
|
|||||||
public:
|
public:
|
||||||
typedef typename internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
|
typedef typename internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
|
||||||
};
|
};
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
@ -37,12 +37,7 @@ struct traits<CwiseUnaryView<ViewOp, MatrixType> >
|
|||||||
typedef typename MatrixType::Nested MatrixTypeNested;
|
typedef typename MatrixType::Nested MatrixTypeNested;
|
||||||
typedef typename remove_all<MatrixTypeNested>::type _MatrixTypeNested;
|
typedef typename remove_all<MatrixTypeNested>::type _MatrixTypeNested;
|
||||||
enum {
|
enum {
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
Flags = (traits<_MatrixTypeNested>::Flags & (HereditaryBits | LvalueBit | LinearAccessBit | DirectAccessBit)),
|
|
||||||
CoeffReadCost = traits<_MatrixTypeNested>::CoeffReadCost + functor_traits<ViewOp>::Cost,
|
|
||||||
#else
|
|
||||||
Flags = traits<_MatrixTypeNested>::Flags & (RowMajorBit | LvalueBit | DirectAccessBit), // FIXME DirectAccessBit should not be handled by expressions
|
Flags = traits<_MatrixTypeNested>::Flags & (RowMajorBit | LvalueBit | DirectAccessBit), // FIXME DirectAccessBit should not be handled by expressions
|
||||||
#endif
|
|
||||||
MatrixTypeInnerStride = inner_stride_at_compile_time<MatrixType>::ret,
|
MatrixTypeInnerStride = inner_stride_at_compile_time<MatrixType>::ret,
|
||||||
// need to cast the sizeof's from size_t to int explicitly, otherwise:
|
// need to cast the sizeof's from size_t to int explicitly, otherwise:
|
||||||
// "error: no integral type can represent all of the enumerator values
|
// "error: no integral type can represent all of the enumerator values
|
||||||
@ -93,7 +88,6 @@ class CwiseUnaryView : public CwiseUnaryViewImpl<ViewOp, MatrixType, typename in
|
|||||||
ViewOp m_functor;
|
ViewOp m_functor;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
// Generic API dispatcher
|
// Generic API dispatcher
|
||||||
template<typename ViewOp, typename XprType, typename StorageKind>
|
template<typename ViewOp, typename XprType, typename StorageKind>
|
||||||
class CwiseUnaryViewImpl
|
class CwiseUnaryViewImpl
|
||||||
@ -102,7 +96,6 @@ class CwiseUnaryViewImpl
|
|||||||
public:
|
public:
|
||||||
typedef typename internal::generic_xpr_base<CwiseUnaryView<ViewOp, XprType> >::type Base;
|
typedef typename internal::generic_xpr_base<CwiseUnaryView<ViewOp, XprType> >::type Base;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename ViewOp, typename MatrixType>
|
template<typename ViewOp, typename MatrixType>
|
||||||
class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
|
class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
|
||||||
@ -128,30 +121,6 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
|
|||||||
{
|
{
|
||||||
return derived().nestedExpression().outerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
|
return derived().nestedExpression().outerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
|
|
||||||
{
|
|
||||||
return derived().functor()(derived().nestedExpression().coeff(row, col));
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
|
|
||||||
{
|
|
||||||
return derived().functor()(derived().nestedExpression().coeff(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
|
|
||||||
{
|
|
||||||
return derived().functor()(const_cast_derived().nestedExpression().coeffRef(row, col));
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
|
|
||||||
{
|
|
||||||
return derived().functor()(const_cast_derived().nestedExpression().coeffRef(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
@ -74,18 +74,6 @@ template<typename Derived> class DenseBase
|
|||||||
using Base::colIndexByOuterInner;
|
using Base::colIndexByOuterInner;
|
||||||
using Base::coeff;
|
using Base::coeff;
|
||||||
using Base::coeffByOuterInner;
|
using Base::coeffByOuterInner;
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
using Base::packet;
|
|
||||||
using Base::packetByOuterInner;
|
|
||||||
using Base::writePacket;
|
|
||||||
using Base::writePacketByOuterInner;
|
|
||||||
using Base::coeffRef;
|
|
||||||
using Base::coeffRefByOuterInner;
|
|
||||||
using Base::copyCoeff;
|
|
||||||
using Base::copyCoeffByOuterInner;
|
|
||||||
using Base::copyPacket;
|
|
||||||
using Base::copyPacketByOuterInner;
|
|
||||||
#endif
|
|
||||||
using Base::operator();
|
using Base::operator();
|
||||||
using Base::operator[];
|
using Base::operator[];
|
||||||
using Base::x;
|
using Base::x;
|
||||||
@ -171,13 +159,6 @@ template<typename Derived> class DenseBase
|
|||||||
InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
|
InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
|
||||||
: int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
|
: int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
|
|
||||||
/**< This is a rough measure of how expensive it is to read one coefficient from
|
|
||||||
* this expression.
|
|
||||||
*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
InnerStrideAtCompileTime = internal::inner_stride_at_compile_time<Derived>::ret,
|
InnerStrideAtCompileTime = internal::inner_stride_at_compile_time<Derived>::ret,
|
||||||
OuterStrideAtCompileTime = internal::outer_stride_at_compile_time<Derived>::ret
|
OuterStrideAtCompileTime = internal::outer_stride_at_compile_time<Derived>::ret
|
||||||
};
|
};
|
||||||
@ -292,15 +273,10 @@ template<typename Derived> class DenseBase
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
CommaInitializer<Derived> operator<< (const Scalar& s);
|
CommaInitializer<Derived> operator<< (const Scalar& s);
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<unsigned int Added,unsigned int Removed>
|
|
||||||
const Flagged<Derived, Added, Removed> flagged() const;
|
|
||||||
#else
|
|
||||||
// TODO flagged is temporarly disabled. It seems useless now
|
// TODO flagged is temporarly disabled. It seems useless now
|
||||||
template<unsigned int Added,unsigned int Removed>
|
template<unsigned int Added,unsigned int Removed>
|
||||||
const Derived& flagged() const
|
const Derived& flagged() const
|
||||||
{ return derived(); }
|
{ return derived(); }
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@ -313,15 +289,6 @@ template<typename Derived> class DenseBase
|
|||||||
ConstTransposeReturnType transpose() const;
|
ConstTransposeReturnType transpose() const;
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
void transposeInPlace();
|
void transposeInPlace();
|
||||||
#ifndef EIGEN_NO_DEBUG
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
protected:
|
|
||||||
template<typename OtherDerived>
|
|
||||||
void checkTransposeAliasing(const OtherDerived& other) const;
|
|
||||||
public:
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC static const ConstantReturnType
|
EIGEN_DEVICE_FUNC static const ConstantReturnType
|
||||||
Constant(Index rows, Index cols, const Scalar& value);
|
Constant(Index rows, Index cols, const Scalar& value);
|
||||||
@ -402,7 +369,6 @@ template<typename Derived> class DenseBase
|
|||||||
return typename internal::eval<Derived>::type(derived());
|
return typename internal::eval<Derived>::type(derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
/** swaps *this with the expression \a other.
|
/** swaps *this with the expression \a other.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -425,28 +391,6 @@ template<typename Derived> class DenseBase
|
|||||||
eigen_assert(rows()==other.rows() && cols()==other.cols());
|
eigen_assert(rows()==other.rows() && cols()==other.cols());
|
||||||
call_assignment(derived(), other.derived(), internal::swap_assign_op<Scalar>());
|
call_assignment(derived(), other.derived(), internal::swap_assign_op<Scalar>());
|
||||||
}
|
}
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
/** swaps *this with the expression \a other.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void swap(const DenseBase<OtherDerived>& other,
|
|
||||||
int = OtherDerived::ThisConstantIsPrivateInPlainObjectBase)
|
|
||||||
{
|
|
||||||
SwapWrapper<Derived>(derived()).lazyAssign(other.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** swaps *this with the matrix or array \a other.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void swap(PlainObjectBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
SwapWrapper<Derived>(derived()).lazyAssign(other.derived());
|
|
||||||
}
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline const NestByValue<Derived> nestByValue() const;
|
EIGEN_DEVICE_FUNC inline const NestByValue<Derived> nestByValue() const;
|
||||||
EIGEN_DEVICE_FUNC inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
|
EIGEN_DEVICE_FUNC inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
|
||||||
|
@ -98,11 +98,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
|||||||
{
|
{
|
||||||
eigen_internal_assert(row >= 0 && row < rows()
|
eigen_internal_assert(row >= 0 && row < rows()
|
||||||
&& col >= 0 && col < cols());
|
&& col >= 0 && col < cols());
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
return derived().coeff(row, col);
|
|
||||||
#else
|
|
||||||
return typename internal::evaluator<Derived>::type(derived()).coeff(row,col);
|
return typename internal::evaluator<Derived>::type(derived()).coeff(row,col);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@ -144,11 +140,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
|||||||
coeff(Index index) const
|
coeff(Index index) const
|
||||||
{
|
{
|
||||||
eigen_internal_assert(index >= 0 && index < size());
|
eigen_internal_assert(index >= 0 && index < size());
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
return derived().coeff(index);
|
|
||||||
#else
|
|
||||||
return typename internal::evaluator<Derived>::type(derived()).coeff(index);
|
return typename internal::evaluator<Derived>::type(derived()).coeff(index);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -226,11 +218,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
|||||||
EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const
|
EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const
|
||||||
{
|
{
|
||||||
eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
|
eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
return derived().template packet<LoadMode>(row,col);
|
|
||||||
#else
|
|
||||||
return typename internal::evaluator<Derived>::type(derived()).template packet<LoadMode>(row,col);
|
return typename internal::evaluator<Derived>::type(derived()).template packet<LoadMode>(row,col);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -256,11 +244,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
|||||||
EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
|
EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
|
||||||
{
|
{
|
||||||
eigen_internal_assert(index >= 0 && index < size());
|
eigen_internal_assert(index >= 0 && index < size());
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
return derived().template packet<LoadMode>(index);
|
|
||||||
#else
|
|
||||||
return typename internal::evaluator<Derived>::type(derived()).template packet<LoadMode>(index);
|
return typename internal::evaluator<Derived>::type(derived()).template packet<LoadMode>(index);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -341,11 +325,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
|||||||
{
|
{
|
||||||
eigen_internal_assert(row >= 0 && row < rows()
|
eigen_internal_assert(row >= 0 && row < rows()
|
||||||
&& col >= 0 && col < cols());
|
&& col >= 0 && col < cols());
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
return derived().coeffRef(row, col);
|
|
||||||
#else
|
|
||||||
return typename internal::evaluator<Derived>::type(derived()).coeffRef(row,col);
|
return typename internal::evaluator<Derived>::type(derived()).coeffRef(row,col);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@ -391,11 +371,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
|||||||
coeffRef(Index index)
|
coeffRef(Index index)
|
||||||
{
|
{
|
||||||
eigen_internal_assert(index >= 0 && index < size());
|
eigen_internal_assert(index >= 0 && index < size());
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
return derived().coeffRef(index);
|
|
||||||
#else
|
|
||||||
return typename internal::evaluator<Derived>::type(derived()).coeffRef(index);
|
return typename internal::evaluator<Derived>::type(derived()).coeffRef(index);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns a reference to the coefficient at given index.
|
/** \returns a reference to the coefficient at given index.
|
||||||
@ -455,146 +431,6 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE Scalar&
|
EIGEN_STRONG_INLINE Scalar&
|
||||||
w() { return (*this)[3]; }
|
w() { return (*this)[3]; }
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \internal
|
|
||||||
* Stores the given packet of coefficients, at the given row and column of this expression. It is your responsibility
|
|
||||||
* to ensure that a packet really starts there. This method is only available on expressions having the
|
|
||||||
* PacketAccessBit.
|
|
||||||
*
|
|
||||||
* The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select
|
|
||||||
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
|
|
||||||
* starting at an address which is a multiple of the packet size.
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<int StoreMode>
|
|
||||||
EIGEN_STRONG_INLINE void writePacket
|
|
||||||
(Index row, Index col, const typename internal::packet_traits<Scalar>::type& val)
|
|
||||||
{
|
|
||||||
eigen_internal_assert(row >= 0 && row < rows()
|
|
||||||
&& col >= 0 && col < cols());
|
|
||||||
derived().template writePacket<StoreMode>(row,col,val);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** \internal */
|
|
||||||
template<int StoreMode>
|
|
||||||
EIGEN_STRONG_INLINE void writePacketByOuterInner
|
|
||||||
(Index outer, Index inner, const typename internal::packet_traits<Scalar>::type& val)
|
|
||||||
{
|
|
||||||
writePacket<StoreMode>(rowIndexByOuterInner(outer, inner),
|
|
||||||
colIndexByOuterInner(outer, inner),
|
|
||||||
val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal
|
|
||||||
* Stores the given packet of coefficients, at the given index in this expression. It is your responsibility
|
|
||||||
* to ensure that a packet really starts there. This method is only available on expressions having the
|
|
||||||
* PacketAccessBit and the LinearAccessBit.
|
|
||||||
*
|
|
||||||
* The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
|
|
||||||
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
|
|
||||||
* starting at an address which is a multiple of the packet size.
|
|
||||||
*/
|
|
||||||
template<int StoreMode>
|
|
||||||
EIGEN_STRONG_INLINE void writePacket
|
|
||||||
(Index index, const typename internal::packet_traits<Scalar>::type& val)
|
|
||||||
{
|
|
||||||
eigen_internal_assert(index >= 0 && index < size());
|
|
||||||
derived().template writePacket<StoreMode>(index,val);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
|
|
||||||
/** \internal Copies the coefficient at position (row,col) of other into *this.
|
|
||||||
*
|
|
||||||
* This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
|
|
||||||
* with usual assignments.
|
|
||||||
*
|
|
||||||
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
eigen_internal_assert(row >= 0 && row < rows()
|
|
||||||
&& col >= 0 && col < cols());
|
|
||||||
derived().coeffRef(row, col) = other.derived().coeff(row, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal Copies the coefficient at the given index of other into *this.
|
|
||||||
*
|
|
||||||
* This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
|
|
||||||
* with usual assignments.
|
|
||||||
*
|
|
||||||
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE void copyCoeff(Index index, const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
eigen_internal_assert(index >= 0 && index < size());
|
|
||||||
derived().coeffRef(index) = other.derived().coeff(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE void copyCoeffByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
const Index row = rowIndexByOuterInner(outer,inner);
|
|
||||||
const Index col = colIndexByOuterInner(outer,inner);
|
|
||||||
// derived() is important here: copyCoeff() may be reimplemented in Derived!
|
|
||||||
derived().copyCoeff(row, col, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal Copies the packet at position (row,col) of other into *this.
|
|
||||||
*
|
|
||||||
* This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
|
|
||||||
* with usual assignments.
|
|
||||||
*
|
|
||||||
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename OtherDerived, int StoreMode, int LoadMode>
|
|
||||||
EIGEN_STRONG_INLINE void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
eigen_internal_assert(row >= 0 && row < rows()
|
|
||||||
&& col >= 0 && col < cols());
|
|
||||||
derived().template writePacket<StoreMode>(row, col,
|
|
||||||
other.derived().template packet<LoadMode>(row, col));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal Copies the packet at the given index of other into *this.
|
|
||||||
*
|
|
||||||
* This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
|
|
||||||
* with usual assignments.
|
|
||||||
*
|
|
||||||
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename OtherDerived, int StoreMode, int LoadMode>
|
|
||||||
EIGEN_STRONG_INLINE void copyPacket(Index index, const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
eigen_internal_assert(index >= 0 && index < size());
|
|
||||||
derived().template writePacket<StoreMode>(index,
|
|
||||||
other.derived().template packet<LoadMode>(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \internal */
|
|
||||||
template<typename OtherDerived, int StoreMode, int LoadMode>
|
|
||||||
EIGEN_STRONG_INLINE void copyPacketByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
const Index row = rowIndexByOuterInner(outer,inner);
|
|
||||||
const Index col = colIndexByOuterInner(outer,inner);
|
|
||||||
// derived() is important here: copyCoeff() may be reimplemented in Derived!
|
|
||||||
derived().template copyPacket< OtherDerived, StoreMode, LoadMode>(row, col, other);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \brief Base class providing direct read-only coefficient access to matrices and arrays.
|
/** \brief Base class providing direct read-only coefficient access to matrices and arrays.
|
||||||
|
@ -51,14 +51,8 @@ struct traits<Diagonal<MatrixType,DiagIndex> >
|
|||||||
: (EIGEN_PLAIN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0),
|
: (EIGEN_PLAIN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0),
|
||||||
MatrixType::MaxColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))),
|
MatrixType::MaxColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))),
|
||||||
MaxColsAtCompileTime = 1,
|
MaxColsAtCompileTime = 1,
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
MaskLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
|
|
||||||
Flags = (unsigned int)_MatrixTypeNested::Flags & (HereditaryBits | LinearAccessBit | MaskLvalueBit | DirectAccessBit) & ~RowMajorBit,
|
|
||||||
CoeffReadCost = _MatrixTypeNested::CoeffReadCost,
|
|
||||||
#else
|
|
||||||
MaskLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
|
MaskLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
|
||||||
Flags = (unsigned int)_MatrixTypeNested::Flags & (RowMajorBit | MaskLvalueBit | DirectAccessBit) & ~RowMajorBit, // FIXME DirectAccessBit should not be handled by expressions
|
Flags = (unsigned int)_MatrixTypeNested::Flags & (RowMajorBit | MaskLvalueBit | DirectAccessBit) & ~RowMajorBit, // FIXME DirectAccessBit should not be handled by expressions
|
||||||
#endif
|
|
||||||
MatrixTypeOuterStride = outer_stride_at_compile_time<MatrixType>::ret,
|
MatrixTypeOuterStride = outer_stride_at_compile_time<MatrixType>::ret,
|
||||||
InnerStrideAtCompileTime = MatrixTypeOuterStride == Dynamic ? Dynamic : MatrixTypeOuterStride+1,
|
InnerStrideAtCompileTime = MatrixTypeOuterStride == Dynamic ? Dynamic : MatrixTypeOuterStride+1,
|
||||||
OuterStrideAtCompileTime = 0
|
OuterStrideAtCompileTime = 0
|
||||||
|
@ -45,20 +45,6 @@ class DiagonalBase : public EigenBase<Derived>
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
DenseMatrixType toDenseMatrix() const { return derived(); }
|
DenseMatrixType toDenseMatrix() const { return derived(); }
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename DenseDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void evalTo(MatrixBase<DenseDerived> &other) const;
|
|
||||||
template<typename DenseDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void addTo(MatrixBase<DenseDerived> &other) const
|
|
||||||
{ other.diagonal() += diagonal(); }
|
|
||||||
template<typename DenseDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void subTo(MatrixBase<DenseDerived> &other) const
|
|
||||||
{ other.diagonal() -= diagonal(); }
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); }
|
inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); }
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@ -69,17 +55,6 @@ class DiagonalBase : public EigenBase<Derived>
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index cols() const { return diagonal().size(); }
|
inline Index cols() const { return diagonal().size(); }
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \returns the diagonal matrix product of \c *this by the matrix \a matrix.
|
|
||||||
*/
|
|
||||||
template<typename MatrixDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const DiagonalProduct<MatrixDerived, Derived, OnTheLeft>
|
|
||||||
operator*(const MatrixBase<MatrixDerived> &matrix) const
|
|
||||||
{
|
|
||||||
return DiagonalProduct<MatrixDerived, Derived, OnTheLeft>(matrix.derived(), derived());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
template<typename MatrixDerived>
|
template<typename MatrixDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const Product<Derived,MatrixDerived,LazyProduct>
|
const Product<Derived,MatrixDerived,LazyProduct>
|
||||||
@ -87,7 +62,6 @@ class DiagonalBase : public EigenBase<Derived>
|
|||||||
{
|
{
|
||||||
return Product<Derived, MatrixDerived, LazyProduct>(derived(),matrix.derived());
|
return Product<Derived, MatrixDerived, LazyProduct>(derived(),matrix.derived());
|
||||||
}
|
}
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const DiagonalVectorType> >
|
inline const DiagonalWrapper<const CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const DiagonalVectorType> >
|
||||||
@ -110,16 +84,6 @@ class DiagonalBase : public EigenBase<Derived>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename DenseDerived>
|
|
||||||
void DiagonalBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
|
|
||||||
{
|
|
||||||
other.setZero();
|
|
||||||
other.diagonal() = diagonal();
|
|
||||||
}
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** \class DiagonalMatrix
|
/** \class DiagonalMatrix
|
||||||
@ -273,10 +237,6 @@ struct traits<DiagonalWrapper<_DiagonalVectorType> >
|
|||||||
MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
|
MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
|
||||||
MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
|
MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
|
||||||
Flags = (traits<DiagonalVectorType>::Flags & LvalueBit) | NoPreferredStorageOrderBit
|
Flags = (traits<DiagonalVectorType>::Flags & LvalueBit) | NoPreferredStorageOrderBit
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
,
|
|
||||||
CoeffReadCost = traits<_DiagonalVectorType>::CoeffReadCost
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -347,7 +307,6 @@ bool MatrixBase<Derived>::isDiagonal(const RealScalar& prec) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<> struct storage_kind_to_shape<DiagonalShape> { typedef DiagonalShape Shape; };
|
template<> struct storage_kind_to_shape<DiagonalShape> { typedef DiagonalShape Shape; };
|
||||||
@ -368,7 +327,6 @@ struct Assignment<DstXprType, SrcXprType, Functor, Diagonal2Dense, Scalar>
|
|||||||
};
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
#endif // EIGEN_ENABLE_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
@ -13,122 +13,6 @@
|
|||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
template<typename MatrixType, typename DiagonalType, int ProductOrder>
|
|
||||||
struct traits<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> >
|
|
||||||
: traits<MatrixType>
|
|
||||||
{
|
|
||||||
typedef typename scalar_product_traits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar;
|
|
||||||
enum {
|
|
||||||
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
|
|
||||||
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
|
||||||
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
|
||||||
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
_StorageOrder = MatrixType::Flags & RowMajorBit ? RowMajor : ColMajor,
|
|
||||||
_ScalarAccessOnDiag = !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft)
|
|
||||||
||(int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheRight)),
|
|
||||||
_SameTypes = is_same<typename MatrixType::Scalar, typename DiagonalType::Scalar>::value,
|
|
||||||
// FIXME currently we need same types, but in the future the next rule should be the one
|
|
||||||
//_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))),
|
|
||||||
_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))),
|
|
||||||
_LinearAccessMask = (RowsAtCompileTime==1 || ColsAtCompileTime==1) ? LinearAccessBit : 0,
|
|
||||||
Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0) | AlignedBit, //(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit),
|
|
||||||
CoeffReadCost = NumTraits<Scalar>::MulCost + MatrixType::CoeffReadCost + DiagonalType::DiagonalVectorType::CoeffReadCost
|
|
||||||
#else
|
|
||||||
Flags = RowMajorBit & (unsigned int)(MatrixType::Flags)
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename MatrixType, typename DiagonalType, int ProductOrder>
|
|
||||||
class DiagonalProduct : internal::no_assignment_operator,
|
|
||||||
public MatrixBase<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef MatrixBase<DiagonalProduct> Base;
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(DiagonalProduct)
|
|
||||||
|
|
||||||
inline DiagonalProduct(const MatrixType& matrix, const DiagonalType& diagonal)
|
|
||||||
: m_matrix(matrix), m_diagonal(diagonal)
|
|
||||||
{
|
|
||||||
eigen_assert(diagonal.diagonal().size() == (ProductOrder == OnTheLeft ? matrix.rows() : matrix.cols()));
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); }
|
|
||||||
EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); }
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
|
|
||||||
{
|
|
||||||
return m_diagonal.diagonal().coeff(ProductOrder == OnTheLeft ? row : col) * m_matrix.coeff(row, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE const Scalar coeff(Index idx) const
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor
|
|
||||||
};
|
|
||||||
return coeff(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
StorageOrder = Flags & RowMajorBit ? RowMajor : ColMajor
|
|
||||||
};
|
|
||||||
const Index indexInDiagonalVector = ProductOrder == OnTheLeft ? row : col;
|
|
||||||
return packet_impl<LoadMode>(row,col,indexInDiagonalVector,typename internal::conditional<
|
|
||||||
((int(StorageOrder) == RowMajor && int(ProductOrder) == OnTheLeft)
|
|
||||||
||(int(StorageOrder) == ColMajor && int(ProductOrder) == OnTheRight)), internal::true_type, internal::false_type>::type());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
EIGEN_STRONG_INLINE PacketScalar packet(Index idx) const
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
StorageOrder = int(MatrixType::Flags) & RowMajorBit ? RowMajor : ColMajor
|
|
||||||
};
|
|
||||||
return packet<LoadMode>(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
template<int LoadMode>
|
|
||||||
EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::true_type) const
|
|
||||||
{
|
|
||||||
return internal::pmul(m_matrix.template packet<LoadMode>(row, col),
|
|
||||||
internal::pset1<PacketScalar>(m_diagonal.diagonal().coeff(id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
EIGEN_STRONG_INLINE PacketScalar packet_impl(Index row, Index col, Index id, internal::false_type) const
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
InnerSize = (MatrixType::Flags & RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime,
|
|
||||||
DiagonalVectorPacketLoadMode = (LoadMode == Aligned && (((InnerSize%16) == 0) || (int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit)==AlignedBit) ? Aligned : Unaligned)
|
|
||||||
};
|
|
||||||
return internal::pmul(m_matrix.template packet<LoadMode>(row, col),
|
|
||||||
m_diagonal.diagonal().template packet<DiagonalVectorPacketLoadMode>(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
typename MatrixType::Nested m_matrix;
|
|
||||||
typename DiagonalType::Nested m_diagonal;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \returns the diagonal matrix product of \c *this by the diagonal matrix \a diagonal.
|
|
||||||
*/
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename DiagonalDerived>
|
|
||||||
inline const DiagonalProduct<Derived, DiagonalDerived, OnTheRight>
|
|
||||||
MatrixBase<Derived>::operator*(const DiagonalBase<DiagonalDerived> &a_diagonal) const
|
|
||||||
{
|
|
||||||
return DiagonalProduct<Derived, DiagonalDerived, OnTheRight>(derived(), a_diagonal.derived());
|
|
||||||
}
|
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
/** \returns the diagonal matrix product of \c *this by the diagonal matrix \a diagonal.
|
/** \returns the diagonal matrix product of \c *this by the diagonal matrix \a diagonal.
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
@ -138,7 +22,6 @@ MatrixBase<Derived>::operator*(const DiagonalBase<DiagonalDerived> &a_diagonal)
|
|||||||
{
|
{
|
||||||
return Product<Derived, DiagonalDerived, LazyProduct>(derived(),a_diagonal.derived());
|
return Product<Derived, DiagonalDerived, LazyProduct>(derived(),a_diagonal.derived());
|
||||||
}
|
}
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
@ -113,13 +113,7 @@ template<typename Derived>
|
|||||||
inline const typename MatrixBase<Derived>::PlainObject
|
inline const typename MatrixBase<Derived>::PlainObject
|
||||||
MatrixBase<Derived>::normalized() const
|
MatrixBase<Derived>::normalized() const
|
||||||
{
|
{
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
typedef typename internal::nested<Derived,2>::type Nested;
|
|
||||||
typedef typename internal::remove_reference<Nested>::type _Nested;
|
|
||||||
#else
|
|
||||||
typedef typename internal::nested_eval<Derived,2>::type _Nested;
|
typedef typename internal::nested_eval<Derived,2>::type _Nested;
|
||||||
// typedef typename internal::remove_reference<Nested>::type _Nested;
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
_Nested n(derived());
|
_Nested n(derived());
|
||||||
return n / n.norm();
|
return n / n.norm();
|
||||||
}
|
}
|
||||||
@ -211,13 +205,8 @@ template<typename OtherDerived>
|
|||||||
bool MatrixBase<Derived>::isOrthogonal
|
bool MatrixBase<Derived>::isOrthogonal
|
||||||
(const MatrixBase<OtherDerived>& other, const RealScalar& prec) const
|
(const MatrixBase<OtherDerived>& other, const RealScalar& prec) const
|
||||||
{
|
{
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
typename internal::nested<Derived,2>::type nested(derived());
|
|
||||||
typename internal::nested<OtherDerived,2>::type otherNested(other.derived());
|
|
||||||
#else
|
|
||||||
typename internal::nested_eval<Derived,2>::type nested(derived());
|
typename internal::nested_eval<Derived,2>::type nested(derived());
|
||||||
typename internal::nested_eval<OtherDerived,2>::type otherNested(other.derived());
|
typename internal::nested_eval<OtherDerived,2>::type otherNested(other.derived());
|
||||||
#endif
|
|
||||||
return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
|
return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,11 +121,7 @@ template<typename Derived>
|
|||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
|
Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
|
||||||
{
|
{
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
other.derived().evalTo(derived());
|
|
||||||
#else
|
|
||||||
call_assignment(derived(), other.derived());
|
call_assignment(derived(), other.derived());
|
||||||
#endif
|
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,11 +129,7 @@ template<typename Derived>
|
|||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other)
|
Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other)
|
||||||
{
|
{
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
other.derived().addTo(derived());
|
|
||||||
#else
|
|
||||||
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar>());
|
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar>());
|
||||||
#endif
|
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,11 +137,7 @@ template<typename Derived>
|
|||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other)
|
Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other)
|
||||||
{
|
{
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
other.derived().subTo(derived());
|
|
||||||
#else
|
|
||||||
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar>());
|
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar>());
|
||||||
#endif
|
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,13 +23,8 @@ struct isApprox_selector
|
|||||||
static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec)
|
static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec)
|
||||||
{
|
{
|
||||||
EIGEN_USING_STD_MATH(min);
|
EIGEN_USING_STD_MATH(min);
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
typename internal::nested_eval<Derived,2>::type nested(x);
|
typename internal::nested_eval<Derived,2>::type nested(x);
|
||||||
typename internal::nested_eval<OtherDerived,2>::type otherNested(y);
|
typename internal::nested_eval<OtherDerived,2>::type otherNested(y);
|
||||||
#else
|
|
||||||
typename internal::nested<Derived,2>::type nested(x);
|
|
||||||
typename internal::nested<OtherDerived,2>::type otherNested(y);
|
|
||||||
#endif
|
|
||||||
return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * (min)(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum());
|
return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * (min)(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -13,31 +13,6 @@
|
|||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \class GeneralProduct
|
|
||||||
* \ingroup Core_Module
|
|
||||||
*
|
|
||||||
* \brief Expression of the product of two general matrices or vectors
|
|
||||||
*
|
|
||||||
* \param LhsNested the type used to store the left-hand side
|
|
||||||
* \param RhsNested the type used to store the right-hand side
|
|
||||||
* \param ProductMode the type of the product
|
|
||||||
*
|
|
||||||
* This class represents an expression of the product of two general matrices.
|
|
||||||
* We call a general matrix, a dense matrix with full storage. For instance,
|
|
||||||
* This excludes triangular, selfadjoint, and sparse matrices.
|
|
||||||
* It is the return type of the operator* between general matrices. Its template
|
|
||||||
* arguments are determined automatically by ProductReturnType. Therefore,
|
|
||||||
* GeneralProduct should never be used direclty. To determine the result type of a
|
|
||||||
* function which involves a matrix product, use ProductReturnType::Type.
|
|
||||||
*
|
|
||||||
* \sa ProductReturnType, MatrixBase::operator*(const MatrixBase<OtherDerived>&)
|
|
||||||
*/
|
|
||||||
template<typename Lhs, typename Rhs, int ProductType = internal::product_type<Lhs,Rhs>::value>
|
|
||||||
class GeneralProduct;
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
Large = 2,
|
Large = 2,
|
||||||
Small = 3
|
Small = 3
|
||||||
@ -156,56 +131,6 @@ template<> struct product_type_selector<Large,Large,Small> { enum
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \class ProductReturnType
|
|
||||||
* \ingroup Core_Module
|
|
||||||
*
|
|
||||||
* \brief Helper class to get the correct and optimized returned type of operator*
|
|
||||||
*
|
|
||||||
* \param Lhs the type of the left-hand side
|
|
||||||
* \param Rhs the type of the right-hand side
|
|
||||||
* \param ProductMode the type of the product (determined automatically by internal::product_mode)
|
|
||||||
*
|
|
||||||
* This class defines the typename Type representing the optimized product expression
|
|
||||||
* between two matrix expressions. In practice, using ProductReturnType<Lhs,Rhs>::Type
|
|
||||||
* is the recommended way to define the result type of a function returning an expression
|
|
||||||
* which involve a matrix product. The class Product should never be
|
|
||||||
* used directly.
|
|
||||||
*
|
|
||||||
* \sa class Product, MatrixBase::operator*(const MatrixBase<OtherDerived>&)
|
|
||||||
*/
|
|
||||||
template<typename Lhs, typename Rhs, int ProductType>
|
|
||||||
struct ProductReturnType
|
|
||||||
{
|
|
||||||
// TODO use the nested type to reduce instanciations ????
|
|
||||||
// typedef typename internal::nested<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
|
|
||||||
// typedef typename internal::nested<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
|
|
||||||
|
|
||||||
typedef GeneralProduct<Lhs/*Nested*/, Rhs/*Nested*/, ProductType> Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
struct ProductReturnType<Lhs,Rhs,CoeffBasedProductMode>
|
|
||||||
{
|
|
||||||
typedef typename internal::nested<Lhs, Rhs::ColsAtCompileTime, typename internal::plain_matrix_type<Lhs>::type >::type LhsNested;
|
|
||||||
typedef typename internal::nested<Rhs, Lhs::RowsAtCompileTime, typename internal::plain_matrix_type<Rhs>::type >::type RhsNested;
|
|
||||||
typedef CoeffBasedProduct<LhsNested, RhsNested, EvalBeforeAssigningBit | EvalBeforeNestingBit> Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
struct ProductReturnType<Lhs,Rhs,LazyCoeffBasedProductMode>
|
|
||||||
{
|
|
||||||
typedef typename internal::nested<Lhs, Rhs::ColsAtCompileTime, typename internal::plain_matrix_type<Lhs>::type >::type LhsNested;
|
|
||||||
typedef typename internal::nested<Rhs, Lhs::RowsAtCompileTime, typename internal::plain_matrix_type<Rhs>::type >::type RhsNested;
|
|
||||||
typedef CoeffBasedProduct<LhsNested, RhsNested, NestByRefBit> Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
// this is a workaround for sun CC
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
struct LazyProductReturnType : public ProductReturnType<Lhs,Rhs,LazyCoeffBasedProductMode>
|
|
||||||
{};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* Implementation of Inner Vector Vector Product
|
* Implementation of Inner Vector Vector Product
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
@ -216,124 +141,11 @@ struct LazyProductReturnType : public ProductReturnType<Lhs,Rhs,LazyCoeffBasedPr
|
|||||||
// Cons: this could be a problem if in a meta unrolled algorithm a matrix-matrix
|
// Cons: this could be a problem if in a meta unrolled algorithm a matrix-matrix
|
||||||
// product ends up to a row-vector times col-vector product... To tackle this use
|
// product ends up to a row-vector times col-vector product... To tackle this use
|
||||||
// case, we could have a specialization for Block<MatrixType,1,1> with: operator=(Scalar x);
|
// case, we could have a specialization for Block<MatrixType,1,1> with: operator=(Scalar x);
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
struct traits<GeneralProduct<Lhs,Rhs,InnerProduct> >
|
|
||||||
: traits<Matrix<typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1> >
|
|
||||||
{};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
class GeneralProduct<Lhs, Rhs, InnerProduct>
|
|
||||||
: internal::no_assignment_operator,
|
|
||||||
public Matrix<typename internal::scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1>
|
|
||||||
{
|
|
||||||
typedef Matrix<typename internal::scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1> Base;
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Convertion to scalar */
|
|
||||||
operator const typename Base::Scalar() const {
|
|
||||||
return Base::coeff(0,0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* Implementation of Outer Vector Vector Product
|
* Implementation of Outer Vector Vector Product
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// Column major
|
|
||||||
template<typename ProductType, typename Dest, typename Func>
|
|
||||||
EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest& dest, const Func& func, const false_type&)
|
|
||||||
{
|
|
||||||
typedef typename Dest::Index Index;
|
|
||||||
// FIXME make sure lhs is sequentially stored
|
|
||||||
// FIXME not very good if rhs is real and lhs complex while alpha is real too
|
|
||||||
const Index cols = dest.cols();
|
|
||||||
for (Index j=0; j<cols; ++j)
|
|
||||||
func(dest.col(j), prod.rhs().coeff(0,j) * prod.lhs());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Row major
|
|
||||||
template<typename ProductType, typename Dest, typename Func>
|
|
||||||
EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest& dest, const Func& func, const true_type&) {
|
|
||||||
typedef typename Dest::Index Index;
|
|
||||||
// FIXME make sure rhs is sequentially stored
|
|
||||||
// FIXME not very good if lhs is real and rhs complex while alpha is real too
|
|
||||||
const Index rows = dest.rows();
|
|
||||||
for (Index i=0; i<rows; ++i)
|
|
||||||
func(dest.row(i), prod.lhs().coeff(i,0) * prod.rhs());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
struct traits<GeneralProduct<Lhs,Rhs,OuterProduct> >
|
|
||||||
: traits<ProductBase<GeneralProduct<Lhs,Rhs,OuterProduct>, Lhs, Rhs> >
|
|
||||||
{};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {};
|
|
||||||
|
|
||||||
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; } };
|
|
||||||
struct add { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() += src; } };
|
|
||||||
struct sub { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() -= src; } };
|
|
||||||
struct adds {
|
|
||||||
Scalar m_scale;
|
|
||||||
adds(const Scalar& s) : m_scale(s) {}
|
|
||||||
template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const {
|
|
||||||
dst.const_cast_derived() += m_scale * src;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Dest>
|
|
||||||
inline void evalTo(Dest& dest) const {
|
|
||||||
internal::outer_product_selector_run(*this, dest, set(), IsRowMajor<Dest>());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Dest>
|
|
||||||
inline void addTo(Dest& dest) const {
|
|
||||||
internal::outer_product_selector_run(*this, dest, add(), IsRowMajor<Dest>());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Dest>
|
|
||||||
inline void subTo(Dest& dest) const {
|
|
||||||
internal::outer_product_selector_run(*this, dest, sub(), IsRowMajor<Dest>());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
|
|
||||||
{
|
|
||||||
internal::outer_product_selector_run(*this, dest, adds(alpha), IsRowMajor<Dest>());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* Implementation of General Matrix Vector Product
|
* Implementation of General Matrix Vector Product
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
@ -347,50 +159,11 @@ class GeneralProduct<Lhs, Rhs, OuterProduct>
|
|||||||
*/
|
*/
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
struct traits<GeneralProduct<Lhs,Rhs,GemvProduct> >
|
|
||||||
: traits<ProductBase<GeneralProduct<Lhs,Rhs,GemvProduct>, Lhs, Rhs> >
|
|
||||||
{};
|
|
||||||
template<int Side, int StorageOrder, bool BlasCompatible>
|
|
||||||
struct gemv_selector;
|
|
||||||
#endif
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
template<int Side, int StorageOrder, bool BlasCompatible>
|
template<int Side, int StorageOrder, bool BlasCompatible>
|
||||||
struct gemv_dense_sense_selector;
|
struct gemv_dense_sense_selector;
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
class GeneralProduct<Lhs, Rhs, GemvProduct>
|
|
||||||
: public ProductBase<GeneralProduct<Lhs,Rhs,GemvProduct>, Lhs, Rhs>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct)
|
|
||||||
|
|
||||||
typedef typename Lhs::Scalar LhsScalar;
|
|
||||||
typedef typename Rhs::Scalar RhsScalar;
|
|
||||||
|
|
||||||
GeneralProduct(const Lhs& a_lhs, const Rhs& a_rhs) : Base(a_lhs,a_rhs)
|
|
||||||
{
|
|
||||||
// EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::Scalar, typename Rhs::Scalar>::value),
|
|
||||||
// YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
|
||||||
}
|
|
||||||
|
|
||||||
enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight };
|
|
||||||
typedef typename internal::conditional<int(Side)==OnTheRight,_LhsNested,_RhsNested>::type MatrixType;
|
|
||||||
|
|
||||||
template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_lhs.rows() == dst.rows() && m_rhs.cols() == dst.cols());
|
|
||||||
internal::gemv_selector<Side,(int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor,
|
|
||||||
bool(internal::blas_traits<MatrixType>::HasUsableDirectAccess)>::run(*this, dst, alpha);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<typename Scalar,int Size,int MaxSize,bool Cond> struct gemv_static_vector_if;
|
template<typename Scalar,int Size,int MaxSize,bool Cond> struct gemv_static_vector_if;
|
||||||
@ -429,177 +202,6 @@ struct gemv_static_vector_if<Scalar,Size,MaxSize,true>
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
// The vector is on the left => transposition
|
|
||||||
template<int StorageOrder, bool BlasCompatible>
|
|
||||||
struct gemv_selector<OnTheLeft,StorageOrder,BlasCompatible>
|
|
||||||
{
|
|
||||||
template<typename ProductType, typename Dest>
|
|
||||||
static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha)
|
|
||||||
{
|
|
||||||
Transpose<Dest> destT(dest);
|
|
||||||
enum { OtherStorageOrder = StorageOrder == RowMajor ? ColMajor : RowMajor };
|
|
||||||
gemv_selector<OnTheRight,OtherStorageOrder,BlasCompatible>
|
|
||||||
::run(GeneralProduct<Transpose<const typename ProductType::_RhsNested>,Transpose<const typename ProductType::_LhsNested>, GemvProduct>
|
|
||||||
(prod.rhs().transpose(), prod.lhs().transpose()), destT, alpha);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct gemv_selector<OnTheRight,ColMajor,true>
|
|
||||||
{
|
|
||||||
template<typename ProductType, typename Dest>
|
|
||||||
static inline void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha)
|
|
||||||
{
|
|
||||||
typedef typename ProductType::Index Index;
|
|
||||||
typedef typename ProductType::LhsScalar LhsScalar;
|
|
||||||
typedef typename ProductType::RhsScalar RhsScalar;
|
|
||||||
typedef typename ProductType::Scalar ResScalar;
|
|
||||||
typedef typename ProductType::RealScalar RealScalar;
|
|
||||||
typedef typename ProductType::ActualLhsType ActualLhsType;
|
|
||||||
typedef typename ProductType::ActualRhsType ActualRhsType;
|
|
||||||
typedef typename ProductType::LhsBlasTraits LhsBlasTraits;
|
|
||||||
typedef typename ProductType::RhsBlasTraits RhsBlasTraits;
|
|
||||||
typedef Map<Matrix<ResScalar,Dynamic,1>, Aligned> MappedDest;
|
|
||||||
|
|
||||||
ActualLhsType actualLhs = LhsBlasTraits::extract(prod.lhs());
|
|
||||||
ActualRhsType actualRhs = RhsBlasTraits::extract(prod.rhs());
|
|
||||||
|
|
||||||
ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs())
|
|
||||||
* RhsBlasTraits::extractScalarFactor(prod.rhs());
|
|
||||||
|
|
||||||
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,
|
|
||||||
ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex),
|
|
||||||
MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal
|
|
||||||
};
|
|
||||||
|
|
||||||
gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
|
|
||||||
|
|
||||||
bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
|
|
||||||
bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
|
|
||||||
|
|
||||||
RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
|
|
||||||
|
|
||||||
ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
|
|
||||||
evalToDest ? dest.data() : static_dest.data());
|
|
||||||
|
|
||||||
if(!evalToDest)
|
|
||||||
{
|
|
||||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
|
||||||
Index size = dest.size();
|
|
||||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
|
||||||
#endif
|
|
||||||
if(!alphaIsCompatible)
|
|
||||||
{
|
|
||||||
MappedDest(actualDestPtr, dest.size()).setZero();
|
|
||||||
compatibleAlpha = RhsScalar(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
MappedDest(actualDestPtr, dest.size()) = dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
general_matrix_vector_product
|
|
||||||
<Index,LhsScalar,ColMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsBlasTraits::NeedToConjugate>::run(
|
|
||||||
actualLhs.rows(), actualLhs.cols(),
|
|
||||||
actualLhs.data(), actualLhs.outerStride(),
|
|
||||||
actualRhs.data(), actualRhs.innerStride(),
|
|
||||||
actualDestPtr, 1,
|
|
||||||
compatibleAlpha);
|
|
||||||
|
|
||||||
if (!evalToDest)
|
|
||||||
{
|
|
||||||
if(!alphaIsCompatible)
|
|
||||||
dest += actualAlpha * MappedDest(actualDestPtr, dest.size());
|
|
||||||
else
|
|
||||||
dest = MappedDest(actualDestPtr, dest.size());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct gemv_selector<OnTheRight,RowMajor,true>
|
|
||||||
{
|
|
||||||
template<typename ProductType, typename Dest>
|
|
||||||
static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha)
|
|
||||||
{
|
|
||||||
typedef typename ProductType::LhsScalar LhsScalar;
|
|
||||||
typedef typename ProductType::RhsScalar RhsScalar;
|
|
||||||
typedef typename ProductType::Scalar ResScalar;
|
|
||||||
typedef typename ProductType::Index Index;
|
|
||||||
typedef typename ProductType::ActualLhsType ActualLhsType;
|
|
||||||
typedef typename ProductType::ActualRhsType ActualRhsType;
|
|
||||||
typedef typename ProductType::_ActualRhsType _ActualRhsType;
|
|
||||||
typedef typename ProductType::LhsBlasTraits LhsBlasTraits;
|
|
||||||
typedef typename ProductType::RhsBlasTraits RhsBlasTraits;
|
|
||||||
|
|
||||||
typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(prod.lhs());
|
|
||||||
typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(prod.rhs());
|
|
||||||
|
|
||||||
ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs())
|
|
||||||
* RhsBlasTraits::extractScalarFactor(prod.rhs());
|
|
||||||
|
|
||||||
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...
|
|
||||||
DirectlyUseRhs = _ActualRhsType::InnerStrideAtCompileTime==1
|
|
||||||
};
|
|
||||||
|
|
||||||
gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
|
|
||||||
|
|
||||||
ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(),
|
|
||||||
DirectlyUseRhs ? const_cast<RhsScalar*>(actualRhs.data()) : static_rhs.data());
|
|
||||||
|
|
||||||
if(!DirectlyUseRhs)
|
|
||||||
{
|
|
||||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
|
||||||
Index size = actualRhs.size();
|
|
||||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
|
||||||
#endif
|
|
||||||
Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
general_matrix_vector_product
|
|
||||||
<Index,LhsScalar,RowMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsBlasTraits::NeedToConjugate>::run(
|
|
||||||
actualLhs.rows(), actualLhs.cols(),
|
|
||||||
actualLhs.data(), actualLhs.outerStride(),
|
|
||||||
actualRhsPtr, 1,
|
|
||||||
dest.data(), dest.innerStride(),
|
|
||||||
actualAlpha);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct gemv_selector<OnTheRight,ColMajor,false>
|
|
||||||
{
|
|
||||||
template<typename ProductType, typename Dest>
|
|
||||||
static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha)
|
|
||||||
{
|
|
||||||
typedef typename Dest::Index Index;
|
|
||||||
// TODO makes sure dest is sequentially stored in memory, otherwise use a temp
|
|
||||||
const Index size = prod.rhs().rows();
|
|
||||||
for(Index k=0; k<size; ++k)
|
|
||||||
dest += (alpha*prod.rhs().coeff(k)) * prod.lhs().col(k);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct gemv_selector<OnTheRight,RowMajor,false>
|
|
||||||
{
|
|
||||||
template<typename ProductType, typename Dest>
|
|
||||||
static void run(const ProductType& prod, Dest& dest, const typename ProductType::Scalar& alpha)
|
|
||||||
{
|
|
||||||
typedef typename Dest::Index Index;
|
|
||||||
// TODO makes sure rhs is sequentially stored in memory, otherwise use a temp
|
|
||||||
const Index rows = prod.rows();
|
|
||||||
for(Index i=0; i<rows; ++i)
|
|
||||||
dest.coeffRef(i) += alpha * (prod.lhs().row(i).cwiseProduct(prod.rhs().transpose())).sum();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
|
|
||||||
// The vector is on the left => transposition
|
// The vector is on the left => transposition
|
||||||
template<int StorageOrder, bool BlasCompatible>
|
template<int StorageOrder, bool BlasCompatible>
|
||||||
struct gemv_dense_sense_selector<OnTheLeft,StorageOrder,BlasCompatible>
|
struct gemv_dense_sense_selector<OnTheLeft,StorageOrder,BlasCompatible>
|
||||||
@ -767,8 +369,6 @@ template<> struct gemv_dense_sense_selector<OnTheRight,RowMajor,false>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EIGEN_ENABLE_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@ -783,7 +383,6 @@ template<> struct gemv_dense_sense_selector<OnTheRight,RowMajor,false>
|
|||||||
*/
|
*/
|
||||||
#ifndef __CUDACC__
|
#ifndef __CUDACC__
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
inline const Product<Derived, OtherDerived>
|
inline const Product<Derived, OtherDerived>
|
||||||
@ -814,37 +413,6 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
|||||||
|
|
||||||
return Product<Derived, OtherDerived>(derived(), other.derived());
|
return Product<Derived, OtherDerived>(derived(), other.derived());
|
||||||
}
|
}
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
inline const typename ProductReturnType<Derived, OtherDerived>::Type
|
|
||||||
MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
|
||||||
{
|
|
||||||
// A note regarding the function declaration: In MSVC, this function will sometimes
|
|
||||||
// not be inlined since DenseStorage is an unwindable object for dynamic
|
|
||||||
// matrices and product types are holding a member to store the result.
|
|
||||||
// Thus it does not help tagging this function with EIGEN_STRONG_INLINE.
|
|
||||||
enum {
|
|
||||||
ProductIsValid = Derived::ColsAtCompileTime==Dynamic
|
|
||||||
|| OtherDerived::RowsAtCompileTime==Dynamic
|
|
||||||
|| int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime),
|
|
||||||
AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime,
|
|
||||||
SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived)
|
|
||||||
};
|
|
||||||
// note to the lost user:
|
|
||||||
// * for a dot product use: v1.dot(v2)
|
|
||||||
// * for a coeff-wise product use: v1.cwiseProduct(v2)
|
|
||||||
EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
|
|
||||||
INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
|
|
||||||
EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
|
|
||||||
INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
|
|
||||||
EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
|
|
||||||
#ifdef EIGEN_DEBUG_PRODUCT
|
|
||||||
internal::product_type<Derived,OtherDerived>::debug();
|
|
||||||
#endif
|
|
||||||
return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
|
|
||||||
}
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
#endif // __CUDACC__
|
#endif // __CUDACC__
|
||||||
|
|
||||||
@ -859,7 +427,6 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
|||||||
*
|
*
|
||||||
* \sa operator*(const MatrixBase&)
|
* \sa operator*(const MatrixBase&)
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
const Product<Derived,OtherDerived,LazyProduct>
|
const Product<Derived,OtherDerived,LazyProduct>
|
||||||
@ -883,31 +450,6 @@ MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
|
|||||||
|
|
||||||
return Product<Derived,OtherDerived,LazyProduct>(derived(), other.derived());
|
return Product<Derived,OtherDerived,LazyProduct>(derived(), other.derived());
|
||||||
}
|
}
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
const typename LazyProductReturnType<Derived,OtherDerived>::Type
|
|
||||||
MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
ProductIsValid = Derived::ColsAtCompileTime==Dynamic
|
|
||||||
|| OtherDerived::RowsAtCompileTime==Dynamic
|
|
||||||
|| int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime),
|
|
||||||
AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime,
|
|
||||||
SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived)
|
|
||||||
};
|
|
||||||
// note to the lost user:
|
|
||||||
// * for a dot product use: v1.dot(v2)
|
|
||||||
// * for a coeff-wise product use: v1.cwiseProduct(v2)
|
|
||||||
EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
|
|
||||||
INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
|
|
||||||
EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
|
|
||||||
INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
|
|
||||||
EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
|
|
||||||
|
|
||||||
return typename LazyProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
|
|
||||||
}
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
// TODO move the general declaration in Core, and rename this file DenseInverseImpl.h, or something like this...
|
// TODO move the general declaration in Core, and rename this file DenseInverseImpl.h, or something like this...
|
||||||
|
|
||||||
template<typename XprType,typename StorageKind> class InverseImpl;
|
template<typename XprType,typename StorageKind> class InverseImpl;
|
||||||
@ -127,8 +125,6 @@ protected:
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_INVERSE_H
|
#endif // EIGEN_INVERSE_H
|
||||||
|
@ -80,26 +80,8 @@ struct traits<Map<PlainObjectType, MapOptions, StrideType> >
|
|||||||
? int(PlainObjectType::OuterStrideAtCompileTime)
|
? int(PlainObjectType::OuterStrideAtCompileTime)
|
||||||
: int(StrideType::OuterStrideAtCompileTime),
|
: int(StrideType::OuterStrideAtCompileTime),
|
||||||
IsAligned = bool(EIGEN_ALIGN) && ((int(MapOptions)&Aligned)==Aligned),
|
IsAligned = bool(EIGEN_ALIGN) && ((int(MapOptions)&Aligned)==Aligned),
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
HasNoInnerStride = InnerStrideAtCompileTime == 1,
|
|
||||||
HasNoOuterStride = StrideType::OuterStrideAtCompileTime == 0,
|
|
||||||
HasNoStride = HasNoInnerStride && HasNoOuterStride,
|
|
||||||
IsDynamicSize = PlainObjectType::SizeAtCompileTime==Dynamic,
|
|
||||||
KeepsPacketAccess = bool(HasNoInnerStride)
|
|
||||||
&& ( bool(IsDynamicSize)
|
|
||||||
|| HasNoOuterStride
|
|
||||||
|| ( OuterStrideAtCompileTime!=Dynamic
|
|
||||||
&& ((static_cast<int>(sizeof(Scalar))*OuterStrideAtCompileTime)%EIGEN_ALIGN_BYTES)==0 ) ),
|
|
||||||
Flags0 = TraitsBase::Flags & (~NestByRefBit),
|
|
||||||
Flags1 = IsAligned ? (int(Flags0) | AlignedBit) : (int(Flags0) & ~AlignedBit),
|
|
||||||
Flags2 = (bool(HasNoStride) || bool(PlainObjectType::IsVectorAtCompileTime))
|
|
||||||
? int(Flags1) : int(Flags1 & ~LinearAccessBit),
|
|
||||||
Flags3 = is_lvalue<PlainObjectType>::value ? int(Flags2) : (int(Flags2) & ~LvalueBit),
|
|
||||||
Flags = KeepsPacketAccess ? int(Flags3) : (int(Flags3) & ~PacketAccessBit)
|
|
||||||
#else
|
|
||||||
Flags0 = TraitsBase::Flags & (~NestByRefBit),
|
Flags0 = TraitsBase::Flags & (~NestByRefBit),
|
||||||
Flags = is_lvalue<PlainObjectType>::value ? int(Flags0) : (int(Flags0) & ~LvalueBit)
|
Flags = is_lvalue<PlainObjectType>::value ? int(Flags0) : (int(Flags0) & ~LvalueBit)
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
enum { Options }; // Expressions don't have Options
|
enum { Options }; // Expressions don't have Options
|
||||||
|
@ -11,15 +11,9 @@
|
|||||||
#ifndef EIGEN_MAPBASE_H
|
#ifndef EIGEN_MAPBASE_H
|
||||||
#define EIGEN_MAPBASE_H
|
#define EIGEN_MAPBASE_H
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
#define EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) \
|
|
||||||
EIGEN_STATIC_ASSERT((int(internal::traits<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \
|
|
||||||
YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT)
|
|
||||||
#else
|
|
||||||
#define EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) \
|
#define EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) \
|
||||||
EIGEN_STATIC_ASSERT((int(internal::evaluator<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \
|
EIGEN_STATIC_ASSERT((int(internal::evaluator<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \
|
||||||
YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT)
|
YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT)
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
@ -167,15 +161,7 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
void checkSanity() const
|
void checkSanity() const
|
||||||
{
|
{
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
// moved to evaluator
|
|
||||||
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(internal::traits<Derived>::Flags&PacketAccessBit,
|
|
||||||
internal::inner_stride_at_compile_time<Derived>::ret==1),
|
|
||||||
PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1);
|
|
||||||
eigen_assert(EIGEN_IMPLIES(internal::traits<Derived>::Flags&AlignedBit, (size_t(m_data) % EIGEN_ALIGN_BYTES) == 0) && "data is not aligned");
|
|
||||||
#else
|
|
||||||
eigen_assert(EIGEN_IMPLIES(internal::traits<Derived>::IsAligned, (size_t(m_data) % EIGEN_ALIGN_BYTES) == 0) && "data is not aligned");
|
eigen_assert(EIGEN_IMPLIES(internal::traits<Derived>::IsAligned, (size_t(m_data) % EIGEN_ALIGN_BYTES) == 0) && "data is not aligned");
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PointerType m_data;
|
PointerType m_data;
|
||||||
|
@ -115,12 +115,8 @@ struct traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
|||||||
MaxRowsAtCompileTime = _MaxRows,
|
MaxRowsAtCompileTime = _MaxRows,
|
||||||
MaxColsAtCompileTime = _MaxCols,
|
MaxColsAtCompileTime = _MaxCols,
|
||||||
Flags = compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret,
|
Flags = compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret,
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
CoeffReadCost = NumTraits<Scalar>::ReadCost,
|
|
||||||
#else
|
|
||||||
// FIXME, the following flag in only used to define NeedsToAlign in PlainObjectBase
|
// FIXME, the following flag in only used to define NeedsToAlign in PlainObjectBase
|
||||||
EvaluatorFlags = compute_matrix_evaluator_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret,
|
EvaluatorFlags = compute_matrix_evaluator_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret,
|
||||||
#endif
|
|
||||||
Options = _Options,
|
Options = _Options,
|
||||||
InnerStrideAtCompileTime = 1,
|
InnerStrideAtCompileTime = 1,
|
||||||
OuterStrideAtCompileTime = (Options&RowMajor) ? ColsAtCompileTime : RowsAtCompileTime
|
OuterStrideAtCompileTime = (Options&RowMajor) ? ColsAtCompileTime : RowsAtCompileTime
|
||||||
|
@ -66,9 +66,6 @@ template<typename Derived> class MatrixBase
|
|||||||
using Base::MaxSizeAtCompileTime;
|
using Base::MaxSizeAtCompileTime;
|
||||||
using Base::IsVectorAtCompileTime;
|
using Base::IsVectorAtCompileTime;
|
||||||
using Base::Flags;
|
using Base::Flags;
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
using Base::CoeffReadCost;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using Base::derived;
|
using Base::derived;
|
||||||
using Base::const_cast_derived;
|
using Base::const_cast_derived;
|
||||||
@ -188,25 +185,15 @@ template<typename Derived> class MatrixBase
|
|||||||
{ return this->lazyProduct(other); }
|
{ return this->lazyProduct(other); }
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
const Product<Derived,OtherDerived>
|
const Product<Derived,OtherDerived>
|
||||||
operator*(const MatrixBase<OtherDerived> &other) const;
|
operator*(const MatrixBase<OtherDerived> &other) const;
|
||||||
#else
|
|
||||||
template<typename OtherDerived>
|
|
||||||
const typename ProductReturnType<Derived,OtherDerived>::Type
|
|
||||||
operator*(const MatrixBase<OtherDerived> &other) const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
const Product<Derived,OtherDerived,LazyProduct>
|
const Product<Derived,OtherDerived,LazyProduct>
|
||||||
#else
|
|
||||||
const typename LazyProductReturnType<Derived,OtherDerived>::Type
|
|
||||||
#endif
|
|
||||||
lazyProduct(const MatrixBase<OtherDerived> &other) const;
|
lazyProduct(const MatrixBase<OtherDerived> &other) const;
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
@ -218,17 +205,10 @@ template<typename Derived> class MatrixBase
|
|||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
void applyOnTheRight(const EigenBase<OtherDerived>& other);
|
void applyOnTheRight(const EigenBase<OtherDerived>& other);
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename DiagonalDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const DiagonalProduct<Derived, DiagonalDerived, OnTheRight>
|
|
||||||
operator*(const DiagonalBase<DiagonalDerived> &diagonal) const;
|
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename DiagonalDerived>
|
template<typename DiagonalDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const Product<Derived, DiagonalDerived, LazyProduct>
|
const Product<Derived, DiagonalDerived, LazyProduct>
|
||||||
operator*(const DiagonalBase<DiagonalDerived> &diagonal) const;
|
operator*(const DiagonalBase<DiagonalDerived> &diagonal) const;
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@ -347,19 +327,12 @@ template<typename Derived> class MatrixBase
|
|||||||
|
|
||||||
NoAlias<Derived,Eigen::MatrixBase > noalias();
|
NoAlias<Derived,Eigen::MatrixBase > noalias();
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
|
|
||||||
inline ForceAlignedAccess<Derived> forceAlignedAccess();
|
|
||||||
template<bool Enable> inline typename internal::add_const_on_value_type<typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type>::type forceAlignedAccessIf() const;
|
|
||||||
template<bool Enable> inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf();
|
|
||||||
#else
|
|
||||||
// TODO forceAlignedAccess is temporarly disabled
|
// TODO forceAlignedAccess is temporarly disabled
|
||||||
// Need to find a nicer workaround.
|
// Need to find a nicer workaround.
|
||||||
inline const Derived& forceAlignedAccess() const { return derived(); }
|
inline const Derived& forceAlignedAccess() const { return derived(); }
|
||||||
inline Derived& forceAlignedAccess() { return derived(); }
|
inline Derived& forceAlignedAccess() { return derived(); }
|
||||||
template<bool Enable> inline const Derived& forceAlignedAccessIf() const { return derived(); }
|
template<bool Enable> inline const Derived& forceAlignedAccessIf() const { return derived(); }
|
||||||
template<bool Enable> inline Derived& forceAlignedAccessIf() { return derived(); }
|
template<bool Enable> inline Derived& forceAlignedAccessIf() { return derived(); }
|
||||||
#endif
|
|
||||||
|
|
||||||
Scalar trace() const;
|
Scalar trace() const;
|
||||||
|
|
||||||
@ -382,13 +355,9 @@ template<typename Derived> class MatrixBase
|
|||||||
|
|
||||||
const PartialPivLU<PlainObject> lu() const;
|
const PartialPivLU<PlainObject> lu() const;
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const Inverse<Derived> inverse() const;
|
const Inverse<Derived> inverse() const;
|
||||||
#else
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const internal::inverse_impl<Derived> inverse() const;
|
|
||||||
#endif
|
|
||||||
template<typename ResultType>
|
template<typename ResultType>
|
||||||
void computeInverseAndDetWithCheck(
|
void computeInverseAndDetWithCheck(
|
||||||
ResultType& inverse,
|
ResultType& inverse,
|
||||||
|
@ -35,7 +35,6 @@ class NoAlias
|
|||||||
|
|
||||||
NoAlias(ExpressionType& expression) : m_expression(expression) {}
|
NoAlias(ExpressionType& expression) : m_expression(expression) {}
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other)
|
EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other)
|
||||||
@ -59,68 +58,6 @@ class NoAlias
|
|||||||
call_assignment_no_alias(m_expression, other.derived(), internal::sub_assign_op<Scalar>());
|
call_assignment_no_alias(m_expression, other.derived(), internal::sub_assign_op<Scalar>());
|
||||||
return m_expression;
|
return m_expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/** Behaves like MatrixBase::lazyAssign(other)
|
|
||||||
* \sa MatrixBase::lazyAssign() */
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other)
|
|
||||||
{ return internal::assign_selector<ExpressionType,OtherDerived,false>::run(m_expression,other.derived()); }
|
|
||||||
|
|
||||||
/** \sa MatrixBase::operator+= */
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
typedef SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, ExpressionType, OtherDerived> SelfAdder;
|
|
||||||
SelfAdder tmp(m_expression);
|
|
||||||
typedef typename internal::nested<OtherDerived>::type OtherDerivedNested;
|
|
||||||
typedef typename internal::remove_all<OtherDerivedNested>::type _OtherDerivedNested;
|
|
||||||
internal::assign_selector<SelfAdder,_OtherDerivedNested,false>::run(tmp,OtherDerivedNested(other.derived()));
|
|
||||||
return m_expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \sa MatrixBase::operator-= */
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
typedef SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, ExpressionType, OtherDerived> SelfAdder;
|
|
||||||
SelfAdder tmp(m_expression);
|
|
||||||
typedef typename internal::nested<OtherDerived>::type OtherDerivedNested;
|
|
||||||
typedef typename internal::remove_all<OtherDerivedNested>::type _OtherDerivedNested;
|
|
||||||
internal::assign_selector<SelfAdder,_OtherDerivedNested,false>::run(tmp,OtherDerivedNested(other.derived()));
|
|
||||||
return m_expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
|
||||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE ExpressionType& operator+=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
|
|
||||||
{ other.derived().addTo(m_expression); return m_expression; }
|
|
||||||
|
|
||||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE ExpressionType& operator-=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
|
|
||||||
{ other.derived().subTo(m_expression); return m_expression; }
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int NestingFlags>
|
|
||||||
EIGEN_STRONG_INLINE ExpressionType& operator+=(const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other)
|
|
||||||
{ return m_expression.derived() += CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); }
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int NestingFlags>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE ExpressionType& operator-=(const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other)
|
|
||||||
{ return m_expression.derived() -= CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); }
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
ExpressionType& operator=(const ReturnByValue<OtherDerived>& func)
|
|
||||||
{ return m_expression = func; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
ExpressionType& expression() const
|
ExpressionType& expression() const
|
||||||
|
@ -61,9 +61,6 @@ class PermutationBase : public EigenBase<Derived>
|
|||||||
typedef typename Traits::IndicesType IndicesType;
|
typedef typename Traits::IndicesType IndicesType;
|
||||||
enum {
|
enum {
|
||||||
Flags = Traits::Flags,
|
Flags = Traits::Flags,
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
CoeffReadCost = Traits::CoeffReadCost,
|
|
||||||
#endif
|
|
||||||
RowsAtCompileTime = Traits::RowsAtCompileTime,
|
RowsAtCompileTime = Traits::RowsAtCompileTime,
|
||||||
ColsAtCompileTime = Traits::ColsAtCompileTime,
|
ColsAtCompileTime = Traits::ColsAtCompileTime,
|
||||||
MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime,
|
MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime,
|
||||||
@ -291,9 +288,7 @@ class PermutationMatrix : public PermutationBase<PermutationMatrix<SizeAtCompile
|
|||||||
typedef internal::traits<PermutationMatrix> Traits;
|
typedef internal::traits<PermutationMatrix> Traits;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
typedef const PermutationMatrix& Nested;
|
typedef const PermutationMatrix& Nested;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
typedef typename Traits::IndicesType IndicesType;
|
typedef typename Traits::IndicesType IndicesType;
|
||||||
@ -484,18 +479,9 @@ struct traits<PermutationWrapper<_IndicesType> >
|
|||||||
enum {
|
enum {
|
||||||
RowsAtCompileTime = _IndicesType::SizeAtCompileTime,
|
RowsAtCompileTime = _IndicesType::SizeAtCompileTime,
|
||||||
ColsAtCompileTime = _IndicesType::SizeAtCompileTime,
|
ColsAtCompileTime = _IndicesType::SizeAtCompileTime,
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
MaxRowsAtCompileTime = IndicesType::MaxSizeAtCompileTime,
|
MaxRowsAtCompileTime = IndicesType::MaxSizeAtCompileTime,
|
||||||
MaxColsAtCompileTime = IndicesType::MaxSizeAtCompileTime,
|
MaxColsAtCompileTime = IndicesType::MaxSizeAtCompileTime,
|
||||||
#else
|
|
||||||
MaxRowsAtCompileTime = IndicesType::MaxRowsAtCompileTime, // is this a bug in Eigen 2.2 ?
|
|
||||||
MaxColsAtCompileTime = IndicesType::MaxColsAtCompileTime,
|
|
||||||
#endif
|
|
||||||
Flags = 0
|
Flags = 0
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
,
|
|
||||||
CoeffReadCost = _IndicesType::CoeffReadCost
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -524,7 +510,6 @@ class PermutationWrapper : public PermutationBase<PermutationWrapper<_IndicesTyp
|
|||||||
typename IndicesType::Nested m_indices;
|
typename IndicesType::Nested m_indices;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
// TODO: Do we need to define these operator* functions? Would it be better to have them inherited
|
// TODO: Do we need to define these operator* functions? Would it be better to have them inherited
|
||||||
// from MatrixBase?
|
// from MatrixBase?
|
||||||
@ -553,35 +538,6 @@ operator*(const PermutationBase<PermutationDerived> &permutation,
|
|||||||
(permutation.derived(), matrix.derived());
|
(permutation.derived(), matrix.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** \returns the matrix with the permutation applied to the columns.
|
|
||||||
*/
|
|
||||||
template<typename Derived, typename PermutationDerived>
|
|
||||||
inline const internal::permut_matrix_product_retval<PermutationDerived, Derived, OnTheRight>
|
|
||||||
operator*(const MatrixBase<Derived>& matrix,
|
|
||||||
const PermutationBase<PermutationDerived> &permutation)
|
|
||||||
{
|
|
||||||
return internal::permut_matrix_product_retval
|
|
||||||
<PermutationDerived, Derived, OnTheRight>
|
|
||||||
(permutation.derived(), matrix.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns the matrix with the permutation applied to the rows.
|
|
||||||
*/
|
|
||||||
template<typename Derived, typename PermutationDerived>
|
|
||||||
inline const internal::permut_matrix_product_retval
|
|
||||||
<PermutationDerived, Derived, OnTheLeft>
|
|
||||||
operator*(const PermutationBase<PermutationDerived> &permutation,
|
|
||||||
const MatrixBase<Derived>& matrix)
|
|
||||||
{
|
|
||||||
return internal::permut_matrix_product_retval
|
|
||||||
<PermutationDerived, Derived, OnTheLeft>
|
|
||||||
(permutation.derived(), matrix.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<typename PermutationType, typename MatrixType, int Side, bool Transposed>
|
template<typename PermutationType, typename MatrixType, int Side, bool Transposed>
|
||||||
@ -682,9 +638,6 @@ class Transpose<PermutationBase<Derived> >
|
|||||||
typedef typename Derived::DenseMatrixType DenseMatrixType;
|
typedef typename Derived::DenseMatrixType DenseMatrixType;
|
||||||
enum {
|
enum {
|
||||||
Flags = Traits::Flags,
|
Flags = Traits::Flags,
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
CoeffReadCost = Traits::CoeffReadCost,
|
|
||||||
#endif
|
|
||||||
RowsAtCompileTime = Traits::RowsAtCompileTime,
|
RowsAtCompileTime = Traits::RowsAtCompileTime,
|
||||||
ColsAtCompileTime = Traits::ColsAtCompileTime,
|
ColsAtCompileTime = Traits::ColsAtCompileTime,
|
||||||
MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime,
|
MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime,
|
||||||
@ -713,8 +666,6 @@ class Transpose<PermutationBase<Derived> >
|
|||||||
|
|
||||||
DenseMatrixType toDenseMatrix() const { return *this; }
|
DenseMatrixType toDenseMatrix() const { return *this; }
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** \returns the matrix with the inverse permutation applied to the columns.
|
/** \returns the matrix with the inverse permutation applied to the columns.
|
||||||
*/
|
*/
|
||||||
template<typename OtherDerived> friend
|
template<typename OtherDerived> friend
|
||||||
@ -733,28 +684,6 @@ class Transpose<PermutationBase<Derived> >
|
|||||||
return Product<Transpose, OtherDerived, DefaultProduct>(*this, matrix.derived());
|
return Product<Transpose, OtherDerived, DefaultProduct>(*this, matrix.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** \returns the matrix with the inverse permutation applied to the columns.
|
|
||||||
*/
|
|
||||||
template<typename OtherDerived> friend
|
|
||||||
inline const internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheRight, true>
|
|
||||||
operator*(const MatrixBase<OtherDerived>& matrix, const Transpose& trPerm)
|
|
||||||
{
|
|
||||||
return internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheRight, true>(trPerm.m_permutation, matrix.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns the matrix with the inverse permutation applied to the rows.
|
|
||||||
*/
|
|
||||||
template<typename OtherDerived>
|
|
||||||
inline const internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheLeft, true>
|
|
||||||
operator*(const MatrixBase<OtherDerived>& matrix) const
|
|
||||||
{
|
|
||||||
return internal::permut_matrix_product_retval<PermutationType, OtherDerived, OnTheLeft, true>(m_permutation, matrix.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
const PermutationType& nestedPermutation() const { return m_permutation; }
|
const PermutationType& nestedPermutation() const { return m_permutation; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -767,7 +696,6 @@ const PermutationWrapper<const Derived> MatrixBase<Derived>::asPermutation() con
|
|||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// TODO currently a permutation matrix expression has the form PermutationMatrix or PermutationWrapper
|
// TODO currently a permutation matrix expression has the form PermutationMatrix or PermutationWrapper
|
||||||
@ -799,7 +727,6 @@ struct evaluator_traits<Transpose<PermutationBase<Derived> > >
|
|||||||
template<> struct AssignmentKind<DenseShape,PermutationShape> { typedef EigenBase2EigenBase Kind; };
|
template<> struct AssignmentKind<DenseShape,PermutationShape> { typedef EigenBase2EigenBase Kind; };
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
@ -128,11 +128,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
|
DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
enum { NeedsToAlign = SizeAtCompileTime != Dynamic && (internal::traits<Derived>::Flags & AlignedBit) != 0 };
|
|
||||||
#else
|
|
||||||
enum { NeedsToAlign = SizeAtCompileTime != Dynamic && (internal::traits<Derived>::EvaluatorFlags & AlignedBit) != 0 };
|
enum { NeedsToAlign = SizeAtCompileTime != Dynamic && (internal::traits<Derived>::EvaluatorFlags & AlignedBit) != 0 };
|
||||||
#endif
|
|
||||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
|
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@ -643,7 +639,6 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
*
|
*
|
||||||
* \internal
|
* \internal
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
// aliasing is dealt once in internall::call_assignment
|
// aliasing is dealt once in internall::call_assignment
|
||||||
// so at this stage we have to assume aliasing... and resising has to be done later.
|
// so at this stage we have to assume aliasing... and resising has to be done later.
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
@ -654,23 +649,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
return this->derived();
|
return this->derived();
|
||||||
return this->derived();
|
return this->derived();
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
_set_selector(other.derived(), typename internal::conditional<static_cast<bool>(int(OtherDerived::Flags) & EvalBeforeAssigningBit), internal::true_type, internal::false_type>::type());
|
|
||||||
return this->derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::true_type&) { _set_noalias(other.eval()); }
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::false_type&) { _set_noalias(other); }
|
|
||||||
#endif
|
|
||||||
/** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which
|
/** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which
|
||||||
* is the case when creating a new matrix) so one can enforce lazy evaluation.
|
* is the case when creating a new matrix) so one can enforce lazy evaluation.
|
||||||
*
|
*
|
||||||
@ -685,12 +664,8 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
//_resize_to_match(other);
|
//_resize_to_match(other);
|
||||||
// the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
|
// the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
|
||||||
// it wouldn't allow to copy a row-vector into a column-vector.
|
// it wouldn't allow to copy a row-vector into a column-vector.
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
internal::call_assignment_no_alias(this->derived(), other.derived(), internal::assign_op<Scalar>());
|
internal::call_assignment_no_alias(this->derived(), other.derived(), internal::assign_op<Scalar>());
|
||||||
return this->derived();
|
return this->derived();
|
||||||
#else
|
|
||||||
return internal::assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T0, typename T1>
|
template<typename T0, typename T1>
|
||||||
|
@ -79,11 +79,6 @@ struct traits<Product<Lhs, Rhs, Option> >
|
|||||||
// FIXME: only needed by GeneralMatrixMatrixTriangular
|
// FIXME: only needed by GeneralMatrixMatrixTriangular
|
||||||
InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(LhsTraits::ColsAtCompileTime, RhsTraits::RowsAtCompileTime),
|
InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(LhsTraits::ColsAtCompileTime, RhsTraits::RowsAtCompileTime),
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
// dummy, for evaluators unit test only
|
|
||||||
CoeffReadCost = Dynamic,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The storage order is somewhat arbitrary here. The correct one will be determined through the evaluator.
|
// The storage order is somewhat arbitrary here. The correct one will be determined through the evaluator.
|
||||||
Flags = ( (MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1)
|
Flags = ( (MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1)
|
||||||
|| ((LhsTraits::Flags&NoPreferredStorageOrderBit) && (RhsTraits::Flags&RowMajorBit))
|
|| ((LhsTraits::Flags&NoPreferredStorageOrderBit) && (RhsTraits::Flags&RowMajorBit))
|
||||||
@ -164,7 +159,6 @@ public:
|
|||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
// Generic API dispatcher
|
// Generic API dispatcher
|
||||||
template<typename Lhs, typename Rhs, int Option, typename StorageKind>
|
template<typename Lhs, typename Rhs, int Option, typename StorageKind>
|
||||||
class ProductImpl : public internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type
|
class ProductImpl : public internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type
|
||||||
@ -172,7 +166,6 @@ class ProductImpl : public internal::generic_xpr_base<Product<Lhs,Rhs,Option>, M
|
|||||||
public:
|
public:
|
||||||
typedef typename internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type Base;
|
typedef typename internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type Base;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int Option>
|
template<typename Lhs, typename Rhs, int Option>
|
||||||
class ProductImpl<Lhs,Rhs,Option,Dense>
|
class ProductImpl<Lhs,Rhs,Option,Dense>
|
||||||
|
@ -12,258 +12,6 @@
|
|||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** \class ProductBase
|
|
||||||
* \ingroup Core_Module
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
template<typename Derived, typename _Lhs, typename _Rhs>
|
|
||||||
struct traits<ProductBase<Derived,_Lhs,_Rhs> >
|
|
||||||
{
|
|
||||||
typedef MatrixXpr XprKind;
|
|
||||||
typedef typename remove_all<_Lhs>::type Lhs;
|
|
||||||
typedef typename remove_all<_Rhs>::type Rhs;
|
|
||||||
typedef typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar;
|
|
||||||
typedef typename product_promote_storage_type<typename traits<Lhs>::StorageKind,
|
|
||||||
typename traits<Rhs>::StorageKind,
|
|
||||||
0>::ret StorageKind;
|
|
||||||
typedef typename promote_index_type<typename traits<Lhs>::Index,
|
|
||||||
typename traits<Rhs>::Index>::type Index;
|
|
||||||
enum {
|
|
||||||
RowsAtCompileTime = traits<Lhs>::RowsAtCompileTime,
|
|
||||||
ColsAtCompileTime = traits<Rhs>::ColsAtCompileTime,
|
|
||||||
MaxRowsAtCompileTime = traits<Lhs>::MaxRowsAtCompileTime,
|
|
||||||
MaxColsAtCompileTime = traits<Rhs>::MaxColsAtCompileTime,
|
|
||||||
Flags = (MaxRowsAtCompileTime==1 ? RowMajorBit : 0)
|
|
||||||
| EvalBeforeNestingBit | EvalBeforeAssigningBit | NestByRefBit,
|
|
||||||
// Note that EvalBeforeNestingBit and NestByRefBit
|
|
||||||
// are not used in practice because nested is overloaded for products
|
|
||||||
CoeffReadCost = 0 // FIXME why is it needed ?
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#define EIGEN_PRODUCT_PUBLIC_INTERFACE(Derived) \
|
|
||||||
typedef ProductBase<Derived, Lhs, Rhs > Base; \
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \
|
|
||||||
typedef typename Base::LhsNested LhsNested; \
|
|
||||||
typedef typename Base::_LhsNested _LhsNested; \
|
|
||||||
typedef typename Base::LhsBlasTraits LhsBlasTraits; \
|
|
||||||
typedef typename Base::ActualLhsType ActualLhsType; \
|
|
||||||
typedef typename Base::_ActualLhsType _ActualLhsType; \
|
|
||||||
typedef typename Base::RhsNested RhsNested; \
|
|
||||||
typedef typename Base::_RhsNested _RhsNested; \
|
|
||||||
typedef typename Base::RhsBlasTraits RhsBlasTraits; \
|
|
||||||
typedef typename Base::ActualRhsType ActualRhsType; \
|
|
||||||
typedef typename Base::_ActualRhsType _ActualRhsType; \
|
|
||||||
using Base::m_lhs; \
|
|
||||||
using Base::m_rhs;
|
|
||||||
|
|
||||||
template<typename Derived, typename Lhs, typename Rhs>
|
|
||||||
class ProductBase : public MatrixBase<Derived>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef MatrixBase<Derived> Base;
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(ProductBase)
|
|
||||||
|
|
||||||
typedef typename Lhs::Nested LhsNested;
|
|
||||||
typedef typename internal::remove_all<LhsNested>::type _LhsNested;
|
|
||||||
typedef internal::blas_traits<_LhsNested> LhsBlasTraits;
|
|
||||||
typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
|
|
||||||
typedef typename internal::remove_all<ActualLhsType>::type _ActualLhsType;
|
|
||||||
typedef typename internal::traits<Lhs>::Scalar LhsScalar;
|
|
||||||
|
|
||||||
typedef typename Rhs::Nested RhsNested;
|
|
||||||
typedef typename internal::remove_all<RhsNested>::type _RhsNested;
|
|
||||||
typedef internal::blas_traits<_RhsNested> RhsBlasTraits;
|
|
||||||
typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
|
|
||||||
typedef typename internal::remove_all<ActualRhsType>::type _ActualRhsType;
|
|
||||||
typedef typename internal::traits<Rhs>::Scalar RhsScalar;
|
|
||||||
|
|
||||||
// Diagonal of a product: no need to evaluate the arguments because they are going to be evaluated only once
|
|
||||||
typedef CoeffBasedProduct<LhsNested, RhsNested, 0> FullyLazyCoeffBaseProductType;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef typename Base::PlainObject PlainObject;
|
|
||||||
|
|
||||||
ProductBase(const Lhs& a_lhs, const Rhs& a_rhs)
|
|
||||||
: m_lhs(a_lhs), m_rhs(a_rhs)
|
|
||||||
{
|
|
||||||
eigen_assert(a_lhs.cols() == a_rhs.rows()
|
|
||||||
&& "invalid matrix product"
|
|
||||||
&& "if you wanted a coeff-wise or a dot product use the respective explicit functions");
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Index rows() const { return m_lhs.rows(); }
|
|
||||||
inline Index cols() const { return m_rhs.cols(); }
|
|
||||||
|
|
||||||
template<typename Dest>
|
|
||||||
inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst,Scalar(1)); }
|
|
||||||
|
|
||||||
template<typename Dest>
|
|
||||||
inline void addTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(1)); }
|
|
||||||
|
|
||||||
template<typename Dest>
|
|
||||||
inline void subTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(-1)); }
|
|
||||||
|
|
||||||
template<typename Dest>
|
|
||||||
inline void scaleAndAddTo(Dest& dst, const Scalar& alpha) const { derived().scaleAndAddTo(dst,alpha); }
|
|
||||||
|
|
||||||
const _LhsNested& lhs() const { return m_lhs; }
|
|
||||||
const _RhsNested& rhs() const { return m_rhs; }
|
|
||||||
|
|
||||||
// Implicit conversion to the nested type (trigger the evaluation of the product)
|
|
||||||
operator const PlainObject& () const
|
|
||||||
{
|
|
||||||
m_result.resize(m_lhs.rows(), m_rhs.cols());
|
|
||||||
derived().evalTo(m_result);
|
|
||||||
return m_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Diagonal<const FullyLazyCoeffBaseProductType,0> diagonal() const
|
|
||||||
{ return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); }
|
|
||||||
|
|
||||||
template<int Index>
|
|
||||||
const Diagonal<FullyLazyCoeffBaseProductType,Index> diagonal() const
|
|
||||||
{ return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); }
|
|
||||||
|
|
||||||
const Diagonal<FullyLazyCoeffBaseProductType,Dynamic> diagonal(Index index) const
|
|
||||||
{ return FullyLazyCoeffBaseProductType(m_lhs, m_rhs).diagonal(index); }
|
|
||||||
|
|
||||||
// restrict coeff accessors to 1x1 expressions. No need to care about mutators here since this isn't an Lvalue expression
|
|
||||||
typename Base::CoeffReturnType coeff(Index row, Index col) const
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
|
|
||||||
eigen_assert(this->rows() == 1 && this->cols() == 1);
|
|
||||||
Matrix<Scalar,1,1> result = *this;
|
|
||||||
return result.coeff(row,col);
|
|
||||||
}
|
|
||||||
|
|
||||||
typename Base::CoeffReturnType coeff(Index i) const
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
|
|
||||||
eigen_assert(this->rows() == 1 && this->cols() == 1);
|
|
||||||
Matrix<Scalar,1,1> result = *this;
|
|
||||||
return result.coeff(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Scalar& coeffRef(Index row, Index col) const
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
|
|
||||||
eigen_assert(this->rows() == 1 && this->cols() == 1);
|
|
||||||
return derived().coeffRef(row,col);
|
|
||||||
}
|
|
||||||
|
|
||||||
const Scalar& coeffRef(Index i) const
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
|
|
||||||
eigen_assert(this->rows() == 1 && this->cols() == 1);
|
|
||||||
return derived().coeffRef(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
LhsNested m_lhs;
|
|
||||||
RhsNested m_rhs;
|
|
||||||
|
|
||||||
mutable PlainObject m_result;
|
|
||||||
};
|
|
||||||
|
|
||||||
// here we need to overload the nested rule for products
|
|
||||||
// such that the nested type is a const reference to a plain matrix
|
|
||||||
namespace internal {
|
|
||||||
template<typename Lhs, typename Rhs, int Mode, int N, typename PlainObject>
|
|
||||||
struct nested<GeneralProduct<Lhs,Rhs,Mode>, N, PlainObject>
|
|
||||||
{
|
|
||||||
typedef PlainObject const& type;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename NestedProduct>
|
|
||||||
class ScaledProduct;
|
|
||||||
|
|
||||||
// Note that these two operator* functions are not defined as member
|
|
||||||
// functions of ProductBase, because, otherwise we would have to
|
|
||||||
// define all overloads defined in MatrixBase. Furthermore, Using
|
|
||||||
// "using Base::operator*" would not work with MSVC.
|
|
||||||
//
|
|
||||||
// Also note that here we accept any compatible scalar types
|
|
||||||
template<typename Derived,typename Lhs,typename Rhs>
|
|
||||||
const ScaledProduct<Derived>
|
|
||||||
operator*(const ProductBase<Derived,Lhs,Rhs>& prod, const typename Derived::Scalar& x)
|
|
||||||
{ return ScaledProduct<Derived>(prod.derived(), x); }
|
|
||||||
|
|
||||||
template<typename Derived,typename Lhs,typename Rhs>
|
|
||||||
typename internal::enable_if<!internal::is_same<typename Derived::Scalar,typename Derived::RealScalar>::value,
|
|
||||||
const ScaledProduct<Derived> >::type
|
|
||||||
operator*(const ProductBase<Derived,Lhs,Rhs>& prod, const typename Derived::RealScalar& x)
|
|
||||||
{ return ScaledProduct<Derived>(prod.derived(), x); }
|
|
||||||
|
|
||||||
|
|
||||||
template<typename Derived,typename Lhs,typename Rhs>
|
|
||||||
const ScaledProduct<Derived>
|
|
||||||
operator*(const typename Derived::Scalar& x,const ProductBase<Derived,Lhs,Rhs>& prod)
|
|
||||||
{ return ScaledProduct<Derived>(prod.derived(), x); }
|
|
||||||
|
|
||||||
template<typename Derived,typename Lhs,typename Rhs>
|
|
||||||
typename internal::enable_if<!internal::is_same<typename Derived::Scalar,typename Derived::RealScalar>::value,
|
|
||||||
const ScaledProduct<Derived> >::type
|
|
||||||
operator*(const typename Derived::RealScalar& x,const ProductBase<Derived,Lhs,Rhs>& prod)
|
|
||||||
{ return ScaledProduct<Derived>(prod.derived(), x); }
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
template<typename NestedProduct>
|
|
||||||
struct traits<ScaledProduct<NestedProduct> >
|
|
||||||
: traits<ProductBase<ScaledProduct<NestedProduct>,
|
|
||||||
typename NestedProduct::_LhsNested,
|
|
||||||
typename NestedProduct::_RhsNested> >
|
|
||||||
{
|
|
||||||
typedef typename traits<NestedProduct>::StorageKind StorageKind;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename NestedProduct>
|
|
||||||
class ScaledProduct
|
|
||||||
: public ProductBase<ScaledProduct<NestedProduct>,
|
|
||||||
typename NestedProduct::_LhsNested,
|
|
||||||
typename NestedProduct::_RhsNested>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef ProductBase<ScaledProduct<NestedProduct>,
|
|
||||||
typename NestedProduct::_LhsNested,
|
|
||||||
typename NestedProduct::_RhsNested> Base;
|
|
||||||
typedef typename Base::Scalar Scalar;
|
|
||||||
typedef typename Base::PlainObject PlainObject;
|
|
||||||
// EIGEN_PRODUCT_PUBLIC_INTERFACE(ScaledProduct)
|
|
||||||
|
|
||||||
ScaledProduct(const NestedProduct& prod, const Scalar& x)
|
|
||||||
: Base(prod.lhs(),prod.rhs()), m_prod(prod), m_alpha(x) {}
|
|
||||||
|
|
||||||
template<typename Dest>
|
|
||||||
inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst, Scalar(1)); }
|
|
||||||
|
|
||||||
template<typename Dest>
|
|
||||||
inline void addTo(Dest& dst) const { scaleAndAddTo(dst, Scalar(1)); }
|
|
||||||
|
|
||||||
template<typename Dest>
|
|
||||||
inline void subTo(Dest& dst) const { scaleAndAddTo(dst, Scalar(-1)); }
|
|
||||||
|
|
||||||
template<typename Dest>
|
|
||||||
inline void scaleAndAddTo(Dest& dst, const Scalar& a_alpha) const { m_prod.derived().scaleAndAddTo(dst,a_alpha * m_alpha); }
|
|
||||||
|
|
||||||
const Scalar& alpha() const { return m_alpha; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const NestedProduct& m_prod;
|
|
||||||
Scalar m_alpha;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* Overloaded to perform an efficient C = (A*B).lazy() */
|
* Overloaded to perform an efficient C = (A*B).lazy() */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
|
@ -69,11 +69,7 @@ public:
|
|||||||
#ifdef EIGEN_DEBUG_ASSIGN
|
#ifdef EIGEN_DEBUG_ASSIGN
|
||||||
static void debug()
|
static void debug()
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
std::cerr << "Xpr: " << typeid(typename Derived::XprType).name() << std::endl;
|
std::cerr << "Xpr: " << typeid(typename Derived::XprType).name() << std::endl;
|
||||||
#else
|
|
||||||
std::cerr << "Xpr: " << typeid(Derived).name() << std::endl;
|
|
||||||
#endif
|
|
||||||
std::cerr.setf(std::ios::hex, std::ios::basefield);
|
std::cerr.setf(std::ios::hex, std::ios::basefield);
|
||||||
EIGEN_DEBUG_VAR(Derived::Flags)
|
EIGEN_DEBUG_VAR(Derived::Flags)
|
||||||
std::cerr.unsetf(std::ios::hex);
|
std::cerr.unsetf(std::ios::hex);
|
||||||
@ -338,7 +334,6 @@ struct redux_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
// evaluator adaptor
|
// evaluator adaptor
|
||||||
template<typename _XprType>
|
template<typename _XprType>
|
||||||
class redux_evaluator
|
class redux_evaluator
|
||||||
@ -395,7 +390,6 @@ protected:
|
|||||||
typename internal::evaluator<XprType>::nestedType m_evaluator;
|
typename internal::evaluator<XprType>::nestedType m_evaluator;
|
||||||
const XprType &m_xpr;
|
const XprType &m_xpr;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
@ -417,7 +411,6 @@ EIGEN_STRONG_INLINE typename internal::result_of<Func(typename internal::traits<
|
|||||||
DenseBase<Derived>::redux(const Func& func) const
|
DenseBase<Derived>::redux(const Func& func) const
|
||||||
{
|
{
|
||||||
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
|
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
// FIXME, eval_nest should be handled by redux_evaluator, however:
|
// FIXME, eval_nest should be handled by redux_evaluator, however:
|
||||||
// - it is currently difficult to provide the right Flags since they are still handled by the expressions
|
// - it is currently difficult to provide the right Flags since they are still handled by the expressions
|
||||||
@ -433,13 +426,6 @@ DenseBase<Derived>::redux(const Func& func) const
|
|||||||
ThisEvaluator thisEval(derived());
|
ThisEvaluator thisEval(derived());
|
||||||
|
|
||||||
return internal::redux_impl<Func, ThisEvaluator>::run(thisEval, func);
|
return internal::redux_impl<Func, ThisEvaluator>::run(thisEval, func);
|
||||||
|
|
||||||
#else
|
|
||||||
typedef typename internal::remove_all<typename Derived::Nested>::type ThisNested;
|
|
||||||
|
|
||||||
return internal::redux_impl<Func, ThisNested>
|
|
||||||
::run(derived(), func);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the minimum of all coefficients of \c *this.
|
/** \returns the minimum of all coefficients of \c *this.
|
||||||
|
@ -243,11 +243,7 @@ template<typename TPlainObjectType, int Options, typename StrideType> class Ref<
|
|||||||
template<typename Expression>
|
template<typename Expression>
|
||||||
void construct(const Expression& expr, internal::false_type)
|
void construct(const Expression& expr, internal::false_type)
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
internal::call_assignment_no_alias(m_object,expr,internal::assign_op<Scalar>());
|
internal::call_assignment_no_alias(m_object,expr,internal::assign_op<Scalar>());
|
||||||
#else
|
|
||||||
m_object.lazyAssign(expr);
|
|
||||||
#endif
|
|
||||||
Base::construct(m_object);
|
Base::construct(m_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,13 +54,8 @@ struct traits<Replicate<MatrixType,RowFactor,ColFactor> >
|
|||||||
: MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1 ? 0
|
: MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1 ? 0
|
||||||
: (MatrixType::Flags & RowMajorBit) ? 1 : 0,
|
: (MatrixType::Flags & RowMajorBit) ? 1 : 0,
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
Flags = (_MatrixTypeNested::Flags & HereditaryBits & ~RowMajorBit) | (IsRowMajor ? RowMajorBit : 0),
|
|
||||||
CoeffReadCost = _MatrixTypeNested::CoeffReadCost
|
|
||||||
#else
|
|
||||||
// FIXME enable DirectAccess with negative strides?
|
// FIXME enable DirectAccess with negative strides?
|
||||||
Flags = IsRowMajor ? RowMajorBit : 0
|
Flags = IsRowMajor ? RowMajorBit : 0
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -33,25 +33,18 @@ struct traits<ReturnByValue<Derived> >
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/* The ReturnByValue object doesn't even have a coeff() method.
|
/* The ReturnByValue object doesn't even have a coeff() method.
|
||||||
* So the only way that nesting it in an expression can work, is by evaluating it into a plain matrix.
|
* So the only way that nesting it in an expression can work, is by evaluating it into a plain matrix.
|
||||||
* So internal::nested always gives the plain return matrix type.
|
* So internal::nested always gives the plain return matrix type.
|
||||||
*
|
*
|
||||||
* FIXME: I don't understand why we need this specialization: isn't this taken care of by the EvalBeforeNestingBit ??
|
* FIXME: I don't understand why we need this specialization: isn't this taken care of by the EvalBeforeNestingBit ??
|
||||||
|
* Answer: EvalBeforeNestingBit should be deprecated since we have the evaluators
|
||||||
*/
|
*/
|
||||||
template<typename Derived,int n,typename PlainObject>
|
template<typename Derived,int n,typename PlainObject>
|
||||||
struct nested<ReturnByValue<Derived>, n, PlainObject>
|
|
||||||
{
|
|
||||||
typedef typename traits<Derived>::ReturnType type;
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
template<typename Derived,int n,typename PlainObject>
|
|
||||||
struct nested_eval<ReturnByValue<Derived>, n, PlainObject>
|
struct nested_eval<ReturnByValue<Derived>, n, PlainObject>
|
||||||
{
|
{
|
||||||
typedef typename traits<Derived>::ReturnType type;
|
typedef typename traits<Derived>::ReturnType type;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
@ -93,7 +86,6 @@ Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
|
|||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Expression is evaluated in a temporary; default implementation of Assignment is bypassed so that
|
// Expression is evaluated in a temporary; default implementation of Assignment is bypassed so that
|
||||||
@ -123,7 +115,6 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
@ -44,17 +44,7 @@ struct traits<Reverse<MatrixType, Direction> >
|
|||||||
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
|
||||||
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
||||||
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
// let's enable LinearAccess only with vectorization because of the product overhead
|
|
||||||
LinearAccess = ( (Direction==BothDirections) && (int(_MatrixTypeNested::Flags)&PacketAccessBit) )
|
|
||||||
? LinearAccessBit : 0,
|
|
||||||
|
|
||||||
Flags = int(_MatrixTypeNested::Flags) & (HereditaryBits | LvalueBit | PacketAccessBit | LinearAccess),
|
|
||||||
CoeffReadCost = _MatrixTypeNested::CoeffReadCost
|
|
||||||
#else
|
|
||||||
Flags = _MatrixTypeNested::Flags & (RowMajorBit | LvalueBit)
|
Flags = _MatrixTypeNested::Flags & (RowMajorBit | LvalueBit)
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,14 +43,7 @@ struct traits<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
|
|||||||
ColsAtCompileTime = ConditionMatrixType::ColsAtCompileTime,
|
ColsAtCompileTime = ConditionMatrixType::ColsAtCompileTime,
|
||||||
MaxRowsAtCompileTime = ConditionMatrixType::MaxRowsAtCompileTime,
|
MaxRowsAtCompileTime = ConditionMatrixType::MaxRowsAtCompileTime,
|
||||||
MaxColsAtCompileTime = ConditionMatrixType::MaxColsAtCompileTime,
|
MaxColsAtCompileTime = ConditionMatrixType::MaxColsAtCompileTime,
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & HereditaryBits,
|
|
||||||
CoeffReadCost = traits<typename remove_all<ConditionMatrixNested>::type>::CoeffReadCost
|
|
||||||
+ EIGEN_SIZE_MAX(traits<typename remove_all<ThenMatrixNested>::type>::CoeffReadCost,
|
|
||||||
traits<typename remove_all<ElseMatrixNested>::type>::CoeffReadCost)
|
|
||||||
#else
|
|
||||||
Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & RowMajorBit
|
Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & RowMajorBit
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -40,20 +40,10 @@ struct traits<SelfAdjointView<MatrixType, UpLo> > : traits<MatrixType>
|
|||||||
Mode = UpLo | SelfAdjoint,
|
Mode = UpLo | SelfAdjoint,
|
||||||
Flags = MatrixTypeNestedCleaned::Flags & (HereditaryBits)
|
Flags = MatrixTypeNestedCleaned::Flags & (HereditaryBits)
|
||||||
& (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)) // FIXME these flags should be preserved
|
& (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)) // FIXME these flags should be preserved
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
,
|
|
||||||
CoeffReadCost = MatrixTypeNestedCleaned::CoeffReadCost
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template <typename Lhs, int LhsMode, bool LhsIsVector,
|
|
||||||
typename Rhs, int RhsMode, bool RhsIsVector>
|
|
||||||
struct SelfadjointProductMatrix;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// FIXME could also be called SelfAdjointWrapper to be consistent with DiagonalWrapper ??
|
// FIXME could also be called SelfAdjointWrapper to be consistent with DiagonalWrapper ??
|
||||||
template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||||
: public TriangularBase<SelfAdjointView<_MatrixType, UpLo> >
|
: public TriangularBase<SelfAdjointView<_MatrixType, UpLo> >
|
||||||
@ -118,8 +108,6 @@ template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
MatrixTypeNestedCleaned& nestedExpression() { return *const_cast<MatrixTypeNestedCleaned*>(&m_matrix); }
|
MatrixTypeNestedCleaned& nestedExpression() { return *const_cast<MatrixTypeNestedCleaned*>(&m_matrix); }
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** Efficient triangular matrix times vector/matrix product */
|
/** Efficient triangular matrix times vector/matrix product */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@ -145,31 +133,6 @@ template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
|||||||
return (s*mat.nestedExpression()).template selfadjointView<UpLo>();
|
return (s*mat.nestedExpression()).template selfadjointView<UpLo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** Efficient self-adjoint matrix times vector/matrix product */
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
SelfadjointProductMatrix<MatrixType,Mode,false,OtherDerived,0,OtherDerived::IsVectorAtCompileTime>
|
|
||||||
operator*(const MatrixBase<OtherDerived>& rhs) const
|
|
||||||
{
|
|
||||||
return SelfadjointProductMatrix
|
|
||||||
<MatrixType,Mode,false,OtherDerived,0,OtherDerived::IsVectorAtCompileTime>
|
|
||||||
(m_matrix, rhs.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Efficient vector/matrix times self-adjoint matrix product */
|
|
||||||
template<typename OtherDerived> friend
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
SelfadjointProductMatrix<OtherDerived,0,OtherDerived::IsVectorAtCompileTime,MatrixType,Mode,false>
|
|
||||||
operator*(const MatrixBase<OtherDerived>& lhs, const SelfAdjointView& rhs)
|
|
||||||
{
|
|
||||||
return SelfadjointProductMatrix
|
|
||||||
<OtherDerived,0,OtherDerived::IsVectorAtCompileTime,MatrixType,Mode,false>
|
|
||||||
(lhs.derived(),rhs.m_matrix);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Perform a symmetric rank 2 update of the selfadjoint matrix \c *this:
|
/** Perform a symmetric rank 2 update of the selfadjoint matrix \c *this:
|
||||||
* \f$ this = this + \alpha u v^* + conj(\alpha) v u^* \f$
|
* \f$ this = this + \alpha u v^* + conj(\alpha) v u^* \f$
|
||||||
* \returns a reference to \c *this
|
* \returns a reference to \c *this
|
||||||
@ -231,104 +194,6 @@ template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int UnrollCount, bool ClearOpposite>
|
|
||||||
struct triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Upper), UnrollCount, ClearOpposite>
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
col = (UnrollCount-1) / Derived1::RowsAtCompileTime,
|
|
||||||
row = (UnrollCount-1) % Derived1::RowsAtCompileTime
|
|
||||||
};
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Upper), UnrollCount-1, ClearOpposite>::run(dst, src);
|
|
||||||
|
|
||||||
if(row == col)
|
|
||||||
dst.coeffRef(row, col) = numext::real(src.coeff(row, col));
|
|
||||||
else if(row < col)
|
|
||||||
dst.coeffRef(col, row) = numext::conj(dst.coeffRef(row, col) = src.coeff(row, col));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
|
||||||
struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Upper, 0, ClearOpposite>
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &, const Derived2 &) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, int UnrollCount, bool ClearOpposite>
|
|
||||||
struct triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Lower), UnrollCount, ClearOpposite>
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
col = (UnrollCount-1) / Derived1::RowsAtCompileTime,
|
|
||||||
row = (UnrollCount-1) % Derived1::RowsAtCompileTime
|
|
||||||
};
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
triangular_assignment_selector<Derived1, Derived2, (SelfAdjoint|Lower), UnrollCount-1, ClearOpposite>::run(dst, src);
|
|
||||||
|
|
||||||
if(row == col)
|
|
||||||
dst.coeffRef(row, col) = numext::real(src.coeff(row, col));
|
|
||||||
else if(row > col)
|
|
||||||
dst.coeffRef(col, row) = numext::conj(dst.coeffRef(row, col) = src.coeff(row, col));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
|
||||||
struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Lower, 0, ClearOpposite>
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &, const Derived2 &) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
|
||||||
struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Upper, Dynamic, ClearOpposite>
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
for(Index j = 0; j < dst.cols(); ++j)
|
|
||||||
{
|
|
||||||
for(Index i = 0; i < j; ++i)
|
|
||||||
{
|
|
||||||
dst.copyCoeff(i, j, src);
|
|
||||||
dst.coeffRef(j,i) = numext::conj(dst.coeff(i,j));
|
|
||||||
}
|
|
||||||
dst.copyCoeff(j, j, src);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
|
||||||
struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Lower, Dynamic, ClearOpposite>
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
for(Index i = 0; i < dst.rows(); ++i)
|
|
||||||
{
|
|
||||||
for(Index j = 0; j < i; ++j)
|
|
||||||
{
|
|
||||||
dst.copyCoeff(i, j, src);
|
|
||||||
dst.coeffRef(j,i) = numext::conj(dst.coeff(i,j));
|
|
||||||
}
|
|
||||||
dst.copyCoeff(i, i, src);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
|
|
||||||
// TODO currently a selfadjoint expression has the form SelfAdjointView<.,.>
|
// TODO currently a selfadjoint expression has the form SelfAdjointView<.,.>
|
||||||
// in the future selfadjoint-ness should be defined by the expression traits
|
// in the future selfadjoint-ness should be defined by the expression traits
|
||||||
// such that Transpose<SelfAdjointView<.,.> > is valid. (currently TriangularBase::transpose() is overloaded to make it work)
|
// such that Transpose<SelfAdjointView<.,.> > is valid. (currently TriangularBase::transpose() is overloaded to make it work)
|
||||||
@ -382,8 +247,6 @@ public:
|
|||||||
{ eigen_internal_assert(false && "should never be called"); }
|
{ eigen_internal_assert(false && "should never be called"); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EIGEN_ENABLE_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
@ -12,178 +12,6 @@
|
|||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** \class SelfCwiseBinaryOp
|
|
||||||
* \ingroup Core_Module
|
|
||||||
*
|
|
||||||
* \internal
|
|
||||||
*
|
|
||||||
* \brief Internal helper class for optimizing operators like +=, -=
|
|
||||||
*
|
|
||||||
* This is a pseudo expression class re-implementing the copyCoeff/copyPacket
|
|
||||||
* method to directly performs a +=/-= operations in an optimal way. In particular,
|
|
||||||
* this allows to make sure that the input/output data are loaded only once using
|
|
||||||
* aligned packet loads.
|
|
||||||
*
|
|
||||||
* \sa class SwapWrapper for a similar trick.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
template<typename BinaryOp, typename Lhs, typename Rhs>
|
|
||||||
struct traits<SelfCwiseBinaryOp<BinaryOp,Lhs,Rhs> >
|
|
||||||
: traits<CwiseBinaryOp<BinaryOp,Lhs,Rhs> >
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
// Note that it is still a good idea to preserve the DirectAccessBit
|
|
||||||
// so that assign can correctly align the data.
|
|
||||||
Flags = traits<CwiseBinaryOp<BinaryOp,Lhs,Rhs> >::Flags | (Lhs::Flags&AlignedBit) | (Lhs::Flags&DirectAccessBit) | (Lhs::Flags&LvalueBit),
|
|
||||||
OuterStrideAtCompileTime = Lhs::OuterStrideAtCompileTime,
|
|
||||||
InnerStrideAtCompileTime = Lhs::InnerStrideAtCompileTime
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename BinaryOp, typename Lhs, typename Rhs> class SelfCwiseBinaryOp
|
|
||||||
: public internal::dense_xpr_base< SelfCwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef typename internal::dense_xpr_base<SelfCwiseBinaryOp>::type Base;
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(SelfCwiseBinaryOp)
|
|
||||||
|
|
||||||
typedef typename internal::packet_traits<Scalar>::type Packet;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline SelfCwiseBinaryOp(Lhs& xpr, const BinaryOp& func = BinaryOp()) : m_matrix(xpr), m_functor(func) {}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.rows(); }
|
|
||||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_matrix.cols(); }
|
|
||||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return m_matrix.outerStride(); }
|
|
||||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return m_matrix.innerStride(); }
|
|
||||||
EIGEN_DEVICE_FUNC inline const Scalar* data() const { return m_matrix.data(); }
|
|
||||||
|
|
||||||
// note that this function is needed by assign to correctly align loads/stores
|
|
||||||
// TODO make Assign use .data()
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline Scalar& coeffRef(Index row, Index col)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(Lhs)
|
|
||||||
return m_matrix.const_cast_derived().coeffRef(row, col);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline const Scalar& coeffRef(Index row, Index col) const
|
|
||||||
{
|
|
||||||
return m_matrix.coeffRef(row, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
// note that this function is needed by assign to correctly align loads/stores
|
|
||||||
// TODO make Assign use .data()
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline Scalar& coeffRef(Index index)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(Lhs)
|
|
||||||
return m_matrix.const_cast_derived().coeffRef(index);
|
|
||||||
}
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline const Scalar& coeffRef(Index index) const
|
|
||||||
{
|
|
||||||
return m_matrix.const_cast_derived().coeffRef(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
OtherDerived& _other = other.const_cast_derived();
|
|
||||||
eigen_internal_assert(row >= 0 && row < rows()
|
|
||||||
&& col >= 0 && col < cols());
|
|
||||||
Scalar& tmp = m_matrix.coeffRef(row,col);
|
|
||||||
tmp = m_functor(tmp, _other.coeff(row,col));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void copyCoeff(Index index, const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
OtherDerived& _other = other.const_cast_derived();
|
|
||||||
eigen_internal_assert(index >= 0 && index < m_matrix.size());
|
|
||||||
Scalar& tmp = m_matrix.coeffRef(index);
|
|
||||||
tmp = m_functor(tmp, _other.coeff(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OtherDerived, int StoreMode, int LoadMode>
|
|
||||||
void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
OtherDerived& _other = other.const_cast_derived();
|
|
||||||
eigen_internal_assert(row >= 0 && row < rows()
|
|
||||||
&& col >= 0 && col < cols());
|
|
||||||
m_matrix.template writePacket<StoreMode>(row, col,
|
|
||||||
m_functor.packetOp(m_matrix.template packet<StoreMode>(row, col),_other.template packet<LoadMode>(row, col)) );
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OtherDerived, int StoreMode, int LoadMode>
|
|
||||||
void copyPacket(Index index, const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
OtherDerived& _other = other.const_cast_derived();
|
|
||||||
eigen_internal_assert(index >= 0 && index < m_matrix.size());
|
|
||||||
m_matrix.template writePacket<StoreMode>(index,
|
|
||||||
m_functor.packetOp(m_matrix.template packet<StoreMode>(index),_other.template packet<LoadMode>(index)) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// reimplement lazyAssign to handle complex *= real
|
|
||||||
// see CwiseBinaryOp ctor for details
|
|
||||||
template<typename RhsDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE SelfCwiseBinaryOp& lazyAssign(const DenseBase<RhsDerived>& rhs)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs,RhsDerived)
|
|
||||||
EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename RhsDerived::Scalar);
|
|
||||||
|
|
||||||
#ifdef EIGEN_DEBUG_ASSIGN
|
|
||||||
internal::assign_traits<SelfCwiseBinaryOp, RhsDerived>::debug();
|
|
||||||
#endif
|
|
||||||
eigen_assert(rows() == rhs.rows() && cols() == rhs.cols());
|
|
||||||
internal::assign_impl<SelfCwiseBinaryOp, RhsDerived>::run(*this,rhs.derived());
|
|
||||||
#ifndef EIGEN_NO_DEBUG
|
|
||||||
this->checkTransposeAliasing(rhs.derived());
|
|
||||||
#endif
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// overloaded to honor evaluation of special matrices
|
|
||||||
// maybe another solution would be to not use SelfCwiseBinaryOp
|
|
||||||
// at first...
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
SelfCwiseBinaryOp& operator=(const Rhs& _rhs)
|
|
||||||
{
|
|
||||||
typename internal::nested<Rhs>::type rhs(_rhs);
|
|
||||||
return Base::operator=(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
Lhs& expression() const
|
|
||||||
{
|
|
||||||
return m_matrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const BinaryOp& functor() const
|
|
||||||
{
|
|
||||||
return m_functor;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Lhs& m_matrix;
|
|
||||||
const BinaryOp& m_functor;
|
|
||||||
|
|
||||||
private:
|
|
||||||
SelfCwiseBinaryOp& operator=(const SelfCwiseBinaryOp&);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline Derived& DenseBase<Derived>::operator*=(const Scalar& other)
|
inline Derived& DenseBase<Derived>::operator*=(const Scalar& other)
|
||||||
{
|
{
|
||||||
@ -215,43 +43,6 @@ inline Derived& DenseBase<Derived>::operator/=(const Scalar& other)
|
|||||||
internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::div_assign_op<Scalar>());
|
internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::div_assign_op<Scalar>());
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
template<typename Derived>
|
|
||||||
inline Derived& DenseBase<Derived>::operator*=(const Scalar& other)
|
|
||||||
{
|
|
||||||
typedef typename Derived::PlainObject PlainObject;
|
|
||||||
SelfCwiseBinaryOp<internal::scalar_product_op<Scalar>, Derived, typename PlainObject::ConstantReturnType> tmp(derived());
|
|
||||||
tmp = PlainObject::Constant(rows(),cols(),other);
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
inline Derived& ArrayBase<Derived>::operator+=(const Scalar& other)
|
|
||||||
{
|
|
||||||
typedef typename Derived::PlainObject PlainObject;
|
|
||||||
SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, typename PlainObject::ConstantReturnType> tmp(derived());
|
|
||||||
tmp = PlainObject::Constant(rows(),cols(),other);
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
inline Derived& ArrayBase<Derived>::operator-=(const Scalar& other)
|
|
||||||
{
|
|
||||||
typedef typename Derived::PlainObject PlainObject;
|
|
||||||
SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, Derived, typename PlainObject::ConstantReturnType> tmp(derived());
|
|
||||||
tmp = PlainObject::Constant(rows(),cols(),other);
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
inline Derived& DenseBase<Derived>::operator/=(const Scalar& other)
|
|
||||||
{
|
|
||||||
typedef typename Derived::PlainObject PlainObject;
|
|
||||||
SelfCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, Derived, typename PlainObject::ConstantReturnType> tmp(derived());
|
|
||||||
tmp = PlainObject::Constant(rows(),cols(), other);
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
@ -99,7 +99,6 @@ private:
|
|||||||
Scalar coeff(Index i) const;
|
Scalar coeff(Index i) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
// Generic API dispatcher
|
// Generic API dispatcher
|
||||||
template<typename Decomposition, typename RhsType, typename StorageKind>
|
template<typename Decomposition, typename RhsType, typename StorageKind>
|
||||||
class SolveImpl : public internal::generic_xpr_base<Solve<Decomposition,RhsType>, MatrixXpr, StorageKind>::type
|
class SolveImpl : public internal::generic_xpr_base<Solve<Decomposition,RhsType>, MatrixXpr, StorageKind>::type
|
||||||
@ -107,7 +106,6 @@ class SolveImpl : public internal::generic_xpr_base<Solve<Decomposition,RhsType>
|
|||||||
public:
|
public:
|
||||||
typedef typename internal::generic_xpr_base<Solve<Decomposition,RhsType>, MatrixXpr, StorageKind>::type Base;
|
typedef typename internal::generic_xpr_base<Solve<Decomposition,RhsType>, MatrixXpr, StorageKind>::type Base;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
@ -12,135 +12,6 @@
|
|||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** \class SwapWrapper
|
|
||||||
* \ingroup Core_Module
|
|
||||||
*
|
|
||||||
* \internal
|
|
||||||
*
|
|
||||||
* \brief Internal helper class for swapping two expressions
|
|
||||||
*/
|
|
||||||
namespace internal {
|
|
||||||
template<typename ExpressionType>
|
|
||||||
struct traits<SwapWrapper<ExpressionType> > : traits<ExpressionType> {};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ExpressionType> class SwapWrapper
|
|
||||||
: public internal::dense_xpr_base<SwapWrapper<ExpressionType> >::type
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef typename internal::dense_xpr_base<SwapWrapper>::type Base;
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(SwapWrapper)
|
|
||||||
typedef typename internal::packet_traits<Scalar>::type Packet;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline SwapWrapper(ExpressionType& xpr) : m_expression(xpr) {}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline Index rows() const { return m_expression.rows(); }
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline Index cols() const { return m_expression.cols(); }
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline Index outerStride() const { return m_expression.outerStride(); }
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline Index innerStride() const { return m_expression.innerStride(); }
|
|
||||||
|
|
||||||
typedef typename internal::conditional<
|
|
||||||
internal::is_lvalue<ExpressionType>::value,
|
|
||||||
Scalar,
|
|
||||||
const Scalar
|
|
||||||
>::type ScalarWithConstIfNotLvalue;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline const Scalar* data() const { return m_expression.data(); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline Scalar& coeffRef(Index rowId, Index colId)
|
|
||||||
{
|
|
||||||
return m_expression.const_cast_derived().coeffRef(rowId, colId);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline Scalar& coeffRef(Index index)
|
|
||||||
{
|
|
||||||
return m_expression.const_cast_derived().coeffRef(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline Scalar& coeffRef(Index rowId, Index colId) const
|
|
||||||
{
|
|
||||||
return m_expression.coeffRef(rowId, colId);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline Scalar& coeffRef(Index index) const
|
|
||||||
{
|
|
||||||
return m_expression.coeffRef(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void copyCoeff(Index rowId, Index colId, const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
OtherDerived& _other = other.const_cast_derived();
|
|
||||||
eigen_internal_assert(rowId >= 0 && rowId < rows()
|
|
||||||
&& colId >= 0 && colId < cols());
|
|
||||||
Scalar tmp = m_expression.coeff(rowId, colId);
|
|
||||||
m_expression.coeffRef(rowId, colId) = _other.coeff(rowId, colId);
|
|
||||||
_other.coeffRef(rowId, colId) = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void copyCoeff(Index index, const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
OtherDerived& _other = other.const_cast_derived();
|
|
||||||
eigen_internal_assert(index >= 0 && index < m_expression.size());
|
|
||||||
Scalar tmp = m_expression.coeff(index);
|
|
||||||
m_expression.coeffRef(index) = _other.coeff(index);
|
|
||||||
_other.coeffRef(index) = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OtherDerived, int StoreMode, int LoadMode>
|
|
||||||
void copyPacket(Index rowId, Index colId, const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
OtherDerived& _other = other.const_cast_derived();
|
|
||||||
eigen_internal_assert(rowId >= 0 && rowId < rows()
|
|
||||||
&& colId >= 0 && colId < cols());
|
|
||||||
Packet tmp = m_expression.template packet<StoreMode>(rowId, colId);
|
|
||||||
m_expression.template writePacket<StoreMode>(rowId, colId,
|
|
||||||
_other.template packet<LoadMode>(rowId, colId)
|
|
||||||
);
|
|
||||||
_other.template writePacket<LoadMode>(rowId, colId, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename OtherDerived, int StoreMode, int LoadMode>
|
|
||||||
void copyPacket(Index index, const DenseBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
OtherDerived& _other = other.const_cast_derived();
|
|
||||||
eigen_internal_assert(index >= 0 && index < m_expression.size());
|
|
||||||
Packet tmp = m_expression.template packet<StoreMode>(index);
|
|
||||||
m_expression.template writePacket<StoreMode>(index,
|
|
||||||
_other.template packet<LoadMode>(index)
|
|
||||||
);
|
|
||||||
_other.template writePacket<LoadMode>(index, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
ExpressionType& expression() const { return m_expression; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ExpressionType& m_expression;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Overload default assignPacket behavior for swapping them
|
// Overload default assignPacket behavior for swapping them
|
||||||
@ -189,8 +60,6 @@ public:
|
|||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_SWAP_H
|
#endif // EIGEN_SWAP_H
|
||||||
|
@ -42,18 +42,10 @@ struct traits<Transpose<MatrixType> >
|
|||||||
ColsAtCompileTime = MatrixType::RowsAtCompileTime,
|
ColsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||||
MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
||||||
MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
|
FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
|
||||||
Flags0 = MatrixTypeNestedPlain::Flags & ~(LvalueBit | NestByRefBit),
|
Flags0 = MatrixTypeNestedPlain::Flags & ~(LvalueBit | NestByRefBit),
|
||||||
Flags1 = Flags0 | FlagsLvalueBit,
|
Flags1 = Flags0 | FlagsLvalueBit,
|
||||||
Flags = Flags1 ^ RowMajorBit,
|
Flags = Flags1 ^ RowMajorBit,
|
||||||
CoeffReadCost = MatrixTypeNestedPlain::CoeffReadCost,
|
|
||||||
#else
|
|
||||||
FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
|
|
||||||
Flags0 = MatrixTypeNestedPlain::Flags & ~(LvalueBit | NestByRefBit),
|
|
||||||
Flags1 = Flags0 | FlagsLvalueBit,
|
|
||||||
Flags = Flags1 ^ RowMajorBit,
|
|
||||||
#endif
|
|
||||||
InnerStrideAtCompileTime = inner_stride_at_compile_time<MatrixType>::ret,
|
InnerStrideAtCompileTime = inner_stride_at_compile_time<MatrixType>::ret,
|
||||||
OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret
|
OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret
|
||||||
};
|
};
|
||||||
@ -109,7 +101,6 @@ struct TransposeImpl_base<MatrixType, false>
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
// Generic API dispatcher
|
// Generic API dispatcher
|
||||||
template<typename XprType, typename StorageKind>
|
template<typename XprType, typename StorageKind>
|
||||||
class TransposeImpl
|
class TransposeImpl
|
||||||
@ -118,7 +109,6 @@ class TransposeImpl
|
|||||||
public:
|
public:
|
||||||
typedef typename internal::generic_xpr_base<Transpose<XprType> >::type Base;
|
typedef typename internal::generic_xpr_base<Transpose<XprType> >::type Base;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
||||||
: public internal::TransposeImpl_base<MatrixType>::type
|
: public internal::TransposeImpl_base<MatrixType>::type
|
||||||
@ -141,59 +131,6 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
|||||||
|
|
||||||
inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
|
inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
|
||||||
inline const Scalar* data() const { return derived().nestedExpression().data(); }
|
inline const Scalar* data() const { return derived().nestedExpression().data(); }
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline ScalarWithConstIfNotLvalue& coeffRef(Index rowId, Index colId)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
|
|
||||||
return derived().nestedExpression().const_cast_derived().coeffRef(colId, rowId);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline ScalarWithConstIfNotLvalue& coeffRef(Index index)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
|
|
||||||
return derived().nestedExpression().const_cast_derived().coeffRef(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline CoeffReturnType coeff(Index rowId, Index colId) const
|
|
||||||
{
|
|
||||||
return derived().nestedExpression().coeff(colId, rowId);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline CoeffReturnType coeff(Index index) const
|
|
||||||
{
|
|
||||||
return derived().nestedExpression().coeff(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
inline const PacketScalar packet(Index rowId, Index colId) const
|
|
||||||
{
|
|
||||||
return derived().nestedExpression().template packet<LoadMode>(colId, rowId);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
inline void writePacket(Index rowId, Index colId, const PacketScalar& x)
|
|
||||||
{
|
|
||||||
derived().nestedExpression().const_cast_derived().template writePacket<LoadMode>(colId, rowId, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
inline const PacketScalar packet(Index index) const
|
|
||||||
{
|
|
||||||
return derived().nestedExpression().template packet<LoadMode>(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
inline void writePacket(Index index, const PacketScalar& x)
|
|
||||||
{
|
|
||||||
derived().nestedExpression().const_cast_derived().template writePacket<LoadMode>(index, x);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// FIXME: shall we keep the const version of coeffRef?
|
// FIXME: shall we keep the const version of coeffRef?
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@ -446,14 +383,6 @@ void check_for_aliasing(const Dst &dst, const Src &src)
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
void DenseBase<Derived>::checkTransposeAliasing(const OtherDerived& other) const
|
|
||||||
{
|
|
||||||
internal::checkTransposeAliasing_impl<Derived, OtherDerived>::run(derived(), other);
|
|
||||||
}
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
#endif // EIGEN_NO_DEBUG
|
#endif // EIGEN_NO_DEBUG
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
@ -32,9 +32,6 @@ template<typename Derived> class TriangularBase : public EigenBase<Derived>
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
Mode = internal::traits<Derived>::Mode,
|
Mode = internal::traits<Derived>::Mode,
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
|
|
||||||
#endif
|
|
||||||
RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
|
RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
|
||||||
ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
|
ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
|
||||||
MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
|
MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
|
||||||
@ -177,21 +174,10 @@ struct traits<TriangularView<MatrixType, _Mode> > : traits<MatrixType>
|
|||||||
enum {
|
enum {
|
||||||
Mode = _Mode,
|
Mode = _Mode,
|
||||||
Flags = (MatrixTypeNestedCleaned::Flags & (HereditaryBits | LvalueBit) & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)))
|
Flags = (MatrixTypeNestedCleaned::Flags & (HereditaryBits | LvalueBit) & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)))
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
,
|
|
||||||
CoeffReadCost = MatrixTypeNestedCleaned::CoeffReadCost
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<int Mode, bool LhsIsTriangular,
|
|
||||||
typename Lhs, bool LhsIsVector,
|
|
||||||
typename Rhs, bool RhsIsVector>
|
|
||||||
struct TriangularProduct;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename _MatrixType, unsigned int _Mode, typename StorageKind> class TriangularViewImpl;
|
template<typename _MatrixType, unsigned int _Mode, typename StorageKind> class TriangularViewImpl;
|
||||||
|
|
||||||
template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
||||||
@ -270,7 +256,6 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
|||||||
return m_matrix.transpose();
|
return m_matrix.transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Other>
|
template<typename Other>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline const Solve<TriangularView, Other>
|
inline const Solve<TriangularView, Other>
|
||||||
@ -287,7 +272,6 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
|||||||
#else
|
#else
|
||||||
using Base::solve;
|
using Base::solve;
|
||||||
#endif
|
#endif
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
const SelfAdjointView<MatrixTypeNestedNonRef,Mode> selfadjointView() const
|
const SelfAdjointView<MatrixTypeNestedNonRef,Mode> selfadjointView() const
|
||||||
@ -348,8 +332,6 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
|
inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** \sa MatrixBase::operator+=() */
|
/** \sa MatrixBase::operator+=() */
|
||||||
template<typename Other>
|
template<typename Other>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@ -365,16 +347,6 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
|||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
/** \sa MatrixBase::operator+=() */
|
|
||||||
template<typename Other>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
TriangularViewType& operator+=(const DenseBase<Other>& other) { return *this = derived().nestedExpression() + other.derived(); }
|
|
||||||
/** \sa MatrixBase::operator-=() */
|
|
||||||
template<typename Other>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
TriangularViewType& operator-=(const DenseBase<Other>& other) { return *this = derived().nestedExpression() - other.derived(); }
|
|
||||||
#endif
|
|
||||||
/** \sa MatrixBase::operator*=() */
|
/** \sa MatrixBase::operator*=() */
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
TriangularViewType& operator*=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = derived().nestedExpression() * other; }
|
TriangularViewType& operator*=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = derived().nestedExpression() * other; }
|
||||||
@ -437,8 +409,6 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
void lazyAssign(const MatrixBase<OtherDerived>& other);
|
void lazyAssign(const MatrixBase<OtherDerived>& other);
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** Efficient triangular matrix times vector/matrix product */
|
/** Efficient triangular matrix times vector/matrix product */
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@ -456,30 +426,6 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
|||||||
{
|
{
|
||||||
return Product<OtherDerived,TriangularViewType>(lhs.derived(),rhs.derived());
|
return Product<OtherDerived,TriangularViewType>(lhs.derived(),rhs.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
/** Efficient triangular matrix times vector/matrix product */
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
TriangularProduct<Mode, true, MatrixType, false, OtherDerived, OtherDerived::ColsAtCompileTime==1>
|
|
||||||
operator*(const MatrixBase<OtherDerived>& rhs) const
|
|
||||||
{
|
|
||||||
return TriangularProduct
|
|
||||||
<Mode, true, MatrixType, false, OtherDerived, OtherDerived::ColsAtCompileTime==1>
|
|
||||||
(derived().nestedExpression(), rhs.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Efficient vector/matrix times triangular matrix product */
|
|
||||||
template<typename OtherDerived> friend
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
TriangularProduct<Mode, false, OtherDerived, OtherDerived::RowsAtCompileTime==1, MatrixType, false>
|
|
||||||
operator*(const MatrixBase<OtherDerived>& lhs, const TriangularViewImpl& rhs)
|
|
||||||
{
|
|
||||||
return TriangularProduct
|
|
||||||
<Mode, false, OtherDerived, OtherDerived::RowsAtCompileTime==1, MatrixType, false>
|
|
||||||
(lhs.derived(),rhs.derived().nestedExpression());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<int Side, typename Other>
|
template<int Side, typename Other>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@ -490,14 +436,6 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
void solveInPlace(const MatrixBase<OtherDerived>& other) const;
|
void solveInPlace(const MatrixBase<OtherDerived>& other) const;
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Other>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline const internal::triangular_solve_retval<OnTheLeft,TriangularViewType, Other>
|
|
||||||
solve(const MatrixBase<Other>& other) const
|
|
||||||
{ return solve<OnTheLeft>(other); }
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
void solveInPlace(const MatrixBase<OtherDerived>& other) const
|
void solveInPlace(const MatrixBase<OtherDerived>& other) const
|
||||||
@ -507,11 +445,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
void swap(TriangularBase<OtherDerived> const & other)
|
void swap(TriangularBase<OtherDerived> const & other)
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
|
call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
|
||||||
#else
|
|
||||||
TriangularView<SwapWrapper<MatrixType>,Mode>(const_cast<MatrixType&>(derived().nestedExpression())).lazyAssign(other.const_cast_derived().nestedExpression());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this overload is ambiguous and it should be deprecated (Gael)
|
// TODO: this overload is ambiguous and it should be deprecated (Gael)
|
||||||
@ -519,65 +453,8 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
|||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
void swap(MatrixBase<OtherDerived> const & other)
|
void swap(MatrixBase<OtherDerived> const & other)
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
|
call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
|
||||||
#else
|
|
||||||
SwapWrapper<MatrixType> swaper(const_cast<MatrixType&>(derived().nestedExpression()));
|
|
||||||
TriangularView<SwapWrapper<MatrixType>,Mode>(swaper).lazyAssign(other.derived());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
// TODO simplify the following:
|
|
||||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE TriangularViewType& operator=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
|
|
||||||
{
|
|
||||||
setZero();
|
|
||||||
return assignProduct(other,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE TriangularViewType& operator+=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
|
|
||||||
{
|
|
||||||
return assignProduct(other,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE TriangularViewType& operator-=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
|
|
||||||
{
|
|
||||||
return assignProduct(other,-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename ProductDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE TriangularViewType& operator=(const ScaledProduct<ProductDerived>& other)
|
|
||||||
{
|
|
||||||
setZero();
|
|
||||||
return assignProduct(other,other.alpha());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ProductDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE TriangularViewType& operator+=(const ScaledProduct<ProductDerived>& other)
|
|
||||||
{
|
|
||||||
return assignProduct(other,other.alpha());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ProductDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE TriangularViewType& operator-=(const ScaledProduct<ProductDerived>& other)
|
|
||||||
{
|
|
||||||
return assignProduct(other,-other.alpha());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
template<typename RhsType, typename DstType>
|
template<typename RhsType, typename DstType>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
@ -590,194 +467,12 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_Mat
|
|||||||
template<typename ProductType>
|
template<typename ProductType>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(const ProductType& prod, const Scalar& alpha);
|
EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(const ProductType& prod, const Scalar& alpha);
|
||||||
|
|
||||||
protected:
|
|
||||||
#else
|
|
||||||
protected:
|
|
||||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE TriangularViewType& assignProduct(const ProductBase<ProductDerived, Lhs,Rhs>& prod, const Scalar& alpha);
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Implementation of triangular evaluation/assignment
|
* Implementation of triangular evaluation/assignment
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, unsigned int Mode, int UnrollCount, bool ClearOpposite>
|
|
||||||
struct triangular_assignment_selector
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
col = (UnrollCount-1) / Derived1::RowsAtCompileTime,
|
|
||||||
row = (UnrollCount-1) % Derived1::RowsAtCompileTime
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef typename Derived1::Scalar Scalar;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
triangular_assignment_selector<Derived1, Derived2, Mode, UnrollCount-1, ClearOpposite>::run(dst, src);
|
|
||||||
|
|
||||||
eigen_assert( Mode == Upper || Mode == Lower
|
|
||||||
|| Mode == StrictlyUpper || Mode == StrictlyLower
|
|
||||||
|| Mode == UnitUpper || Mode == UnitLower);
|
|
||||||
if((Mode == Upper && row <= col)
|
|
||||||
|| (Mode == Lower && row >= col)
|
|
||||||
|| (Mode == StrictlyUpper && row < col)
|
|
||||||
|| (Mode == StrictlyLower && row > col)
|
|
||||||
|| (Mode == UnitUpper && row < col)
|
|
||||||
|| (Mode == UnitLower && row > col))
|
|
||||||
dst.copyCoeff(row, col, src);
|
|
||||||
else if(ClearOpposite)
|
|
||||||
{
|
|
||||||
if (Mode&UnitDiag && row==col)
|
|
||||||
dst.coeffRef(row, col) = Scalar(1);
|
|
||||||
else
|
|
||||||
dst.coeffRef(row, col) = Scalar(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// prevent buggy user code from causing an infinite recursion
|
|
||||||
template<typename Derived1, typename Derived2, unsigned int Mode, bool ClearOpposite>
|
|
||||||
struct triangular_assignment_selector<Derived1, Derived2, Mode, 0, ClearOpposite>
|
|
||||||
{
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &, const Derived2 &) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
|
||||||
struct triangular_assignment_selector<Derived1, Derived2, Upper, Dynamic, ClearOpposite>
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
typedef typename Derived1::Scalar Scalar;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
for(Index j = 0; j < dst.cols(); ++j)
|
|
||||||
{
|
|
||||||
Index maxi = (std::min)(j, dst.rows()-1);
|
|
||||||
for(Index i = 0; i <= maxi; ++i)
|
|
||||||
dst.copyCoeff(i, j, src);
|
|
||||||
if (ClearOpposite)
|
|
||||||
for(Index i = maxi+1; i < dst.rows(); ++i)
|
|
||||||
dst.coeffRef(i, j) = Scalar(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
|
||||||
struct triangular_assignment_selector<Derived1, Derived2, Lower, Dynamic, ClearOpposite>
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
for(Index j = 0; j < dst.cols(); ++j)
|
|
||||||
{
|
|
||||||
for(Index i = j; i < dst.rows(); ++i)
|
|
||||||
dst.copyCoeff(i, j, src);
|
|
||||||
Index maxi = (std::min)(j, dst.rows());
|
|
||||||
if (ClearOpposite)
|
|
||||||
for(Index i = 0; i < maxi; ++i)
|
|
||||||
dst.coeffRef(i, j) = static_cast<typename Derived1::Scalar>(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
|
||||||
struct triangular_assignment_selector<Derived1, Derived2, StrictlyUpper, Dynamic, ClearOpposite>
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
typedef typename Derived1::Scalar Scalar;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
for(Index j = 0; j < dst.cols(); ++j)
|
|
||||||
{
|
|
||||||
Index maxi = (std::min)(j, dst.rows());
|
|
||||||
for(Index i = 0; i < maxi; ++i)
|
|
||||||
dst.copyCoeff(i, j, src);
|
|
||||||
if (ClearOpposite)
|
|
||||||
for(Index i = maxi; i < dst.rows(); ++i)
|
|
||||||
dst.coeffRef(i, j) = Scalar(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
|
||||||
struct triangular_assignment_selector<Derived1, Derived2, StrictlyLower, Dynamic, ClearOpposite>
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
for(Index j = 0; j < dst.cols(); ++j)
|
|
||||||
{
|
|
||||||
for(Index i = j+1; i < dst.rows(); ++i)
|
|
||||||
dst.copyCoeff(i, j, src);
|
|
||||||
Index maxi = (std::min)(j, dst.rows()-1);
|
|
||||||
if (ClearOpposite)
|
|
||||||
for(Index i = 0; i <= maxi; ++i)
|
|
||||||
dst.coeffRef(i, j) = static_cast<typename Derived1::Scalar>(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
|
||||||
struct triangular_assignment_selector<Derived1, Derived2, UnitUpper, Dynamic, ClearOpposite>
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
for(Index j = 0; j < dst.cols(); ++j)
|
|
||||||
{
|
|
||||||
Index maxi = (std::min)(j, dst.rows());
|
|
||||||
for(Index i = 0; i < maxi; ++i)
|
|
||||||
dst.copyCoeff(i, j, src);
|
|
||||||
if (ClearOpposite)
|
|
||||||
{
|
|
||||||
for(Index i = maxi+1; i < dst.rows(); ++i)
|
|
||||||
dst.coeffRef(i, j) = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst.diagonal().setOnes();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
|
||||||
struct triangular_assignment_selector<Derived1, Derived2, UnitLower, Dynamic, ClearOpposite>
|
|
||||||
{
|
|
||||||
typedef typename Derived1::Index Index;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
|
||||||
{
|
|
||||||
for(Index j = 0; j < dst.cols(); ++j)
|
|
||||||
{
|
|
||||||
Index maxi = (std::min)(j, dst.rows());
|
|
||||||
for(Index i = maxi+1; i < dst.rows(); ++i)
|
|
||||||
dst.copyCoeff(i, j, src);
|
|
||||||
if (ClearOpposite)
|
|
||||||
{
|
|
||||||
for(Index i = 0; i < maxi; ++i)
|
|
||||||
dst.coeffRef(i, j) = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst.diagonal().setOnes();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
// FIXME should we keep that possibility
|
// FIXME should we keep that possibility
|
||||||
template<typename MatrixType, unsigned int Mode>
|
template<typename MatrixType, unsigned int Mode>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
@ -816,84 +511,6 @@ void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const TriangularBas
|
|||||||
internal::call_assignment(derived().noalias(), other.derived());
|
internal::call_assignment(derived().noalias(), other.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// FIXME should we keep that possibility
|
|
||||||
template<typename MatrixType, unsigned int Mode>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
inline TriangularView<MatrixType, Mode>&
|
|
||||||
TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const MatrixBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
if(OtherDerived::Flags & EvalBeforeAssigningBit)
|
|
||||||
{
|
|
||||||
typename internal::plain_matrix_type<OtherDerived>::type other_evaluated(other.rows(), other.cols());
|
|
||||||
other_evaluated.template triangularView<Mode>().lazyAssign(other.derived());
|
|
||||||
lazyAssign(other_evaluated);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
lazyAssign(other.derived());
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME should we keep that possibility
|
|
||||||
template<typename MatrixType, unsigned int Mode>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const MatrixBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
unroll = MatrixType::SizeAtCompileTime != Dynamic
|
|
||||||
&& internal::traits<OtherDerived>::CoeffReadCost != Dynamic
|
|
||||||
&& MatrixType::SizeAtCompileTime*internal::traits<OtherDerived>::CoeffReadCost/2 <= EIGEN_UNROLLING_LIMIT
|
|
||||||
};
|
|
||||||
eigen_assert(derived().rows() == other.rows() && derived().cols() == other.cols());
|
|
||||||
|
|
||||||
internal::triangular_assignment_selector
|
|
||||||
<MatrixType, OtherDerived, int(Mode),
|
|
||||||
unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic,
|
|
||||||
false // do not change the opposite triangular part
|
|
||||||
>::run(derived().nestedExpression().const_cast_derived(), other.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename MatrixType, unsigned int Mode>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
inline TriangularView<MatrixType, Mode>&
|
|
||||||
TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const TriangularBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
eigen_assert(Mode == int(OtherDerived::Mode));
|
|
||||||
if(internal::traits<OtherDerived>::Flags & EvalBeforeAssigningBit)
|
|
||||||
{
|
|
||||||
typename OtherDerived::DenseMatrixType other_evaluated(other.rows(), other.cols());
|
|
||||||
other_evaluated.template triangularView<Mode>().lazyAssign(other.derived().nestedExpression());
|
|
||||||
lazyAssign(other_evaluated);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
lazyAssign(other.derived().nestedExpression());
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename MatrixType, unsigned int Mode>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const TriangularBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
unroll = MatrixType::SizeAtCompileTime != Dynamic
|
|
||||||
&& internal::traits<OtherDerived>::CoeffReadCost != Dynamic
|
|
||||||
&& MatrixType::SizeAtCompileTime * internal::traits<OtherDerived>::CoeffReadCost / 2
|
|
||||||
<= EIGEN_UNROLLING_LIMIT
|
|
||||||
};
|
|
||||||
eigen_assert(derived().rows() == other.rows() && derived().cols() == other.cols());
|
|
||||||
|
|
||||||
internal::triangular_assignment_selector
|
|
||||||
<MatrixType, OtherDerived, int(Mode),
|
|
||||||
unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic,
|
|
||||||
false // preserve the opposite triangular part
|
|
||||||
>::run(derived().nestedExpression().const_cast_derived(), other.derived().nestedExpression());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Implementation of TriangularBase methods
|
* Implementation of TriangularBase methods
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@ -914,31 +531,6 @@ void TriangularBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
|
|||||||
evalToLazy(other.derived());
|
evalToLazy(other.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** Assigns a triangular or selfadjoint matrix to a dense matrix.
|
|
||||||
* If the matrix is triangular, the opposite part is set to zero. */
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename DenseDerived>
|
|
||||||
void TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDerived> &other) const
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
unroll = DenseDerived::SizeAtCompileTime != Dynamic
|
|
||||||
&& internal::traits<Derived>::CoeffReadCost != Dynamic
|
|
||||||
&& DenseDerived::SizeAtCompileTime * internal::traits<Derived>::CoeffReadCost / 2
|
|
||||||
<= EIGEN_UNROLLING_LIMIT
|
|
||||||
};
|
|
||||||
other.derived().resize(this->rows(), this->cols());
|
|
||||||
|
|
||||||
internal::triangular_assignment_selector
|
|
||||||
<DenseDerived, typename internal::traits<Derived>::MatrixTypeNestedCleaned, Derived::Mode,
|
|
||||||
unroll ? int(DenseDerived::SizeAtCompileTime) : Dynamic,
|
|
||||||
true // clear the opposite triangular part
|
|
||||||
>::run(other.derived(), derived().nestedExpression());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Implementation of TriangularView methods
|
* Implementation of TriangularView methods
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@ -1028,8 +620,6 @@ bool MatrixBase<Derived>::isLowerTriangular(const RealScalar& prec) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
****************************************************************************
|
****************************************************************************
|
||||||
* Evaluators and Assignment of triangular expressions
|
* Evaluators and Assignment of triangular expressions
|
||||||
@ -1268,7 +858,6 @@ struct triangular_assignment_loop<Kernel, Mode, Dynamic, SetOpposite>
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
/** Assigns a triangular or selfadjoint matrix to a dense matrix.
|
/** Assigns a triangular or selfadjoint matrix to a dense matrix.
|
||||||
* If the matrix is triangular, the opposite part is set to zero. */
|
* If the matrix is triangular, the opposite part is set to zero. */
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
@ -1315,11 +904,7 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_ass
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // EIGEN_ENABLE_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
@ -48,25 +48,9 @@ struct traits<PartialReduxExpr<MatrixType, MemberOp, Direction> >
|
|||||||
ColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::ColsAtCompileTime,
|
ColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::ColsAtCompileTime,
|
||||||
MaxRowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::MaxRowsAtCompileTime,
|
MaxRowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::MaxRowsAtCompileTime,
|
||||||
MaxColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::MaxColsAtCompileTime,
|
MaxColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::MaxColsAtCompileTime,
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
Flags0 = (unsigned int)_MatrixTypeNested::Flags & HereditaryBits,
|
|
||||||
Flags = (Flags0 & ~RowMajorBit) | (RowsAtCompileTime == 1 ? RowMajorBit : 0),
|
|
||||||
#else
|
|
||||||
Flags = RowsAtCompileTime == 1 ? RowMajorBit : 0,
|
Flags = RowsAtCompileTime == 1 ? RowMajorBit : 0,
|
||||||
#endif
|
|
||||||
TraversalSize = Direction==Vertical ? MatrixType::RowsAtCompileTime : MatrixType::ColsAtCompileTime
|
TraversalSize = Direction==Vertical ? MatrixType::RowsAtCompileTime : MatrixType::ColsAtCompileTime
|
||||||
};
|
};
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
#if EIGEN_GNUC_AT_LEAST(3,4)
|
|
||||||
typedef typename MemberOp::template Cost<InputScalar,int(TraversalSize)> CostOpType;
|
|
||||||
#else
|
|
||||||
typedef typename MemberOp::template Cost<InputScalar,TraversalSize> CostOpType;
|
|
||||||
#endif
|
|
||||||
enum {
|
|
||||||
CoeffReadCost = TraversalSize==Dynamic ? Dynamic
|
|
||||||
: TraversalSize * traits<_MatrixTypeNested>::CoeffReadCost + int(CostOpType::value)
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,6 @@ struct visitor_impl<Visitor, Derived, Dynamic>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
// evaluator adaptor
|
// evaluator adaptor
|
||||||
template<typename XprType>
|
template<typename XprType>
|
||||||
class visitor_evaluator
|
class visitor_evaluator
|
||||||
@ -81,7 +80,6 @@ protected:
|
|||||||
typename internal::evaluator<XprType>::nestedType m_evaluator;
|
typename internal::evaluator<XprType>::nestedType m_evaluator;
|
||||||
const XprType &m_xpr;
|
const XprType &m_xpr;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/** Applies the visitor \a visitor to the whole coefficients of the matrix or vector.
|
/** Applies the visitor \a visitor to the whole coefficients of the matrix or vector.
|
||||||
@ -105,7 +103,6 @@ template<typename Derived>
|
|||||||
template<typename Visitor>
|
template<typename Visitor>
|
||||||
void DenseBase<Derived>::visit(Visitor& visitor) const
|
void DenseBase<Derived>::visit(Visitor& visitor) const
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
typedef typename internal::visitor_evaluator<Derived> ThisEvaluator;
|
typedef typename internal::visitor_evaluator<Derived> ThisEvaluator;
|
||||||
ThisEvaluator thisEval(derived());
|
ThisEvaluator thisEval(derived());
|
||||||
|
|
||||||
@ -117,16 +114,6 @@ void DenseBase<Derived>::visit(Visitor& visitor) const
|
|||||||
return internal::visitor_impl<Visitor, ThisEvaluator,
|
return internal::visitor_impl<Visitor, ThisEvaluator,
|
||||||
unroll ? int(SizeAtCompileTime) : Dynamic
|
unroll ? int(SizeAtCompileTime) : Dynamic
|
||||||
>::run(thisEval, visitor);
|
>::run(thisEval, visitor);
|
||||||
#else
|
|
||||||
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,
|
|
||||||
unroll ? int(SizeAtCompileTime) : Dynamic
|
|
||||||
>::run(derived(), visitor);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -1,460 +0,0 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
|
||||||
// for linear algebra.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
|
||||||
// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
|
|
||||||
//
|
|
||||||
// This Source Code Form is subject to the terms of the Mozilla
|
|
||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
#ifndef EIGEN_COEFFBASED_PRODUCT_H
|
|
||||||
#define EIGEN_COEFFBASED_PRODUCT_H
|
|
||||||
|
|
||||||
namespace Eigen {
|
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
/*********************************************************************************
|
|
||||||
* Coefficient based product implementation.
|
|
||||||
* It is designed for the following use cases:
|
|
||||||
* - small fixed sizes
|
|
||||||
* - lazy products
|
|
||||||
*********************************************************************************/
|
|
||||||
|
|
||||||
/* Since the all the dimensions of the product are small, here we can rely
|
|
||||||
* on the generic Assign mechanism to evaluate the product per coeff (or packet).
|
|
||||||
*
|
|
||||||
* Note that here the inner-loops should always be unrolled.
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<int Traversal, int UnrollingIndex, typename Lhs, typename Rhs, typename RetScalar>
|
|
||||||
struct product_coeff_impl;
|
|
||||||
|
|
||||||
template<int StorageOrder, int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
|
||||||
struct product_packet_impl;
|
|
||||||
|
|
||||||
template<typename LhsNested, typename RhsNested, int NestingFlags>
|
|
||||||
struct traits<CoeffBasedProduct<LhsNested,RhsNested,NestingFlags> >
|
|
||||||
{
|
|
||||||
typedef MatrixXpr XprKind;
|
|
||||||
typedef typename remove_all<LhsNested>::type _LhsNested;
|
|
||||||
typedef typename remove_all<RhsNested>::type _RhsNested;
|
|
||||||
typedef typename scalar_product_traits<typename _LhsNested::Scalar, typename _RhsNested::Scalar>::ReturnType Scalar;
|
|
||||||
typedef typename product_promote_storage_type<typename traits<_LhsNested>::StorageKind,
|
|
||||||
typename traits<_RhsNested>::StorageKind,
|
|
||||||
0>::ret StorageKind;
|
|
||||||
typedef typename promote_index_type<typename traits<_LhsNested>::Index,
|
|
||||||
typename traits<_RhsNested>::Index>::type Index;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
LhsFlags = traits<_LhsNested>::Flags,
|
|
||||||
RhsFlags = traits<_RhsNested>::Flags,
|
|
||||||
|
|
||||||
RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
|
|
||||||
ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
|
|
||||||
InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime),
|
|
||||||
|
|
||||||
MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
|
|
||||||
MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,
|
|
||||||
|
|
||||||
LhsRowMajor = LhsFlags & RowMajorBit,
|
|
||||||
RhsRowMajor = RhsFlags & RowMajorBit,
|
|
||||||
|
|
||||||
SameType = is_same<typename _LhsNested::Scalar,typename _RhsNested::Scalar>::value,
|
|
||||||
|
|
||||||
CanVectorizeRhs = RhsRowMajor && (RhsFlags & PacketAccessBit)
|
|
||||||
&& (ColsAtCompileTime == Dynamic
|
|
||||||
|| ( (ColsAtCompileTime % packet_traits<Scalar>::size) == 0
|
|
||||||
&& (RhsFlags&AlignedBit)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
|
|
||||||
CanVectorizeLhs = (!LhsRowMajor) && (LhsFlags & PacketAccessBit)
|
|
||||||
&& (RowsAtCompileTime == Dynamic
|
|
||||||
|| ( (RowsAtCompileTime % packet_traits<Scalar>::size) == 0
|
|
||||||
&& (LhsFlags&AlignedBit)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
|
|
||||||
EvalToRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
|
|
||||||
: (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
|
|
||||||
: (RhsRowMajor && !CanVectorizeLhs),
|
|
||||||
|
|
||||||
Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & ~RowMajorBit)
|
|
||||||
| (EvalToRowMajor ? RowMajorBit : 0)
|
|
||||||
| NestingFlags
|
|
||||||
| (CanVectorizeLhs ? (LhsFlags & AlignedBit) : 0)
|
|
||||||
| (CanVectorizeRhs ? (RhsFlags & AlignedBit) : 0)
|
|
||||||
// TODO enable vectorization for mixed types
|
|
||||||
| (SameType && (CanVectorizeLhs || CanVectorizeRhs) ? PacketAccessBit : 0),
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
LhsCoeffReadCost = traits<_LhsNested>::CoeffReadCost,
|
|
||||||
RhsCoeffReadCost = traits<_RhsNested>::CoeffReadCost,
|
|
||||||
CoeffReadCost = (InnerSize == Dynamic || LhsCoeffReadCost==Dynamic || RhsCoeffReadCost==Dynamic || NumTraits<Scalar>::AddCost==Dynamic || NumTraits<Scalar>::MulCost==Dynamic) ? Dynamic
|
|
||||||
: InnerSize * (NumTraits<Scalar>::MulCost + LhsCoeffReadCost + RhsCoeffReadCost)
|
|
||||||
+ (InnerSize - 1) * NumTraits<Scalar>::AddCost,
|
|
||||||
#endif
|
|
||||||
/* CanVectorizeInner deserves special explanation. It does not affect the product flags. It is not used outside
|
|
||||||
* of Product. If the Product itself is not a packet-access expression, there is still a chance that the inner
|
|
||||||
* loop of the product might be vectorized. This is the meaning of CanVectorizeInner. Since it doesn't affect
|
|
||||||
* the Flags, it is safe to make this value depend on ActualPacketAccessBit, that doesn't affect the ABI.
|
|
||||||
*/
|
|
||||||
CanVectorizeInner = SameType
|
|
||||||
&& LhsRowMajor
|
|
||||||
&& (!RhsRowMajor)
|
|
||||||
&& (LhsFlags & RhsFlags & ActualPacketAccessBit)
|
|
||||||
&& (LhsFlags & RhsFlags & AlignedBit)
|
|
||||||
&& (InnerSize % packet_traits<Scalar>::size == 0)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
template<typename LhsNested, typename RhsNested, int NestingFlags>
|
|
||||||
class CoeffBasedProduct
|
|
||||||
: internal::no_assignment_operator,
|
|
||||||
public MatrixBase<CoeffBasedProduct<LhsNested, RhsNested, NestingFlags> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef MatrixBase<CoeffBasedProduct> Base;
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(CoeffBasedProduct)
|
|
||||||
typedef typename Base::PlainObject PlainObject;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
typedef typename internal::traits<CoeffBasedProduct>::_LhsNested _LhsNested;
|
|
||||||
typedef typename internal::traits<CoeffBasedProduct>::_RhsNested _RhsNested;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PacketSize = internal::packet_traits<Scalar>::size,
|
|
||||||
InnerSize = internal::traits<CoeffBasedProduct>::InnerSize,
|
|
||||||
Unroll = CoeffReadCost != Dynamic && CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
|
|
||||||
CanVectorizeInner = internal::traits<CoeffBasedProduct>::CanVectorizeInner
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef internal::product_coeff_impl<CanVectorizeInner ? InnerVectorizedTraversal : DefaultTraversal,
|
|
||||||
Unroll ? InnerSize-1 : Dynamic,
|
|
||||||
_LhsNested, _RhsNested, Scalar> ScalarCoeffImpl;
|
|
||||||
|
|
||||||
typedef CoeffBasedProduct<LhsNested,RhsNested,NestByRefBit> LazyCoeffBasedProductType;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline CoeffBasedProduct(const CoeffBasedProduct& other)
|
|
||||||
: Base(), m_lhs(other.m_lhs), m_rhs(other.m_rhs)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline CoeffBasedProduct(const Lhs& lhs, const Rhs& rhs)
|
|
||||||
: m_lhs(lhs), m_rhs(rhs)
|
|
||||||
{
|
|
||||||
// we don't allow taking products of matrices of different real types, as that wouldn't be vectorizable.
|
|
||||||
// We still allow to mix T and complex<T>.
|
|
||||||
EIGEN_STATIC_ASSERT((internal::scalar_product_traits<typename Lhs::RealScalar, typename Rhs::RealScalar>::Defined),
|
|
||||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
|
||||||
eigen_assert(lhs.cols() == rhs.rows()
|
|
||||||
&& "invalid matrix product"
|
|
||||||
&& "if you wanted a coeff-wise or a dot product use the respective explicit functions");
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); }
|
|
||||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
|
|
||||||
{
|
|
||||||
Scalar res;
|
|
||||||
ScalarCoeffImpl::run(row, col, m_lhs, m_rhs, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allow index-based non-packet access. It is impossible though to allow index-based packed access,
|
|
||||||
* which is why we don't set the LinearAccessBit.
|
|
||||||
*/
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
|
|
||||||
{
|
|
||||||
Scalar res;
|
|
||||||
const Index row = RowsAtCompileTime == 1 ? 0 : index;
|
|
||||||
const Index col = RowsAtCompileTime == 1 ? index : 0;
|
|
||||||
ScalarCoeffImpl::run(row, col, m_lhs, m_rhs, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int LoadMode>
|
|
||||||
EIGEN_STRONG_INLINE const PacketScalar packet(Index row, Index col) const
|
|
||||||
{
|
|
||||||
PacketScalar res;
|
|
||||||
internal::product_packet_impl<Flags&RowMajorBit ? RowMajor : ColMajor,
|
|
||||||
Unroll ? InnerSize-1 : Dynamic,
|
|
||||||
_LhsNested, _RhsNested, PacketScalar, LoadMode>
|
|
||||||
::run(row, col, m_lhs, m_rhs, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implicit conversion to the nested type (trigger the evaluation of the product)
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
EIGEN_STRONG_INLINE operator const PlainObject& () const
|
|
||||||
{
|
|
||||||
m_result.lazyAssign(*this);
|
|
||||||
return m_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC const _LhsNested& lhs() const { return m_lhs; }
|
|
||||||
EIGEN_DEVICE_FUNC const _RhsNested& rhs() const { return m_rhs; }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const Diagonal<const LazyCoeffBasedProductType,0> diagonal() const
|
|
||||||
{ return reinterpret_cast<const LazyCoeffBasedProductType&>(*this); }
|
|
||||||
|
|
||||||
template<int DiagonalIndex>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const Diagonal<const LazyCoeffBasedProductType,DiagonalIndex> diagonal() const
|
|
||||||
{ return reinterpret_cast<const LazyCoeffBasedProductType&>(*this); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
const Diagonal<const LazyCoeffBasedProductType,Dynamic> diagonal(Index index) const
|
|
||||||
{ return reinterpret_cast<const LazyCoeffBasedProductType&>(*this).diagonal(index); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
typename internal::add_const_on_value_type<LhsNested>::type m_lhs;
|
|
||||||
typename internal::add_const_on_value_type<RhsNested>::type m_rhs;
|
|
||||||
|
|
||||||
mutable PlainObject m_result;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// here we need to overload the nested rule for products
|
|
||||||
// such that the nested type is a const reference to a plain matrix
|
|
||||||
template<typename Lhs, typename Rhs, int N, typename PlainObject>
|
|
||||||
struct nested<CoeffBasedProduct<Lhs,Rhs,EvalBeforeNestingBit|EvalBeforeAssigningBit>, N, PlainObject>
|
|
||||||
{
|
|
||||||
typedef PlainObject const& type;
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* Normal product .coeff() implementation (with meta-unrolling)
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/**************************************
|
|
||||||
*** Scalar path - no vectorization ***
|
|
||||||
**************************************/
|
|
||||||
|
|
||||||
template<int UnrollingIndex, typename Lhs, typename Rhs, typename RetScalar>
|
|
||||||
struct product_coeff_impl<DefaultTraversal, UnrollingIndex, Lhs, Rhs, RetScalar>
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
|
|
||||||
{
|
|
||||||
product_coeff_impl<DefaultTraversal, UnrollingIndex-1, Lhs, Rhs, RetScalar>::run(row, col, lhs, rhs, res);
|
|
||||||
res += lhs.coeff(row, UnrollingIndex) * rhs.coeff(UnrollingIndex, col);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, typename RetScalar>
|
|
||||||
struct product_coeff_impl<DefaultTraversal, 0, Lhs, Rhs, RetScalar>
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
|
|
||||||
{
|
|
||||||
res = lhs.coeff(row, 0) * rhs.coeff(0, col);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, typename RetScalar>
|
|
||||||
struct product_coeff_impl<DefaultTraversal, Dynamic, Lhs, Rhs, RetScalar>
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar& res)
|
|
||||||
{
|
|
||||||
eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix");
|
|
||||||
res = lhs.coeff(row, 0) * rhs.coeff(0, col);
|
|
||||||
for(Index i = 1; i < lhs.cols(); ++i)
|
|
||||||
res += lhs.coeff(row, i) * rhs.coeff(i, col);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************
|
|
||||||
*** Scalar path with inner vectorization ***
|
|
||||||
*******************************************/
|
|
||||||
|
|
||||||
template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet>
|
|
||||||
struct product_coeff_vectorized_unroller
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
enum { PacketSize = packet_traits<typename Lhs::Scalar>::size };
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres)
|
|
||||||
{
|
|
||||||
product_coeff_vectorized_unroller<UnrollingIndex-PacketSize, Lhs, Rhs, Packet>::run(row, col, lhs, rhs, pres);
|
|
||||||
pres = padd(pres, pmul( lhs.template packet<Aligned>(row, UnrollingIndex) , rhs.template packet<Aligned>(UnrollingIndex, col) ));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, typename Packet>
|
|
||||||
struct product_coeff_vectorized_unroller<0, Lhs, Rhs, Packet>
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::PacketScalar &pres)
|
|
||||||
{
|
|
||||||
pres = pmul(lhs.template packet<Aligned>(row, 0) , rhs.template packet<Aligned>(0, col));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int UnrollingIndex, typename Lhs, typename Rhs, typename RetScalar>
|
|
||||||
struct product_coeff_impl<InnerVectorizedTraversal, UnrollingIndex, Lhs, Rhs, RetScalar>
|
|
||||||
{
|
|
||||||
typedef typename Lhs::PacketScalar Packet;
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
enum { PacketSize = packet_traits<typename Lhs::Scalar>::size };
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
|
|
||||||
{
|
|
||||||
Packet pres;
|
|
||||||
product_coeff_vectorized_unroller<UnrollingIndex+1-PacketSize, Lhs, Rhs, Packet>::run(row, col, lhs, rhs, pres);
|
|
||||||
res = predux(pres);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int LhsRows = Lhs::RowsAtCompileTime, int RhsCols = Rhs::ColsAtCompileTime>
|
|
||||||
struct product_coeff_vectorized_dyn_selector
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
|
|
||||||
{
|
|
||||||
res = lhs.row(row).transpose().cwiseProduct(rhs.col(col)).sum();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// NOTE the 3 following specializations are because taking .col(0) on a vector is a bit slower
|
|
||||||
// NOTE maybe they are now useless since we have a specialization for Block<Matrix>
|
|
||||||
template<typename Lhs, typename Rhs, int RhsCols>
|
|
||||||
struct product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,RhsCols>
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index /*row*/, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
|
|
||||||
{
|
|
||||||
res = lhs.transpose().cwiseProduct(rhs.col(col)).sum();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int LhsRows>
|
|
||||||
struct product_coeff_vectorized_dyn_selector<Lhs,Rhs,LhsRows,1>
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
|
|
||||||
{
|
|
||||||
res = lhs.row(row).transpose().cwiseProduct(rhs).sum();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
struct product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,1>
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
|
|
||||||
{
|
|
||||||
res = lhs.transpose().cwiseProduct(rhs).sum();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, typename RetScalar>
|
|
||||||
struct product_coeff_impl<InnerVectorizedTraversal, Dynamic, Lhs, Rhs, RetScalar>
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res)
|
|
||||||
{
|
|
||||||
product_coeff_vectorized_dyn_selector<Lhs,Rhs>::run(row, col, lhs, rhs, res);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************
|
|
||||||
*** Packet path ***
|
|
||||||
*******************/
|
|
||||||
|
|
||||||
template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
|
||||||
struct product_packet_impl<RowMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res)
|
|
||||||
{
|
|
||||||
product_packet_impl<RowMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, res);
|
|
||||||
res = pmadd(pset1<Packet>(lhs.coeff(row, UnrollingIndex)), rhs.template packet<LoadMode>(UnrollingIndex, col), res);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
|
||||||
struct product_packet_impl<ColMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res)
|
|
||||||
{
|
|
||||||
product_packet_impl<ColMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, res);
|
|
||||||
res = pmadd(lhs.template packet<LoadMode>(row, UnrollingIndex), pset1<Packet>(rhs.coeff(UnrollingIndex, col)), res);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
|
||||||
struct product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res)
|
|
||||||
{
|
|
||||||
res = pmul(pset1<Packet>(lhs.coeff(row, 0)),rhs.template packet<LoadMode>(0, col));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
|
||||||
struct product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res)
|
|
||||||
{
|
|
||||||
res = pmul(lhs.template packet<LoadMode>(row, 0), pset1<Packet>(rhs.coeff(0, col)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
|
||||||
struct product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res)
|
|
||||||
{
|
|
||||||
eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix");
|
|
||||||
res = pmul(pset1<Packet>(lhs.coeff(row, 0)),rhs.template packet<LoadMode>(0, col));
|
|
||||||
for(Index i = 1; i < lhs.cols(); ++i)
|
|
||||||
res = pmadd(pset1<Packet>(lhs.coeff(row, i)), rhs.template packet<LoadMode>(i, col), res);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
|
||||||
struct product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
|
||||||
{
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res)
|
|
||||||
{
|
|
||||||
eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix");
|
|
||||||
res = pmul(lhs.template packet<LoadMode>(row, 0), pset1<Packet>(rhs.coeff(0, col)));
|
|
||||||
for(Index i = 1; i < lhs.cols(); ++i)
|
|
||||||
res = pmadd(lhs.template packet<LoadMode>(row, i), pset1<Packet>(rhs.coeff(i, col)), res);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
#endif // <EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
|
||||||
|
|
||||||
#endif // EIGEN_COEFFBASED_PRODUCT_H
|
|
@ -367,87 +367,6 @@ class gemm_blocking_space<StorageOrder,_LhsScalar,_RhsScalar,MaxRows, MaxCols, M
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
class GeneralProduct<Lhs, Rhs, GemmProduct>
|
|
||||||
: public ProductBase<GeneralProduct<Lhs,Rhs,GemmProduct>, Lhs, Rhs>
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
MaxDepthAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(Lhs::MaxColsAtCompileTime,Rhs::MaxRowsAtCompileTime)
|
|
||||||
};
|
|
||||||
public:
|
|
||||||
EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct)
|
|
||||||
|
|
||||||
typedef typename Lhs::Scalar LhsScalar;
|
|
||||||
typedef typename Rhs::Scalar RhsScalar;
|
|
||||||
typedef Scalar ResScalar;
|
|
||||||
|
|
||||||
GeneralProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
|
|
||||||
{
|
|
||||||
typedef internal::scalar_product_op<LhsScalar,RhsScalar> BinOp;
|
|
||||||
EIGEN_CHECK_BINARY_COMPATIBILIY(BinOp,LhsScalar,RhsScalar);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Dest>
|
|
||||||
inline void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
if((m_rhs.rows()+dst.rows()+dst.cols())<20 && m_rhs.rows()>0)
|
|
||||||
dst.noalias() = m_lhs .lazyProduct( m_rhs );
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dst.setZero();
|
|
||||||
scaleAndAddTo(dst,Scalar(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Dest>
|
|
||||||
inline void addTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
if((m_rhs.rows()+dst.rows()+dst.cols())<20 && m_rhs.rows()>0)
|
|
||||||
dst.noalias() += m_lhs .lazyProduct( m_rhs );
|
|
||||||
else
|
|
||||||
scaleAndAddTo(dst,Scalar(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Dest>
|
|
||||||
inline void subTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
if((m_rhs.rows()+dst.rows()+dst.cols())<20 && m_rhs.rows()>0)
|
|
||||||
dst.noalias() -= m_lhs .lazyProduct( m_rhs );
|
|
||||||
else
|
|
||||||
scaleAndAddTo(dst,Scalar(-1));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
|
|
||||||
{
|
|
||||||
eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs)
|
|
||||||
* RhsBlasTraits::extractScalarFactor(m_rhs);
|
|
||||||
|
|
||||||
typedef internal::gemm_blocking_space<(Dest::Flags&RowMajorBit) ? RowMajor : ColMajor,LhsScalar,RhsScalar,
|
|
||||||
Dest::MaxRowsAtCompileTime,Dest::MaxColsAtCompileTime,MaxDepthAtCompileTime> BlockingType;
|
|
||||||
|
|
||||||
typedef internal::gemm_functor<
|
|
||||||
Scalar, Index,
|
|
||||||
internal::general_matrix_matrix_product<
|
|
||||||
Index,
|
|
||||||
LhsScalar, (_ActualLhsType::Flags&RowMajorBit) ? RowMajor : ColMajor, bool(LhsBlasTraits::NeedToConjugate),
|
|
||||||
RhsScalar, (_ActualRhsType::Flags&RowMajorBit) ? RowMajor : ColMajor, bool(RhsBlasTraits::NeedToConjugate),
|
|
||||||
(Dest::Flags&RowMajorBit) ? RowMajor : ColMajor>,
|
|
||||||
_ActualLhsType, _ActualRhsType, Dest, BlockingType> GemmFunctor;
|
|
||||||
|
|
||||||
BlockingType blocking(dst.rows(), dst.cols(), lhs.cols(), true);
|
|
||||||
|
|
||||||
internal::parallelize_gemm<(Dest::MaxRowsAtCompileTime>32 || Dest::MaxRowsAtCompileTime==Dynamic)>(GemmFunctor(lhs, rhs, dst, actualAlpha, blocking), this->rows(), this->cols(), Dest::Flags&RowMajorBit);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
template<typename Lhs, typename Rhs>
|
||||||
@ -534,7 +453,6 @@ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemmProduct>
|
|||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
#endif // EIGEN_ENABLE_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
@ -261,7 +261,6 @@ struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,false>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename MatrixType, unsigned int UpLo>
|
template<typename MatrixType, unsigned int UpLo>
|
||||||
template<typename ProductType>
|
template<typename ProductType>
|
||||||
TriangularView<MatrixType,UpLo>& TriangularViewImpl<MatrixType,UpLo,Dense>::_assignProduct(const ProductType& prod, const Scalar& alpha)
|
TriangularView<MatrixType,UpLo>& TriangularViewImpl<MatrixType,UpLo,Dense>::_assignProduct(const ProductType& prod, const Scalar& alpha)
|
||||||
@ -272,19 +271,7 @@ TriangularView<MatrixType,UpLo>& TriangularViewImpl<MatrixType,UpLo,Dense>::_ass
|
|||||||
|
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
template<typename MatrixType, unsigned int UpLo>
|
|
||||||
template<typename ProductDerived, typename _Lhs, typename _Rhs>
|
|
||||||
TriangularView<MatrixType,UpLo>& TriangularViewImpl<MatrixType,UpLo,Dense>::assignProduct(const ProductBase<ProductDerived, _Lhs,_Rhs>& prod, const Scalar& alpha)
|
|
||||||
{
|
|
||||||
eigen_assert(derived().rows() == prod.rows() && derived().cols() == prod.cols());
|
|
||||||
|
|
||||||
general_product_to_triangular_selector<MatrixType, ProductDerived, UpLo, (_Lhs::ColsAtCompileTime==1) || (_Rhs::RowsAtCompileTime==1)>
|
|
||||||
::run(derived().nestedExpression().const_cast_derived(), prod.derived(), alpha);
|
|
||||||
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H
|
#endif // EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H
|
||||||
|
@ -459,58 +459,6 @@ EIGEN_DONT_INLINE void product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,f
|
|||||||
* Wrapper to product_selfadjoint_matrix
|
* Wrapper to product_selfadjoint_matrix
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
template<typename Lhs, int LhsMode, typename Rhs, int RhsMode>
|
|
||||||
struct traits<SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false> >
|
|
||||||
: traits<ProductBase<SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false>, Lhs, Rhs> >
|
|
||||||
{};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Lhs, int LhsMode, typename Rhs, int RhsMode>
|
|
||||||
struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false>
|
|
||||||
: public ProductBase<SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false>, Lhs, Rhs >
|
|
||||||
{
|
|
||||||
EIGEN_PRODUCT_PUBLIC_INTERFACE(SelfadjointProductMatrix)
|
|
||||||
|
|
||||||
SelfadjointProductMatrix(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {}
|
|
||||||
|
|
||||||
enum {
|
|
||||||
LhsIsUpper = (LhsMode&(Upper|Lower))==Upper,
|
|
||||||
LhsIsSelfAdjoint = (LhsMode&SelfAdjoint)==SelfAdjoint,
|
|
||||||
RhsIsUpper = (RhsMode&(Upper|Lower))==Upper,
|
|
||||||
RhsIsSelfAdjoint = (RhsMode&SelfAdjoint)==SelfAdjoint
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
|
|
||||||
{
|
|
||||||
eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs)
|
|
||||||
* RhsBlasTraits::extractScalarFactor(m_rhs);
|
|
||||||
|
|
||||||
internal::product_selfadjoint_matrix<Scalar, Index,
|
|
||||||
EIGEN_LOGICAL_XOR(LhsIsUpper,
|
|
||||||
internal::traits<Lhs>::Flags &RowMajorBit) ? RowMajor : ColMajor, LhsIsSelfAdjoint,
|
|
||||||
NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(LhsIsUpper,bool(LhsBlasTraits::NeedToConjugate)),
|
|
||||||
EIGEN_LOGICAL_XOR(RhsIsUpper,
|
|
||||||
internal::traits<Rhs>::Flags &RowMajorBit) ? RowMajor : ColMajor, RhsIsSelfAdjoint,
|
|
||||||
NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(RhsIsUpper,bool(RhsBlasTraits::NeedToConjugate)),
|
|
||||||
internal::traits<Dest>::Flags&RowMajorBit ? RowMajor : ColMajor>
|
|
||||||
::run(
|
|
||||||
lhs.rows(), rhs.cols(), // sizes
|
|
||||||
&lhs.coeffRef(0,0), lhs.outerStride(), // lhs info
|
|
||||||
&rhs.coeffRef(0,0), rhs.outerStride(), // rhs info
|
|
||||||
&dst.coeffRef(0,0), dst.outerStride(), // result info
|
|
||||||
actualAlpha // alpha
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<typename Lhs, int LhsMode, typename Rhs, int RhsMode>
|
template<typename Lhs, int LhsMode, typename Rhs, int RhsMode>
|
||||||
@ -560,8 +508,6 @@ struct selfadjoint_product_impl<Lhs,LhsMode,false,Rhs,RhsMode,false>
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#endif // EIGEN_ENABLE_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_SELFADJOINT_MATRIX_MATRIX_H
|
#endif // EIGEN_SELFADJOINT_MATRIX_MATRIX_H
|
||||||
|
@ -168,117 +168,6 @@ EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product<Scalar,Index,StorageOrd
|
|||||||
* Wrapper to product_selfadjoint_vector
|
* Wrapper to product_selfadjoint_vector
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
template<typename Lhs, int LhsMode, typename Rhs>
|
|
||||||
struct traits<SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true> >
|
|
||||||
: traits<ProductBase<SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true>, Lhs, Rhs> >
|
|
||||||
{};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Lhs, int LhsMode, typename Rhs>
|
|
||||||
struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true>
|
|
||||||
: public ProductBase<SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true>, Lhs, Rhs >
|
|
||||||
{
|
|
||||||
EIGEN_PRODUCT_PUBLIC_INTERFACE(SelfadjointProductMatrix)
|
|
||||||
|
|
||||||
enum {
|
|
||||||
LhsUpLo = LhsMode&(Upper|Lower)
|
|
||||||
};
|
|
||||||
|
|
||||||
SelfadjointProductMatrix(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {}
|
|
||||||
|
|
||||||
template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
|
|
||||||
{
|
|
||||||
typedef typename Dest::Scalar ResScalar;
|
|
||||||
typedef typename Base::RhsScalar RhsScalar;
|
|
||||||
typedef Map<Matrix<ResScalar,Dynamic,1>, Aligned> MappedDest;
|
|
||||||
|
|
||||||
eigen_assert(dest.rows()==m_lhs.rows() && dest.cols()==m_rhs.cols());
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs)
|
|
||||||
* RhsBlasTraits::extractScalarFactor(m_rhs);
|
|
||||||
|
|
||||||
enum {
|
|
||||||
EvalToDest = (Dest::InnerStrideAtCompileTime==1),
|
|
||||||
UseRhs = (_ActualRhsType::InnerStrideAtCompileTime==1)
|
|
||||||
};
|
|
||||||
|
|
||||||
internal::gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,!EvalToDest> static_dest;
|
|
||||||
internal::gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!UseRhs> static_rhs;
|
|
||||||
|
|
||||||
ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
|
|
||||||
EvalToDest ? dest.data() : static_dest.data());
|
|
||||||
|
|
||||||
ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,rhs.size(),
|
|
||||||
UseRhs ? const_cast<RhsScalar*>(rhs.data()) : static_rhs.data());
|
|
||||||
|
|
||||||
if(!EvalToDest)
|
|
||||||
{
|
|
||||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
|
||||||
Index size = dest.size();
|
|
||||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
|
||||||
#endif
|
|
||||||
MappedDest(actualDestPtr, dest.size()) = dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!UseRhs)
|
|
||||||
{
|
|
||||||
#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
|
||||||
Index size = rhs.size();
|
|
||||||
EIGEN_DENSE_STORAGE_CTOR_PLUGIN
|
|
||||||
#endif
|
|
||||||
Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, rhs.size()) = rhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
internal::selfadjoint_matrix_vector_product<Scalar, Index, (internal::traits<_ActualLhsType>::Flags&RowMajorBit) ? RowMajor : ColMajor, int(LhsUpLo), bool(LhsBlasTraits::NeedToConjugate), bool(RhsBlasTraits::NeedToConjugate)>::run
|
|
||||||
(
|
|
||||||
lhs.rows(), // size
|
|
||||||
&lhs.coeffRef(0,0), lhs.outerStride(), // lhs info
|
|
||||||
actualRhsPtr, 1, // rhs info
|
|
||||||
actualDestPtr, // result info
|
|
||||||
actualAlpha // scale factor
|
|
||||||
);
|
|
||||||
|
|
||||||
if(!EvalToDest)
|
|
||||||
dest = MappedDest(actualDestPtr, dest.size());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
template<typename Lhs, typename Rhs, int RhsMode>
|
|
||||||
struct traits<SelfadjointProductMatrix<Lhs,0,true,Rhs,RhsMode,false> >
|
|
||||||
: traits<ProductBase<SelfadjointProductMatrix<Lhs,0,true,Rhs,RhsMode,false>, Lhs, Rhs> >
|
|
||||||
{};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int RhsMode>
|
|
||||||
struct SelfadjointProductMatrix<Lhs,0,true,Rhs,RhsMode,false>
|
|
||||||
: public ProductBase<SelfadjointProductMatrix<Lhs,0,true,Rhs,RhsMode,false>, Lhs, Rhs >
|
|
||||||
{
|
|
||||||
EIGEN_PRODUCT_PUBLIC_INTERFACE(SelfadjointProductMatrix)
|
|
||||||
|
|
||||||
enum {
|
|
||||||
RhsUpLo = RhsMode&(Upper|Lower)
|
|
||||||
};
|
|
||||||
|
|
||||||
SelfadjointProductMatrix(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {}
|
|
||||||
|
|
||||||
template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
|
|
||||||
{
|
|
||||||
// let's simply transpose the product
|
|
||||||
Transpose<Dest> destT(dest);
|
|
||||||
SelfadjointProductMatrix<Transpose<const Rhs>, int(RhsUpLo)==Upper ? Lower : Upper, false,
|
|
||||||
Transpose<const Lhs>, 0, true>(m_rhs.transpose(), m_lhs.transpose()).scaleAndAddTo(destT, alpha);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<typename Lhs, int LhsMode, typename Rhs>
|
template<typename Lhs, int LhsMode, typename Rhs>
|
||||||
@ -378,8 +267,6 @@ struct selfadjoint_product_impl<Lhs,0,true,Rhs,RhsMode,false>
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_SELFADJOINT_MATRIX_VECTOR_H
|
#endif // EIGEN_SELFADJOINT_MATRIX_VECTOR_H
|
||||||
|
@ -368,59 +368,9 @@ EIGEN_DONT_INLINE void product_triangular_matrix_matrix<Scalar,Index,Mode,false,
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Wrapper to product_triangular_matrix_matrix
|
* Wrapper to product_triangular_matrix_matrix
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<int Mode, bool LhsIsTriangular, typename Lhs, typename Rhs>
|
|
||||||
struct traits<TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,false> >
|
|
||||||
: traits<ProductBase<TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,false>, Lhs, Rhs> >
|
|
||||||
{};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<int Mode, bool LhsIsTriangular, typename Lhs, typename Rhs>
|
|
||||||
struct TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,false>
|
|
||||||
: public ProductBase<TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,false>, Lhs, Rhs >
|
|
||||||
{
|
|
||||||
EIGEN_PRODUCT_PUBLIC_INTERFACE(TriangularProduct)
|
|
||||||
|
|
||||||
TriangularProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {}
|
|
||||||
|
|
||||||
template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs)
|
|
||||||
* RhsBlasTraits::extractScalarFactor(m_rhs);
|
|
||||||
|
|
||||||
typedef internal::gemm_blocking_space<(Dest::Flags&RowMajorBit) ? RowMajor : ColMajor,Scalar,Scalar,
|
|
||||||
Lhs::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime, Lhs::MaxColsAtCompileTime,4> BlockingType;
|
|
||||||
|
|
||||||
enum { IsLower = (Mode&Lower) == Lower };
|
|
||||||
Index stripedRows = ((!LhsIsTriangular) || (IsLower)) ? lhs.rows() : (std::min)(lhs.rows(),lhs.cols());
|
|
||||||
Index stripedCols = ((LhsIsTriangular) || (!IsLower)) ? rhs.cols() : (std::min)(rhs.cols(),rhs.rows());
|
|
||||||
Index stripedDepth = LhsIsTriangular ? ((!IsLower) ? lhs.cols() : (std::min)(lhs.cols(),lhs.rows()))
|
|
||||||
: ((IsLower) ? rhs.rows() : (std::min)(rhs.rows(),rhs.cols()));
|
|
||||||
|
|
||||||
BlockingType blocking(stripedRows, stripedCols, stripedDepth);
|
|
||||||
|
|
||||||
internal::product_triangular_matrix_matrix<Scalar, Index,
|
|
||||||
Mode, LhsIsTriangular,
|
|
||||||
(internal::traits<_ActualLhsType>::Flags&RowMajorBit) ? RowMajor : ColMajor, LhsBlasTraits::NeedToConjugate,
|
|
||||||
(internal::traits<_ActualRhsType>::Flags&RowMajorBit) ? RowMajor : ColMajor, RhsBlasTraits::NeedToConjugate,
|
|
||||||
(internal::traits<Dest >::Flags&RowMajorBit) ? RowMajor : ColMajor>
|
|
||||||
::run(
|
|
||||||
stripedRows, stripedCols, stripedDepth, // sizes
|
|
||||||
&lhs.coeffRef(0,0), lhs.outerStride(), // lhs info
|
|
||||||
&rhs.coeffRef(0,0), rhs.outerStride(), // rhs info
|
|
||||||
&dst.coeffRef(0,0), dst.outerStride(), // result info
|
|
||||||
actualAlpha, blocking
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
template<int Mode, bool LhsIsTriangular, typename Lhs, typename Rhs>
|
template<int Mode, bool LhsIsTriangular, typename Lhs, typename Rhs>
|
||||||
struct triangular_product_impl<Mode,LhsIsTriangular,Lhs,false,Rhs,false>
|
struct triangular_product_impl<Mode,LhsIsTriangular,Lhs,false,Rhs,false>
|
||||||
@ -470,7 +420,6 @@ struct triangular_product_impl<Mode,LhsIsTriangular,Lhs,false,Rhs,false>
|
|||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
#endif // EIGEN_ENABLE_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
@ -157,61 +157,11 @@ EIGEN_DONT_INLINE void triangular_matrix_vector_product<Index,Mode,LhsScalar,Con
|
|||||||
* Wrapper to product_triangular_vector
|
* Wrapper to product_triangular_vector
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
template<int Mode, bool LhsIsTriangular, typename Lhs, typename Rhs>
|
|
||||||
struct traits<TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,true> >
|
|
||||||
: traits<ProductBase<TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,true>, Lhs, Rhs> >
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<int Mode, bool LhsIsTriangular, typename Lhs, typename Rhs>
|
|
||||||
struct traits<TriangularProduct<Mode,LhsIsTriangular,Lhs,true,Rhs,false> >
|
|
||||||
: traits<ProductBase<TriangularProduct<Mode,LhsIsTriangular,Lhs,true,Rhs,false>, Lhs, Rhs> >
|
|
||||||
{};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<int Mode,int StorageOrder>
|
template<int Mode,int StorageOrder>
|
||||||
struct trmv_selector;
|
struct trmv_selector;
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<int Mode, typename Lhs, typename Rhs>
|
|
||||||
struct TriangularProduct<Mode,true,Lhs,false,Rhs,true>
|
|
||||||
: public ProductBase<TriangularProduct<Mode,true,Lhs,false,Rhs,true>, Lhs, Rhs >
|
|
||||||
{
|
|
||||||
EIGEN_PRODUCT_PUBLIC_INTERFACE(TriangularProduct)
|
|
||||||
|
|
||||||
TriangularProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {}
|
|
||||||
|
|
||||||
template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
|
|
||||||
{
|
|
||||||
eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
|
|
||||||
|
|
||||||
internal::trmv_selector<Mode,(int(internal::traits<Lhs>::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(m_lhs, m_rhs, dst, alpha);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int Mode, typename Lhs, typename Rhs>
|
|
||||||
struct TriangularProduct<Mode,false,Lhs,true,Rhs,false>
|
|
||||||
: public ProductBase<TriangularProduct<Mode,false,Lhs,true,Rhs,false>, Lhs, Rhs >
|
|
||||||
{
|
|
||||||
EIGEN_PRODUCT_PUBLIC_INTERFACE(TriangularProduct)
|
|
||||||
|
|
||||||
TriangularProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {}
|
|
||||||
|
|
||||||
template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
|
|
||||||
{
|
|
||||||
eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
|
|
||||||
|
|
||||||
Transpose<Dest> dstT(dst);
|
|
||||||
internal::trmv_selector<(Mode & (UnitDiag|ZeroDiag)) | ((Mode & Lower) ? Upper : Lower),
|
|
||||||
(int(internal::traits<Rhs>::Flags)&RowMajorBit) ? ColMajor : RowMajor>
|
|
||||||
::run(m_rhs.transpose(),m_lhs.transpose(), dstT, alpha);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<int Mode, typename Lhs, typename Rhs>
|
template<int Mode, typename Lhs, typename Rhs>
|
||||||
@ -240,7 +190,6 @@ struct triangular_product_impl<Mode,false,Lhs,true,Rhs,false>
|
|||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
@ -139,10 +139,6 @@ template<typename ExpressionType> class ArrayWrapper;
|
|||||||
template<typename ExpressionType> class MatrixWrapper;
|
template<typename ExpressionType> class MatrixWrapper;
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
#ifndef EIGEN_TEST_EVALUATROS
|
|
||||||
template<typename DecompositionType, typename Rhs> struct solve_retval_base;
|
|
||||||
template<typename DecompositionType, typename Rhs> struct solve_retval;
|
|
||||||
#endif
|
|
||||||
template<typename DecompositionType> struct kernel_retval_base;
|
template<typename DecompositionType> struct kernel_retval_base;
|
||||||
template<typename DecompositionType> struct kernel_retval;
|
template<typename DecompositionType> struct kernel_retval;
|
||||||
template<typename DecompositionType> struct image_retval_base;
|
template<typename DecompositionType> struct image_retval_base;
|
||||||
|
@ -374,46 +374,6 @@ namespace Eigen {
|
|||||||
* documentation in a single line.
|
* documentation in a single line.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \
|
|
||||||
typedef typename Eigen::internal::traits<Derived>::Scalar Scalar; /*!< \brief Numeric type, e.g. float, double, int or std::complex<float>. */ \
|
|
||||||
typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; /*!< \brief The underlying numeric type for composed scalar types. \details In cases where Scalar is e.g. std::complex<T>, T were corresponding to RealScalar. */ \
|
|
||||||
typedef typename Base::CoeffReturnType CoeffReturnType; /*!< \brief The return type for coefficient access. \details Depending on whether the object allows direct coefficient access (e.g. for a MatrixXd), this type is either 'const Scalar&' or simply 'Scalar' for objects that do not allow direct coefficient access. */ \
|
|
||||||
typedef typename Eigen::internal::nested<Derived>::type Nested; \
|
|
||||||
typedef typename Eigen::internal::traits<Derived>::StorageKind StorageKind; \
|
|
||||||
typedef typename Eigen::internal::traits<Derived>::Index Index; \
|
|
||||||
enum { RowsAtCompileTime = Eigen::internal::traits<Derived>::RowsAtCompileTime, \
|
|
||||||
ColsAtCompileTime = Eigen::internal::traits<Derived>::ColsAtCompileTime, \
|
|
||||||
Flags = Eigen::internal::traits<Derived>::Flags, \
|
|
||||||
CoeffReadCost = Eigen::internal::traits<Derived>::CoeffReadCost, \
|
|
||||||
SizeAtCompileTime = Base::SizeAtCompileTime, \
|
|
||||||
MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \
|
|
||||||
IsVectorAtCompileTime = Base::IsVectorAtCompileTime };
|
|
||||||
|
|
||||||
|
|
||||||
#define EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \
|
|
||||||
typedef typename Eigen::internal::traits<Derived>::Scalar Scalar; /*!< \brief Numeric type, e.g. float, double, int or std::complex<float>. */ \
|
|
||||||
typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; /*!< \brief The underlying numeric type for composed scalar types. \details In cases where Scalar is e.g. std::complex<T>, T were corresponding to RealScalar. */ \
|
|
||||||
typedef typename Base::PacketScalar PacketScalar; \
|
|
||||||
typedef typename Base::CoeffReturnType CoeffReturnType; /*!< \brief The return type for coefficient access. \details Depending on whether the object allows direct coefficient access (e.g. for a MatrixXd), this type is either 'const Scalar&' or simply 'Scalar' for objects that do not allow direct coefficient access. */ \
|
|
||||||
typedef typename Eigen::internal::nested<Derived>::type Nested; \
|
|
||||||
typedef typename Eigen::internal::traits<Derived>::StorageKind StorageKind; \
|
|
||||||
typedef typename Eigen::internal::traits<Derived>::Index Index; \
|
|
||||||
enum { RowsAtCompileTime = Eigen::internal::traits<Derived>::RowsAtCompileTime, \
|
|
||||||
ColsAtCompileTime = Eigen::internal::traits<Derived>::ColsAtCompileTime, \
|
|
||||||
MaxRowsAtCompileTime = Eigen::internal::traits<Derived>::MaxRowsAtCompileTime, \
|
|
||||||
MaxColsAtCompileTime = Eigen::internal::traits<Derived>::MaxColsAtCompileTime, \
|
|
||||||
Flags = Eigen::internal::traits<Derived>::Flags, \
|
|
||||||
CoeffReadCost = Eigen::internal::traits<Derived>::CoeffReadCost, \
|
|
||||||
SizeAtCompileTime = Base::SizeAtCompileTime, \
|
|
||||||
MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \
|
|
||||||
IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; \
|
|
||||||
using Base::derived; \
|
|
||||||
using Base::const_cast_derived;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// TODO The EIGEN_DENSE_PUBLIC_INTERFACE should not exists anymore
|
// TODO The EIGEN_DENSE_PUBLIC_INTERFACE should not exists anymore
|
||||||
|
|
||||||
#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \
|
#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \
|
||||||
@ -450,8 +410,6 @@ namespace Eigen {
|
|||||||
using Base::derived; \
|
using Base::derived; \
|
||||||
using Base::const_cast_derived;
|
using Base::const_cast_derived;
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
#define EIGEN_PLAIN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b)
|
#define EIGEN_PLAIN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b)
|
||||||
#define EIGEN_PLAIN_ENUM_MAX(a,b) (((int)a >= (int)b) ? (int)a : (int)b)
|
#define EIGEN_PLAIN_ENUM_MAX(a,b) (((int)a >= (int)b) ? (int)a : (int)b)
|
||||||
|
|
||||||
|
@ -125,43 +125,6 @@ template<typename _Scalar, int _Rows, int _Cols,
|
|||||||
typedef Matrix<_Scalar, _Rows, _Cols, Options, _MaxRows, _MaxCols> type;
|
typedef Matrix<_Scalar, _Rows, _Cols, Options, _MaxRows, _MaxCols> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
|
||||||
class compute_matrix_flags
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
row_major_bit = Options&RowMajor ? RowMajorBit : 0,
|
|
||||||
is_dynamic_size_storage = MaxRows==Dynamic || MaxCols==Dynamic,
|
|
||||||
|
|
||||||
aligned_bit =
|
|
||||||
(
|
|
||||||
((Options&DontAlign)==0)
|
|
||||||
&& (
|
|
||||||
#if EIGEN_ALIGN_STATICALLY
|
|
||||||
((!is_dynamic_size_storage) && (((MaxCols*MaxRows*int(sizeof(Scalar))) % EIGEN_ALIGN_BYTES) == 0))
|
|
||||||
#else
|
|
||||||
0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
||
|
|
||||||
|
|
||||||
#if EIGEN_ALIGN
|
|
||||||
is_dynamic_size_storage
|
|
||||||
#else
|
|
||||||
0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
)
|
|
||||||
) ? AlignedBit : 0,
|
|
||||||
packet_access_bit = packet_traits<Scalar>::Vectorizable && aligned_bit ? PacketAccessBit : 0
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum { ret = LinearAccessBit | LvalueBit | DirectAccessBit | NestByRefBit | packet_access_bit | row_major_bit | aligned_bit };
|
|
||||||
};
|
|
||||||
|
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
||||||
class compute_matrix_flags
|
class compute_matrix_flags
|
||||||
{
|
{
|
||||||
@ -172,9 +135,7 @@ class compute_matrix_flags
|
|||||||
// However, I (Gael) think that DirectAccessBit should only matter at the evaluation stage.
|
// However, I (Gael) think that DirectAccessBit should only matter at the evaluation stage.
|
||||||
enum { ret = DirectAccessBit | LvalueBit | NestByRefBit | row_major_bit };
|
enum { ret = DirectAccessBit | LvalueBit | NestByRefBit | row_major_bit };
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
||||||
class compute_matrix_evaluator_flags
|
class compute_matrix_evaluator_flags
|
||||||
{
|
{
|
||||||
@ -209,8 +170,6 @@ class compute_matrix_evaluator_flags
|
|||||||
enum { ret = LinearAccessBit | DirectAccessBit | packet_access_bit | row_major_bit | aligned_bit };
|
enum { ret = LinearAccessBit | DirectAccessBit | packet_access_bit | row_major_bit | aligned_bit };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EIGEN_ENABLE_EVALUATORS
|
|
||||||
|
|
||||||
template<int _Rows, int _Cols> struct size_at_compile_time
|
template<int _Rows, int _Cols> struct size_at_compile_time
|
||||||
{
|
{
|
||||||
enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
|
enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
|
||||||
@ -361,58 +320,6 @@ struct transfer_constness
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** \internal Determines how a given expression should be nested into another one.
|
|
||||||
* For example, when you do a * (b+c), Eigen will determine how the expression b+c should be
|
|
||||||
* nested into the bigger product expression. The choice is between nesting the expression b+c as-is, or
|
|
||||||
* evaluating that expression b+c into a temporary variable d, and nest d so that the resulting expression is
|
|
||||||
* a*d. Evaluating can be beneficial for example if every coefficient access in the resulting expression causes
|
|
||||||
* many coefficient accesses in the nested expressions -- as is the case with matrix product for example.
|
|
||||||
*
|
|
||||||
* \param T the type of the expression being nested
|
|
||||||
* \param n the number of coefficient accesses in the nested expression for each coefficient access in the bigger expression.
|
|
||||||
*
|
|
||||||
* Note that if no evaluation occur, then the constness of T is preserved.
|
|
||||||
*
|
|
||||||
* Example. Suppose that a, b, and c are of type Matrix3d. The user forms the expression a*(b+c).
|
|
||||||
* b+c is an expression "sum of matrices", which we will denote by S. In order to determine how to nest it,
|
|
||||||
* the Product expression uses: nested<S, 3>::type, which turns out to be Matrix3d because the internal logic of
|
|
||||||
* nested determined that in this case it was better to evaluate the expression b+c into a temporary. On the other hand,
|
|
||||||
* since a is of type Matrix3d, the Product expression nests it as nested<Matrix3d, 3>::type, which turns out to be
|
|
||||||
* const Matrix3d&, because the internal logic of nested determined that since a was already a matrix, there was no point
|
|
||||||
* in copying it into another matrix.
|
|
||||||
*/
|
|
||||||
template<typename T, int n=1, typename PlainObject = typename eval<T>::type> struct nested
|
|
||||||
{
|
|
||||||
enum {
|
|
||||||
// for the purpose of this test, to keep it reasonably simple, we arbitrarily choose a value of Dynamic values.
|
|
||||||
// the choice of 10000 makes it larger than any practical fixed value and even most dynamic values.
|
|
||||||
// in extreme cases where these assumptions would be wrong, we would still at worst suffer performance issues
|
|
||||||
// (poor choice of temporaries).
|
|
||||||
// it's important that this value can still be squared without integer overflowing.
|
|
||||||
DynamicAsInteger = 10000,
|
|
||||||
ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost,
|
|
||||||
ScalarReadCostAsInteger = ScalarReadCost == Dynamic ? int(DynamicAsInteger) : int(ScalarReadCost),
|
|
||||||
CoeffReadCost = traits<T>::CoeffReadCost,
|
|
||||||
CoeffReadCostAsInteger = CoeffReadCost == Dynamic ? int(DynamicAsInteger) : int(CoeffReadCost),
|
|
||||||
NAsInteger = n == Dynamic ? int(DynamicAsInteger) : n,
|
|
||||||
CostEvalAsInteger = (NAsInteger+1) * ScalarReadCostAsInteger + CoeffReadCostAsInteger,
|
|
||||||
CostNoEvalAsInteger = NAsInteger * CoeffReadCostAsInteger
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef typename conditional<
|
|
||||||
( (int(traits<T>::Flags) & EvalBeforeNestingBit) ||
|
|
||||||
int(CostEvalAsInteger) < int(CostNoEvalAsInteger)
|
|
||||||
),
|
|
||||||
PlainObject,
|
|
||||||
typename ref_selector<T>::type
|
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// When using evaluators, we never evaluate when assembling the expression!!
|
// When using evaluators, we never evaluate when assembling the expression!!
|
||||||
// TODO: get rid of this nested class since it's just an alias for ref_selector.
|
// TODO: get rid of this nested class since it's just an alias for ref_selector.
|
||||||
template<typename T, int n=1, typename PlainObject = void> struct nested
|
template<typename T, int n=1, typename PlainObject = void> struct nested
|
||||||
@ -420,12 +327,20 @@ template<typename T, int n=1, typename PlainObject = void> struct nested
|
|||||||
typedef typename ref_selector<T>::type type;
|
typedef typename ref_selector<T>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
// However, we still need a mechanism to detect whether an expression which is evaluated multiple time
|
// However, we still need a mechanism to detect whether an expression which is evaluated multiple time
|
||||||
// has to be evaluated into a temporary.
|
// has to be evaluated into a temporary.
|
||||||
// That's the purpose of this new nested_eval helper:
|
// That's the purpose of this new nested_eval helper:
|
||||||
|
/** \internal Determines how a given expression should be nested when evaluated multiple times.
|
||||||
|
* For example, when you do a * (b+c), Eigen will determine how the expression b+c should be
|
||||||
|
* evaluated into the bigger product expression. The choice is between nesting the expression b+c as-is, or
|
||||||
|
* evaluating that expression b+c into a temporary variable d, and nest d so that the resulting expression is
|
||||||
|
* a*d. Evaluating can be beneficial for example if every coefficient access in the resulting expression causes
|
||||||
|
* many coefficient accesses in the nested expressions -- as is the case with matrix product for example.
|
||||||
|
*
|
||||||
|
* \param T the type of the expression being nested.
|
||||||
|
* \param n the number of coefficient accesses in the nested expression for each coefficient access in the bigger expression.
|
||||||
|
* \param PlainObject the type of the temporary if needed.
|
||||||
|
*/
|
||||||
template<typename T, int n, typename PlainObject = typename eval<T>::type> struct nested_eval
|
template<typename T, int n, typename PlainObject = typename eval<T>::type> struct nested_eval
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
@ -453,7 +368,6 @@ template<typename T, int n, typename PlainObject = typename eval<T>::type> struc
|
|||||||
typename ref_selector<T>::type
|
typename ref_selector<T>::type
|
||||||
>::type type;
|
>::type type;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
|
@ -71,11 +71,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
|
|||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline explicit AlignedBox(const MatrixBase<Derived>& a_p)
|
inline explicit AlignedBox(const MatrixBase<Derived>& a_p)
|
||||||
{
|
{
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
typename internal::nested<Derived,2>::type p(a_p.derived());
|
|
||||||
#else
|
|
||||||
typename internal::nested_eval<Derived,2>::type p(a_p.derived());
|
typename internal::nested_eval<Derived,2>::type p(a_p.derived());
|
||||||
#endif
|
|
||||||
m_min = p;
|
m_min = p;
|
||||||
m_max = p;
|
m_max = p;
|
||||||
}
|
}
|
||||||
|
@ -49,9 +49,6 @@ struct traits<Homogeneous<MatrixType,Direction> >
|
|||||||
Flags = ColsAtCompileTime==1 ? (TmpFlags & ~RowMajorBit)
|
Flags = ColsAtCompileTime==1 ? (TmpFlags & ~RowMajorBit)
|
||||||
: RowsAtCompileTime==1 ? (TmpFlags | RowMajorBit)
|
: RowsAtCompileTime==1 ? (TmpFlags | RowMajorBit)
|
||||||
: TmpFlags
|
: TmpFlags
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
, CoeffReadCost = _MatrixTypeNested::CoeffReadCost
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -80,39 +77,6 @@ template<typename MatrixType,int _Direction> class Homogeneous
|
|||||||
|
|
||||||
const NestedExpression& nestedExpression() const { return m_matrix; }
|
const NestedExpression& nestedExpression() const { return m_matrix; }
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
inline Scalar coeff(Index row, Index col) const
|
|
||||||
{
|
|
||||||
if( (int(Direction)==Vertical && row==m_matrix.rows())
|
|
||||||
|| (int(Direction)==Horizontal && col==m_matrix.cols()))
|
|
||||||
return 1;
|
|
||||||
return m_matrix.coeff(row, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::homogeneous_right_product_impl<Homogeneous,Rhs>
|
|
||||||
operator* (const MatrixBase<Rhs>& rhs) const
|
|
||||||
{
|
|
||||||
eigen_assert(int(Direction)==Horizontal);
|
|
||||||
return internal::homogeneous_right_product_impl<Homogeneous,Rhs>(m_matrix,rhs.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Lhs> friend
|
|
||||||
inline const internal::homogeneous_left_product_impl<Homogeneous,Lhs>
|
|
||||||
operator* (const MatrixBase<Lhs>& lhs, const Homogeneous& rhs)
|
|
||||||
{
|
|
||||||
eigen_assert(int(Direction)==Vertical);
|
|
||||||
return internal::homogeneous_left_product_impl<Homogeneous,Lhs>(lhs.derived(),rhs.m_matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Scalar, int Dim, int Mode, int Options> friend
|
|
||||||
inline const internal::homogeneous_left_product_impl<Homogeneous,Transform<Scalar,Dim,Mode,Options> >
|
|
||||||
operator* (const Transform<Scalar,Dim,Mode,Options>& lhs, const Homogeneous& rhs)
|
|
||||||
{
|
|
||||||
eigen_assert(int(Direction)==Vertical);
|
|
||||||
return internal::homogeneous_left_product_impl<Homogeneous,Transform<Scalar,Dim,Mode,Options> >(lhs,rhs.m_matrix);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
template<typename Rhs>
|
template<typename Rhs>
|
||||||
inline const Product<Homogeneous,Rhs>
|
inline const Product<Homogeneous,Rhs>
|
||||||
operator* (const MatrixBase<Rhs>& rhs) const
|
operator* (const MatrixBase<Rhs>& rhs) const
|
||||||
@ -136,7 +100,6 @@ template<typename MatrixType,int _Direction> class Homogeneous
|
|||||||
eigen_assert(int(Direction)==Vertical);
|
eigen_assert(int(Direction)==Vertical);
|
||||||
return Product<Transform<Scalar,Dim,Mode,Options>, Homogeneous>(lhs,rhs);
|
return Product<Transform<Scalar,Dim,Mode,Options>, Homogeneous>(lhs,rhs);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename Func>
|
template<typename Func>
|
||||||
EIGEN_STRONG_INLINE typename internal::result_of<Func(Scalar)>::type
|
EIGEN_STRONG_INLINE typename internal::result_of<Func(Scalar)>::type
|
||||||
@ -338,8 +301,6 @@ struct homogeneous_right_product_impl<Homogeneous<MatrixType,Horizontal>,Rhs>
|
|||||||
typename Rhs::Nested m_rhs;
|
typename Rhs::Nested m_rhs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
template<typename ArgType,int Direction>
|
template<typename ArgType,int Direction>
|
||||||
struct evaluator_traits<Homogeneous<ArgType,Direction> >
|
struct evaluator_traits<Homogeneous<ArgType,Direction> >
|
||||||
{
|
{
|
||||||
@ -427,8 +388,6 @@ struct generic_product_impl<Transform<Scalar,Dim,Mode,Options>, Homogeneous<RhsA
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
@ -30,13 +30,8 @@ MatrixBase<Derived>::cross(const MatrixBase<OtherDerived>& other) const
|
|||||||
|
|
||||||
// Note that there is no need for an expression here since the compiler
|
// Note that there is no need for an expression here since the compiler
|
||||||
// optimize such a small temporary very well (even within a complex expression)
|
// optimize such a small temporary very well (even within a complex expression)
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
typename internal::nested<Derived,2>::type lhs(derived());
|
|
||||||
typename internal::nested<OtherDerived,2>::type rhs(other.derived());
|
|
||||||
#else
|
|
||||||
typename internal::nested_eval<Derived,2>::type lhs(derived());
|
typename internal::nested_eval<Derived,2>::type lhs(derived());
|
||||||
typename internal::nested_eval<OtherDerived,2>::type rhs(other.derived());
|
typename internal::nested_eval<OtherDerived,2>::type rhs(other.derived());
|
||||||
#endif
|
|
||||||
return typename cross_product_return_type<OtherDerived>::type(
|
return typename cross_product_return_type<OtherDerived>::type(
|
||||||
numext::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)),
|
numext::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)),
|
||||||
numext::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)),
|
numext::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)),
|
||||||
@ -81,13 +76,8 @@ MatrixBase<Derived>::cross3(const MatrixBase<OtherDerived>& other) const
|
|||||||
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived,4)
|
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived,4)
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,4)
|
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,4)
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
typedef typename internal::nested<Derived,2>::type DerivedNested;
|
|
||||||
typedef typename internal::nested<OtherDerived,2>::type OtherDerivedNested;
|
|
||||||
#else
|
|
||||||
typedef typename internal::nested_eval<Derived,2>::type DerivedNested;
|
typedef typename internal::nested_eval<Derived,2>::type DerivedNested;
|
||||||
typedef typename internal::nested_eval<OtherDerived,2>::type OtherDerivedNested;
|
typedef typename internal::nested_eval<OtherDerived,2>::type OtherDerivedNested;
|
||||||
#endif
|
|
||||||
DerivedNested lhs(derived());
|
DerivedNested lhs(derived());
|
||||||
OtherDerivedNested rhs(other.derived());
|
OtherDerivedNested rhs(other.derived());
|
||||||
|
|
||||||
@ -114,13 +104,8 @@ VectorwiseOp<ExpressionType,Direction>::cross(const MatrixBase<OtherDerived>& ot
|
|||||||
EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
|
EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
|
||||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
typename internal::nested<ExpressionType,2>::type mat(_expression());
|
|
||||||
typename internal::nested<OtherDerived,2>::type vec(other.derived());
|
|
||||||
#else
|
|
||||||
typename internal::nested_eval<ExpressionType,2>::type mat(_expression());
|
typename internal::nested_eval<ExpressionType,2>::type mat(_expression());
|
||||||
typename internal::nested_eval<OtherDerived,2>::type vec(other.derived());
|
typename internal::nested_eval<OtherDerived,2>::type vec(other.derived());
|
||||||
#endif
|
|
||||||
|
|
||||||
CrossReturnType res(_expression().rows(),_expression().cols());
|
CrossReturnType res(_expression().rows(),_expression().cols());
|
||||||
if(Direction==Vertical)
|
if(Direction==Vertical)
|
||||||
|
@ -217,11 +217,7 @@ struct traits<Quaternion<_Scalar,_Options> >
|
|||||||
typedef _Scalar Scalar;
|
typedef _Scalar Scalar;
|
||||||
typedef Matrix<_Scalar,4,1,_Options> Coefficients;
|
typedef Matrix<_Scalar,4,1,_Options> Coefficients;
|
||||||
enum{
|
enum{
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
IsAligned = internal::traits<Coefficients>::Flags & AlignedBit,
|
|
||||||
#else
|
|
||||||
IsAligned = (internal::traits<Coefficients>::EvaluatorFlags & AlignedBit) != 0,
|
IsAligned = (internal::traits<Coefficients>::EvaluatorFlags & AlignedBit) != 0,
|
||||||
#endif
|
|
||||||
Flags = IsAligned ? (AlignedBit | LvalueBit) : LvalueBit
|
Flags = IsAligned ? (AlignedBit | LvalueBit) : LvalueBit
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -62,7 +62,6 @@ struct transform_construct_from_matrix;
|
|||||||
|
|
||||||
template<typename TransformType> struct transform_take_affine_part;
|
template<typename TransformType> struct transform_take_affine_part;
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename _Scalar, int _Dim, int _Mode, int _Options>
|
template<typename _Scalar, int _Dim, int _Mode, int _Options>
|
||||||
struct traits<Transform<_Scalar,_Dim,_Mode,_Options> >
|
struct traits<Transform<_Scalar,_Dim,_Mode,_Options> >
|
||||||
{
|
{
|
||||||
@ -78,7 +77,6 @@ struct traits<Transform<_Scalar,_Dim,_Mode,_Options> >
|
|||||||
Flags = 0
|
Flags = 0
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
@ -374,10 +372,8 @@ public:
|
|||||||
inline QTransform toQTransform(void) const;
|
inline QTransform toQTransform(void) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
Index rows() const { return int(Mode)==int(Projective) ? m_matrix.cols() : (m_matrix.cols()-1); }
|
Index rows() const { return int(Mode)==int(Projective) ? m_matrix.cols() : (m_matrix.cols()-1); }
|
||||||
Index cols() const { return m_matrix.cols(); }
|
Index cols() const { return m_matrix.cols(); }
|
||||||
#endif
|
|
||||||
|
|
||||||
/** shortcut for m_matrix(row,col);
|
/** shortcut for m_matrix(row,col);
|
||||||
* \sa MatrixBase::operator(Index,Index) const */
|
* \sa MatrixBase::operator(Index,Index) const */
|
||||||
|
@ -73,8 +73,6 @@ struct traits<HouseholderSequence<VectorsType,CoeffsType,Side> >
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
struct HouseholderSequenceShape {};
|
struct HouseholderSequenceShape {};
|
||||||
|
|
||||||
template<typename VectorsType, typename CoeffsType, int Side>
|
template<typename VectorsType, typename CoeffsType, int Side>
|
||||||
@ -83,7 +81,6 @@ struct evaluator_traits<HouseholderSequence<VectorsType,CoeffsType,Side> >
|
|||||||
{
|
{
|
||||||
typedef HouseholderSequenceShape Shape;
|
typedef HouseholderSequenceShape Shape;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename VectorsType, typename CoeffsType, int Side>
|
template<typename VectorsType, typename CoeffsType, int Side>
|
||||||
struct hseq_side_dependent_impl
|
struct hseq_side_dependent_impl
|
||||||
|
@ -87,16 +87,6 @@ class DiagonalPreconditioner
|
|||||||
x = m_invdiag.array() * b.array() ;
|
x = m_invdiag.array() * b.array() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Rhs> inline const internal::solve_retval<DiagonalPreconditioner, Rhs>
|
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "DiagonalPreconditioner is not initialized.");
|
|
||||||
eigen_assert(m_invdiag.size()==b.rows()
|
|
||||||
&& "DiagonalPreconditioner::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::solve_retval<DiagonalPreconditioner, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
template<typename Rhs> inline const Solve<DiagonalPreconditioner, Rhs>
|
template<typename Rhs> inline const Solve<DiagonalPreconditioner, Rhs>
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
solve(const MatrixBase<Rhs>& b) const
|
||||||
{
|
{
|
||||||
@ -105,31 +95,12 @@ class DiagonalPreconditioner
|
|||||||
&& "DiagonalPreconditioner::solve(): invalid number of rows of the right hand side matrix b");
|
&& "DiagonalPreconditioner::solve(): invalid number of rows of the right hand side matrix b");
|
||||||
return Solve<DiagonalPreconditioner, Rhs>(*this, b.derived());
|
return Solve<DiagonalPreconditioner, Rhs>(*this, b.derived());
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Vector m_invdiag;
|
Vector m_invdiag;
|
||||||
bool m_isInitialized;
|
bool m_isInitialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename _MatrixType, typename Rhs>
|
|
||||||
struct solve_retval<DiagonalPreconditioner<_MatrixType>, Rhs>
|
|
||||||
: solve_retval_base<DiagonalPreconditioner<_MatrixType>, Rhs>
|
|
||||||
{
|
|
||||||
typedef DiagonalPreconditioner<_MatrixType> Dec;
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec()._solve_impl(rhs(),dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** \ingroup IterativeLinearSolvers_Module
|
/** \ingroup IterativeLinearSolvers_Module
|
||||||
* \brief A naive preconditioner which approximates any matrix as the identity matrix
|
* \brief A naive preconditioner which approximates any matrix as the identity matrix
|
||||||
|
@ -182,24 +182,6 @@ public:
|
|||||||
|
|
||||||
~BiCGSTAB() {}
|
~BiCGSTAB() {}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A
|
|
||||||
* \a x0 as an initial solution.
|
|
||||||
*
|
|
||||||
* \sa compute()
|
|
||||||
*/
|
|
||||||
template<typename Rhs,typename Guess>
|
|
||||||
inline const internal::solve_retval_with_guess<BiCGSTAB, Rhs, Guess>
|
|
||||||
solveWithGuess(const MatrixBase<Rhs>& b, const Guess& x0) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "BiCGSTAB is not initialized.");
|
|
||||||
eigen_assert(Base::rows()==b.rows()
|
|
||||||
&& "BiCGSTAB::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::solve_retval_with_guess
|
|
||||||
<BiCGSTAB, Rhs, Guess>(*this, b.derived(), x0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \internal */
|
/** \internal */
|
||||||
template<typename Rhs,typename Dest>
|
template<typename Rhs,typename Dest>
|
||||||
void _solve_with_guess_impl(const Rhs& b, Dest& x) const
|
void _solve_with_guess_impl(const Rhs& b, Dest& x) const
|
||||||
@ -234,25 +216,6 @@ protected:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename _MatrixType, typename _Preconditioner, typename Rhs>
|
|
||||||
struct solve_retval<BiCGSTAB<_MatrixType, _Preconditioner>, Rhs>
|
|
||||||
: solve_retval_base<BiCGSTAB<_MatrixType, _Preconditioner>, Rhs>
|
|
||||||
{
|
|
||||||
typedef BiCGSTAB<_MatrixType, _Preconditioner> Dec;
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec()._solve_impl(rhs(),dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_BICGSTAB_H
|
#endif // EIGEN_BICGSTAB_H
|
||||||
|
@ -192,24 +192,6 @@ public:
|
|||||||
ConjugateGradient(const MatrixType& A) : Base(A) {}
|
ConjugateGradient(const MatrixType& A) : Base(A) {}
|
||||||
|
|
||||||
~ConjugateGradient() {}
|
~ConjugateGradient() {}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A
|
|
||||||
* \a x0 as an initial solution.
|
|
||||||
*
|
|
||||||
* \sa compute()
|
|
||||||
*/
|
|
||||||
template<typename Rhs,typename Guess>
|
|
||||||
inline const internal::solve_retval_with_guess<ConjugateGradient, Rhs, Guess>
|
|
||||||
solveWithGuess(const MatrixBase<Rhs>& b, const Guess& x0) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "ConjugateGradient is not initialized.");
|
|
||||||
eigen_assert(Base::rows()==b.rows()
|
|
||||||
&& "ConjugateGradient::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::solve_retval_with_guess
|
|
||||||
<ConjugateGradient, Rhs, Guess>(*this, b.derived(), x0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \internal */
|
/** \internal */
|
||||||
template<typename Rhs,typename Dest>
|
template<typename Rhs,typename Dest>
|
||||||
@ -245,25 +227,6 @@ protected:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename _MatrixType, int _UpLo, typename _Preconditioner, typename Rhs>
|
|
||||||
struct solve_retval<ConjugateGradient<_MatrixType,_UpLo,_Preconditioner>, Rhs>
|
|
||||||
: solve_retval_base<ConjugateGradient<_MatrixType,_UpLo,_Preconditioner>, Rhs>
|
|
||||||
{
|
|
||||||
typedef ConjugateGradient<_MatrixType,_UpLo,_Preconditioner> Dec;
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec()._solve_impl(rhs(),dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_CONJUGATE_GRADIENT_H
|
#endif // EIGEN_CONJUGATE_GRADIENT_H
|
||||||
|
@ -171,17 +171,6 @@ class IncompleteLUT : public SparseSolverBase<IncompleteLUT<_Scalar> >
|
|||||||
x = m_P * x;
|
x = m_P * x;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Rhs> inline const internal::solve_retval<IncompleteLUT, Rhs>
|
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "IncompleteLUT is not initialized.");
|
|
||||||
eigen_assert(cols()==b.rows()
|
|
||||||
&& "IncompleteLUT::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::solve_retval<IncompleteLUT, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** keeps off-diagonal entries; drops diagonal entries */
|
/** keeps off-diagonal entries; drops diagonal entries */
|
||||||
@ -451,25 +440,6 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
|
|||||||
m_info = Success;
|
m_info = Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename _MatrixType, typename Rhs>
|
|
||||||
struct solve_retval<IncompleteLUT<_MatrixType>, Rhs>
|
|
||||||
: solve_retval_base<IncompleteLUT<_MatrixType>, Rhs>
|
|
||||||
{
|
|
||||||
typedef IncompleteLUT<_MatrixType> Dec;
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec()._solve_impl(rhs(),dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_INCOMPLETE_LUT_H
|
#endif // EIGEN_INCOMPLETE_LUT_H
|
||||||
|
@ -162,38 +162,6 @@ public:
|
|||||||
return m_error;
|
return m_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
|
||||||
*
|
|
||||||
* \sa compute()
|
|
||||||
*/
|
|
||||||
template<typename Rhs> inline const internal::solve_retval<Derived, Rhs>
|
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized.");
|
|
||||||
eigen_assert(rows()==b.rows()
|
|
||||||
&& "IterativeSolverBase::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::solve_retval<Derived, Rhs>(derived(), b.derived());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
|
||||||
*
|
|
||||||
* \sa compute()
|
|
||||||
*/
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::sparse_solve_retval<IterativeSolverBase, Rhs>
|
|
||||||
solve(const SparseMatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized.");
|
|
||||||
eigen_assert(rows()==b.rows()
|
|
||||||
&& "IterativeSolverBase::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::sparse_solve_retval<IterativeSolverBase, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A
|
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A
|
||||||
* and \a x0 as an initial solution.
|
* and \a x0 as an initial solution.
|
||||||
*
|
*
|
||||||
@ -207,7 +175,6 @@ public:
|
|||||||
eigen_assert(derived().rows()==b.rows() && "solve(): invalid number of rows of the right hand side matrix b");
|
eigen_assert(derived().rows()==b.rows() && "solve(): invalid number of rows of the right hand side matrix b");
|
||||||
return SolveWithGuess<Derived, Rhs, Guess>(derived(), b.derived(), x0);
|
return SolveWithGuess<Derived, Rhs, Guess>(derived(), b.derived(), x0);
|
||||||
}
|
}
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** \returns Success if the iterations converged, and NoConvergence otherwise. */
|
/** \returns Success if the iterations converged, and NoConvergence otherwise. */
|
||||||
ComputationInfo info() const
|
ComputationInfo info() const
|
||||||
@ -216,25 +183,6 @@ public:
|
|||||||
return m_info;
|
return m_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \internal */
|
|
||||||
template<typename Rhs, typename DestScalar, int DestOptions, typename DestIndex>
|
|
||||||
void _solve_sparse(const Rhs& b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const
|
|
||||||
{
|
|
||||||
eigen_assert(rows()==b.rows());
|
|
||||||
|
|
||||||
int rhsCols = b.cols();
|
|
||||||
int size = b.rows();
|
|
||||||
Eigen::Matrix<DestScalar,Dynamic,1> tb(size);
|
|
||||||
Eigen::Matrix<DestScalar,Dynamic,1> tx(size);
|
|
||||||
for(int k=0; k<rhsCols; ++k)
|
|
||||||
{
|
|
||||||
tb = b.col(k);
|
|
||||||
tx = derived().solve(tb);
|
|
||||||
dest.col(k) = tx.sparseView(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/** \internal */
|
/** \internal */
|
||||||
template<typename Rhs, typename DestScalar, int DestOptions, typename DestIndex>
|
template<typename Rhs, typename DestScalar, int DestOptions, typename DestIndex>
|
||||||
void _solve_impl(const Rhs& b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const
|
void _solve_impl(const Rhs& b, SparseMatrix<DestScalar,DestOptions,DestIndex> &dest) const
|
||||||
@ -252,7 +200,6 @@ public:
|
|||||||
dest.col(k) = tx.sparseView(0);
|
dest.col(k) = tx.sparseView(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void init()
|
void init()
|
||||||
@ -275,25 +222,6 @@ protected:
|
|||||||
mutable bool m_analysisIsOk, m_factorizationIsOk;
|
mutable bool m_analysisIsOk, m_factorizationIsOk;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename Derived, typename Rhs>
|
|
||||||
struct sparse_solve_retval<IterativeSolverBase<Derived>, Rhs>
|
|
||||||
: sparse_solve_retval_base<IterativeSolverBase<Derived>, Rhs>
|
|
||||||
{
|
|
||||||
typedef IterativeSolverBase<Derived> Dec;
|
|
||||||
EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec().derived()._solve_sparse(rhs(),dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_ITERATIVE_SOLVER_BASE_H
|
#endif // EIGEN_ITERATIVE_SOLVER_BASE_H
|
||||||
|
@ -92,11 +92,7 @@ template<typename Derived>
|
|||||||
inline typename internal::traits<Derived>::Scalar MatrixBase<Derived>::determinant() const
|
inline typename internal::traits<Derived>::Scalar MatrixBase<Derived>::determinant() const
|
||||||
{
|
{
|
||||||
eigen_assert(rows() == cols());
|
eigen_assert(rows() == cols());
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
typedef typename internal::nested_eval<Derived,Base::RowsAtCompileTime>::type Nested;
|
typedef typename internal::nested_eval<Derived,Base::RowsAtCompileTime>::type Nested;
|
||||||
#else
|
|
||||||
typedef typename internal::nested<Derived,Base::RowsAtCompileTime>::type Nested;
|
|
||||||
#endif
|
|
||||||
return internal::determinant_impl<typename internal::remove_all<Nested>::type>::run(derived());
|
return internal::determinant_impl<typename internal::remove_all<Nested>::type>::run(derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +220,6 @@ template<typename _MatrixType> class FullPivLU
|
|||||||
*
|
*
|
||||||
* \sa TriangularView::solve(), kernel(), inverse()
|
* \sa TriangularView::solve(), kernel(), inverse()
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Rhs>
|
template<typename Rhs>
|
||||||
inline const Solve<FullPivLU, Rhs>
|
inline const Solve<FullPivLU, Rhs>
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
solve(const MatrixBase<Rhs>& b) const
|
||||||
@ -228,15 +227,6 @@ template<typename _MatrixType> class FullPivLU
|
|||||||
eigen_assert(m_isInitialized && "LU is not initialized.");
|
eigen_assert(m_isInitialized && "LU is not initialized.");
|
||||||
return Solve<FullPivLU, Rhs>(*this, b.derived());
|
return Solve<FullPivLU, Rhs>(*this, b.derived());
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::solve_retval<FullPivLU, Rhs>
|
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "LU is not initialized.");
|
|
||||||
return internal::solve_retval<FullPivLU, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \returns the determinant of the matrix of which
|
/** \returns the determinant of the matrix of which
|
||||||
* *this is the LU decomposition. It has only linear complexity
|
* *this is the LU decomposition. It has only linear complexity
|
||||||
@ -380,22 +370,12 @@ template<typename _MatrixType> class FullPivLU
|
|||||||
*
|
*
|
||||||
* \sa MatrixBase::inverse()
|
* \sa MatrixBase::inverse()
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
inline const Inverse<FullPivLU> inverse() const
|
inline const Inverse<FullPivLU> inverse() const
|
||||||
{
|
{
|
||||||
eigen_assert(m_isInitialized && "LU is not initialized.");
|
eigen_assert(m_isInitialized && "LU is not initialized.");
|
||||||
eigen_assert(m_lu.rows() == m_lu.cols() && "You can't take the inverse of a non-square matrix!");
|
eigen_assert(m_lu.rows() == m_lu.cols() && "You can't take the inverse of a non-square matrix!");
|
||||||
return Inverse<FullPivLU>(*this);
|
return Inverse<FullPivLU>(*this);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
inline const internal::solve_retval<FullPivLU,typename MatrixType::IdentityReturnType> inverse() const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "LU is not initialized.");
|
|
||||||
eigen_assert(m_lu.rows() == m_lu.cols() && "You can't take the inverse of a non-square matrix!");
|
|
||||||
return internal::solve_retval<FullPivLU,typename MatrixType::IdentityReturnType>
|
|
||||||
(*this, MatrixType::Identity(m_lu.rows(), m_lu.cols()));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MatrixType reconstructedMatrix() const;
|
MatrixType reconstructedMatrix() const;
|
||||||
|
|
||||||
@ -752,22 +732,8 @@ void FullPivLU<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename _MatrixType, typename Rhs>
|
|
||||||
struct solve_retval<FullPivLU<_MatrixType>, Rhs>
|
|
||||||
: solve_retval_base<FullPivLU<_MatrixType>, Rhs>
|
|
||||||
{
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(FullPivLU<_MatrixType>,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec()._solve_impl(rhs(), dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***** Implementation of inverse() *****************************************************/
|
/***** Implementation of inverse() *****************************************************/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename DstXprType, typename MatrixType, typename Scalar>
|
template<typename DstXprType, typename MatrixType, typename Scalar>
|
||||||
struct Assignment<DstXprType, Inverse<FullPivLU<MatrixType> >, internal::assign_op<Scalar>, Dense2Dense, Scalar>
|
struct Assignment<DstXprType, Inverse<FullPivLU<MatrixType> >, internal::assign_op<Scalar>, Dense2Dense, Scalar>
|
||||||
{
|
{
|
||||||
@ -778,7 +744,6 @@ struct Assignment<DstXprType, Inverse<FullPivLU<MatrixType> >, internal::assign_
|
|||||||
dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
|
dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/******* MatrixBase methods *****************************************************************/
|
/******* MatrixBase methods *****************************************************************/
|
||||||
|
@ -43,12 +43,8 @@ struct compute_inverse<MatrixType, ResultType, 1>
|
|||||||
static inline void run(const MatrixType& matrix, ResultType& result)
|
static inline void run(const MatrixType& matrix, ResultType& result)
|
||||||
{
|
{
|
||||||
typedef typename MatrixType::Scalar Scalar;
|
typedef typename MatrixType::Scalar Scalar;
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
typename internal::evaluator<MatrixType>::type matrixEval(matrix);
|
typename internal::evaluator<MatrixType>::type matrixEval(matrix);
|
||||||
result.coeffRef(0,0) = Scalar(1) / matrixEval.coeff(0,0);
|
result.coeffRef(0,0) = Scalar(1) / matrixEval.coeff(0,0);
|
||||||
#else
|
|
||||||
result.coeffRef(0,0) = Scalar(1) / matrix.coeff(0,0);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -285,46 +281,8 @@ struct compute_inverse_and_det_with_check<MatrixType, ResultType, 4>
|
|||||||
*** MatrixBase methods ***
|
*** MatrixBase methods ***
|
||||||
*************************/
|
*************************/
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename MatrixType>
|
|
||||||
struct traits<inverse_impl<MatrixType> >
|
|
||||||
{
|
|
||||||
typedef typename MatrixType::PlainObject ReturnType;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename MatrixType>
|
|
||||||
struct inverse_impl : public ReturnByValue<inverse_impl<MatrixType> >
|
|
||||||
{
|
|
||||||
typedef typename MatrixType::Index Index;
|
|
||||||
typedef typename internal::eval<MatrixType>::type MatrixTypeNested;
|
|
||||||
typedef typename remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned;
|
|
||||||
MatrixTypeNested m_matrix;
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inverse_impl(const MatrixType& matrix)
|
|
||||||
: m_matrix(matrix)
|
|
||||||
{}
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.rows(); }
|
|
||||||
EIGEN_DEVICE_FUNC inline Index cols() const { return m_matrix.cols(); }
|
|
||||||
|
|
||||||
template<typename Dest>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
inline void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
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)))
|
|
||||||
&& "Aliasing problem detected in inverse(), you need to do inverse().eval() here.");
|
|
||||||
|
|
||||||
compute_inverse<MatrixTypeNestedCleaned, Dest>::run(m_matrix, dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// Specialization for "dense = dense_xpr.inverse()"
|
// Specialization for "dense = dense_xpr.inverse()"
|
||||||
@ -352,8 +310,6 @@ struct Assignment<DstXprType, Inverse<XprType>, internal::assign_op<Scalar>, Den
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \lu_module
|
/** \lu_module
|
||||||
*
|
*
|
||||||
* \returns the matrix inverse of this matrix.
|
* \returns the matrix inverse of this matrix.
|
||||||
@ -371,7 +327,6 @@ struct Assignment<DstXprType, Inverse<XprType>, internal::assign_op<Scalar>, Den
|
|||||||
*
|
*
|
||||||
* \sa computeInverseAndDetWithCheck()
|
* \sa computeInverseAndDetWithCheck()
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline const Inverse<Derived> MatrixBase<Derived>::inverse() const
|
inline const Inverse<Derived> MatrixBase<Derived>::inverse() const
|
||||||
{
|
{
|
||||||
@ -379,15 +334,6 @@ inline const Inverse<Derived> MatrixBase<Derived>::inverse() const
|
|||||||
eigen_assert(rows() == cols());
|
eigen_assert(rows() == cols());
|
||||||
return Inverse<Derived>(derived());
|
return Inverse<Derived>(derived());
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
template<typename Derived>
|
|
||||||
inline const internal::inverse_impl<Derived> MatrixBase<Derived>::inverse() const
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsInteger,THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES)
|
|
||||||
eigen_assert(rows() == cols());
|
|
||||||
return internal::inverse_impl<Derived>(derived());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \lu_module
|
/** \lu_module
|
||||||
*
|
*
|
||||||
@ -422,11 +368,7 @@ inline void MatrixBase<Derived>::computeInverseAndDetWithCheck(
|
|||||||
// for larger sizes, evaluating has negligible cost and limits code size.
|
// for larger sizes, evaluating has negligible cost and limits code size.
|
||||||
typedef typename internal::conditional<
|
typedef typename internal::conditional<
|
||||||
RowsAtCompileTime == 2,
|
RowsAtCompileTime == 2,
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
typename internal::remove_all<typename internal::nested<Derived, 2>::type>::type,
|
|
||||||
#else
|
|
||||||
typename internal::remove_all<typename internal::nested_eval<Derived, 2>::type>::type,
|
typename internal::remove_all<typename internal::nested_eval<Derived, 2>::type>::type,
|
||||||
#endif
|
|
||||||
PlainObject
|
PlainObject
|
||||||
>::type MatrixType;
|
>::type MatrixType;
|
||||||
internal::compute_inverse_and_det_with_check<MatrixType, ResultType>::run
|
internal::compute_inverse_and_det_with_check<MatrixType, ResultType>::run
|
||||||
|
@ -142,7 +142,6 @@ template<typename _MatrixType> class PartialPivLU
|
|||||||
*
|
*
|
||||||
* \sa TriangularView::solve(), inverse(), computeInverse()
|
* \sa TriangularView::solve(), inverse(), computeInverse()
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Rhs>
|
template<typename Rhs>
|
||||||
inline const Solve<PartialPivLU, Rhs>
|
inline const Solve<PartialPivLU, Rhs>
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
solve(const MatrixBase<Rhs>& b) const
|
||||||
@ -150,15 +149,6 @@ template<typename _MatrixType> class PartialPivLU
|
|||||||
eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
|
eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
|
||||||
return Solve<PartialPivLU, Rhs>(*this, b.derived());
|
return Solve<PartialPivLU, Rhs>(*this, b.derived());
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::solve_retval<PartialPivLU, Rhs>
|
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
|
|
||||||
return internal::solve_retval<PartialPivLU, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \returns the inverse of the matrix of which *this is the LU decomposition.
|
/** \returns the inverse of the matrix of which *this is the LU decomposition.
|
||||||
*
|
*
|
||||||
@ -167,20 +157,11 @@ template<typename _MatrixType> class PartialPivLU
|
|||||||
*
|
*
|
||||||
* \sa MatrixBase::inverse(), LU::inverse()
|
* \sa MatrixBase::inverse(), LU::inverse()
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
inline const Inverse<PartialPivLU> inverse() const
|
inline const Inverse<PartialPivLU> inverse() const
|
||||||
{
|
{
|
||||||
eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
|
eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
|
||||||
return Inverse<PartialPivLU>(*this);
|
return Inverse<PartialPivLU>(*this);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
inline const internal::solve_retval<PartialPivLU,typename MatrixType::IdentityReturnType> inverse() const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
|
|
||||||
return internal::solve_retval<PartialPivLU,typename MatrixType::IdentityReturnType>
|
|
||||||
(*this, MatrixType::Identity(m_lu.rows(), m_lu.cols()));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \returns the determinant of the matrix of which
|
/** \returns the determinant of the matrix of which
|
||||||
* *this is the LU decomposition. It has only linear complexity
|
* *this is the LU decomposition. It has only linear complexity
|
||||||
@ -490,22 +471,7 @@ MatrixType PartialPivLU<MatrixType>::reconstructedMatrix() const
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename _MatrixType, typename Rhs>
|
|
||||||
struct solve_retval<PartialPivLU<_MatrixType>, Rhs>
|
|
||||||
: solve_retval_base<PartialPivLU<_MatrixType>, Rhs>
|
|
||||||
{
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(PartialPivLU<_MatrixType>,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec()._solve_impl(rhs(), dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/***** Implementation of inverse() *****************************************************/
|
/***** Implementation of inverse() *****************************************************/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename DstXprType, typename MatrixType, typename Scalar>
|
template<typename DstXprType, typename MatrixType, typename Scalar>
|
||||||
struct Assignment<DstXprType, Inverse<PartialPivLU<MatrixType> >, internal::assign_op<Scalar>, Dense2Dense, Scalar>
|
struct Assignment<DstXprType, Inverse<PartialPivLU<MatrixType> >, internal::assign_op<Scalar>, Dense2Dense, Scalar>
|
||||||
{
|
{
|
||||||
@ -516,7 +482,6 @@ struct Assignment<DstXprType, Inverse<PartialPivLU<MatrixType> >, internal::assi
|
|||||||
dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
|
dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
/******** MatrixBase methods *******/
|
/******** MatrixBase methods *******/
|
||||||
|
@ -153,22 +153,6 @@ class PastixBase : public SparseSolverBase<Derived>
|
|||||||
{
|
{
|
||||||
clean();
|
clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
|
||||||
*
|
|
||||||
* \sa compute()
|
|
||||||
*/
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::solve_retval<PastixBase, Rhs>
|
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "Pastix solver is not initialized.");
|
|
||||||
eigen_assert(rows()==b.rows()
|
|
||||||
&& "PastixBase::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::solve_retval<PastixBase, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename Rhs,typename Dest>
|
template<typename Rhs,typename Dest>
|
||||||
bool _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &x) const;
|
bool _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &x) const;
|
||||||
@ -227,22 +211,6 @@ class PastixBase : public SparseSolverBase<Derived>
|
|||||||
return m_info;
|
return m_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
|
||||||
*
|
|
||||||
* \sa compute()
|
|
||||||
*/
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::sparse_solve_retval<PastixBase, Rhs>
|
|
||||||
solve(const SparseMatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "Pastix LU, LLT or LDLT is not initialized.");
|
|
||||||
eigen_assert(rows()==b.rows()
|
|
||||||
&& "PastixBase::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::sparse_solve_retval<PastixBase, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Initialize the Pastix data structure, check the matrix
|
// Initialize the Pastix data structure, check the matrix
|
||||||
@ -693,38 +661,6 @@ class PastixLDLT : public PastixBase< PastixLDLT<_MatrixType, _UpLo> >
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename _MatrixType, typename Rhs>
|
|
||||||
struct solve_retval<PastixBase<_MatrixType>, Rhs>
|
|
||||||
: solve_retval_base<PastixBase<_MatrixType>, Rhs>
|
|
||||||
{
|
|
||||||
typedef PastixBase<_MatrixType> Dec;
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec()._solve_impl(rhs(),dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename _MatrixType, typename Rhs>
|
|
||||||
struct sparse_solve_retval<PastixBase<_MatrixType>, Rhs>
|
|
||||||
: sparse_solve_retval_base<PastixBase<_MatrixType>, Rhs>
|
|
||||||
{
|
|
||||||
typedef PastixBase<_MatrixType> Dec;
|
|
||||||
EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
this->defaultEvalTo(dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -172,36 +172,6 @@ class PardisoImpl : public SparseSolveBase<PardisoImpl<Derived>
|
|||||||
Derived& factorize(const MatrixType& matrix);
|
Derived& factorize(const MatrixType& matrix);
|
||||||
|
|
||||||
Derived& compute(const MatrixType& matrix);
|
Derived& compute(const MatrixType& matrix);
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
|
||||||
*
|
|
||||||
* \sa compute()
|
|
||||||
*/
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::solve_retval<PardisoImpl, Rhs>
|
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "Pardiso solver is not initialized.");
|
|
||||||
eigen_assert(rows()==b.rows()
|
|
||||||
&& "PardisoImpl::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::solve_retval<PardisoImpl, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
|
||||||
*
|
|
||||||
* \sa compute()
|
|
||||||
*/
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::sparse_solve_retval<PardisoImpl, Rhs>
|
|
||||||
solve(const SparseMatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "Pardiso solver is not initialized.");
|
|
||||||
eigen_assert(rows()==b.rows()
|
|
||||||
&& "PardisoImpl::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::sparse_solve_retval<PardisoImpl, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename BDerived, typename XDerived>
|
template<typename BDerived, typename XDerived>
|
||||||
bool _solve_impl(const MatrixBase<BDerived> &b, MatrixBase<XDerived>& x) const;
|
bool _solve_impl(const MatrixBase<BDerived> &b, MatrixBase<XDerived>& x) const;
|
||||||
@ -546,38 +516,6 @@ class PardisoLDLT : public PardisoImpl< PardisoLDLT<MatrixType,Options> >
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename _Derived, typename Rhs>
|
|
||||||
struct solve_retval<PardisoImpl<_Derived>, Rhs>
|
|
||||||
: solve_retval_base<PardisoImpl<_Derived>, Rhs>
|
|
||||||
{
|
|
||||||
typedef PardisoImpl<_Derived> Dec;
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec()._solve_impl(rhs(),dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived, typename Rhs>
|
|
||||||
struct sparse_solve_retval<PardisoImpl<Derived>, Rhs>
|
|
||||||
: sparse_solve_retval_base<PardisoImpl<Derived>, Rhs>
|
|
||||||
{
|
|
||||||
typedef PardisoImpl<Derived> Dec;
|
|
||||||
EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
this->defaultEvalTo(dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_PARDISOSUPPORT_H
|
#endif // EIGEN_PARDISOSUPPORT_H
|
||||||
|
@ -147,7 +147,6 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||||||
* Example: \include ColPivHouseholderQR_solve.cpp
|
* Example: \include ColPivHouseholderQR_solve.cpp
|
||||||
* Output: \verbinclude ColPivHouseholderQR_solve.out
|
* Output: \verbinclude ColPivHouseholderQR_solve.out
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Rhs>
|
template<typename Rhs>
|
||||||
inline const Solve<ColPivHouseholderQR, Rhs>
|
inline const Solve<ColPivHouseholderQR, Rhs>
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
solve(const MatrixBase<Rhs>& b) const
|
||||||
@ -155,15 +154,6 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||||||
eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
||||||
return Solve<ColPivHouseholderQR, Rhs>(*this, b.derived());
|
return Solve<ColPivHouseholderQR, Rhs>(*this, b.derived());
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::solve_retval<ColPivHouseholderQR, Rhs>
|
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
|
||||||
return internal::solve_retval<ColPivHouseholderQR, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
HouseholderSequenceType householderQ() const;
|
HouseholderSequenceType householderQ() const;
|
||||||
HouseholderSequenceType matrixQ() const
|
HouseholderSequenceType matrixQ() const
|
||||||
@ -304,22 +294,11 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||||||
* \note If this matrix is not invertible, the returned matrix has undefined coefficients.
|
* \note If this matrix is not invertible, the returned matrix has undefined coefficients.
|
||||||
* Use isInvertible() to first determine whether this matrix is invertible.
|
* Use isInvertible() to first determine whether this matrix is invertible.
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
inline const Inverse<ColPivHouseholderQR> inverse() const
|
inline const Inverse<ColPivHouseholderQR> inverse() const
|
||||||
{
|
{
|
||||||
eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
||||||
return Inverse<ColPivHouseholderQR>(*this);
|
return Inverse<ColPivHouseholderQR>(*this);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
inline const
|
|
||||||
internal::solve_retval<ColPivHouseholderQR, typename MatrixType::IdentityReturnType>
|
|
||||||
inverse() const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
|
||||||
return internal::solve_retval<ColPivHouseholderQR,typename MatrixType::IdentityReturnType>
|
|
||||||
(*this, MatrixType::Identity(m_qr.rows(), m_qr.cols()));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline Index rows() const { return m_qr.rows(); }
|
inline Index rows() const { return m_qr.rows(); }
|
||||||
inline Index cols() const { return m_qr.cols(); }
|
inline Index cols() const { return m_qr.cols(); }
|
||||||
@ -582,21 +561,6 @@ void ColPivHouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename _MatrixType, typename Rhs>
|
|
||||||
struct solve_retval<ColPivHouseholderQR<_MatrixType>, Rhs>
|
|
||||||
: solve_retval_base<ColPivHouseholderQR<_MatrixType>, Rhs>
|
|
||||||
{
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(ColPivHouseholderQR<_MatrixType>,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec()._solve_impl(rhs(), dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename DstXprType, typename MatrixType, typename Scalar>
|
template<typename DstXprType, typename MatrixType, typename Scalar>
|
||||||
struct Assignment<DstXprType, Inverse<ColPivHouseholderQR<MatrixType> >, internal::assign_op<Scalar>, Dense2Dense, Scalar>
|
struct Assignment<DstXprType, Inverse<ColPivHouseholderQR<MatrixType> >, internal::assign_op<Scalar>, Dense2Dense, Scalar>
|
||||||
{
|
{
|
||||||
@ -607,7 +571,6 @@ struct Assignment<DstXprType, Inverse<ColPivHouseholderQR<MatrixType> >, interna
|
|||||||
dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
|
dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
|
@ -151,7 +151,6 @@ template<typename _MatrixType> class FullPivHouseholderQR
|
|||||||
* Example: \include FullPivHouseholderQR_solve.cpp
|
* Example: \include FullPivHouseholderQR_solve.cpp
|
||||||
* Output: \verbinclude FullPivHouseholderQR_solve.out
|
* Output: \verbinclude FullPivHouseholderQR_solve.out
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Rhs>
|
template<typename Rhs>
|
||||||
inline const Solve<FullPivHouseholderQR, Rhs>
|
inline const Solve<FullPivHouseholderQR, Rhs>
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
solve(const MatrixBase<Rhs>& b) const
|
||||||
@ -159,15 +158,6 @@ template<typename _MatrixType> class FullPivHouseholderQR
|
|||||||
eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
|
eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
|
||||||
return Solve<FullPivHouseholderQR, Rhs>(*this, b.derived());
|
return Solve<FullPivHouseholderQR, Rhs>(*this, b.derived());
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::solve_retval<FullPivHouseholderQR, Rhs>
|
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
|
|
||||||
return internal::solve_retval<FullPivHouseholderQR, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \returns Expression object representing the matrix Q
|
/** \returns Expression object representing the matrix Q
|
||||||
*/
|
*/
|
||||||
@ -298,22 +288,11 @@ template<typename _MatrixType> class FullPivHouseholderQR
|
|||||||
* \note If this matrix is not invertible, the returned matrix has undefined coefficients.
|
* \note If this matrix is not invertible, the returned matrix has undefined coefficients.
|
||||||
* Use isInvertible() to first determine whether this matrix is invertible.
|
* Use isInvertible() to first determine whether this matrix is invertible.
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
inline const Inverse<FullPivHouseholderQR> inverse() const
|
inline const Inverse<FullPivHouseholderQR> inverse() const
|
||||||
{
|
{
|
||||||
eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
|
eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
|
||||||
return Inverse<FullPivHouseholderQR>(*this);
|
return Inverse<FullPivHouseholderQR>(*this);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
inline const
|
|
||||||
internal::solve_retval<FullPivHouseholderQR, typename MatrixType::IdentityReturnType>
|
|
||||||
inverse() const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
|
|
||||||
return internal::solve_retval<FullPivHouseholderQR,typename MatrixType::IdentityReturnType>
|
|
||||||
(*this, MatrixType::Identity(m_qr.rows(), m_qr.cols()));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline Index rows() const { return m_qr.rows(); }
|
inline Index rows() const { return m_qr.rows(); }
|
||||||
inline Index cols() const { return m_qr.cols(); }
|
inline Index cols() const { return m_qr.cols(); }
|
||||||
@ -556,21 +535,6 @@ void FullPivHouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename _MatrixType, typename Rhs>
|
|
||||||
struct solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs>
|
|
||||||
: solve_retval_base<FullPivHouseholderQR<_MatrixType>, Rhs>
|
|
||||||
{
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(FullPivHouseholderQR<_MatrixType>,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec()._solve_impl(rhs(), dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename DstXprType, typename MatrixType, typename Scalar>
|
template<typename DstXprType, typename MatrixType, typename Scalar>
|
||||||
struct Assignment<DstXprType, Inverse<FullPivHouseholderQR<MatrixType> >, internal::assign_op<Scalar>, Dense2Dense, Scalar>
|
struct Assignment<DstXprType, Inverse<FullPivHouseholderQR<MatrixType> >, internal::assign_op<Scalar>, Dense2Dense, Scalar>
|
||||||
{
|
{
|
||||||
@ -581,7 +545,6 @@ struct Assignment<DstXprType, Inverse<FullPivHouseholderQR<MatrixType> >, intern
|
|||||||
dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
|
dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
/** \ingroup QR_Module
|
/** \ingroup QR_Module
|
||||||
*
|
*
|
||||||
@ -589,7 +552,6 @@ struct Assignment<DstXprType, Inverse<FullPivHouseholderQR<MatrixType> >, intern
|
|||||||
*
|
*
|
||||||
* \tparam MatrixType type of underlying dense matrix
|
* \tparam MatrixType type of underlying dense matrix
|
||||||
*/
|
*/
|
||||||
// #ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename MatrixType> struct FullPivHouseholderQRMatrixQReturnType
|
template<typename MatrixType> struct FullPivHouseholderQRMatrixQReturnType
|
||||||
: public ReturnByValue<FullPivHouseholderQRMatrixQReturnType<MatrixType> >
|
: public ReturnByValue<FullPivHouseholderQRMatrixQReturnType<MatrixType> >
|
||||||
{
|
{
|
||||||
@ -645,12 +607,10 @@ protected:
|
|||||||
typename IntDiagSizeVectorType::Nested m_rowsTranspositions;
|
typename IntDiagSizeVectorType::Nested m_rowsTranspositions;
|
||||||
};
|
};
|
||||||
|
|
||||||
// #ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
// template<typename MatrixType>
|
// template<typename MatrixType>
|
||||||
// struct evaluator<FullPivHouseholderQRMatrixQReturnType<MatrixType> >
|
// struct evaluator<FullPivHouseholderQRMatrixQReturnType<MatrixType> >
|
||||||
// : public evaluator<ReturnByValue<FullPivHouseholderQRMatrixQReturnType<MatrixType> > >
|
// : public evaluator<ReturnByValue<FullPivHouseholderQRMatrixQReturnType<MatrixType> > >
|
||||||
// {};
|
// {};
|
||||||
// #endif
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
|
@ -117,7 +117,6 @@ template<typename _MatrixType> class HouseholderQR
|
|||||||
* Example: \include HouseholderQR_solve.cpp
|
* Example: \include HouseholderQR_solve.cpp
|
||||||
* Output: \verbinclude HouseholderQR_solve.out
|
* Output: \verbinclude HouseholderQR_solve.out
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Rhs>
|
template<typename Rhs>
|
||||||
inline const Solve<HouseholderQR, Rhs>
|
inline const Solve<HouseholderQR, Rhs>
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
solve(const MatrixBase<Rhs>& b) const
|
||||||
@ -125,15 +124,6 @@ template<typename _MatrixType> class HouseholderQR
|
|||||||
eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
|
eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
|
||||||
return Solve<HouseholderQR, Rhs>(*this, b.derived());
|
return Solve<HouseholderQR, Rhs>(*this, b.derived());
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::solve_retval<HouseholderQR, Rhs>
|
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
|
|
||||||
return internal::solve_retval<HouseholderQR, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** This method returns an expression of the unitary matrix Q as a sequence of Householder transformations.
|
/** This method returns an expression of the unitary matrix Q as a sequence of Householder transformations.
|
||||||
*
|
*
|
||||||
@ -351,24 +341,6 @@ void HouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) c
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename _MatrixType, typename Rhs>
|
|
||||||
struct solve_retval<HouseholderQR<_MatrixType>, Rhs>
|
|
||||||
: solve_retval_base<HouseholderQR<_MatrixType>, Rhs>
|
|
||||||
{
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(HouseholderQR<_MatrixType>,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec()._solve_impl(rhs(), dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** Performs the QR factorization of the given matrix \a matrix. The result of
|
/** Performs the QR factorization of the given matrix \a matrix. The result of
|
||||||
* the factorization is stored into \c *this, and a reference to \c *this
|
* the factorization is stored into \c *this, and a reference to \c *this
|
||||||
* is returned.
|
* is returned.
|
||||||
|
@ -124,21 +124,6 @@ class SPQR : public SparseSolverBase<SPQR<_MatrixType> >
|
|||||||
* Get the number of columns of the input matrix.
|
* Get the number of columns of the input matrix.
|
||||||
*/
|
*/
|
||||||
inline Index cols() const { return m_cR->ncol; }
|
inline Index cols() const { return m_cR->ncol; }
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \returns the solution X of \f$ A X = B \f$ using the current decomposition of A.
|
|
||||||
*
|
|
||||||
* \sa compute()
|
|
||||||
*/
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::solve_retval<SPQR, Rhs> solve(const MatrixBase<Rhs>& B) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && " The QR factorization should be computed first, call compute()");
|
|
||||||
eigen_assert(this->rows()==B.rows()
|
|
||||||
&& "SPQR::solve(): invalid number of rows of the right hand side matrix B");
|
|
||||||
return internal::solve_retval<SPQR, Rhs>(*this, B.derived());
|
|
||||||
}
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
template<typename Rhs, typename Dest>
|
template<typename Rhs, typename Dest>
|
||||||
void _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
|
void _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
|
||||||
@ -292,24 +277,5 @@ struct SPQRMatrixQTransposeReturnType{
|
|||||||
const SPQRType& m_spqr;
|
const SPQRType& m_spqr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename _MatrixType, typename Rhs>
|
|
||||||
struct solve_retval<SPQR<_MatrixType>, Rhs>
|
|
||||||
: solve_retval_base<SPQR<_MatrixType>, Rhs>
|
|
||||||
{
|
|
||||||
typedef SPQR<_MatrixType> Dec;
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec()._solve_impl(rhs(),dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}// End namespace Eigen
|
}// End namespace Eigen
|
||||||
#endif
|
#endif
|
||||||
|
@ -200,7 +200,6 @@ public:
|
|||||||
* \note SVD solving is implicitly least-squares. Thus, this method serves both purposes of exact solving and least-squares solving.
|
* \note SVD solving is implicitly least-squares. Thus, this method serves both purposes of exact solving and least-squares solving.
|
||||||
* In other words, the returned solution is guaranteed to minimize the Euclidean norm \f$ \Vert A x - b \Vert \f$.
|
* In other words, the returned solution is guaranteed to minimize the Euclidean norm \f$ \Vert A x - b \Vert \f$.
|
||||||
*/
|
*/
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Rhs>
|
template<typename Rhs>
|
||||||
inline const Solve<Derived, Rhs>
|
inline const Solve<Derived, Rhs>
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
solve(const MatrixBase<Rhs>& b) const
|
||||||
@ -209,16 +208,6 @@ public:
|
|||||||
eigen_assert(computeU() && computeV() && "SVD::solve() requires both unitaries U and V to be computed (thin unitaries suffice).");
|
eigen_assert(computeU() && computeV() && "SVD::solve() requires both unitaries U and V to be computed (thin unitaries suffice).");
|
||||||
return Solve<Derived, Rhs>(derived(), b.derived());
|
return Solve<Derived, Rhs>(derived(), b.derived());
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::solve_retval<SVDBase, Rhs>
|
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "SVD is not initialized.");
|
|
||||||
eigen_assert(computeU() && computeV() && "SVD::solve() requires both unitaries U and V to be computed (thin unitaries suffice).");
|
|
||||||
return internal::solve_retval<SVDBase, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template<typename RhsType, typename DstType>
|
template<typename RhsType, typename DstType>
|
||||||
@ -273,23 +262,6 @@ void SVDBase<Derived>::_solve_impl(const RhsType &rhs, DstType &dst) const
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Derived, typename Rhs>
|
|
||||||
struct solve_retval<SVDBase<Derived>, Rhs>
|
|
||||||
: solve_retval_base<SVDBase<Derived>, Rhs>
|
|
||||||
{
|
|
||||||
typedef SVDBase<Derived> SVDType;
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(SVDType,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec().derived()._solve_impl(rhs(), dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
bool SVDBase<MatrixType>::allocate(Index rows, Index cols, unsigned int computationOptions)
|
bool SVDBase<MatrixType>::allocate(Index rows, Index cols, unsigned int computationOptions)
|
||||||
{
|
{
|
||||||
|
@ -84,36 +84,6 @@ class SimplicialCholeskyBase : public SparseSolverBase<Derived>
|
|||||||
return m_info;
|
return m_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
|
||||||
*
|
|
||||||
* \sa compute()
|
|
||||||
*/
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::solve_retval<SimplicialCholeskyBase, Rhs>
|
|
||||||
solve(const MatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "Simplicial LLT or LDLT is not initialized.");
|
|
||||||
eigen_assert(rows()==b.rows()
|
|
||||||
&& "SimplicialCholeskyBase::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::solve_retval<SimplicialCholeskyBase, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
|
||||||
*
|
|
||||||
* \sa compute()
|
|
||||||
*/
|
|
||||||
template<typename Rhs>
|
|
||||||
inline const internal::sparse_solve_retval<SimplicialCholeskyBase, Rhs>
|
|
||||||
solve(const SparseMatrixBase<Rhs>& b) const
|
|
||||||
{
|
|
||||||
eigen_assert(m_isInitialized && "Simplicial LLT or LDLT is not initialized.");
|
|
||||||
eigen_assert(rows()==b.rows()
|
|
||||||
&& "SimplicialCholesky::solve(): invalid number of rows of the right hand side matrix b");
|
|
||||||
return internal::sparse_solve_retval<SimplicialCholeskyBase, Rhs>(*this, b.derived());
|
|
||||||
}
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
/** \returns the permutation P
|
/** \returns the permutation P
|
||||||
* \sa permutationPinv() */
|
* \sa permutationPinv() */
|
||||||
const PermutationMatrix<Dynamic,Dynamic,Index>& permutationP() const
|
const PermutationMatrix<Dynamic,Dynamic,Index>& permutationP() const
|
||||||
@ -157,11 +127,7 @@ class SimplicialCholeskyBase : public SparseSolverBase<Derived>
|
|||||||
|
|
||||||
/** \internal */
|
/** \internal */
|
||||||
template<typename Rhs,typename Dest>
|
template<typename Rhs,typename Dest>
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
void _solve(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
|
|
||||||
#else
|
|
||||||
void _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
|
void _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
|
eigen_assert(m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
|
||||||
eigen_assert(m_matrix.rows()==b.rows());
|
eigen_assert(m_matrix.rows()==b.rows());
|
||||||
@ -186,14 +152,12 @@ class SimplicialCholeskyBase : public SparseSolverBase<Derived>
|
|||||||
if(m_P.size()>0)
|
if(m_P.size()>0)
|
||||||
dest = m_Pinv * dest;
|
dest = m_Pinv * dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Rhs,typename Dest>
|
template<typename Rhs,typename Dest>
|
||||||
void _solve_impl(const SparseMatrixBase<Rhs> &b, SparseMatrixBase<Dest> &dest) const
|
void _solve_impl(const SparseMatrixBase<Rhs> &b, SparseMatrixBase<Dest> &dest) const
|
||||||
{
|
{
|
||||||
internal::solve_sparse_through_dense_panels(derived(), b, dest);
|
internal::solve_sparse_through_dense_panels(derived(), b, dest);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // EIGEN_PARSED_BY_DOXYGEN
|
#endif // EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
|
||||||
@ -578,11 +542,7 @@ public:
|
|||||||
|
|
||||||
/** \internal */
|
/** \internal */
|
||||||
template<typename Rhs,typename Dest>
|
template<typename Rhs,typename Dest>
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
void _solve(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
|
|
||||||
#else
|
|
||||||
void _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
|
void _solve_impl(const MatrixBase<Rhs> &b, MatrixBase<Dest> &dest) const
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
eigen_assert(Base::m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
|
eigen_assert(Base::m_factorizationIsOk && "The decomposition is not in a valid state for solving, you must first call either compute() or symbolic()/numeric()");
|
||||||
eigen_assert(Base::m_matrix.rows()==b.rows());
|
eigen_assert(Base::m_matrix.rows()==b.rows());
|
||||||
@ -618,14 +578,12 @@ public:
|
|||||||
dest = Base::m_Pinv * dest;
|
dest = Base::m_Pinv * dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
/** \internal */
|
/** \internal */
|
||||||
template<typename Rhs,typename Dest>
|
template<typename Rhs,typename Dest>
|
||||||
void _solve_impl(const SparseMatrixBase<Rhs> &b, SparseMatrixBase<Dest> &dest) const
|
void _solve_impl(const SparseMatrixBase<Rhs> &b, SparseMatrixBase<Dest> &dest) const
|
||||||
{
|
{
|
||||||
internal::solve_sparse_through_dense_panels(*this, b, dest);
|
internal::solve_sparse_through_dense_panels(*this, b, dest);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
Scalar determinant() const
|
Scalar determinant() const
|
||||||
{
|
{
|
||||||
@ -667,38 +625,6 @@ void SimplicialCholeskyBase<Derived>::ordering(const MatrixType& a, CholMatrixTy
|
|||||||
ap.template selfadjointView<Upper>() = a.template selfadjointView<UpLo>().twistedBy(m_P);
|
ap.template selfadjointView<Upper>() = a.template selfadjointView<UpLo>().twistedBy(m_P);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename Derived, typename Rhs>
|
|
||||||
struct solve_retval<SimplicialCholeskyBase<Derived>, Rhs>
|
|
||||||
: solve_retval_base<SimplicialCholeskyBase<Derived>, Rhs>
|
|
||||||
{
|
|
||||||
typedef SimplicialCholeskyBase<Derived> Dec;
|
|
||||||
EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
dec().derived()._solve(rhs(),dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Derived, typename Rhs>
|
|
||||||
struct sparse_solve_retval<SimplicialCholeskyBase<Derived>, Rhs>
|
|
||||||
: sparse_solve_retval_base<SimplicialCholeskyBase<Derived>, Rhs>
|
|
||||||
{
|
|
||||||
typedef SimplicialCholeskyBase<Derived> Dec;
|
|
||||||
EIGEN_MAKE_SPARSE_SOLVE_HELPERS(Dec,Rhs)
|
|
||||||
|
|
||||||
template<typename Dest> void evalTo(Dest& dst) const
|
|
||||||
{
|
|
||||||
this->defaultEvalTo(dst);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_SIMPLICIAL_CHOLESKY_H
|
#endif // EIGEN_SIMPLICIAL_CHOLESKY_H
|
||||||
|
@ -39,10 +39,8 @@ static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& r
|
|||||||
// Therefore, we have nnz(lhs*rhs) = nnz(lhs) + nnz(rhs)
|
// Therefore, we have nnz(lhs*rhs) = nnz(lhs) + nnz(rhs)
|
||||||
Index estimated_nnz_prod = lhs.nonZeros() + rhs.nonZeros();
|
Index estimated_nnz_prod = lhs.nonZeros() + rhs.nonZeros();
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
typename evaluator<Lhs>::type lhsEval(lhs);
|
typename evaluator<Lhs>::type lhsEval(lhs);
|
||||||
typename evaluator<Rhs>::type rhsEval(rhs);
|
typename evaluator<Rhs>::type rhsEval(rhs);
|
||||||
#endif
|
|
||||||
|
|
||||||
res.setZero();
|
res.setZero();
|
||||||
res.reserve(Index(estimated_nnz_prod));
|
res.reserve(Index(estimated_nnz_prod));
|
||||||
@ -52,19 +50,11 @@ static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& r
|
|||||||
|
|
||||||
res.startVec(j);
|
res.startVec(j);
|
||||||
Index nnz = 0;
|
Index nnz = 0;
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
for (typename Rhs::InnerIterator rhsIt(rhs, j); rhsIt; ++rhsIt)
|
|
||||||
#else
|
|
||||||
for (typename evaluator<Rhs>::InnerIterator rhsIt(rhsEval, j); rhsIt; ++rhsIt)
|
for (typename evaluator<Rhs>::InnerIterator rhsIt(rhsEval, j); rhsIt; ++rhsIt)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
Scalar y = rhsIt.value();
|
Scalar y = rhsIt.value();
|
||||||
Index k = rhsIt.index();
|
Index k = rhsIt.index();
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
for (typename Lhs::InnerIterator lhsIt(lhs, k); lhsIt; ++lhsIt)
|
|
||||||
#else
|
|
||||||
for (typename evaluator<Lhs>::InnerIterator lhsIt(lhsEval, k); lhsIt; ++lhsIt)
|
for (typename evaluator<Lhs>::InnerIterator lhsIt(lhsEval, k); lhsIt; ++lhsIt)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
Index i = lhsIt.index();
|
Index i = lhsIt.index();
|
||||||
Scalar x = lhsIt.value();
|
Scalar x = lhsIt.value();
|
||||||
|
@ -176,7 +176,6 @@ class MappedSparseMatrix<Scalar,_Flags,_Index>::ReverseInnerIterator
|
|||||||
const Index m_end;
|
const Index m_end;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<typename _Scalar, int _Options, typename _Index>
|
template<typename _Scalar, int _Options, typename _Index>
|
||||||
@ -202,7 +201,6 @@ struct evaluator<MappedSparseMatrix<_Scalar,_Options,_Index> >
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
@ -12,117 +12,6 @@
|
|||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
Derived& SparseMatrixBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
|
|
||||||
{
|
|
||||||
other.derived().evalTo(derived());
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
Derived& SparseMatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
other.evalTo(derived());
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
inline Derived& SparseMatrixBase<Derived>::operator=(const SparseMatrixBase<OtherDerived>& other)
|
|
||||||
{
|
|
||||||
return assign(other.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
inline Derived& SparseMatrixBase<Derived>::operator=(const Derived& other)
|
|
||||||
{
|
|
||||||
// if (other.isRValue())
|
|
||||||
// derived().swap(other.const_cast_derived());
|
|
||||||
// else
|
|
||||||
return assign(other.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
inline Derived& SparseMatrixBase<Derived>::assign(const OtherDerived& other)
|
|
||||||
{
|
|
||||||
const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
|
|
||||||
const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? Index(other.rows()) : Index(other.cols());
|
|
||||||
if ((!transpose) && other.isRValue())
|
|
||||||
{
|
|
||||||
// eval without temporary
|
|
||||||
derived().resize(Index(other.rows()), Index(other.cols()));
|
|
||||||
derived().setZero();
|
|
||||||
derived().reserve((std::max)(this->rows(),this->cols())*2);
|
|
||||||
for (Index j=0; j<outerSize; ++j)
|
|
||||||
{
|
|
||||||
derived().startVec(j);
|
|
||||||
for (typename OtherDerived::InnerIterator it(other, typename OtherDerived::Index(j)); it; ++it)
|
|
||||||
{
|
|
||||||
Scalar v = it.value();
|
|
||||||
derived().insertBackByOuterInner(j,Index(it.index())) = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
derived().finalize();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assignGeneric(other);
|
|
||||||
}
|
|
||||||
return derived();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
template<typename OtherDerived>
|
|
||||||
inline void SparseMatrixBase<Derived>::assignGeneric(const OtherDerived& other)
|
|
||||||
{
|
|
||||||
//const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
|
|
||||||
eigen_assert(( ((internal::traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) ||
|
|
||||||
(!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) &&
|
|
||||||
"the transpose operation is supposed to be handled in SparseMatrix::operator=");
|
|
||||||
|
|
||||||
enum { Flip = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit) };
|
|
||||||
|
|
||||||
const Index outerSize = Index(other.outerSize());
|
|
||||||
//typedef typename internal::conditional<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::type TempType;
|
|
||||||
// thanks to shallow copies, we always eval to a tempary
|
|
||||||
Derived temp(Index(other.rows()), Index(other.cols()));
|
|
||||||
|
|
||||||
temp.reserve((std::max)(this->rows(),this->cols())*2);
|
|
||||||
for (Index j=0; j<outerSize; ++j)
|
|
||||||
{
|
|
||||||
temp.startVec(j);
|
|
||||||
for (typename OtherDerived::InnerIterator it(other.derived(), typename OtherDerived::Index(j)); it; ++it)
|
|
||||||
{
|
|
||||||
Scalar v = it.value();
|
|
||||||
temp.insertBackByOuterInner(Flip?Index(it.index()):j,Flip?j:Index(it.index())) = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
temp.finalize();
|
|
||||||
|
|
||||||
derived() = temp.markAsRValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
// template<typename Lhs, typename Rhs>
|
|
||||||
// inline Derived& operator=(const SparseSparseProduct<Lhs,Rhs>& product);
|
|
||||||
//
|
|
||||||
// template<typename OtherDerived>
|
|
||||||
// Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
|
|
||||||
// template<typename OtherDerived>
|
|
||||||
// Derived& operator-=(const SparseMatrixBase<OtherDerived>& other);
|
|
||||||
//
|
|
||||||
// Derived& operator*=(const Scalar& other);
|
|
||||||
// Derived& operator/=(const Scalar& other);
|
|
||||||
//
|
|
||||||
// template<typename OtherDerived>
|
|
||||||
// Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);
|
|
||||||
|
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
Derived& SparseMatrixBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
|
Derived& SparseMatrixBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
|
||||||
@ -298,8 +187,6 @@ struct Assignment<DstXprType, Solve<DecType,RhsType>, internal::assign_op<Scalar
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_SPARSEASSIGN_H
|
#endif // EIGEN_SPARSEASSIGN_H
|
||||||
|
@ -25,33 +25,6 @@ protected:
|
|||||||
enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
|
enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
|
||||||
public:
|
public:
|
||||||
EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
|
EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
class InnerIterator: public XprType::InnerIterator
|
|
||||||
{
|
|
||||||
typedef typename BlockImpl::Index Index;
|
|
||||||
public:
|
|
||||||
inline InnerIterator(const BlockType& xpr, Index outer)
|
|
||||||
: XprType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
|
|
||||||
{}
|
|
||||||
inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
|
|
||||||
inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
|
|
||||||
protected:
|
|
||||||
Index m_outer;
|
|
||||||
};
|
|
||||||
class ReverseInnerIterator: public XprType::ReverseInnerIterator
|
|
||||||
{
|
|
||||||
typedef typename BlockImpl::Index Index;
|
|
||||||
public:
|
|
||||||
inline ReverseInnerIterator(const BlockType& xpr, Index outer)
|
|
||||||
: XprType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
|
|
||||||
{}
|
|
||||||
inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
|
|
||||||
inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
|
|
||||||
protected:
|
|
||||||
Index m_outer;
|
|
||||||
};
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
inline BlockImpl(const XprType& xpr, Index i)
|
inline BlockImpl(const XprType& xpr, Index i)
|
||||||
: m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize)
|
: m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize)
|
||||||
@ -66,14 +39,6 @@ public:
|
|||||||
|
|
||||||
Index nonZeros() const
|
Index nonZeros() const
|
||||||
{
|
{
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
Index nnz = 0;
|
|
||||||
Index end = m_outerStart + m_outerSize.value();
|
|
||||||
for(Index j=m_outerStart; j<end; ++j)
|
|
||||||
for(typename XprType::InnerIterator it(m_matrix, j); it; ++it)
|
|
||||||
++nnz;
|
|
||||||
return nnz;
|
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
typedef typename internal::evaluator<XprType>::type EvaluatorType;
|
typedef typename internal::evaluator<XprType>::type EvaluatorType;
|
||||||
EvaluatorType matEval(m_matrix);
|
EvaluatorType matEval(m_matrix);
|
||||||
Index nnz = 0;
|
Index nnz = 0;
|
||||||
@ -82,7 +47,6 @@ public:
|
|||||||
for(typename EvaluatorType::InnerIterator it(matEval, j); it; ++it)
|
for(typename EvaluatorType::InnerIterator it(matEval, j); it; ++it)
|
||||||
++nnz;
|
++nnz;
|
||||||
return nnz;
|
return nnz;
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const _MatrixTypeNested& nestedExpression() const { return m_matrix; }
|
inline const _MatrixTypeNested& nestedExpression() const { return m_matrix; }
|
||||||
@ -120,31 +84,6 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
|
enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
|
||||||
public:
|
public:
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
class InnerIterator: public SparseMatrixType::InnerIterator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline InnerIterator(const BlockType& xpr, Index outer)
|
|
||||||
: SparseMatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
|
|
||||||
{}
|
|
||||||
inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
|
|
||||||
inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
|
|
||||||
protected:
|
|
||||||
Index m_outer;
|
|
||||||
};
|
|
||||||
class ReverseInnerIterator: public SparseMatrixType::ReverseInnerIterator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline ReverseInnerIterator(const BlockType& xpr, Index outer)
|
|
||||||
: SparseMatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
|
|
||||||
{}
|
|
||||||
inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
|
|
||||||
inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
|
|
||||||
protected:
|
|
||||||
Index m_outer;
|
|
||||||
};
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
inline sparse_matrix_block_impl(const SparseMatrixType& xpr, Index i)
|
inline sparse_matrix_block_impl(const SparseMatrixType& xpr, Index i)
|
||||||
: m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize)
|
: m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize)
|
||||||
@ -434,34 +373,6 @@ public:
|
|||||||
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
|
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
typedef internal::GenericSparseBlockInnerIteratorImpl<XprType,BlockRows,BlockCols,InnerPanel> InnerIterator;
|
|
||||||
|
|
||||||
class ReverseInnerIterator : public _MatrixTypeNested::ReverseInnerIterator
|
|
||||||
{
|
|
||||||
typedef typename _MatrixTypeNested::ReverseInnerIterator Base;
|
|
||||||
const BlockType& m_block;
|
|
||||||
Index m_begin;
|
|
||||||
public:
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE ReverseInnerIterator(const BlockType& block, Index outer)
|
|
||||||
: Base(block.derived().nestedExpression(), outer + (IsRowMajor ? block.m_startRow.value() : block.m_startCol.value())),
|
|
||||||
m_block(block),
|
|
||||||
m_begin(IsRowMajor ? block.m_startCol.value() : block.m_startRow.value())
|
|
||||||
{
|
|
||||||
while( (Base::operator bool()) && (Base::index() >= (IsRowMajor ? m_block.m_startCol.value()+block.m_blockCols.value() : m_block.m_startRow.value()+block.m_blockRows.value())) )
|
|
||||||
Base::operator--();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Index index() const { return Base::index() - (IsRowMajor ? m_block.m_startCol.value() : m_block.m_startRow.value()); }
|
|
||||||
inline Index outer() const { return Base::outer() - (IsRowMajor ? m_block.m_startRow.value() : m_block.m_startCol.value()); }
|
|
||||||
inline Index row() const { return Base::row() - m_block.m_startRow.value(); }
|
|
||||||
inline Index col() const { return Base::col() - m_block.m_startCol.value(); }
|
|
||||||
|
|
||||||
inline operator bool() const { return Base::operator bool() && Base::index() >= m_begin; }
|
|
||||||
};
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
inline const _MatrixTypeNested& nestedExpression() const { return m_matrix; }
|
inline const _MatrixTypeNested& nestedExpression() const { return m_matrix; }
|
||||||
Index startRow() const { return m_startRow.value(); }
|
Index startRow() const { return m_startRow.value(); }
|
||||||
Index startCol() const { return m_startCol.value(); }
|
Index startCol() const { return m_startCol.value(); }
|
||||||
@ -574,9 +485,6 @@ namespace internal {
|
|||||||
inline operator bool() const { return m_outerPos < m_end; }
|
inline operator bool() const { return m_outerPos < m_end; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
//
|
|
||||||
template<typename ArgType, int BlockRows, int BlockCols, bool InnerPanel>
|
template<typename ArgType, int BlockRows, int BlockCols, bool InnerPanel>
|
||||||
struct unary_evaluator<Block<ArgType,BlockRows,BlockCols,InnerPanel>, IteratorBased >
|
struct unary_evaluator<Block<ArgType,BlockRows,BlockCols,InnerPanel>, IteratorBased >
|
||||||
: public evaluator_base<Block<ArgType,BlockRows,BlockCols,InnerPanel> >
|
: public evaluator_base<Block<ArgType,BlockRows,BlockCols,InnerPanel> >
|
||||||
@ -690,9 +598,6 @@ public:
|
|||||||
inline operator bool() const { return m_outerPos < m_end; }
|
inline operator bool() const { return m_outerPos < m_end; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,256 +38,6 @@ class sparse_cwise_binary_op_inner_iterator_selector;
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
template<typename BinaryOp, typename Lhs, typename Rhs>
|
|
||||||
class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Sparse>
|
|
||||||
: public SparseMatrixBase<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
class InnerIterator;
|
|
||||||
class ReverseInnerIterator;
|
|
||||||
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived;
|
|
||||||
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)
|
|
||||||
|| ((Lhs::Flags&RowMajorBit) == (Rhs::Flags&RowMajorBit))),
|
|
||||||
THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename BinaryOp, typename Lhs, typename Rhs>
|
|
||||||
class CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator
|
|
||||||
: public internal::sparse_cwise_binary_op_inner_iterator_selector<BinaryOp,Lhs,Rhs,typename CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef internal::sparse_cwise_binary_op_inner_iterator_selector<
|
|
||||||
BinaryOp,Lhs,Rhs, InnerIterator> Base;
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, Index outer)
|
|
||||||
: Base(binOp.derived(),outer)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* Implementation of inner-iterators
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
// template<typename T> struct internal::func_is_conjunction { enum { ret = false }; };
|
|
||||||
// template<typename T> struct internal::func_is_conjunction<internal::scalar_product_op<T> > { enum { ret = true }; };
|
|
||||||
|
|
||||||
// TODO generalize the internal::scalar_product_op specialization to all conjunctions if any !
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// sparse - sparse (generic)
|
|
||||||
template<typename BinaryOp, typename Lhs, typename Rhs, typename Derived>
|
|
||||||
class sparse_cwise_binary_op_inner_iterator_selector<BinaryOp, Lhs, Rhs, Derived, Sparse, Sparse>
|
|
||||||
{
|
|
||||||
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> CwiseBinaryXpr;
|
|
||||||
typedef typename traits<CwiseBinaryXpr>::Scalar Scalar;
|
|
||||||
typedef typename traits<CwiseBinaryXpr>::Index Index;
|
|
||||||
typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
|
|
||||||
typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
|
|
||||||
typedef typename _LhsNested::InnerIterator LhsIterator;
|
|
||||||
typedef typename _RhsNested::InnerIterator RhsIterator;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
|
|
||||||
: m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
|
|
||||||
{
|
|
||||||
this->operator++();
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Derived& operator++()
|
|
||||||
{
|
|
||||||
if (m_lhsIter && m_rhsIter && (m_lhsIter.index() == m_rhsIter.index()))
|
|
||||||
{
|
|
||||||
m_id = m_lhsIter.index();
|
|
||||||
m_value = m_functor(m_lhsIter.value(), m_rhsIter.value());
|
|
||||||
++m_lhsIter;
|
|
||||||
++m_rhsIter;
|
|
||||||
}
|
|
||||||
else if (m_lhsIter && (!m_rhsIter || (m_lhsIter.index() < m_rhsIter.index())))
|
|
||||||
{
|
|
||||||
m_id = m_lhsIter.index();
|
|
||||||
m_value = m_functor(m_lhsIter.value(), Scalar(0));
|
|
||||||
++m_lhsIter;
|
|
||||||
}
|
|
||||||
else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index())))
|
|
||||||
{
|
|
||||||
m_id = m_rhsIter.index();
|
|
||||||
m_value = m_functor(Scalar(0), m_rhsIter.value());
|
|
||||||
++m_rhsIter;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_value = 0; // this is to avoid a compilation warning
|
|
||||||
m_id = -1;
|
|
||||||
}
|
|
||||||
return *static_cast<Derived*>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Scalar value() const { return m_value; }
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Index index() const { return m_id; }
|
|
||||||
EIGEN_STRONG_INLINE Index row() const { return Lhs::IsRowMajor ? m_lhsIter.row() : index(); }
|
|
||||||
EIGEN_STRONG_INLINE Index col() const { return Lhs::IsRowMajor ? index() : m_lhsIter.col(); }
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE operator bool() const { return m_id>=0; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
LhsIterator m_lhsIter;
|
|
||||||
RhsIterator m_rhsIter;
|
|
||||||
const BinaryOp& m_functor;
|
|
||||||
Scalar m_value;
|
|
||||||
Index m_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
// sparse - sparse (product)
|
|
||||||
template<typename T, typename Lhs, typename Rhs, typename Derived>
|
|
||||||
class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Sparse>
|
|
||||||
{
|
|
||||||
typedef scalar_product_op<T> BinaryFunc;
|
|
||||||
typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
|
|
||||||
typedef typename CwiseBinaryXpr::Scalar Scalar;
|
|
||||||
typedef typename CwiseBinaryXpr::Index Index;
|
|
||||||
typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
|
|
||||||
typedef typename _LhsNested::InnerIterator LhsIterator;
|
|
||||||
typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
|
|
||||||
typedef typename _RhsNested::InnerIterator RhsIterator;
|
|
||||||
public:
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
|
|
||||||
: m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
|
|
||||||
{
|
|
||||||
while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
|
|
||||||
{
|
|
||||||
if (m_lhsIter.index() < m_rhsIter.index())
|
|
||||||
++m_lhsIter;
|
|
||||||
else
|
|
||||||
++m_rhsIter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Derived& operator++()
|
|
||||||
{
|
|
||||||
++m_lhsIter;
|
|
||||||
++m_rhsIter;
|
|
||||||
while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
|
|
||||||
{
|
|
||||||
if (m_lhsIter.index() < m_rhsIter.index())
|
|
||||||
++m_lhsIter;
|
|
||||||
else
|
|
||||||
++m_rhsIter;
|
|
||||||
}
|
|
||||||
return *static_cast<Derived*>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Scalar value() const { return m_functor(m_lhsIter.value(), m_rhsIter.value()); }
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Index index() const { return m_lhsIter.index(); }
|
|
||||||
EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); }
|
|
||||||
EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); }
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE operator bool() const { return (m_lhsIter && m_rhsIter); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
LhsIterator m_lhsIter;
|
|
||||||
RhsIterator m_rhsIter;
|
|
||||||
const BinaryFunc& m_functor;
|
|
||||||
};
|
|
||||||
|
|
||||||
// sparse - dense (product)
|
|
||||||
template<typename T, typename Lhs, typename Rhs, typename Derived>
|
|
||||||
class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Dense>
|
|
||||||
{
|
|
||||||
typedef scalar_product_op<T> BinaryFunc;
|
|
||||||
typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
|
|
||||||
typedef typename CwiseBinaryXpr::Scalar Scalar;
|
|
||||||
typedef typename CwiseBinaryXpr::Index Index;
|
|
||||||
typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
|
|
||||||
typedef typename traits<CwiseBinaryXpr>::RhsNested RhsNested;
|
|
||||||
typedef typename _LhsNested::InnerIterator LhsIterator;
|
|
||||||
enum { IsRowMajor = (int(Lhs::Flags)&RowMajorBit)==RowMajorBit };
|
|
||||||
public:
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
|
|
||||||
: m_rhs(xpr.rhs()), m_lhsIter(xpr.lhs(),typename _LhsNested::Index(outer)), m_functor(xpr.functor()), m_outer(outer)
|
|
||||||
{}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Derived& operator++()
|
|
||||||
{
|
|
||||||
++m_lhsIter;
|
|
||||||
return *static_cast<Derived*>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Scalar value() const
|
|
||||||
{ return m_functor(m_lhsIter.value(),
|
|
||||||
m_rhs.coeff(IsRowMajor?m_outer:m_lhsIter.index(),IsRowMajor?m_lhsIter.index():m_outer)); }
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Index index() const { return m_lhsIter.index(); }
|
|
||||||
EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); }
|
|
||||||
EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); }
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE operator bool() const { return m_lhsIter; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
RhsNested m_rhs;
|
|
||||||
LhsIterator m_lhsIter;
|
|
||||||
const BinaryFunc m_functor;
|
|
||||||
const Index m_outer;
|
|
||||||
};
|
|
||||||
|
|
||||||
// sparse - dense (product)
|
|
||||||
template<typename T, typename Lhs, typename Rhs, typename Derived>
|
|
||||||
class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Dense, Sparse>
|
|
||||||
{
|
|
||||||
typedef scalar_product_op<T> BinaryFunc;
|
|
||||||
typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
|
|
||||||
typedef typename CwiseBinaryXpr::Scalar Scalar;
|
|
||||||
typedef typename CwiseBinaryXpr::Index Index;
|
|
||||||
typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
|
|
||||||
typedef typename _RhsNested::InnerIterator RhsIterator;
|
|
||||||
|
|
||||||
enum { IsRowMajor = (int(Rhs::Flags)&RowMajorBit)==RowMajorBit };
|
|
||||||
public:
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
|
|
||||||
: m_xpr(xpr), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor()), m_outer(outer)
|
|
||||||
{}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Derived& operator++()
|
|
||||||
{
|
|
||||||
++m_rhsIter;
|
|
||||||
return *static_cast<Derived*>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Scalar value() const
|
|
||||||
{ return m_functor(m_xpr.lhs().coeff(IsRowMajor?m_outer:m_rhsIter.index(),IsRowMajor?m_rhsIter.index():m_outer), m_rhsIter.value()); }
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Index index() const { return m_rhsIter.index(); }
|
|
||||||
EIGEN_STRONG_INLINE Index row() const { return m_rhsIter.row(); }
|
|
||||||
EIGEN_STRONG_INLINE Index col() const { return m_rhsIter.col(); }
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE operator bool() const { return m_rhsIter; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const CwiseBinaryXpr& m_xpr;
|
|
||||||
RhsIterator m_rhsIter;
|
|
||||||
const BinaryFunc& m_functor;
|
|
||||||
const Index m_outer;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
|
||||||
@ -590,10 +340,6 @@ protected:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Implementation of SparseMatrixBase and SparseCwise functions/operators
|
* Implementation of SparseMatrixBase and SparseCwise functions/operators
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
@ -11,136 +11,6 @@
|
|||||||
#define EIGEN_SPARSE_CWISE_UNARY_OP_H
|
#define EIGEN_SPARSE_CWISE_UNARY_OP_H
|
||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
template<typename UnaryOp, typename MatrixType>
|
|
||||||
class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>
|
|
||||||
: public SparseMatrixBase<CwiseUnaryOp<UnaryOp, MatrixType> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef CwiseUnaryOp<UnaryOp, MatrixType> Derived;
|
|
||||||
EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
|
|
||||||
|
|
||||||
class InnerIterator;
|
|
||||||
class ReverseInnerIterator;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
typedef typename internal::traits<Derived>::_XprTypeNested _MatrixTypeNested;
|
|
||||||
typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator;
|
|
||||||
typedef typename _MatrixTypeNested::ReverseInnerIterator MatrixTypeReverseIterator;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename UnaryOp, typename MatrixType>
|
|
||||||
class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::InnerIterator
|
|
||||||
: public CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeIterator
|
|
||||||
{
|
|
||||||
typedef typename CwiseUnaryOpImpl::Scalar Scalar;
|
|
||||||
typedef typename CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeIterator Base;
|
|
||||||
public:
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryOpImpl& unaryOp, typename CwiseUnaryOpImpl::Index outer)
|
|
||||||
: Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor())
|
|
||||||
{}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE InnerIterator& operator++()
|
|
||||||
{ Base::operator++(); return *this; }
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE typename CwiseUnaryOpImpl::Scalar value() const { return m_functor(Base::value()); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const UnaryOp m_functor;
|
|
||||||
private:
|
|
||||||
typename CwiseUnaryOpImpl::Scalar& valueRef();
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename UnaryOp, typename MatrixType>
|
|
||||||
class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::ReverseInnerIterator
|
|
||||||
: public CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeReverseIterator
|
|
||||||
{
|
|
||||||
typedef typename CwiseUnaryOpImpl::Scalar Scalar;
|
|
||||||
typedef typename CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeReverseIterator Base;
|
|
||||||
public:
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE ReverseInnerIterator(const CwiseUnaryOpImpl& unaryOp, typename CwiseUnaryOpImpl::Index outer)
|
|
||||||
: Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor())
|
|
||||||
{}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE ReverseInnerIterator& operator--()
|
|
||||||
{ Base::operator--(); return *this; }
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE typename CwiseUnaryOpImpl::Scalar value() const { return m_functor(Base::value()); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const UnaryOp m_functor;
|
|
||||||
private:
|
|
||||||
typename CwiseUnaryOpImpl::Scalar& valueRef();
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ViewOp, typename MatrixType>
|
|
||||||
class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>
|
|
||||||
: public SparseMatrixBase<CwiseUnaryView<ViewOp, MatrixType> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
class InnerIterator;
|
|
||||||
class ReverseInnerIterator;
|
|
||||||
|
|
||||||
typedef CwiseUnaryView<ViewOp, MatrixType> Derived;
|
|
||||||
EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
|
|
||||||
|
|
||||||
protected:
|
|
||||||
typedef typename internal::traits<Derived>::_MatrixTypeNested _MatrixTypeNested;
|
|
||||||
typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator;
|
|
||||||
typedef typename _MatrixTypeNested::ReverseInnerIterator MatrixTypeReverseIterator;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ViewOp, typename MatrixType>
|
|
||||||
class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::InnerIterator
|
|
||||||
: public CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeIterator
|
|
||||||
{
|
|
||||||
typedef typename CwiseUnaryViewImpl::Scalar Scalar;
|
|
||||||
typedef typename CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeIterator Base;
|
|
||||||
public:
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryViewImpl& unaryOp, typename CwiseUnaryViewImpl::Index outer)
|
|
||||||
: Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor())
|
|
||||||
{}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE InnerIterator& operator++()
|
|
||||||
{ Base::operator++(); return *this; }
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar value() const { return m_functor(Base::value()); }
|
|
||||||
EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar& valueRef() { return m_functor(Base::valueRef()); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const ViewOp m_functor;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ViewOp, typename MatrixType>
|
|
||||||
class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::ReverseInnerIterator
|
|
||||||
: public CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeReverseIterator
|
|
||||||
{
|
|
||||||
typedef typename CwiseUnaryViewImpl::Scalar Scalar;
|
|
||||||
typedef typename CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeReverseIterator Base;
|
|
||||||
public:
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE ReverseInnerIterator(const CwiseUnaryViewImpl& unaryOp, typename CwiseUnaryViewImpl::Index outer)
|
|
||||||
: Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor())
|
|
||||||
{}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE ReverseInnerIterator& operator--()
|
|
||||||
{ Base::operator--(); return *this; }
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar value() const { return m_functor(Base::value()); }
|
|
||||||
EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar& valueRef() { return m_functor(Base::valueRef()); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const ViewOp m_functor;
|
|
||||||
};
|
|
||||||
|
|
||||||
#else // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
@ -291,8 +161,6 @@ class unary_evaluator<CwiseUnaryView<ViewOp,ArgType>, IteratorBased>::InnerItera
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
EIGEN_STRONG_INLINE Derived&
|
EIGEN_STRONG_INLINE Derived&
|
||||||
SparseMatrixBase<Derived>::operator*=(const Scalar& other)
|
SparseMatrixBase<Derived>::operator*=(const Scalar& other)
|
||||||
|
@ -30,18 +30,10 @@ struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, t
|
|||||||
typedef typename internal::remove_all<DenseRhsType>::type Rhs;
|
typedef typename internal::remove_all<DenseRhsType>::type Rhs;
|
||||||
typedef typename internal::remove_all<DenseResType>::type Res;
|
typedef typename internal::remove_all<DenseResType>::type Res;
|
||||||
typedef typename Lhs::Index Index;
|
typedef typename Lhs::Index Index;
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
typedef typename Lhs::InnerIterator LhsInnerIterator;
|
|
||||||
#else
|
|
||||||
typedef typename evaluator<Lhs>::InnerIterator LhsInnerIterator;
|
typedef typename evaluator<Lhs>::InnerIterator LhsInnerIterator;
|
||||||
#endif
|
|
||||||
static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha)
|
static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha)
|
||||||
{
|
{
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
typename evaluator<Lhs>::type lhsEval(lhs);
|
||||||
const Lhs &lhsEval(lhs);
|
|
||||||
#else
|
|
||||||
typename evaluator<Lhs>::type lhsEval(lhs);
|
|
||||||
#endif
|
|
||||||
for(Index c=0; c<rhs.cols(); ++c)
|
for(Index c=0; c<rhs.cols(); ++c)
|
||||||
{
|
{
|
||||||
Index n = lhs.outerSize();
|
Index n = lhs.outerSize();
|
||||||
@ -71,18 +63,10 @@ struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, A
|
|||||||
typedef typename internal::remove_all<DenseRhsType>::type Rhs;
|
typedef typename internal::remove_all<DenseRhsType>::type Rhs;
|
||||||
typedef typename internal::remove_all<DenseResType>::type Res;
|
typedef typename internal::remove_all<DenseResType>::type Res;
|
||||||
typedef typename Lhs::Index Index;
|
typedef typename Lhs::Index Index;
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
typedef typename Lhs::InnerIterator LhsInnerIterator;
|
|
||||||
#else
|
|
||||||
typedef typename evaluator<Lhs>::InnerIterator LhsInnerIterator;
|
typedef typename evaluator<Lhs>::InnerIterator LhsInnerIterator;
|
||||||
#endif
|
|
||||||
static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const AlphaType& alpha)
|
static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const AlphaType& alpha)
|
||||||
{
|
{
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
typename evaluator<Lhs>::type lhsEval(lhs);
|
||||||
const Lhs &lhsEval(lhs);
|
|
||||||
#else
|
|
||||||
typename evaluator<Lhs>::type lhsEval(lhs);
|
|
||||||
#endif
|
|
||||||
for(Index c=0; c<rhs.cols(); ++c)
|
for(Index c=0; c<rhs.cols(); ++c)
|
||||||
{
|
{
|
||||||
for(Index j=0; j<lhs.outerSize(); ++j)
|
for(Index j=0; j<lhs.outerSize(); ++j)
|
||||||
@ -103,18 +87,10 @@ struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, t
|
|||||||
typedef typename internal::remove_all<DenseRhsType>::type Rhs;
|
typedef typename internal::remove_all<DenseRhsType>::type Rhs;
|
||||||
typedef typename internal::remove_all<DenseResType>::type Res;
|
typedef typename internal::remove_all<DenseResType>::type Res;
|
||||||
typedef typename Lhs::Index Index;
|
typedef typename Lhs::Index Index;
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
typedef typename Lhs::InnerIterator LhsInnerIterator;
|
|
||||||
#else
|
|
||||||
typedef typename evaluator<Lhs>::InnerIterator LhsInnerIterator;
|
typedef typename evaluator<Lhs>::InnerIterator LhsInnerIterator;
|
||||||
#endif
|
|
||||||
static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha)
|
static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha)
|
||||||
{
|
{
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
typename evaluator<Lhs>::type lhsEval(lhs);
|
||||||
const Lhs &lhsEval(lhs);
|
|
||||||
#else
|
|
||||||
typename evaluator<Lhs>::type lhsEval(lhs);
|
|
||||||
#endif
|
|
||||||
for(Index j=0; j<lhs.outerSize(); ++j)
|
for(Index j=0; j<lhs.outerSize(); ++j)
|
||||||
{
|
{
|
||||||
typename Res::RowXpr res_j(res.row(j));
|
typename Res::RowXpr res_j(res.row(j));
|
||||||
@ -131,18 +107,10 @@ struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, t
|
|||||||
typedef typename internal::remove_all<DenseRhsType>::type Rhs;
|
typedef typename internal::remove_all<DenseRhsType>::type Rhs;
|
||||||
typedef typename internal::remove_all<DenseResType>::type Res;
|
typedef typename internal::remove_all<DenseResType>::type Res;
|
||||||
typedef typename Lhs::Index Index;
|
typedef typename Lhs::Index Index;
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
typedef typename Lhs::InnerIterator LhsInnerIterator;
|
|
||||||
#else
|
|
||||||
typedef typename evaluator<Lhs>::InnerIterator LhsInnerIterator;
|
typedef typename evaluator<Lhs>::InnerIterator LhsInnerIterator;
|
||||||
#endif
|
|
||||||
static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha)
|
static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha)
|
||||||
{
|
{
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
typename evaluator<Lhs>::type lhsEval(lhs);
|
||||||
const Lhs &lhsEval(lhs);
|
|
||||||
#else
|
|
||||||
typename evaluator<Lhs>::type lhsEval(lhs);
|
|
||||||
#endif
|
|
||||||
for(Index j=0; j<lhs.outerSize(); ++j)
|
for(Index j=0; j<lhs.outerSize(); ++j)
|
||||||
{
|
{
|
||||||
typename Rhs::ConstRowXpr rhs_j(rhs.row(j));
|
typename Rhs::ConstRowXpr rhs_j(rhs.row(j));
|
||||||
@ -160,212 +128,6 @@ inline void sparse_time_dense_product(const SparseLhsType& lhs, const DenseRhsTy
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
|
||||||
template<typename Lhs, typename Rhs, int InnerSize> struct SparseDenseProductReturnType
|
|
||||||
{
|
|
||||||
typedef SparseTimeDenseProduct<Lhs,Rhs> Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs> struct SparseDenseProductReturnType<Lhs,Rhs,1>
|
|
||||||
{
|
|
||||||
typedef typename internal::conditional<
|
|
||||||
Lhs::IsRowMajor,
|
|
||||||
SparseDenseOuterProduct<Rhs,Lhs,true>,
|
|
||||||
SparseDenseOuterProduct<Lhs,Rhs,false> >::type Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int InnerSize> struct DenseSparseProductReturnType
|
|
||||||
{
|
|
||||||
typedef DenseTimeSparseProduct<Lhs,Rhs> Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs> struct DenseSparseProductReturnType<Lhs,Rhs,1>
|
|
||||||
{
|
|
||||||
typedef typename internal::conditional<
|
|
||||||
Rhs::IsRowMajor,
|
|
||||||
SparseDenseOuterProduct<Rhs,Lhs,true>,
|
|
||||||
SparseDenseOuterProduct<Lhs,Rhs,false> >::type Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, bool Tr>
|
|
||||||
struct traits<SparseDenseOuterProduct<Lhs,Rhs,Tr> >
|
|
||||||
{
|
|
||||||
typedef Sparse StorageKind;
|
|
||||||
typedef typename scalar_product_traits<typename traits<Lhs>::Scalar,
|
|
||||||
typename traits<Rhs>::Scalar>::ReturnType Scalar;
|
|
||||||
typedef typename Lhs::Index Index;
|
|
||||||
typedef typename Lhs::Nested LhsNested;
|
|
||||||
typedef typename Rhs::Nested RhsNested;
|
|
||||||
typedef typename remove_all<LhsNested>::type _LhsNested;
|
|
||||||
typedef typename remove_all<RhsNested>::type _RhsNested;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
LhsCoeffReadCost = traits<_LhsNested>::CoeffReadCost,
|
|
||||||
RhsCoeffReadCost = traits<_RhsNested>::CoeffReadCost,
|
|
||||||
|
|
||||||
RowsAtCompileTime = Tr ? int(traits<Rhs>::RowsAtCompileTime) : int(traits<Lhs>::RowsAtCompileTime),
|
|
||||||
ColsAtCompileTime = Tr ? int(traits<Lhs>::ColsAtCompileTime) : int(traits<Rhs>::ColsAtCompileTime),
|
|
||||||
MaxRowsAtCompileTime = Tr ? int(traits<Rhs>::MaxRowsAtCompileTime) : int(traits<Lhs>::MaxRowsAtCompileTime),
|
|
||||||
MaxColsAtCompileTime = Tr ? int(traits<Lhs>::MaxColsAtCompileTime) : int(traits<Rhs>::MaxColsAtCompileTime),
|
|
||||||
|
|
||||||
Flags = Tr ? RowMajorBit : 0,
|
|
||||||
|
|
||||||
CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + NumTraits<Scalar>::MulCost
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, bool Tr>
|
|
||||||
class SparseDenseOuterProduct
|
|
||||||
: public SparseMatrixBase<SparseDenseOuterProduct<Lhs,Rhs,Tr> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef SparseMatrixBase<SparseDenseOuterProduct> Base;
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(SparseDenseOuterProduct)
|
|
||||||
typedef internal::traits<SparseDenseOuterProduct> Traits;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
typedef typename Traits::LhsNested LhsNested;
|
|
||||||
typedef typename Traits::RhsNested RhsNested;
|
|
||||||
typedef typename Traits::_LhsNested _LhsNested;
|
|
||||||
typedef typename Traits::_RhsNested _RhsNested;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
class InnerIterator;
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE SparseDenseOuterProduct(const Lhs& lhs, const Rhs& rhs)
|
|
||||||
: m_lhs(lhs), m_rhs(rhs)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT(!Tr,YOU_MADE_A_PROGRAMMING_MISTAKE);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE SparseDenseOuterProduct(const Rhs& rhs, const Lhs& lhs)
|
|
||||||
: m_lhs(lhs), m_rhs(rhs)
|
|
||||||
{
|
|
||||||
EIGEN_STATIC_ASSERT(Tr,YOU_MADE_A_PROGRAMMING_MISTAKE);
|
|
||||||
}
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE Index rows() const { return Tr ? Index(m_rhs.rows()) : m_lhs.rows(); }
|
|
||||||
EIGEN_STRONG_INLINE Index cols() const { return Tr ? m_lhs.cols() : Index(m_rhs.cols()); }
|
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; }
|
|
||||||
EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
LhsNested m_lhs;
|
|
||||||
RhsNested m_rhs;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, bool Transpose>
|
|
||||||
class SparseDenseOuterProduct<Lhs,Rhs,Transpose>::InnerIterator : public _LhsNested::InnerIterator
|
|
||||||
{
|
|
||||||
typedef typename _LhsNested::InnerIterator Base;
|
|
||||||
typedef typename SparseDenseOuterProduct::Index Index;
|
|
||||||
public:
|
|
||||||
EIGEN_STRONG_INLINE InnerIterator(const SparseDenseOuterProduct& prod, Index outer)
|
|
||||||
: Base(prod.lhs(), 0), m_outer(outer), m_empty(false), m_factor(get(prod.rhs(), outer, typename internal::traits<Rhs>::StorageKind() ))
|
|
||||||
{}
|
|
||||||
|
|
||||||
inline Index outer() const { return m_outer; }
|
|
||||||
inline Index row() const { return Transpose ? m_outer : Base::index(); }
|
|
||||||
inline Index col() const { return Transpose ? Base::index() : m_outer; }
|
|
||||||
|
|
||||||
inline Scalar value() const { return Base::value() * m_factor; }
|
|
||||||
inline operator bool() const { return Base::operator bool() && !m_empty; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Scalar get(const _RhsNested &rhs, Index outer, Dense = Dense()) const
|
|
||||||
{
|
|
||||||
return rhs.coeff(outer);
|
|
||||||
}
|
|
||||||
|
|
||||||
Scalar get(const _RhsNested &rhs, Index outer, Sparse = Sparse())
|
|
||||||
{
|
|
||||||
typename Traits::_RhsNested::InnerIterator it(rhs, outer);
|
|
||||||
if (it && it.index()==0 && it.value()!=Scalar(0))
|
|
||||||
return it.value();
|
|
||||||
m_empty = true;
|
|
||||||
return Scalar(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Index m_outer;
|
|
||||||
bool m_empty;
|
|
||||||
Scalar m_factor;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
struct traits<SparseTimeDenseProduct<Lhs,Rhs> >
|
|
||||||
: traits<ProductBase<SparseTimeDenseProduct<Lhs,Rhs>, Lhs, Rhs> >
|
|
||||||
{
|
|
||||||
typedef Dense StorageKind;
|
|
||||||
typedef MatrixXpr XprKind;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
class SparseTimeDenseProduct
|
|
||||||
: public ProductBase<SparseTimeDenseProduct<Lhs,Rhs>, Lhs, Rhs>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EIGEN_PRODUCT_PUBLIC_INTERFACE(SparseTimeDenseProduct)
|
|
||||||
|
|
||||||
SparseTimeDenseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
|
|
||||||
{
|
|
||||||
internal::sparse_time_dense_product(m_lhs, m_rhs, dest, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
SparseTimeDenseProduct& operator=(const SparseTimeDenseProduct&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// dense = dense * sparse
|
|
||||||
namespace internal {
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
struct traits<DenseTimeSparseProduct<Lhs,Rhs> >
|
|
||||||
: traits<ProductBase<DenseTimeSparseProduct<Lhs,Rhs>, Lhs, Rhs> >
|
|
||||||
{
|
|
||||||
typedef Dense StorageKind;
|
|
||||||
};
|
|
||||||
} // end namespace internal
|
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs>
|
|
||||||
class DenseTimeSparseProduct
|
|
||||||
: public ProductBase<DenseTimeSparseProduct<Lhs,Rhs>, Lhs, Rhs>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EIGEN_PRODUCT_PUBLIC_INTERFACE(DenseTimeSparseProduct)
|
|
||||||
|
|
||||||
DenseTimeSparseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
|
|
||||||
{
|
|
||||||
Transpose<const _LhsNested> lhs_t(m_lhs);
|
|
||||||
Transpose<const _RhsNested> rhs_t(m_rhs);
|
|
||||||
Transpose<Dest> dest_t(dest);
|
|
||||||
internal::sparse_time_dense_product(rhs_t, lhs_t, dest_t, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
DenseTimeSparseProduct& operator=(const DenseTimeSparseProduct&);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
#ifdef EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<typename Lhs, typename Rhs, int ProductType>
|
template<typename Lhs, typename Rhs, int ProductType>
|
||||||
@ -514,8 +276,6 @@ struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, OuterProduct, DenseS
|
|||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
|
|
||||||
#endif // EIGEN_TEST_EVALUATORS
|
|
||||||
|
|
||||||
} // end namespace Eigen
|
} // end namespace Eigen
|
||||||
|
|
||||||
#endif // EIGEN_SPARSEDENSEPRODUCT_H
|
#endif // EIGEN_SPARSEDENSEPRODUCT_H
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user