275 template<
int S
ide,
typename Other>
277 inline const internal::triangular_solve_retval<Side,TriangularView, Other>
278 solve(
const MatrixBase<Other>& other)
const
279 {
return Base::template solve<Side>(other); }
314 return m_matrix.diagonal().prod();
319 MatrixTypeNested m_matrix;
331template<
typename _MatrixType,
unsigned int _Mode>
class TriangularViewImpl<_MatrixType,_Mode,
Dense>
332 :
public TriangularBase<TriangularView<_MatrixType, _Mode> >
337 typedef TriangularBase<TriangularViewType> Base;
338 typedef typename internal::traits<TriangularViewType>::Scalar Scalar;
340 typedef _MatrixType MatrixType;
341 typedef typename MatrixType::PlainObject DenseMatrixType;
342 typedef DenseMatrixType PlainObject;
348 typedef typename internal::traits<TriangularViewType>::StorageKind StorageKind;
352 Flags = internal::traits<TriangularViewType>::Flags
365 template<
typename Other>
368 internal::call_assignment_no_alias(
derived(), other.derived(), internal::add_assign_op<Scalar,typename Other::Scalar>());
372 template<
typename Other>
375 internal::call_assignment_no_alias(
derived(), other.derived(), internal::sub_assign_op<Scalar,typename Other::Scalar>());
381 TriangularViewType&
operator*=(
const typename internal::traits<MatrixType>::Scalar& other) {
return *
this =
derived().nestedExpression() * other; }
384 TriangularViewType&
operator/=(
const typename internal::traits<MatrixType>::Scalar& other) {
return *
this =
derived().nestedExpression() / other; }
392 {
return *
this = MatrixType::Constant(
derived().rows(),
derived().cols(), value); }
406 Base::check_coordinates_internal(row, col);
407 return derived().nestedExpression().coeff(row, col);
416 EIGEN_STATIC_ASSERT_LVALUE(TriangularViewType);
417 Base::check_coordinates_internal(row, col);
418 return derived().nestedExpression().coeffRef(row, col);
422 template<
typename OtherDerived>
424 TriangularViewType&
operator=(
const TriangularBase<OtherDerived>& other);
427 template<
typename OtherDerived>
431#ifndef EIGEN_PARSED_BY_DOXYGEN
433 TriangularViewType&
operator=(
const TriangularViewImpl& other)
434 {
return *
this = other.derived().nestedExpression(); }
437 template<
typename OtherDerived>
442 template<
typename OtherDerived>
448 template<
typename OtherDerived>
457 template<
typename OtherDerived>
friend
488 template<
int S
ide,
typename Other>
490 inline const internal::triangular_solve_retval<Side,TriangularViewType, Other>
502 template<
int S
ide,
typename OtherDerived>
506 template<
typename OtherDerived>
512 template<
typename OtherDerived>
514#ifdef EIGEN_PARSED_BY_DOXYGEN
515 void swap(TriangularBase<OtherDerived> &other)
517 void swap(TriangularBase<OtherDerived>
const & other)
520 EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
521 call_assignment(
derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
526 template<
typename OtherDerived>
530 EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
531 call_assignment(
derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
534 template<
typename RhsType,
typename DstType>
536 EIGEN_STRONG_INLINE
void _solve_impl(
const RhsType &rhs, DstType &dst)
const {
537 if(!internal::is_same_dense(dst,rhs))
539 this->solveInPlace(dst);
542 template<
typename ProductType>
544 EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(
const ProductType& prod,
const Scalar& alpha,
bool beta);
546 EIGEN_DEFAULT_COPY_CONSTRUCTOR(TriangularViewImpl)
547 EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(TriangularViewImpl)
555#ifndef EIGEN_PARSED_BY_DOXYGEN
557template<
typename MatrixType,
unsigned int Mode>
558template<
typename OtherDerived>
562 internal::call_assignment_no_alias(derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
567template<
typename MatrixType,
unsigned int Mode>
568template<
typename OtherDerived>
569EIGEN_DEVICE_FUNC
void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(
const MatrixBase<OtherDerived>& other)
571 internal::call_assignment_no_alias(derived(), other.template triangularView<Mode>());
576template<
typename MatrixType,
unsigned int Mode>
577template<
typename OtherDerived>
581 eigen_assert(Mode ==
int(OtherDerived::Mode));
582 internal::call_assignment(derived(), other.derived());
586template<
typename MatrixType,
unsigned int Mode>
587template<
typename OtherDerived>
590 eigen_assert(Mode ==
int(OtherDerived::Mode));
591 internal::call_assignment_no_alias(derived(), other.derived());
601template<
typename Derived>
602template<
typename DenseDerived>
627template<
typename Derived>
628template<
unsigned int Mode>
630MatrixBase<Derived>::triangularView()
632 return typename TriangularViewReturnType<Mode>::Type(derived());
636template<
typename Derived>
637template<
unsigned int Mode>
639MatrixBase<Derived>::triangularView()
const
641 return typename ConstTriangularViewReturnType<Mode>::Type(derived());
649template<
typename Derived>
652 RealScalar maxAbsOnUpperPart =
static_cast<RealScalar
>(-1);
653 for(
Index j = 0; j < cols(); ++j)
655 Index maxi = numext::mini(j, rows()-1);
656 for(
Index i = 0; i <= maxi; ++i)
658 RealScalar absValue = numext::abs(coeff(i,j));
659 if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
662 RealScalar threshold = maxAbsOnUpperPart * prec;
663 for(
Index j = 0; j < cols(); ++j)
664 for(
Index i = j+1; i < rows(); ++i)
665 if(numext::abs(coeff(i, j)) > threshold)
return false;
674template<
typename Derived>
677 RealScalar maxAbsOnLowerPart =
static_cast<RealScalar
>(-1);
678 for(
Index j = 0; j < cols(); ++j)
679 for(
Index i = j; i < rows(); ++i)
681 RealScalar absValue = numext::abs(coeff(i,j));
682 if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
684 RealScalar threshold = maxAbsOnLowerPart * prec;
685 for(
Index j = 1; j < cols(); ++j)
687 Index maxi = numext::mini(j, rows()-1);
688 for(
Index i = 0; i < maxi; ++i)
689 if(numext::abs(coeff(i, j)) > threshold)
return false;
707template<
typename MatrixType,
unsigned int Mode>
710 typedef typename storage_kind_to_evaluator_kind<typename MatrixType::StorageKind>::Kind Kind;
711 typedef typename glue_shapes<typename evaluator_traits<MatrixType>::Shape, TriangularShape>::type Shape;
714template<
typename MatrixType,
unsigned int Mode>
715struct unary_evaluator<TriangularView<MatrixType,Mode>, IndexBased>
716 : evaluator<typename internal::remove_all<MatrixType>::type>
718 typedef TriangularView<MatrixType,Mode> XprType;
719 typedef evaluator<typename internal::remove_all<MatrixType>::type> Base;
720 unary_evaluator(
const XprType &xpr) : Base(xpr.nestedExpression()) {}
724struct Triangular2Triangular {};
725struct Triangular2Dense {};
726struct Dense2Triangular {};
729template<
typename Kernel,
unsigned int Mode,
int UnrollCount,
bool ClearOpposite>
struct triangular_assignment_loop;
737template<
int UpLo,
int Mode,
int SetOpposite,
typename DstEvaluatorTypeT,
typename SrcEvaluatorTypeT,
typename Functor,
int Version = Specialized>
738class triangular_dense_assignment_kernel :
public generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version>
741 typedef generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version> Base;
742 typedef typename Base::DstXprType DstXprType;
743 typedef typename Base::SrcXprType SrcXprType;
746 using Base::m_functor;
749 typedef typename Base::DstEvaluatorType DstEvaluatorType;
750 typedef typename Base::SrcEvaluatorType SrcEvaluatorType;
751 typedef typename Base::Scalar Scalar;
752 typedef typename Base::AssignmentTraits AssignmentTraits;
755 EIGEN_DEVICE_FUNC triangular_dense_assignment_kernel(DstEvaluatorType &dst,
const SrcEvaluatorType &src,
const Functor &func, DstXprType& dstExpr)
756 : Base(dst, src, func, dstExpr)
759#ifdef EIGEN_INTERNAL_DEBUGGING
760 EIGEN_DEVICE_FUNC
void assignCoeff(
Index row,
Index col)
762 eigen_internal_assert(row!=col);
763 Base::assignCoeff(row,col);
766 using Base::assignCoeff;
769 EIGEN_DEVICE_FUNC
void assignDiagonalCoeff(
Index id)
771 if(Mode==
UnitDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(
id,
id), Scalar(1));
772 else if(Mode==
ZeroDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(
id,
id), Scalar(0));
773 else if(Mode==0) Base::assignCoeff(
id,
id);
776 EIGEN_DEVICE_FUNC
void assignOppositeCoeff(
Index row,
Index col)
778 eigen_internal_assert(row!=col);
780 m_functor.assignCoeff(m_dst.coeffRef(row,col), Scalar(0));
784template<
int Mode,
bool SetOpposite,
typename DstXprType,
typename SrcXprType,
typename Functor>
785EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
786void call_triangular_assignment_loop(DstXprType& dst,
const SrcXprType& src,
const Functor &func)
788 typedef evaluator<DstXprType> DstEvaluatorType;
789 typedef evaluator<SrcXprType> SrcEvaluatorType;
791 SrcEvaluatorType srcEvaluator(src);
793 Index dstRows = src.rows();
794 Index dstCols = src.cols();
795 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
796 dst.resize(dstRows, dstCols);
797 DstEvaluatorType dstEvaluator(dst);
800 DstEvaluatorType,SrcEvaluatorType,Functor> Kernel;
801 Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived());
804 unroll = DstXprType::SizeAtCompileTime !=
Dynamic
805 && SrcEvaluatorType::CoeffReadCost <
HugeCost
806 && DstXprType::SizeAtCompileTime * (DstEvaluatorType::CoeffReadCost+SrcEvaluatorType::CoeffReadCost) / 2 <= EIGEN_UNROLLING_LIMIT
809 triangular_assignment_loop<Kernel, Mode, unroll ? int(DstXprType::SizeAtCompileTime) :
Dynamic, SetOpposite>::run(kernel);
812template<
int Mode,
bool SetOpposite,
typename DstXprType,
typename SrcXprType>
813EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
814void call_triangular_assignment_loop(DstXprType& dst,
const SrcXprType& src)
816 call_triangular_assignment_loop<Mode,SetOpposite>(dst, src, internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar>());
819template<>
struct AssignmentKind<TriangularShape,TriangularShape> {
typedef Triangular2Triangular Kind; };
820template<>
struct AssignmentKind<DenseShape,TriangularShape> {
typedef Triangular2Dense Kind; };
821template<>
struct AssignmentKind<TriangularShape,DenseShape> {
typedef Dense2Triangular Kind; };
824template<
typename DstXprType,
typename SrcXprType,
typename Functor>
825struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Triangular>
827 EIGEN_DEVICE_FUNC
static void run(DstXprType &dst,
const SrcXprType &src,
const Functor &func)
829 eigen_assert(
int(DstXprType::Mode) ==
int(SrcXprType::Mode));
831 call_triangular_assignment_loop<DstXprType::Mode, false>(dst, src, func);
835template<
typename DstXprType,
typename SrcXprType,
typename Functor>
836struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Dense>
838 EIGEN_DEVICE_FUNC
static void run(DstXprType &dst,
const SrcXprType &src,
const Functor &func)
840 call_triangular_assignment_loop<SrcXprType::Mode, (SrcXprType::Mode&SelfAdjoint)==0>(dst, src, func);
844template<
typename DstXprType,
typename SrcXprType,
typename Functor>
845struct Assignment<DstXprType, SrcXprType, Functor, Dense2Triangular>
847 EIGEN_DEVICE_FUNC
static void run(DstXprType &dst,
const SrcXprType &src,
const Functor &func)
849 call_triangular_assignment_loop<DstXprType::Mode, false>(dst, src, func);
854template<
typename Kernel,
unsigned int Mode,
int UnrollCount,
bool SetOpposite>
855struct triangular_assignment_loop
858 typedef typename Kernel::DstEvaluatorType DstEvaluatorType;
859 typedef typename DstEvaluatorType::XprType DstXprType;
862 col = (UnrollCount-1) / DstXprType::RowsAtCompileTime,
863 row = (UnrollCount-1) % DstXprType::RowsAtCompileTime
866 typedef typename Kernel::Scalar Scalar;
869 static inline void run(Kernel &kernel)
871 triangular_assignment_loop<Kernel, Mode, UnrollCount-1, SetOpposite>::run(kernel);
874 kernel.assignDiagonalCoeff(row);
875 else if( ((Mode&
Lower) && row>col) || ((Mode&
Upper) && row<col) )
876 kernel.assignCoeff(row,col);
878 kernel.assignOppositeCoeff(row,col);
883template<
typename Kernel,
unsigned int Mode,
bool SetOpposite>
884struct triangular_assignment_loop<Kernel, Mode, 0, SetOpposite>
887 static inline void run(Kernel &) {}
896template<
typename Kernel,
unsigned int Mode,
bool SetOpposite>
897struct triangular_assignment_loop<Kernel, Mode,
Dynamic, SetOpposite>
899 typedef typename Kernel::Scalar Scalar;
901 static inline void run(Kernel &kernel)
903 for(
Index j = 0; j < kernel.cols(); ++j)
905 Index maxi = numext::mini(j, kernel.rows());
907 if (((Mode&
Lower) && SetOpposite) || (Mode&
Upper))
910 if(Mode&
Upper) kernel.assignCoeff(i, j);
911 else kernel.assignOppositeCoeff(i, j);
917 kernel.assignDiagonalCoeff(i++);
919 if (((Mode&
Upper) && SetOpposite) || (Mode&
Lower))
921 for(; i < kernel.rows(); ++i)
922 if(Mode&
Lower) kernel.assignCoeff(i, j);
923 else kernel.assignOppositeCoeff(i, j);
933template<
typename Derived>
934template<
typename DenseDerived>
937 other.derived().
resize(this->rows(), this->cols());
938 internal::call_triangular_assignment_loop<Derived::Mode,(Derived::Mode&
SelfAdjoint)==0 >(other.derived(),
derived().nestedExpression());
944template<
typename DstXprType,
typename Lhs,
typename Rhs,
typename Scalar>
945struct Assignment<DstXprType,
Product<Lhs,Rhs,DefaultProduct>, internal::assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
948 static EIGEN_DEVICE_FUNC
void run(DstXprType &dst,
const SrcXprType &src,
const internal::assign_op<Scalar,typename SrcXprType::Scalar> &)
950 Index dstRows = src.rows();
951 Index dstCols = src.cols();
952 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
953 dst.resize(dstRows, dstCols);
955 dst._assignProduct(src, 1, 0);
960template<
typename DstXprType,
typename Lhs,
typename Rhs,
typename Scalar>
961struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::add_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
963 typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
964 static EIGEN_DEVICE_FUNC
void run(DstXprType &dst,
const SrcXprType &src,
const internal::add_assign_op<Scalar,typename SrcXprType::Scalar> &)
966 dst._assignProduct(src, 1, 1);
971template<
typename DstXprType,
typename Lhs,
typename Rhs,
typename Scalar>
972struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
974 typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
975 static EIGEN_DEVICE_FUNC
void run(DstXprType &dst,
const SrcXprType &src,
const internal::sub_assign_op<Scalar,typename SrcXprType::Scalar> &)
977 dst._assignProduct(src, -1, 1);