276 return m_matrix.transpose();
280 template<
typename OtherDerived>
281 TriangularProduct<Mode, true, MatrixType, false, OtherDerived, OtherDerived::ColsAtCompileTime==1>
284 return TriangularProduct
285 <Mode,
true, MatrixType,
false, OtherDerived, OtherDerived::ColsAtCompileTime==1>
286 (m_matrix, rhs.derived());
290 template<
typename OtherDerived>
friend
291 TriangularProduct<Mode, false, OtherDerived, OtherDerived::RowsAtCompileTime==1, MatrixType, false>
294 return TriangularProduct
295 <Mode,
false, OtherDerived, OtherDerived::RowsAtCompileTime==1, 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.derived(),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.derived(),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.derived(),-1);
399 template<
typename ProductDerived>
400 EIGEN_STRONG_INLINE TriangularView&
operator=(
const ScaledProduct<ProductDerived>& other)
403 return assignProduct(other.derived(),other.alpha());
406 template<
typename ProductDerived>
407 EIGEN_STRONG_INLINE TriangularView&
operator+=(
const ScaledProduct<ProductDerived>& other)
409 return assignProduct(other.derived(),other.alpha());
412 template<
typename ProductDerived>
413 EIGEN_STRONG_INLINE TriangularView&
operator-=(
const ScaledProduct<ProductDerived>& other)
415 return assignProduct(other.derived(),-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 template<
int Mode,
bool LhsIsTriangular,
424 typename Lhs,
bool LhsIsVector,
425 typename Rhs,
bool RhsIsVector>
426 EIGEN_STRONG_INLINE TriangularView& assignProduct(
const TriangularProduct<Mode, LhsIsTriangular, Lhs, LhsIsVector, Rhs, RhsIsVector>& prod,
const Scalar& alpha)
428 lazyAssign(alpha*prod.eval());
432 MatrixTypeNested m_matrix;
441template<
typename Derived1,
typename Derived2,
unsigned int Mode,
int UnrollCount,
bool ClearOpposite>
442struct triangular_assignment_selector
445 col = (UnrollCount-1) / Derived1::RowsAtCompileTime,
446 row = (UnrollCount-1) % Derived1::RowsAtCompileTime
449 typedef typename Derived1::Scalar Scalar;
451 static inline void run(Derived1 &dst,
const Derived2 &src)
453 triangular_assignment_selector<Derived1, Derived2, Mode, UnrollCount-1, ClearOpposite>::run(dst, src);
458 if((Mode ==
Upper && row <= col)
459 || (Mode ==
Lower && row >= col)
464 dst.copyCoeff(row, col, src);
465 else if(ClearOpposite)
468 dst.coeffRef(row, col) = Scalar(1);
470 dst.coeffRef(row, col) = Scalar(0);
476template<
typename Derived1,
typename Derived2,
unsigned int Mode,
bool ClearOpposite>
477struct triangular_assignment_selector<Derived1, Derived2, Mode, 0, ClearOpposite>
479 static inline void run(Derived1 &,
const Derived2 &) {}
482template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
483struct triangular_assignment_selector<Derived1, Derived2,
Upper, Dynamic, ClearOpposite>
485 typedef typename Derived1::Index Index;
486 typedef typename Derived1::Scalar Scalar;
487 static inline void run(Derived1 &dst,
const Derived2 &src)
489 for(Index j = 0; j < dst.cols(); ++j)
491 Index maxi = (std::min)(j, dst.rows()-1);
492 for(Index i = 0; i <= maxi; ++i)
493 dst.copyCoeff(i, j, src);
495 for(Index i = maxi+1; i < dst.rows(); ++i)
496 dst.coeffRef(i, j) = Scalar(0);
501template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
502struct triangular_assignment_selector<Derived1, Derived2,
Lower, Dynamic, ClearOpposite>
504 typedef typename Derived1::Index Index;
505 static inline void run(Derived1 &dst,
const Derived2 &src)
507 for(Index j = 0; j < dst.cols(); ++j)
509 for(Index i = j; i < dst.rows(); ++i)
510 dst.copyCoeff(i, j, src);
511 Index maxi = (std::min)(j, dst.rows());
513 for(Index i = 0; i < maxi; ++i)
514 dst.coeffRef(i, j) =
static_cast<typename Derived1::Scalar
>(0);
519template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
520struct triangular_assignment_selector<Derived1, Derived2,
StrictlyUpper, Dynamic, ClearOpposite>
522 typedef typename Derived1::Index Index;
523 typedef typename Derived1::Scalar Scalar;
524 static inline void run(Derived1 &dst,
const Derived2 &src)
526 for(Index j = 0; j < dst.cols(); ++j)
528 Index maxi = (std::min)(j, dst.rows());
529 for(Index i = 0; i < maxi; ++i)
530 dst.copyCoeff(i, j, src);
532 for(Index i = maxi; i < dst.rows(); ++i)
533 dst.coeffRef(i, j) = Scalar(0);
538template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
539struct triangular_assignment_selector<Derived1, Derived2,
StrictlyLower, Dynamic, ClearOpposite>
541 typedef typename Derived1::Index Index;
542 static inline void run(Derived1 &dst,
const Derived2 &src)
544 for(Index j = 0; j < dst.cols(); ++j)
546 for(Index i = j+1; i < dst.rows(); ++i)
547 dst.copyCoeff(i, j, src);
548 Index maxi = (std::min)(j, dst.rows()-1);
550 for(Index i = 0; i <= maxi; ++i)
551 dst.coeffRef(i, j) =
static_cast<typename Derived1::Scalar
>(0);
556template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
557struct triangular_assignment_selector<Derived1, Derived2,
UnitUpper, Dynamic, ClearOpposite>
559 typedef typename Derived1::Index Index;
560 static inline void run(Derived1 &dst,
const Derived2 &src)
562 for(Index j = 0; j < dst.cols(); ++j)
564 Index maxi = (std::min)(j, dst.rows());
565 for(Index i = 0; i < maxi; ++i)
566 dst.copyCoeff(i, j, src);
569 for(Index i = maxi+1; i < dst.rows(); ++i)
570 dst.coeffRef(i, j) = 0;
573 dst.diagonal().setOnes();
576template<
typename Derived1,
typename Derived2,
bool ClearOpposite>
577struct triangular_assignment_selector<Derived1, Derived2,
UnitLower, Dynamic, ClearOpposite>
579 typedef typename Derived1::Index Index;
580 static inline void run(Derived1 &dst,
const Derived2 &src)
582 for(Index j = 0; j < dst.cols(); ++j)
584 Index maxi = (std::min)(j, dst.rows());
585 for(Index i = maxi+1; i < dst.rows(); ++i)
586 dst.copyCoeff(i, j, src);
589 for(Index i = 0; i < maxi; ++i)
590 dst.coeffRef(i, j) = 0;
593 dst.diagonal().setOnes();
600template<
typename MatrixType,
unsigned int Mode>
601template<
typename OtherDerived>
607 typename internal::plain_matrix_type<OtherDerived>::type other_evaluated(other.rows(), other.cols());
608 other_evaluated.template triangularView<Mode>().lazyAssign(other.derived());
609 lazyAssign(other_evaluated);
612 lazyAssign(other.derived());
617template<
typename MatrixType,
unsigned int Mode>
618template<
typename OtherDerived>
622 unroll = MatrixType::SizeAtCompileTime != Dynamic
623 && internal::traits<OtherDerived>::CoeffReadCost != Dynamic
624 && MatrixType::SizeAtCompileTime*internal::traits<OtherDerived>::CoeffReadCost/2 <= EIGEN_UNROLLING_LIMIT
626 eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols());
628 internal::triangular_assignment_selector
630 unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic,
632 >::run(m_matrix.const_cast_derived(), other.derived());
637template<
typename MatrixType,
unsigned int Mode>
638template<
typename OtherDerived>
642 eigen_assert(Mode ==
int(OtherDerived::Mode));
645 typename OtherDerived::DenseMatrixType other_evaluated(other.rows(), other.cols());
646 other_evaluated.template triangularView<Mode>().lazyAssign(other.derived().nestedExpression());
647 lazyAssign(other_evaluated);
650 lazyAssign(other.derived().nestedExpression());
654template<
typename MatrixType,
unsigned int Mode>
655template<
typename OtherDerived>
656void TriangularView<MatrixType, Mode>::lazyAssign(
const TriangularBase<OtherDerived>& other)
659 unroll = MatrixType::SizeAtCompileTime != Dynamic
660 && internal::traits<OtherDerived>::CoeffReadCost != Dynamic
661 && MatrixType::SizeAtCompileTime * internal::traits<OtherDerived>::CoeffReadCost / 2
662 <= EIGEN_UNROLLING_LIMIT
664 eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols());
666 internal::triangular_assignment_selector
668 unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic,
670 >::run(m_matrix.const_cast_derived(), other.derived().nestedExpression());
679template<
typename Derived>
680template<
typename DenseDerived>
685 typename internal::plain_matrix_type<Derived>::type other_evaluated(rows(), cols());
686 evalToLazy(other_evaluated);
687 other.derived().swap(other_evaluated);
690 evalToLazy(other.derived());
695template<
typename Derived>
696template<
typename DenseDerived>
700 unroll = DenseDerived::SizeAtCompileTime != Dynamic
701 && internal::traits<Derived>::CoeffReadCost != Dynamic
702 && DenseDerived::SizeAtCompileTime * internal::traits<Derived>::CoeffReadCost / 2
703 <= EIGEN_UNROLLING_LIMIT
705 other.derived().resize(this->rows(), this->cols());
707 internal::triangular_assignment_selector
708 <DenseDerived,
typename internal::traits<Derived>::MatrixTypeNestedCleaned, Derived::Mode,
709 unroll ? int(DenseDerived::SizeAtCompileTime) : Dynamic,
711 >::run(other.derived(), derived().nestedExpression());
727template<
typename MatrixType,
unsigned int Mode>
728struct eigen2_part_return_type
730 typedef TriangularView<MatrixType, Mode> type;
733template<
typename MatrixType>
734struct eigen2_part_return_type<MatrixType,
SelfAdjoint>
736 typedef SelfAdjointView<MatrixType, Upper> type;
741template<
typename Derived>
742template<
unsigned int Mode>
749template<
typename Derived>
750template<
unsigned int Mode>
768template<
typename Derived>
769template<
unsigned int Mode>
771MatrixBase<Derived>::triangularView()
777template<
typename Derived>
778template<
unsigned int Mode>
780MatrixBase<Derived>::triangularView()
const
790template<
typename Derived>
794 RealScalar maxAbsOnUpperPart =
static_cast<RealScalar
>(-1);
795 for(
Index j = 0; j < cols(); ++j)
797 Index maxi = (std::min)(j, rows()-1);
798 for(
Index i = 0; i <= maxi; ++i)
800 RealScalar absValue = abs(coeff(i,j));
801 if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
804 RealScalar threshold = maxAbsOnUpperPart * prec;
805 for(
Index j = 0; j < cols(); ++j)
806 for(
Index i = j+1; i < rows(); ++i)
807 if(abs(coeff(i, j)) > threshold)
return false;
816template<
typename Derived>
820 RealScalar maxAbsOnLowerPart =
static_cast<RealScalar
>(-1);
821 for(
Index j = 0; j < cols(); ++j)
822 for(
Index i = j; i < rows(); ++i)
824 RealScalar absValue = abs(coeff(i,j));
825 if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
827 RealScalar threshold = maxAbsOnLowerPart * prec;
828 for(
Index j = 1; j < cols(); ++j)
830 Index maxi = (std::min)(j, rows()-1);
831 for(
Index i = 0; i < maxi; ++i)
832 if(abs(coeff(i, j)) > threshold)
return false;