mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-03-19 18:40:38 +08:00
* the Upper->UpperTriangular change
* finally get ei_add_test right
This commit is contained in:
parent
21ab65e4b3
commit
9e00d94543
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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 };
|
||||
|
@ -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
|
||||
|
@ -243,7 +243,7 @@ HessenbergDecomposition<MatrixType>::matrixH(void) const
|
||||
int n = m_matrix.rows();
|
||||
MatrixType matH = m_matrix;
|
||||
if (n>2)
|
||||
matH.corner(BottomLeft,n-2, n-2).template part<Lower>().setZero();
|
||||
matH.corner(BottomLeft,n-2, n-2).template part<LowerTriangular>().setZero();
|
||||
return matH;
|
||||
}
|
||||
|
||||
|
@ -60,11 +60,11 @@ template<typename MatrixType> class QR
|
||||
bool isFullRank() const { return ei_isMuchSmallerThan(m_hCoeffs.cwise().abs().minCoeff(), Scalar(1)); }
|
||||
|
||||
/** \returns a read-only expression of the matrix R of the actual the QR decomposition */
|
||||
const Part<NestByValue<MatrixRBlockType>, Upper>
|
||||
const Part<NestByValue<MatrixRBlockType>, UpperTriangular>
|
||||
matrixR(void) const
|
||||
{
|
||||
int cols = m_qr.cols();
|
||||
return MatrixRBlockType(m_qr, 0, 0, cols, cols).nestByValue().template part<Upper>();
|
||||
return MatrixRBlockType(m_qr, 0, 0, cols, cols).nestByValue().template part<UpperTriangular>();
|
||||
}
|
||||
|
||||
MatrixType matrixQ(void) const;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -162,9 +162,9 @@ struct SluMatrixMapHelper<SparseMatrix<Scalar,Flags> >
|
||||
res.setScalarType<Scalar>();
|
||||
|
||||
// FIXME the following is not very accurate
|
||||
if (Flags & Upper)
|
||||
if (Flags & UpperTriangular)
|
||||
res.Mtype = SLU_TRU;
|
||||
if (Flags & Lower)
|
||||
if (Flags & LowerTriangular)
|
||||
res.Mtype = SLU_TRL;
|
||||
if (Flags & SelfAdjoint)
|
||||
ei_assert(false && "SelfAdjoint matrix shape not supported by SuperLU");
|
||||
@ -213,8 +213,8 @@ class SparseLU<MatrixType,SuperLU> : public SparseLU<MatrixType>
|
||||
typedef Matrix<Scalar,Dynamic,1> Vector;
|
||||
typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
|
||||
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
|
||||
typedef SparseMatrix<Scalar,Lower|UnitDiagBit> LMatrixType;
|
||||
typedef SparseMatrix<Scalar,Upper> UMatrixType;
|
||||
typedef SparseMatrix<Scalar,LowerTriangular|UnitDiagBit> LMatrixType;
|
||||
typedef SparseMatrix<Scalar,UpperTriangular> UMatrixType;
|
||||
using Base::m_flags;
|
||||
using Base::m_status;
|
||||
|
||||
|
@ -50,13 +50,13 @@ taucs_ccs_matrix SparseMatrix<Scalar,Flags>::asTaucsMatrix()
|
||||
ei_assert(false && "Scalar type not supported by TAUCS");
|
||||
}
|
||||
|
||||
if (Flags & Upper)
|
||||
if (Flags & UpperTriangular)
|
||||
res.flags |= TAUCS_UPPER;
|
||||
if (Flags & Lower)
|
||||
if (Flags & LowerTriangular)
|
||||
res.flags |= TAUCS_LOWER;
|
||||
if (Flags & SelfAdjoint)
|
||||
res.flags |= (NumTraits<Scalar>::IsComplex ? TAUCS_HERMITIAN : TAUCS_SYMMETRIC);
|
||||
else if ((Flags & Upper) || (Flags & Lower))
|
||||
else if ((Flags & UpperTriangular) || (Flags & LowerTriangular))
|
||||
res.flags |= TAUCS_TRIANGULAR;
|
||||
|
||||
return res;
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
// forward substitution, row-major
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct ei_solve_triangular_selector<Lhs,Rhs,Lower,RowMajor|IsSparse>
|
||||
struct ei_solve_triangular_selector<Lhs,Rhs,LowerTriangular,RowMajor|IsSparse>
|
||||
{
|
||||
typedef typename Rhs::Scalar Scalar;
|
||||
static void run(const Lhs& lhs, Rhs& other)
|
||||
@ -59,7 +59,7 @@ struct ei_solve_triangular_selector<Lhs,Rhs,Lower,RowMajor|IsSparse>
|
||||
|
||||
// backward substitution, row-major
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct ei_solve_triangular_selector<Lhs,Rhs,Upper,RowMajor|IsSparse>
|
||||
struct ei_solve_triangular_selector<Lhs,Rhs,UpperTriangular,RowMajor|IsSparse>
|
||||
{
|
||||
typedef typename Rhs::Scalar Scalar;
|
||||
static void run(const Lhs& lhs, Rhs& other)
|
||||
@ -92,7 +92,7 @@ struct ei_solve_triangular_selector<Lhs,Rhs,Upper,RowMajor|IsSparse>
|
||||
|
||||
// forward substitution, col-major
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct ei_solve_triangular_selector<Lhs,Rhs,Lower,ColMajor|IsSparse>
|
||||
struct ei_solve_triangular_selector<Lhs,Rhs,LowerTriangular,ColMajor|IsSparse>
|
||||
{
|
||||
typedef typename Rhs::Scalar Scalar;
|
||||
static void run(const Lhs& lhs, Rhs& other)
|
||||
@ -120,7 +120,7 @@ struct ei_solve_triangular_selector<Lhs,Rhs,Lower,ColMajor|IsSparse>
|
||||
|
||||
// backward substitution, col-major
|
||||
template<typename Lhs, typename Rhs>
|
||||
struct ei_solve_triangular_selector<Lhs,Rhs,Upper,ColMajor|IsSparse>
|
||||
struct ei_solve_triangular_selector<Lhs,Rhs,UpperTriangular,ColMajor|IsSparse>
|
||||
{
|
||||
typedef typename Rhs::Scalar Scalar;
|
||||
static void run(const Lhs& lhs, Rhs& other)
|
||||
|
@ -127,8 +127,8 @@ class SparseLU<MatrixType,UmfPack> : public SparseLU<MatrixType>
|
||||
typedef Matrix<Scalar,Dynamic,1> Vector;
|
||||
typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
|
||||
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
|
||||
typedef SparseMatrix<Scalar,Lower|UnitDiagBit> LMatrixType;
|
||||
typedef SparseMatrix<Scalar,Upper> UMatrixType;
|
||||
typedef SparseMatrix<Scalar,LowerTriangular|UnitDiagBit> LMatrixType;
|
||||
typedef SparseMatrix<Scalar,UpperTriangular> UMatrixType;
|
||||
using Base::m_flags;
|
||||
using Base::m_status;
|
||||
|
||||
|
@ -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){
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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())
|
||||
|
@ -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());
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user