Medial Code Documentation
Loading...
Searching...
No Matches
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
13namespace Eigen {
14
28namespace internal {
29template<typename _Scalar, int _Options, typename _StorageIndex>
30struct 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:
49enum {
50 SVA_RuntimeSwitch,
51 SVA_Inner,
52 SVA_Outer
53};
54
55template< typename Dest, typename Src,
56 int AssignmentKind = !bool(Src::IsVectorAtCompileTime) ? SVA_RuntimeSwitch
57 : Src::InnerSizeAtCompileTime==1 ? SVA_Outer
58 : SVA_Inner>
60
61}
62
63template<typename _Scalar, int _Options, typename _StorageIndex>
65 : public SparseCompressedBase<SparseVector<_Scalar, _Options, _StorageIndex> >
66{
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
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
355protected:
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
367namespace internal {
368
369template<typename _Scalar, int _Options, typename _Index>
370struct evaluator<SparseVector<_Scalar,_Options,_Index> >
371 : evaluator_base<SparseVector<_Scalar,_Options,_Index> >
372{
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
397template< typename Dest, typename Src>
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
408template< typename Dest, typename Src>
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
423template< typename Dest, typename Src>
424struct sparse_vector_assign_selector<Dest,Src,SVA_RuntimeSwitch> {
425 static void run(Dest& dst, const Src& src) {
428 }
429};
430
431}
432
433} // end namespace Eigen
434
435#endif // EIGEN_SPARSEVECTOR_H
An InnerIterator allows to loop over the element of any matrix expression.
Definition CoreIterators.h:34
Pseudo expression representing a solving operation.
Definition Solve.h:63
Definition SparseCompressedBase.h:28
Index size() const
Definition SparseMatrixBase.h:168
NumTraits< Scalar >::Real RealScalar
This is the "real scalar" type; if the Scalar type is already real numbers (e.g.
Definition SparseMatrixBase.h:125
a sparse vector class
Definition SparseVector.h:66
Scalar sum() const
Overloaded for performance.
Definition SparseRedux.h:38
Scalar & coeffRef(Index i)
Definition SparseVector.h:125
void swap(SparseVector &other)
Swaps the values of *this and other.
Definition SparseVector.h:255
~SparseVector()
Destructor.
Definition SparseVector.h:301
Index nonZeros() const
Definition SparseVector.h:139
Definition CompressedStorage.h:23
Scalar at(Index key, const Scalar &defaultValue=Scalar(0)) const
Definition CompressedStorage.h:141
Scalar & atWithInsertion(Index key, const Scalar &defaultValue=Scalar(0))
Definition CompressedStorage.h:169
@ ColMajor
Storage order is column major (see TopicStorageOrders).
Definition Constants.h:320
@ RowMajor
Storage order is row major (see TopicStorageOrders).
Definition Constants.h:322
const unsigned int LvalueBit
Means the expression has a coeffRef() method, i.e.
Definition Constants.h:138
const unsigned int RowMajorBit
for a matrix, this means that the storage order is row-major.
Definition Constants.h:61
const unsigned int CompressedAccessBit
Means that the underlying coefficients can be accessed through pointers to the sparse (un)compressed ...
Definition Constants.h:185
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition json.hpp:24418
Eigen::Index Index
The interface type of indices.
Definition EigenBase.h:37
The type used to identify a matrix expression.
Definition Constants.h:505
Holds information about the various numeric (i.e.
Definition NumTraits.h:108
The type used to identify a general sparse storage.
Definition Constants.h:493
Definition CoreEvaluators.h:101
Definition CoreEvaluators.h:82
Definition ForwardDeclarations.h:17