File indexing completed on 2025-01-18 09:56:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef EIGEN_TRIANGULARMATRIX_H
0012 #define EIGEN_TRIANGULARMATRIX_H
0013
0014 namespace Eigen {
0015
0016 namespace internal {
0017
0018 template<int Side, typename TriangularType, typename Rhs> struct triangular_solve_retval;
0019
0020 }
0021
0022
0023
0024
0025
0026
0027 template<typename Derived> class TriangularBase : public EigenBase<Derived>
0028 {
0029 public:
0030
0031 enum {
0032 Mode = internal::traits<Derived>::Mode,
0033 RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
0034 ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
0035 MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
0036 MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime,
0037
0038 SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
0039 internal::traits<Derived>::ColsAtCompileTime>::ret),
0040
0041
0042
0043
0044 MaxSizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::MaxRowsAtCompileTime,
0045 internal::traits<Derived>::MaxColsAtCompileTime>::ret)
0046
0047 };
0048 typedef typename internal::traits<Derived>::Scalar Scalar;
0049 typedef typename internal::traits<Derived>::StorageKind StorageKind;
0050 typedef typename internal::traits<Derived>::StorageIndex StorageIndex;
0051 typedef typename internal::traits<Derived>::FullMatrixType DenseMatrixType;
0052 typedef DenseMatrixType DenseType;
0053 typedef Derived const& Nested;
0054
0055 EIGEN_DEVICE_FUNC
0056 inline TriangularBase() { eigen_assert(!((int(Mode) & int(UnitDiag)) && (int(Mode) & int(ZeroDiag)))); }
0057
0058 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0059 inline Index rows() const EIGEN_NOEXCEPT { return derived().rows(); }
0060 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0061 inline Index cols() const EIGEN_NOEXCEPT { return derived().cols(); }
0062 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0063 inline Index outerStride() const EIGEN_NOEXCEPT { return derived().outerStride(); }
0064 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0065 inline Index innerStride() const EIGEN_NOEXCEPT { return derived().innerStride(); }
0066
0067
0068 EIGEN_DEVICE_FUNC
0069 void resize(Index rows, Index cols)
0070 {
0071 EIGEN_UNUSED_VARIABLE(rows);
0072 EIGEN_UNUSED_VARIABLE(cols);
0073 eigen_assert(rows==this->rows() && cols==this->cols());
0074 }
0075
0076 EIGEN_DEVICE_FUNC
0077 inline Scalar coeff(Index row, Index col) const { return derived().coeff(row,col); }
0078 EIGEN_DEVICE_FUNC
0079 inline Scalar& coeffRef(Index row, Index col) { return derived().coeffRef(row,col); }
0080
0081
0082
0083 template<typename Other>
0084 EIGEN_DEVICE_FUNC
0085 EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, Other& other)
0086 {
0087 derived().coeffRef(row, col) = other.coeff(row, col);
0088 }
0089
0090 EIGEN_DEVICE_FUNC
0091 inline Scalar operator()(Index row, Index col) const
0092 {
0093 check_coordinates(row, col);
0094 return coeff(row,col);
0095 }
0096 EIGEN_DEVICE_FUNC
0097 inline Scalar& operator()(Index row, Index col)
0098 {
0099 check_coordinates(row, col);
0100 return coeffRef(row,col);
0101 }
0102
0103 #ifndef EIGEN_PARSED_BY_DOXYGEN
0104 EIGEN_DEVICE_FUNC
0105 inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
0106 EIGEN_DEVICE_FUNC
0107 inline Derived& derived() { return *static_cast<Derived*>(this); }
0108 #endif
0109
0110 template<typename DenseDerived>
0111 EIGEN_DEVICE_FUNC
0112 void evalTo(MatrixBase<DenseDerived> &other) const;
0113 template<typename DenseDerived>
0114 EIGEN_DEVICE_FUNC
0115 void evalToLazy(MatrixBase<DenseDerived> &other) const;
0116
0117 EIGEN_DEVICE_FUNC
0118 DenseMatrixType toDenseMatrix() const
0119 {
0120 DenseMatrixType res(rows(), cols());
0121 evalToLazy(res);
0122 return res;
0123 }
0124
0125 protected:
0126
0127 void check_coordinates(Index row, Index col) const
0128 {
0129 EIGEN_ONLY_USED_FOR_DEBUG(row);
0130 EIGEN_ONLY_USED_FOR_DEBUG(col);
0131 eigen_assert(col>=0 && col<cols() && row>=0 && row<rows());
0132 const int mode = int(Mode) & ~SelfAdjoint;
0133 EIGEN_ONLY_USED_FOR_DEBUG(mode);
0134 eigen_assert((mode==Upper && col>=row)
0135 || (mode==Lower && col<=row)
0136 || ((mode==StrictlyUpper || mode==UnitUpper) && col>row)
0137 || ((mode==StrictlyLower || mode==UnitLower) && col<row));
0138 }
0139
0140 #ifdef EIGEN_INTERNAL_DEBUGGING
0141 void check_coordinates_internal(Index row, Index col) const
0142 {
0143 check_coordinates(row, col);
0144 }
0145 #else
0146 void check_coordinates_internal(Index , Index ) const {}
0147 #endif
0148
0149 };
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 namespace internal {
0169 template<typename MatrixType, unsigned int _Mode>
0170 struct traits<TriangularView<MatrixType, _Mode> > : traits<MatrixType>
0171 {
0172 typedef typename ref_selector<MatrixType>::non_const_type MatrixTypeNested;
0173 typedef typename remove_reference<MatrixTypeNested>::type MatrixTypeNestedNonRef;
0174 typedef typename remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned;
0175 typedef typename MatrixType::PlainObject FullMatrixType;
0176 typedef MatrixType ExpressionType;
0177 enum {
0178 Mode = _Mode,
0179 FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
0180 Flags = (MatrixTypeNestedCleaned::Flags & (HereditaryBits | FlagsLvalueBit) & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)))
0181 };
0182 };
0183 }
0184
0185 template<typename _MatrixType, unsigned int _Mode, typename StorageKind> class TriangularViewImpl;
0186
0187 template<typename _MatrixType, unsigned int _Mode> class TriangularView
0188 : public TriangularViewImpl<_MatrixType, _Mode, typename internal::traits<_MatrixType>::StorageKind >
0189 {
0190 public:
0191
0192 typedef TriangularViewImpl<_MatrixType, _Mode, typename internal::traits<_MatrixType>::StorageKind > Base;
0193 typedef typename internal::traits<TriangularView>::Scalar Scalar;
0194 typedef _MatrixType MatrixType;
0195
0196 protected:
0197 typedef typename internal::traits<TriangularView>::MatrixTypeNested MatrixTypeNested;
0198 typedef typename internal::traits<TriangularView>::MatrixTypeNestedNonRef MatrixTypeNestedNonRef;
0199
0200 typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
0201 typedef TriangularView<typename internal::add_const<MatrixType>::type, _Mode> ConstTriangularView;
0202
0203 public:
0204
0205 typedef typename internal::traits<TriangularView>::StorageKind StorageKind;
0206 typedef typename internal::traits<TriangularView>::MatrixTypeNestedCleaned NestedExpression;
0207
0208 enum {
0209 Mode = _Mode,
0210 Flags = internal::traits<TriangularView>::Flags,
0211 TransposeMode = (Mode & Upper ? Lower : 0)
0212 | (Mode & Lower ? Upper : 0)
0213 | (Mode & (UnitDiag))
0214 | (Mode & (ZeroDiag)),
0215 IsVectorAtCompileTime = false
0216 };
0217
0218 EIGEN_DEVICE_FUNC
0219 explicit inline TriangularView(MatrixType& matrix) : m_matrix(matrix)
0220 {}
0221
0222 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TriangularView)
0223
0224
0225 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0226 inline Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
0227
0228 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
0229 inline Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
0230
0231
0232 EIGEN_DEVICE_FUNC
0233 const NestedExpression& nestedExpression() const { return m_matrix; }
0234
0235
0236 EIGEN_DEVICE_FUNC
0237 NestedExpression& nestedExpression() { return m_matrix; }
0238
0239 typedef TriangularView<const MatrixConjugateReturnType,Mode> ConjugateReturnType;
0240
0241 EIGEN_DEVICE_FUNC
0242 inline const ConjugateReturnType conjugate() const
0243 { return ConjugateReturnType(m_matrix.conjugate()); }
0244
0245
0246
0247
0248 template<bool Cond>
0249 EIGEN_DEVICE_FUNC
0250 inline typename internal::conditional<Cond,ConjugateReturnType,ConstTriangularView>::type
0251 conjugateIf() const
0252 {
0253 typedef typename internal::conditional<Cond,ConjugateReturnType,ConstTriangularView>::type ReturnType;
0254 return ReturnType(m_matrix.template conjugateIf<Cond>());
0255 }
0256
0257 typedef TriangularView<const typename MatrixType::AdjointReturnType,TransposeMode> AdjointReturnType;
0258
0259 EIGEN_DEVICE_FUNC
0260 inline const AdjointReturnType adjoint() const
0261 { return AdjointReturnType(m_matrix.adjoint()); }
0262
0263 typedef TriangularView<typename MatrixType::TransposeReturnType,TransposeMode> TransposeReturnType;
0264
0265 EIGEN_DEVICE_FUNC
0266 inline TransposeReturnType transpose()
0267 {
0268 EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
0269 typename MatrixType::TransposeReturnType tmp(m_matrix);
0270 return TransposeReturnType(tmp);
0271 }
0272
0273 typedef TriangularView<const typename MatrixType::ConstTransposeReturnType,TransposeMode> ConstTransposeReturnType;
0274
0275 EIGEN_DEVICE_FUNC
0276 inline const ConstTransposeReturnType transpose() const
0277 {
0278 return ConstTransposeReturnType(m_matrix.transpose());
0279 }
0280
0281 template<typename Other>
0282 EIGEN_DEVICE_FUNC
0283 inline const Solve<TriangularView, Other>
0284 solve(const MatrixBase<Other>& other) const
0285 { return Solve<TriangularView, Other>(*this, other.derived()); }
0286
0287
0288 #if EIGEN_COMP_MSVC
0289 template<int Side, typename Other>
0290 EIGEN_DEVICE_FUNC
0291 inline const internal::triangular_solve_retval<Side,TriangularView, Other>
0292 solve(const MatrixBase<Other>& other) const
0293 { return Base::template solve<Side>(other); }
0294 #else
0295 using Base::solve;
0296 #endif
0297
0298
0299
0300
0301
0302 EIGEN_DEVICE_FUNC
0303 SelfAdjointView<MatrixTypeNestedNonRef,Mode> selfadjointView()
0304 {
0305 EIGEN_STATIC_ASSERT((Mode&(UnitDiag|ZeroDiag))==0,PROGRAMMING_ERROR);
0306 return SelfAdjointView<MatrixTypeNestedNonRef,Mode>(m_matrix);
0307 }
0308
0309
0310 EIGEN_DEVICE_FUNC
0311 const SelfAdjointView<MatrixTypeNestedNonRef,Mode> selfadjointView() const
0312 {
0313 EIGEN_STATIC_ASSERT((Mode&(UnitDiag|ZeroDiag))==0,PROGRAMMING_ERROR);
0314 return SelfAdjointView<MatrixTypeNestedNonRef,Mode>(m_matrix);
0315 }
0316
0317
0318
0319
0320 EIGEN_DEVICE_FUNC
0321 Scalar determinant() const
0322 {
0323 if (Mode & UnitDiag)
0324 return 1;
0325 else if (Mode & ZeroDiag)
0326 return 0;
0327 else
0328 return m_matrix.diagonal().prod();
0329 }
0330
0331 protected:
0332
0333 MatrixTypeNested m_matrix;
0334 };
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345 template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_MatrixType,_Mode,Dense>
0346 : public TriangularBase<TriangularView<_MatrixType, _Mode> >
0347 {
0348 public:
0349
0350 typedef TriangularView<_MatrixType, _Mode> TriangularViewType;
0351 typedef TriangularBase<TriangularViewType> Base;
0352 typedef typename internal::traits<TriangularViewType>::Scalar Scalar;
0353
0354 typedef _MatrixType MatrixType;
0355 typedef typename MatrixType::PlainObject DenseMatrixType;
0356 typedef DenseMatrixType PlainObject;
0357
0358 public:
0359 using Base::evalToLazy;
0360 using Base::derived;
0361
0362 typedef typename internal::traits<TriangularViewType>::StorageKind StorageKind;
0363
0364 enum {
0365 Mode = _Mode,
0366 Flags = internal::traits<TriangularViewType>::Flags
0367 };
0368
0369
0370
0371 EIGEN_DEVICE_FUNC
0372 inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
0373
0374
0375 EIGEN_DEVICE_FUNC
0376 inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
0377
0378
0379 template<typename Other>
0380 EIGEN_DEVICE_FUNC
0381 TriangularViewType& operator+=(const DenseBase<Other>& other) {
0382 internal::call_assignment_no_alias(derived(), other.derived(), internal::add_assign_op<Scalar,typename Other::Scalar>());
0383 return derived();
0384 }
0385
0386 template<typename Other>
0387 EIGEN_DEVICE_FUNC
0388 TriangularViewType& operator-=(const DenseBase<Other>& other) {
0389 internal::call_assignment_no_alias(derived(), other.derived(), internal::sub_assign_op<Scalar,typename Other::Scalar>());
0390 return derived();
0391 }
0392
0393
0394 EIGEN_DEVICE_FUNC
0395 TriangularViewType& operator*=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = derived().nestedExpression() * other; }
0396
0397 EIGEN_DEVICE_FUNC
0398 TriangularViewType& operator/=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = derived().nestedExpression() / other; }
0399
0400
0401 EIGEN_DEVICE_FUNC
0402 void fill(const Scalar& value) { setConstant(value); }
0403
0404 EIGEN_DEVICE_FUNC
0405 TriangularViewType& setConstant(const Scalar& value)
0406 { return *this = MatrixType::Constant(derived().rows(), derived().cols(), value); }
0407
0408 EIGEN_DEVICE_FUNC
0409 TriangularViewType& setZero() { return setConstant(Scalar(0)); }
0410
0411 EIGEN_DEVICE_FUNC
0412 TriangularViewType& setOnes() { return setConstant(Scalar(1)); }
0413
0414
0415
0416
0417 EIGEN_DEVICE_FUNC
0418 inline Scalar coeff(Index row, Index col) const
0419 {
0420 Base::check_coordinates_internal(row, col);
0421 return derived().nestedExpression().coeff(row, col);
0422 }
0423
0424
0425
0426
0427 EIGEN_DEVICE_FUNC
0428 inline Scalar& coeffRef(Index row, Index col)
0429 {
0430 EIGEN_STATIC_ASSERT_LVALUE(TriangularViewType);
0431 Base::check_coordinates_internal(row, col);
0432 return derived().nestedExpression().coeffRef(row, col);
0433 }
0434
0435
0436 template<typename OtherDerived>
0437 EIGEN_DEVICE_FUNC
0438 TriangularViewType& operator=(const TriangularBase<OtherDerived>& other);
0439
0440
0441 template<typename OtherDerived>
0442 EIGEN_DEVICE_FUNC
0443 TriangularViewType& operator=(const MatrixBase<OtherDerived>& other);
0444
0445 #ifndef EIGEN_PARSED_BY_DOXYGEN
0446 EIGEN_DEVICE_FUNC
0447 TriangularViewType& operator=(const TriangularViewImpl& other)
0448 { return *this = other.derived().nestedExpression(); }
0449
0450 template<typename OtherDerived>
0451
0452 EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
0453 void lazyAssign(const TriangularBase<OtherDerived>& other);
0454
0455 template<typename OtherDerived>
0456
0457 EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
0458 void lazyAssign(const MatrixBase<OtherDerived>& other);
0459 #endif
0460
0461
0462 template<typename OtherDerived>
0463 EIGEN_DEVICE_FUNC
0464 const Product<TriangularViewType,OtherDerived>
0465 operator*(const MatrixBase<OtherDerived>& rhs) const
0466 {
0467 return Product<TriangularViewType,OtherDerived>(derived(), rhs.derived());
0468 }
0469
0470
0471 template<typename OtherDerived> friend
0472 EIGEN_DEVICE_FUNC
0473 const Product<OtherDerived,TriangularViewType>
0474 operator*(const MatrixBase<OtherDerived>& lhs, const TriangularViewImpl& rhs)
0475 {
0476 return Product<OtherDerived,TriangularViewType>(lhs.derived(),rhs.derived());
0477 }
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502 template<int Side, typename Other>
0503 inline const internal::triangular_solve_retval<Side,TriangularViewType, Other>
0504 solve(const MatrixBase<Other>& other) const;
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515 template<int Side, typename OtherDerived>
0516 EIGEN_DEVICE_FUNC
0517 void solveInPlace(const MatrixBase<OtherDerived>& other) const;
0518
0519 template<typename OtherDerived>
0520 EIGEN_DEVICE_FUNC
0521 void solveInPlace(const MatrixBase<OtherDerived>& other) const
0522 { return solveInPlace<OnTheLeft>(other); }
0523
0524
0525 template<typename OtherDerived>
0526 EIGEN_DEVICE_FUNC
0527 #ifdef EIGEN_PARSED_BY_DOXYGEN
0528 void swap(TriangularBase<OtherDerived> &other)
0529 #else
0530 void swap(TriangularBase<OtherDerived> const & other)
0531 #endif
0532 {
0533 EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
0534 call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
0535 }
0536
0537
0538 template<typename OtherDerived>
0539
0540 EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
0541 void swap(MatrixBase<OtherDerived> const & other)
0542 {
0543 EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
0544 call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
0545 }
0546
0547 template<typename RhsType, typename DstType>
0548 EIGEN_DEVICE_FUNC
0549 EIGEN_STRONG_INLINE void _solve_impl(const RhsType &rhs, DstType &dst) const {
0550 if(!internal::is_same_dense(dst,rhs))
0551 dst = rhs;
0552 this->solveInPlace(dst);
0553 }
0554
0555 template<typename ProductType>
0556 EIGEN_DEVICE_FUNC
0557 EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(const ProductType& prod, const Scalar& alpha, bool beta);
0558 protected:
0559 EIGEN_DEFAULT_COPY_CONSTRUCTOR(TriangularViewImpl)
0560 EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(TriangularViewImpl)
0561
0562 };
0563
0564
0565
0566
0567
0568 #ifndef EIGEN_PARSED_BY_DOXYGEN
0569
0570 template<typename MatrixType, unsigned int Mode>
0571 template<typename OtherDerived>
0572 EIGEN_DEVICE_FUNC inline TriangularView<MatrixType, Mode>&
0573 TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const MatrixBase<OtherDerived>& other)
0574 {
0575 internal::call_assignment_no_alias(derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
0576 return derived();
0577 }
0578
0579
0580 template<typename MatrixType, unsigned int Mode>
0581 template<typename OtherDerived>
0582 EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const MatrixBase<OtherDerived>& other)
0583 {
0584 internal::call_assignment_no_alias(derived(), other.template triangularView<Mode>());
0585 }
0586
0587
0588
0589 template<typename MatrixType, unsigned int Mode>
0590 template<typename OtherDerived>
0591 EIGEN_DEVICE_FUNC inline TriangularView<MatrixType, Mode>&
0592 TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const TriangularBase<OtherDerived>& other)
0593 {
0594 eigen_assert(Mode == int(OtherDerived::Mode));
0595 internal::call_assignment(derived(), other.derived());
0596 return derived();
0597 }
0598
0599 template<typename MatrixType, unsigned int Mode>
0600 template<typename OtherDerived>
0601 EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const TriangularBase<OtherDerived>& other)
0602 {
0603 eigen_assert(Mode == int(OtherDerived::Mode));
0604 internal::call_assignment_no_alias(derived(), other.derived());
0605 }
0606 #endif
0607
0608
0609
0610
0611
0612
0613
0614 template<typename Derived>
0615 template<typename DenseDerived>
0616 EIGEN_DEVICE_FUNC void TriangularBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
0617 {
0618 evalToLazy(other.derived());
0619 }
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640 template<typename Derived>
0641 template<unsigned int Mode>
0642 EIGEN_DEVICE_FUNC
0643 typename MatrixBase<Derived>::template TriangularViewReturnType<Mode>::Type
0644 MatrixBase<Derived>::triangularView()
0645 {
0646 return typename TriangularViewReturnType<Mode>::Type(derived());
0647 }
0648
0649
0650 template<typename Derived>
0651 template<unsigned int Mode>
0652 EIGEN_DEVICE_FUNC
0653 typename MatrixBase<Derived>::template ConstTriangularViewReturnType<Mode>::Type
0654 MatrixBase<Derived>::triangularView() const
0655 {
0656 return typename ConstTriangularViewReturnType<Mode>::Type(derived());
0657 }
0658
0659
0660
0661
0662
0663
0664 template<typename Derived>
0665 bool MatrixBase<Derived>::isUpperTriangular(const RealScalar& prec) const
0666 {
0667 RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1);
0668 for(Index j = 0; j < cols(); ++j)
0669 {
0670 Index maxi = numext::mini(j, rows()-1);
0671 for(Index i = 0; i <= maxi; ++i)
0672 {
0673 RealScalar absValue = numext::abs(coeff(i,j));
0674 if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
0675 }
0676 }
0677 RealScalar threshold = maxAbsOnUpperPart * prec;
0678 for(Index j = 0; j < cols(); ++j)
0679 for(Index i = j+1; i < rows(); ++i)
0680 if(numext::abs(coeff(i, j)) > threshold) return false;
0681 return true;
0682 }
0683
0684
0685
0686
0687
0688
0689 template<typename Derived>
0690 bool MatrixBase<Derived>::isLowerTriangular(const RealScalar& prec) const
0691 {
0692 RealScalar maxAbsOnLowerPart = static_cast<RealScalar>(-1);
0693 for(Index j = 0; j < cols(); ++j)
0694 for(Index i = j; i < rows(); ++i)
0695 {
0696 RealScalar absValue = numext::abs(coeff(i,j));
0697 if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
0698 }
0699 RealScalar threshold = maxAbsOnLowerPart * prec;
0700 for(Index j = 1; j < cols(); ++j)
0701 {
0702 Index maxi = numext::mini(j, rows()-1);
0703 for(Index i = 0; i < maxi; ++i)
0704 if(numext::abs(coeff(i, j)) > threshold) return false;
0705 }
0706 return true;
0707 }
0708
0709
0710
0711
0712
0713
0714
0715
0716 namespace internal {
0717
0718
0719
0720
0721
0722 template<typename MatrixType, unsigned int Mode>
0723 struct evaluator_traits<TriangularView<MatrixType,Mode> >
0724 {
0725 typedef typename storage_kind_to_evaluator_kind<typename MatrixType::StorageKind>::Kind Kind;
0726 typedef typename glue_shapes<typename evaluator_traits<MatrixType>::Shape, TriangularShape>::type Shape;
0727 };
0728
0729 template<typename MatrixType, unsigned int Mode>
0730 struct unary_evaluator<TriangularView<MatrixType,Mode>, IndexBased>
0731 : evaluator<typename internal::remove_all<MatrixType>::type>
0732 {
0733 typedef TriangularView<MatrixType,Mode> XprType;
0734 typedef evaluator<typename internal::remove_all<MatrixType>::type> Base;
0735 EIGEN_DEVICE_FUNC
0736 unary_evaluator(const XprType &xpr) : Base(xpr.nestedExpression()) {}
0737 };
0738
0739
0740 struct Triangular2Triangular {};
0741 struct Triangular2Dense {};
0742 struct Dense2Triangular {};
0743
0744
0745 template<typename Kernel, unsigned int Mode, int UnrollCount, bool ClearOpposite> struct triangular_assignment_loop;
0746
0747
0748
0749
0750
0751
0752
0753 template<int UpLo, int Mode, int SetOpposite, typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT, typename Functor, int Version = Specialized>
0754 class triangular_dense_assignment_kernel : public generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version>
0755 {
0756 protected:
0757 typedef generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version> Base;
0758 typedef typename Base::DstXprType DstXprType;
0759 typedef typename Base::SrcXprType SrcXprType;
0760 using Base::m_dst;
0761 using Base::m_src;
0762 using Base::m_functor;
0763 public:
0764
0765 typedef typename Base::DstEvaluatorType DstEvaluatorType;
0766 typedef typename Base::SrcEvaluatorType SrcEvaluatorType;
0767 typedef typename Base::Scalar Scalar;
0768 typedef typename Base::AssignmentTraits AssignmentTraits;
0769
0770
0771 EIGEN_DEVICE_FUNC triangular_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
0772 : Base(dst, src, func, dstExpr)
0773 {}
0774
0775 #ifdef EIGEN_INTERNAL_DEBUGGING
0776 EIGEN_DEVICE_FUNC void assignCoeff(Index row, Index col)
0777 {
0778 eigen_internal_assert(row!=col);
0779 Base::assignCoeff(row,col);
0780 }
0781 #else
0782 using Base::assignCoeff;
0783 #endif
0784
0785 EIGEN_DEVICE_FUNC void assignDiagonalCoeff(Index id)
0786 {
0787 if(Mode==UnitDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(id,id), Scalar(1));
0788 else if(Mode==ZeroDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(id,id), Scalar(0));
0789 else if(Mode==0) Base::assignCoeff(id,id);
0790 }
0791
0792 EIGEN_DEVICE_FUNC void assignOppositeCoeff(Index row, Index col)
0793 {
0794 eigen_internal_assert(row!=col);
0795 if(SetOpposite)
0796 m_functor.assignCoeff(m_dst.coeffRef(row,col), Scalar(0));
0797 }
0798 };
0799
0800 template<int Mode, bool SetOpposite, typename DstXprType, typename SrcXprType, typename Functor>
0801 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0802 void call_triangular_assignment_loop(DstXprType& dst, const SrcXprType& src, const Functor &func)
0803 {
0804 typedef evaluator<DstXprType> DstEvaluatorType;
0805 typedef evaluator<SrcXprType> SrcEvaluatorType;
0806
0807 SrcEvaluatorType srcEvaluator(src);
0808
0809 Index dstRows = src.rows();
0810 Index dstCols = src.cols();
0811 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
0812 dst.resize(dstRows, dstCols);
0813 DstEvaluatorType dstEvaluator(dst);
0814
0815 typedef triangular_dense_assignment_kernel< Mode&(Lower|Upper),Mode&(UnitDiag|ZeroDiag|SelfAdjoint),SetOpposite,
0816 DstEvaluatorType,SrcEvaluatorType,Functor> Kernel;
0817 Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived());
0818
0819 enum {
0820 unroll = DstXprType::SizeAtCompileTime != Dynamic
0821 && SrcEvaluatorType::CoeffReadCost < HugeCost
0822 && DstXprType::SizeAtCompileTime * (int(DstEvaluatorType::CoeffReadCost) + int(SrcEvaluatorType::CoeffReadCost)) / 2 <= EIGEN_UNROLLING_LIMIT
0823 };
0824
0825 triangular_assignment_loop<Kernel, Mode, unroll ? int(DstXprType::SizeAtCompileTime) : Dynamic, SetOpposite>::run(kernel);
0826 }
0827
0828 template<int Mode, bool SetOpposite, typename DstXprType, typename SrcXprType>
0829 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0830 void call_triangular_assignment_loop(DstXprType& dst, const SrcXprType& src)
0831 {
0832 call_triangular_assignment_loop<Mode,SetOpposite>(dst, src, internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar>());
0833 }
0834
0835 template<> struct AssignmentKind<TriangularShape,TriangularShape> { typedef Triangular2Triangular Kind; };
0836 template<> struct AssignmentKind<DenseShape,TriangularShape> { typedef Triangular2Dense Kind; };
0837 template<> struct AssignmentKind<TriangularShape,DenseShape> { typedef Dense2Triangular Kind; };
0838
0839
0840 template< typename DstXprType, typename SrcXprType, typename Functor>
0841 struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Triangular>
0842 {
0843 EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
0844 {
0845 eigen_assert(int(DstXprType::Mode) == int(SrcXprType::Mode));
0846
0847 call_triangular_assignment_loop<DstXprType::Mode, false>(dst, src, func);
0848 }
0849 };
0850
0851 template< typename DstXprType, typename SrcXprType, typename Functor>
0852 struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Dense>
0853 {
0854 EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
0855 {
0856 call_triangular_assignment_loop<SrcXprType::Mode, (int(SrcXprType::Mode) & int(SelfAdjoint)) == 0>(dst, src, func);
0857 }
0858 };
0859
0860 template< typename DstXprType, typename SrcXprType, typename Functor>
0861 struct Assignment<DstXprType, SrcXprType, Functor, Dense2Triangular>
0862 {
0863 EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
0864 {
0865 call_triangular_assignment_loop<DstXprType::Mode, false>(dst, src, func);
0866 }
0867 };
0868
0869
0870 template<typename Kernel, unsigned int Mode, int UnrollCount, bool SetOpposite>
0871 struct triangular_assignment_loop
0872 {
0873
0874 typedef typename Kernel::DstEvaluatorType DstEvaluatorType;
0875 typedef typename DstEvaluatorType::XprType DstXprType;
0876
0877 enum {
0878 col = (UnrollCount-1) / DstXprType::RowsAtCompileTime,
0879 row = (UnrollCount-1) % DstXprType::RowsAtCompileTime
0880 };
0881
0882 typedef typename Kernel::Scalar Scalar;
0883
0884 EIGEN_DEVICE_FUNC
0885 static inline void run(Kernel &kernel)
0886 {
0887 triangular_assignment_loop<Kernel, Mode, UnrollCount-1, SetOpposite>::run(kernel);
0888
0889 if(row==col)
0890 kernel.assignDiagonalCoeff(row);
0891 else if( ((Mode&Lower) && row>col) || ((Mode&Upper) && row<col) )
0892 kernel.assignCoeff(row,col);
0893 else if(SetOpposite)
0894 kernel.assignOppositeCoeff(row,col);
0895 }
0896 };
0897
0898
0899 template<typename Kernel, unsigned int Mode, bool SetOpposite>
0900 struct triangular_assignment_loop<Kernel, Mode, 0, SetOpposite>
0901 {
0902 EIGEN_DEVICE_FUNC
0903 static inline void run(Kernel &) {}
0904 };
0905
0906
0907
0908
0909
0910
0911
0912 template<typename Kernel, unsigned int Mode, bool SetOpposite>
0913 struct triangular_assignment_loop<Kernel, Mode, Dynamic, SetOpposite>
0914 {
0915 typedef typename Kernel::Scalar Scalar;
0916 EIGEN_DEVICE_FUNC
0917 static inline void run(Kernel &kernel)
0918 {
0919 for(Index j = 0; j < kernel.cols(); ++j)
0920 {
0921 Index maxi = numext::mini(j, kernel.rows());
0922 Index i = 0;
0923 if (((Mode&Lower) && SetOpposite) || (Mode&Upper))
0924 {
0925 for(; i < maxi; ++i)
0926 if(Mode&Upper) kernel.assignCoeff(i, j);
0927 else kernel.assignOppositeCoeff(i, j);
0928 }
0929 else
0930 i = maxi;
0931
0932 if(i<kernel.rows())
0933 kernel.assignDiagonalCoeff(i++);
0934
0935 if (((Mode&Upper) && SetOpposite) || (Mode&Lower))
0936 {
0937 for(; i < kernel.rows(); ++i)
0938 if(Mode&Lower) kernel.assignCoeff(i, j);
0939 else kernel.assignOppositeCoeff(i, j);
0940 }
0941 }
0942 }
0943 };
0944
0945 }
0946
0947
0948
0949 template<typename Derived>
0950 template<typename DenseDerived>
0951 EIGEN_DEVICE_FUNC void TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDerived> &other) const
0952 {
0953 other.derived().resize(this->rows(), this->cols());
0954 internal::call_triangular_assignment_loop<Derived::Mode, (int(Derived::Mode) & int(SelfAdjoint)) == 0 >(other.derived(), derived().nestedExpression());
0955 }
0956
0957 namespace internal {
0958
0959
0960 template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
0961 struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
0962 {
0963 typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
0964 static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,typename SrcXprType::Scalar> &)
0965 {
0966 Index dstRows = src.rows();
0967 Index dstCols = src.cols();
0968 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
0969 dst.resize(dstRows, dstCols);
0970
0971 dst._assignProduct(src, Scalar(1), false);
0972 }
0973 };
0974
0975
0976 template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
0977 struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::add_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
0978 {
0979 typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
0980 static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,typename SrcXprType::Scalar> &)
0981 {
0982 dst._assignProduct(src, Scalar(1), true);
0983 }
0984 };
0985
0986
0987 template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
0988 struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
0989 {
0990 typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
0991 static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,typename SrcXprType::Scalar> &)
0992 {
0993 dst._assignProduct(src, Scalar(-1), true);
0994 }
0995 };
0996
0997 }
0998
0999 }
1000
1001 #endif