268 inline TriangularView<Transpose<MatrixType>,TransposeMode>
transpose()
270 EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
271 return m_matrix.const_cast_derived().transpose();
274 inline const TriangularView<Transpose<MatrixType>,TransposeMode>
transpose()
const
276 return m_matrix.transpose();
280 template<
typename OtherDerived>
281 TriangularProduct<Mode,true,MatrixType,false,OtherDerived, OtherDerived::IsVectorAtCompileTime>
284 return TriangularProduct
285 <Mode,
true,MatrixType,
false,OtherDerived,OtherDerived::IsVectorAtCompileTime>
286 (m_matrix, rhs.derived());
290 template<
typename OtherDerived>
friend
291 TriangularProduct<Mode,false,OtherDerived,OtherDerived::IsVectorAtCompileTime,MatrixType,false>
294 return TriangularProduct
295 <Mode,
false,OtherDerived,OtherDerived::IsVectorAtCompileTime,MatrixType,
false>
296 (lhs.derived(),rhs.m_matrix);
299 #ifdef EIGEN2_SUPPORT
300 template<
typename OtherDerived>
301 struct eigen2_product_return_type
303 typedef typename TriangularView<MatrixType,Mode>::DenseMatrixType DenseMatrixType;
304 typedef typename OtherDerived::PlainObject::DenseType OtherPlainObject;
305 typedef typename ProductReturnType<DenseMatrixType, OtherPlainObject>::Type ProdRetType;
306 typedef typename ProdRetType::PlainObject type;
308 template<
typename OtherDerived>
309 const typename eigen2_product_return_type<OtherDerived>::type
310 operator*(
const EigenBase<OtherDerived>& rhs)
const
312 typename OtherDerived::PlainObject::DenseType rhsPlainObject;
313 rhs.evalTo(rhsPlainObject);
314 return this->toDenseMatrix() * rhsPlainObject;
316 template<
typename OtherMatrixType>
317 bool isApprox(
const TriangularView<OtherMatrixType, Mode>& other,
typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
const
319 return this->toDenseMatrix().isApprox(other.toDenseMatrix(), precision);
321 template<
typename OtherDerived>
322 bool isApprox(
const MatrixBase<OtherDerived>& other,
typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
const
324 return this->toDenseMatrix().isApprox(other, precision);
328 template<
int S
ide,
typename Other>
329 inline const internal::triangular_solve_retval<Side,TriangularView, Other>
330 solve(
const MatrixBase<Other>& other)
const;
332 template<
int S
ide,
typename OtherDerived>
335 template<
typename Other>
336 inline const internal::triangular_solve_retval<OnTheLeft,TriangularView, Other>
338 {
return solve<OnTheLeft>(other); }
340 template<
typename OtherDerived>
344 const SelfAdjointView<MatrixTypeNestedNonRef,Mode> selfadjointView()
const
346 EIGEN_STATIC_ASSERT((Mode&
UnitDiag)==0,PROGRAMMING_ERROR);
347 return SelfAdjointView<MatrixTypeNestedNonRef,Mode>(m_matrix);
349 SelfAdjointView<MatrixTypeNestedNonRef,Mode> selfadjointView()
351 EIGEN_STATIC_ASSERT((Mode&
UnitDiag)==0,PROGRAMMING_ERROR);
352 return SelfAdjointView<MatrixTypeNestedNonRef,Mode>(m_matrix);
355 template<
typename OtherDerived>
356 void swap(TriangularBase<OtherDerived>
const & other)
358 TriangularView<SwapWrapper<MatrixType>,Mode>(
const_cast<MatrixType&
>(m_matrix)).lazyAssign(other.derived());
361 template<
typename OtherDerived>
362 void swap(MatrixBase<OtherDerived>
const & other)
364 SwapWrapper<MatrixType> swaper(
const_cast<MatrixType&
>(m_matrix));
365 TriangularView<SwapWrapper<MatrixType>,Mode>(swaper).lazyAssign(other.derived());
368 Scalar determinant()
const
375 return m_matrix.diagonal().prod();
379 template<
typename ProductDerived,
typename Lhs,
typename Rhs>
380 EIGEN_STRONG_INLINE TriangularView&
operator=(
const ProductBase<ProductDerived, Lhs,Rhs>& other)
383 return assignProduct(other,1);
386 template<
typename ProductDerived,
typename Lhs,
typename Rhs>
387 EIGEN_STRONG_INLINE TriangularView&
operator+=(
const ProductBase<ProductDerived, Lhs,Rhs>& other)
389 return assignProduct(other,1);
392 template<
typename ProductDerived,
typename Lhs,
typename Rhs>
393 EIGEN_STRONG_INLINE TriangularView&
operator-=(
const ProductBase<ProductDerived, Lhs,Rhs>& other)
395 return assignProduct(other,-1);
399 template<
typename ProductDerived>
400 EIGEN_STRONG_INLINE TriangularView&
operator=(
const ScaledProduct<ProductDerived>& other)
403 return assignProduct(other,other.alpha());
406 template<
typename ProductDerived>
407 EIGEN_STRONG_INLINE TriangularView&
operator+=(
const ScaledProduct<ProductDerived>& other)
409 return assignProduct(other,other.alpha());
412 template<
typename ProductDerived>
413 EIGEN_STRONG_INLINE TriangularView&
operator-=(
const ScaledProduct<ProductDerived>& other)
415 return assignProduct(other,-other.alpha());
420 template<
typename ProductDerived,
typename Lhs,
typename Rhs>
421 EIGEN_STRONG_INLINE TriangularView& assignProduct(
const ProductBase<ProductDerived, Lhs,Rhs>& prod,
const Scalar& alpha);
423 MatrixTypeNested m_matrix;
432template<
typename Derived1,
typename Derived2,
unsigned int Mode,
int UnrollCount,
bool ClearOpposite>
433struct triangular_assignment_selector
436 col = (UnrollCount-1) / Derived1::RowsAtCompileTime,
437 row = (UnrollCount-1) % Derived1::RowsAtCompileTime
440 typedef typename Derived1::Scalar Scalar;
442 static inline void run(Derived1 &dst,
const Derived2 &src)
444 triangular_assignment_selector<Derived1, Derived2, Mode, UnrollCount-1, ClearOpposite>::run(dst, src);
449 if((Mode ==
Upper && row <= col)
450 || (Mode ==
Lower && row >= col)
455 dst.copyCoeff(row, col, src);
456 else if(ClearOpposite)
459 dst.coeffRef(row, col) = Scalar(1);
461 dst.coeffRef(row, col) = Scalar(0);
467template<
typename Derived1,
typename Derived2,
unsigned int Mode,
bool ClearOpposite>
468struct triangular_assignment_selector<Derived1, Derived2, Mode, 0, ClearOpposite>
470 static inline void run(Derived1 &,
const Derived2 &) {}
473template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
474struct triangular_assignment_selector<Derived1, Derived2,
Upper, Dynamic, ClearOpposite>
476 typedef typename Derived1::Index Index;
477 typedef typename Derived1::Scalar Scalar;
478 static inline void run(Derived1 &dst,
const Derived2 &src)
480 for(Index j = 0; j < dst.cols(); ++j)
482 Index maxi = (std::min)(j, dst.rows()-1);
483 for(Index i = 0; i <= maxi; ++i)
484 dst.copyCoeff(i, j, src);
486 for(Index i = maxi+1; i < dst.rows(); ++i)
487 dst.coeffRef(i, j) = Scalar(0);
492template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
493struct triangular_assignment_selector<Derived1, Derived2,
Lower, Dynamic, ClearOpposite>
495 typedef typename Derived1::Index Index;
496 static inline void run(Derived1 &dst,
const Derived2 &src)
498 for(Index j = 0; j < dst.cols(); ++j)
500 for(Index i = j; i < dst.rows(); ++i)
501 dst.copyCoeff(i, j, src);
502 Index maxi = (std::min)(j, dst.rows());
504 for(Index i = 0; i < maxi; ++i)
505 dst.coeffRef(i, j) =
static_cast<typename Derived1::Scalar
>(0);
510template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
511struct triangular_assignment_selector<Derived1, Derived2,
StrictlyUpper, Dynamic, ClearOpposite>
513 typedef typename Derived1::Index Index;
514 typedef typename Derived1::Scalar Scalar;
515 static inline void run(Derived1 &dst,
const Derived2 &src)
517 for(Index j = 0; j < dst.cols(); ++j)
519 Index maxi = (std::min)(j, dst.rows());
520 for(Index i = 0; i < maxi; ++i)
521 dst.copyCoeff(i, j, src);
523 for(Index i = maxi; i < dst.rows(); ++i)
524 dst.coeffRef(i, j) = Scalar(0);
529template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
530struct triangular_assignment_selector<Derived1, Derived2,
StrictlyLower, Dynamic, ClearOpposite>
532 typedef typename Derived1::Index Index;
533 static inline void run(Derived1 &dst,
const Derived2 &src)
535 for(Index j = 0; j < dst.cols(); ++j)
537 for(Index i = j+1; i < dst.rows(); ++i)
538 dst.copyCoeff(i, j, src);
539 Index maxi = (std::min)(j, dst.rows()-1);
541 for(Index i = 0; i <= maxi; ++i)
542 dst.coeffRef(i, j) =
static_cast<typename Derived1::Scalar
>(0);
547template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
548struct triangular_assignment_selector<Derived1, Derived2,
UnitUpper, Dynamic, ClearOpposite>
550 typedef typename Derived1::Index Index;
551 static inline void run(Derived1 &dst,
const Derived2 &src)
553 for(Index j = 0; j < dst.cols(); ++j)
555 Index maxi = (std::min)(j, dst.rows());
556 for(Index i = 0; i < maxi; ++i)
557 dst.copyCoeff(i, j, src);
560 for(Index i = maxi+1; i < dst.rows(); ++i)
561 dst.coeffRef(i, j) = 0;
564 dst.diagonal().setOnes();
567template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
568struct triangular_assignment_selector<Derived1, Derived2,
UnitLower, Dynamic, ClearOpposite>
570 typedef typename Derived1::Index Index;
571 static inline void run(Derived1 &dst,
const Derived2 &src)
573 for(Index j = 0; j < dst.cols(); ++j)
575 Index maxi = (std::min)(j, dst.rows());
576 for(Index i = maxi+1; i < dst.rows(); ++i)
577 dst.copyCoeff(i, j, src);
580 for(Index i = 0; i < maxi; ++i)
581 dst.coeffRef(i, j) = 0;
584 dst.diagonal().setOnes();
591template<
typename MatrixType,
unsigned int Mode>
592template<
typename OtherDerived>
598 typename internal::plain_matrix_type<OtherDerived>::type other_evaluated(other.rows(), other.cols());
599 other_evaluated.template triangularView<Mode>().lazyAssign(other.derived());
600 lazyAssign(other_evaluated);
603 lazyAssign(other.derived());
608template<
typename MatrixType,
unsigned int Mode>
609template<
typename OtherDerived>
613 unroll = MatrixType::SizeAtCompileTime != Dynamic
614 && internal::traits<OtherDerived>::CoeffReadCost != Dynamic
615 && MatrixType::SizeAtCompileTime*internal::traits<OtherDerived>::CoeffReadCost/2 <= EIGEN_UNROLLING_LIMIT
617 eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols());
619 internal::triangular_assignment_selector
621 unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic,
623 >::run(m_matrix.const_cast_derived(), other.derived());
628template<
typename MatrixType,
unsigned int Mode>
629template<
typename OtherDerived>
633 eigen_assert(Mode ==
int(OtherDerived::Mode));
636 typename OtherDerived::DenseMatrixType other_evaluated(other.rows(), other.cols());
637 other_evaluated.template triangularView<Mode>().lazyAssign(other.derived().nestedExpression());
638 lazyAssign(other_evaluated);
641 lazyAssign(other.derived().nestedExpression());
645template<
typename MatrixType,
unsigned int Mode>
646template<
typename OtherDerived>
647void TriangularView<MatrixType, Mode>::lazyAssign(
const TriangularBase<OtherDerived>& other)
650 unroll = MatrixType::SizeAtCompileTime != Dynamic
651 && internal::traits<OtherDerived>::CoeffReadCost != Dynamic
652 && MatrixType::SizeAtCompileTime * internal::traits<OtherDerived>::CoeffReadCost / 2
653 <= EIGEN_UNROLLING_LIMIT
655 eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols());
657 internal::triangular_assignment_selector
659 unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic,
661 >::run(m_matrix.const_cast_derived(), other.derived().nestedExpression());
670template<
typename Derived>
671template<
typename DenseDerived>
676 typename internal::plain_matrix_type<Derived>::type other_evaluated(rows(), cols());
677 evalToLazy(other_evaluated);
678 other.derived().swap(other_evaluated);
681 evalToLazy(other.derived());
686template<
typename Derived>
687template<
typename DenseDerived>
691 unroll = DenseDerived::SizeAtCompileTime != Dynamic
692 && internal::traits<Derived>::CoeffReadCost != Dynamic
693 && DenseDerived::SizeAtCompileTime * internal::traits<Derived>::CoeffReadCost / 2
694 <= EIGEN_UNROLLING_LIMIT
696 other.derived().resize(this->rows(), this->cols());
698 internal::triangular_assignment_selector
699 <DenseDerived,
typename internal::traits<Derived>::MatrixTypeNestedCleaned, Derived::Mode,
700 unroll ? int(DenseDerived::SizeAtCompileTime) : Dynamic,
702 >::run(other.derived(), derived().nestedExpression());
718template<
typename MatrixType,
unsigned int Mode>
719struct eigen2_part_return_type
721 typedef TriangularView<MatrixType, Mode> type;
724template<
typename MatrixType>
725struct eigen2_part_return_type<MatrixType,
SelfAdjoint>
727 typedef SelfAdjointView<MatrixType, Upper> type;
732template<
typename Derived>
733template<
unsigned int Mode>
740template<
typename Derived>
741template<
unsigned int Mode>
759template<
typename Derived>
760template<
unsigned int Mode>
762MatrixBase<Derived>::triangularView()
768template<
typename Derived>
769template<
unsigned int Mode>
771MatrixBase<Derived>::triangularView()
const
781template<
typename Derived>
784 RealScalar maxAbsOnUpperPart =
static_cast<RealScalar
>(-1);
785 for(
Index j = 0; j < cols(); ++j)
787 Index maxi = (std::min)(j, rows()-1);
788 for(
Index i = 0; i <= maxi; ++i)
790 RealScalar absValue = internal::abs(coeff(i,j));
791 if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
794 RealScalar threshold = maxAbsOnUpperPart * prec;
795 for(
Index j = 0; j < cols(); ++j)
796 for(
Index i = j+1; i < rows(); ++i)
797 if(internal::abs(coeff(i, j)) > threshold)
return false;
806template<
typename Derived>
809 RealScalar maxAbsOnLowerPart =
static_cast<RealScalar
>(-1);
810 for(
Index j = 0; j < cols(); ++j)
811 for(
Index i = j; i < rows(); ++i)
813 RealScalar absValue = internal::abs(coeff(i,j));
814 if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
816 RealScalar threshold = maxAbsOnLowerPart * prec;
817 for(
Index j = 1; j < cols(); ++j)
819 Index maxi = (std::min)(j, rows()-1);
820 for(
Index i = 0; i < maxi; ++i)
821 if(internal::abs(coeff(i, j)) > threshold)
return false;