Eigen  3.2.92
SparseVector.h
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 namespace Eigen {
14 
28 namespace internal {
29 template<typename _Scalar, int _Options, typename _StorageIndex>
30 struct traits<SparseVector<_Scalar, _Options, _StorageIndex> >
31 {
32  typedef _Scalar Scalar;
33  typedef _StorageIndex StorageIndex;
34  typedef Sparse StorageKind;
35  typedef MatrixXpr XprKind;
36  enum {
37  IsColVector = (_Options & RowMajorBit) ? 0 : 1,
38 
39  RowsAtCompileTime = IsColVector ? Dynamic : 1,
40  ColsAtCompileTime = IsColVector ? 1 : Dynamic,
41  MaxRowsAtCompileTime = RowsAtCompileTime,
42  MaxColsAtCompileTime = ColsAtCompileTime,
43  Flags = _Options | NestByRefBit | LvalueBit | (IsColVector ? 0 : RowMajorBit) | CompressedAccessBit,
44  SupportedAccessPatterns = InnerRandomAccessPattern
45  };
46 };
47 
48 // Sparse-Vector-Assignment kinds:
49 enum {
50  SVA_RuntimeSwitch,
51  SVA_Inner,
52  SVA_Outer
53 };
54 
55 template< typename Dest, typename Src,
56  int AssignmentKind = !bool(Src::IsVectorAtCompileTime) ? SVA_RuntimeSwitch
57  : Src::InnerSizeAtCompileTime==1 ? SVA_Outer
58  : SVA_Inner>
59 struct sparse_vector_assign_selector;
60 
61 }
62 
63 template<typename _Scalar, int _Options, typename _StorageIndex>
64 class SparseVector
65  : public SparseCompressedBase<SparseVector<_Scalar, _Options, _StorageIndex> >
66 {
67  typedef SparseCompressedBase<SparseVector> Base;
68  using Base::convert_index;
69  public:
70  EIGEN_SPARSE_PUBLIC_INTERFACE(SparseVector)
71  EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, +=)
72  EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, -=)
73 
74  typedef internal::CompressedStorage<Scalar,StorageIndex> Storage;
75  enum { IsColVector = internal::traits<SparseVector>::IsColVector };
76 
77  enum {
78  Options = _Options
79  };
80 
81  EIGEN_STRONG_INLINE Index rows() const { return IsColVector ? m_size : 1; }
82  EIGEN_STRONG_INLINE Index cols() const { return IsColVector ? 1 : m_size; }
83  EIGEN_STRONG_INLINE Index innerSize() const { return m_size; }
84  EIGEN_STRONG_INLINE Index outerSize() const { return 1; }
85 
86  EIGEN_STRONG_INLINE const Scalar* valuePtr() const { return &m_data.value(0); }
87  EIGEN_STRONG_INLINE Scalar* valuePtr() { return &m_data.value(0); }
88 
89  EIGEN_STRONG_INLINE const StorageIndex* innerIndexPtr() const { return &m_data.index(0); }
90  EIGEN_STRONG_INLINE StorageIndex* innerIndexPtr() { return &m_data.index(0); }
91 
92  inline const StorageIndex* outerIndexPtr() const { return 0; }
93  inline StorageIndex* outerIndexPtr() { return 0; }
94  inline const StorageIndex* innerNonZeroPtr() const { return 0; }
95  inline StorageIndex* innerNonZeroPtr() { return 0; }
96 
98  inline Storage& data() { return m_data; }
100  inline const Storage& data() const { return m_data; }
101 
102  inline Scalar coeff(Index row, Index col) const
103  {
104  eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
105  return coeff(IsColVector ? row : col);
106  }
107  inline Scalar coeff(Index i) const
108  {
109  eigen_assert(i>=0 && i<m_size);
110  return m_data.at(StorageIndex(i));
111  }
112 
113  inline Scalar& coeffRef(Index row, Index col)
114  {
115  eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
116  return coeffRef(IsColVector ? row : col);
117  }
118 
125  inline Scalar& coeffRef(Index i)
126  {
127  eigen_assert(i>=0 && i<m_size);
128  return m_data.atWithInsertion(StorageIndex(i));
129  }
130 
131  public:
132 
133  typedef typename Base::InnerIterator InnerIterator;
134  typedef typename Base::ReverseInnerIterator ReverseInnerIterator;
135 
136  inline void setZero() { m_data.clear(); }
137 
139  inline Index nonZeros() const { return m_data.size(); }
140 
141  inline void startVec(Index outer)
142  {
143  EIGEN_UNUSED_VARIABLE(outer);
144  eigen_assert(outer==0);
145  }
146 
147  inline Scalar& insertBackByOuterInner(Index outer, Index inner)
148  {
149  EIGEN_UNUSED_VARIABLE(outer);
150  eigen_assert(outer==0);
151  return insertBack(inner);
152  }
153  inline Scalar& insertBack(Index i)
154  {
155  m_data.append(0, i);
156  return m_data.value(m_data.size()-1);
157  }
158 
159  Scalar& insertBackByOuterInnerUnordered(Index outer, Index inner)
160  {
161  EIGEN_UNUSED_VARIABLE(outer);
162  eigen_assert(outer==0);
163  return insertBackUnordered(inner);
164  }
165  inline Scalar& insertBackUnordered(Index i)
166  {
167  m_data.append(0, i);
168  return m_data.value(m_data.size()-1);
169  }
170 
171  inline Scalar& insert(Index row, Index col)
172  {
173  eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size));
174 
175  Index inner = IsColVector ? row : col;
176  Index outer = IsColVector ? col : row;
177  EIGEN_ONLY_USED_FOR_DEBUG(outer);
178  eigen_assert(outer==0);
179  return insert(inner);
180  }
181  Scalar& insert(Index i)
182  {
183  eigen_assert(i>=0 && i<m_size);
184 
185  Index startId = 0;
186  Index p = Index(m_data.size()) - 1;
187  // TODO smart realloc
188  m_data.resize(p+2,1);
189 
190  while ( (p >= startId) && (m_data.index(p) > i) )
191  {
192  m_data.index(p+1) = m_data.index(p);
193  m_data.value(p+1) = m_data.value(p);
194  --p;
195  }
196  m_data.index(p+1) = convert_index(i);
197  m_data.value(p+1) = 0;
198  return m_data.value(p+1);
199  }
200 
203  inline void reserve(Index reserveSize) { m_data.reserve(reserveSize); }
204 
205 
206  inline void finalize() {}
207 
208  void prune(const Scalar& reference, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision())
209  {
210  m_data.prune(reference,epsilon);
211  }
212 
213  void resize(Index rows, Index cols)
214  {
215  eigen_assert((IsColVector ? cols : rows)==1 && "Outer dimension must equal 1");
216  resize(IsColVector ? rows : cols);
217  }
218 
219  void resize(Index newSize)
220  {
221  m_size = newSize;
222  m_data.clear();
223  }
224 
225  void resizeNonZeros(Index size) { m_data.resize(size); }
226 
227  inline SparseVector() : m_size(0) { check_template_parameters(); resize(0); }
228 
229  explicit inline SparseVector(Index size) : m_size(0) { check_template_parameters(); resize(size); }
230 
231  inline SparseVector(Index rows, Index cols) : m_size(0) { check_template_parameters(); resize(rows,cols); }
232 
233  template<typename OtherDerived>
234  inline SparseVector(const SparseMatrixBase<OtherDerived>& other)
235  : m_size(0)
236  {
237  #ifdef EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
238  EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
239  #endif
240  check_template_parameters();
241  *this = other.derived();
242  }
243 
244  inline SparseVector(const SparseVector& other)
245  : Base(other), m_size(0)
246  {
247  check_template_parameters();
248  *this = other.derived();
249  }
250 
255  inline void swap(SparseVector& other)
256  {
257  std::swap(m_size, other.m_size);
258  m_data.swap(other.m_data);
259  }
260 
261  inline SparseVector& operator=(const SparseVector& other)
262  {
263  if (other.isRValue())
264  {
265  swap(other.const_cast_derived());
266  }
267  else
268  {
269  resize(other.size());
270  m_data = other.m_data;
271  }
272  return *this;
273  }
274 
275  template<typename OtherDerived>
276  inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& other)
277  {
278  SparseVector tmp(other.size());
279  internal::sparse_vector_assign_selector<SparseVector,OtherDerived>::run(tmp,other.derived());
280  this->swap(tmp);
281  return *this;
282  }
283 
284  #ifndef EIGEN_PARSED_BY_DOXYGEN
285  template<typename Lhs, typename Rhs>
286  inline SparseVector& operator=(const SparseSparseProduct<Lhs,Rhs>& product)
287  {
288  return Base::operator=(product);
289  }
290  #endif
291 
292  friend std::ostream & operator << (std::ostream & s, const SparseVector& m)
293  {
294  for (Index i=0; i<m.nonZeros(); ++i)
295  s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") ";
296  s << std::endl;
297  return s;
298  }
299 
301  inline ~SparseVector() {}
302 
304  Scalar sum() const;
305 
306  public:
307 
309  EIGEN_DEPRECATED void startFill(Index reserve)
310  {
311  setZero();
312  m_data.reserve(reserve);
313  }
314 
316  EIGEN_DEPRECATED Scalar& fill(Index r, Index c)
317  {
318  eigen_assert(r==0 || c==0);
319  return fill(IsColVector ? r : c);
320  }
321 
323  EIGEN_DEPRECATED Scalar& fill(Index i)
324  {
325  m_data.append(0, i);
326  return m_data.value(m_data.size()-1);
327  }
328 
330  EIGEN_DEPRECATED Scalar& fillrand(Index r, Index c)
331  {
332  eigen_assert(r==0 || c==0);
333  return fillrand(IsColVector ? r : c);
334  }
335 
337  EIGEN_DEPRECATED Scalar& fillrand(Index i)
338  {
339  return insert(i);
340  }
341 
343  EIGEN_DEPRECATED void endFill() {}
344 
345  // These two functions were here in the 3.1 release, so let's keep them in case some code rely on them.
347  EIGEN_DEPRECATED Storage& _data() { return m_data; }
349  EIGEN_DEPRECATED const Storage& _data() const { return m_data; }
350 
351 # ifdef EIGEN_SPARSEVECTOR_PLUGIN
352 # include EIGEN_SPARSEVECTOR_PLUGIN
353 # endif
354 
355 protected:
356 
357  static void check_template_parameters()
358  {
359  EIGEN_STATIC_ASSERT(NumTraits<StorageIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
360  EIGEN_STATIC_ASSERT((_Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS);
361  }
362 
363  Storage m_data;
364  Index m_size;
365 };
366 
367 namespace internal {
368 
369 template<typename _Scalar, int _Options, typename _Index>
370 struct evaluator<SparseVector<_Scalar,_Options,_Index> >
371  : evaluator_base<SparseVector<_Scalar,_Options,_Index> >
372 {
373  typedef SparseVector<_Scalar,_Options,_Index> SparseVectorType;
374  typedef typename SparseVectorType::InnerIterator InnerIterator;
375  typedef typename SparseVectorType::ReverseInnerIterator ReverseInnerIterator;
376 
377  enum {
378  CoeffReadCost = NumTraits<_Scalar>::ReadCost,
379  Flags = SparseVectorType::Flags
380  };
381 
382  explicit evaluator(const SparseVectorType &mat) : m_matrix(mat)
383  {
384  EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
385  }
386 
387  inline Index nonZerosEstimate() const {
388  return m_matrix.nonZeros();
389  }
390 
391  operator SparseVectorType&() { return m_matrix.const_cast_derived(); }
392  operator const SparseVectorType&() const { return m_matrix; }
393 
394  const SparseVectorType &m_matrix;
395 };
396 
397 template< typename Dest, typename Src>
398 struct sparse_vector_assign_selector<Dest,Src,SVA_Inner> {
399  static void run(Dest& dst, const Src& src) {
400  eigen_internal_assert(src.innerSize()==src.size());
401  typedef internal::evaluator<Src> SrcEvaluatorType;
402  SrcEvaluatorType srcEval(src);
403  for(typename SrcEvaluatorType::InnerIterator it(srcEval, 0); it; ++it)
404  dst.insert(it.index()) = it.value();
405  }
406 };
407 
408 template< typename Dest, typename Src>
409 struct sparse_vector_assign_selector<Dest,Src,SVA_Outer> {
410  static void run(Dest& dst, const Src& src) {
411  eigen_internal_assert(src.outerSize()==src.size());
412  typedef internal::evaluator<Src> SrcEvaluatorType;
413  SrcEvaluatorType srcEval(src);
414  for(Index i=0; i<src.size(); ++i)
415  {
416  typename SrcEvaluatorType::InnerIterator it(srcEval, i);
417  if(it)
418  dst.insert(i) = it.value();
419  }
420  }
421 };
422 
423 template< typename Dest, typename Src>
424 struct sparse_vector_assign_selector<Dest,Src,SVA_RuntimeSwitch> {
425  static void run(Dest& dst, const Src& src) {
426  if(src.outerSize()==1) sparse_vector_assign_selector<Dest,Src,SVA_Inner>::run(dst, src);
427  else sparse_vector_assign_selector<Dest,Src,SVA_Outer>::run(dst, src);
428  }
429 };
430 
431 }
432 
433 } // end namespace Eigen
434 
435 #endif // EIGEN_SPARSEVECTOR_H
Index size() const
Definition: SparseMatrixBase.h:168
const unsigned int CompressedAccessBit
Definition: Constants.h:185
RowXpr row(Index i)
Definition: SparseMatrixBase.h:797
const unsigned int LvalueBit
Definition: Constants.h:138
Scalar & coeffRef(Index i)
Definition: SparseVector.h:125
Definition: LDLT.h:16
Index nonZeros() const
Definition: SparseVector.h:139
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:37
const unsigned int RowMajorBit
Definition: Constants.h:61
~SparseVector()
Definition: SparseVector.h:301
void swap(SparseVector &other)
Definition: SparseVector.h:255
Definition: Constants.h:320
Scalar sum() const
Definition: SparseRedux.h:38
Definition: Constants.h:322
a sparse vector class
Definition: SparseUtil.h:54
Definition: Eigen_Colamd.h:54
ColXpr col(Index i)
Definition: SparseMatrixBase.h:778