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       InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
00094                              : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
00095 
00096       #ifndef EIGEN_PARSED_BY_DOXYGEN
00097       _HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0 // workaround sunCC
00098       #endif
00099     };
00100 
00102     typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
00103                         CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, Eigen::Transpose<const Derived> >,
00104                         Transpose<const Derived>
00105                      >::type AdjointReturnType;
00106 
00107 
00108     typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor, Index> PlainObject;
00109 
00110 
00111 #ifndef EIGEN_PARSED_BY_DOXYGEN
00112 
00118     typedef typename NumTraits<Scalar>::Real RealScalar;
00119 
00122     typedef typename internal::conditional<_HasDirectAccess, const Scalar&, Scalar>::type CoeffReturnType;
00123 
00125     typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Matrix<Scalar,Dynamic,Dynamic> > ConstantReturnType;
00126 
00128     typedef Matrix<Scalar,EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime),
00129                           EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType;
00130 
00131     inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
00132     inline Derived& derived() { return *static_cast<Derived*>(this); }
00133     inline Derived& const_cast_derived() const
00134     { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); }
00135 #endif // not EIGEN_PARSED_BY_DOXYGEN
00136 
00137 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase
00138 #   include "../plugins/CommonCwiseUnaryOps.h"
00139 #   include "../plugins/CommonCwiseBinaryOps.h"
00140 #   include "../plugins/MatrixCwiseUnaryOps.h"
00141 #   include "../plugins/MatrixCwiseBinaryOps.h"
00142 #   include "../plugins/BlockMethods.h"
00143 #   ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN
00144 #     include EIGEN_SPARSEMATRIXBASE_PLUGIN
00145 #   endif
00146 #   undef EIGEN_CURRENT_STORAGE_BASE_CLASS
00147 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS
00148 
00150     inline Index rows() const { return derived().rows(); }
00152     inline Index cols() const { return derived().cols(); }
00155     inline Index size() const { return rows() * cols(); }
00158     inline Index nonZeros() const { return derived().nonZeros(); }
00163     inline bool isVector() const { return rows()==1 || cols()==1; }
00166     Index outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); }
00169     Index innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
00170 
00171     bool isRValue() const { return m_isRValue; }
00172     Derived& markAsRValue() { m_isRValue = true; return derived(); }
00173 
00174     SparseMatrixBase() : m_isRValue(false) { /* TODO check flags */ }
00175 
00176     
00177     template<typename OtherDerived>
00178     Derived& operator=(const ReturnByValue<OtherDerived>& other)
00179     {
00180       other.evalTo(derived());
00181       return derived();
00182     }
00183 
00184 
00185     template<typename OtherDerived>
00186     inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other)
00187     {
00188       return assign(other.derived());
00189     }
00190 
00191     inline Derived& operator=(const Derived& other)
00192     {
00193 //       if (other.isRValue())
00194 //         derived().swap(other.const_cast_derived());
00195 //       else
00196       return assign(other.derived());
00197     }
00198 
00199   protected:
00200 
00201     template<typename OtherDerived>
00202     inline Derived& assign(const OtherDerived& other)
00203     {
00204       const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
00205       const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols();
00206       if ((!transpose) && other.isRValue())
00207       {
00208         // eval without temporary
00209         derived().resize(other.rows(), other.cols());
00210         derived().setZero();
00211         derived().reserve((std::max)(this->rows(),this->cols())*2);
00212         for (Index j=0; j<outerSize; ++j)
00213         {
00214           derived().startVec(j);
00215           for (typename OtherDerived::InnerIterator it(other, j); it; ++it)
00216           {
00217             Scalar v = it.value();
00218             derived().insertBackByOuterInner(j,it.index()) = v;
00219           }
00220         }
00221         derived().finalize();
00222       }
00223       else
00224       {
00225         assignGeneric(other);
00226       }
00227       return derived();
00228     }
00229 
00230     template<typename OtherDerived>
00231     inline void assignGeneric(const OtherDerived& other)
00232     {
00233       //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
00234       eigen_assert(( ((internal::traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) ||
00235                   (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) &&
00236                   "the transpose operation is supposed to be handled in SparseMatrix::operator=");
00237 
00238       enum { Flip = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit) };
00239 
00240       const Index outerSize = other.outerSize();
00241       //typedef typename internal::conditional<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::type TempType;
00242       // thanks to shallow copies, we always eval to a tempary
00243       Derived temp(other.rows(), other.cols());
00244 
00245       temp.reserve((std::max)(this->rows(),this->cols())*2);
00246       for (Index j=0; j<outerSize; ++j)
00247       {
00248         temp.startVec(j);
00249         for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it)
00250         {
00251           Scalar v = it.value();
00252           temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v;
00253         }
00254       }
00255       temp.finalize();
00256 
00257       derived() = temp.markAsRValue();
00258     }
00259 
00260   public:
00261 
00262     template<typename Lhs, typename Rhs>
00263     inline Derived& operator=(const SparseSparseProduct<Lhs,Rhs>& product);
00264 
00265     friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m)
00266     {
00267       typedef typename Derived::Nested Nested;
00268       typedef typename internal::remove_all<Nested>::type NestedCleaned;
00269 
00270       if (Flags&RowMajorBit)
00271       {
00272         const Nested nm(m.derived());
00273         for (Index row=0; row<nm.outerSize(); ++row)
00274         {
00275           Index col = 0;
00276           for (typename NestedCleaned::InnerIterator it(nm.derived(), row); it; ++it)
00277           {
00278             for ( ; col<it.index(); ++col)
00279               s << "0 ";
00280             s << it.value() << " ";
00281             ++col;
00282           }
00283           for ( ; col<m.cols(); ++col)
00284             s << "0 ";
00285           s << std::endl;
00286         }
00287       }
00288       else
00289       {
00290         const Nested nm(m.derived());
00291         if (m.cols() == 1) {
00292           Index row = 0;
00293           for (typename NestedCleaned::InnerIterator it(nm.derived(), 0); it; ++it)
00294           {
00295             for ( ; row<it.index(); ++row)
00296               s << "0" << std::endl;
00297             s << it.value() << std::endl;
00298             ++row;
00299           }
00300           for ( ; row<m.rows(); ++row)
00301             s << "0" << std::endl;
00302         }
00303         else
00304         {
00305           SparseMatrix<Scalar, RowMajorBit> trans = m;
00306           s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit> >&>(trans);
00307         }
00308       }
00309       return s;
00310     }
00311 
00312     template<typename OtherDerived>
00313     Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
00314     template<typename OtherDerived>
00315     Derived& operator-=(const SparseMatrixBase<OtherDerived>& other);
00316 
00317     Derived& operator*=(const Scalar& other);
00318     Derived& operator/=(const Scalar& other);
00319 
00320     #define EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE \
00321       CwiseBinaryOp< \
00322         internal::scalar_product_op< \
00323           typename internal::scalar_product_traits< \
00324             typename internal::traits<Derived>::Scalar, \
00325             typename internal::traits<OtherDerived>::Scalar \
00326           >::ReturnType \
00327         >, \
00328         const Derived, \
00329         const OtherDerived \
00330       >
00331 
00332     template<typename OtherDerived>
00333     EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
00334     cwiseProduct(const MatrixBase<OtherDerived> &other) const;
00335 
00336     // sparse * sparse
00337     template<typename OtherDerived>
00338     const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type
00339     operator*(const SparseMatrixBase<OtherDerived> &other) const;
00340 
00341     // sparse * diagonal
00342     template<typename OtherDerived>
00343     const SparseDiagonalProduct<Derived,OtherDerived>
00344     operator*(const DiagonalBase<OtherDerived> &other) const;
00345 
00346     // diagonal * sparse
00347     template<typename OtherDerived> friend
00348     const SparseDiagonalProduct<OtherDerived,Derived>
00349     operator*(const DiagonalBase<OtherDerived> &lhs, const SparseMatrixBase& rhs)
00350     { return SparseDiagonalProduct<OtherDerived,Derived>(lhs.derived(), rhs.derived()); }
00351 
00353     template<typename OtherDerived> friend
00354     const typename DenseSparseProductReturnType<OtherDerived,Derived>::Type
00355     operator*(const MatrixBase<OtherDerived>& lhs, const Derived& rhs)
00356     { return typename DenseSparseProductReturnType<OtherDerived,Derived>::Type(lhs.derived(),rhs); }
00357 
00359     template<typename OtherDerived>
00360     const typename SparseDenseProductReturnType<Derived,OtherDerived>::Type
00361     operator*(const MatrixBase<OtherDerived> &other) const;
00362     
00364     SparseSymmetricPermutationProduct<Derived,Upper|Lower> twistedBy(const PermutationMatrix<Dynamic,Dynamic,Index>& perm) const
00365     {
00366       return SparseSymmetricPermutationProduct<Derived,Upper|Lower>(derived(), perm);
00367     }
00368 
00369     template<typename OtherDerived>
00370     Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);
00371 
00372     #ifdef EIGEN2_SUPPORT
00373     // deprecated
00374     template<typename OtherDerived>
00375     typename internal::plain_matrix_type_column_major<OtherDerived>::type
00376     solveTriangular(const MatrixBase<OtherDerived>& other) const;
00377 
00378     // deprecated
00379     template<typename OtherDerived>
00380     void solveTriangularInPlace(MatrixBase<OtherDerived>& other) const;
00381     #endif // EIGEN2_SUPPORT
00382 
00383     template<int Mode>
00384     inline const SparseTriangularView<Derived, Mode> triangularView() const;
00385 
00386     template<unsigned int UpLo> inline const SparseSelfAdjointView<Derived, UpLo> selfadjointView() const;
00387     template<unsigned int UpLo> inline SparseSelfAdjointView<Derived, UpLo> selfadjointView();
00388 
00389     template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const;
00390     template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
00391     RealScalar squaredNorm() const;
00392     RealScalar norm()  const;
00393     RealScalar blueNorm() const;
00394 
00395     Transpose<Derived> transpose() { return derived(); }
00396     const Transpose<const Derived> transpose() const { return derived(); }
00397     const AdjointReturnType adjoint() const { return transpose(); }
00398 
00399     // inner-vector
00400     typedef Block<Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true>       InnerVectorReturnType;
00401     typedef Block<const Derived,IsRowMajor?1:Dynamic,IsRowMajor?Dynamic:1,true> ConstInnerVectorReturnType;
00402     InnerVectorReturnType innerVector(Index outer);
00403     const ConstInnerVectorReturnType innerVector(Index outer) const;
00404 
00405     // set of inner-vectors
00406     Block<Derived,Dynamic,Dynamic,true> innerVectors(Index outerStart, Index outerSize);
00407     const Block<const Derived,Dynamic,Dynamic,true> innerVectors(Index outerStart, Index outerSize) const;
00408 
00410     template<typename DenseDerived>
00411     void evalTo(MatrixBase<DenseDerived>& dst) const
00412     {
00413       dst.setZero();
00414       for (Index j=0; j<outerSize(); ++j)
00415         for (typename Derived::InnerIterator i(derived(),j); i; ++i)
00416           dst.coeffRef(i.row(),i.col()) = i.value();
00417     }
00418 
00419     Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const
00420     {
00421       return derived();
00422     }
00423 
00424     template<typename OtherDerived>
00425     bool isApprox(const SparseMatrixBase<OtherDerived>& other,
00426                   const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const
00427     { return toDense().isApprox(other.toDense(),prec); }
00428 
00429     template<typename OtherDerived>
00430     bool isApprox(const MatrixBase<OtherDerived>& other,
00431                   const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const
00432     { return toDense().isApprox(other,prec); }
00433 
00439     inline const typename internal::eval<Derived>::type eval() const
00440     { return typename internal::eval<Derived>::type(derived()); }
00441 
00442     Scalar sum() const;
00443 
00444   protected:
00445 
00446     bool m_isRValue;
00447 };
00448 
00449 } // end namespace Eigen
00450 
00451 #endif // EIGEN_SPARSEMATRIXBASE_H


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