00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef EIGEN_TRIANGULARMATRIX_H
00012 #define EIGEN_TRIANGULARMATRIX_H
00013
00014 namespace Eigen {
00015
00016 namespace internal {
00017
00018 template<int Side, typename TriangularType, typename Rhs> struct triangular_solve_retval;
00019
00020 }
00021
00029 template<typename Derived> class TriangularBase : public EigenBase<Derived>
00030 {
00031 public:
00032
00033 enum {
00034 Mode = internal::traits<Derived>::Mode,
00035 CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
00036 RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
00037 ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
00038 MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
00039 MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime
00040 };
00041 typedef typename internal::traits<Derived>::Scalar Scalar;
00042 typedef typename internal::traits<Derived>::StorageKind StorageKind;
00043 typedef typename internal::traits<Derived>::Index Index;
00044 typedef typename internal::traits<Derived>::DenseMatrixType DenseMatrixType;
00045 typedef DenseMatrixType DenseType;
00046
00047 inline TriangularBase() { eigen_assert(!((Mode&UnitDiag) && (Mode&ZeroDiag))); }
00048
00049 inline Index rows() const { return derived().rows(); }
00050 inline Index cols() const { return derived().cols(); }
00051 inline Index outerStride() const { return derived().outerStride(); }
00052 inline Index innerStride() const { return derived().innerStride(); }
00053
00054 inline Scalar coeff(Index row, Index col) const { return derived().coeff(row,col); }
00055 inline Scalar& coeffRef(Index row, Index col) { return derived().coeffRef(row,col); }
00056
00059 template<typename Other>
00060 EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, Other& other)
00061 {
00062 derived().coeffRef(row, col) = other.coeff(row, col);
00063 }
00064
00065 inline Scalar operator()(Index row, Index col) const
00066 {
00067 check_coordinates(row, col);
00068 return coeff(row,col);
00069 }
00070 inline Scalar& operator()(Index row, Index col)
00071 {
00072 check_coordinates(row, col);
00073 return coeffRef(row,col);
00074 }
00075
00076 #ifndef EIGEN_PARSED_BY_DOXYGEN
00077 inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
00078 inline Derived& derived() { return *static_cast<Derived*>(this); }
00079 #endif // not EIGEN_PARSED_BY_DOXYGEN
00080
00081 template<typename DenseDerived>
00082 void evalTo(MatrixBase<DenseDerived> &other) const;
00083 template<typename DenseDerived>
00084 void evalToLazy(MatrixBase<DenseDerived> &other) const;
00085
00086 DenseMatrixType toDenseMatrix() const
00087 {
00088 DenseMatrixType res(rows(), cols());
00089 evalToLazy(res);
00090 return res;
00091 }
00092
00093 protected:
00094
00095 void check_coordinates(Index row, Index col) const
00096 {
00097 EIGEN_ONLY_USED_FOR_DEBUG(row);
00098 EIGEN_ONLY_USED_FOR_DEBUG(col);
00099 eigen_assert(col>=0 && col<cols() && row>=0 && row<rows());
00100 const int mode = int(Mode) & ~SelfAdjoint;
00101 EIGEN_ONLY_USED_FOR_DEBUG(mode);
00102 eigen_assert((mode==Upper && col>=row)
00103 || (mode==Lower && col<=row)
00104 || ((mode==StrictlyUpper || mode==UnitUpper) && col>row)
00105 || ((mode==StrictlyLower || mode==UnitLower) && col<row));
00106 }
00107
00108 #ifdef EIGEN_INTERNAL_DEBUGGING
00109 void check_coordinates_internal(Index row, Index col) const
00110 {
00111 check_coordinates(row, col);
00112 }
00113 #else
00114 void check_coordinates_internal(Index , Index ) const {}
00115 #endif
00116
00117 };
00118
00136 namespace internal {
00137 template<typename MatrixType, unsigned int _Mode>
00138 struct traits<TriangularView<MatrixType, _Mode> > : traits<MatrixType>
00139 {
00140 typedef typename nested<MatrixType>::type MatrixTypeNested;
00141 typedef typename remove_reference<MatrixTypeNested>::type MatrixTypeNestedNonRef;
00142 typedef typename remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned;
00143 typedef MatrixType ExpressionType;
00144 typedef typename MatrixType::PlainObject DenseMatrixType;
00145 enum {
00146 Mode = _Mode,
00147 Flags = (MatrixTypeNestedCleaned::Flags & (HereditaryBits) & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit))) | Mode,
00148 CoeffReadCost = MatrixTypeNestedCleaned::CoeffReadCost
00149 };
00150 };
00151 }
00152
00153 template<int Mode, bool LhsIsTriangular,
00154 typename Lhs, bool LhsIsVector,
00155 typename Rhs, bool RhsIsVector>
00156 struct TriangularProduct;
00157
00158 template<typename _MatrixType, unsigned int _Mode> class TriangularView
00159 : public TriangularBase<TriangularView<_MatrixType, _Mode> >
00160 {
00161 public:
00162
00163 typedef TriangularBase<TriangularView> Base;
00164 typedef typename internal::traits<TriangularView>::Scalar Scalar;
00165
00166 typedef _MatrixType MatrixType;
00167 typedef typename internal::traits<TriangularView>::DenseMatrixType DenseMatrixType;
00168 typedef DenseMatrixType PlainObject;
00169
00170 protected:
00171 typedef typename internal::traits<TriangularView>::MatrixTypeNested MatrixTypeNested;
00172 typedef typename internal::traits<TriangularView>::MatrixTypeNestedNonRef MatrixTypeNestedNonRef;
00173 typedef typename internal::traits<TriangularView>::MatrixTypeNestedCleaned MatrixTypeNestedCleaned;
00174
00175 typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
00176
00177 public:
00178 using Base::evalToLazy;
00179
00180
00181 typedef typename internal::traits<TriangularView>::StorageKind StorageKind;
00182 typedef typename internal::traits<TriangularView>::Index Index;
00183
00184 enum {
00185 Mode = _Mode,
00186 TransposeMode = (Mode & Upper ? Lower : 0)
00187 | (Mode & Lower ? Upper : 0)
00188 | (Mode & (UnitDiag))
00189 | (Mode & (ZeroDiag))
00190 };
00191
00192 inline TriangularView(const MatrixType& matrix) : m_matrix(matrix)
00193 {}
00194
00195 inline Index rows() const { return m_matrix.rows(); }
00196 inline Index cols() const { return m_matrix.cols(); }
00197 inline Index outerStride() const { return m_matrix.outerStride(); }
00198 inline Index innerStride() const { return m_matrix.innerStride(); }
00199
00201 template<typename Other> TriangularView& operator+=(const DenseBase<Other>& other) { return *this = m_matrix + other.derived(); }
00203 template<typename Other> TriangularView& operator-=(const DenseBase<Other>& other) { return *this = m_matrix - other.derived(); }
00205 TriangularView& operator*=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = m_matrix * other; }
00207 TriangularView& operator/=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = m_matrix / other; }
00208
00210 void fill(const Scalar& value) { setConstant(value); }
00212 TriangularView& setConstant(const Scalar& value)
00213 { return *this = MatrixType::Constant(rows(), cols(), value); }
00215 TriangularView& setZero() { return setConstant(Scalar(0)); }
00217 TriangularView& setOnes() { return setConstant(Scalar(1)); }
00218
00222 inline Scalar coeff(Index row, Index col) const
00223 {
00224 Base::check_coordinates_internal(row, col);
00225 return m_matrix.coeff(row, col);
00226 }
00227
00231 inline Scalar& coeffRef(Index row, Index col)
00232 {
00233 Base::check_coordinates_internal(row, col);
00234 return m_matrix.const_cast_derived().coeffRef(row, col);
00235 }
00236
00237 const MatrixTypeNestedCleaned& nestedExpression() const { return m_matrix; }
00238 MatrixTypeNestedCleaned& nestedExpression() { return *const_cast<MatrixTypeNestedCleaned*>(&m_matrix); }
00239
00241 template<typename OtherDerived>
00242 TriangularView& operator=(const TriangularBase<OtherDerived>& other);
00243
00244 template<typename OtherDerived>
00245 TriangularView& operator=(const MatrixBase<OtherDerived>& other);
00246
00247 TriangularView& operator=(const TriangularView& other)
00248 { return *this = other.nestedExpression(); }
00249
00250 template<typename OtherDerived>
00251 void lazyAssign(const TriangularBase<OtherDerived>& other);
00252
00253 template<typename OtherDerived>
00254 void lazyAssign(const MatrixBase<OtherDerived>& other);
00255
00257 inline TriangularView<MatrixConjugateReturnType,Mode> conjugate()
00258 { return m_matrix.conjugate(); }
00260 inline const TriangularView<MatrixConjugateReturnType,Mode> conjugate() const
00261 { return m_matrix.conjugate(); }
00262
00264 inline const TriangularView<const typename MatrixType::AdjointReturnType,TransposeMode> adjoint() const
00265 { return m_matrix.adjoint(); }
00266
00268 inline TriangularView<Transpose<MatrixType>,TransposeMode> transpose()
00269 {
00270 EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
00271 return m_matrix.const_cast_derived().transpose();
00272 }
00274 inline const TriangularView<Transpose<MatrixType>,TransposeMode> transpose() const
00275 {
00276 return m_matrix.transpose();
00277 }
00278
00280 template<typename OtherDerived>
00281 TriangularProduct<Mode,true,MatrixType,false,OtherDerived, OtherDerived::IsVectorAtCompileTime>
00282 operator*(const MatrixBase<OtherDerived>& rhs) const
00283 {
00284 return TriangularProduct
00285 <Mode,true,MatrixType,false,OtherDerived,OtherDerived::IsVectorAtCompileTime>
00286 (m_matrix, rhs.derived());
00287 }
00288
00290 template<typename OtherDerived> friend
00291 TriangularProduct<Mode,false,OtherDerived,OtherDerived::IsVectorAtCompileTime,MatrixType,false>
00292 operator*(const MatrixBase<OtherDerived>& lhs, const TriangularView& rhs)
00293 {
00294 return TriangularProduct
00295 <Mode,false,OtherDerived,OtherDerived::IsVectorAtCompileTime,MatrixType,false>
00296 (lhs.derived(),rhs.m_matrix);
00297 }
00298
00299 #ifdef EIGEN2_SUPPORT
00300 template<typename OtherDerived>
00301 struct eigen2_product_return_type
00302 {
00303 typedef typename TriangularView<MatrixType,Mode>::DenseMatrixType DenseMatrixType;
00304 typedef typename OtherDerived::PlainObject::DenseType OtherPlainObject;
00305 typedef typename ProductReturnType<DenseMatrixType, OtherPlainObject>::Type ProdRetType;
00306 typedef typename ProdRetType::PlainObject type;
00307 };
00308 template<typename OtherDerived>
00309 const typename eigen2_product_return_type<OtherDerived>::type
00310 operator*(const EigenBase<OtherDerived>& rhs) const
00311 {
00312 typename OtherDerived::PlainObject::DenseType rhsPlainObject;
00313 rhs.evalTo(rhsPlainObject);
00314 return this->toDenseMatrix() * rhsPlainObject;
00315 }
00316 template<typename OtherMatrixType>
00317 bool isApprox(const TriangularView<OtherMatrixType, Mode>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const
00318 {
00319 return this->toDenseMatrix().isApprox(other.toDenseMatrix(), precision);
00320 }
00321 template<typename OtherDerived>
00322 bool isApprox(const MatrixBase<OtherDerived>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const
00323 {
00324 return this->toDenseMatrix().isApprox(other, precision);
00325 }
00326 #endif // EIGEN2_SUPPORT
00327
00328 template<int Side, typename Other>
00329 inline const internal::triangular_solve_retval<Side,TriangularView, Other>
00330 solve(const MatrixBase<Other>& other) const;
00331
00332 template<int Side, typename OtherDerived>
00333 void solveInPlace(const MatrixBase<OtherDerived>& other) const;
00334
00335 template<typename Other>
00336 inline const internal::triangular_solve_retval<OnTheLeft,TriangularView, Other>
00337 solve(const MatrixBase<Other>& other) const
00338 { return solve<OnTheLeft>(other); }
00339
00340 template<typename OtherDerived>
00341 void solveInPlace(const MatrixBase<OtherDerived>& other) const
00342 { return solveInPlace<OnTheLeft>(other); }
00343
00344 const SelfAdjointView<MatrixTypeNestedNonRef,Mode> selfadjointView() const
00345 {
00346 EIGEN_STATIC_ASSERT((Mode&UnitDiag)==0,PROGRAMMING_ERROR);
00347 return SelfAdjointView<MatrixTypeNestedNonRef,Mode>(m_matrix);
00348 }
00349 SelfAdjointView<MatrixTypeNestedNonRef,Mode> selfadjointView()
00350 {
00351 EIGEN_STATIC_ASSERT((Mode&UnitDiag)==0,PROGRAMMING_ERROR);
00352 return SelfAdjointView<MatrixTypeNestedNonRef,Mode>(m_matrix);
00353 }
00354
00355 template<typename OtherDerived>
00356 void swap(TriangularBase<OtherDerived> const & other)
00357 {
00358 TriangularView<SwapWrapper<MatrixType>,Mode>(const_cast<MatrixType&>(m_matrix)).lazyAssign(other.derived());
00359 }
00360
00361 template<typename OtherDerived>
00362 void swap(MatrixBase<OtherDerived> const & other)
00363 {
00364 SwapWrapper<MatrixType> swaper(const_cast<MatrixType&>(m_matrix));
00365 TriangularView<SwapWrapper<MatrixType>,Mode>(swaper).lazyAssign(other.derived());
00366 }
00367
00368 Scalar determinant() const
00369 {
00370 if (Mode & UnitDiag)
00371 return 1;
00372 else if (Mode & ZeroDiag)
00373 return 0;
00374 else
00375 return m_matrix.diagonal().prod();
00376 }
00377
00378
00379 template<typename ProductDerived, typename Lhs, typename Rhs>
00380 EIGEN_STRONG_INLINE TriangularView& operator=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
00381 {
00382 setZero();
00383 return assignProduct(other,1);
00384 }
00385
00386 template<typename ProductDerived, typename Lhs, typename Rhs>
00387 EIGEN_STRONG_INLINE TriangularView& operator+=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
00388 {
00389 return assignProduct(other,1);
00390 }
00391
00392 template<typename ProductDerived, typename Lhs, typename Rhs>
00393 EIGEN_STRONG_INLINE TriangularView& operator-=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
00394 {
00395 return assignProduct(other,-1);
00396 }
00397
00398
00399 template<typename ProductDerived>
00400 EIGEN_STRONG_INLINE TriangularView& operator=(const ScaledProduct<ProductDerived>& other)
00401 {
00402 setZero();
00403 return assignProduct(other,other.alpha());
00404 }
00405
00406 template<typename ProductDerived>
00407 EIGEN_STRONG_INLINE TriangularView& operator+=(const ScaledProduct<ProductDerived>& other)
00408 {
00409 return assignProduct(other,other.alpha());
00410 }
00411
00412 template<typename ProductDerived>
00413 EIGEN_STRONG_INLINE TriangularView& operator-=(const ScaledProduct<ProductDerived>& other)
00414 {
00415 return assignProduct(other,-other.alpha());
00416 }
00417
00418 protected:
00419
00420 template<typename ProductDerived, typename Lhs, typename Rhs>
00421 EIGEN_STRONG_INLINE TriangularView& assignProduct(const ProductBase<ProductDerived, Lhs,Rhs>& prod, const Scalar& alpha);
00422
00423 MatrixTypeNested m_matrix;
00424 };
00425
00426
00427
00428
00429
00430 namespace internal {
00431
00432 template<typename Derived1, typename Derived2, unsigned int Mode, int UnrollCount, bool ClearOpposite>
00433 struct triangular_assignment_selector
00434 {
00435 enum {
00436 col = (UnrollCount-1) / Derived1::RowsAtCompileTime,
00437 row = (UnrollCount-1) % Derived1::RowsAtCompileTime
00438 };
00439
00440 typedef typename Derived1::Scalar Scalar;
00441
00442 static inline void run(Derived1 &dst, const Derived2 &src)
00443 {
00444 triangular_assignment_selector<Derived1, Derived2, Mode, UnrollCount-1, ClearOpposite>::run(dst, src);
00445
00446 eigen_assert( Mode == Upper || Mode == Lower
00447 || Mode == StrictlyUpper || Mode == StrictlyLower
00448 || Mode == UnitUpper || Mode == UnitLower);
00449 if((Mode == Upper && row <= col)
00450 || (Mode == Lower && row >= col)
00451 || (Mode == StrictlyUpper && row < col)
00452 || (Mode == StrictlyLower && row > col)
00453 || (Mode == UnitUpper && row < col)
00454 || (Mode == UnitLower && row > col))
00455 dst.copyCoeff(row, col, src);
00456 else if(ClearOpposite)
00457 {
00458 if (Mode&UnitDiag && row==col)
00459 dst.coeffRef(row, col) = Scalar(1);
00460 else
00461 dst.coeffRef(row, col) = Scalar(0);
00462 }
00463 }
00464 };
00465
00466
00467 template<typename Derived1, typename Derived2, unsigned int Mode, bool ClearOpposite>
00468 struct triangular_assignment_selector<Derived1, Derived2, Mode, 0, ClearOpposite>
00469 {
00470 static inline void run(Derived1 &, const Derived2 &) {}
00471 };
00472
00473 template<typename Derived1, typename Derived2, bool ClearOpposite>
00474 struct triangular_assignment_selector<Derived1, Derived2, Upper, Dynamic, ClearOpposite>
00475 {
00476 typedef typename Derived1::Index Index;
00477 typedef typename Derived1::Scalar Scalar;
00478 static inline void run(Derived1 &dst, const Derived2 &src)
00479 {
00480 for(Index j = 0; j < dst.cols(); ++j)
00481 {
00482 Index maxi = (std::min)(j, dst.rows()-1);
00483 for(Index i = 0; i <= maxi; ++i)
00484 dst.copyCoeff(i, j, src);
00485 if (ClearOpposite)
00486 for(Index i = maxi+1; i < dst.rows(); ++i)
00487 dst.coeffRef(i, j) = Scalar(0);
00488 }
00489 }
00490 };
00491
00492 template<typename Derived1, typename Derived2, bool ClearOpposite>
00493 struct triangular_assignment_selector<Derived1, Derived2, Lower, Dynamic, ClearOpposite>
00494 {
00495 typedef typename Derived1::Index Index;
00496 static inline void run(Derived1 &dst, const Derived2 &src)
00497 {
00498 for(Index j = 0; j < dst.cols(); ++j)
00499 {
00500 for(Index i = j; i < dst.rows(); ++i)
00501 dst.copyCoeff(i, j, src);
00502 Index maxi = (std::min)(j, dst.rows());
00503 if (ClearOpposite)
00504 for(Index i = 0; i < maxi; ++i)
00505 dst.coeffRef(i, j) = static_cast<typename Derived1::Scalar>(0);
00506 }
00507 }
00508 };
00509
00510 template<typename Derived1, typename Derived2, bool ClearOpposite>
00511 struct triangular_assignment_selector<Derived1, Derived2, StrictlyUpper, Dynamic, ClearOpposite>
00512 {
00513 typedef typename Derived1::Index Index;
00514 typedef typename Derived1::Scalar Scalar;
00515 static inline void run(Derived1 &dst, const Derived2 &src)
00516 {
00517 for(Index j = 0; j < dst.cols(); ++j)
00518 {
00519 Index maxi = (std::min)(j, dst.rows());
00520 for(Index i = 0; i < maxi; ++i)
00521 dst.copyCoeff(i, j, src);
00522 if (ClearOpposite)
00523 for(Index i = maxi; i < dst.rows(); ++i)
00524 dst.coeffRef(i, j) = Scalar(0);
00525 }
00526 }
00527 };
00528
00529 template<typename Derived1, typename Derived2, bool ClearOpposite>
00530 struct triangular_assignment_selector<Derived1, Derived2, StrictlyLower, Dynamic, ClearOpposite>
00531 {
00532 typedef typename Derived1::Index Index;
00533 static inline void run(Derived1 &dst, const Derived2 &src)
00534 {
00535 for(Index j = 0; j < dst.cols(); ++j)
00536 {
00537 for(Index i = j+1; i < dst.rows(); ++i)
00538 dst.copyCoeff(i, j, src);
00539 Index maxi = (std::min)(j, dst.rows()-1);
00540 if (ClearOpposite)
00541 for(Index i = 0; i <= maxi; ++i)
00542 dst.coeffRef(i, j) = static_cast<typename Derived1::Scalar>(0);
00543 }
00544 }
00545 };
00546
00547 template<typename Derived1, typename Derived2, bool ClearOpposite>
00548 struct triangular_assignment_selector<Derived1, Derived2, UnitUpper, Dynamic, ClearOpposite>
00549 {
00550 typedef typename Derived1::Index Index;
00551 static inline void run(Derived1 &dst, const Derived2 &src)
00552 {
00553 for(Index j = 0; j < dst.cols(); ++j)
00554 {
00555 Index maxi = (std::min)(j, dst.rows());
00556 for(Index i = 0; i < maxi; ++i)
00557 dst.copyCoeff(i, j, src);
00558 if (ClearOpposite)
00559 {
00560 for(Index i = maxi+1; i < dst.rows(); ++i)
00561 dst.coeffRef(i, j) = 0;
00562 }
00563 }
00564 dst.diagonal().setOnes();
00565 }
00566 };
00567 template<typename Derived1, typename Derived2, bool ClearOpposite>
00568 struct triangular_assignment_selector<Derived1, Derived2, UnitLower, Dynamic, ClearOpposite>
00569 {
00570 typedef typename Derived1::Index Index;
00571 static inline void run(Derived1 &dst, const Derived2 &src)
00572 {
00573 for(Index j = 0; j < dst.cols(); ++j)
00574 {
00575 Index maxi = (std::min)(j, dst.rows());
00576 for(Index i = maxi+1; i < dst.rows(); ++i)
00577 dst.copyCoeff(i, j, src);
00578 if (ClearOpposite)
00579 {
00580 for(Index i = 0; i < maxi; ++i)
00581 dst.coeffRef(i, j) = 0;
00582 }
00583 }
00584 dst.diagonal().setOnes();
00585 }
00586 };
00587
00588 }
00589
00590
00591 template<typename MatrixType, unsigned int Mode>
00592 template<typename OtherDerived>
00593 inline TriangularView<MatrixType, Mode>&
00594 TriangularView<MatrixType, Mode>::operator=(const MatrixBase<OtherDerived>& other)
00595 {
00596 if(OtherDerived::Flags & EvalBeforeAssigningBit)
00597 {
00598 typename internal::plain_matrix_type<OtherDerived>::type other_evaluated(other.rows(), other.cols());
00599 other_evaluated.template triangularView<Mode>().lazyAssign(other.derived());
00600 lazyAssign(other_evaluated);
00601 }
00602 else
00603 lazyAssign(other.derived());
00604 return *this;
00605 }
00606
00607
00608 template<typename MatrixType, unsigned int Mode>
00609 template<typename OtherDerived>
00610 void TriangularView<MatrixType, Mode>::lazyAssign(const MatrixBase<OtherDerived>& other)
00611 {
00612 enum {
00613 unroll = MatrixType::SizeAtCompileTime != Dynamic
00614 && internal::traits<OtherDerived>::CoeffReadCost != Dynamic
00615 && MatrixType::SizeAtCompileTime*internal::traits<OtherDerived>::CoeffReadCost/2 <= EIGEN_UNROLLING_LIMIT
00616 };
00617 eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols());
00618
00619 internal::triangular_assignment_selector
00620 <MatrixType, OtherDerived, int(Mode),
00621 unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic,
00622 false
00623 >::run(m_matrix.const_cast_derived(), other.derived());
00624 }
00625
00626
00627
00628 template<typename MatrixType, unsigned int Mode>
00629 template<typename OtherDerived>
00630 inline TriangularView<MatrixType, Mode>&
00631 TriangularView<MatrixType, Mode>::operator=(const TriangularBase<OtherDerived>& other)
00632 {
00633 eigen_assert(Mode == int(OtherDerived::Mode));
00634 if(internal::traits<OtherDerived>::Flags & EvalBeforeAssigningBit)
00635 {
00636 typename OtherDerived::DenseMatrixType other_evaluated(other.rows(), other.cols());
00637 other_evaluated.template triangularView<Mode>().lazyAssign(other.derived().nestedExpression());
00638 lazyAssign(other_evaluated);
00639 }
00640 else
00641 lazyAssign(other.derived().nestedExpression());
00642 return *this;
00643 }
00644
00645 template<typename MatrixType, unsigned int Mode>
00646 template<typename OtherDerived>
00647 void TriangularView<MatrixType, Mode>::lazyAssign(const TriangularBase<OtherDerived>& other)
00648 {
00649 enum {
00650 unroll = MatrixType::SizeAtCompileTime != Dynamic
00651 && internal::traits<OtherDerived>::CoeffReadCost != Dynamic
00652 && MatrixType::SizeAtCompileTime * internal::traits<OtherDerived>::CoeffReadCost / 2
00653 <= EIGEN_UNROLLING_LIMIT
00654 };
00655 eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols());
00656
00657 internal::triangular_assignment_selector
00658 <MatrixType, OtherDerived, int(Mode),
00659 unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic,
00660 false
00661 >::run(m_matrix.const_cast_derived(), other.derived().nestedExpression());
00662 }
00663
00664
00665
00666
00667
00670 template<typename Derived>
00671 template<typename DenseDerived>
00672 void TriangularBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
00673 {
00674 if(internal::traits<Derived>::Flags & EvalBeforeAssigningBit)
00675 {
00676 typename internal::plain_matrix_type<Derived>::type other_evaluated(rows(), cols());
00677 evalToLazy(other_evaluated);
00678 other.derived().swap(other_evaluated);
00679 }
00680 else
00681 evalToLazy(other.derived());
00682 }
00683
00686 template<typename Derived>
00687 template<typename DenseDerived>
00688 void TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDerived> &other) const
00689 {
00690 enum {
00691 unroll = DenseDerived::SizeAtCompileTime != Dynamic
00692 && internal::traits<Derived>::CoeffReadCost != Dynamic
00693 && DenseDerived::SizeAtCompileTime * internal::traits<Derived>::CoeffReadCost / 2
00694 <= EIGEN_UNROLLING_LIMIT
00695 };
00696 other.derived().resize(this->rows(), this->cols());
00697
00698 internal::triangular_assignment_selector
00699 <DenseDerived, typename internal::traits<Derived>::MatrixTypeNestedCleaned, Derived::Mode,
00700 unroll ? int(DenseDerived::SizeAtCompileTime) : Dynamic,
00701 true
00702 >::run(other.derived(), derived().nestedExpression());
00703 }
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713 #ifdef EIGEN2_SUPPORT
00714
00715
00716
00717 namespace internal {
00718 template<typename MatrixType, unsigned int Mode>
00719 struct eigen2_part_return_type
00720 {
00721 typedef TriangularView<MatrixType, Mode> type;
00722 };
00723
00724 template<typename MatrixType>
00725 struct eigen2_part_return_type<MatrixType, SelfAdjoint>
00726 {
00727 typedef SelfAdjointView<MatrixType, Upper> type;
00728 };
00729 }
00730
00732 template<typename Derived>
00733 template<unsigned int Mode>
00734 const typename internal::eigen2_part_return_type<Derived, Mode>::type MatrixBase<Derived>::part() const
00735 {
00736 return derived();
00737 }
00738
00740 template<typename Derived>
00741 template<unsigned int Mode>
00742 typename internal::eigen2_part_return_type<Derived, Mode>::type MatrixBase<Derived>::part()
00743 {
00744 return derived();
00745 }
00746 #endif
00747
00759 template<typename Derived>
00760 template<unsigned int Mode>
00761 typename MatrixBase<Derived>::template TriangularViewReturnType<Mode>::Type
00762 MatrixBase<Derived>::triangularView()
00763 {
00764 return derived();
00765 }
00766
00768 template<typename Derived>
00769 template<unsigned int Mode>
00770 typename MatrixBase<Derived>::template ConstTriangularViewReturnType<Mode>::Type
00771 MatrixBase<Derived>::triangularView() const
00772 {
00773 return derived();
00774 }
00775
00781 template<typename Derived>
00782 bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const
00783 {
00784 RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1);
00785 for(Index j = 0; j < cols(); ++j)
00786 {
00787 Index maxi = (std::min)(j, rows()-1);
00788 for(Index i = 0; i <= maxi; ++i)
00789 {
00790 RealScalar absValue = internal::abs(coeff(i,j));
00791 if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
00792 }
00793 }
00794 RealScalar threshold = maxAbsOnUpperPart * prec;
00795 for(Index j = 0; j < cols(); ++j)
00796 for(Index i = j+1; i < rows(); ++i)
00797 if(internal::abs(coeff(i, j)) > threshold) return false;
00798 return true;
00799 }
00800
00806 template<typename Derived>
00807 bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const
00808 {
00809 RealScalar maxAbsOnLowerPart = static_cast<RealScalar>(-1);
00810 for(Index j = 0; j < cols(); ++j)
00811 for(Index i = j; i < rows(); ++i)
00812 {
00813 RealScalar absValue = internal::abs(coeff(i,j));
00814 if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
00815 }
00816 RealScalar threshold = maxAbsOnLowerPart * prec;
00817 for(Index j = 1; j < cols(); ++j)
00818 {
00819 Index maxi = (std::min)(j, rows()-1);
00820 for(Index i = 0; i < maxi; ++i)
00821 if(internal::abs(coeff(i, j)) > threshold) return false;
00822 }
00823 return true;
00824 }
00825
00826 }
00827
00828 #endif // EIGEN_TRIANGULARMATRIX_H