TriangularMatrix.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
00005 // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
00006 //
00007 // This Source Code Form is subject to the terms of the Mozilla
00008 // Public License v. 2.0. If a copy of the MPL was not distributed
00009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
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     // TODO simplify the following:
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 * Implementation of triangular evaluation/assignment
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 // prevent buggy user code from causing an infinite recursion
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 } // end namespace internal
00589 
00590 // FIXME should we keep that possibility
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 // FIXME should we keep that possibility
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 // do not change the opposite triangular part
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 // preserve the opposite triangular part
00661     >::run(m_matrix.const_cast_derived(), other.derived().nestedExpression());
00662 }
00663 
00664 /***************************************************************************
00665 * Implementation of TriangularBase methods
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 // clear the opposite triangular part
00702     >::run(other.derived(), derived().nestedExpression());
00703 }
00704 
00705 /***************************************************************************
00706 * Implementation of TriangularView methods
00707 ***************************************************************************/
00708 
00709 /***************************************************************************
00710 * Implementation of MatrixBase methods
00711 ***************************************************************************/
00712 
00713 #ifdef EIGEN2_SUPPORT
00714 
00715 // implementation of part<>(), including the SelfAdjoint case.
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(const RealScalar& prec) const
00783 {
00784   using std::abs;
00785   RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1);
00786   for(Index j = 0; j < cols(); ++j)
00787   {
00788     Index maxi = (std::min)(j, rows()-1);
00789     for(Index i = 0; i <= maxi; ++i)
00790     {
00791       RealScalar absValue = abs(coeff(i,j));
00792       if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
00793     }
00794   }
00795   RealScalar threshold = maxAbsOnUpperPart * prec;
00796   for(Index j = 0; j < cols(); ++j)
00797     for(Index i = j+1; i < rows(); ++i)
00798       if(abs(coeff(i, j)) > threshold) return false;
00799   return true;
00800 }
00801 
00807 template<typename Derived>
00808 bool MatrixBase<Derived>::isLowerTriangular(const RealScalar& prec) const
00809 {
00810   using std::abs;
00811   RealScalar maxAbsOnLowerPart = static_cast<RealScalar>(-1);
00812   for(Index j = 0; j < cols(); ++j)
00813     for(Index i = j; i < rows(); ++i)
00814     {
00815       RealScalar absValue = abs(coeff(i,j));
00816       if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
00817     }
00818   RealScalar threshold = maxAbsOnLowerPart * prec;
00819   for(Index j = 1; j < cols(); ++j)
00820   {
00821     Index maxi = (std::min)(j, rows()-1);
00822     for(Index i = 0; i < maxi; ++i)
00823       if(abs(coeff(i, j)) > threshold) return false;
00824   }
00825   return true;
00826 }
00827 
00828 } // end namespace Eigen
00829 
00830 #endif // EIGEN_TRIANGULARMATRIX_H


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Thu Aug 27 2015 12:01:16