* the Upper->UpperTriangular change

* finally get ei_add_test right
This commit is contained in:
Benoit Jacob 2008-12-20 13:36:12 +00:00
parent 21ab65e4b3
commit 9e00d94543
33 changed files with 181 additions and 179 deletions

View File

@ -52,7 +52,7 @@ template<typename MatrixType> class Cholesky
} }
/** \deprecated */ /** \deprecated */
inline Part<MatrixType, Lower> matrixL(void) const { return m_matrix; } inline Part<MatrixType, LowerTriangular> matrixL(void) const { return m_matrix; }
/** \deprecated */ /** \deprecated */
inline bool isPositiveDefinite(void) const { return m_isPositiveDefinite; } inline bool isPositiveDefinite(void) const { return m_isPositiveDefinite; }
@ -148,7 +148,7 @@ bool Cholesky<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const
if (!m_isPositiveDefinite) if (!m_isPositiveDefinite)
return false; return false;
matrixL().solveTriangularInPlace(bAndX); matrixL().solveTriangularInPlace(bAndX);
m_matrix.adjoint().template part<Upper>().solveTriangularInPlace(bAndX); m_matrix.adjoint().template part<UpperTriangular>().solveTriangularInPlace(bAndX);
return true; return true;
} }

View File

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

View File

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

View File

@ -67,7 +67,7 @@ template<typename MatrixType> class LLT
} }
/** \returns the lower triangular matrix L */ /** \returns the lower triangular matrix L */
inline Part<MatrixType, Lower> matrixL(void) const { return m_matrix; } inline Part<MatrixType, LowerTriangular> matrixL(void) const { return m_matrix; }
/** \returns true if the matrix is positive definite */ /** \returns true if the matrix is positive definite */
inline bool isPositiveDefinite(void) const { return m_isPositiveDefinite; } inline bool isPositiveDefinite(void) const { return m_isPositiveDefinite; }
@ -169,7 +169,7 @@ bool LLT<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const
if (!m_isPositiveDefinite) if (!m_isPositiveDefinite)
return false; return false;
matrixL().solveTriangularInPlace(bAndX); matrixL().solveTriangularInPlace(bAndX);
m_matrix.adjoint().template part<Upper>().solveTriangularInPlace(bAndX); m_matrix.adjoint().template part<UpperTriangular>().solveTriangularInPlace(bAndX);
return true; return true;
} }

View File

@ -470,8 +470,8 @@ template<typename Derived> class MatrixBase
bool isIdentity(RealScalar prec = precision<Scalar>()) const; bool isIdentity(RealScalar prec = precision<Scalar>()) const;
bool isDiagonal(RealScalar prec = precision<Scalar>()) const; bool isDiagonal(RealScalar prec = precision<Scalar>()) const;
bool isUpper(RealScalar prec = precision<Scalar>()) const; bool isUpperTriangular(RealScalar prec = precision<Scalar>()) const;
bool isLower(RealScalar prec = precision<Scalar>()) const; bool isLowerTriangular(RealScalar prec = precision<Scalar>()) const;
template<typename OtherDerived> template<typename OtherDerived>
bool isOrthogonal(const MatrixBase<OtherDerived>& other, bool isOrthogonal(const MatrixBase<OtherDerived>& other,

View File

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

View File

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

View File

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

View File

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

View File

@ -114,7 +114,7 @@ template<typename MatrixType> class LU
* *
* \sa matrixLU(), matrixU() * \sa matrixLU(), matrixU()
*/ */
inline const Part<MatrixType, UnitLower> matrixL() const inline const Part<MatrixType, UnitLowerTriangular> matrixL() const
{ {
return m_lu; return m_lu;
} }
@ -123,7 +123,7 @@ template<typename MatrixType> class LU
* *
* \sa matrixLU(), matrixL() * \sa matrixLU(), matrixL()
*/ */
inline const Part<MatrixType, Upper> matrixU() const inline const Part<MatrixType, UpperTriangular> matrixU() const
{ {
return m_lu; return m_lu;
} }
@ -441,7 +441,7 @@ void LU<MatrixType>::computeKernel(KernelMatrixType *result) const
y(-m_lu.corner(TopRight, m_rank, dimker)); y(-m_lu.corner(TopRight, m_rank, dimker));
m_lu.corner(TopLeft, m_rank, m_rank) m_lu.corner(TopLeft, m_rank, m_rank)
.template marked<Upper>() .template marked<UpperTriangular>()
.solveTriangularInPlace(y); .solveTriangularInPlace(y);
for(int i = 0; i < m_rank; ++i) for(int i = 0; i < m_rank; ++i)
@ -510,7 +510,7 @@ bool LU<MatrixType>::solve(
l.setZero(); l.setZero();
l.corner(Eigen::TopLeft,rows,smalldim) l.corner(Eigen::TopLeft,rows,smalldim)
= m_lu.corner(Eigen::TopLeft,rows,smalldim); = m_lu.corner(Eigen::TopLeft,rows,smalldim);
l.template marked<UnitLower>().solveTriangularInPlace(c); l.template marked<UnitLowerTriangular>().solveTriangularInPlace(c);
// Step 3 // Step 3
if(!isSurjective()) if(!isSurjective())
@ -527,7 +527,7 @@ bool LU<MatrixType>::solve(
MatrixType::MaxRowsAtCompileTime, OtherDerived::MaxColsAtCompileTime> MatrixType::MaxRowsAtCompileTime, OtherDerived::MaxColsAtCompileTime>
d(c.corner(TopLeft, m_rank, c.cols())); d(c.corner(TopLeft, m_rank, c.cols()));
m_lu.corner(TopLeft, m_rank, m_rank) m_lu.corner(TopLeft, m_rank, m_rank)
.template marked<Upper>() .template marked<UpperTriangular>()
.solveTriangularInPlace(d); .solveTriangularInPlace(d);
// Step 4 // Step 4

View File

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

View File

@ -60,11 +60,11 @@ template<typename MatrixType> class QR
bool isFullRank() const { return ei_isMuchSmallerThan(m_hCoeffs.cwise().abs().minCoeff(), Scalar(1)); } bool isFullRank() const { return ei_isMuchSmallerThan(m_hCoeffs.cwise().abs().minCoeff(), Scalar(1)); }
/** \returns a read-only expression of the matrix R of the actual the QR decomposition */ /** \returns a read-only expression of the matrix R of the actual the QR decomposition */
const Part<NestByValue<MatrixRBlockType>, Upper> const Part<NestByValue<MatrixRBlockType>, UpperTriangular>
matrixR(void) const matrixR(void) const
{ {
int cols = m_qr.cols(); int cols = m_qr.cols();
return MatrixRBlockType(m_qr, 0, 0, cols, cols).nestByValue().template part<Upper>(); return MatrixRBlockType(m_qr, 0, 0, cols, cols).nestByValue().template part<UpperTriangular>();
} }
MatrixType matrixQ(void) const; MatrixType matrixQ(void) const;

View File

@ -254,22 +254,22 @@ compute(const MatrixType& matA, const MatrixType& matB, bool computeEigenvectors
cholB.matrixL().solveTriangularInPlace(matC); cholB.matrixL().solveTriangularInPlace(matC);
// FIXME since we currently do not support A * inv(L'), let's do (inv(L) A')' : // FIXME since we currently do not support A * inv(L'), let's do (inv(L) A')' :
matC = matC.adjoint().eval(); matC = matC.adjoint().eval();
cholB.matrixL().template marked<Lower>().solveTriangularInPlace(matC); cholB.matrixL().template marked<LowerTriangular>().solveTriangularInPlace(matC);
matC = matC.adjoint().eval(); matC = matC.adjoint().eval();
// this version works too: // this version works too:
// matC = matC.transpose(); // matC = matC.transpose();
// cholB.matrixL().conjugate().template marked<Lower>().solveTriangularInPlace(matC); // cholB.matrixL().conjugate().template marked<LowerTriangular>().solveTriangularInPlace(matC);
// matC = matC.transpose(); // matC = matC.transpose();
// FIXME: this should work: (currently it only does for small matrices) // FIXME: this should work: (currently it only does for small matrices)
// Transpose<MatrixType> trMatC(matC); // Transpose<MatrixType> trMatC(matC);
// cholB.matrixL().conjugate().eval().template marked<Lower>().solveTriangularInPlace(trMatC); // cholB.matrixL().conjugate().eval().template marked<LowerTriangular>().solveTriangularInPlace(trMatC);
compute(matC, computeEigenvectors); compute(matC, computeEigenvectors);
if (computeEigenvectors) if (computeEigenvectors)
{ {
// transform back the eigen vectors: evecs = inv(U) * evecs // transform back the eigen vectors: evecs = inv(U) * evecs
cholB.matrixL().adjoint().template marked<Upper>().solveTriangularInPlace(m_eivec); cholB.matrixL().adjoint().template marked<UpperTriangular>().solveTriangularInPlace(m_eivec);
for (int i=0; i<m_eivec.cols(); ++i) for (int i=0; i<m_eivec.cols(); ++i)
m_eivec.col(i) = m_eivec.col(i).normalized(); m_eivec.col(i) = m_eivec.col(i).normalized();
} }

View File

@ -167,8 +167,8 @@ Tridiagonalization<MatrixType>::matrixT(void) const
matT.corner(TopRight,n-1, n-1).diagonal() = subDiagonal().conjugate(); matT.corner(TopRight,n-1, n-1).diagonal() = subDiagonal().conjugate();
if (n>2) if (n>2)
{ {
matT.corner(TopRight,n-2, n-2).template part<Upper>().setZero(); matT.corner(TopRight,n-2, n-2).template part<UpperTriangular>().setZero();
matT.corner(BottomLeft,n-2, n-2).template part<Lower>().setZero(); matT.corner(BottomLeft,n-2, n-2).template part<LowerTriangular>().setZero();
} }
return matT; return matT;
} }
@ -223,17 +223,17 @@ void Tridiagonalization<MatrixType>::_compute(MatrixType& matA, CoeffVectorType&
/* This is the initial algorithm which minimize operation counts and maximize /* This is the initial algorithm which minimize operation counts and maximize
* the use of Eigen's expression. Unfortunately, the first matrix-vector product * the use of Eigen's expression. Unfortunately, the first matrix-vector product
* using Part<Lower|Selfadjoint> is very very slow */ * using Part<LowerTriangular|Selfadjoint> is very very slow */
#ifdef EIGEN_NEVER_DEFINED #ifdef EIGEN_NEVER_DEFINED
// matrix - vector product // matrix - vector product
hCoeffs.end(n-i-1) = (matA.corner(BottomRight,n-i-1,n-i-1).template part<Lower|SelfAdjoint>() hCoeffs.end(n-i-1) = (matA.corner(BottomRight,n-i-1,n-i-1).template part<LowerTriangular|SelfAdjoint>()
* (h * matA.col(i).end(n-i-1))).lazy(); * (h * matA.col(i).end(n-i-1))).lazy();
// simple axpy // simple axpy
hCoeffs.end(n-i-1) += (h * Scalar(-0.5) * matA.col(i).end(n-i-1).dot(hCoeffs.end(n-i-1))) hCoeffs.end(n-i-1) += (h * Scalar(-0.5) * matA.col(i).end(n-i-1).dot(hCoeffs.end(n-i-1)))
* matA.col(i).end(n-i-1); * matA.col(i).end(n-i-1);
// rank-2 update // rank-2 update
//Block<MatrixType,Dynamic,1> B(matA,i+1,i,n-i-1,1); //Block<MatrixType,Dynamic,1> B(matA,i+1,i,n-i-1,1);
matA.corner(BottomRight,n-i-1,n-i-1).template part<Lower>() -= matA.corner(BottomRight,n-i-1,n-i-1).template part<LowerTriangular>() -=
(matA.col(i).end(n-i-1) * hCoeffs.end(n-i-1).adjoint()).lazy() (matA.col(i).end(n-i-1) * hCoeffs.end(n-i-1).adjoint()).lazy()
+ (hCoeffs.end(n-i-1) * matA.col(i).end(n-i-1).adjoint()).lazy(); + (hCoeffs.end(n-i-1) * matA.col(i).end(n-i-1).adjoint()).lazy();
#endif #endif
@ -256,7 +256,7 @@ void Tridiagonalization<MatrixType>::_compute(MatrixType& matA, CoeffVectorType&
Block<MatrixType,Dynamic,4>(matA,b+4,b,n-b-4,4).adjoint() * Block<MatrixType,Dynamic,1>(matA,b+4,i,n-b-4,1); Block<MatrixType,Dynamic,4>(matA,b+4,b,n-b-4,4).adjoint() * Block<MatrixType,Dynamic,1>(matA,b+4,i,n-b-4,1);
// the 4x4 block diagonal: // the 4x4 block diagonal:
Block<CoeffVectorType,4,1>(hCoeffs, b, 0, 4,1) += Block<CoeffVectorType,4,1>(hCoeffs, b, 0, 4,1) +=
(Block<MatrixType,4,4>(matA,b,b,4,4).template part<Lower|SelfAdjoint>() (Block<MatrixType,4,4>(matA,b,b,4,4).template part<LowerTriangular|SelfAdjoint>()
* (h * Block<MatrixType,4,1>(matA,b,i,4,1))).lazy(); * (h * Block<MatrixType,4,1>(matA,b,i,4,1))).lazy();
} }
#endif #endif

View File

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

View File

@ -79,7 +79,7 @@ class SparseLDLT
protected: protected:
typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar; typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
typedef SparseMatrix<Scalar,Lower|UnitDiagBit> CholMatrixType; typedef SparseMatrix<Scalar,LowerTriangular|UnitDiagBit> CholMatrixType;
typedef Matrix<Scalar,MatrixType::ColsAtCompileTime,1> VectorType; typedef Matrix<Scalar,MatrixType::ColsAtCompileTime,1> VectorType;
enum { enum {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -513,20 +513,20 @@ Read/write access to special parts of a matrix can be achieved. See \link Matrix
<tr><td> <tr><td>
Extract triangular matrices \n from a given matrix m: Extract triangular matrices \n from a given matrix m:
</td><td>\code </td><td>\code
m.part<Eigen::Upper>() m.part<Eigen::UpperTriangular>()
m.part<Eigen::StrictlyUpper>() m.part<Eigen::StrictlyUpperTriangular>()
m.part<Eigen::UnitUpper>() m.part<Eigen::UnitUpperTriangular>()
m.part<Eigen::Lower>() m.part<Eigen::LowerTriangular>()
m.part<Eigen::StrictlyLower>() m.part<Eigen::StrictlyLowerTriangular>()
m.part<Eigen::UnitLower>()\endcode m.part<Eigen::UnitLowerTriangular>()\endcode
</td></tr> </td></tr>
<tr><td> <tr><td>
Write to triangular parts \n of a matrix m: Write to triangular parts \n of a matrix m:
</td><td>\code </td><td>\code
m1.part<Eigen::Upper>() = m2; m1.part<Eigen::UpperTriangular>() = m2;
m1.part<Eigen::StrictlyUpper>() = m2; m1.part<Eigen::StrictlyUpperTriangular>() = m2;
m1.part<Eigen::Lower>() = m2; m1.part<Eigen::LowerTriangular>() = m2;
m1.part<Eigen::StrictlyLower>() = m2;\endcode m1.part<Eigen::StrictlyLowerTriangular>() = m2;\endcode
</td></tr> </td></tr>
<tr><td> <tr><td>
Special: take advantage of symmetry \n (selfadjointness) when copying \n an expression into a matrix Special: take advantage of symmetry \n (selfadjointness) when copying \n an expression into a matrix

View File

@ -1,8 +1,8 @@
Matrix3i m = Matrix3i::Random(); Matrix3i m = Matrix3i::Random();
cout << "Here is the matrix m:" << endl << m << endl; cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is the upper-triangular matrix extracted from m:" << endl cout << "Here is the upper-triangular matrix extracted from m:" << endl
<< m.part<Eigen::Upper>() << endl; << m.part<Eigen::UpperTriangular>() << endl;
cout << "Here is the strictly-upper-triangular matrix extracted from m:" << endl cout << "Here is the strictly-upper-triangular matrix extracted from m:" << endl
<< m.part<Eigen::StrictlyUpper>() << endl; << m.part<Eigen::StrictlyUpperTriangular>() << endl;
cout << "Here is the unit-lower-triangular matrix extracted from m:" << endl cout << "Here is the unit-lower-triangular matrix extracted from m:" << endl
<< m.part<Eigen::UnitLower>() << endl; << m.part<Eigen::UnitLowerTriangular>() << endl;

View File

@ -1,9 +1,9 @@
Matrix3d m = Matrix3d::Zero(); Matrix3d m = Matrix3d::Zero();
m.part<Eigen::Upper>().setOnes(); m.part<Eigen::UpperTriangular>().setOnes();
cout << "Here is the matrix m:" << endl << m << endl; cout << "Here is the matrix m:" << endl << m << endl;
Matrix3d n = Matrix3d::Ones(); Matrix3d n = Matrix3d::Ones();
n.part<Eigen::Lower>() *= 2; n.part<Eigen::LowerTriangular>() *= 2;
cout << "Here is the matrix n:" << endl << n << endl; cout << "Here is the matrix n:" << endl << n << endl;
cout << "And now here is m.inverse()*n, taking advantage of the fact that" cout << "And now here is m.inverse()*n, taking advantage of the fact that"
" m is upper-triangular:" << endl " m is upper-triangular:" << endl
<< m.marked<Eigen::Upper>().solveTriangular(n); << m.marked<Eigen::UpperTriangular>().solveTriangular(n);

View File

@ -1,5 +1,5 @@
Matrix3d m = Matrix3i::Zero(); Matrix3d m = Matrix3i::Zero();
m.part<Eigen::StrictlyUpper>().setOnes(); m.part<Eigen::StrictlyUpperTriangular>().setOnes();
cout << "Here is the matrix m:" << endl << m << endl; cout << "Here is the matrix m:" << endl << m << endl;
cout << "And let us now compute m*m.adjoint() in a very optimized way" << endl cout << "And let us now compute m*m.adjoint() in a very optimized way" << endl
<< "taking advantage of the symmetry." << endl; << "taking advantage of the symmetry." << endl;

View File

@ -7,7 +7,7 @@ cout << "Here is, up to permutations, its LU decomposition matrix:"
<< endl << lu.matrixLU() << endl; << endl << lu.matrixLU() << endl;
cout << "Here is the actual L matrix in this decomposition:" << endl; cout << "Here is the actual L matrix in this decomposition:" << endl;
Matrix5x5 l = Matrix5x5::Identity(); Matrix5x5 l = Matrix5x5::Identity();
l.block<5,3>(0,0).part<StrictlyLower>() = lu.matrixLU(); l.block<5,3>(0,0).part<StrictlyLowerTriangular>() = lu.matrixLU();
cout << l << endl; cout << l << endl;
cout << "Let us now reconstruct the original matrix m:" << endl; cout << "Let us now reconstruct the original matrix m:" << endl;
Matrix5x3 x = l * lu.matrixU(); Matrix5x3 x = l * lu.matrixU();

View File

@ -131,9 +131,11 @@ macro(ei_add_test testname)
target_link_libraries(${targetname} ${EXTERNAL_LIBS}) target_link_libraries(${targetname} ${EXTERNAL_LIBS})
if(${ARGC} GREATER 2) if(${ARGC} GREATER 2)
if(ARGV2) string(STRIP "${ARGV2}" ARGV2_stripped)
string(LENGTH "${ARGV2_stripped}" ARGV2_stripped_length)
if(${ARGV2_stripped_length} GREATER 0)
target_link_libraries(${targetname} ${ARGV2}) target_link_libraries(${targetname} ${ARGV2})
endif(ARGV2) endif(${ARGV2_stripped_length} GREATER 0)
endif(${ARGC} GREATER 2) endif(${ARGC} GREATER 2)
if(WIN32) if(WIN32)

View File

@ -44,13 +44,13 @@ template<typename Scalar> void sparse_solvers(int rows, int cols)
// lower // lower
initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular, &zeroCoords, &nonzeroCoords); initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular, &zeroCoords, &nonzeroCoords);
VERIFY_IS_APPROX(refMat2.template marked<Lower>().solveTriangular(vec2), VERIFY_IS_APPROX(refMat2.template marked<LowerTriangular>().solveTriangular(vec2),
m2.template marked<Lower>().solveTriangular(vec3)); m2.template marked<LowerTriangular>().solveTriangular(vec3));
// upper // upper
initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeUpperTriangular, &zeroCoords, &nonzeroCoords); initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeUpperTriangular, &zeroCoords, &nonzeroCoords);
VERIFY_IS_APPROX(refMat2.template marked<Upper>().solveTriangular(vec2), VERIFY_IS_APPROX(refMat2.template marked<UpperTriangular>().solveTriangular(vec2),
m2.template marked<Upper>().solveTriangular(vec3)); m2.template marked<UpperTriangular>().solveTriangular(vec3));
// TODO test row major // TODO test row major
} }
@ -70,7 +70,7 @@ template<typename Scalar> void sparse_solvers(int rows, int cols)
refMat2.diagonal() *= 0.5; refMat2.diagonal() *= 0.5;
refMat2.llt().solve(b, &refX); refMat2.llt().solve(b, &refX);
typedef SparseMatrix<Scalar,Lower|SelfAdjoint> SparseSelfAdjointMatrix; typedef SparseMatrix<Scalar,LowerTriangular|SelfAdjoint> SparseSelfAdjointMatrix;
x = b; x = b;
SparseLLT<SparseSelfAdjointMatrix> (m2).solveInPlace(x); SparseLLT<SparseSelfAdjointMatrix> (m2).solveInPlace(x);
//VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LLT: default"); //VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LLT: default");
@ -107,7 +107,7 @@ template<typename Scalar> void sparse_solvers(int rows, int cols)
refMat2.diagonal() *= 0.5; refMat2.diagonal() *= 0.5;
refMat2.ldlt().solve(b, &refX); refMat2.ldlt().solve(b, &refX);
typedef SparseMatrix<Scalar,Lower|SelfAdjoint> SparseSelfAdjointMatrix; typedef SparseMatrix<Scalar,LowerTriangular|SelfAdjoint> SparseSelfAdjointMatrix;
x = b; x = b;
SparseLDLT<SparseSelfAdjointMatrix> ldlt(m2); SparseLDLT<SparseSelfAdjointMatrix> ldlt(m2);
if (ldlt.succeeded()) if (ldlt.succeeded())

