26 #ifndef EIGEN_TRIANGULARMATRIX_H
27 #define EIGEN_TRIANGULARMATRIX_H
33 template<
int S
ide,
typename TriangularType,
typename Rhs>
struct triangular_solve_retval;
49 Mode = internal::traits<Derived>::Mode,
56 typedef typename internal::traits<Derived>::Scalar
Scalar;
57 typedef typename internal::traits<Derived>::StorageKind
StorageKind;
58 typedef typename internal::traits<Derived>::Index
Index;
74 template<
typename Other>
77 derived().coeffRef(row, col) = other.coeff(row, col);
83 return coeff(row,col);
91 #ifndef EIGEN_PARSED_BY_DOXYGEN
92 inline const Derived&
derived()
const {
return *
static_cast<const Derived*
>(
this); }
93 inline Derived&
derived() {
return *
static_cast<Derived*
>(
this); }
94 #endif // not EIGEN_PARSED_BY_DOXYGEN
96 template<
typename DenseDerived>
97 void evalTo(MatrixBase<DenseDerived> &other)
const;
98 template<
typename DenseDerived>
99 void evalToLazy(MatrixBase<DenseDerived> &other)
const;
118 || (mode==
Lower && col<=row)
123 #ifdef EIGEN_INTERNAL_DEBUGGING
152 template<
typename MatrixType,
unsigned int _Mode>
153 struct traits<TriangularView<MatrixType, _Mode> > :
traits<MatrixType>
155 typedef typename nested<MatrixType>::type MatrixTypeNested;
156 typedef typename remove_reference<MatrixTypeNested>::type MatrixTypeNestedNonRef;
157 typedef typename remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned;
158 typedef MatrixType ExpressionType;
159 typedef typename MatrixType::PlainObject DenseMatrixType;
163 CoeffReadCost = MatrixTypeNestedCleaned::CoeffReadCost
168 template<
int Mode,
bool LhsIsTriangular,
169 typename Lhs,
bool LhsIsVector,
170 typename Rhs,
bool RhsIsVector>
171 struct TriangularProduct;
179 typedef typename internal::traits<TriangularView>::Scalar
Scalar;
196 typedef typename internal::traits<TriangularView>::StorageKind
StorageKind;
197 typedef typename internal::traits<TriangularView>::Index
Index;
228 {
return *
this = MatrixType::Constant(
rows(),
cols(), value); }
249 return m_matrix.const_cast_derived().coeffRef(row, col);
256 template<
typename OtherDerived>
259 template<
typename OtherDerived>
265 template<
typename OtherDerived>
268 template<
typename OtherDerived>
286 return m_matrix.const_cast_derived().transpose();
295 template<
typename OtherDerived>
296 TriangularProduct<Mode,true,MatrixType,false,OtherDerived, OtherDerived::IsVectorAtCompileTime>
299 return TriangularProduct
300 <
Mode,
true,
MatrixType,
false,OtherDerived,OtherDerived::IsVectorAtCompileTime>
305 template<
typename OtherDerived>
friend
306 TriangularProduct<Mode,false,OtherDerived,OtherDerived::IsVectorAtCompileTime,MatrixType,false>
309 return TriangularProduct
310 <
Mode,
false,OtherDerived,OtherDerived::IsVectorAtCompileTime,
MatrixType,
false>
314 #ifdef EIGEN2_SUPPORT
315 template<
typename OtherDerived>
316 struct eigen2_product_return_type
319 typedef typename OtherDerived::PlainObject::DenseType OtherPlainObject;
321 typedef typename ProdRetType::PlainObject type;
323 template<
typename OtherDerived>
324 const typename eigen2_product_return_type<OtherDerived>::type
325 operator*(
const EigenBase<OtherDerived>& rhs)
const
327 typename OtherDerived::PlainObject::DenseType rhsPlainObject;
328 rhs.evalTo(rhsPlainObject);
331 template<
typename OtherMatrixType>
332 bool isApprox(
const TriangularView<OtherMatrixType, Mode>& other,
typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
const
334 return this->
toDenseMatrix().isApprox(other.toDenseMatrix(), precision);
336 template<
typename OtherDerived>
341 #endif // EIGEN2_SUPPORT
343 template<
int S
ide,
typename Other>
344 inline const internal::triangular_solve_retval<Side,TriangularView, Other>
345 solve(
const MatrixBase<Other>& other)
const;
347 template<
int S
ide,
typename OtherDerived>
348 void solveInPlace(
const MatrixBase<OtherDerived>& other)
const;
350 template<
typename Other>
351 inline const internal::triangular_solve_retval<OnTheLeft,TriangularView, Other>
353 {
return solve<OnTheLeft>(other); }
355 template<
typename OtherDerived>
357 {
return solveInPlace<OnTheLeft>(other); }
370 template<
typename OtherDerived>
376 template<
typename OtherDerived>
394 template<
typename ProductDerived,
typename Lhs,
typename Rhs>
401 template<
typename ProductDerived,
typename Lhs,
typename Rhs>
407 template<
typename ProductDerived,
typename Lhs,
typename Rhs>
414 template<
typename ProductDerived>
421 template<
typename ProductDerived>
427 template<
typename ProductDerived>
435 template<
typename ProductDerived,
typename Lhs,
typename Rhs>
447 template<
typename Derived1,
typename Derived2,
unsigned int Mode,
int UnrollCount,
bool ClearOpposite>
448 struct triangular_assignment_selector
451 col = (UnrollCount-1) / Derived1::RowsAtCompileTime,
452 row = (UnrollCount-1) % Derived1::RowsAtCompileTime
455 typedef typename Derived1::Scalar Scalar;
457 static inline void run(Derived1 &dst,
const Derived2 &src)
459 triangular_assignment_selector<Derived1, Derived2, Mode, UnrollCount-1, ClearOpposite>::run(dst, src);
470 dst.copyCoeff(
row,
col, src);
471 else if(ClearOpposite)
474 dst.coeffRef(
row,
col) = Scalar(1);
476 dst.coeffRef(
row,
col) = Scalar(0);
482 template<
typename Derived1,
typename Derived2,
unsigned int Mode,
bool ClearOpposite>
483 struct triangular_assignment_selector<Derived1, Derived2, Mode, 0, ClearOpposite>
485 static inline void run(Derived1 &,
const Derived2 &) {}
488 template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
489 struct triangular_assignment_selector<Derived1, Derived2,
Upper,
Dynamic, ClearOpposite>
491 typedef typename Derived1::Index Index;
492 typedef typename Derived1::Scalar Scalar;
493 static inline void run(Derived1 &dst,
const Derived2 &src)
495 for(Index j = 0; j < dst.cols(); ++j)
497 Index maxi = (std::min)(j, dst.rows()-1);
498 for(Index i = 0; i <= maxi; ++i)
499 dst.copyCoeff(i, j, src);
501 for(Index i = maxi+1; i < dst.rows(); ++i)
502 dst.coeffRef(i, j) = Scalar(0);
507 template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
508 struct triangular_assignment_selector<Derived1, Derived2,
Lower,
Dynamic, ClearOpposite>
510 typedef typename Derived1::Index Index;
511 static inline void run(Derived1 &dst,
const Derived2 &src)
513 for(Index j = 0; j < dst.cols(); ++j)
515 for(Index i = j; i < dst.rows(); ++i)
516 dst.copyCoeff(i, j, src);
517 Index maxi = (std::min)(j, dst.rows());
519 for(Index i = 0; i < maxi; ++i)
520 dst.coeffRef(i, j) =
static_cast<typename Derived1::Scalar
>(0);
525 template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
526 struct triangular_assignment_selector<Derived1, Derived2,
StrictlyUpper,
Dynamic, ClearOpposite>
528 typedef typename Derived1::Index Index;
529 static inline void run(Derived1 &dst,
const Derived2 &src)
531 for(Index j = 0; j < dst.cols(); ++j)
533 Index maxi = (std::min)(j, dst.rows());
534 for(Index i = 0; i < maxi; ++i)
535 dst.copyCoeff(i, j, src);
537 for(Index i = maxi; i < dst.rows(); ++i)
538 dst.coeffRef(i, j) = 0;
543 template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
544 struct triangular_assignment_selector<Derived1, Derived2,
StrictlyLower,
Dynamic, ClearOpposite>
546 typedef typename Derived1::Index Index;
547 static inline void run(Derived1 &dst,
const Derived2 &src)
549 for(Index j = 0; j < dst.cols(); ++j)
551 for(Index i = j+1; i < dst.rows(); ++i)
552 dst.copyCoeff(i, j, src);
553 Index maxi = (std::min)(j, dst.rows()-1);
555 for(Index i = 0; i <= maxi; ++i)
556 dst.coeffRef(i, j) =
static_cast<typename Derived1::Scalar
>(0);
561 template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
562 struct triangular_assignment_selector<Derived1, Derived2,
UnitUpper,
Dynamic, ClearOpposite>
564 typedef typename Derived1::Index Index;
565 static inline void run(Derived1 &dst,
const Derived2 &src)
567 for(Index j = 0; j < dst.cols(); ++j)
569 Index maxi = (std::min)(j, dst.rows());
570 for(Index i = 0; i < maxi; ++i)
571 dst.copyCoeff(i, j, src);
574 for(Index i = maxi+1; i < dst.rows(); ++i)
575 dst.coeffRef(i, j) = 0;
578 dst.diagonal().setOnes();
581 template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
582 struct triangular_assignment_selector<Derived1, Derived2,
UnitLower,
Dynamic, ClearOpposite>
584 typedef typename Derived1::Index Index;
585 static inline void run(Derived1 &dst,
const Derived2 &src)
587 for(Index j = 0; j < dst.cols(); ++j)
589 Index maxi = (std::min)(j, dst.rows());
590 for(Index i = maxi+1; i < dst.rows(); ++i)
591 dst.copyCoeff(i, j, src);
594 for(Index i = 0; i < maxi; ++i)
595 dst.coeffRef(i, j) = 0;
598 dst.diagonal().setOnes();
605 template<
typename MatrixType,
unsigned int Mode>
606 template<
typename OtherDerived>
607 inline TriangularView<MatrixType, Mode>&
612 typename internal::plain_matrix_type<OtherDerived>::type other_evaluated(other.rows(), other.cols());
613 other_evaluated.template triangularView<Mode>().lazyAssign(other.derived());
614 lazyAssign(other_evaluated);
617 lazyAssign(other.derived());
622 template<
typename MatrixType,
unsigned int Mode>
623 template<
typename OtherDerived>
627 unroll = MatrixType::SizeAtCompileTime !=
Dynamic
628 && internal::traits<OtherDerived>::CoeffReadCost !=
Dynamic
629 && MatrixType::SizeAtCompileTime*internal::traits<OtherDerived>::CoeffReadCost/2 <=
EIGEN_UNROLLING_LIMIT
631 eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols());
633 internal::triangular_assignment_selector
635 unroll ?
int(MatrixType::SizeAtCompileTime) :
Dynamic,
637 >::run(m_matrix.const_cast_derived(), other.derived());
642 template<
typename MatrixType,
unsigned int Mode>
643 template<
typename OtherDerived>
650 typename OtherDerived::DenseMatrixType other_evaluated(other.
rows(), other.
cols());
651 other_evaluated.template triangularView<Mode>().lazyAssign(other.
derived().nestedExpression());
652 lazyAssign(other_evaluated);
655 lazyAssign(other.
derived().nestedExpression());
659 template<
typename MatrixType,
unsigned int Mode>
660 template<
typename OtherDerived>
664 unroll = MatrixType::SizeAtCompileTime !=
Dynamic
665 && internal::traits<OtherDerived>::CoeffReadCost !=
Dynamic
666 && MatrixType::SizeAtCompileTime * internal::traits<OtherDerived>::CoeffReadCost / 2
671 internal::triangular_assignment_selector
673 unroll ?
int(MatrixType::SizeAtCompileTime) :
Dynamic,
675 >::run(m_matrix.const_cast_derived(), other.
derived().nestedExpression());
684 template<
typename Derived>
685 template<
typename DenseDerived>
690 typename internal::plain_matrix_type<Derived>::type other_evaluated(rows(), cols());
691 evalToLazy(other_evaluated);
692 other.derived().
swap(other_evaluated);
695 evalToLazy(other.derived());
700 template<
typename Derived>
701 template<
typename DenseDerived>
705 unroll = DenseDerived::SizeAtCompileTime !=
Dynamic
706 && internal::traits<Derived>::CoeffReadCost !=
Dynamic
707 && DenseDerived::SizeAtCompileTime * internal::traits<Derived>::CoeffReadCost / 2
710 other.derived().
resize(this->rows(), this->cols());
712 internal::triangular_assignment_selector
713 <DenseDerived,
typename internal::traits<Derived>::MatrixTypeNestedCleaned, Derived::Mode,
714 unroll ?
int(DenseDerived::SizeAtCompileTime) :
Dynamic,
716 >::run(other.derived(), derived().nestedExpression());
727 #ifdef EIGEN2_SUPPORT
732 template<
typename MatrixType,
unsigned int Mode>
733 struct eigen2_part_return_type
738 template<
typename MatrixType>
739 struct eigen2_part_return_type<MatrixType,
SelfAdjoint>
741 typedef SelfAdjointView<MatrixType, Upper> type;
746 template<
typename Derived>
747 template<
unsigned int Mode>
748 const typename internal::eigen2_part_return_type<Derived, Mode>::type MatrixBase<Derived>::part()
const
754 template<
typename Derived>
755 template<
unsigned int Mode>
756 typename internal::eigen2_part_return_type<Derived, Mode>::type MatrixBase<Derived>::part()
773 template<
typename Derived>
774 template<
unsigned int Mode>
782 template<
typename Derived>
783 template<
unsigned int Mode>
795 template<
typename Derived>
799 for(
Index j = 0; j < cols(); ++j)
801 Index maxi = (std::min)(j, rows()-1);
802 for(
Index i = 0; i <= maxi; ++i)
805 if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
808 RealScalar threshold = maxAbsOnUpperPart * prec;
809 for(
Index j = 0; j < cols(); ++j)
810 for(
Index i = j+1; i < rows(); ++i)
820 template<
typename Derived>
824 for(
Index j = 0; j < cols(); ++j)
825 for(
Index i = j; i < rows(); ++i)
828 if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
830 RealScalar threshold = maxAbsOnLowerPart * prec;
831 for(
Index j = 1; j < cols(); ++j)
833 Index maxi = (std::min)(j, rows()-1);
834 for(
Index i = 0; i < maxi; ++i)
842 #endif // EIGEN_TRIANGULARMATRIX_H