276 return ConstTransposeReturnType(m_matrix.transpose());
279 template<
typename Other>
287 template<
int S
ide,
typename Other>
289 inline const internal::triangular_solve_retval<Side,TriangularView, Other>
290 solve(
const MatrixBase<Other>& other)
const
291 {
return Base::template solve<Side>(other); }
326 return m_matrix.diagonal().prod();
331 MatrixTypeNested m_matrix;
343template<
typename _MatrixType,
unsigned int _Mode>
class TriangularViewImpl<_MatrixType,_Mode,
Dense>
344 :
public TriangularBase<TriangularView<_MatrixType, _Mode> >
349 typedef TriangularBase<TriangularViewType> Base;
350 typedef typename internal::traits<TriangularViewType>::Scalar Scalar;
352 typedef _MatrixType MatrixType;
353 typedef typename MatrixType::PlainObject DenseMatrixType;
354 typedef DenseMatrixType PlainObject;
360 typedef typename internal::traits<TriangularViewType>::StorageKind StorageKind;
364 Flags = internal::traits<TriangularViewType>::Flags
377 template<
typename Other>
380 internal::call_assignment_no_alias(derived(), other.derived(), internal::add_assign_op<Scalar,typename Other::Scalar>());
384 template<
typename Other>
387 internal::call_assignment_no_alias(derived(), other.derived(), internal::sub_assign_op<Scalar,typename Other::Scalar>());
393 TriangularViewType&
operator*=(
const typename internal::traits<MatrixType>::Scalar& other) {
return *
this = derived().
nestedExpression() * other; }
396 TriangularViewType&
operator/=(
const typename internal::traits<MatrixType>::Scalar& other) {
return *
this = derived().
nestedExpression() / other; }
404 {
return *
this = MatrixType::Constant(derived().rows(), derived().cols(), value); }
418 Base::check_coordinates_internal(row, col);
419 return derived().nestedExpression().coeff(row, col);
428 EIGEN_STATIC_ASSERT_LVALUE(TriangularViewType);
429 Base::check_coordinates_internal(row, col);
430 return derived().nestedExpression().coeffRef(row, col);
434 template<
typename OtherDerived>
436 TriangularViewType&
operator=(
const TriangularBase<OtherDerived>& other);
439 template<
typename OtherDerived>
444 TriangularViewType&
operator=(
const TriangularViewImpl& other)
445 {
return *
this = other.derived().nestedExpression(); }
447 template<
typename OtherDerived>
449 EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
452 template<
typename OtherDerived>
454 EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
458 template<
typename OtherDerived>
467 template<
typename OtherDerived>
friend
498 template<
int S
ide,
typename Other>
499 inline const internal::triangular_solve_retval<Side,TriangularViewType, Other>
511 template<
int S
ide,
typename OtherDerived>
515 template<
typename OtherDerived>
521 template<
typename OtherDerived>
523 void swap(TriangularBase<OtherDerived>
const & other)
525 EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
526 call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
530 template<
typename OtherDerived>
532 EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
535 EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
536 call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
539 template<
typename RhsType,
typename DstType>
541 EIGEN_STRONG_INLINE
void _solve_impl(
const RhsType &rhs, DstType &dst)
const {
542 if(!internal::is_same_dense(dst,rhs))
544 this->solveInPlace(dst);
547 template <
typename ProductType>
548 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(
const ProductType& prod,
const Scalar& alpha,
552 EIGEN_DEFAULT_COPY_CONSTRUCTOR(TriangularViewImpl)
553 EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(TriangularViewImpl)
561#ifndef EIGEN_PARSED_BY_DOXYGEN
563template<
typename MatrixType,
unsigned int Mode>
564template<
typename OtherDerived>
568 internal::call_assignment_no_alias(derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
573template<
typename MatrixType,
unsigned int Mode>
574template<
typename OtherDerived>
575EIGEN_DEVICE_FUNC
void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(
const MatrixBase<OtherDerived>& other)
577 internal::call_assignment_no_alias(derived(), other.template triangularView<Mode>());
582template<
typename MatrixType,
unsigned int Mode>
583template<
typename OtherDerived>
587 eigen_assert(Mode ==
int(OtherDerived::Mode));
588 internal::call_assignment(derived(), other.derived());
592template<
typename MatrixType,
unsigned int Mode>
593template<
typename OtherDerived>
596 eigen_assert(Mode ==
int(OtherDerived::Mode));
597 internal::call_assignment_no_alias(derived(), other.derived());
607template<
typename Derived>
608template<
typename DenseDerived>
633template<
typename Derived>
634template<
unsigned int Mode>
637MatrixBase<Derived>::triangularView()
639 return typename TriangularViewReturnType<Mode>::Type(derived());
643template<
typename Derived>
644template<
unsigned int Mode>
647MatrixBase<Derived>::triangularView()
const
649 return typename ConstTriangularViewReturnType<Mode>::Type(derived());
657template<
typename Derived>
660 RealScalar maxAbsOnUpperPart =
static_cast<RealScalar
>(-1);
661 for(
Index j = 0; j < cols(); ++j)
663 Index maxi = numext::mini(j, rows()-1);
664 for(
Index i = 0; i <= maxi; ++i)
666 RealScalar absValue = numext::abs(coeff(i,j));
667 if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
670 RealScalar threshold = maxAbsOnUpperPart * prec;
671 for(
Index j = 0; j < cols(); ++j)
672 for(
Index i = j+1; i < rows(); ++i)
673 if(numext::abs(coeff(i, j)) > threshold)
return false;
682template<
typename Derived>
685 RealScalar maxAbsOnLowerPart =
static_cast<RealScalar
>(-1);
686 for(
Index j = 0; j < cols(); ++j)
687 for(
Index i = j; i < rows(); ++i)
689 RealScalar absValue = numext::abs(coeff(i,j));
690 if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
692 RealScalar threshold = maxAbsOnLowerPart * prec;
693 for(
Index j = 1; j < cols(); ++j)
695 Index maxi = numext::mini(j, rows()-1);
696 for(
Index i = 0; i < maxi; ++i)
697 if(numext::abs(coeff(i, j)) > threshold)
return false;
715template<
typename MatrixType,
unsigned int Mode>
718 typedef typename storage_kind_to_evaluator_kind<typename MatrixType::StorageKind>::Kind Kind;
719 typedef typename glue_shapes<typename evaluator_traits<MatrixType>::Shape, TriangularShape>::type Shape;
722template<
typename MatrixType,
unsigned int Mode>
723struct unary_evaluator<TriangularView<MatrixType,Mode>, IndexBased>
724 : evaluator<typename internal::remove_all<MatrixType>::type>
726 typedef TriangularView<MatrixType,Mode> XprType;
727 typedef evaluator<typename internal::remove_all<MatrixType>::type> Base;
729 unary_evaluator(
const XprType &xpr) : Base(xpr.nestedExpression()) {}
733struct Triangular2Triangular {};
734struct Triangular2Dense {};
735struct Dense2Triangular {};
738template<
typename Kernel,
unsigned int Mode,
int UnrollCount,
bool ClearOpposite>
struct triangular_assignment_loop;
746template<
int UpLo,
int Mode,
int SetOpposite,
typename DstEvaluatorTypeT,
typename SrcEvaluatorTypeT,
typename Functor,
int Version = Specialized>
747class triangular_dense_assignment_kernel :
public generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version>
750 typedef generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version> Base;
751 typedef typename Base::DstXprType DstXprType;
752 typedef typename Base::SrcXprType SrcXprType;
755 using Base::m_functor;
758 typedef typename Base::DstEvaluatorType DstEvaluatorType;
759 typedef typename Base::SrcEvaluatorType SrcEvaluatorType;
760 typedef typename Base::Scalar Scalar;
761 typedef typename Base::AssignmentTraits AssignmentTraits;
764 EIGEN_DEVICE_FUNC triangular_dense_assignment_kernel(DstEvaluatorType &dst,
const SrcEvaluatorType &src,
const Functor &func, DstXprType& dstExpr)
765 : Base(dst, src, func, dstExpr)
768#ifdef EIGEN_INTERNAL_DEBUGGING
769 EIGEN_DEVICE_FUNC
void assignCoeff(
Index row,
Index col)
771 eigen_internal_assert(row!=col);
772 Base::assignCoeff(row,col);
775 using Base::assignCoeff;
778 EIGEN_DEVICE_FUNC
void assignDiagonalCoeff(
Index id)
780 if(Mode==
UnitDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(
id,
id), Scalar(1));
781 else if(Mode==
ZeroDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(
id,
id), Scalar(0));
782 else if(Mode==0) Base::assignCoeff(
id,
id);
785 EIGEN_DEVICE_FUNC
void assignOppositeCoeff(
Index row,
Index col)
787 eigen_internal_assert(row!=col);
789 m_functor.assignCoeff(m_dst.coeffRef(row,col), Scalar(0));
793template<
int Mode,
bool SetOpposite,
typename DstXprType,
typename SrcXprType,
typename Functor>
794EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
795void call_triangular_assignment_loop(DstXprType& dst,
const SrcXprType& src,
const Functor &func)
797 typedef evaluator<DstXprType> DstEvaluatorType;
798 typedef evaluator<SrcXprType> SrcEvaluatorType;
800 SrcEvaluatorType srcEvaluator(src);
802 Index dstRows = src.rows();
803 Index dstCols = src.cols();
804 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
805 dst.resize(dstRows, dstCols);
806 DstEvaluatorType dstEvaluator(dst);
809 DstEvaluatorType,SrcEvaluatorType,Functor> Kernel;
810 Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived());
813 unroll = DstXprType::SizeAtCompileTime !=
Dynamic
814 && SrcEvaluatorType::CoeffReadCost <
HugeCost
815 && DstXprType::SizeAtCompileTime * (int(DstEvaluatorType::CoeffReadCost) + int(SrcEvaluatorType::CoeffReadCost)) / 2 <= EIGEN_UNROLLING_LIMIT
818 triangular_assignment_loop<Kernel, Mode, unroll ? int(DstXprType::SizeAtCompileTime) :
Dynamic, SetOpposite>::run(kernel);
821template<
int Mode,
bool SetOpposite,
typename DstXprType,
typename SrcXprType>
822EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
823void call_triangular_assignment_loop(DstXprType& dst,
const SrcXprType& src)
825 call_triangular_assignment_loop<Mode,SetOpposite>(dst, src, internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar>());
828template<>
struct AssignmentKind<TriangularShape,TriangularShape> {
typedef Triangular2Triangular Kind; };
829template<>
struct AssignmentKind<DenseShape,TriangularShape> {
typedef Triangular2Dense Kind; };
830template<>
struct AssignmentKind<TriangularShape,DenseShape> {
typedef Dense2Triangular Kind; };
833template<
typename DstXprType,
typename SrcXprType,
typename Functor>
834struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Triangular>
836 EIGEN_DEVICE_FUNC
static void run(DstXprType &dst,
const SrcXprType &src,
const Functor &func)
838 eigen_assert(
int(DstXprType::Mode) ==
int(SrcXprType::Mode));
840 call_triangular_assignment_loop<DstXprType::Mode, false>(dst, src, func);
844template<
typename DstXprType,
typename SrcXprType,
typename Functor>
845struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Dense>
847 EIGEN_DEVICE_FUNC
static void run(DstXprType &dst,
const SrcXprType &src,
const Functor &func)
849 call_triangular_assignment_loop<SrcXprType::Mode, (int(SrcXprType::Mode) & int(SelfAdjoint)) == 0>(dst, src, func);
853template<
typename DstXprType,
typename SrcXprType,
typename Functor>
854struct Assignment<DstXprType, SrcXprType, Functor, Dense2Triangular>
856 EIGEN_DEVICE_FUNC
static void run(DstXprType &dst,
const SrcXprType &src,
const Functor &func)
858 call_triangular_assignment_loop<DstXprType::Mode, false>(dst, src, func);
863template<
typename Kernel,
unsigned int Mode,
int UnrollCount,
bool SetOpposite>
864struct triangular_assignment_loop
867 typedef typename Kernel::DstEvaluatorType DstEvaluatorType;
868 typedef typename DstEvaluatorType::XprType DstXprType;
871 col = (UnrollCount-1) / DstXprType::RowsAtCompileTime,
872 row = (UnrollCount-1) % DstXprType::RowsAtCompileTime
875 typedef typename Kernel::Scalar Scalar;
878 static inline void run(Kernel &kernel)
880 triangular_assignment_loop<Kernel, Mode, UnrollCount-1, SetOpposite>::run(kernel);
883 kernel.assignDiagonalCoeff(row);
884 else if( ((Mode&
Lower) && row>col) || ((Mode&
Upper) && row<col) )
885 kernel.assignCoeff(row,col);
887 kernel.assignOppositeCoeff(row,col);
892template<
typename Kernel,
unsigned int Mode,
bool SetOpposite>
893struct triangular_assignment_loop<Kernel, Mode, 0, SetOpposite>
896 static inline void run(Kernel &) {}
905template<
typename Kernel,
unsigned int Mode,
bool SetOpposite>
906struct triangular_assignment_loop<Kernel, Mode,
Dynamic, SetOpposite>
908 typedef typename Kernel::Scalar Scalar;
910 static inline void run(Kernel &kernel)
912 for(
Index j = 0; j < kernel.cols(); ++j)
914 Index maxi = numext::mini(j, kernel.rows());
916 if (((Mode&
Lower) && SetOpposite) || (Mode&
Upper))
919 if(Mode&
Upper) kernel.assignCoeff(i, j);
920 else kernel.assignOppositeCoeff(i, j);
926 kernel.assignDiagonalCoeff(i++);
928 if (((Mode&
Upper) && SetOpposite) || (Mode&
Lower))
930 for(; i < kernel.rows(); ++i)
931 if(Mode&
Lower) kernel.assignCoeff(i, j);
932 else kernel.assignOppositeCoeff(i, j);
942template<
typename Derived>
943template<
typename DenseDerived>
946 other.derived().
resize(this->rows(), this->cols());
947 internal::call_triangular_assignment_loop<Derived::Mode, (int(Derived::Mode) & int(
SelfAdjoint)) == 0 >(other.derived(), derived().nestedExpression());
953template<
typename DstXprType,
typename Lhs,
typename Rhs,
typename Scalar>
954struct Assignment<DstXprType,
Product<Lhs,Rhs,DefaultProduct>, internal::assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
957 static void run(DstXprType &dst,
const SrcXprType &src,
const internal::assign_op<Scalar,typename SrcXprType::Scalar> &)
959 Index dstRows = src.rows();
960 Index dstCols = src.cols();
961 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
962 dst.resize(dstRows, dstCols);
964 dst._assignProduct(src,
Scalar(1),
false);
969template<
typename DstXprType,
typename Lhs,
typename Rhs,
typename Scalar>
970struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::add_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
972 typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
973 static void run(DstXprType &dst,
const SrcXprType &src,
const internal::add_assign_op<Scalar,typename SrcXprType::Scalar> &)
975 dst._assignProduct(src, Scalar(1),
true);
980template<
typename DstXprType,
typename Lhs,
typename Rhs,
typename Scalar>
981struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
983 typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
984 static void run(DstXprType &dst,
const SrcXprType &src,
const internal::sub_assign_op<Scalar,typename SrcXprType::Scalar> &)
986 dst._assignProduct(src, Scalar(-1),
true);