SparseVector.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2008-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
  5. //
  6. // This Source Code Form is subject to the terms of the Mozilla
  7. // Public License v. 2.0. If a copy of the MPL was not distributed
  8. // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. #ifndef EIGEN_SPARSEVECTOR_H
  10. #define EIGEN_SPARSEVECTOR_H
  11. namespace Eigen {
  12. /** \ingroup SparseCore_Module
  13. * \class SparseVector
  14. *
  15. * \brief a sparse vector class
  16. *
  17. * \tparam _Scalar the scalar type, i.e. the type of the coefficients
  18. *
  19. * See http://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme.
  20. *
  21. * This class can be extended with the help of the plugin mechanism described on the page
  22. * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_SPARSEVECTOR_PLUGIN.
  23. */
  24. namespace internal {
  25. template<typename _Scalar, int _Options, typename _StorageIndex>
  26. struct traits<SparseVector<_Scalar, _Options, _StorageIndex> >
  27. {
  28. typedef _Scalar Scalar;
  29. typedef _StorageIndex StorageIndex;
  30. typedef Sparse StorageKind;
  31. typedef MatrixXpr XprKind;
  32. enum {
  33. IsColVector = (_Options & RowMajorBit) ? 0 : 1,
  34. RowsAtCompileTime = IsColVector ? Dynamic : 1,
  35. ColsAtCompileTime = IsColVector ? 1 : Dynamic,
  36. MaxRowsAtCompileTime = RowsAtCompileTime,
  37. MaxColsAtCompileTime = ColsAtCompileTime,
  38. Flags = _Options | NestByRefBit | LvalueBit | (IsColVector ? 0 : RowMajorBit) | CompressedAccessBit,
  39. SupportedAccessPatterns = InnerRandomAccessPattern
  40. };
  41. };
  42. // Sparse-Vector-Assignment kinds:
  43. enum {
  44. SVA_RuntimeSwitch,
  45. SVA_Inner,
  46. SVA_Outer
  47. };
  48. template< typename Dest, typename Src,
  49. int AssignmentKind = !bool(Src::IsVectorAtCompileTime) ? SVA_RuntimeSwitch
  50. : Src::InnerSizeAtCompileTime==1 ? SVA_Outer
  51. : SVA_Inner>
  52. struct sparse_vector_assign_selector;
  53. }
  54. template<typename _Scalar, int _Options, typename _StorageIndex>
  55. class SparseVector
  56. : public SparseCompressedBase<SparseVector<_Scalar, _Options, _StorageIndex> >
  57. {
  58. typedef SparseCompressedBase<SparseVector> Base;
  59. using Base::convert_index;
  60. public:
  61. EIGEN_SPARSE_PUBLIC_INTERFACE(SparseVector)
  62. EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, +=)
  63. EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, -=)
  64. typedef internal::CompressedStorage<Scalar,StorageIndex> Storage;
  65. enum { IsColVector = internal::traits<SparseVector>::IsColVector };
  66. enum {
  67. Options = _Options
  68. };
  69. EIGEN_STRONG_INLINE Index rows() const { return IsColVector ? m_size : 1; }
  70. EIGEN_STRONG_INLINE Index cols() const { return IsColVector ? 1 : m_size; }
  71. EIGEN_STRONG_INLINE Index innerSize() const { return m_size; }
  72. EIGEN_STRONG_INLINE Index outerSize() const { return 1; }
  73. EIGEN_STRONG_INLINE const Scalar* valuePtr() const { return m_data.valuePtr(); }
  74. EIGEN_STRONG_INLINE Scalar* valuePtr() { return m_data.valuePtr(); }
  75. EIGEN_STRONG_INLINE const StorageIndex* innerIndexPtr() const { return m_data.indexPtr(); }
  76. EIGEN_STRONG_INLINE StorageIndex* innerIndexPtr() { return m_data.indexPtr(); }
  77. inline const StorageIndex* outerIndexPtr() const { return 0; }
  78. inline StorageIndex* outerIndexPtr() { return 0; }
  79. inline const StorageIndex* innerNonZeroPtr() const { return 0; }
  80. inline StorageIndex* innerNonZeroPtr() { return 0; }
  81. /** \internal */
  82. inline Storage& data() { return m_data; }
  83. /** \internal */
  84. inline const Storage& data() const { return m_data; }
  85. inline Scalar coeff(Index row, Index col) const
  86. {
  87. eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
  88. return coeff(IsColVector ? row : col);
  89. }
  90. inline Scalar coeff(Index i) const
  91. {
  92. eigen_assert(i>=0 && i<m_size);
  93. return m_data.at(StorageIndex(i));
  94. }
  95. inline Scalar& coeffRef(Index row, Index col)
  96. {
  97. eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
  98. return coeffRef(IsColVector ? row : col);
  99. }
  100. /** \returns a reference to the coefficient value at given index \a i
  101. * This operation involes a log(rho*size) binary search. If the coefficient does not
  102. * exist yet, then a sorted insertion into a sequential buffer is performed.
  103. *
  104. * This insertion might be very costly if the number of nonzeros above \a i is large.
  105. */
  106. inline Scalar& coeffRef(Index i)
  107. {
  108. eigen_assert(i>=0 && i<m_size);
  109. return m_data.atWithInsertion(StorageIndex(i));
  110. }
  111. public:
  112. typedef typename Base::InnerIterator InnerIterator;
  113. typedef typename Base::ReverseInnerIterator ReverseInnerIterator;
  114. inline void setZero() { m_data.clear(); }
  115. /** \returns the number of non zero coefficients */
  116. inline Index nonZeros() const { return m_data.size(); }
  117. inline void startVec(Index outer)
  118. {
  119. EIGEN_UNUSED_VARIABLE(outer);
  120. eigen_assert(outer==0);
  121. }
  122. inline Scalar& insertBackByOuterInner(Index outer, Index inner)
  123. {
  124. EIGEN_UNUSED_VARIABLE(outer);
  125. eigen_assert(outer==0);
  126. return insertBack(inner);
  127. }
  128. inline Scalar& insertBack(Index i)
  129. {
  130. m_data.append(0, i);
  131. return m_data.value(m_data.size()-1);
  132. }
  133. Scalar& insertBackByOuterInnerUnordered(Index outer, Index inner)
  134. {
  135. EIGEN_UNUSED_VARIABLE(outer);
  136. eigen_assert(outer==0);
  137. return insertBackUnordered(inner);
  138. }
  139. inline Scalar& insertBackUnordered(Index i)
  140. {
  141. m_data.append(0, i);
  142. return m_data.value(m_data.size()-1);
  143. }
  144. inline Scalar& insert(Index row, Index col)
  145. {
  146. eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
  147. Index inner = IsColVector ? row : col;
  148. Index outer = IsColVector ? col : row;
  149. EIGEN_ONLY_USED_FOR_DEBUG(outer);
  150. eigen_assert(outer==0);
  151. return insert(inner);
  152. }
  153. Scalar& insert(Index i)
  154. {
  155. eigen_assert(i>=0 && i<m_size);
  156. Index startId = 0;
  157. Index p = Index(m_data.size()) - 1;
  158. // TODO smart realloc
  159. m_data.resize(p+2,1);
  160. while ( (p >= startId) && (m_data.index(p) > i) )
  161. {
  162. m_data.index(p+1) = m_data.index(p);
  163. m_data.value(p+1) = m_data.value(p);
  164. --p;
  165. }
  166. m_data.index(p+1) = convert_index(i);
  167. m_data.value(p+1) = 0;
  168. return m_data.value(p+1);
  169. }
  170. /**
  171. */
  172. inline void reserve(Index reserveSize) { m_data.reserve(reserveSize); }
  173. inline void finalize() {}
  174. /** \copydoc SparseMatrix::prune(const Scalar&,const RealScalar&) */
  175. void prune(const Scalar& reference, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision())
  176. {
  177. m_data.prune(reference,epsilon);
  178. }
  179. /** Resizes the sparse vector to \a rows x \a cols
  180. *
  181. * This method is provided for compatibility with matrices.
  182. * For a column vector, \a cols must be equal to 1.
  183. * For a row vector, \a rows must be equal to 1.
  184. *
  185. * \sa resize(Index)
  186. */
  187. void resize(Index rows, Index cols)
  188. {
  189. eigen_assert((IsColVector ? cols : rows)==1 && "Outer dimension must equal 1");
  190. resize(IsColVector ? rows : cols);
  191. }
  192. /** Resizes the sparse vector to \a newSize
  193. * This method deletes all entries, thus leaving an empty sparse vector
  194. *
  195. * \sa conservativeResize(), setZero() */
  196. void resize(Index newSize)
  197. {
  198. m_size = newSize;
  199. m_data.clear();
  200. }
  201. /** Resizes the sparse vector to \a newSize, while leaving old values untouched.
  202. *
  203. * If the size of the vector is decreased, then the storage of the out-of bounds coefficients is kept and reserved.
  204. * Call .data().squeeze() to free extra memory.
  205. *
  206. * \sa reserve(), setZero()
  207. */
  208. void conservativeResize(Index newSize)
  209. {
  210. if (newSize < m_size)
  211. {
  212. Index i = 0;
  213. while (i<m_data.size() && m_data.index(i)<newSize) ++i;
  214. m_data.resize(i);
  215. }
  216. m_size = newSize;
  217. }
  218. void resizeNonZeros(Index size) { m_data.resize(size); }
  219. inline SparseVector() : m_size(0) { check_template_parameters(); resize(0); }
  220. explicit inline SparseVector(Index size) : m_size(0) { check_template_parameters(); resize(size); }
  221. inline SparseVector(Index rows, Index cols) : m_size(0) { check_template_parameters(); resize(rows,cols); }
  222. template<typename OtherDerived>
  223. inline SparseVector(const SparseMatrixBase<OtherDerived>& other)
  224. : m_size(0)
  225. {
  226. #ifdef EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
  227. EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
  228. #endif
  229. check_template_parameters();
  230. *this = other.derived();
  231. }
  232. inline SparseVector(const SparseVector& other)
  233. : Base(other), m_size(0)
  234. {
  235. check_template_parameters();
  236. *this = other.derived();
  237. }
  238. /** Swaps the values of \c *this and \a other.
  239. * Overloaded for performance: this version performs a \em shallow swap by swapping pointers and attributes only.
  240. * \sa SparseMatrixBase::swap()
  241. */
  242. inline void swap(SparseVector& other)
  243. {
  244. std::swap(m_size, other.m_size);
  245. m_data.swap(other.m_data);
  246. }
  247. template<int OtherOptions>
  248. inline void swap(SparseMatrix<Scalar,OtherOptions,StorageIndex>& other)
  249. {
  250. eigen_assert(other.outerSize()==1);
  251. std::swap(m_size, other.m_innerSize);
  252. m_data.swap(other.m_data);
  253. }
  254. inline SparseVector& operator=(const SparseVector& other)
  255. {
  256. if (other.isRValue())
  257. {
  258. swap(other.const_cast_derived());
  259. }
  260. else
  261. {
  262. resize(other.size());
  263. m_data = other.m_data;
  264. }
  265. return *this;
  266. }
  267. template<typename OtherDerived>
  268. inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& other)
  269. {
  270. SparseVector tmp(other.size());
  271. internal::sparse_vector_assign_selector<SparseVector,OtherDerived>::run(tmp,other.derived());
  272. this->swap(tmp);
  273. return *this;
  274. }
  275. #ifndef EIGEN_PARSED_BY_DOXYGEN
  276. template<typename Lhs, typename Rhs>
  277. inline SparseVector& operator=(const SparseSparseProduct<Lhs,Rhs>& product)
  278. {
  279. return Base::operator=(product);
  280. }
  281. #endif
  282. friend std::ostream & operator << (std::ostream & s, const SparseVector& m)
  283. {
  284. for (Index i=0; i<m.nonZeros(); ++i)
  285. s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") ";
  286. s << std::endl;
  287. return s;
  288. }
  289. /** Destructor */
  290. inline ~SparseVector() {}
  291. /** Overloaded for performance */
  292. Scalar sum() const;
  293. public:
  294. /** \internal \deprecated use setZero() and reserve() */
  295. EIGEN_DEPRECATED void startFill(Index reserve)
  296. {
  297. setZero();
  298. m_data.reserve(reserve);
  299. }
  300. /** \internal \deprecated use insertBack(Index,Index) */
  301. EIGEN_DEPRECATED Scalar& fill(Index r, Index c)
  302. {
  303. eigen_assert(r==0 || c==0);
  304. return fill(IsColVector ? r : c);
  305. }
  306. /** \internal \deprecated use insertBack(Index) */
  307. EIGEN_DEPRECATED Scalar& fill(Index i)
  308. {
  309. m_data.append(0, i);
  310. return m_data.value(m_data.size()-1);
  311. }
  312. /** \internal \deprecated use insert(Index,Index) */
  313. EIGEN_DEPRECATED Scalar& fillrand(Index r, Index c)
  314. {
  315. eigen_assert(r==0 || c==0);
  316. return fillrand(IsColVector ? r : c);
  317. }
  318. /** \internal \deprecated use insert(Index) */
  319. EIGEN_DEPRECATED Scalar& fillrand(Index i)
  320. {
  321. return insert(i);
  322. }
  323. /** \internal \deprecated use finalize() */
  324. EIGEN_DEPRECATED void endFill() {}
  325. // These two functions were here in the 3.1 release, so let's keep them in case some code rely on them.
  326. /** \internal \deprecated use data() */
  327. EIGEN_DEPRECATED Storage& _data() { return m_data; }
  328. /** \internal \deprecated use data() */
  329. EIGEN_DEPRECATED const Storage& _data() const { return m_data; }
  330. # ifdef EIGEN_SPARSEVECTOR_PLUGIN
  331. # include EIGEN_SPARSEVECTOR_PLUGIN
  332. # endif
  333. protected:
  334. static void check_template_parameters()
  335. {
  336. EIGEN_STATIC_ASSERT(NumTraits<StorageIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
  337. EIGEN_STATIC_ASSERT((_Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS);
  338. }
  339. Storage m_data;
  340. Index m_size;
  341. };
  342. namespace internal {
  343. template<typename _Scalar, int _Options, typename _Index>
  344. struct evaluator<SparseVector<_Scalar,_Options,_Index> >
  345. : evaluator_base<SparseVector<_Scalar,_Options,_Index> >
  346. {
  347. typedef SparseVector<_Scalar,_Options,_Index> SparseVectorType;
  348. typedef evaluator_base<SparseVectorType> Base;
  349. typedef typename SparseVectorType::InnerIterator InnerIterator;
  350. typedef typename SparseVectorType::ReverseInnerIterator ReverseInnerIterator;
  351. enum {
  352. CoeffReadCost = NumTraits<_Scalar>::ReadCost,
  353. Flags = SparseVectorType::Flags
  354. };
  355. evaluator() : Base() {}
  356. explicit evaluator(const SparseVectorType &mat) : m_matrix(&mat)
  357. {
  358. EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
  359. }
  360. inline Index nonZerosEstimate() const {
  361. return m_matrix->nonZeros();
  362. }
  363. operator SparseVectorType&() { return m_matrix->const_cast_derived(); }
  364. operator const SparseVectorType&() const { return *m_matrix; }
  365. const SparseVectorType *m_matrix;
  366. };
  367. template< typename Dest, typename Src>
  368. struct sparse_vector_assign_selector<Dest,Src,SVA_Inner> {
  369. static void run(Dest& dst, const Src& src) {
  370. eigen_internal_assert(src.innerSize()==src.size());
  371. typedef internal::evaluator<Src> SrcEvaluatorType;
  372. SrcEvaluatorType srcEval(src);
  373. for(typename SrcEvaluatorType::InnerIterator it(srcEval, 0); it; ++it)
  374. dst.insert(it.index()) = it.value();
  375. }
  376. };
  377. template< typename Dest, typename Src>
  378. struct sparse_vector_assign_selector<Dest,Src,SVA_Outer> {
  379. static void run(Dest& dst, const Src& src) {
  380. eigen_internal_assert(src.outerSize()==src.size());
  381. typedef internal::evaluator<Src> SrcEvaluatorType;
  382. SrcEvaluatorType srcEval(src);
  383. for(Index i=0; i<src.size(); ++i)
  384. {
  385. typename SrcEvaluatorType::InnerIterator it(srcEval, i);
  386. if(it)
  387. dst.insert(i) = it.value();
  388. }
  389. }
  390. };
  391. template< typename Dest, typename Src>
  392. struct sparse_vector_assign_selector<Dest,Src,SVA_RuntimeSwitch> {
  393. static void run(Dest& dst, const Src& src) {
  394. if(src.outerSize()==1) sparse_vector_assign_selector<Dest,Src,SVA_Inner>::run(dst, src);
  395. else sparse_vector_assign_selector<Dest,Src,SVA_Outer>::run(dst, src);
  396. }
  397. };
  398. }
  399. } // end namespace Eigen
  400. #endif // EIGEN_SPARSEVECTOR_H