MOAB  4.9.3pre
SparseVector.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-2015 Gael Guennebaud <[email protected]>
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 _StorageIndex>
00030 struct traits<SparseVector<_Scalar, _Options, _StorageIndex> >
00031 {
00032   typedef _Scalar Scalar;
00033   typedef _StorageIndex StorageIndex;
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) | CompressedAccessBit,
00044     SupportedAccessPatterns = InnerRandomAccessPattern
00045   };
00046 };
00047 
00048 // Sparse-Vector-Assignment kinds:
00049 enum {
00050   SVA_RuntimeSwitch,
00051   SVA_Inner,
00052   SVA_Outer
00053 };
00054 
00055 template< typename Dest, typename Src,
00056           int AssignmentKind = !bool(Src::IsVectorAtCompileTime) ? SVA_RuntimeSwitch
00057                              : Src::InnerSizeAtCompileTime==1 ? SVA_Outer
00058                              : SVA_Inner>
00059 struct sparse_vector_assign_selector;
00060 
00061 }
00062 
00063 template<typename _Scalar, int _Options, typename _StorageIndex>
00064 class SparseVector
00065   : public SparseCompressedBase<SparseVector<_Scalar, _Options, _StorageIndex> >
00066 {
00067     typedef SparseCompressedBase<SparseVector> Base;
00068     using Base::convert_index;
00069   public:
00070     EIGEN_SPARSE_PUBLIC_INTERFACE(SparseVector)
00071     EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, +=)
00072     EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, -=)
00073     
00074     typedef internal::CompressedStorage<Scalar,StorageIndex> Storage;
00075     enum { IsColVector = internal::traits<SparseVector>::IsColVector };
00076     
00077     enum {
00078       Options = _Options
00079     };
00080     
00081     EIGEN_STRONG_INLINE Index rows() const { return IsColVector ? m_size : 1; }
00082     EIGEN_STRONG_INLINE Index cols() const { return IsColVector ? 1 : m_size; }
00083     EIGEN_STRONG_INLINE Index innerSize() const { return m_size; }
00084     EIGEN_STRONG_INLINE Index outerSize() const { return 1; }
00085 
00086     EIGEN_STRONG_INLINE const Scalar* valuePtr() const { return m_data.valuePtr(); }
00087     EIGEN_STRONG_INLINE Scalar* valuePtr() { return m_data.valuePtr(); }
00088 
00089     EIGEN_STRONG_INLINE const StorageIndex* innerIndexPtr() const { return m_data.indexPtr(); }
00090     EIGEN_STRONG_INLINE StorageIndex* innerIndexPtr() { return m_data.indexPtr(); }
00091 
00092     inline const StorageIndex* outerIndexPtr() const { return 0; }
00093     inline StorageIndex* outerIndexPtr() { return 0; }
00094     inline const StorageIndex* innerNonZeroPtr() const { return 0; }
00095     inline StorageIndex* innerNonZeroPtr() { return 0; }
00096     
00098     inline Storage& data() { return m_data; }
00100     inline const Storage& data() const { return m_data; }
00101 
00102     inline Scalar coeff(Index row, Index col) const
00103     {
00104       eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
00105       return coeff(IsColVector ? row : col);
00106     }
00107     inline Scalar coeff(Index i) const
00108     {
00109       eigen_assert(i>=0 && i<m_size);
00110       return m_data.at(StorageIndex(i));
00111     }
00112 
00113     inline Scalar& coeffRef(Index row, Index col)
00114     {
00115       eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
00116       return coeffRef(IsColVector ? row : col);
00117     }
00118 
00125     inline Scalar& coeffRef(Index i)
00126     {
00127       eigen_assert(i>=0 && i<m_size);
00128 
00129       return m_data.atWithInsertion(StorageIndex(i));
00130     }
00131 
00132   public:
00133 
00134     typedef typename Base::InnerIterator InnerIterator;
00135     typedef typename Base::ReverseInnerIterator ReverseInnerIterator;
00136 
00137     inline void setZero() { m_data.clear(); }
00138 
00140     inline Index nonZeros() const  { return m_data.size(); }
00141 
00142     inline void startVec(Index outer)
00143     {
00144       EIGEN_UNUSED_VARIABLE(outer);
00145       eigen_assert(outer==0);
00146     }
00147 
00148     inline Scalar& insertBackByOuterInner(Index outer, Index inner)
00149     {
00150       EIGEN_UNUSED_VARIABLE(outer);
00151       eigen_assert(outer==0);
00152       return insertBack(inner);
00153     }
00154     inline Scalar& insertBack(Index i)
00155     {
00156       m_data.append(0, i);
00157       return m_data.value(m_data.size()-1);
00158     }
00159     
00160     Scalar& insertBackByOuterInnerUnordered(Index outer, Index inner)
00161     {
00162       EIGEN_UNUSED_VARIABLE(outer);
00163       eigen_assert(outer==0);
00164       return insertBackUnordered(inner);
00165     }
00166     inline Scalar& insertBackUnordered(Index i)
00167     {
00168       m_data.append(0, i);
00169       return m_data.value(m_data.size()-1);
00170     }
00171 
00172     inline Scalar& insert(Index row, Index col)
00173     {
00174       eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
00175       
00176       Index inner = IsColVector ? row : col;
00177       Index outer = IsColVector ? col : row;
00178       EIGEN_ONLY_USED_FOR_DEBUG(outer);
00179       eigen_assert(outer==0);
00180       return insert(inner);
00181     }
00182     Scalar& insert(Index i)
00183     {
00184       eigen_assert(i>=0 && i<m_size);
00185       
00186       Index startId = 0;
00187       Index p = Index(m_data.size()) - 1;
00188       // TODO smart realloc
00189       m_data.resize(p+2,1);
00190 
00191       while ( (p >= startId) && (m_data.index(p) > i) )
00192       {
00193         m_data.index(p+1) = m_data.index(p);
00194         m_data.value(p+1) = m_data.value(p);
00195         --p;
00196       }
00197       m_data.index(p+1) = convert_index(i);
00198       m_data.value(p+1) = 0;
00199       return m_data.value(p+1);
00200     }
00201 
00204     inline void reserve(Index reserveSize) { m_data.reserve(reserveSize); }
00205 
00206 
00207     inline void finalize() {}
00208 
00210     void prune(const Scalar& reference, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision())
00211     {
00212       m_data.prune(reference,epsilon);
00213     }
00214 
00223     void resize(Index rows, Index cols)
00224     {
00225       eigen_assert((IsColVector ? cols : rows)==1 && "Outer dimension must equal 1");
00226       resize(IsColVector ? rows : cols);
00227     }
00228 
00233     void resize(Index newSize)
00234     {
00235       m_size = newSize;
00236       m_data.clear();
00237     }
00238 
00246     void conservativeResize(Index newSize)
00247     {
00248       if (newSize < m_size)
00249       {
00250         Index i = 0;
00251         while (i<m_data.size() && m_data.index(i)<newSize) ++i;
00252         m_data.resize(i);
00253       }
00254       m_size = newSize;
00255     }
00256 
00257     void resizeNonZeros(Index size) { m_data.resize(size); }
00258 
00259     inline SparseVector() : m_size(0) { check_template_parameters(); resize(0); }
00260 
00261     explicit inline SparseVector(Index size) : m_size(0) { check_template_parameters(); resize(size); }
00262 
00263     inline SparseVector(Index rows, Index cols) : m_size(0) { check_template_parameters(); resize(rows,cols); }
00264 
00265     template<typename OtherDerived>
00266     inline SparseVector(const SparseMatrixBase<OtherDerived>& other)
00267       : m_size(0)
00268     {
00269       #ifdef EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
00270         EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
00271       #endif
00272       check_template_parameters();
00273       *this = other.derived();
00274     }
00275 
00276     inline SparseVector(const SparseVector& other)
00277       : Base(other), m_size(0)
00278     {
00279       check_template_parameters();
00280       *this = other.derived();
00281     }
00282 
00287     inline void swap(SparseVector& other)
00288     {
00289       std::swap(m_size, other.m_size);
00290       m_data.swap(other.m_data);
00291     }
00292 
00293     inline SparseVector& operator=(const SparseVector& other)
00294     {
00295       if (other.isRValue())
00296       {
00297         swap(other.const_cast_derived());
00298       }
00299       else
00300       {
00301         resize(other.size());
00302         m_data = other.m_data;
00303       }
00304       return *this;
00305     }
00306 
00307     template<typename OtherDerived>
00308     inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& other)
00309     {
00310       SparseVector tmp(other.size());
00311       internal::sparse_vector_assign_selector<SparseVector,OtherDerived>::run(tmp,other.derived());
00312       this->swap(tmp);
00313       return *this;
00314     }
00315 
00316     #ifndef EIGEN_PARSED_BY_DOXYGEN
00317     template<typename Lhs, typename Rhs>
00318     inline SparseVector& operator=(const SparseSparseProduct<Lhs,Rhs>& product)
00319     {
00320       return Base::operator=(product);
00321     }
00322     #endif
00323 
00324     friend std::ostream & operator << (std::ostream & s, const SparseVector& m)
00325     {
00326       for (Index i=0; i<m.nonZeros(); ++i)
00327         s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") ";
00328       s << std::endl;
00329       return s;
00330     }
00331 
00333     inline ~SparseVector() {}
00334 
00336     Scalar sum() const;
00337 
00338   public:
00339 
00341     EIGEN_DEPRECATED void startFill(Index reserve)
00342     {
00343       setZero();
00344       m_data.reserve(reserve);
00345     }
00346 
00348     EIGEN_DEPRECATED Scalar& fill(Index r, Index c)
00349     {
00350       eigen_assert(r==0 || c==0);
00351       return fill(IsColVector ? r : c);
00352     }
00353 
00355     EIGEN_DEPRECATED Scalar& fill(Index i)
00356     {
00357       m_data.append(0, i);
00358       return m_data.value(m_data.size()-1);
00359     }
00360 
00362     EIGEN_DEPRECATED Scalar& fillrand(Index r, Index c)
00363     {
00364       eigen_assert(r==0 || c==0);
00365       return fillrand(IsColVector ? r : c);
00366     }
00367 
00369     EIGEN_DEPRECATED Scalar& fillrand(Index i)
00370     {
00371       return insert(i);
00372     }
00373 
00375     EIGEN_DEPRECATED void endFill() {}
00376     
00377     // These two functions were here in the 3.1 release, so let's keep them in case some code rely on them.
00379     EIGEN_DEPRECATED Storage& _data() { return m_data; }
00381     EIGEN_DEPRECATED const Storage& _data() const { return m_data; }
00382     
00383 #   ifdef EIGEN_SPARSEVECTOR_PLUGIN
00384 #     include EIGEN_SPARSEVECTOR_PLUGIN
00385 #   endif
00386 
00387 protected:
00388   
00389     static void check_template_parameters()
00390     {
00391       EIGEN_STATIC_ASSERT(NumTraits<StorageIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
00392       EIGEN_STATIC_ASSERT((_Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS);
00393     }
00394     
00395     Storage m_data;
00396     Index m_size;
00397 };
00398 
00399 namespace internal {
00400 
00401 template<typename _Scalar, int _Options, typename _Index>
00402 struct evaluator<SparseVector<_Scalar,_Options,_Index> >
00403   : evaluator_base<SparseVector<_Scalar,_Options,_Index> >
00404 {
00405   typedef SparseVector<_Scalar,_Options,_Index> SparseVectorType;
00406   typedef typename SparseVectorType::InnerIterator InnerIterator;
00407   typedef typename SparseVectorType::ReverseInnerIterator ReverseInnerIterator;
00408   
00409   enum {
00410     CoeffReadCost = NumTraits<_Scalar>::ReadCost,
00411     Flags = SparseVectorType::Flags
00412   };
00413   
00414   explicit evaluator(const SparseVectorType &mat) : m_matrix(mat)
00415   {
00416     EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
00417   }
00418   
00419   inline Index nonZerosEstimate() const {
00420     return m_matrix.nonZeros();
00421   }
00422   
00423   operator SparseVectorType&() { return m_matrix.const_cast_derived(); }
00424   operator const SparseVectorType&() const { return m_matrix; }
00425   
00426   const SparseVectorType &m_matrix;
00427 };
00428 
00429 template< typename Dest, typename Src>
00430 struct sparse_vector_assign_selector<Dest,Src,SVA_Inner> {
00431   static void run(Dest& dst, const Src& src) {
00432     eigen_internal_assert(src.innerSize()==src.size());
00433     typedef internal::evaluator<Src> SrcEvaluatorType;
00434     SrcEvaluatorType srcEval(src);
00435     for(typename SrcEvaluatorType::InnerIterator it(srcEval, 0); it; ++it)
00436       dst.insert(it.index()) = it.value();
00437   }
00438 };
00439 
00440 template< typename Dest, typename Src>
00441 struct sparse_vector_assign_selector<Dest,Src,SVA_Outer> {
00442   static void run(Dest& dst, const Src& src) {
00443     eigen_internal_assert(src.outerSize()==src.size());
00444     typedef internal::evaluator<Src> SrcEvaluatorType;
00445     SrcEvaluatorType srcEval(src);
00446     for(Index i=0; i<src.size(); ++i)
00447     {
00448       typename SrcEvaluatorType::InnerIterator it(srcEval, i);
00449       if(it)
00450         dst.insert(i) = it.value();
00451     }
00452   }
00453 };
00454 
00455 template< typename Dest, typename Src>
00456 struct sparse_vector_assign_selector<Dest,Src,SVA_RuntimeSwitch> {
00457   static void run(Dest& dst, const Src& src) {
00458     if(src.outerSize()==1)  sparse_vector_assign_selector<Dest,Src,SVA_Inner>::run(dst, src);
00459     else                    sparse_vector_assign_selector<Dest,Src,SVA_Outer>::run(dst, src);
00460   }
00461 };
00462 
00463 }
00464 
00465 } // end namespace Eigen
00466 
00467 #endif // EIGEN_SPARSEVECTOR_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines