Eigen  3.2.8
SparseVector.h
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008-2009 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_SPARSEVECTOR_H
00011 #define EIGEN_SPARSEVECTOR_H
00012 
00013 namespace Eigen { 
00014 
00028 namespace internal {
00029 template<typename _Scalar, int _Options, typename _Index>
00030 struct traits<SparseVector<_Scalar, _Options, _Index> >
00031 {
00032   typedef _Scalar Scalar;
00033   typedef _Index Index;
00034   typedef Sparse StorageKind;
00035   typedef MatrixXpr XprKind;
00036   enum {
00037     IsColVector = (_Options & RowMajorBit) ? 0 : 1,
00038 
00039     RowsAtCompileTime = IsColVector ? Dynamic : 1,
00040     ColsAtCompileTime = IsColVector ? 1 : Dynamic,
00041     MaxRowsAtCompileTime = RowsAtCompileTime,
00042     MaxColsAtCompileTime = ColsAtCompileTime,
00043     Flags = _Options | NestByRefBit | LvalueBit | (IsColVector ? 0 : RowMajorBit),
00044     CoeffReadCost = NumTraits<Scalar>::ReadCost,
00045     SupportedAccessPatterns = InnerRandomAccessPattern
00046   };
00047 };
00048 
00049 // Sparse-Vector-Assignment kinds:
00050 enum {
00051   SVA_RuntimeSwitch,
00052   SVA_Inner,
00053   SVA_Outer
00054 };
00055 
00056 template< typename Dest, typename Src,
00057           int AssignmentKind = !bool(Src::IsVectorAtCompileTime) ? SVA_RuntimeSwitch
00058                              : Src::InnerSizeAtCompileTime==1 ? SVA_Outer
00059                              : SVA_Inner>
00060 struct sparse_vector_assign_selector;
00061 
00062 }
00063 
00064 template<typename _Scalar, int _Options, typename _Index>
00065 class SparseVector
00066   : public SparseMatrixBase<SparseVector<_Scalar, _Options, _Index> >
00067 {
00068     typedef SparseMatrixBase<SparseVector> SparseBase;
00069     
00070   public:
00071     EIGEN_SPARSE_PUBLIC_INTERFACE(SparseVector)
00072     EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, +=)
00073     EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, -=)
00074     
00075     typedef internal::CompressedStorage<Scalar,Index> Storage;
00076     enum { IsColVector = internal::traits<SparseVector>::IsColVector };
00077     
00078     enum {
00079       Options = _Options
00080     };
00081     
00082     EIGEN_STRONG_INLINE Index rows() const { return IsColVector ? m_size : 1; }
00083     EIGEN_STRONG_INLINE Index cols() const { return IsColVector ? 1 : m_size; }
00084     EIGEN_STRONG_INLINE Index innerSize() const { return m_size; }
00085     EIGEN_STRONG_INLINE Index outerSize() const { return 1; }
00086 
00087     EIGEN_STRONG_INLINE const Scalar* valuePtr() const { return &m_data.value(0); }
00088     EIGEN_STRONG_INLINE Scalar* valuePtr() { return &m_data.value(0); }
00089 
00090     EIGEN_STRONG_INLINE const Index* innerIndexPtr() const { return &m_data.index(0); }
00091     EIGEN_STRONG_INLINE Index* innerIndexPtr() { return &m_data.index(0); }
00092     
00094     inline Storage& data() { return m_data; }
00096     inline const Storage& data() const { return m_data; }
00097 
00098     inline Scalar coeff(Index row, Index col) const
00099     {
00100       eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
00101       return coeff(IsColVector ? row : col);
00102     }
00103     inline Scalar coeff(Index i) const
00104     {
00105       eigen_assert(i>=0 && i<m_size);
00106       return m_data.at(i);
00107     }
00108 
00109     inline Scalar& coeffRef(Index row, Index col)
00110     {
00111       eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
00112       return coeff(IsColVector ? row : col);
00113     }
00114 
00121     inline Scalar& coeffRef(Index i)
00122     {
00123       eigen_assert(i>=0 && i<m_size);
00124       return m_data.atWithInsertion(i);
00125     }
00126 
00127   public:
00128 
00129     class InnerIterator;
00130     class ReverseInnerIterator;
00131 
00132     inline void setZero() { m_data.clear(); }
00133 
00135     inline Index nonZeros() const  { return static_cast<Index>(m_data.size()); }
00136 
00137     inline void startVec(Index outer)
00138     {
00139       EIGEN_UNUSED_VARIABLE(outer);
00140       eigen_assert(outer==0);
00141     }
00142 
00143     inline Scalar& insertBackByOuterInner(Index outer, Index inner)
00144     {
00145       EIGEN_UNUSED_VARIABLE(outer);
00146       eigen_assert(outer==0);
00147       return insertBack(inner);
00148     }
00149     inline Scalar& insertBack(Index i)
00150     {
00151       m_data.append(0, i);
00152       return m_data.value(m_data.size()-1);
00153     }
00154 
00155     inline Scalar& insert(Index row, Index col)
00156     {
00157       eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
00158       
00159       Index inner = IsColVector ? row : col;
00160       Index outer = IsColVector ? col : row;
00161       EIGEN_ONLY_USED_FOR_DEBUG(outer);
00162       eigen_assert(outer==0);
00163       return insert(inner);
00164     }
00165     Scalar& insert(Index i)
00166     {
00167       eigen_assert(i>=0 && i<m_size);
00168       
00169       Index startId = 0;
00170       Index p = Index(m_data.size()) - 1;
00171       // TODO smart realloc
00172       m_data.resize(p+2,1);
00173 
00174       while ( (p >= startId) && (m_data.index(p) > i) )
00175       {
00176         m_data.index(p+1) = m_data.index(p);
00177         m_data.value(p+1) = m_data.value(p);
00178         --p;
00179       }
00180       m_data.index(p+1) = i;
00181       m_data.value(p+1) = 0;
00182       return m_data.value(p+1);
00183     }
00184 
00187     inline void reserve(Index reserveSize) { m_data.reserve(reserveSize); }
00188 
00189 
00190     inline void finalize() {}
00191 
00192     void prune(const Scalar& reference, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision())
00193     {
00194       m_data.prune(reference,epsilon);
00195     }
00196 
00197     void resize(Index rows, Index cols)
00198     {
00199       eigen_assert(rows==1 || cols==1);
00200       resize(IsColVector ? rows : cols);
00201     }
00202 
00203     void resize(Index newSize)
00204     {
00205       m_size = newSize;
00206       m_data.clear();
00207     }
00208 
00209     void resizeNonZeros(Index size) { m_data.resize(size); }
00210 
00211     inline SparseVector() : m_size(0) { check_template_parameters(); resize(0); }
00212 
00213     inline SparseVector(Index size) : m_size(0) { check_template_parameters(); resize(size); }
00214 
00215     inline SparseVector(Index rows, Index cols) : m_size(0) { check_template_parameters(); resize(rows,cols); }
00216 
00217     template<typename OtherDerived>
00218     inline SparseVector(const SparseMatrixBase<OtherDerived>& other)
00219       : m_size(0)
00220     {
00221       check_template_parameters();
00222       *this = other.derived();
00223     }
00224 
00225     inline SparseVector(const SparseVector& other)
00226       : SparseBase(other), m_size(0)
00227     {
00228       check_template_parameters();
00229       *this = other.derived();
00230     }
00231 
00236     inline void swap(SparseVector& other)
00237     {
00238       std::swap(m_size, other.m_size);
00239       m_data.swap(other.m_data);
00240     }
00241 
00242     inline SparseVector& operator=(const SparseVector& other)
00243     {
00244       if (other.isRValue())
00245       {
00246         swap(other.const_cast_derived());
00247       }
00248       else
00249       {
00250         resize(other.size());
00251         m_data = other.m_data;
00252       }
00253       return *this;
00254     }
00255 
00256     template<typename OtherDerived>
00257     inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& other)
00258     {
00259       SparseVector tmp(other.size());
00260       internal::sparse_vector_assign_selector<SparseVector,OtherDerived>::run(tmp,other.derived());
00261       this->swap(tmp);
00262       return *this;
00263     }
00264 
00265     #ifndef EIGEN_PARSED_BY_DOXYGEN
00266     template<typename Lhs, typename Rhs>
00267     inline SparseVector& operator=(const SparseSparseProduct<Lhs,Rhs>& product)
00268     {
00269       return Base::operator=(product);
00270     }
00271     #endif
00272 
00273     friend std::ostream & operator << (std::ostream & s, const SparseVector& m)
00274     {
00275       for (Index i=0; i<m.nonZeros(); ++i)
00276         s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") ";
00277       s << std::endl;
00278       return s;
00279     }
00280 
00282     inline ~SparseVector() {}
00283 
00285     Scalar sum() const;
00286 
00287   public:
00288 
00290     EIGEN_DEPRECATED void startFill(Index reserve)
00291     {
00292       setZero();
00293       m_data.reserve(reserve);
00294     }
00295 
00297     EIGEN_DEPRECATED Scalar& fill(Index r, Index c)
00298     {
00299       eigen_assert(r==0 || c==0);
00300       return fill(IsColVector ? r : c);
00301     }
00302 
00304     EIGEN_DEPRECATED Scalar& fill(Index i)
00305     {
00306       m_data.append(0, i);
00307       return m_data.value(m_data.size()-1);
00308     }
00309 
00311     EIGEN_DEPRECATED Scalar& fillrand(Index r, Index c)
00312     {
00313       eigen_assert(r==0 || c==0);
00314       return fillrand(IsColVector ? r : c);
00315     }
00316 
00318     EIGEN_DEPRECATED Scalar& fillrand(Index i)
00319     {
00320       return insert(i);
00321     }
00322 
00324     EIGEN_DEPRECATED void endFill() {}
00325     
00326     // These two functions were here in the 3.1 release, so let's keep them in case some code rely on them.
00328     EIGEN_DEPRECATED Storage& _data() { return m_data; }
00330     EIGEN_DEPRECATED const Storage& _data() const { return m_data; }
00331     
00332 #   ifdef EIGEN_SPARSEVECTOR_PLUGIN
00333 #     include EIGEN_SPARSEVECTOR_PLUGIN
00334 #   endif
00335 
00336 protected:
00337   
00338     static void check_template_parameters()
00339     {
00340       EIGEN_STATIC_ASSERT(NumTraits<Index>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
00341       EIGEN_STATIC_ASSERT((_Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS);
00342     }
00343     
00344     Storage m_data;
00345     Index m_size;
00346 };
00347 
00348 template<typename Scalar, int _Options, typename _Index>
00349 class SparseVector<Scalar,_Options,_Index>::InnerIterator
00350 {
00351   public:
00352     InnerIterator(const SparseVector& vec, Index outer=0)
00353       : m_data(vec.m_data), m_id(0), m_end(static_cast<Index>(m_data.size()))
00354     {
00355       EIGEN_UNUSED_VARIABLE(outer);
00356       eigen_assert(outer==0);
00357     }
00358 
00359     InnerIterator(const internal::CompressedStorage<Scalar,Index>& data)
00360       : m_data(data), m_id(0), m_end(static_cast<Index>(m_data.size()))
00361     {}
00362 
00363     inline InnerIterator& operator++() { m_id++; return *this; }
00364 
00365     inline Scalar value() const { return m_data.value(m_id); }
00366     inline Scalar& valueRef() { return const_cast<Scalar&>(m_data.value(m_id)); }
00367 
00368     inline Index index() const { return m_data.index(m_id); }
00369     inline Index row() const { return IsColVector ? index() : 0; }
00370     inline Index col() const { return IsColVector ? 0 : index(); }
00371 
00372     inline operator bool() const { return (m_id < m_end); }
00373 
00374   protected:
00375     const internal::CompressedStorage<Scalar,Index>& m_data;
00376     Index m_id;
00377     const Index m_end;
00378 };
00379 
00380 template<typename Scalar, int _Options, typename _Index>
00381 class SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator
00382 {
00383   public:
00384     ReverseInnerIterator(const SparseVector& vec, Index outer=0)
00385       : m_data(vec.m_data), m_id(static_cast<Index>(m_data.size())), m_start(0)
00386     {
00387       EIGEN_UNUSED_VARIABLE(outer);
00388       eigen_assert(outer==0);
00389     }
00390 
00391     ReverseInnerIterator(const internal::CompressedStorage<Scalar,Index>& data)
00392       : m_data(data), m_id(static_cast<Index>(m_data.size())), m_start(0)
00393     {}
00394 
00395     inline ReverseInnerIterator& operator--() { m_id--; return *this; }
00396 
00397     inline Scalar value() const { return m_data.value(m_id-1); }
00398     inline Scalar& valueRef() { return const_cast<Scalar&>(m_data.value(m_id-1)); }
00399 
00400     inline Index index() const { return m_data.index(m_id-1); }
00401     inline Index row() const { return IsColVector ? index() : 0; }
00402     inline Index col() const { return IsColVector ? 0 : index(); }
00403 
00404     inline operator bool() const { return (m_id > m_start); }
00405 
00406   protected:
00407     const internal::CompressedStorage<Scalar,Index>& m_data;
00408     Index m_id;
00409     const Index m_start;
00410 };
00411 
00412 namespace internal {
00413 
00414 template< typename Dest, typename Src>
00415 struct sparse_vector_assign_selector<Dest,Src,SVA_Inner> {
00416   static void run(Dest& dst, const Src& src) {
00417     eigen_internal_assert(src.innerSize()==src.size());
00418     for(typename Src::InnerIterator it(src, 0); it; ++it)
00419       dst.insert(it.index()) = it.value();
00420   }
00421 };
00422 
00423 template< typename Dest, typename Src>
00424 struct sparse_vector_assign_selector<Dest,Src,SVA_Outer> {
00425   static void run(Dest& dst, const Src& src) {
00426     eigen_internal_assert(src.outerSize()==src.size());
00427     for(typename Dest::Index i=0; i<src.size(); ++i)
00428     {
00429       typename Src::InnerIterator it(src, i);
00430       if(it)
00431         dst.insert(i) = it.value();
00432     }
00433   }
00434 };
00435 
00436 template< typename Dest, typename Src>
00437 struct sparse_vector_assign_selector<Dest,Src,SVA_RuntimeSwitch> {
00438   static void run(Dest& dst, const Src& src) {
00439     if(src.outerSize()==1)  sparse_vector_assign_selector<Dest,Src,SVA_Inner>::run(dst, src);
00440     else                    sparse_vector_assign_selector<Dest,Src,SVA_Outer>::run(dst, src);
00441   }
00442 };
00443 
00444 }
00445 
00446 } // end namespace Eigen
00447 
00448 #endif // EIGEN_SPARSEVECTOR_H
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends