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

View File

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

View File

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

View File

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

View File

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

View File

@ -31,8 +31,8 @@
* \brief Expression of a triangular matrix extracted from a given matrix
*
* \param MatrixType the type of the object in which we are taking the triangular part
* \param Mode the kind of triangular matrix expression to construct. Can be Upper, StrictlyUpper,
* UnitUpper, Lower, StrictlyLower, UnitLower. This is in fact a bit field; it must have either
* \param Mode the kind of triangular matrix expression to construct. Can be UpperTriangular, StrictlyUpperTriangular,
* UnitUpperTriangular, LowerTriangular, StrictlyLowerTriangular, UnitLowerTriangular. This is in fact a bit field; it must have either
* UpperTriangularBit or LowerTriangularBit, and additionnaly it may have either ZeroDiagBit or
* UnitDiagBit.
*
@ -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 & SelfAdjointBit), COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED)
ei_assert( (Mode==Upper && col>=row)
|| (Mode==Lower && col<=row)
|| (Mode==StrictlyUpper && col>row)
|| (Mode==StrictlyLower && col<row));
ei_assert( (Mode==UpperTriangular && col>=row)
|| (Mode==LowerTriangular && col<=row)
|| (Mode==StrictlyUpperTriangular && col>row)
|| (Mode==StrictlyLowerTriangular && col<row));
return m_matrix.const_cast_derived().coeffRef(row, col);
}
@ -134,8 +134,8 @@ template<typename MatrixType, unsigned int Mode> class Part
/** \returns an expression of a triangular matrix extracted from the current matrix
*
* The parameter \a Mode can have the following values: \c Upper, \c StrictlyUpper, \c UnitUpper,
* \c Lower, \c StrictlyLower, \c UnitLower.
* The parameter \a Mode can have the following values: \c UpperTriangular, \c StrictlyUpperTriangular, \c UnitUpperTriangular,
* \c LowerTriangular, \c StrictlyLowerTriangular, \c UnitLowerTriangular.
*
* \addexample PartExample \label How to extract a triangular part of an arbitrary matrix
*
@ -187,11 +187,11 @@ struct ei_part_assignment_impl
}
else
{
ei_assert(Mode == Upper || Mode == Lower || Mode == StrictlyUpper || Mode == StrictlyLower);
if((Mode == Upper && row <= col)
|| (Mode == Lower && row >= col)
|| (Mode == StrictlyUpper && row < col)
|| (Mode == StrictlyLower && row > col))
ei_assert(Mode == UpperTriangular || Mode == LowerTriangular || Mode == StrictlyUpperTriangular || Mode == StrictlyLowerTriangular);
if((Mode == UpperTriangular && row <= col)
|| (Mode == LowerTriangular && row >= col)
|| (Mode == StrictlyUpperTriangular && row < col)
|| (Mode == StrictlyLowerTriangular && row > col))
dst.copyCoeff(row, col, src);
}
}
@ -215,7 +215,7 @@ struct ei_part_assignment_impl<Derived1, Derived2, Mode, 0>
};
template<typename Derived1, typename Derived2>
struct ei_part_assignment_impl<Derived1, Derived2, Upper, Dynamic>
struct ei_part_assignment_impl<Derived1, Derived2, UpperTriangular, Dynamic>
{
inline static void run(Derived1 &dst, const Derived2 &src)
{
@ -226,7 +226,7 @@ struct ei_part_assignment_impl<Derived1, Derived2, Upper, Dynamic>
};
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)
{
@ -237,7 +237,7 @@ struct ei_part_assignment_impl<Derived1, Derived2, Lower, Dynamic>
};
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)
{
@ -247,7 +247,7 @@ struct ei_part_assignment_impl<Derived1, Derived2, StrictlyUpper, Dynamic>
}
};
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)
{
@ -285,8 +285,8 @@ void Part<MatrixType, Mode>::lazyAssign(const Other& other)
/** \returns a lvalue pseudo-expression allowing to perform special operations on \c *this.
*
* The \a Mode parameter can have the following values: \c Upper, \c StrictlyUpper, \c Lower,
* \c StrictlyLower, \c SelfAdjoint.
* The \a Mode parameter can have the following values: \c UpperTriangular, \c StrictlyUpperTriangular, \c LowerTriangular,
* \c StrictlyLowerTriangular, \c SelfAdjoint.
*
* \addexample PartExample \label How to write to a triangular part of a matrix
*
@ -305,44 +305,44 @@ inline Part<Derived, Mode> MatrixBase<Derived>::part()
/** \returns true if *this is approximately equal to an upper triangular matrix,
* within the precision given by \a prec.
*
* \sa isLower(), extract(), part(), marked()
* \sa isLowerTriangular(), extract(), part(), marked()
*/
template<typename Derived>
bool MatrixBase<Derived>::isUpper(RealScalar prec) const
bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const
{
if(cols() != rows()) return false;
RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1);
RealScalar maxAbsOnUpperTriangularPart = static_cast<RealScalar>(-1);
for(int j = 0; j < cols(); ++j)
for(int i = 0; i <= j; ++i)
{
RealScalar absValue = ei_abs(coeff(i,j));
if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
if(absValue > maxAbsOnUpperTriangularPart) maxAbsOnUpperTriangularPart = absValue;
}
for(int j = 0; j < cols()-1; ++j)
for(int i = j+1; i < rows(); ++i)
if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnUpperPart, prec)) return false;
if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnUpperTriangularPart, prec)) return false;
return true;
}
/** \returns true if *this is approximately equal to a lower triangular matrix,
* within the precision given by \a prec.
*
* \sa isUpper(), extract(), part(), marked()
* \sa isUpperTriangular(), extract(), part(), marked()
*/
template<typename Derived>
bool MatrixBase<Derived>::isLower(RealScalar prec) const
bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const
{
if(cols() != rows()) return false;
RealScalar maxAbsOnLowerPart = static_cast<RealScalar>(-1);
RealScalar maxAbsOnLowerTriangularPart = static_cast<RealScalar>(-1);
for(int j = 0; j < cols(); ++j)
for(int i = j; i < rows(); ++i)
{
RealScalar absValue = ei_abs(coeff(i,j));
if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
if(absValue > maxAbsOnLowerTriangularPart) maxAbsOnLowerTriangularPart = absValue;
}
for(int j = 1; j < cols(); ++j)
for(int i = 0; i < j; ++i)
if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnLowerPart, prec)) return false;
if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnLowerTriangularPart, prec)) return false;
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,
int TriangularPart = (int(Lhs::Flags) & LowerTriangularBit)
? Lower
? LowerTriangular
: (int(Lhs::Flags) & UpperTriangularBit)
? Upper
? UpperTriangular
: -1,
int StorageOrder = ei_is_part<Lhs>::value ? -1 // this is to solve ambiguous specializations
: int(Lhs::Flags) & (RowMajorBit|SparseBit)
@ -56,14 +56,14 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,RowMajor|IsDense>
typedef typename Rhs::Scalar Scalar;
static void run(const Lhs& lhs, Rhs& other)
{
const bool IsLower = (UpLo==Lower);
const bool IsLowerTriangular = (UpLo==LowerTriangular);
const int size = lhs.cols();
/* We perform the inverse product per block of 4 rows such that we perfectly match
* our optimized matrix * vector product. blockyStart represents the number of rows
* we have process first using the non-block version.
*/
int blockyStart = (std::max(size-5,0)/4)*4;
if (IsLower)
if (IsLowerTriangular)
blockyStart = size - blockyStart;
else
blockyStart -= 1;
@ -72,15 +72,15 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,RowMajor|IsDense>
// process first rows using the non block version
if(!(Lhs::Flags & UnitDiagBit))
{
if (IsLower)
if (IsLowerTriangular)
other.coeffRef(0,c) = other.coeff(0,c)/lhs.coeff(0, 0);
else
other.coeffRef(size-1,c) = other.coeff(size-1, c)/lhs.coeff(size-1, size-1);
}
for(int i=(IsLower ? 1 : size-2); IsLower ? i<blockyStart : i>blockyStart; i += (IsLower ? 1 : -1) )
for(int i=(IsLowerTriangular ? 1 : size-2); IsLowerTriangular ? i<blockyStart : i>blockyStart; i += (IsLowerTriangular ? 1 : -1) )
{
Scalar tmp = other.coeff(i,c)
- (IsLower ? ((lhs.row(i).start(i)) * other.col(c).start(i)).coeff(0,0)
- (IsLowerTriangular ? ((lhs.row(i).start(i)) * other.col(c).start(i)).coeff(0,0)
: ((lhs.row(i).end(size-i-1)) * other.col(c).end(size-i-1)).coeff(0,0));
if (Lhs::Flags & UnitDiagBit)
other.coeffRef(i,c) = tmp;
@ -89,15 +89,15 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,RowMajor|IsDense>
}
// now let's process the remaining rows 4 at once
for(int i=blockyStart; IsLower ? i<size : i>0; )
for(int i=blockyStart; IsLowerTriangular ? i<size : i>0; )
{
int startBlock = i;
int endBlock = startBlock + (IsLower ? 4 : -4);
int endBlock = startBlock + (IsLowerTriangular ? 4 : -4);
/* Process the i cols times 4 rows block, and keep the result in a temporary vector */
// FIXME use fixed size block but take care to small fixed size matrices...
Matrix<Scalar,Dynamic,1> btmp(4);
if (IsLower)
if (IsLowerTriangular)
btmp = lhs.block(startBlock,0,4,i) * other.col(c).start(i);
else
btmp = lhs.block(i-3,i+1,4,size-1-i) * other.col(c).end(size-1-i);
@ -106,21 +106,21 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,RowMajor|IsDense>
* btmp stores the diagonal coefficients used to update the remaining part of the result.
*/
{
Scalar tmp = other.coeff(startBlock,c)-btmp.coeff(IsLower?0:3);
Scalar tmp = other.coeff(startBlock,c)-btmp.coeff(IsLowerTriangular?0:3);
if (Lhs::Flags & UnitDiagBit)
other.coeffRef(i,c) = tmp;
else
other.coeffRef(i,c) = tmp/lhs.coeff(i,i);
}
i += IsLower ? 1 : -1;
for (;IsLower ? i<endBlock : i>endBlock; i += IsLower ? 1 : -1)
i += IsLowerTriangular ? 1 : -1;
for (;IsLowerTriangular ? i<endBlock : i>endBlock; i += IsLowerTriangular ? 1 : -1)
{
int remainingSize = IsLower ? i-startBlock : startBlock-i;
int remainingSize = IsLowerTriangular ? i-startBlock : startBlock-i;
Scalar tmp = other.coeff(i,c)
- btmp.coeff(IsLower ? remainingSize : 3-remainingSize)
- ( lhs.row(i).segment(IsLower ? startBlock : i+1, remainingSize)
* other.col(c).segment(IsLower ? startBlock : i+1, remainingSize)).coeff(0,0);
- btmp.coeff(IsLowerTriangular ? remainingSize : 3-remainingSize)
- ( lhs.row(i).segment(IsLowerTriangular ? startBlock : i+1, remainingSize)
* other.col(c).segment(IsLowerTriangular ? startBlock : i+1, remainingSize)).coeff(0,0);
if (Lhs::Flags & UnitDiagBit)
other.coeffRef(i,c) = tmp;
@ -133,10 +133,10 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,RowMajor|IsDense>
};
// Implements the following configurations:
// - inv(Lower, ColMajor) * Column vector
// - inv(Lower,UnitDiag,ColMajor) * Column vector
// - inv(Upper, ColMajor) * Column vector
// - inv(Upper,UnitDiag,ColMajor) * Column vector
// - inv(LowerTriangular, ColMajor) * Column vector
// - inv(LowerTriangular,UnitDiag,ColMajor) * Column vector
// - inv(UpperTriangular, ColMajor) * Column vector
// - inv(UpperTriangular,UnitDiag,ColMajor) * Column vector
template<typename Lhs, typename Rhs, int UpLo>
struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,ColMajor|IsDense>
{
@ -146,7 +146,7 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,ColMajor|IsDense>
static void run(const Lhs& lhs, Rhs& other)
{
static const bool IsLower = (UpLo==Lower);
static const bool IsLowerTriangular = (UpLo==LowerTriangular);
const int size = lhs.cols();
for(int c=0 ; c<other.cols() ; ++c)
{
@ -155,27 +155,27 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,ColMajor|IsDense>
* we can process using the block version.
*/
int blockyEnd = (std::max(size-5,0)/4)*4;
if (!IsLower)
if (!IsLowerTriangular)
blockyEnd = size-1 - blockyEnd;
for(int i=IsLower ? 0 : size-1; IsLower ? i<blockyEnd : i>blockyEnd;)
for(int i=IsLowerTriangular ? 0 : size-1; IsLowerTriangular ? i<blockyEnd : i>blockyEnd;)
{
/* Let's process the 4x4 sub-matrix as usual.
* btmp stores the diagonal coefficients used to update the remaining part of the result.
*/
int startBlock = i;
int endBlock = startBlock + (IsLower ? 4 : -4);
int endBlock = startBlock + (IsLowerTriangular ? 4 : -4);
Matrix<Scalar,4,1> btmp;
for (;IsLower ? i<endBlock : i>endBlock;
i += IsLower ? 1 : -1)
for (;IsLowerTriangular ? i<endBlock : i>endBlock;
i += IsLowerTriangular ? 1 : -1)
{
if(!(Lhs::Flags & UnitDiagBit))
other.coeffRef(i,c) /= lhs.coeff(i,i);
int remainingSize = IsLower ? endBlock-i-1 : i-endBlock-1;
int remainingSize = IsLowerTriangular ? endBlock-i-1 : i-endBlock-1;
if (remainingSize>0)
other.col(c).segment((IsLower ? i : endBlock) + 1, remainingSize) -=
other.col(c).segment((IsLowerTriangular ? i : endBlock) + 1, remainingSize) -=
other.coeffRef(i,c)
* Block<Lhs,Dynamic,1>(lhs, (IsLower ? i : endBlock) + 1, i, remainingSize, 1);
btmp.coeffRef(IsLower ? i-startBlock : remainingSize) = -other.coeffRef(i,c);
* Block<Lhs,Dynamic,1>(lhs, (IsLowerTriangular ? i : endBlock) + 1, i, remainingSize, 1);
btmp.coeffRef(IsLowerTriangular ? i-startBlock : remainingSize) = -other.coeffRef(i,c);
}
/* Now we can efficiently update the remaining part of the result as a matrix * vector product.
@ -187,11 +187,11 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,ColMajor|IsDense>
// FIXME this is cool but what about conjugate/adjoint expressions ? do we want to evaluate them ?
// this is a more general problem though.
ei_cache_friendly_product_colmajor_times_vector(
IsLower ? size-endBlock : endBlock+1,
&(lhs.const_cast_derived().coeffRef(IsLower ? endBlock : 0, IsLower ? startBlock : endBlock+1)),
IsLowerTriangular ? size-endBlock : endBlock+1,
&(lhs.const_cast_derived().coeffRef(IsLowerTriangular ? endBlock : 0, IsLowerTriangular ? startBlock : endBlock+1)),
lhs.stride(),
btmp, &(other.coeffRef(IsLower ? endBlock : 0, c)));
// if (IsLower)
btmp, &(other.coeffRef(IsLowerTriangular ? endBlock : 0, c)));
// if (IsLowerTriangular)
// other.col(c).end(size-endBlock) += (lhs.block(endBlock, startBlock, size-endBlock, endBlock-startBlock)
// * other.col(c).block(startBlock,endBlock-startBlock)).lazy();
// else
@ -201,7 +201,7 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,ColMajor|IsDense>
/* Now we have to process the remaining part as usual */
int i;
for(i=blockyEnd; IsLower ? i<size-1 : i>0; i += (IsLower ? 1 : -1) )
for(i=blockyEnd; IsLowerTriangular ? i<size-1 : i>0; i += (IsLowerTriangular ? 1 : -1) )
{
if(!(Lhs::Flags & UnitDiagBit))
other.coeffRef(i,c) /= lhs.coeff(i,i);
@ -209,7 +209,7 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,ColMajor|IsDense>
/* NOTE we cannot use lhs.col(i).end(size-i-1) because Part::coeffRef gets called by .col() to
* get the address of the start of the row
*/
if(IsLower)
if(IsLowerTriangular)
other.col(c).end(size-i-1) -= other.coeffRef(i,c) * Block<Lhs,Dynamic,1>(lhs, i+1,i, size-i-1,1);
else
other.col(c).start(i) -= other.coeffRef(i,c) * Block<Lhs,Dynamic,1>(lhs, 0,i, i, 1);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,8 +1,8 @@
Matrix3i m = Matrix3i::Random();
cout << "Here is the matrix m:" << endl << 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
<< m.part<Eigen::StrictlyUpper>() << endl;
<< m.part<Eigen::StrictlyUpperTriangular>() << 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();
m.part<Eigen::Upper>().setOnes();
m.part<Eigen::UpperTriangular>().setOnes();
cout << "Here is the matrix m:" << endl << m << endl;
Matrix3d n = Matrix3d::Ones();
n.part<Eigen::Lower>() *= 2;
n.part<Eigen::LowerTriangular>() *= 2;
cout << "Here is the matrix n:" << endl << n << endl;
cout << "And now here is m.inverse()*n, taking advantage of the fact that"
" 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();
m.part<Eigen::StrictlyUpper>().setOnes();
m.part<Eigen::StrictlyUpperTriangular>().setOnes();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "And let us now compute m*m.adjoint() in a very optimized way" << 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;
cout << "Here is the actual L matrix in this decomposition:" << endl;
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 << "Let us now reconstruct the original matrix m:" << endl;
Matrix5x3 x = l * lu.matrixU();

View File

@ -131,9 +131,11 @@ macro(ei_add_test testname)
target_link_libraries(${targetname} ${EXTERNAL_LIBS})
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})
endif(ARGV2)
endif(${ARGV2_stripped_length} GREATER 0)
endif(${ARGC} GREATER 2)
if(WIN32)

View File

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

View File

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