Eigen  3.3.3
SparseVector.h
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008-2015 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 _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     template<int OtherOptions>
00294     inline void swap(SparseMatrix<Scalar,OtherOptions,StorageIndex>& other)
00295     {
00296       eigen_assert(other.outerSize()==1);
00297       std::swap(m_size, other.m_innerSize);
00298       m_data.swap(other.m_data);
00299     }
00300 
00301     inline SparseVector& operator=(const SparseVector& other)
00302     {
00303       if (other.isRValue())
00304       {
00305         swap(other.const_cast_derived());
00306       }
00307       else
00308       {
00309         resize(other.size());
00310         m_data = other.m_data;
00311       }
00312       return *this;
00313     }
00314 
00315     template<typename OtherDerived>
00316     inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& other)
00317     {
00318       SparseVector tmp(other.size());
00319       internal::sparse_vector_assign_selector<SparseVector,OtherDerived>::run(tmp,other.derived());
00320       this->swap(tmp);
00321       return *this;
00322     }
00323 
00324     #ifndef EIGEN_PARSED_BY_DOXYGEN
00325     template<typename Lhs, typename Rhs>
00326     inline SparseVector& operator=(const SparseSparseProduct<Lhs,Rhs>& product)
00327     {
00328       return Base::operator=(product);
00329     }
00330     #endif
00331 
00332     friend std::ostream & operator << (std::ostream & s, const SparseVector& m)
00333     {
00334       for (Index i=0; i<m.nonZeros(); ++i)
00335         s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") ";
00336       s << std::endl;
00337       return s;
00338     }
00339 
00341     inline ~SparseVector() {}
00342 
00344     Scalar sum() const;
00345 
00346   public:
00347 
00349     EIGEN_DEPRECATED void startFill(Index reserve)
00350     {
00351       setZero();
00352       m_data.reserve(reserve);
00353     }
00354 
00356     EIGEN_DEPRECATED Scalar& fill(Index r, Index c)
00357     {
00358       eigen_assert(r==0 || c==0);
00359       return fill(IsColVector ? r : c);
00360     }
00361 
00363     EIGEN_DEPRECATED Scalar& fill(Index i)
00364     {
00365       m_data.append(0, i);
00366       return m_data.value(m_data.size()-1);
00367     }
00368 
00370     EIGEN_DEPRECATED Scalar& fillrand(Index r, Index c)
00371     {
00372       eigen_assert(r==0 || c==0);
00373       return fillrand(IsColVector ? r : c);
00374     }
00375 
00377     EIGEN_DEPRECATED Scalar& fillrand(Index i)
00378     {
00379       return insert(i);
00380     }
00381 
00383     EIGEN_DEPRECATED void endFill() {}
00384     
00385     // These two functions were here in the 3.1 release, so let's keep them in case some code rely on them.
00387     EIGEN_DEPRECATED Storage& _data() { return m_data; }
00389     EIGEN_DEPRECATED const Storage& _data() const { return m_data; }
00390     
00391 #   ifdef EIGEN_SPARSEVECTOR_PLUGIN
00392 #     include EIGEN_SPARSEVECTOR_PLUGIN
00393 #   endif
00394 
00395 protected:
00396   
00397     static void check_template_parameters()
00398     {
00399       EIGEN_STATIC_ASSERT(NumTraits<StorageIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
00400       EIGEN_STATIC_ASSERT((_Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS);
00401     }
00402     
00403     Storage m_data;
00404     Index m_size;
00405 };
00406 
00407 namespace internal {
00408 
00409 template<typename _Scalar, int _Options, typename _Index>
00410 struct evaluator<SparseVector<_Scalar,_Options,_Index> >
00411   : evaluator_base<SparseVector<_Scalar,_Options,_Index> >
00412 {
00413   typedef SparseVector<_Scalar,_Options,_Index> SparseVectorType;
00414   typedef evaluator_base<SparseVectorType> Base;
00415   typedef typename SparseVectorType::InnerIterator InnerIterator;
00416   typedef typename SparseVectorType::ReverseInnerIterator ReverseInnerIterator;
00417   
00418   enum {
00419     CoeffReadCost = NumTraits<_Scalar>::ReadCost,
00420     Flags = SparseVectorType::Flags
00421   };
00422 
00423   evaluator() : Base() {}
00424   
00425   explicit evaluator(const SparseVectorType &mat) : m_matrix(&mat)
00426   {
00427     EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
00428   }
00429   
00430   inline Index nonZerosEstimate() const {
00431     return m_matrix->nonZeros();
00432   }
00433   
00434   operator SparseVectorType&() { return m_matrix->const_cast_derived(); }
00435   operator const SparseVectorType&() const { return *m_matrix; }
00436   
00437   const SparseVectorType *m_matrix;
00438 };
00439 
00440 template< typename Dest, typename Src>
00441 struct sparse_vector_assign_selector<Dest,Src,SVA_Inner> {
00442   static void run(Dest& dst, const Src& src) {
00443     eigen_internal_assert(src.innerSize()==src.size());
00444     typedef internal::evaluator<Src> SrcEvaluatorType;
00445     SrcEvaluatorType srcEval(src);
00446     for(typename SrcEvaluatorType::InnerIterator it(srcEval, 0); it; ++it)
00447       dst.insert(it.index()) = it.value();
00448   }
00449 };
00450 
00451 template< typename Dest, typename Src>
00452 struct sparse_vector_assign_selector<Dest,Src,SVA_Outer> {
00453   static void run(Dest& dst, const Src& src) {
00454     eigen_internal_assert(src.outerSize()==src.size());
00455     typedef internal::evaluator<Src> SrcEvaluatorType;
00456     SrcEvaluatorType srcEval(src);
00457     for(Index i=0; i<src.size(); ++i)
00458     {
00459       typename SrcEvaluatorType::InnerIterator it(srcEval, i);
00460       if(it)
00461         dst.insert(i) = it.value();
00462     }
00463   }
00464 };
00465 
00466 template< typename Dest, typename Src>
00467 struct sparse_vector_assign_selector<Dest,Src,SVA_RuntimeSwitch> {
00468   static void run(Dest& dst, const Src& src) {
00469     if(src.outerSize()==1)  sparse_vector_assign_selector<Dest,Src,SVA_Inner>::run(dst, src);
00470     else                    sparse_vector_assign_selector<Dest,Src,SVA_Outer>::run(dst, src);
00471   }
00472 };
00473 
00474 }
00475 
00476 } // end namespace Eigen
00477 
00478 #endif // EIGEN_SPARSEVECTOR_H
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends