Eigen  3.2.8
SparseMatrixBase.h
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
00027 #ifndef EIGEN_PARSED_BY_DOXYGEN
00028   : public internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
00029                                             typename NumTraits<typename internal::traits<Derived>::Scalar>::Real,
00030                                             EigenBase<Derived> >
00031 #else
00032   : public EigenBase<Derived>
00033 #endif // not EIGEN_PARSED_BY_DOXYGEN
00034 {
00035   public:
00036 
00037     typedef typename internal::traits<Derived>::Scalar Scalar;
00038     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00039     typedef typename internal::traits<Derived>::StorageKind StorageKind;
00040     typedef typename internal::traits<Derived>::Index Index;
00041     typedef typename internal::add_const_on_value_type_if_arithmetic<
00042                          typename internal::packet_traits<Scalar>::type
00043                      >::type PacketReturnType;
00044 
00045     typedef SparseMatrixBase StorageBaseType;
00046     
00047     template<typename OtherDerived>
00048     Derived& operator=(const EigenBase<OtherDerived> &other)
00049     {
00050       other.derived().evalTo(derived());
00051       return derived();
00052     }
00053 
00054     enum {
00055 
00056       RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
00062       ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
00069       SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
00070                                                    internal::traits<Derived>::ColsAtCompileTime>::ret),
00075       MaxRowsAtCompileTime = RowsAtCompileTime,
00076       MaxColsAtCompileTime = ColsAtCompileTime,
00077 
00078       MaxSizeAtCompileTime = (internal::size_at_compile_time<MaxRowsAtCompileTime,
00079                                                       MaxColsAtCompileTime>::ret),
00080 
00081       IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1,
00087       Flags = internal::traits<Derived>::Flags,
00092       CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
00097       IsRowMajor = Flags&RowMajorBit ? 1 : 0,
00098       
00099       InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
00100                              : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
00101 
00102       #ifndef EIGEN_PARSED_BY_DOXYGEN
00103       _HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0 // workaround sunCC
00104       #endif
00105     };
00106 
00108     typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
00109                         CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, Eigen::Transpose<const Derived> >,
00110                         Transpose<const Derived>
00111                      >::type AdjointReturnType;
00112 
00113 
00114     typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor, Index> PlainObject;
00115 
00116 
00117 #ifndef EIGEN_PARSED_BY_DOXYGEN
00118 
00124     typedef typename NumTraits<Scalar>::Real RealScalar;
00125 
00128     typedef typename internal::conditional<_HasDirectAccess, const Scalar&, Scalar>::type CoeffReturnType;
00129 
00131     typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Matrix<Scalar,Dynamic,Dynamic> > ConstantReturnType;
00132 
00134     typedef Matrix<Scalar,EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime),
00135                           EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType;
00136 
00137     inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
00138     inline Derived& derived() { return *static_cast<Derived*>(this); }
00139     inline Derived& const_cast_derived() const
00140     { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); }
00141 
00142     typedef internal::special_scalar_op_base<Derived, Scalar, RealScalar, EigenBase<Derived> > Base;
00143     using Base::operator*;
00144 #endif // not EIGEN_PARSED_BY_DOXYGEN
00145 
00146 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase
00147 #   include "../plugins/CommonCwiseUnaryOps.h"
00148 #   include "../plugins/CommonCwiseBinaryOps.h"
00149 #   include "../plugins/MatrixCwiseUnaryOps.h"
00150 #   include "../plugins/MatrixCwiseBinaryOps.h"
00151 #   include "../plugins/BlockMethods.h"
00152 #   ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN
00153 #     include EIGEN_SPARSEMATRIXBASE_PLUGIN
00154 #   endif
00155 #   undef EIGEN_CURRENT_STORAGE_BASE_CLASS
00156 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS
00157 
00159     inline Index rows() const { return derived().rows(); }
00161     inline Index cols() const { return derived().cols(); }
00164     inline Index size() const { return rows() * cols(); }
00167     inline Index nonZeros() const { return derived().nonZeros(); }
00172     inline bool isVector() const { return rows()==1 || cols()==1; }
00175     Index outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); }
00178     Index innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
00179 
00180     bool isRValue() const { return m_isRValue; }
00181     Derived& markAsRValue() { m_isRValue = true; return derived(); }
00182 
00183     SparseMatrixBase() : m_isRValue(false) { /* TODO check flags */ }
00184 
00185     
00186     template<typename OtherDerived>
00187     Derived& operator=(const ReturnByValue<OtherDerived>& other)
00188     {
00189       other.evalTo(derived());
00190       return derived();
00191     }
00192 
00193 
00194     template<typename OtherDerived>
00195     inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other)
00196     {
00197       return assign(other.derived());
00198     }
00199 
00200     inline Derived& operator=(const Derived& other)
00201     {
00202 //       if (other.isRValue())
00203 //         derived().swap(other.const_cast_derived());
00204 //       else
00205       return assign(other.derived());
00206     }
00207 
00208   protected:
00209 
00210     template<typename OtherDerived>
00211     inline Derived& assign(const OtherDerived& other)
00212     {
00213       const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
00214       const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols();
00215       if ((!transpose) && other.isRValue())
00216       {
00217         // eval without temporary
00218         derived().resize(other.rows(), other.cols());
00219         derived().setZero();
00220         derived().reserve((std::max)(this->rows(),this->cols())*2);
00221         for (Index j=0; j<outerSize; ++j)
00222         {
00223           derived().startVec(j);
00224           for (typename OtherDerived::InnerIterator it(other, j); it; ++it)
00225           {
00226             Scalar v = it.value();
00227             derived().insertBackByOuterInner(j,it.index()) = v;
00228           }
00229         }
00230         derived().finalize();
00231       }
00232       else
00233       {
00234         assignGeneric(other);
00235       }
00236       return derived();
00237     }
00238 
00239     template<typename OtherDerived>
00240     inline void assignGeneric(const OtherDerived& other)
00241     {
00242       //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
00243       eigen_assert(( ((internal::traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) ||
00244                   (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) &&
00245                   "the transpose operation is supposed to be handled in SparseMatrix::operator=");
00246 
00247       enum { Flip = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit) };
00248 
00249       const Index outerSize = other.outerSize();
00250       //typedef typename internal::conditional<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::type TempType;
00251       // thanks to shallow copies, we always eval to a tempary
00252       Derived temp(other.rows(), other.cols());
00253 
00254       temp.reserve((std::max)(this->rows(),this->cols())*2);
00255       for (Index j=0; j<outerSize; ++j)
00256       {
00257         temp.startVec(j);
00258         for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it)
00259         {
00260           Scalar v = it.value();
00261           temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v;
00262         }
00263       }
00264       temp.finalize();
00265 
00266       derived() = temp.markAsRValue();
00267     }
00268 
00269   public:
00270 
00271     template<typename Lhs, typename Rhs>
00272     inline Derived& operator=(const SparseSparseProduct<Lhs,Rhs>& product);
00273 
00274     friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m)
00275     {
00276       typedef typename Derived::Nested Nested;
00277       typedef typename internal::remove_all<Nested>::type NestedCleaned;
00278 
00279       if (Flags&RowMajorBit)
00280       {
00281         const Nested nm(m.derived());
00282         for (Index row=0; row<nm.outerSize(); ++row)
00283         {
00284           Index col = 0;
00285           for (typename NestedCleaned::InnerIterator it(nm.derived(), row); it; ++it)
00286           {
00287             for ( ; col<it.index(); ++col)
00288               s << "0 ";
00289             s << it.value() << " ";
00290             ++col;
00291           }
00292           for ( ; col<m.cols(); ++col)
00293             s << "0 ";
00294           s << std::endl;
00295         }
00296       }
00297       else
00298       {
00299         const Nested nm(m.derived());
00300         if (m.cols() == 1) {
00301           Index row = 0;
00302           for (typename NestedCleaned::InnerIterator it(nm.derived(), 0); it; ++it)
00303           {
00304             for ( ; row<it.index(); ++row)
00305               s << "0" << std::endl;
00306             s << it.value() << std::endl;
00307             ++row;
00308           }
00309           for ( ; row<m.rows(); ++row)
00310             s << "0" << std::endl;
00311         }
00312         else
00313         {
00314           SparseMatrix<Scalar, RowMajorBit, Index> trans = m;
00315           s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit, Index> >&>(trans);
00316         }
00317       }
00318       return s;
00319     }
00320 
00321     template<typename OtherDerived>
00322     Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
00323     template<typename OtherDerived>
00324     Derived& operator-=(const SparseMatrixBase<OtherDerived>& other);
00325 
00326     Derived& operator*=(const Scalar& other);
00327     Derived& operator/=(const Scalar& other);
00328 
00329     template<typename OtherDerived> struct CwiseProductDenseReturnType {
00330       typedef CwiseBinaryOp<internal::scalar_product_op<typename internal::scalar_product_traits<
00331                                                           typename internal::traits<Derived>::Scalar,
00332                                                           typename internal::traits<OtherDerived>::Scalar
00333                                                         >::ReturnType>,
00334                             const Derived,
00335                             const OtherDerived
00336                           > Type;
00337     };
00338 
00339     template<typename OtherDerived>
00340     EIGEN_STRONG_INLINE const typename CwiseProductDenseReturnType<OtherDerived>::Type
00341     cwiseProduct(const MatrixBase<OtherDerived> &other) const;
00342 
00343     // sparse * sparse
00344     template<typename OtherDerived>
00345     const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type
00346     operator*(const SparseMatrixBase<OtherDerived> &other) const;
00347 
00348     // sparse * diagonal
00349     template<typename OtherDerived>
00350     const SparseDiagonalProduct<Derived,OtherDerived>
00351     operator*(const DiagonalBase<OtherDerived> &other) const;
00352 
00353     // diagonal * sparse
00354     template<typename OtherDerived> friend
00355     const SparseDiagonalProduct<OtherDerived,Derived>
00356     operator*(const DiagonalBase<OtherDerived> &lhs, const SparseMatrixBase& rhs)
00357     { return SparseDiagonalProduct<OtherDerived,Derived>(lhs.derived(), rhs.derived()); }
00358 
00360     template<typename OtherDerived> friend
00361     const typename DenseSparseProductReturnType<OtherDerived,Derived>::Type
00362     operator*(const MatrixBase<OtherDerived>& lhs, const Derived& rhs)
00363     { return typename DenseSparseProductReturnType<OtherDerived,Derived>::Type(lhs.derived(),rhs); }
00364 
00366     template<typename OtherDerived>
00367     const typename SparseDenseProductReturnType<Derived,OtherDerived>::Type
00368     operator*(const MatrixBase<OtherDerived> &other) const
00369     { return typename SparseDenseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); }
00370     
00372     SparseSymmetricPermutationProduct<Derived,Upper|Lower> twistedBy(const PermutationMatrix<Dynamic,Dynamic,Index>& perm) const
00373     {
00374       return SparseSymmetricPermutationProduct<Derived,Upper|Lower>(derived(), perm);
00375     }
00376 
00377     template<typename OtherDerived>
00378     Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);
00379 
00380     #ifdef EIGEN2_SUPPORT
00381     // deprecated
00382     template<typename OtherDerived>
00383     typename internal::plain_matrix_type_column_major<OtherDerived>::type
00384     solveTriangular(const MatrixBase<OtherDerived>& other) const;
00385 
00386     // deprecated
00387     template<typename OtherDerived>
00388     void solveTriangularInPlace(MatrixBase<OtherDerived>& other) const;
00389     #endif // EIGEN2_SUPPORT
00390 
00391     template<int Mode>
00392     inline const SparseTriangularView<Derived, Mode> triangularView() const;
00393 
00394     template<unsigned int UpLo> inline const SparseSelfAdjointView<Derived, UpLo> selfadjointView() const;
00395     template<unsigned int UpLo> inline SparseSelfAdjointView<Derived, UpLo> selfadjointView();
00396 
00397     template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const;
00398     template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
00399     RealScalar squaredNorm() const;
00400     RealScalar norm()  const;
00401     RealScalar blueNorm() const;
00402 
00403     Transpose<Derived> transpose() { return derived(); }
00404     const Transpose<const Derived> transpose() const { return derived(); }
00405     const AdjointReturnType adjoint() const { return transpose(); }
00406 
00407     // inner-vector
00408     typedef Block<Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true>       InnerVectorReturnType;
00409     typedef Block<const Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true> ConstInnerVectorReturnType;
00410     InnerVectorReturnType innerVector(Index outer);
00411     const ConstInnerVectorReturnType innerVector(Index outer) const;
00412 
00413     // set of inner-vectors
00414     typedef Block<Derived,Dynamic,Dynamic,true> InnerVectorsReturnType;
00415     typedef Block<const Derived,Dynamic,Dynamic,true> ConstInnerVectorsReturnType;
00416     InnerVectorsReturnType innerVectors(Index outerStart, Index outerSize);
00417     const ConstInnerVectorsReturnType innerVectors(Index outerStart, Index outerSize) const;
00418 
00420     template<typename DenseDerived>
00421     void evalTo(MatrixBase<DenseDerived>& dst) const
00422     {
00423       dst.setZero();
00424       for (Index j=0; j<outerSize(); ++j)
00425         for (typename Derived::InnerIterator i(derived(),j); i; ++i)
00426           dst.coeffRef(i.row(),i.col()) = i.value();
00427     }
00428 
00429     Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const
00430     {
00431       return derived();
00432     }
00433 
00434     template<typename OtherDerived>
00435     bool isApprox(const SparseMatrixBase<OtherDerived>& other,
00436                   const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const
00437     { return toDense().isApprox(other.toDense(),prec); }
00438 
00439     template<typename OtherDerived>
00440     bool isApprox(const MatrixBase<OtherDerived>& other,
00441                   const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const
00442     { return toDense().isApprox(other,prec); }
00443 
00449     inline const typename internal::eval<Derived>::type eval() const
00450     { return typename internal::eval<Derived>::type(derived()); }
00451 
00452     Scalar sum() const;
00453 
00454   protected:
00455 
00456     bool m_isRValue;
00457 };
00458 
00459 } // end namespace Eigen
00460 
00461 #endif // EIGEN_SPARSEMATRIXBASE_H
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends