316 return m_matrix.diagonal().prod();
321 MatrixTypeNested m_matrix;
333template<
typename _MatrixType,
unsigned int _Mode>
class TriangularViewImpl<_MatrixType,_Mode,
Dense>
340 typedef typename internal::traits<TriangularViewType>::Scalar Scalar;
342 typedef _MatrixType MatrixType;
343 typedef typename MatrixType::PlainObject DenseMatrixType;
344 typedef DenseMatrixType PlainObject;
347 using Base::evalToLazy;
350 typedef typename internal::traits<TriangularViewType>::StorageKind StorageKind;
354 Flags = internal::traits<TriangularViewType>::Flags
367 template<
typename Other>
370 internal::call_assignment_no_alias(derived(), other.
derived(), internal::add_assign_op<Scalar,typename Other::Scalar>());
374 template<
typename Other>
377 internal::call_assignment_no_alias(derived(), other.
derived(), internal::sub_assign_op<Scalar,typename Other::Scalar>());
383 TriangularViewType&
operator*=(
const typename internal::traits<MatrixType>::Scalar& other) {
return *
this = derived().nestedExpression() * other; }
386 TriangularViewType&
operator/=(
const typename internal::traits<MatrixType>::Scalar& other) {
return *
this = derived().nestedExpression() / other; }
390 void fill(
const Scalar& value) { setConstant(value); }
394 {
return *
this = MatrixType::Constant(derived().rows(), derived().cols(), value); }
397 TriangularViewType&
setZero() {
return setConstant(Scalar(0)); }
400 TriangularViewType&
setOnes() {
return setConstant(Scalar(1)); }
408 Base::check_coordinates_internal(row, col);
409 return derived().nestedExpression().coeff(row, col);
418 EIGEN_STATIC_ASSERT_LVALUE(TriangularViewType);
419 Base::check_coordinates_internal(row, col);
420 return derived().nestedExpression().coeffRef(row, col);
424 template<
typename OtherDerived>
429 template<
typename OtherDerived>
433#ifndef EIGEN_PARSED_BY_DOXYGEN
435 TriangularViewType& operator=(
const TriangularViewImpl& other)
436 {
return *
this = other.derived().nestedExpression(); }
439 template<
typename OtherDerived>
444 template<
typename OtherDerived>
450 template<
typename OtherDerived>
459 template<
typename OtherDerived>
friend
488 template<
int S
ide,
typename Other>
490 inline const internal::triangular_solve_retval<Side,TriangularViewType, Other>
500 template<
int S
ide,
typename OtherDerived>
504 template<
typename OtherDerived>
507 {
return solveInPlace<OnTheLeft>(other); }
510 template<
typename OtherDerived>
512#ifdef EIGEN_PARSED_BY_DOXYGEN
518 EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
519 call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
524 template<
typename OtherDerived>
528 EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
529 call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
532 template<
typename RhsType,
typename DstType>
534 EIGEN_STRONG_INLINE
void _solve_impl(
const RhsType &rhs, DstType &dst)
const {
535 if(!internal::is_same_dense(dst,rhs))
537 this->solveInPlace(dst);
540 template<
typename ProductType>
542 EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(
const ProductType& prod,
const Scalar& alpha);
550template<
typename MatrixType,
unsigned int Mode>
551template<
typename OtherDerived>
552inline TriangularView<MatrixType, Mode>&
553TriangularViewImpl<MatrixType, Mode, Dense>::operator=(
const MatrixBase<OtherDerived>& other)
555 internal::call_assignment_no_alias(derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
560template<
typename MatrixType,
unsigned int Mode>
561template<
typename OtherDerived>
562void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(
const MatrixBase<OtherDerived>& other)
564 internal::call_assignment_no_alias(derived(), other.template triangularView<Mode>());
569template<
typename MatrixType,
unsigned int Mode>
570template<
typename OtherDerived>
571inline TriangularView<MatrixType, Mode>&
572TriangularViewImpl<MatrixType, Mode, Dense>::operator=(
const TriangularBase<OtherDerived>& other)
574 eigen_assert(Mode ==
int(OtherDerived::Mode));
575 internal::call_assignment(derived(), other.derived());
579template<
typename MatrixType,
unsigned int Mode>
580template<
typename OtherDerived>
581void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(
const TriangularBase<OtherDerived>& other)
583 eigen_assert(Mode ==
int(OtherDerived::Mode));
584 internal::call_assignment_no_alias(derived(), other.derived());
593template<
typename Derived>
594template<
typename DenseDerived>
619template<
typename Derived>
620template<
unsigned int Mode>
624 return typename TriangularViewReturnType<Mode>::Type(derived());
628template<
typename Derived>
629template<
unsigned int Mode>
633 return typename ConstTriangularViewReturnType<Mode>::Type(derived());
641template<
typename Derived>
644 RealScalar maxAbsOnUpperPart =
static_cast<RealScalar
>(-1);
645 for(
Index j = 0; j < cols(); ++j)
647 Index maxi = numext::mini(j, rows()-1);
648 for(
Index i = 0; i <= maxi; ++i)
650 RealScalar absValue = numext::abs(coeff(i,j));
651 if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
654 RealScalar threshold = maxAbsOnUpperPart * prec;
655 for(
Index j = 0; j < cols(); ++j)
656 for(
Index i = j+1; i < rows(); ++i)
657 if(numext::abs(coeff(i, j)) > threshold)
return false;
666template<
typename Derived>
669 RealScalar maxAbsOnLowerPart =
static_cast<RealScalar
>(-1);
670 for(
Index j = 0; j < cols(); ++j)
671 for(
Index i = j; i < rows(); ++i)
673 RealScalar absValue = numext::abs(coeff(i,j));
674 if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
676 RealScalar threshold = maxAbsOnLowerPart * prec;
677 for(
Index j = 1; j < cols(); ++j)
679 Index maxi = numext::mini(j, rows()-1);
680 for(
Index i = 0; i < maxi; ++i)
681 if(numext::abs(coeff(i, j)) > threshold)
return false;
699template<
typename MatrixType,
unsigned int Mode>
702 typedef typename storage_kind_to_evaluator_kind<typename MatrixType::StorageKind>::Kind Kind;
703 typedef typename glue_shapes<typename evaluator_traits<MatrixType>::Shape, TriangularShape>::type Shape;
706template<
typename MatrixType,
unsigned int Mode>
707struct unary_evaluator<TriangularView<MatrixType,Mode>, IndexBased>
708 : evaluator<typename internal::remove_all<MatrixType>::type>
710 typedef TriangularView<MatrixType,Mode> XprType;
711 typedef evaluator<typename internal::remove_all<MatrixType>::type> Base;
712 unary_evaluator(
const XprType &xpr) : Base(xpr.nestedExpression()) {}
716struct Triangular2Triangular {};
717struct Triangular2Dense {};
718struct Dense2Triangular {};
721template<
typename Kernel,
unsigned int Mode,
int UnrollCount,
bool ClearOpposite>
struct triangular_assignment_loop;
729template<
int UpLo,
int Mode,
int SetOpposite,
typename DstEvaluatorTypeT,
typename SrcEvaluatorTypeT,
typename Functor,
int Version = Specialized>
730class triangular_dense_assignment_kernel :
public generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version>
733 typedef generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version> Base;
734 typedef typename Base::DstXprType DstXprType;
735 typedef typename Base::SrcXprType SrcXprType;
738 using Base::m_functor;
741 typedef typename Base::DstEvaluatorType DstEvaluatorType;
742 typedef typename Base::SrcEvaluatorType SrcEvaluatorType;
743 typedef typename Base::Scalar Scalar;
744 typedef typename Base::AssignmentTraits AssignmentTraits;
747 EIGEN_DEVICE_FUNC triangular_dense_assignment_kernel(DstEvaluatorType &dst,
const SrcEvaluatorType &src,
const Functor &func, DstXprType& dstExpr)
748 : Base(dst, src, func, dstExpr)
751#ifdef EIGEN_INTERNAL_DEBUGGING
752 EIGEN_DEVICE_FUNC
void assignCoeff(
Index row,
Index col)
754 eigen_internal_assert(row!=col);
755 Base::assignCoeff(row,col);
758 using Base::assignCoeff;
761 EIGEN_DEVICE_FUNC
void assignDiagonalCoeff(
Index id)
763 if(Mode==
UnitDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(
id,
id), Scalar(1));
764 else if(Mode==
ZeroDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(
id,
id), Scalar(0));
765 else if(Mode==0) Base::assignCoeff(
id,
id);
768 EIGEN_DEVICE_FUNC
void assignOppositeCoeff(
Index row,
Index col)
770 eigen_internal_assert(row!=col);
772 m_functor.assignCoeff(m_dst.coeffRef(row,col), Scalar(0));
776template<
int Mode,
bool SetOpposite,
typename DstXprType,
typename SrcXprType,
typename Functor>
777EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
778void call_triangular_assignment_loop(DstXprType& dst,
const SrcXprType& src,
const Functor &func)
780 typedef evaluator<DstXprType> DstEvaluatorType;
781 typedef evaluator<SrcXprType> SrcEvaluatorType;
783 SrcEvaluatorType srcEvaluator(src);
785 Index dstRows = src.rows();
786 Index dstCols = src.cols();
787 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
788 dst.resize(dstRows, dstCols);
789 DstEvaluatorType dstEvaluator(dst);
792 DstEvaluatorType,SrcEvaluatorType,Functor> Kernel;
793 Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived());
796 unroll = DstXprType::SizeAtCompileTime !=
Dynamic
797 && SrcEvaluatorType::CoeffReadCost <
HugeCost
798 && DstXprType::SizeAtCompileTime * (DstEvaluatorType::CoeffReadCost+SrcEvaluatorType::CoeffReadCost) / 2 <= EIGEN_UNROLLING_LIMIT
801 triangular_assignment_loop<Kernel, Mode, unroll ? int(DstXprType::SizeAtCompileTime) :
Dynamic, SetOpposite>::run(kernel);
804template<
int Mode,
bool SetOpposite,
typename DstXprType,
typename SrcXprType>
805EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
806void call_triangular_assignment_loop(DstXprType& dst,
const SrcXprType& src)
808 call_triangular_assignment_loop<Mode,SetOpposite>(dst, src, internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar>());
811template<>
struct AssignmentKind<TriangularShape,TriangularShape> {
typedef Triangular2Triangular Kind; };
812template<>
struct AssignmentKind<DenseShape,TriangularShape> {
typedef Triangular2Dense Kind; };
813template<>
struct AssignmentKind<TriangularShape,DenseShape> {
typedef Dense2Triangular Kind; };
816template<
typename DstXprType,
typename SrcXprType,
typename Functor>
817struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Triangular>
819 EIGEN_DEVICE_FUNC
static void run(DstXprType &dst,
const SrcXprType &src,
const Functor &func)
821 eigen_assert(
int(DstXprType::Mode) ==
int(SrcXprType::Mode));
823 call_triangular_assignment_loop<DstXprType::Mode, false>(dst, src, func);
827template<
typename DstXprType,
typename SrcXprType,
typename Functor>
828struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Dense>
830 EIGEN_DEVICE_FUNC
static void run(DstXprType &dst,
const SrcXprType &src,
const Functor &func)
832 call_triangular_assignment_loop<SrcXprType::Mode, (SrcXprType::Mode&SelfAdjoint)==0>(dst, src, func);
836template<
typename DstXprType,
typename SrcXprType,
typename Functor>
837struct Assignment<DstXprType, SrcXprType, Functor, Dense2Triangular>
839 EIGEN_DEVICE_FUNC
static void run(DstXprType &dst,
const SrcXprType &src,
const Functor &func)
841 call_triangular_assignment_loop<DstXprType::Mode, false>(dst, src, func);
846template<
typename Kernel,
unsigned int Mode,
int UnrollCount,
bool SetOpposite>
847struct triangular_assignment_loop
850 typedef typename Kernel::DstEvaluatorType DstEvaluatorType;
851 typedef typename DstEvaluatorType::XprType DstXprType;
854 col = (UnrollCount-1) / DstXprType::RowsAtCompileTime,
855 row = (UnrollCount-1) % DstXprType::RowsAtCompileTime
858 typedef typename Kernel::Scalar Scalar;
861 static inline void run(Kernel &kernel)
863 triangular_assignment_loop<Kernel, Mode, UnrollCount-1, SetOpposite>::run(kernel);
866 kernel.assignDiagonalCoeff(row);
867 else if( ((Mode&
Lower) && row>col) || ((Mode&
Upper) && row<col) )
868 kernel.assignCoeff(row,col);
870 kernel.assignOppositeCoeff(row,col);
875template<
typename Kernel,
unsigned int Mode,
bool SetOpposite>
876struct triangular_assignment_loop<Kernel, Mode, 0, SetOpposite>
879 static inline void run(Kernel &) {}
888template<
typename Kernel,
unsigned int Mode,
bool SetOpposite>
889struct triangular_assignment_loop<Kernel, Mode,
Dynamic, SetOpposite>
891 typedef typename Kernel::Scalar Scalar;
893 static inline void run(Kernel &kernel)
895 for(
Index j = 0; j < kernel.cols(); ++j)
897 Index maxi = numext::mini(j, kernel.rows());
899 if (((Mode&
Lower) && SetOpposite) || (Mode&
Upper))
902 if(Mode&
Upper) kernel.assignCoeff(i, j);
903 else kernel.assignOppositeCoeff(i, j);
909 kernel.assignDiagonalCoeff(i++);
911 if (((Mode&
Upper) && SetOpposite) || (Mode&
Lower))
913 for(; i < kernel.rows(); ++i)
914 if(Mode&
Lower) kernel.assignCoeff(i, j);
915 else kernel.assignOppositeCoeff(i, j);
925template<
typename Derived>
926template<
typename DenseDerived>
929 other.
derived().resize(this->rows(), this->cols());
930 internal::call_triangular_assignment_loop<Derived::Mode,(Derived::Mode&
SelfAdjoint)==0 >(other.
derived(), derived().nestedExpression());
936template<
typename DstXprType,
typename Lhs,
typename Rhs,
typename Scalar>
937struct Assignment<DstXprType,
Product<Lhs,Rhs,DefaultProduct>, internal::assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
940 static void run(DstXprType &dst,
const SrcXprType &src,
const internal::assign_op<Scalar,typename SrcXprType::Scalar> &)
942 Index dstRows = src.rows();
943 Index dstCols = src.cols();
944 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
945 dst.resize(dstRows, dstCols);
948 dst._assignProduct(src, 1);
953template<
typename DstXprType,
typename Lhs,
typename Rhs,
typename Scalar>
954struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::add_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
956 typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
957 static void run(DstXprType &dst,
const SrcXprType &src,
const internal::add_assign_op<Scalar,typename SrcXprType::Scalar> &)
959 dst._assignProduct(src, 1);
964template<
typename DstXprType,
typename Lhs,
typename Rhs,
typename Scalar>
965struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
967 typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
968 static void run(DstXprType &dst,
const SrcXprType &src,
const internal::sub_assign_op<Scalar,typename SrcXprType::Scalar> &)
970 dst._assignProduct(src, -1);