SparseMatrixBase.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-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 //
00006 // This Source Code Form is subject to the terms of the Mozilla
00007 // Public License v. 2.0. If a copy of the MPL was not distributed
00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
00009 
00010 #ifndef EIGEN_SPARSEMATRIXBASE_H
00011 #define EIGEN_SPARSEMATRIXBASE_H
00012 
00013 namespace Eigen { 
00014 
00026 template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
00027 {
00028   public:
00029 
00030     typedef typename internal::traits<Derived>::Scalar Scalar;
00031     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00032     typedef typename internal::traits<Derived>::StorageKind StorageKind;
00033     typedef typename internal::traits<Derived>::Index Index;
00034     typedef typename internal::add_const_on_value_type_if_arithmetic<
00035                          typename internal::packet_traits<Scalar>::type
00036                      >::type PacketReturnType;
00037 
00038     typedef SparseMatrixBase StorageBaseType;
00039     typedef EigenBase<Derived> Base;
00040     
00041     template<typename OtherDerived>
00042     Derived& operator=(const EigenBase<OtherDerived> &other)
00043     {
00044       other.derived().evalTo(derived());
00045       return derived();
00046     }
00047 
00048     enum {
00049 
00050       RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
00056       ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
00063       SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
00064                                                    internal::traits<Derived>::ColsAtCompileTime>::ret),
00069       MaxRowsAtCompileTime = RowsAtCompileTime,
00070       MaxColsAtCompileTime = ColsAtCompileTime,
00071 
00072       MaxSizeAtCompileTime = (internal::size_at_compile_time<MaxRowsAtCompileTime,
00073                                                       MaxColsAtCompileTime>::ret),
00074 
00075       IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1,
00081       Flags = internal::traits<Derived>::Flags,
00086       CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
00091       IsRowMajor = Flags&RowMajorBit ? 1 : 0,
00092 
00093       #ifndef EIGEN_PARSED_BY_DOXYGEN
00094       _HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0 // workaround sunCC
00095       #endif
00096     };
00097 
00099     typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
00100                         CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, Eigen::Transpose<const Derived> >,
00101                         Transpose<const Derived>
00102                      >::type AdjointReturnType;
00103 
00104 
00105     typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor> PlainObject;
00106 
00107 
00108 #ifndef EIGEN_PARSED_BY_DOXYGEN
00109 
00115     typedef typename NumTraits<Scalar>::Real RealScalar;
00116 
00119     typedef typename internal::conditional<_HasDirectAccess, const Scalar&, Scalar>::type CoeffReturnType;
00120 
00122     typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Matrix<Scalar,Dynamic,Dynamic> > ConstantReturnType;
00123 
00125     typedef Matrix<Scalar,EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime),
00126                           EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType;
00127 
00128     inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
00129     inline Derived& derived() { return *static_cast<Derived*>(this); }
00130     inline Derived& const_cast_derived() const
00131     { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); }
00132 #endif // not EIGEN_PARSED_BY_DOXYGEN
00133 
00134 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase
00135 #   include "../plugins/CommonCwiseUnaryOps.h"
00136 #   include "../plugins/CommonCwiseBinaryOps.h"
00137 #   include "../plugins/MatrixCwiseUnaryOps.h"
00138 #   include "../plugins/MatrixCwiseBinaryOps.h"
00139 #   ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN
00140 #     include EIGEN_SPARSEMATRIXBASE_PLUGIN
00141 #   endif
00142 #   undef EIGEN_CURRENT_STORAGE_BASE_CLASS
00143 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS
00144 
00145 
00147     inline Index rows() const { return derived().rows(); }
00149     inline Index cols() const { return derived().cols(); }
00152     inline Index size() const { return rows() * cols(); }
00155     inline Index nonZeros() const { return derived().nonZeros(); }
00160     inline bool isVector() const { return rows()==1 || cols()==1; }
00163     Index outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); }
00166     Index innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
00167 
00168     bool isRValue() const { return m_isRValue; }
00169     Derived& markAsRValue() { m_isRValue = true; return derived(); }
00170 
00171     SparseMatrixBase() : m_isRValue(false) { /* TODO check flags */ }
00172 
00173     
00174     template<typename OtherDerived>
00175     Derived& operator=(const ReturnByValue<OtherDerived>& other)
00176     {
00177       other.evalTo(derived());
00178       return derived();
00179     }
00180 
00181 
00182     template<typename OtherDerived>
00183     inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other)
00184     {
00185       return assign(other.derived());
00186     }
00187 
00188     inline Derived& operator=(const Derived& other)
00189     {
00190 //       if (other.isRValue())
00191 //         derived().swap(other.const_cast_derived());
00192 //       else
00193       return assign(other.derived());
00194     }
00195 
00196   protected:
00197 
00198     template<typename OtherDerived>
00199     inline Derived& assign(const OtherDerived& other)
00200     {
00201       const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
00202       const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols();
00203       if ((!transpose) && other.isRValue())
00204       {
00205         // eval without temporary
00206         derived().resize(other.rows(), other.cols());
00207         derived().setZero();
00208         derived().reserve((std::max)(this->rows(),this->cols())*2);
00209         for (Index j=0; j<outerSize; ++j)
00210         {
00211           derived().startVec(j);
00212           for (typename OtherDerived::InnerIterator it(other, j); it; ++it)
00213           {
00214             Scalar v = it.value();
00215             derived().insertBackByOuterInner(j,it.index()) = v;
00216           }
00217         }
00218         derived().finalize();
00219       }
00220       else
00221       {
00222         assignGeneric(other);
00223       }
00224       return derived();
00225     }
00226 
00227     template<typename OtherDerived>
00228     inline void assignGeneric(const OtherDerived& other)
00229     {
00230       //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
00231       eigen_assert(( ((internal::traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) ||
00232                   (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) &&
00233                   "the transpose operation is supposed to be handled in SparseMatrix::operator=");
00234 
00235       enum { Flip = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit) };
00236 
00237       const Index outerSize = other.outerSize();
00238       //typedef typename internal::conditional<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::type TempType;
00239       // thanks to shallow copies, we always eval to a tempary
00240       Derived temp(other.rows(), other.cols());
00241 
00242       temp.reserve((std::max)(this->rows(),this->cols())*2);
00243       for (Index j=0; j<outerSize; ++j)
00244       {
00245         temp.startVec(j);
00246         for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it)
00247         {
00248           Scalar v = it.value();
00249           temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v;
00250         }
00251       }
00252       temp.finalize();
00253 
00254       derived() = temp.markAsRValue();
00255     }
00256 
00257   public:
00258 
00259     template<typename Lhs, typename Rhs>
00260     inline Derived& operator=(const SparseSparseProduct<Lhs,Rhs>& product);
00261 
00262     friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m)
00263     {
00264       typedef typename Derived::Nested Nested;
00265       typedef typename internal::remove_all<Nested>::type NestedCleaned;
00266 
00267       if (Flags&RowMajorBit)
00268       {
00269         const Nested nm(m.derived());
00270         for (Index row=0; row<nm.outerSize(); ++row)
00271         {
00272           Index col = 0;
00273           for (typename NestedCleaned::InnerIterator it(nm.derived(), row); it; ++it)
00274           {
00275             for ( ; col<it.index(); ++col)
00276               s << "0 ";
00277             s << it.value() << " ";
00278             ++col;
00279           }
00280           for ( ; col<m.cols(); ++col)
00281             s << "0 ";
00282           s << std::endl;
00283         }
00284       }
00285       else
00286       {
00287         const Nested nm(m.derived());
00288         if (m.cols() == 1) {
00289           Index row = 0;
00290           for (typename NestedCleaned::InnerIterator it(nm.derived(), 0); it; ++it)
00291           {
00292             for ( ; row<it.index(); ++row)
00293               s << "0" << std::endl;
00294             s << it.value() << std::endl;
00295             ++row;
00296           }
00297           for ( ; row<m.rows(); ++row)
00298             s << "0" << std::endl;
00299         }
00300         else
00301         {
00302           SparseMatrix<Scalar, RowMajorBit> trans = m;
00303           s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit> >&>(trans);
00304         }
00305       }
00306       return s;
00307     }
00308 
00309     template<typename OtherDerived>
00310     Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
00311     template<typename OtherDerived>
00312     Derived& operator-=(const SparseMatrixBase<OtherDerived>& other);
00313 
00314     Derived& operator*=(const Scalar& other);
00315     Derived& operator/=(const Scalar& other);
00316 
00317     #define EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE \
00318       CwiseBinaryOp< \
00319         internal::scalar_product_op< \
00320           typename internal::scalar_product_traits< \
00321             typename internal::traits<Derived>::Scalar, \
00322             typename internal::traits<OtherDerived>::Scalar \
00323           >::ReturnType \
00324         >, \
00325         Derived, \
00326         OtherDerived \
00327       >
00328 
00329     template<typename OtherDerived>
00330     EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
00331     cwiseProduct(const MatrixBase<OtherDerived> &other) const;
00332 
00333     // sparse * sparse
00334     template<typename OtherDerived>
00335     const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type
00336     operator*(const SparseMatrixBase<OtherDerived> &other) const;
00337 
00338     // sparse * diagonal
00339     template<typename OtherDerived>
00340     const SparseDiagonalProduct<Derived,OtherDerived>
00341     operator*(const DiagonalBase<OtherDerived> &other) const;
00342 
00343     // diagonal * sparse
00344     template<typename OtherDerived> friend
00345     const SparseDiagonalProduct<OtherDerived,Derived>
00346     operator*(const DiagonalBase<OtherDerived> &lhs, const SparseMatrixBase& rhs)
00347     { return SparseDiagonalProduct<OtherDerived,Derived>(lhs.derived(), rhs.derived()); }
00348 
00350     template<typename OtherDerived> friend
00351     const typename DenseSparseProductReturnType<OtherDerived,Derived>::Type
00352     operator*(const MatrixBase<OtherDerived>& lhs, const Derived& rhs)
00353     { return typename DenseSparseProductReturnType<OtherDerived,Derived>::Type(lhs.derived(),rhs); }
00354 
00356     template<typename OtherDerived>
00357     const typename SparseDenseProductReturnType<Derived,OtherDerived>::Type
00358     operator*(const MatrixBase<OtherDerived> &other) const;
00359     
00361     SparseSymmetricPermutationProduct<Derived,Upper|Lower> twistedBy(const PermutationMatrix<Dynamic,Dynamic,Index>& perm) const
00362     {
00363       return SparseSymmetricPermutationProduct<Derived,Upper|Lower>(derived(), perm);
00364     }
00365 
00366     template<typename OtherDerived>
00367     Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);
00368 
00369     #ifdef EIGEN2_SUPPORT
00370     // deprecated
00371     template<typename OtherDerived>
00372     typename internal::plain_matrix_type_column_major<OtherDerived>::type
00373     solveTriangular(const MatrixBase<OtherDerived>& other) const;
00374 
00375     // deprecated
00376     template<typename OtherDerived>
00377     void solveTriangularInPlace(MatrixBase<OtherDerived>& other) const;
00378     #endif // EIGEN2_SUPPORT
00379 
00380     template<int Mode>
00381     inline const SparseTriangularView<Derived, Mode> triangularView() const;
00382 
00383     template<unsigned int UpLo> inline const SparseSelfAdjointView<Derived, UpLo> selfadjointView() const;
00384     template<unsigned int UpLo> inline SparseSelfAdjointView<Derived, UpLo> selfadjointView();
00385 
00386     template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const;
00387     template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
00388     RealScalar squaredNorm() const;
00389     RealScalar norm()  const;
00390 
00391     Transpose<Derived> transpose() { return derived(); }
00392     const Transpose<const Derived> transpose() const { return derived(); }
00393     const AdjointReturnType adjoint() const { return transpose(); }
00394 
00395     // sub-vector
00396     SparseInnerVectorSet<Derived,1> row(Index i);
00397     const SparseInnerVectorSet<Derived,1> row(Index i) const;
00398     SparseInnerVectorSet<Derived,1> col(Index j);
00399     const SparseInnerVectorSet<Derived,1> col(Index j) const;
00400     SparseInnerVectorSet<Derived,1> innerVector(Index outer);
00401     const SparseInnerVectorSet<Derived,1> innerVector(Index outer) const;
00402 
00403     // set of sub-vectors
00404     SparseInnerVectorSet<Derived,Dynamic> subrows(Index start, Index size);
00405     const SparseInnerVectorSet<Derived,Dynamic> subrows(Index start, Index size) const;
00406     SparseInnerVectorSet<Derived,Dynamic> subcols(Index start, Index size);
00407     const SparseInnerVectorSet<Derived,Dynamic> subcols(Index start, Index size) const;
00408     
00409     SparseInnerVectorSet<Derived,Dynamic> middleRows(Index start, Index size);
00410     const SparseInnerVectorSet<Derived,Dynamic> middleRows(Index start, Index size) const;
00411     SparseInnerVectorSet<Derived,Dynamic> middleCols(Index start, Index size);
00412     const SparseInnerVectorSet<Derived,Dynamic> middleCols(Index start, Index size) const;
00413     SparseInnerVectorSet<Derived,Dynamic> innerVectors(Index outerStart, Index outerSize);
00414     const SparseInnerVectorSet<Derived,Dynamic> innerVectors(Index outerStart, Index outerSize) const;
00415 
00417       template<typename DenseDerived>
00418       void evalTo(MatrixBase<DenseDerived>& dst) const
00419       {
00420         dst.setZero();
00421         for (Index j=0; j<outerSize(); ++j)
00422           for (typename Derived::InnerIterator i(derived(),j); i; ++i)
00423             dst.coeffRef(i.row(),i.col()) = i.value();
00424       }
00425 
00426       Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const
00427       {
00428         return derived();
00429       }
00430 
00431     template<typename OtherDerived>
00432     bool isApprox(const SparseMatrixBase<OtherDerived>& other,
00433                   RealScalar prec = NumTraits<Scalar>::dummy_precision()) const
00434     { return toDense().isApprox(other.toDense(),prec); }
00435 
00436     template<typename OtherDerived>
00437     bool isApprox(const MatrixBase<OtherDerived>& other,
00438                   RealScalar prec = NumTraits<Scalar>::dummy_precision()) const
00439     { return toDense().isApprox(other,prec); }
00440 
00446     inline const typename internal::eval<Derived>::type eval() const
00447     { return typename internal::eval<Derived>::type(derived()); }
00448 
00449     Scalar sum() const;
00450 
00451   protected:
00452 
00453     bool m_isRValue;
00454 };
00455 
00456 } // end namespace Eigen
00457 
00458 #endif // EIGEN_SPARSEMATRIXBASE_H


win_eigen
Author(s): Daniel Stonier
autogenerated on Mon Oct 6 2014 12:26:17