View File

@ -51,14 +51,14 @@ template<typename MatrixType> void triangular(const MatrixType& m)
v2 = VectorType::Random(rows), v2 = VectorType::Random(rows),
vzero = VectorType::Zero(rows); vzero = VectorType::Zero(rows);
MatrixType m1up = m1.template part<Eigen::Upper>(); MatrixType m1up = m1.template part<Eigen::UpperTriangular>();
MatrixType m2up = m2.template part<Eigen::Upper>(); MatrixType m2up = m2.template part<Eigen::UpperTriangular>();
if (rows*cols>1) if (rows*cols>1)
{ {
VERIFY(m1up.isUpper()); VERIFY(m1up.isUpperTriangular());
VERIFY(m2up.transpose().isLower()); VERIFY(m2up.transpose().isLowerTriangular());
VERIFY(!m2.isLower()); VERIFY(!m2.isLowerTriangular());
} }
// VERIFY_IS_APPROX(m1up.transpose() * m2, m1.upper().transpose().lower() * m2); // VERIFY_IS_APPROX(m1up.transpose() * m2, m1.upper().transpose().lower() * m2);
@ -66,20 +66,20 @@ template<typename MatrixType> void triangular(const MatrixType& m)
// test overloaded operator+= // test overloaded operator+=
r1.setZero(); r1.setZero();
r2.setZero(); r2.setZero();
r1.template part<Eigen::Upper>() += m1; r1.template part<Eigen::UpperTriangular>() += m1;
r2 += m1up; r2 += m1up;
VERIFY_IS_APPROX(r1,r2); VERIFY_IS_APPROX(r1,r2);
// test overloaded operator= // test overloaded operator=
m1.setZero(); m1.setZero();
m1.template part<Eigen::Upper>() = (m2.transpose() * m2).lazy(); m1.template part<Eigen::UpperTriangular>() = (m2.transpose() * m2).lazy();
m3 = m2.transpose() * m2; m3 = m2.transpose() * m2;
VERIFY_IS_APPROX(m3.template part<Eigen::Lower>().transpose(), m1); VERIFY_IS_APPROX(m3.template part<Eigen::LowerTriangular>().transpose(), m1);
// test overloaded operator= // test overloaded operator=
m1.setZero(); m1.setZero();
m1.template part<Eigen::Lower>() = (m2.transpose() * m2).lazy(); m1.template part<Eigen::LowerTriangular>() = (m2.transpose() * m2).lazy();
VERIFY_IS_APPROX(m3.template part<Eigen::Lower>(), m1); VERIFY_IS_APPROX(m3.template part<Eigen::LowerTriangular>(), m1);
VERIFY_IS_APPROX(m3.template part<Diagonal>(), m3.diagonal().asDiagonal()); VERIFY_IS_APPROX(m3.template part<Diagonal>(), m3.diagonal().asDiagonal());
@ -89,30 +89,30 @@ template<typename MatrixType> void triangular(const MatrixType& m)
Transpose<MatrixType> trm4(m4); Transpose<MatrixType> trm4(m4);
// test back and forward subsitution // test back and forward subsitution
m3 = m1.template part<Eigen::Lower>(); m3 = m1.template part<Eigen::LowerTriangular>();
VERIFY(m3.template marked<Eigen::Lower>().solveTriangular(m3).cwise().abs().isIdentity(test_precision<RealScalar>())); VERIFY(m3.template marked<Eigen::LowerTriangular>().solveTriangular(m3).cwise().abs().isIdentity(test_precision<RealScalar>()));
VERIFY(m3.transpose().template marked<Eigen::Upper>() VERIFY(m3.transpose().template marked<Eigen::UpperTriangular>()
.solveTriangular(m3.transpose()).cwise().abs().isIdentity(test_precision<RealScalar>())); .solveTriangular(m3.transpose()).cwise().abs().isIdentity(test_precision<RealScalar>()));
// check M * inv(L) using in place API // check M * inv(L) using in place API
m4 = m3; m4 = m3;
m3.transpose().template marked<Eigen::Upper>().solveTriangularInPlace(trm4); m3.transpose().template marked<Eigen::UpperTriangular>().solveTriangularInPlace(trm4);
VERIFY(m4.cwise().abs().isIdentity(test_precision<RealScalar>())); VERIFY(m4.cwise().abs().isIdentity(test_precision<RealScalar>()));
m3 = m1.template part<Eigen::Upper>(); m3 = m1.template part<Eigen::UpperTriangular>();
VERIFY(m3.template marked<Eigen::Upper>().solveTriangular(m3).cwise().abs().isIdentity(test_precision<RealScalar>())); VERIFY(m3.template marked<Eigen::UpperTriangular>().solveTriangular(m3).cwise().abs().isIdentity(test_precision<RealScalar>()));
VERIFY(m3.transpose().template marked<Eigen::Lower>() VERIFY(m3.transpose().template marked<Eigen::LowerTriangular>()
.solveTriangular(m3.transpose()).cwise().abs().isIdentity(test_precision<RealScalar>())); .solveTriangular(m3.transpose()).cwise().abs().isIdentity(test_precision<RealScalar>()));
// check M * inv(U) using in place API // check M * inv(U) using in place API
m4 = m3; m4 = m3;
m3.transpose().template marked<Eigen::Lower>().solveTriangularInPlace(trm4); m3.transpose().template marked<Eigen::LowerTriangular>().solveTriangularInPlace(trm4);
VERIFY(m4.cwise().abs().isIdentity(test_precision<RealScalar>())); VERIFY(m4.cwise().abs().isIdentity(test_precision<RealScalar>()));
m3 = m1.template part<Eigen::Upper>(); m3 = m1.template part<Eigen::UpperTriangular>();
VERIFY(m2.isApprox(m3 * (m3.template marked<Eigen::Upper>().solveTriangular(m2)), largerEps)); VERIFY(m2.isApprox(m3 * (m3.template marked<Eigen::UpperTriangular>().solveTriangular(m2)), largerEps));
m3 = m1.template part<Eigen::Lower>(); m3 = m1.template part<Eigen::LowerTriangular>();
VERIFY(m2.isApprox(m3 * (m3.template marked<Eigen::Lower>().solveTriangular(m2)), largerEps)); VERIFY(m2.isApprox(m3 * (m3.template marked<Eigen::LowerTriangular>().solveTriangular(m2)), largerEps));
VERIFY((m1.template part<Eigen::Upper>() * m2.template part<Eigen::Upper>()).isUpper()); VERIFY((m1.template part<Eigen::UpperTriangular>() * m2.template part<Eigen::UpperTriangular>()).isUpperTriangular());
} }