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::ColsAtCompileTime==1>
00282 operator*(const MatrixBase<OtherDerived>& rhs) const
00283 {
00284 return TriangularProduct
00285 <Mode, true, MatrixType, false, OtherDerived, OtherDerived::ColsAtCompileTime==1>
00286 (m_matrix, rhs.derived());
00287 }
00288
00290 template<typename OtherDerived> friend
00291 TriangularProduct<Mode, false, OtherDerived, OtherDerived::RowsAtCompileTime==1, MatrixType, false>
00292 operator*(const MatrixBase<OtherDerived>& lhs, const TriangularView& rhs)
00293 {
00294 return TriangularProduct
00295 <Mode, false, OtherDerived, OtherDerived::RowsAtCompileTime==1, 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.derived(),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.derived(),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.derived(),-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.derived(),other.alpha());
00404 }
00405
00406 template<typename ProductDerived>
00407 EIGEN_STRONG_INLINE TriangularView& operator+=(const ScaledProduct<ProductDerived>& other)
00408 {
00409 return assignProduct(other.derived(),other.alpha());
00410 }
00411
00412 template<typename ProductDerived>
00413 EIGEN_STRONG_INLINE TriangularView& operator-=(const ScaledProduct<ProductDerived>& other)
00414 {
00415 return assignProduct(other.derived(),-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 template<int Mode, bool LhsIsTriangular,
00424 typename Lhs, bool LhsIsVector,
00425 typename Rhs, bool RhsIsVector>
00426 EIGEN_STRONG_INLINE TriangularView& assignProduct(const TriangularProduct<Mode, LhsIsTriangular, Lhs, LhsIsVector, Rhs, RhsIsVector>& prod, const Scalar& alpha)
00427 {
00428 lazyAssign(alpha*prod.eval());
00429 return *this;
00430 }
00431
00432 MatrixTypeNested m_matrix;
00433 };
00434
00435
00436
00437
00438
00439 namespace internal {
00440
00441 template<typename Derived1, typename Derived2, unsigned int Mode, int UnrollCount, bool ClearOpposite>
00442 struct triangular_assignment_selector
00443 {
00444 enum {
00445 col = (UnrollCount-1) / Derived1::RowsAtCompileTime,
00446 row = (UnrollCount-1) % Derived1::RowsAtCompileTime
00447 };
00448
00449 typedef typename Derived1::Scalar Scalar;
00450
00451 static inline void run(Derived1 &dst, const Derived2 &src)
00452 {
00453 triangular_assignment_selector<Derived1, Derived2, Mode, UnrollCount-1, ClearOpposite>::run(dst, src);
00454
00455 eigen_assert( Mode == Upper || Mode == Lower
00456 || Mode == StrictlyUpper || Mode == StrictlyLower
00457 || Mode == UnitUpper || Mode == UnitLower);
00458 if((Mode == Upper && row <= col)
00459 || (Mode == Lower && row >= col)
00460 || (Mode == StrictlyUpper && row < col)
00461 || (Mode == StrictlyLower && row > col)
00462 || (Mode == UnitUpper && row < col)
00463 || (Mode == UnitLower && row > col))
00464 dst.copyCoeff(row, col, src);
00465 else if(ClearOpposite)
00466 {
00467 if (Mode&UnitDiag && row==col)
00468 dst.coeffRef(row, col) = Scalar(1);
00469 else
00470 dst.coeffRef(row, col) = Scalar(0);
00471 }
00472 }
00473 };
00474
00475
00476 template<typename Derived1, typename Derived2, unsigned int Mode, bool ClearOpposite>
00477 struct triangular_assignment_selector<Derived1, Derived2, Mode, 0, ClearOpposite>
00478 {
00479 static inline void run(Derived1 &, const Derived2 &) {}
00480 };
00481
00482 template<typename Derived1, typename Derived2, bool ClearOpposite>
00483 struct triangular_assignment_selector<Derived1, Derived2, Upper, Dynamic, ClearOpposite>
00484 {
00485 typedef typename Derived1::Index Index;
00486 typedef typename Derived1::Scalar Scalar;
00487 static inline void run(Derived1 &dst, const Derived2 &src)
00488 {
00489 for(Index j = 0; j < dst.cols(); ++j)
00490 {
00491 Index maxi = (std::min)(j, dst.rows()-1);
00492 for(Index i = 0; i <= maxi; ++i)
00493 dst.copyCoeff(i, j, src);
00494 if (ClearOpposite)
00495 for(Index i = maxi+1; i < dst.rows(); ++i)
00496 dst.coeffRef(i, j) = Scalar(0);
00497 }
00498 }
00499 };
00500
00501 template<typename Derived1, typename Derived2, bool ClearOpposite>
00502 struct triangular_assignment_selector<Derived1, Derived2, Lower, Dynamic, ClearOpposite>
00503 {
00504 typedef typename Derived1::Index Index;
00505 static inline void run(Derived1 &dst, const Derived2 &src)
00506 {
00507 for(Index j = 0; j < dst.cols(); ++j)
00508 {
00509 for(Index i = j; i < dst.rows(); ++i)
00510 dst.copyCoeff(i, j, src);
00511 Index maxi = (std::min)(j, dst.rows());
00512 if (ClearOpposite)
00513 for(Index i = 0; i < maxi; ++i)
00514 dst.coeffRef(i, j) = static_cast<typename Derived1::Scalar>(0);
00515 }
00516 }
00517 };
00518
00519 template<typename Derived1, typename Derived2, bool ClearOpposite>
00520 struct triangular_assignment_selector<Derived1, Derived2, StrictlyUpper, Dynamic, ClearOpposite>
00521 {
00522 typedef typename Derived1::Index Index;
00523 typedef typename Derived1::Scalar Scalar;
00524 static inline void run(Derived1 &dst, const Derived2 &src)
00525 {
00526 for(Index j = 0; j < dst.cols(); ++j)
00527 {
00528 Index maxi = (std::min)(j, dst.rows());
00529 for(Index i = 0; i < maxi; ++i)
00530 dst.copyCoeff(i, j, src);
00531 if (ClearOpposite)
00532 for(Index i = maxi; i < dst.rows(); ++i)
00533 dst.coeffRef(i, j) = Scalar(0);
00534 }
00535 }
00536 };
00537
00538 template<typename Derived1, typename Derived2, bool ClearOpposite>
00539 struct triangular_assignment_selector<Derived1, Derived2, StrictlyLower, Dynamic, ClearOpposite>
00540 {
00541 typedef typename Derived1::Index Index;
00542 static inline void run(Derived1 &dst, const Derived2 &src)
00543 {
00544 for(Index j = 0; j < dst.cols(); ++j)
00545 {
00546 for(Index i = j+1; i < dst.rows(); ++i)
00547 dst.copyCoeff(i, j, src);
00548 Index maxi = (std::min)(j, dst.rows()-1);
00549 if (ClearOpposite)
00550 for(Index i = 0; i <= maxi; ++i)
00551 dst.coeffRef(i, j) = static_cast<typename Derived1::Scalar>(0);
00552 }
00553 }
00554 };
00555
00556 template<typename Derived1, typename Derived2, bool ClearOpposite>
00557 struct triangular_assignment_selector<Derived1, Derived2, UnitUpper, Dynamic, ClearOpposite>
00558 {
00559 typedef typename Derived1::Index Index;
00560 static inline void run(Derived1 &dst, const Derived2 &src)
00561 {
00562 for(Index j = 0; j < dst.cols(); ++j)
00563 {
00564 Index maxi = (std::min)(j, dst.rows());
00565 for(Index i = 0; i < maxi; ++i)
00566 dst.copyCoeff(i, j, src);
00567 if (ClearOpposite)
00568 {
00569 for(Index i = maxi+1; i < dst.rows(); ++i)
00570 dst.coeffRef(i, j) = 0;
00571 }
00572 }
00573 dst.diagonal().setOnes();
00574 }
00575 };
00576 template<typename Derived1, typename Derived2, bool ClearOpposite>
00577 struct triangular_assignment_selector<Derived1, Derived2, UnitLower, Dynamic, ClearOpposite>
00578 {
00579 typedef typename Derived1::Index Index;
00580 static inline void run(Derived1 &dst, const Derived2 &src)
00581 {
00582 for(Index j = 0; j < dst.cols(); ++j)
00583 {
00584 Index maxi = (std::min)(j, dst.rows());
00585 for(Index i = maxi+1; i < dst.rows(); ++i)
00586 dst.copyCoeff(i, j, src);
00587 if (ClearOpposite)
00588 {
00589 for(Index i = 0; i < maxi; ++i)
00590 dst.coeffRef(i, j) = 0;
00591 }
00592 }
00593 dst.diagonal().setOnes();
00594 }
00595 };
00596
00597 }
00598
00599
00600 template<typename MatrixType, unsigned int Mode>
00601 template<typename OtherDerived>
00602 inline TriangularView<MatrixType, Mode>&
00603 TriangularView<MatrixType, Mode>::operator=(const MatrixBase<OtherDerived>& other)
00604 {
00605 if(OtherDerived::Flags & EvalBeforeAssigningBit)
00606 {
00607 typename internal::plain_matrix_type<OtherDerived>::type other_evaluated(other.rows(), other.cols());
00608 other_evaluated.template triangularView<Mode>().lazyAssign(other.derived());
00609 lazyAssign(other_evaluated);
00610 }
00611 else
00612 lazyAssign(other.derived());
00613 return *this;
00614 }
00615
00616
00617 template<typename MatrixType, unsigned int Mode>
00618 template<typename OtherDerived>
00619 void TriangularView<MatrixType, Mode>::lazyAssign(const MatrixBase<OtherDerived>& other)
00620 {
00621 enum {
00622 unroll = MatrixType::SizeAtCompileTime != Dynamic
00623 && internal::traits<OtherDerived>::CoeffReadCost != Dynamic
00624 && MatrixType::SizeAtCompileTime*internal::traits<OtherDerived>::CoeffReadCost/2 <= EIGEN_UNROLLING_LIMIT
00625 };
00626 eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols());
00627
00628 internal::triangular_assignment_selector
00629 <MatrixType, OtherDerived, int(Mode),
00630 unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic,
00631 false
00632 >::run(m_matrix.const_cast_derived(), other.derived());
00633 }
00634
00635
00636
00637 template<typename MatrixType, unsigned int Mode>
00638 template<typename OtherDerived>
00639 inline TriangularView<MatrixType, Mode>&
00640 TriangularView<MatrixType, Mode>::operator=(const TriangularBase<OtherDerived>& other)
00641 {
00642 eigen_assert(Mode == int(OtherDerived::Mode));
00643 if(internal::traits<OtherDerived>::Flags & EvalBeforeAssigningBit)
00644 {
00645 typename OtherDerived::DenseMatrixType other_evaluated(other.rows(), other.cols());
00646 other_evaluated.template triangularView<Mode>().lazyAssign(other.derived().nestedExpression());
00647 lazyAssign(other_evaluated);
00648 }
00649 else
00650 lazyAssign(other.derived().nestedExpression());
00651 return *this;
00652 }
00653
00654 template<typename MatrixType, unsigned int Mode>
00655 template<typename OtherDerived>
00656 void TriangularView<MatrixType, Mode>::lazyAssign(const TriangularBase<OtherDerived>& other)
00657 {
00658 enum {
00659 unroll = MatrixType::SizeAtCompileTime != Dynamic
00660 && internal::traits<OtherDerived>::CoeffReadCost != Dynamic
00661 && MatrixType::SizeAtCompileTime * internal::traits<OtherDerived>::CoeffReadCost / 2
00662 <= EIGEN_UNROLLING_LIMIT
00663 };
00664 eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols());
00665
00666 internal::triangular_assignment_selector
00667 <MatrixType, OtherDerived, int(Mode),
00668 unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic,
00669 false
00670 >::run(m_matrix.const_cast_derived(), other.derived().nestedExpression());
00671 }
00672
00673
00674
00675
00676
00679 template<typename Derived>
00680 template<typename DenseDerived>
00681 void TriangularBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
00682 {
00683 if(internal::traits<Derived>::Flags & EvalBeforeAssigningBit)
00684 {
00685 typename internal::plain_matrix_type<Derived>::type other_evaluated(rows(), cols());
00686 evalToLazy(other_evaluated);
00687 other.derived().swap(other_evaluated);
00688 }
00689 else
00690 evalToLazy(other.derived());
00691 }
00692
00695 template<typename Derived>
00696 template<typename DenseDerived>
00697 void TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDerived> &other) const
00698 {
00699 enum {
00700 unroll = DenseDerived::SizeAtCompileTime != Dynamic
00701 && internal::traits<Derived>::CoeffReadCost != Dynamic
00702 && DenseDerived::SizeAtCompileTime * internal::traits<Derived>::CoeffReadCost / 2
00703 <= EIGEN_UNROLLING_LIMIT
00704 };
00705 other.derived().resize(this->rows(), this->cols());
00706
00707 internal::triangular_assignment_selector
00708 <DenseDerived, typename internal::traits<Derived>::MatrixTypeNestedCleaned, Derived::Mode,
00709 unroll ? int(DenseDerived::SizeAtCompileTime) : Dynamic,
00710 true
00711 >::run(other.derived(), derived().nestedExpression());
00712 }
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722 #ifdef EIGEN2_SUPPORT
00723
00724
00725
00726 namespace internal {
00727 template<typename MatrixType, unsigned int Mode>
00728 struct eigen2_part_return_type
00729 {
00730 typedef TriangularView<MatrixType, Mode> type;
00731 };
00732
00733 template<typename MatrixType>
00734 struct eigen2_part_return_type<MatrixType, SelfAdjoint>
00735 {
00736 typedef SelfAdjointView<MatrixType, Upper> type;
00737 };
00738 }
00739
00741 template<typename Derived>
00742 template<unsigned int Mode>
00743 const typename internal::eigen2_part_return_type<Derived, Mode>::type MatrixBase<Derived>::part() const
00744 {
00745 return derived();
00746 }
00747
00749 template<typename Derived>
00750 template<unsigned int Mode>
00751 typename internal::eigen2_part_return_type<Derived, Mode>::type MatrixBase<Derived>::part()
00752 {
00753 return derived();
00754 }
00755 #endif
00756
00768 template<typename Derived>
00769 template<unsigned int Mode>
00770 typename MatrixBase<Derived>::template TriangularViewReturnType<Mode>::Type
00771 MatrixBase<Derived>::triangularView()
00772 {
00773 return derived();
00774 }
00775
00777 template<typename Derived>
00778 template<unsigned int Mode>
00779 typename MatrixBase<Derived>::template ConstTriangularViewReturnType<Mode>::Type
00780 MatrixBase<Derived>::triangularView() const
00781 {
00782 return derived();
00783 }
00784
00790 template<typename Derived>
00791 bool MatrixBase<Derived>::isUpperTriangular(const RealScalar& prec) const
00792 {
00793 using std::abs;
00794 RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1);
00795 for(Index j = 0; j < cols(); ++j)
00796 {
00797 Index maxi = (std::min)(j, rows()-1);
00798 for(Index i = 0; i <= maxi; ++i)
00799 {
00800 RealScalar absValue = abs(coeff(i,j));
00801 if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
00802 }
00803 }
00804 RealScalar threshold = maxAbsOnUpperPart * prec;
00805 for(Index j = 0; j < cols(); ++j)
00806 for(Index i = j+1; i < rows(); ++i)
00807 if(abs(coeff(i, j)) > threshold) return false;
00808 return true;
00809 }
00810
00816 template<typename Derived>
00817 bool MatrixBase<Derived>::isLowerTriangular(const RealScalar& prec) const
00818 {
00819 using std::abs;
00820 RealScalar maxAbsOnLowerPart = static_cast<RealScalar>(-1);
00821 for(Index j = 0; j < cols(); ++j)
00822 for(Index i = j; i < rows(); ++i)
00823 {
00824 RealScalar absValue = abs(coeff(i,j));
00825 if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
00826 }
00827 RealScalar threshold = maxAbsOnLowerPart * prec;
00828 for(Index j = 1; j < cols(); ++j)
00829 {
00830 Index maxi = (std::min)(j, rows()-1);
00831 for(Index i = 0; i < maxi; ++i)
00832 if(abs(coeff(i, j)) > threshold) return false;
00833 }
00834 return true;
00835 }
00836
00837 }
00838
00839 #endif // EIGEN_TRIANGULARMATRIX_H