mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
remove the Triangular suffix to Upper, Lower, UnitLower, etc,
and remove the respective bit flags
This commit is contained in:
@@ -405,13 +405,6 @@ template<typename Derived> class MatrixBase
|
||||
template<int Size> const VectorBlock<Derived,Size> start() const;
|
||||
template<int Size> VectorBlock<Derived,Size> end();
|
||||
template<int Size> const VectorBlock<Derived,Size> end() const;
|
||||
|
||||
template<typename OtherDerived>
|
||||
typename ei_plain_matrix_type_column_major<OtherDerived>::type
|
||||
solveTriangular(const MatrixBase<OtherDerived>& other) const;
|
||||
|
||||
template<typename OtherDerived>
|
||||
void solveTriangularInPlace(const MatrixBase<OtherDerived>& other) const;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
* \brief Expression of a selfadjoint matrix from a triangular part of a dense matrix
|
||||
*
|
||||
* \param MatrixType the type of the dense matrix storing the coefficients
|
||||
* \param TriangularPart can be either \c LowerTriangular or \c UpperTriangular
|
||||
* \param TriangularPart can be either \c Lower or \c Upper
|
||||
*
|
||||
* This class is an expression of a sefladjoint matrix from a triangular part of a matrix
|
||||
* with given dense storage of the coefficients. It is the return type of MatrixBase::selfadjointView()
|
||||
@@ -46,7 +46,7 @@ struct ei_traits<SelfAdjointView<MatrixType, TriangularPart> > : ei_traits<Matri
|
||||
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
|
||||
typedef MatrixType ExpressionType;
|
||||
enum {
|
||||
Mode = TriangularPart | SelfAdjointBit,
|
||||
Mode = TriangularPart | SelfAdjoint,
|
||||
Flags = _MatrixTypeNested::Flags & (HereditaryBits)
|
||||
& (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)), // FIXME these flags should be preserved
|
||||
CoeffReadCost = _MatrixTypeNested::CoeffReadCost
|
||||
|
||||
@@ -57,7 +57,7 @@ struct ei_triangular_solver_selector<Lhs,Rhs,OnTheLeft,Mode,NoUnrolling,RowMajor
|
||||
typedef ei_blas_traits<Lhs> LhsProductTraits;
|
||||
typedef typename LhsProductTraits::ExtractType ActualLhsType;
|
||||
enum {
|
||||
IsLowerTriangular = ((Mode&LowerTriangularBit)==LowerTriangularBit)
|
||||
IsLower = ((Mode&Lower)==Lower)
|
||||
};
|
||||
static void run(const Lhs& lhs, Rhs& other)
|
||||
{
|
||||
@@ -65,20 +65,20 @@ struct ei_triangular_solver_selector<Lhs,Rhs,OnTheLeft,Mode,NoUnrolling,RowMajor
|
||||
ActualLhsType actualLhs = LhsProductTraits::extract(lhs);
|
||||
|
||||
const int size = lhs.cols();
|
||||
for(int pi=IsLowerTriangular ? 0 : size;
|
||||
IsLowerTriangular ? pi<size : pi>0;
|
||||
IsLowerTriangular ? pi+=PanelWidth : pi-=PanelWidth)
|
||||
for(int pi=IsLower ? 0 : size;
|
||||
IsLower ? pi<size : pi>0;
|
||||
IsLower ? pi+=PanelWidth : pi-=PanelWidth)
|
||||
{
|
||||
int actualPanelWidth = std::min(IsLowerTriangular ? size - pi : pi, PanelWidth);
|
||||
int actualPanelWidth = std::min(IsLower ? size - pi : pi, PanelWidth);
|
||||
|
||||
int r = IsLowerTriangular ? pi : size - pi; // remaining size
|
||||
int r = IsLower ? pi : size - pi; // remaining size
|
||||
if (r > 0)
|
||||
{
|
||||
// let's directly call the low level product function because:
|
||||
// 1 - it is faster to compile
|
||||
// 2 - it is slighlty faster at runtime
|
||||
int startRow = IsLowerTriangular ? pi : pi-actualPanelWidth;
|
||||
int startCol = IsLowerTriangular ? 0 : pi;
|
||||
int startRow = IsLower ? pi : pi-actualPanelWidth;
|
||||
int startCol = IsLower ? 0 : pi;
|
||||
VectorBlock<Rhs,Dynamic> target(other,startRow,actualPanelWidth);
|
||||
|
||||
ei_cache_friendly_product_rowmajor_times_vector<LhsProductTraits::NeedToConjugate,false>(
|
||||
@@ -89,12 +89,12 @@ struct ei_triangular_solver_selector<Lhs,Rhs,OnTheLeft,Mode,NoUnrolling,RowMajor
|
||||
|
||||
for(int k=0; k<actualPanelWidth; ++k)
|
||||
{
|
||||
int i = IsLowerTriangular ? pi+k : pi-k-1;
|
||||
int s = IsLowerTriangular ? pi : i+1;
|
||||
int i = IsLower ? pi+k : pi-k-1;
|
||||
int s = IsLower ? pi : i+1;
|
||||
if (k>0)
|
||||
other.coeffRef(i) -= (lhs.row(i).segment(s,k).transpose().cwiseProduct(other.segment(s,k))).sum();
|
||||
|
||||
if(!(Mode & UnitDiagBit))
|
||||
if(!(Mode & UnitDiag))
|
||||
other.coeffRef(i) /= lhs.coeff(i,i);
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@ struct ei_triangular_solver_selector<Lhs,Rhs,OnTheLeft,Mode,NoUnrolling,ColMajor
|
||||
typedef typename LhsProductTraits::ExtractType ActualLhsType;
|
||||
enum {
|
||||
PacketSize = ei_packet_traits<Scalar>::size,
|
||||
IsLowerTriangular = ((Mode&LowerTriangularBit)==LowerTriangularBit)
|
||||
IsLower = ((Mode&Lower)==Lower)
|
||||
};
|
||||
|
||||
static void run(const Lhs& lhs, Rhs& other)
|
||||
@@ -120,26 +120,26 @@ struct ei_triangular_solver_selector<Lhs,Rhs,OnTheLeft,Mode,NoUnrolling,ColMajor
|
||||
ActualLhsType actualLhs = LhsProductTraits::extract(lhs);
|
||||
|
||||
const int size = lhs.cols();
|
||||
for(int pi=IsLowerTriangular ? 0 : size;
|
||||
IsLowerTriangular ? pi<size : pi>0;
|
||||
IsLowerTriangular ? pi+=PanelWidth : pi-=PanelWidth)
|
||||
for(int pi=IsLower ? 0 : size;
|
||||
IsLower ? pi<size : pi>0;
|
||||
IsLower ? pi+=PanelWidth : pi-=PanelWidth)
|
||||
{
|
||||
int actualPanelWidth = std::min(IsLowerTriangular ? size - pi : pi, PanelWidth);
|
||||
int startBlock = IsLowerTriangular ? pi : pi-actualPanelWidth;
|
||||
int endBlock = IsLowerTriangular ? pi + actualPanelWidth : 0;
|
||||
int actualPanelWidth = std::min(IsLower ? size - pi : pi, PanelWidth);
|
||||
int startBlock = IsLower ? pi : pi-actualPanelWidth;
|
||||
int endBlock = IsLower ? pi + actualPanelWidth : 0;
|
||||
|
||||
for(int k=0; k<actualPanelWidth; ++k)
|
||||
{
|
||||
int i = IsLowerTriangular ? pi+k : pi-k-1;
|
||||
if(!(Mode & UnitDiagBit))
|
||||
int i = IsLower ? pi+k : pi-k-1;
|
||||
if(!(Mode & UnitDiag))
|
||||
other.coeffRef(i) /= lhs.coeff(i,i);
|
||||
|
||||
int r = actualPanelWidth - k - 1; // remaining size
|
||||
int s = IsLowerTriangular ? i+1 : i-r;
|
||||
int s = IsLower ? i+1 : i-r;
|
||||
if (r>0)
|
||||
other.segment(s,r) -= other.coeffRef(i) * Block<Lhs,Dynamic,1>(lhs, s, i, r, 1);
|
||||
}
|
||||
int r = IsLowerTriangular ? size - endBlock : startBlock; // remaining size
|
||||
int r = IsLower ? size - endBlock : startBlock; // remaining size
|
||||
if (r > 0)
|
||||
{
|
||||
// let's directly call the low level product function because:
|
||||
@@ -198,16 +198,16 @@ struct ei_triangular_solver_unroller;
|
||||
template<typename Lhs, typename Rhs, int Mode, int Index, int Size>
|
||||
struct ei_triangular_solver_unroller<Lhs,Rhs,Mode,Index,Size,false> {
|
||||
enum {
|
||||
IsLowerTriangular = ((Mode&LowerTriangularBit)==LowerTriangularBit),
|
||||
I = IsLowerTriangular ? Index : Size - Index - 1,
|
||||
S = IsLowerTriangular ? 0 : I+1
|
||||
IsLower = ((Mode&Lower)==Lower),
|
||||
I = IsLower ? Index : Size - Index - 1,
|
||||
S = IsLower ? 0 : I+1
|
||||
};
|
||||
static void run(const Lhs& lhs, Rhs& rhs)
|
||||
{
|
||||
if (Index>0)
|
||||
rhs.coeffRef(I) -= ((lhs.row(I).template segment<Index>(S).transpose()).cwiseProduct(rhs.template segment<Index>(S))).sum();
|
||||
|
||||
if(!(Mode & UnitDiagBit))
|
||||
if(!(Mode & UnitDiag))
|
||||
rhs.coeffRef(I) /= lhs.coeff(I,I);
|
||||
|
||||
ei_triangular_solver_unroller<Lhs,Rhs,Mode,Index+1,Size>::run(lhs,rhs);
|
||||
@@ -245,8 +245,8 @@ void TriangularView<MatrixType,Mode>::solveInPlace(const MatrixBase<OtherDerived
|
||||
OtherDerived& other = _other.const_cast_derived();
|
||||
ei_assert(cols() == rows());
|
||||
ei_assert( (Side==OnTheLeft && cols() == other.rows()) || (Side==OnTheRight && cols() == other.cols()) );
|
||||
ei_assert(!(Mode & ZeroDiagBit));
|
||||
ei_assert(Mode & (UpperTriangularBit|LowerTriangularBit));
|
||||
ei_assert(!(Mode & ZeroDiag));
|
||||
ei_assert(Mode & (Upper|Lower));
|
||||
|
||||
enum { copy = ei_traits<OtherDerived>::Flags & RowMajorBit && OtherDerived::IsVectorAtCompileTime };
|
||||
typedef typename ei_meta_if<copy,
|
||||
|
||||
@@ -49,10 +49,7 @@ struct ei_traits<Transpose<MatrixType> > : ei_traits<MatrixType>
|
||||
ColsAtCompileTime = MatrixType::RowsAtCompileTime,
|
||||
MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
||||
MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
||||
Flags = ((int(_MatrixTypeNested::Flags) ^ RowMajorBit)
|
||||
& ~(LowerTriangularBit | UpperTriangularBit))
|
||||
| (int(_MatrixTypeNested::Flags)&UpperTriangularBit ? LowerTriangularBit : 0)
|
||||
| (int(_MatrixTypeNested::Flags)&LowerTriangularBit ? UpperTriangularBit : 0),
|
||||
Flags = (int(_MatrixTypeNested::Flags) ^ RowMajorBit),
|
||||
CoeffReadCost = _MatrixTypeNested::CoeffReadCost
|
||||
};
|
||||
};
|
||||
@@ -229,7 +226,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 triangularView<StrictlyUpperTriangular>().swap(m.transpose());
|
||||
m.template triangularView<StrictlyUpper>().swap(m.transpose());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -237,7 +234,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 triangularView<StrictlyUpperTriangular>().swap(m.transpose());
|
||||
m.template triangularView<StrictlyUpper>().swap(m.transpose());
|
||||
else
|
||||
m = m.transpose().eval();
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ template<typename Derived> class TriangularBase : public AnyMatrixBase<Derived>
|
||||
};
|
||||
typedef typename ei_traits<Derived>::Scalar Scalar;
|
||||
|
||||
inline TriangularBase() { ei_assert(ei_are_flags_consistent<Mode>::ret); }
|
||||
inline TriangularBase() { ei_assert(!((Mode&UnitDiag) && (Mode&ZeroDiag))); }
|
||||
|
||||
inline int rows() const { return derived().rows(); }
|
||||
inline int cols() const { return derived().cols(); }
|
||||
@@ -89,10 +89,10 @@ template<typename Derived> class TriangularBase : public AnyMatrixBase<Derived>
|
||||
void check_coordinates(int row, int col)
|
||||
{
|
||||
ei_assert(col>=0 && col<cols() && row>=0 && row<rows());
|
||||
ei_assert( (Mode==UpperTriangular && col>=row)
|
||||
|| (Mode==LowerTriangular && col<=row)
|
||||
|| ((Mode==StrictlyUpperTriangular || Mode==UnitUpperTriangular) && col>row)
|
||||
|| ((Mode==StrictlyLowerTriangular || Mode==UnitLowerTriangular) && col<row));
|
||||
ei_assert( (Mode==Upper && col>=row)
|
||||
|| (Mode==Lower && col<=row)
|
||||
|| ((Mode==StrictlyUpper || Mode==UnitUpper) && col>row)
|
||||
|| ((Mode==StrictlyLower || Mode==UnitLower) && col<row));
|
||||
}
|
||||
|
||||
#ifdef EIGEN_INTERNAL_DEBUGGING
|
||||
@@ -111,10 +111,10 @@ template<typename Derived> class TriangularBase : public AnyMatrixBase<Derived>
|
||||
* \brief Base class for triangular part in a 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 UpperTriangular,
|
||||
* LowerTriangular, UpperSelfadjoint, or LowerSelfadjoint. This is in fact a bit field;
|
||||
* it must have either UpperBit or LowerBit, and additionnaly it may have either
|
||||
* TraingularBit or SelfadjointBit.
|
||||
* \param Mode the kind of triangular matrix expression to construct. Can be Upper,
|
||||
* Lower, UpperSelfadjoint, or LowerSelfadjoint. This is in fact a bit field;
|
||||
* it must have either Upper or Lower, and additionnaly it may have either
|
||||
* UnitDiag or Selfadjoint.
|
||||
*
|
||||
* This class represents a triangular part of a matrix, not necessarily square. Strictly speaking, for rectangular
|
||||
* matrices one should speak ok "trapezoid" parts. This class is the return type
|
||||
@@ -154,9 +154,10 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
||||
|
||||
enum {
|
||||
Mode = _Mode,
|
||||
TransposeMode = (Mode & UpperTriangularBit ? LowerTriangularBit : 0)
|
||||
| (Mode & LowerTriangularBit ? UpperTriangularBit : 0)
|
||||
| (Mode & (ZeroDiagBit | UnitDiagBit))
|
||||
TransposeMode = (Mode & Upper ? Lower : 0)
|
||||
| (Mode & Lower ? Upper : 0)
|
||||
| (Mode & (UnitDiag))
|
||||
| (Mode & (ZeroDiag))
|
||||
};
|
||||
|
||||
inline TriangularView(const MatrixType& matrix) : m_matrix(matrix)
|
||||
@@ -283,12 +284,12 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
||||
|
||||
const SelfAdjointView<_MatrixTypeNested,Mode> selfadjointView() const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((Mode&UnitDiagBit)==0,PROGRAMMING_ERROR);
|
||||
EIGEN_STATIC_ASSERT((Mode&UnitDiag)==0,PROGRAMMING_ERROR);
|
||||
return SelfAdjointView<_MatrixTypeNested,Mode>(m_matrix);
|
||||
}
|
||||
SelfAdjointView<_MatrixTypeNested,Mode> selfadjointView()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT((Mode&UnitDiagBit)==0,PROGRAMMING_ERROR);
|
||||
EIGEN_STATIC_ASSERT((Mode&UnitDiag)==0,PROGRAMMING_ERROR);
|
||||
return SelfAdjointView<_MatrixTypeNested,Mode>(m_matrix);
|
||||
}
|
||||
|
||||
@@ -304,6 +305,16 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
||||
TriangularView<SwapWrapper<MatrixType>,Mode>(const_cast<MatrixType&>(m_matrix)).lazyAssign(other.derived());
|
||||
}
|
||||
|
||||
Scalar determinant() const
|
||||
{
|
||||
if (Mode & UnitDiag)
|
||||
return 1;
|
||||
else if (Mode & ZeroDiag)
|
||||
return 0;
|
||||
else
|
||||
return m_matrix.diagonal().prod();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
const MatrixTypeNested m_matrix;
|
||||
@@ -325,19 +336,19 @@ struct ei_triangular_assignment_selector
|
||||
{
|
||||
ei_triangular_assignment_selector<Derived1, Derived2, Mode, UnrollCount-1, ClearOpposite>::run(dst, src);
|
||||
|
||||
ei_assert( Mode == UpperTriangular || Mode == LowerTriangular
|
||||
|| Mode == StrictlyUpperTriangular || Mode == StrictlyLowerTriangular
|
||||
|| Mode == UnitUpperTriangular || Mode == UnitLowerTriangular);
|
||||
if((Mode == UpperTriangular && row <= col)
|
||||
|| (Mode == LowerTriangular && row >= col)
|
||||
|| (Mode == StrictlyUpperTriangular && row < col)
|
||||
|| (Mode == StrictlyLowerTriangular && row > col)
|
||||
|| (Mode == UnitUpperTriangular && row < col)
|
||||
|| (Mode == UnitLowerTriangular && row > col))
|
||||
ei_assert( Mode == Upper || Mode == Lower
|
||||
|| Mode == StrictlyUpper || Mode == StrictlyLower
|
||||
|| Mode == UnitUpper || Mode == UnitLower);
|
||||
if((Mode == Upper && row <= col)
|
||||
|| (Mode == Lower && row >= col)
|
||||
|| (Mode == StrictlyUpper && row < col)
|
||||
|| (Mode == StrictlyLower && row > col)
|
||||
|| (Mode == UnitUpper && row < col)
|
||||
|| (Mode == UnitLower && row > col))
|
||||
dst.copyCoeff(row, col, src);
|
||||
else if(ClearOpposite)
|
||||
{
|
||||
if (Mode&UnitDiagBit && row==col)
|
||||
if (Mode&UnitDiag && row==col)
|
||||
dst.coeffRef(row, col) = 1;
|
||||
else
|
||||
dst.coeffRef(row, col) = 0;
|
||||
@@ -353,7 +364,7 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, Mode, 0, ClearOppos
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
||||
struct ei_triangular_assignment_selector<Derived1, Derived2, UpperTriangular, Dynamic, ClearOpposite>
|
||||
struct ei_triangular_assignment_selector<Derived1, Derived2, Upper, Dynamic, ClearOpposite>
|
||||
{
|
||||
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
@@ -370,7 +381,7 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, UpperTriangular, Dy
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
||||
struct ei_triangular_assignment_selector<Derived1, Derived2, LowerTriangular, Dynamic, ClearOpposite>
|
||||
struct ei_triangular_assignment_selector<Derived1, Derived2, Lower, Dynamic, ClearOpposite>
|
||||
{
|
||||
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
@@ -387,7 +398,7 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, LowerTriangular, Dy
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
||||
struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyUpperTriangular, Dynamic, ClearOpposite>
|
||||
struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyUpper, Dynamic, ClearOpposite>
|
||||
{
|
||||
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
@@ -404,7 +415,7 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyUpperTriang
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
||||
struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyLowerTriangular, Dynamic, ClearOpposite>
|
||||
struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyLower, Dynamic, ClearOpposite>
|
||||
{
|
||||
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
@@ -421,7 +432,7 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyLowerTriang
|
||||
};
|
||||
|
||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
||||
struct ei_triangular_assignment_selector<Derived1, Derived2, UnitUpperTriangular, Dynamic, ClearOpposite>
|
||||
struct ei_triangular_assignment_selector<Derived1, Derived2, UnitUpper, Dynamic, ClearOpposite>
|
||||
{
|
||||
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
@@ -440,7 +451,7 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, UnitUpperTriangular
|
||||
}
|
||||
};
|
||||
template<typename Derived1, typename Derived2, bool ClearOpposite>
|
||||
struct ei_triangular_assignment_selector<Derived1, Derived2, UnitLowerTriangular, Dynamic, ClearOpposite>
|
||||
struct ei_triangular_assignment_selector<Derived1, Derived2, UnitLower, Dynamic, ClearOpposite>
|
||||
{
|
||||
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
@@ -590,8 +601,8 @@ EIGEN_DEPRECATED TriangularView<Derived, Mode> MatrixBase<Derived>::part()
|
||||
/** \nonstableyet
|
||||
* \returns an expression of a triangular view extracted from the current matrix
|
||||
*
|
||||
* The parameter \a Mode can have the following values: \c UpperTriangular, \c StrictlyUpperTriangular, \c UnitUpperTriangular,
|
||||
* \c LowerTriangular, \c StrictlyLowerTriangular, \c UnitLowerTriangular.
|
||||
* The parameter \a Mode can have the following values: \c Upper, \c StrictlyUpper, \c UnitUpper,
|
||||
* \c Lower, \c StrictlyLower, \c UnitLower.
|
||||
*
|
||||
* Example: \include MatrixBase_extract.cpp
|
||||
* Output: \verbinclude MatrixBase_extract.out
|
||||
@@ -616,22 +627,22 @@ const TriangularView<Derived, Mode> MatrixBase<Derived>::triangularView() const
|
||||
/** \returns true if *this is approximately equal to an upper triangular matrix,
|
||||
* within the precision given by \a prec.
|
||||
*
|
||||
* \sa isLowerTriangular(), extract(), part(), marked()
|
||||
* \sa isLower(), extract(), part(), marked()
|
||||
*/
|
||||
template<typename Derived>
|
||||
bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const
|
||||
{
|
||||
RealScalar maxAbsOnUpperTriangularPart = static_cast<RealScalar>(-1);
|
||||
RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1);
|
||||
for(int j = 0; j < cols(); ++j)
|
||||
{
|
||||
int maxi = std::min(j, rows()-1);
|
||||
for(int i = 0; i <= maxi; ++i)
|
||||
{
|
||||
RealScalar absValue = ei_abs(coeff(i,j));
|
||||
if(absValue > maxAbsOnUpperTriangularPart) maxAbsOnUpperTriangularPart = absValue;
|
||||
if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
|
||||
}
|
||||
}
|
||||
RealScalar threshold = maxAbsOnUpperTriangularPart * prec;
|
||||
RealScalar threshold = maxAbsOnUpperPart * prec;
|
||||
for(int j = 0; j < cols(); ++j)
|
||||
for(int i = j+1; i < rows(); ++i)
|
||||
if(ei_abs(coeff(i, j)) > threshold) return false;
|
||||
@@ -641,19 +652,19 @@ bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const
|
||||
/** \returns true if *this is approximately equal to a lower triangular matrix,
|
||||
* within the precision given by \a prec.
|
||||
*
|
||||
* \sa isUpperTriangular(), extract(), part(), marked()
|
||||
* \sa isUpper(), extract(), part(), marked()
|
||||
*/
|
||||
template<typename Derived>
|
||||
bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const
|
||||
{
|
||||
RealScalar maxAbsOnLowerTriangularPart = static_cast<RealScalar>(-1);
|
||||
RealScalar maxAbsOnLowerPart = 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 > maxAbsOnLowerTriangularPart) maxAbsOnLowerTriangularPart = absValue;
|
||||
if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
|
||||
}
|
||||
RealScalar threshold = maxAbsOnLowerTriangularPart * prec;
|
||||
RealScalar threshold = maxAbsOnLowerPart * prec;
|
||||
for(int j = 1; j < cols(); ++j)
|
||||
{
|
||||
int maxi = std::min(j, rows()-1);
|
||||
|
||||
@@ -368,10 +368,10 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false>
|
||||
SelfadjointProductMatrix(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {}
|
||||
|
||||
enum {
|
||||
LhsUpLo = LhsMode&(UpperTriangularBit|LowerTriangularBit),
|
||||
LhsIsSelfAdjoint = (LhsMode&SelfAdjointBit)==SelfAdjointBit,
|
||||
RhsUpLo = RhsMode&(UpperTriangularBit|LowerTriangularBit),
|
||||
RhsIsSelfAdjoint = (RhsMode&SelfAdjointBit)==SelfAdjointBit
|
||||
LhsUpLo = LhsMode&(Upper|Lower),
|
||||
LhsIsSelfAdjoint = (LhsMode&SelfAdjoint)==SelfAdjoint,
|
||||
RhsUpLo = RhsMode&(Upper|Lower),
|
||||
RhsIsSelfAdjoint = (RhsMode&SelfAdjoint)==SelfAdjoint
|
||||
};
|
||||
|
||||
template<typename Dest> void scaleAndAddTo(Dest& dst, Scalar alpha) const
|
||||
@@ -385,12 +385,12 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false>
|
||||
* RhsBlasTraits::extractScalarFactor(m_rhs);
|
||||
|
||||
ei_product_selfadjoint_matrix<Scalar,
|
||||
EIGEN_LOGICAL_XOR(LhsUpLo==UpperTriangular,
|
||||
EIGEN_LOGICAL_XOR(LhsUpLo==Upper,
|
||||
ei_traits<Lhs>::Flags &RowMajorBit) ? RowMajor : ColMajor, LhsIsSelfAdjoint,
|
||||
NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(LhsUpLo==UpperTriangular,bool(LhsBlasTraits::NeedToConjugate)),
|
||||
EIGEN_LOGICAL_XOR(RhsUpLo==UpperTriangular,
|
||||
NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(LhsUpLo==Upper,bool(LhsBlasTraits::NeedToConjugate)),
|
||||
EIGEN_LOGICAL_XOR(RhsUpLo==Upper,
|
||||
ei_traits<Rhs>::Flags &RowMajorBit) ? RowMajor : ColMajor, RhsIsSelfAdjoint,
|
||||
NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(RhsUpLo==UpperTriangular,bool(RhsBlasTraits::NeedToConjugate)),
|
||||
NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(RhsUpLo==Upper,bool(RhsBlasTraits::NeedToConjugate)),
|
||||
ei_traits<Dest>::Flags&RowMajorBit ? RowMajor : ColMajor>
|
||||
::run(
|
||||
lhs.rows(), rhs.cols(), // sizes
|
||||
|
||||
@@ -42,7 +42,7 @@ static EIGEN_DONT_INLINE void ei_product_selfadjoint_vector(
|
||||
|
||||
enum {
|
||||
IsRowMajor = StorageOrder==RowMajor ? 1 : 0,
|
||||
IsLower = UpLo == LowerTriangularBit ? 1 : 0,
|
||||
IsLower = UpLo == Lower ? 1 : 0,
|
||||
FirstTriangular = IsRowMajor == IsLower
|
||||
};
|
||||
|
||||
@@ -170,7 +170,7 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true>
|
||||
EIGEN_PRODUCT_PUBLIC_INTERFACE(SelfadjointProductMatrix)
|
||||
|
||||
enum {
|
||||
LhsUpLo = LhsMode&(UpperTriangularBit|LowerTriangularBit)
|
||||
LhsUpLo = LhsMode&(Upper|Lower)
|
||||
};
|
||||
|
||||
SelfadjointProductMatrix(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {}
|
||||
|
||||
@@ -47,7 +47,7 @@ struct ei_selfadjoint_product<Scalar,MatStorageOrder, RowMajor, AAT, UpLo>
|
||||
{
|
||||
static EIGEN_STRONG_INLINE void run(int size, int depth, const Scalar* mat, int matStride, Scalar* res, int resStride, Scalar alpha)
|
||||
{
|
||||
ei_selfadjoint_product<Scalar, MatStorageOrder, ColMajor, !AAT, UpLo==LowerTriangular?UpperTriangular:LowerTriangular>
|
||||
ei_selfadjoint_product<Scalar, MatStorageOrder, ColMajor, !AAT, UpLo==Lower?Upper:Lower>
|
||||
::run(size, depth, mat, matStride, res, resStride, alpha);
|
||||
}
|
||||
};
|
||||
@@ -100,13 +100,13 @@ struct ei_selfadjoint_product<Scalar,MatStorageOrder, ColMajor, AAT, UpLo>
|
||||
// 1 - before the diagonal => processed with gebp or skipped
|
||||
// 2 - the actual_mc x actual_mc symmetric block => processed with a special kernel
|
||||
// 3 - after the diagonal => processed with gebp or skipped
|
||||
if (UpLo==LowerTriangular)
|
||||
if (UpLo==Lower)
|
||||
gebp_kernel(res+i2, resStride, blockA, blockB, actual_mc, actual_kc, std::min(size,i2));
|
||||
|
||||
ei_sybb_kernel<Scalar, Blocking::mr, Blocking::nr, Conj, UpLo>()
|
||||
(res+resStride*i2 + i2, resStride, blockA, blockB + actual_kc*Blocking::PacketSize*i2, actual_mc, actual_kc);
|
||||
|
||||
if (UpLo==UpperTriangular)
|
||||
if (UpLo==Upper)
|
||||
{
|
||||
int j2 = i2+actual_mc;
|
||||
gebp_kernel(res+resStride*j2+i2, resStride, blockA, blockB+actual_kc*Blocking::PacketSize*j2, actual_mc, actual_kc, std::max(0,size-j2));
|
||||
@@ -173,7 +173,7 @@ struct ei_sybb_kernel
|
||||
int actualBlockSize = std::min<int>(BlockSize,size - j);
|
||||
const Scalar* actual_b = blockB+j*depth*PacketSize;
|
||||
|
||||
if(UpLo==UpperTriangular)
|
||||
if(UpLo==Upper)
|
||||
gebp_kernel(res+j*resStride, resStride, blockA, actual_b, j, depth, actualBlockSize);
|
||||
|
||||
// selfadjoint micro block
|
||||
@@ -186,13 +186,13 @@ struct ei_sybb_kernel
|
||||
for(int j1=0; j1<actualBlockSize; ++j1)
|
||||
{
|
||||
Scalar* r = res + (j+j1)*resStride + i;
|
||||
for(int i1=UpLo==LowerTriangular ? j1 : 0;
|
||||
UpLo==LowerTriangular ? i1<actualBlockSize : i1<=j1; ++i1)
|
||||
for(int i1=UpLo==Lower ? j1 : 0;
|
||||
UpLo==Lower ? i1<actualBlockSize : i1<=j1; ++i1)
|
||||
r[i1] += buffer(i1,j1);
|
||||
}
|
||||
}
|
||||
|
||||
if(UpLo==LowerTriangular)
|
||||
if(UpLo==Lower)
|
||||
{
|
||||
int i = j+actualBlockSize;
|
||||
gebp_kernel(res+j*resStride+i, resStride, blockA+depth*i, actual_b, size-i, depth, actualBlockSize);
|
||||
|
||||
@@ -33,7 +33,7 @@ template<typename Scalar, typename UType, typename VType, int UpLo>
|
||||
struct ei_selfadjoint_rank2_update_selector;
|
||||
|
||||
template<typename Scalar, typename UType, typename VType>
|
||||
struct ei_selfadjoint_rank2_update_selector<Scalar,UType,VType,LowerTriangular>
|
||||
struct ei_selfadjoint_rank2_update_selector<Scalar,UType,VType,Lower>
|
||||
{
|
||||
static void run(Scalar* mat, int stride, const UType& u, const VType& v, Scalar alpha)
|
||||
{
|
||||
@@ -48,7 +48,7 @@ struct ei_selfadjoint_rank2_update_selector<Scalar,UType,VType,LowerTriangular>
|
||||
};
|
||||
|
||||
template<typename Scalar, typename UType, typename VType>
|
||||
struct ei_selfadjoint_rank2_update_selector<Scalar,UType,VType,UpperTriangular>
|
||||
struct ei_selfadjoint_rank2_update_selector<Scalar,UType,VType,Upper>
|
||||
{
|
||||
static void run(Scalar* mat, int stride, const UType& u, const VType& v, Scalar alpha)
|
||||
{
|
||||
@@ -87,7 +87,7 @@ SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
|
||||
ei_selfadjoint_rank2_update_selector<Scalar,
|
||||
typename ei_cleantype<typename ei_conj_expr_if<IsRowMajor ^ UBlasTraits::NeedToConjugate,_ActualUType>::ret>::type,
|
||||
typename ei_cleantype<typename ei_conj_expr_if<IsRowMajor ^ VBlasTraits::NeedToConjugate,_ActualVType>::ret>::type,
|
||||
(IsRowMajor ? (UpLo==UpperTriangular ? LowerTriangular : UpperTriangular) : UpLo)>
|
||||
(IsRowMajor ? (UpLo==Upper ? Lower : Upper) : UpLo)>
|
||||
::run(const_cast<Scalar*>(_expression().data()),_expression().stride(),actualU,actualV,actualAlpha);
|
||||
|
||||
return *this;
|
||||
|
||||
@@ -75,7 +75,7 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,LhsIsTriangular,
|
||||
Scalar alpha)
|
||||
{
|
||||
ei_product_triangular_matrix_matrix<Scalar,
|
||||
(Mode&UnitDiagBit) | (Mode&UpperTriangular) ? LowerTriangular : UpperTriangular,
|
||||
(Mode&UnitDiag) | (Mode&Upper) ? Lower : Upper,
|
||||
(!LhsIsTriangular),
|
||||
RhsStorageOrder==RowMajor ? ColMajor : RowMajor,
|
||||
ConjugateRhs,
|
||||
@@ -113,7 +113,7 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,true,
|
||||
typedef ei_product_blocking_traits<Scalar> Blocking;
|
||||
enum {
|
||||
SmallPanelWidth = EIGEN_ENUM_MAX(Blocking::mr,Blocking::nr),
|
||||
IsLowerTriangular = (Mode&LowerTriangular) == LowerTriangular
|
||||
IsLower = (Mode&Lower) == Lower
|
||||
};
|
||||
|
||||
int kc = std::min<int>(Blocking::Max_kc/4,size); // cache block size along the K direction
|
||||
@@ -130,12 +130,12 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,true,
|
||||
ei_gemm_pack_lhs<Scalar,Blocking::mr,LhsStorageOrder> pack_lhs;
|
||||
ei_gemm_pack_rhs<Scalar,Blocking::nr,RhsStorageOrder> pack_rhs;
|
||||
|
||||
for(int k2=IsLowerTriangular ? size : 0;
|
||||
IsLowerTriangular ? k2>0 : k2<size;
|
||||
IsLowerTriangular ? k2-=kc : k2+=kc)
|
||||
for(int k2=IsLower ? size : 0;
|
||||
IsLower ? k2>0 : k2<size;
|
||||
IsLower ? k2-=kc : k2+=kc)
|
||||
{
|
||||
const int actual_kc = std::min(IsLowerTriangular ? k2 : size-k2, kc);
|
||||
int actual_k2 = IsLowerTriangular ? k2-actual_kc : k2;
|
||||
const int actual_kc = std::min(IsLower ? k2 : size-k2, kc);
|
||||
int actual_k2 = IsLower ? k2-actual_kc : k2;
|
||||
|
||||
pack_rhs(blockB, &rhs(actual_k2,0), rhsStride, alpha, actual_kc, cols);
|
||||
|
||||
@@ -149,7 +149,7 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,true,
|
||||
for (int k1=0; k1<actual_kc; k1+=SmallPanelWidth)
|
||||
{
|
||||
int actualPanelWidth = std::min<int>(actual_kc-k1, SmallPanelWidth);
|
||||
int lengthTarget = IsLowerTriangular ? actual_kc-k1-actualPanelWidth : k1;
|
||||
int lengthTarget = IsLower ? actual_kc-k1-actualPanelWidth : k1;
|
||||
int startBlock = actual_k2+k1;
|
||||
int blockBOffset = k1;
|
||||
|
||||
@@ -158,9 +158,9 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,true,
|
||||
// To this end we do an extra triangular copy to small temporary buffer
|
||||
for (int k=0;k<actualPanelWidth;++k)
|
||||
{
|
||||
if (!(Mode&UnitDiagBit))
|
||||
if (!(Mode&UnitDiag))
|
||||
triangularBuffer.coeffRef(k,k) = lhs(startBlock+k,startBlock+k);
|
||||
for (int i=IsLowerTriangular ? k+1 : 0; IsLowerTriangular ? i<actualPanelWidth : i<k; ++i)
|
||||
for (int i=IsLower ? k+1 : 0; IsLower ? i<actualPanelWidth : i<k; ++i)
|
||||
triangularBuffer.coeffRef(i,k) = lhs(startBlock+i,startBlock+k);
|
||||
}
|
||||
pack_lhs(blockA, triangularBuffer.data(), triangularBuffer.stride(), actualPanelWidth, actualPanelWidth);
|
||||
@@ -171,7 +171,7 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,true,
|
||||
// GEBP with remaining micro panel
|
||||
if (lengthTarget>0)
|
||||
{
|
||||
int startTarget = IsLowerTriangular ? actual_k2+k1+actualPanelWidth : actual_k2;
|
||||
int startTarget = IsLower ? actual_k2+k1+actualPanelWidth : actual_k2;
|
||||
|
||||
pack_lhs(blockA, &lhs(startTarget,startBlock), lhsStride, actualPanelWidth, lengthTarget);
|
||||
|
||||
@@ -182,8 +182,8 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,true,
|
||||
}
|
||||
// the part below the diagonal => GEPP
|
||||
{
|
||||
int start = IsLowerTriangular ? k2 : 0;
|
||||
int end = IsLowerTriangular ? size : actual_k2;
|
||||
int start = IsLower ? k2 : 0;
|
||||
int end = IsLower ? size : actual_k2;
|
||||
for(int i2=start; i2<end; i2+=mc)
|
||||
{
|
||||
const int actual_mc = std::min(i2+mc,end)-i2;
|
||||
@@ -227,7 +227,7 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,false,
|
||||
typedef ei_product_blocking_traits<Scalar> Blocking;
|
||||
enum {
|
||||
SmallPanelWidth = EIGEN_ENUM_MAX(Blocking::mr,Blocking::nr),
|
||||
IsLowerTriangular = (Mode&LowerTriangular) == LowerTriangular
|
||||
IsLower = (Mode&Lower) == Lower
|
||||
};
|
||||
|
||||
int kc = std::min<int>(Blocking::Max_kc/4,size); // cache block size along the K direction
|
||||
@@ -245,16 +245,16 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,false,
|
||||
ei_gemm_pack_rhs<Scalar,Blocking::nr,RhsStorageOrder> pack_rhs;
|
||||
ei_gemm_pack_rhs<Scalar,Blocking::nr,RhsStorageOrder,true> pack_rhs_panel;
|
||||
|
||||
for(int k2=IsLowerTriangular ? 0 : size;
|
||||
IsLowerTriangular ? k2<size : k2>0;
|
||||
IsLowerTriangular ? k2+=kc : k2-=kc)
|
||||
for(int k2=IsLower ? 0 : size;
|
||||
IsLower ? k2<size : k2>0;
|
||||
IsLower ? k2+=kc : k2-=kc)
|
||||
{
|
||||
const int actual_kc = std::min(IsLowerTriangular ? size-k2 : k2, kc);
|
||||
int actual_k2 = IsLowerTriangular ? k2 : k2-actual_kc;
|
||||
int rs = IsLowerTriangular ? actual_k2 : size - k2;
|
||||
const int actual_kc = std::min(IsLower ? size-k2 : k2, kc);
|
||||
int actual_k2 = IsLower ? k2 : k2-actual_kc;
|
||||
int rs = IsLower ? actual_k2 : size - k2;
|
||||
Scalar* geb = blockB+actual_kc*actual_kc*Blocking::PacketSize;
|
||||
|
||||
pack_rhs(geb, &rhs(actual_k2,IsLowerTriangular ? 0 : k2), rhsStride, alpha, actual_kc, rs);
|
||||
pack_rhs(geb, &rhs(actual_k2,IsLower ? 0 : k2), rhsStride, alpha, actual_kc, rs);
|
||||
|
||||
// pack the triangular part of the rhs padding the unrolled blocks with zeros
|
||||
{
|
||||
@@ -262,8 +262,8 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,false,
|
||||
{
|
||||
int actualPanelWidth = std::min<int>(actual_kc-j2, SmallPanelWidth);
|
||||
int actual_j2 = actual_k2 + j2;
|
||||
int panelOffset = IsLowerTriangular ? j2+actualPanelWidth : 0;
|
||||
int panelLength = IsLowerTriangular ? actual_kc-j2-actualPanelWidth : j2;
|
||||
int panelOffset = IsLower ? j2+actualPanelWidth : 0;
|
||||
int panelLength = IsLower ? actual_kc-j2-actualPanelWidth : j2;
|
||||
// general part
|
||||
pack_rhs_panel(blockB+j2*actual_kc*Blocking::PacketSize,
|
||||
&rhs(actual_k2+panelOffset, actual_j2), rhsStride, alpha,
|
||||
@@ -273,9 +273,9 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,false,
|
||||
// append the triangular part via a temporary buffer
|
||||
for (int j=0;j<actualPanelWidth;++j)
|
||||
{
|
||||
if (!(Mode&UnitDiagBit))
|
||||
if (!(Mode&UnitDiag))
|
||||
triangularBuffer.coeffRef(j,j) = rhs(actual_j2+j,actual_j2+j);
|
||||
for (int k=IsLowerTriangular ? j+1 : 0; IsLowerTriangular ? k<actualPanelWidth : k<j; ++k)
|
||||
for (int k=IsLower ? j+1 : 0; IsLower ? k<actualPanelWidth : k<j; ++k)
|
||||
triangularBuffer.coeffRef(k,j) = rhs(actual_j2+k,actual_j2+j);
|
||||
}
|
||||
|
||||
@@ -296,8 +296,8 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,false,
|
||||
for (int j2=0; j2<actual_kc; j2+=SmallPanelWidth)
|
||||
{
|
||||
int actualPanelWidth = std::min<int>(actual_kc-j2, SmallPanelWidth);
|
||||
int panelLength = IsLowerTriangular ? actual_kc-j2 : j2+actualPanelWidth;
|
||||
int blockOffset = IsLowerTriangular ? j2 : 0;
|
||||
int panelLength = IsLower ? actual_kc-j2 : j2+actualPanelWidth;
|
||||
int blockOffset = IsLower ? j2 : 0;
|
||||
|
||||
gebp_kernel(res+i2+(actual_k2+j2)*resStride, resStride,
|
||||
blockA, blockB+j2*actual_kc*Blocking::PacketSize,
|
||||
@@ -306,7 +306,7 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,false,
|
||||
blockOffset, blockOffset*Blocking::PacketSize);// offsets
|
||||
}
|
||||
}
|
||||
gebp_kernel(res+i2+(IsLowerTriangular ? 0 : k2)*resStride, resStride,
|
||||
gebp_kernel(res+i2+(IsLower ? 0 : k2)*resStride, resStride,
|
||||
blockA, geb, actual_mc, actual_kc, rs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ struct ei_product_triangular_vector_selector<Lhs,Rhs,Result,Mode,ConjLhs,ConjRhs
|
||||
{
|
||||
typedef typename Rhs::Scalar Scalar;
|
||||
enum {
|
||||
IsLowerTriangular = ((Mode&LowerTriangularBit)==LowerTriangularBit),
|
||||
HasUnitDiag = (Mode & UnitDiagBit)==UnitDiagBit
|
||||
IsLower = ((Mode&Lower)==Lower),
|
||||
HasUnitDiag = (Mode & UnitDiag)==UnitDiag
|
||||
};
|
||||
static EIGEN_DONT_INLINE void run(const Lhs& lhs, const Rhs& rhs, Result& res, typename ei_traits<Lhs>::Scalar alpha)
|
||||
{
|
||||
@@ -50,17 +50,17 @@ struct ei_product_triangular_vector_selector<Lhs,Rhs,Result,Mode,ConjLhs,ConjRhs
|
||||
for (int k=0; k<actualPanelWidth; ++k)
|
||||
{
|
||||
int i = pi + k;
|
||||
int s = IsLowerTriangular ? (HasUnitDiag ? i+1 : i ) : pi;
|
||||
int r = IsLowerTriangular ? actualPanelWidth-k : k+1;
|
||||
int s = IsLower ? (HasUnitDiag ? i+1 : i ) : pi;
|
||||
int r = IsLower ? actualPanelWidth-k : k+1;
|
||||
if ((!HasUnitDiag) || (--r)>0)
|
||||
res.segment(s,r) += (alpha * cjRhs.coeff(i)) * cjLhs.col(i).segment(s,r);
|
||||
if (HasUnitDiag)
|
||||
res.coeffRef(i) += alpha * cjRhs.coeff(i);
|
||||
}
|
||||
int r = IsLowerTriangular ? size - pi - actualPanelWidth : pi;
|
||||
int r = IsLower ? size - pi - actualPanelWidth : pi;
|
||||
if (r>0)
|
||||
{
|
||||
int s = IsLowerTriangular ? pi+actualPanelWidth : 0;
|
||||
int s = IsLower ? pi+actualPanelWidth : 0;
|
||||
ei_cache_friendly_product_colmajor_times_vector<ConjLhs,ConjRhs>(
|
||||
r,
|
||||
&(lhs.const_cast_derived().coeffRef(s,pi)), lhs.stride(),
|
||||
@@ -77,8 +77,8 @@ struct ei_product_triangular_vector_selector<Lhs,Rhs,Result,Mode,ConjLhs,ConjRhs
|
||||
{
|
||||
typedef typename Rhs::Scalar Scalar;
|
||||
enum {
|
||||
IsLowerTriangular = ((Mode&LowerTriangularBit)==LowerTriangularBit),
|
||||
HasUnitDiag = (Mode & UnitDiagBit)==UnitDiagBit
|
||||
IsLower = ((Mode&Lower)==Lower),
|
||||
HasUnitDiag = (Mode & UnitDiag)==UnitDiag
|
||||
};
|
||||
static void run(const Lhs& lhs, const Rhs& rhs, Result& res, typename ei_traits<Lhs>::Scalar alpha)
|
||||
{
|
||||
@@ -92,17 +92,17 @@ struct ei_product_triangular_vector_selector<Lhs,Rhs,Result,Mode,ConjLhs,ConjRhs
|
||||
for (int k=0; k<actualPanelWidth; ++k)
|
||||
{
|
||||
int i = pi + k;
|
||||
int s = IsLowerTriangular ? pi : (HasUnitDiag ? i+1 : i);
|
||||
int r = IsLowerTriangular ? k+1 : actualPanelWidth-k;
|
||||
int s = IsLower ? pi : (HasUnitDiag ? i+1 : i);
|
||||
int r = IsLower ? k+1 : actualPanelWidth-k;
|
||||
if ((!HasUnitDiag) || (--r)>0)
|
||||
res.coeffRef(i) += alpha * (cjLhs.row(i).segment(s,r).cwiseProduct(cjRhs.segment(s,r).transpose())).sum();
|
||||
if (HasUnitDiag)
|
||||
res.coeffRef(i) += alpha * cjRhs.coeff(i);
|
||||
}
|
||||
int r = IsLowerTriangular ? pi : size - pi - actualPanelWidth;
|
||||
int r = IsLower ? pi : size - pi - actualPanelWidth;
|
||||
if (r>0)
|
||||
{
|
||||
int s = IsLowerTriangular ? 0 : pi + actualPanelWidth;
|
||||
int s = IsLower ? 0 : pi + actualPanelWidth;
|
||||
Block<Result,Dynamic,1> target(res,pi,0,actualPanelWidth,1);
|
||||
ei_cache_friendly_product_rowmajor_times_vector<ConjLhs,ConjRhs>(
|
||||
&(lhs.const_cast_derived().coeffRef(pi,s)), lhs.stride(),
|
||||
|
||||
@@ -36,7 +36,7 @@ struct ei_triangular_solve_matrix<Scalar,Side,Mode,Conjugate,TriStorageOrder,Row
|
||||
{
|
||||
ei_triangular_solve_matrix<
|
||||
Scalar, Side==OnTheLeft?OnTheRight:OnTheLeft,
|
||||
(Mode&UnitDiagBit) | ((Mode&UpperTriangular) ? LowerTriangular : UpperTriangular),
|
||||
(Mode&UnitDiag) | ((Mode&Upper) ? Lower : Upper),
|
||||
NumTraits<Scalar>::IsComplex && Conjugate,
|
||||
TriStorageOrder==RowMajor ? ColMajor : RowMajor, ColMajor>
|
||||
::run(size, cols, tri, triStride, _other, otherStride);
|
||||
@@ -60,7 +60,7 @@ struct ei_triangular_solve_matrix<Scalar,OnTheLeft,Mode,Conjugate,TriStorageOrde
|
||||
typedef ei_product_blocking_traits<Scalar> Blocking;
|
||||
enum {
|
||||
SmallPanelWidth = EIGEN_ENUM_MAX(Blocking::mr,Blocking::nr),
|
||||
IsLowerTriangular = (Mode&LowerTriangular) == LowerTriangular
|
||||
IsLower = (Mode&Lower) == Lower
|
||||
};
|
||||
|
||||
int kc = std::min<int>(Blocking::Max_kc/4,size); // cache block size along the K direction
|
||||
@@ -73,11 +73,11 @@ struct ei_triangular_solve_matrix<Scalar,OnTheLeft,Mode,Conjugate,TriStorageOrde
|
||||
ei_gebp_kernel<Scalar, Blocking::mr, Blocking::nr, ei_conj_helper<Conjugate,false> > gebp_kernel;
|
||||
ei_gemm_pack_lhs<Scalar,Blocking::mr,TriStorageOrder> pack_lhs;
|
||||
|
||||
for(int k2=IsLowerTriangular ? 0 : size;
|
||||
IsLowerTriangular ? k2<size : k2>0;
|
||||
IsLowerTriangular ? k2+=kc : k2-=kc)
|
||||
for(int k2=IsLower ? 0 : size;
|
||||
IsLower ? k2<size : k2>0;
|
||||
IsLower ? k2+=kc : k2-=kc)
|
||||
{
|
||||
const int actual_kc = std::min(IsLowerTriangular ? size-k2 : k2, kc);
|
||||
const int actual_kc = std::min(IsLower ? size-k2 : k2, kc);
|
||||
|
||||
// We have selected and packed a big horizontal panel R1 of rhs. Let B be the packed copy of this panel,
|
||||
// and R2 the remaining part of rhs. The corresponding vertical panel of lhs is split into
|
||||
@@ -101,11 +101,11 @@ struct ei_triangular_solve_matrix<Scalar,OnTheLeft,Mode,Conjugate,TriStorageOrde
|
||||
for (int k=0; k<actualPanelWidth; ++k)
|
||||
{
|
||||
// TODO write a small kernel handling this (can be shared with trsv)
|
||||
int i = IsLowerTriangular ? k2+k1+k : k2-k1-k-1;
|
||||
int s = IsLowerTriangular ? k2+k1 : i+1;
|
||||
int i = IsLower ? k2+k1+k : k2-k1-k-1;
|
||||
int s = IsLower ? k2+k1 : i+1;
|
||||
int rs = actualPanelWidth - k - 1; // remaining size
|
||||
|
||||
Scalar a = (Mode & UnitDiagBit) ? Scalar(1) : Scalar(1)/conj(tri(i,i));
|
||||
Scalar a = (Mode & UnitDiag) ? Scalar(1) : Scalar(1)/conj(tri(i,i));
|
||||
for (int j=0; j<cols; ++j)
|
||||
{
|
||||
if (TriStorageOrder==RowMajor)
|
||||
@@ -120,7 +120,7 @@ struct ei_triangular_solve_matrix<Scalar,OnTheLeft,Mode,Conjugate,TriStorageOrde
|
||||
}
|
||||
else
|
||||
{
|
||||
int s = IsLowerTriangular ? i+1 : i-rs;
|
||||
int s = IsLower ? i+1 : i-rs;
|
||||
Scalar b = (other(i,j) *= a);
|
||||
Scalar* r = &other(s,j);
|
||||
const Scalar* l = &tri(s,i);
|
||||
@@ -131,8 +131,8 @@ struct ei_triangular_solve_matrix<Scalar,OnTheLeft,Mode,Conjugate,TriStorageOrde
|
||||
}
|
||||
|
||||
int lengthTarget = actual_kc-k1-actualPanelWidth;
|
||||
int startBlock = IsLowerTriangular ? k2+k1 : k2-k1-actualPanelWidth;
|
||||
int blockBOffset = IsLowerTriangular ? k1 : lengthTarget;
|
||||
int startBlock = IsLower ? k2+k1 : k2-k1-actualPanelWidth;
|
||||
int blockBOffset = IsLower ? k1 : lengthTarget;
|
||||
|
||||
// update the respective rows of B from other
|
||||
ei_gemm_pack_rhs<Scalar, Blocking::nr, ColMajor, true>()
|
||||
@@ -141,7 +141,7 @@ struct ei_triangular_solve_matrix<Scalar,OnTheLeft,Mode,Conjugate,TriStorageOrde
|
||||
// GEBP
|
||||
if (lengthTarget>0)
|
||||
{
|
||||
int startTarget = IsLowerTriangular ? k2+k1+actualPanelWidth : k2-actual_kc;
|
||||
int startTarget = IsLower ? k2+k1+actualPanelWidth : k2-actual_kc;
|
||||
|
||||
pack_lhs(blockA, &tri(startTarget,startBlock), triStride, actualPanelWidth, lengthTarget);
|
||||
|
||||
@@ -153,14 +153,14 @@ struct ei_triangular_solve_matrix<Scalar,OnTheLeft,Mode,Conjugate,TriStorageOrde
|
||||
|
||||
// R2 = A2 * B => GEPP
|
||||
{
|
||||
int start = IsLowerTriangular ? k2+kc : 0;
|
||||
int end = IsLowerTriangular ? size : k2-kc;
|
||||
int start = IsLower ? k2+kc : 0;
|
||||
int end = IsLower ? size : k2-kc;
|
||||
for(int i2=start; i2<end; i2+=mc)
|
||||
{
|
||||
const int actual_mc = std::min(mc,end-i2);
|
||||
if (actual_mc>0)
|
||||
{
|
||||
pack_lhs(blockA, &tri(i2, IsLowerTriangular ? k2 : k2-kc), triStride, actual_kc, actual_mc);
|
||||
pack_lhs(blockA, &tri(i2, IsLower ? k2 : k2-kc), triStride, actual_kc, actual_mc);
|
||||
|
||||
gebp_kernel(_other+i2, otherStride, blockA, blockB, actual_mc, actual_kc, cols);
|
||||
}
|
||||
@@ -191,7 +191,7 @@ struct ei_triangular_solve_matrix<Scalar,OnTheRight,Mode,Conjugate,TriStorageOrd
|
||||
enum {
|
||||
RhsStorageOrder = TriStorageOrder,
|
||||
SmallPanelWidth = EIGEN_ENUM_MAX(Blocking::mr,Blocking::nr),
|
||||
IsLowerTriangular = (Mode&LowerTriangular) == LowerTriangular
|
||||
IsLower = (Mode&Lower) == Lower
|
||||
};
|
||||
|
||||
int kc = std::min<int>(Blocking::Max_kc/4,size); // cache block size along the K direction
|
||||
@@ -206,15 +206,15 @@ struct ei_triangular_solve_matrix<Scalar,OnTheRight,Mode,Conjugate,TriStorageOrd
|
||||
ei_gemm_pack_rhs<Scalar,Blocking::nr,RhsStorageOrder,true> pack_rhs_panel;
|
||||
ei_gemm_pack_lhs<Scalar, Blocking::mr, ColMajor, false, true> pack_lhs_panel;
|
||||
|
||||
for(int k2=IsLowerTriangular ? size : 0;
|
||||
IsLowerTriangular ? k2>0 : k2<size;
|
||||
IsLowerTriangular ? k2-=kc : k2+=kc)
|
||||
for(int k2=IsLower ? size : 0;
|
||||
IsLower ? k2>0 : k2<size;
|
||||
IsLower ? k2-=kc : k2+=kc)
|
||||
{
|
||||
const int actual_kc = std::min(IsLowerTriangular ? k2 : size-k2, kc);
|
||||
int actual_k2 = IsLowerTriangular ? k2-actual_kc : k2 ;
|
||||
const int actual_kc = std::min(IsLower ? k2 : size-k2, kc);
|
||||
int actual_k2 = IsLower ? k2-actual_kc : k2 ;
|
||||
|
||||
int startPanel = IsLowerTriangular ? 0 : k2+actual_kc;
|
||||
int rs = IsLowerTriangular ? actual_k2 : size - actual_k2 - actual_kc;
|
||||
int startPanel = IsLower ? 0 : k2+actual_kc;
|
||||
int rs = IsLower ? actual_k2 : size - actual_k2 - actual_kc;
|
||||
Scalar* geb = blockB+actual_kc*actual_kc*Blocking::PacketSize;
|
||||
|
||||
if (rs>0) pack_rhs(geb, &rhs(actual_k2,startPanel), triStride, -1, actual_kc, rs);
|
||||
@@ -226,8 +226,8 @@ struct ei_triangular_solve_matrix<Scalar,OnTheRight,Mode,Conjugate,TriStorageOrd
|
||||
{
|
||||
int actualPanelWidth = std::min<int>(actual_kc-j2, SmallPanelWidth);
|
||||
int actual_j2 = actual_k2 + j2;
|
||||
int panelOffset = IsLowerTriangular ? j2+actualPanelWidth : 0;
|
||||
int panelLength = IsLowerTriangular ? actual_kc-j2-actualPanelWidth : j2;
|
||||
int panelOffset = IsLower ? j2+actualPanelWidth : 0;
|
||||
int panelLength = IsLower ? actual_kc-j2-actualPanelWidth : j2;
|
||||
|
||||
if (panelLength>0)
|
||||
pack_rhs_panel(blockB+j2*actual_kc*Blocking::PacketSize,
|
||||
@@ -244,17 +244,17 @@ struct ei_triangular_solve_matrix<Scalar,OnTheRight,Mode,Conjugate,TriStorageOrd
|
||||
// triangular solver kernel
|
||||
{
|
||||
// for each small block of the diagonal (=> vertical panels of rhs)
|
||||
for (int j2 = IsLowerTriangular
|
||||
for (int j2 = IsLower
|
||||
? (actual_kc - ((actual_kc%SmallPanelWidth) ? (actual_kc%SmallPanelWidth)
|
||||
: SmallPanelWidth))
|
||||
: 0;
|
||||
IsLowerTriangular ? j2>=0 : j2<actual_kc;
|
||||
IsLowerTriangular ? j2-=SmallPanelWidth : j2+=SmallPanelWidth)
|
||||
IsLower ? j2>=0 : j2<actual_kc;
|
||||
IsLower ? j2-=SmallPanelWidth : j2+=SmallPanelWidth)
|
||||
{
|
||||
int actualPanelWidth = std::min<int>(actual_kc-j2, SmallPanelWidth);
|
||||
int absolute_j2 = actual_k2 + j2;
|
||||
int panelOffset = IsLowerTriangular ? j2+actualPanelWidth : 0;
|
||||
int panelLength = IsLowerTriangular ? actual_kc - j2 - actualPanelWidth : j2;
|
||||
int panelOffset = IsLower ? j2+actualPanelWidth : 0;
|
||||
int panelLength = IsLower ? actual_kc - j2 - actualPanelWidth : j2;
|
||||
|
||||
// GEBP
|
||||
if(panelLength>0)
|
||||
@@ -269,17 +269,17 @@ struct ei_triangular_solve_matrix<Scalar,OnTheRight,Mode,Conjugate,TriStorageOrd
|
||||
// unblocked triangular solve
|
||||
for (int k=0; k<actualPanelWidth; ++k)
|
||||
{
|
||||
int j = IsLowerTriangular ? absolute_j2+actualPanelWidth-k-1 : absolute_j2+k;
|
||||
int j = IsLower ? absolute_j2+actualPanelWidth-k-1 : absolute_j2+k;
|
||||
|
||||
Scalar* r = &lhs(i2,j);
|
||||
for (int k3=0; k3<k; ++k3)
|
||||
{
|
||||
Scalar b = conj(rhs(IsLowerTriangular ? j+1+k3 : absolute_j2+k3,j));
|
||||
Scalar* a = &lhs(i2,IsLowerTriangular ? j+1+k3 : absolute_j2+k3);
|
||||
Scalar b = conj(rhs(IsLower ? j+1+k3 : absolute_j2+k3,j));
|
||||
Scalar* a = &lhs(i2,IsLower ? j+1+k3 : absolute_j2+k3);
|
||||
for (int i=0; i<actual_mc; ++i)
|
||||
r[i] -= a[i] * b;
|
||||
}
|
||||
Scalar b = (Mode & UnitDiagBit) ? Scalar(1) : Scalar(1)/conj(rhs(j,j));
|
||||
Scalar b = (Mode & UnitDiag) ? Scalar(1) : Scalar(1)/conj(rhs(j,j));
|
||||
for (int i=0; i<actual_mc; ++i)
|
||||
r[i] *= b;
|
||||
}
|
||||
|
||||
@@ -149,44 +149,18 @@ const unsigned int DirectAccessBit = 0x20;
|
||||
* means the first coefficient packet is guaranteed to be aligned */
|
||||
const unsigned int AlignedBit = 0x40;
|
||||
|
||||
/** \ingroup flags
|
||||
*
|
||||
* means all diagonal coefficients are equal to 0 */
|
||||
const unsigned int ZeroDiagBit = 0x80;
|
||||
|
||||
/** \ingroup flags
|
||||
*
|
||||
* means all diagonal coefficients are equal to 1 */
|
||||
const unsigned int UnitDiagBit = 0x100;
|
||||
|
||||
/** \ingroup flags
|
||||
*
|
||||
* means the matrix is selfadjoint (M=M*). */
|
||||
const unsigned int SelfAdjointBit = 0x200;
|
||||
|
||||
/** \ingroup flags
|
||||
*
|
||||
* means the strictly lower triangular part is 0 */
|
||||
const unsigned int UpperTriangularBit = 0x400;
|
||||
|
||||
/** \ingroup flags
|
||||
*
|
||||
* means the strictly upper triangular part is 0 */
|
||||
const unsigned int LowerTriangularBit = 0x800;
|
||||
|
||||
// list of flags that are inherited by default
|
||||
const unsigned int HereditaryBits = RowMajorBit
|
||||
| EvalBeforeNestingBit
|
||||
| EvalBeforeAssigningBit;
|
||||
|
||||
// Possible values for the Mode parameter of part()
|
||||
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;
|
||||
const unsigned int UnitUpperTriangular = UpperTriangularBit | UnitDiagBit;
|
||||
const unsigned int UnitLowerTriangular = LowerTriangularBit | UnitDiagBit;
|
||||
// Possible values for the Mode parameter of triangularView()
|
||||
enum {
|
||||
Lower=0x1, Upper=0x2, UnitDiag=0x4, ZeroDiag=0x8,
|
||||
UnitLower=UnitDiag|Lower, UnitUpper=UnitDiag|Upper,
|
||||
StrictlyLower=ZeroDiag|Lower, StrictlyUpper=ZeroDiag|Upper,
|
||||
SelfAdjoint=0x10};
|
||||
|
||||
enum { Unaligned=0, Aligned=1 };
|
||||
enum { ConditionalJumpCost = 5 };
|
||||
|
||||
@@ -132,7 +132,7 @@ template<typename MatrixType> class ColPivHouseholderQR;
|
||||
template<typename MatrixType> class FullPivHouseholderQR;
|
||||
template<typename MatrixType> class SVD;
|
||||
template<typename MatrixType, unsigned int Options = 0> class JacobiSVD;
|
||||
template<typename MatrixType, int UpLo = LowerTriangular> class LLT;
|
||||
template<typename MatrixType, int UpLo = Lower> class LLT;
|
||||
template<typename MatrixType> class LDLT;
|
||||
template<typename VectorsType, typename CoeffsType> class HouseholderSequence;
|
||||
template<typename Scalar> class PlanarRotation;
|
||||
|
||||
@@ -263,8 +263,7 @@ template<typename T, int n=1, typename PlainMatrixType = typename ei_eval<T>::ty
|
||||
|
||||
template<unsigned int Flags> struct ei_are_flags_consistent
|
||||
{
|
||||
enum { ret = !( (Flags&UnitDiagBit && Flags&ZeroDiagBit) )
|
||||
};
|
||||
enum { ret = true };
|
||||
};
|
||||
|
||||
/** \internal Helper base class to add a scalar multiple operator
|
||||
|
||||
Reference in New Issue
Block a user