SparseVector.h
Go to the documentation of this file.
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 
10 #ifndef EIGEN_SPARSEVECTOR_H
11 #define EIGEN_SPARSEVECTOR_H
12 
13 #include "./InternalHeaderCheck.h"
14 
15 namespace Eigen {
16 
30 namespace internal {
31 template<typename Scalar_, int Options_, typename StorageIndex_>
32 struct traits<SparseVector<Scalar_, Options_, StorageIndex_> >
33 {
34  typedef Scalar_ Scalar;
35  typedef StorageIndex_ StorageIndex;
36  typedef Sparse StorageKind;
37  typedef MatrixXpr XprKind;
38  enum {
39  IsColVector = (Options_ & RowMajorBit) ? 0 : 1,
40 
41  RowsAtCompileTime = IsColVector ? Dynamic : 1,
42  ColsAtCompileTime = IsColVector ? 1 : Dynamic,
43  MaxRowsAtCompileTime = RowsAtCompileTime,
44  MaxColsAtCompileTime = ColsAtCompileTime,
45  Flags = Options_ | NestByRefBit | LvalueBit | (IsColVector ? 0 : RowMajorBit) | CompressedAccessBit,
46  SupportedAccessPatterns = InnerRandomAccessPattern
47  };
48 };
49 
50 // Sparse-Vector-Assignment kinds:
51 enum {
54  SVA_Outer
55 };
56 
57 template< typename Dest, typename Src,
58  int AssignmentKind = !bool(Src::IsVectorAtCompileTime) ? SVA_RuntimeSwitch
59  : Src::InnerSizeAtCompileTime==1 ? SVA_Outer
60  : SVA_Inner>
61 struct sparse_vector_assign_selector;
62 
63 }
64 
65 template<typename Scalar_, int Options_, typename StorageIndex_>
67  : public SparseCompressedBase<SparseVector<Scalar_, Options_, StorageIndex_> >
68 {
70  using Base::convert_index;
71  public:
75 
76  typedef internal::CompressedStorage<Scalar,StorageIndex> Storage;
77  enum { IsColVector = internal::traits<SparseVector>::IsColVector };
78 
79  enum {
80  Options = Options_
81  };
82 
83  EIGEN_STRONG_INLINE Index rows() const { return IsColVector ? m_size : 1; }
84  EIGEN_STRONG_INLINE Index cols() const { return IsColVector ? 1 : m_size; }
85  EIGEN_STRONG_INLINE Index innerSize() const { return m_size; }
86  EIGEN_STRONG_INLINE Index outerSize() const { return 1; }
87 
88  EIGEN_STRONG_INLINE const Scalar* valuePtr() const { return m_data.valuePtr(); }
89  EIGEN_STRONG_INLINE Scalar* valuePtr() { return m_data.valuePtr(); }
90 
91  EIGEN_STRONG_INLINE const StorageIndex* innerIndexPtr() const { return m_data.indexPtr(); }
92  EIGEN_STRONG_INLINE StorageIndex* innerIndexPtr() { return m_data.indexPtr(); }
93 
94  inline const StorageIndex* outerIndexPtr() const { return 0; }
95  inline StorageIndex* outerIndexPtr() { return 0; }
96  inline const StorageIndex* innerNonZeroPtr() const { return 0; }
97  inline StorageIndex* innerNonZeroPtr() { return 0; }
98 
100  inline Storage& data() { return m_data; }
102  inline const Storage& data() const { return m_data; }
103 
104  inline Scalar coeff(Index row, Index col) const
105  {
106  eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
107  return coeff(IsColVector ? row : col);
108  }
109  inline Scalar coeff(Index i) const
110  {
111  eigen_assert(i>=0 && i<m_size);
112  return m_data.at(StorageIndex(i));
113  }
114 
116  {
117  eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
118  return coeffRef(IsColVector ? row : col);
119  }
120 
128  {
129  eigen_assert(i>=0 && i<m_size);
130 
131  return m_data.atWithInsertion(StorageIndex(i));
132  }
133 
134  public:
135 
136  typedef typename Base::InnerIterator InnerIterator;
137  typedef typename Base::ReverseInnerIterator ReverseInnerIterator;
138 
139  inline void setZero() { m_data.clear(); }
140 
142  inline Index nonZeros() const { return m_data.size(); }
143 
144  inline void startVec(Index outer)
145  {
146  EIGEN_UNUSED_VARIABLE(outer);
147  eigen_assert(outer==0);
148  }
149 
150  inline Scalar& insertBackByOuterInner(Index outer, Index inner)
151  {
152  EIGEN_UNUSED_VARIABLE(outer);
153  eigen_assert(outer==0);
154  return insertBack(inner);
155  }
157  {
158  m_data.append(0, i);
159  return m_data.value(m_data.size()-1);
160  }
161 
163  {
164  EIGEN_UNUSED_VARIABLE(outer);
165  eigen_assert(outer==0);
166  return insertBackUnordered(inner);
167  }
169  {
170  m_data.append(0, i);
171  return m_data.value(m_data.size()-1);
172  }
173 
175  {
176  eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
177 
178  Index inner = IsColVector ? row : col;
179  Index outer = IsColVector ? col : row;
181  eigen_assert(outer==0);
182  return insert(inner);
183  }
185  {
186  eigen_assert(i>=0 && i<m_size);
187 
188  Index startId = 0;
189  Index p = Index(m_data.size()) - 1;
190  // TODO smart realloc
191  m_data.resize(p+2,1);
192 
193  while ( (p >= startId) && (m_data.index(p) > i) )
194  {
195  m_data.index(p+1) = m_data.index(p);
196  m_data.value(p+1) = m_data.value(p);
197  --p;
198  }
199  m_data.index(p+1) = convert_index(i);
200  m_data.value(p+1) = 0;
201  return m_data.value(p+1);
202  }
203 
206  inline void reserve(Index reserveSize) { m_data.reserve(reserveSize); }
207 
208 
209  inline void finalize() {}
210 
212  Index prune(const Scalar& reference, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision()) {
213  return prune([&](const Scalar& val){ return !internal::isMuchSmallerThan(val, reference, epsilon); });
214  }
215 
223  template<class F>
224  Index prune(F&& keep_predicate)
225  {
226  Index k = 0;
227  Index n = m_data.size();
228  for (Index i = 0; i < n; ++i)
229  {
230  if (keep_predicate(m_data.value(i)))
231  {
232  m_data.value(k) = std::move(m_data.value(i));
233  m_data.index(k) = m_data.index(i);
234  ++k;
235  }
236  }
237  m_data.resize(k);
238  return k;
239  }
240 
250  {
251  eigen_assert((IsColVector ? cols : rows)==1 && "Outer dimension must equal 1");
253  }
254 
259  void resize(Index newSize)
260  {
261  m_size = newSize;
262  m_data.clear();
263  }
264 
272  void conservativeResize(Index newSize)
273  {
274  if (newSize < m_size)
275  {
276  Index i = 0;
277  while (i<m_data.size() && m_data.index(i)<newSize) ++i;
278  m_data.resize(i);
279  }
280  m_size = newSize;
281  }
282 
283  void resizeNonZeros(Index size) { m_data.resize(size); }
284 
285  inline SparseVector() : m_size(0) { resize(0); }
286 
287  explicit inline SparseVector(Index size) : m_size(0) { resize(size); }
288 
290 
291  template<typename OtherDerived>
293  : m_size(0)
294  {
295  #ifdef EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
296  EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
297  #endif
298  *this = other.derived();
299  }
300 
301  inline SparseVector(const SparseVector& other)
302  : Base(other), m_size(0)
303  {
304  *this = other.derived();
305  }
306 
311  inline void swap(SparseVector& other)
312  {
313  std::swap(m_size, other.m_size);
314  m_data.swap(other.m_data);
315  }
316 
317  template<int OtherOptions>
319  {
320  eigen_assert(other.outerSize()==1);
321  std::swap(m_size, other.m_innerSize);
322  m_data.swap(other.m_data);
323  }
324 
325  inline SparseVector& operator=(const SparseVector& other)
326  {
327  if (other.isRValue())
328  {
329  swap(other.const_cast_derived());
330  }
331  else
332  {
333  resize(other.size());
334  m_data = other.m_data;
335  }
336  return *this;
337  }
338 
339  template<typename OtherDerived>
341  {
342  SparseVector tmp(other.size());
343  internal::sparse_vector_assign_selector<SparseVector,OtherDerived>::run(tmp,other.derived());
344  this->swap(tmp);
345  return *this;
346  }
347 
348  #ifndef EIGEN_PARSED_BY_DOXYGEN
349  template<typename Lhs, typename Rhs>
350  inline SparseVector& operator=(const SparseSparseProduct<Lhs,Rhs>& product)
351  {
352  return Base::operator=(product);
353  }
354  #endif
355 
356 #ifndef EIGEN_NO_IO
357  friend std::ostream & operator << (std::ostream & s, const SparseVector& m)
358  {
359  for (Index i=0; i<m.nonZeros(); ++i)
360  s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") ";
361  s << std::endl;
362  return s;
363  }
364 #endif
365 
367  inline ~SparseVector() {}
368 
370  Scalar sum() const;
371 
372  public:
373 
376  {
377  setZero();
378  m_data.reserve(reserve);
379  }
380 
383  {
384  eigen_assert(r==0 || c==0);
385  return fill(IsColVector ? r : c);
386  }
387 
390  {
391  m_data.append(0, i);
392  return m_data.value(m_data.size()-1);
393  }
394 
397  {
398  eigen_assert(r==0 || c==0);
399  return fillrand(IsColVector ? r : c);
400  }
401 
404  {
405  return insert(i);
406  }
407 
410 
411  // These two functions were here in the 3.1 release, so let's keep them in case some code rely on them.
413  EIGEN_DEPRECATED Storage& _data() { return m_data; }
415  EIGEN_DEPRECATED const Storage& _data() const { return m_data; }
416 
417 # ifdef EIGEN_SPARSEVECTOR_PLUGIN
418 # include EIGEN_SPARSEVECTOR_PLUGIN
419 # endif
420 
421 protected:
422  EIGEN_STATIC_ASSERT(NumTraits<StorageIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE)
423  EIGEN_STATIC_ASSERT((Options_&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS)
424 
425  Storage m_data;
427 };
428 
429 namespace internal {
430 
431 template<typename Scalar_, int Options_, typename Index_>
432 struct evaluator<SparseVector<Scalar_,Options_,Index_> >
433  : evaluator_base<SparseVector<Scalar_,Options_,Index_> >
434 {
435  typedef SparseVector<Scalar_,Options_,Index_> SparseVectorType;
436  typedef evaluator_base<SparseVectorType> Base;
437  typedef typename SparseVectorType::InnerIterator InnerIterator;
438  typedef typename SparseVectorType::ReverseInnerIterator ReverseInnerIterator;
439 
440  enum {
441  CoeffReadCost = NumTraits<Scalar_>::ReadCost,
442  Flags = SparseVectorType::Flags
443  };
444 
445  evaluator() : Base() {}
446 
447  explicit evaluator(const SparseVectorType &mat) : m_matrix(&mat)
448  {
449  EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
450  }
451 
452  inline Index nonZerosEstimate() const {
453  return m_matrix->nonZeros();
454  }
455 
456  operator SparseVectorType&() { return m_matrix->const_cast_derived(); }
457  operator const SparseVectorType&() const { return *m_matrix; }
458 
459  const SparseVectorType *m_matrix;
460 };
461 
462 template< typename Dest, typename Src>
463 struct sparse_vector_assign_selector<Dest,Src,SVA_Inner> {
464  static void run(Dest& dst, const Src& src) {
465  eigen_internal_assert(src.innerSize()==src.size());
466  typedef internal::evaluator<Src> SrcEvaluatorType;
467  SrcEvaluatorType srcEval(src);
468  for(typename SrcEvaluatorType::InnerIterator it(srcEval, 0); it; ++it)
469  dst.insert(it.index()) = it.value();
470  }
471 };
472 
473 template< typename Dest, typename Src>
474 struct sparse_vector_assign_selector<Dest,Src,SVA_Outer> {
475  static void run(Dest& dst, const Src& src) {
476  eigen_internal_assert(src.outerSize()==src.size());
477  typedef internal::evaluator<Src> SrcEvaluatorType;
478  SrcEvaluatorType srcEval(src);
479  for(Index i=0; i<src.size(); ++i)
480  {
481  typename SrcEvaluatorType::InnerIterator it(srcEval, i);
482  if(it)
483  dst.insert(i) = it.value();
484  }
485  }
486 };
487 
488 template< typename Dest, typename Src>
489 struct sparse_vector_assign_selector<Dest,Src,SVA_RuntimeSwitch> {
490  static void run(Dest& dst, const Src& src) {
491  if(src.outerSize()==1) sparse_vector_assign_selector<Dest,Src,SVA_Inner>::run(dst, src);
492  else sparse_vector_assign_selector<Dest,Src,SVA_Outer>::run(dst, src);
493  }
494 };
495 
496 }
497 
498 // Specialization for SparseVector.
499 // Serializes [size, numNonZeros, innerIndices, values].
500 template <typename Scalar, int Options, typename StorageIndex>
502  public:
504 
505  struct Header {
508  };
509 
510  EIGEN_DEVICE_FUNC size_t size(const SparseMat& value) const {
511  return sizeof(Header) +
512  (sizeof(Scalar) + sizeof(StorageIndex)) * value.nonZeros();
513  }
514 
516  const SparseMat& value) {
517  if (EIGEN_PREDICT_FALSE(dest == nullptr)) return nullptr;
518  if (EIGEN_PREDICT_FALSE(dest + size(value) > end)) return nullptr;
519 
520  const size_t header_bytes = sizeof(Header);
521  Header header = {value.innerSize(), value.nonZeros()};
522  EIGEN_USING_STD(memcpy)
523  memcpy(dest, &header, header_bytes);
524  dest += header_bytes;
525 
526  // Inner indices.
527  std::size_t data_bytes = sizeof(StorageIndex) * header.num_non_zeros;
528  memcpy(dest, value.innerIndexPtr(), data_bytes);
529  dest += data_bytes;
530 
531  // Values.
532  data_bytes = sizeof(Scalar) * header.num_non_zeros;
533  memcpy(dest, value.valuePtr(), data_bytes);
534  dest += data_bytes;
535 
536  return dest;
537  }
538 
540  const uint8_t* end,
541  SparseMat& value) const {
542  if (EIGEN_PREDICT_FALSE(src == nullptr)) return nullptr;
543  if (EIGEN_PREDICT_FALSE(src + sizeof(Header) > end)) return nullptr;
544 
545  const size_t header_bytes = sizeof(Header);
546  Header header;
547  EIGEN_USING_STD(memcpy)
548  memcpy(&header, src, header_bytes);
549  src += header_bytes;
550 
551  value.setZero();
552  value.resize(header.size);
553  value.resizeNonZeros(header.num_non_zeros);
554 
555  // Inner indices.
556  std::size_t data_bytes = sizeof(StorageIndex) * header.num_non_zeros;
557  if (EIGEN_PREDICT_FALSE(src + data_bytes > end)) return nullptr;
558  memcpy(value.innerIndexPtr(), src, data_bytes);
559  src += data_bytes;
560 
561  // Values.
562  data_bytes = sizeof(Scalar) * header.num_non_zeros;
563  if (EIGEN_PREDICT_FALSE(src + data_bytes > end)) return nullptr;
564  memcpy(value.valuePtr(), src, data_bytes);
565  src += data_bytes;
566  return src;
567  }
568 };
569 
570 } // end namespace Eigen
571 
572 #endif // EIGEN_SPARSEVECTOR_H
Matrix3f m
int n
RowXpr row(Index i)
This is the const version of row(). *‍/.
ColXpr col(Index i)
This is the const version of col().
Array33i c
if((m *x).isApprox(y))
#define EIGEN_DEPRECATED
Definition: Macros.h:923
#define EIGEN_USING_STD(FUNC)
Definition: Macros.h:1080
#define eigen_internal_assert(x)
Definition: Macros.h:908
#define EIGEN_PREDICT_FALSE(x)
Definition: Macros.h:1177
#define EIGEN_UNUSED_VARIABLE(var)
Definition: Macros.h:957
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:883
#define EIGEN_ONLY_USED_FOR_DEBUG(x)
Definition: Macros.h:914
#define eigen_assert(x)
Definition: Macros.h:902
#define EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
Definition: SparseUtil.h:45
#define EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(Derived, Op)
Definition: SparseUtil.h:23
#define EIGEN_INTERNAL_CHECK_COST_VALUE(C)
Definition: StaticAssert.h:112
float * p
const uint8_t * deserialize(const uint8_t *src, const uint8_t *end, SparseMat &value) const
Definition: SparseVector.h:539
uint8_t * serialize(uint8_t *dest, uint8_t *end, const SparseMat &value)
Definition: SparseVector.h:515
Common base class for sparse [compressed]-{row|column}-storage format.
SparseVector< Scalar_, Options_, StorageIndex_ > & operator=(const SparseVector< Scalar_, Options_, StorageIndex_ > &other)
Definition: SparseAssign.h:45
Base class of any sparse matrices or sparse expressions.
internal::traits< SparseVector< Scalar_, Options_, StorageIndex_ > >::StorageIndex StorageIndex
internal::traits< SparseVector< Scalar_, Options_, StorageIndex_ > >::Scalar Scalar
static StorageIndex convert_index(const Index idx)
A versatible sparse matrix representation.
Definition: SparseMatrix.h:125
Index outerSize() const
Definition: SparseMatrix.h:172
a sparse vector class
Definition: SparseVector.h:68
void startVec(Index outer)
Definition: SparseVector.h:144
EIGEN_DEPRECATED Scalar & fillrand(Index r, Index c)
Definition: SparseVector.h:396
Scalar & insertBackByOuterInnerUnordered(Index outer, Index inner)
Definition: SparseVector.h:162
Scalar & coeffRef(Index row, Index col)
Definition: SparseVector.h:115
StorageIndex * innerNonZeroPtr()
Definition: SparseVector.h:97
void resizeNonZeros(Index size)
Definition: SparseVector.h:283
const Scalar * valuePtr() const
Definition: SparseVector.h:88
EIGEN_DEPRECATED Scalar & fill(Index i)
Definition: SparseVector.h:389
Scalar & insert(Index row, Index col)
Definition: SparseVector.h:174
Scalar * valuePtr()
Definition: SparseVector.h:89
void conservativeResize(Index newSize)
Definition: SparseVector.h:272
SparseVector(Index rows, Index cols)
Definition: SparseVector.h:289
Scalar & insertBackByOuterInner(Index outer, Index inner)
Definition: SparseVector.h:150
internal::CompressedStorage< Scalar, StorageIndex > Storage
Definition: SparseVector.h:76
const StorageIndex * outerIndexPtr() const
Definition: SparseVector.h:94
Index prune(const Scalar &reference, const RealScalar &epsilon=NumTraits< RealScalar >::dummy_precision())
Definition: SparseVector.h:212
friend std::ostream & operator<<(std::ostream &s, const SparseVector &m)
Definition: SparseVector.h:357
void resize(Index rows, Index cols)
Definition: SparseVector.h:249
Scalar & coeffRef(Index i)
Definition: SparseVector.h:127
Index cols() const
Definition: SparseVector.h:84
Scalar & insert(Index i)
Definition: SparseVector.h:184
StorageIndex * innerIndexPtr()
Definition: SparseVector.h:92
const StorageIndex * innerNonZeroPtr() const
Definition: SparseVector.h:96
void swap(SparseVector &other)
Definition: SparseVector.h:311
void swap(SparseMatrix< Scalar, OtherOptions, StorageIndex > &other)
Definition: SparseVector.h:318
const StorageIndex * innerIndexPtr() const
Definition: SparseVector.h:91
Index outerSize() const
Definition: SparseVector.h:86
Scalar & insertBack(Index i)
Definition: SparseVector.h:156
Index prune(F &&keep_predicate)
Prunes the entries of the vector based on a predicate
Definition: SparseVector.h:224
Scalar coeff(Index row, Index col) const
Definition: SparseVector.h:104
SparseVector & operator=(const SparseMatrixBase< OtherDerived > &other)
Definition: SparseVector.h:340
const Storage & data() const
Definition: SparseVector.h:102
EIGEN_DEPRECATED void startFill(Index reserve)
Definition: SparseVector.h:375
EIGEN_DEPRECATED Scalar & fillrand(Index i)
Definition: SparseVector.h:403
void reserve(Index reserveSize)
Definition: SparseVector.h:206
Scalar & insertBackUnordered(Index i)
Definition: SparseVector.h:168
Index nonZeros() const
Definition: SparseVector.h:142
SparseVector(Index size)
Definition: SparseVector.h:287
SparseCompressedBase< SparseVector > Base
Definition: SparseVector.h:69
Index rows() const
Definition: SparseVector.h:83
EIGEN_DEPRECATED Scalar & fill(Index r, Index c)
Definition: SparseVector.h:382
SparseVector(const SparseMatrixBase< OtherDerived > &other)
Definition: SparseVector.h:292
StorageIndex * outerIndexPtr()
Definition: SparseVector.h:95
SparseVector(const SparseVector &other)
Definition: SparseVector.h:301
SparseVector & operator=(const SparseVector &other)
Definition: SparseVector.h:325
EIGEN_DEPRECATED void endFill()
Definition: SparseVector.h:409
EIGEN_DEPRECATED const Storage & _data() const
Definition: SparseVector.h:415
void resize(Index newSize)
Definition: SparseVector.h:259
Scalar coeff(Index i) const
Definition: SparseVector.h:109
EIGEN_DEPRECATED Storage & _data()
Definition: SparseVector.h:413
Index innerSize() const
Definition: SparseVector.h:85
EIGEN_STATIC_ASSERT((Options_ &(ColMajor|RowMajor))==Options, INVALID_MATRIX_TEMPLATE_PARAMETERS) Storage m_data
Scalar sum() const
Definition: SparseRedux.h:43
static const lastp1_t end
@ ColMajor
Definition: Constants.h:321
@ RowMajor
Definition: Constants.h:323
const unsigned int LvalueBit
Definition: Constants.h:146
const unsigned int RowMajorBit
Definition: Constants.h:68
const unsigned int CompressedAccessBit
Definition: Constants.h:193
bool isMuchSmallerThan(const Scalar &x, const OtherScalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
void swap(scoped_array< T > &a, scoped_array< T > &b)
Definition: Memory.h:788
std::uint8_t uint8_t
Definition: Meta.h:35
: InteropHeaders
Definition: Core:139
const unsigned int NestByRefBit
Definition: Constants.h:171
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
const int InnerRandomAccessPattern
Definition: SparseUtil.h:50
const int Dynamic
Definition: Constants.h:24
Derived & derived()
Definition: EigenBase.h:48
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:41
Derived & const_cast_derived() const
Definition: EigenBase.h:54
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:231