11#ifndef EIGEN_SPARSEVECTOR_H
12#define EIGEN_SPARSEVECTOR_H
15#include "./InternalHeaderCheck.h"
33template <
typename Scalar_,
int Options_,
typename StorageIndex_>
34struct traits<SparseVector<Scalar_, Options_, StorageIndex_> > {
35 using Scalar = Scalar_;
36 using StorageIndex = StorageIndex_;
37 using StorageKind = Sparse;
38 using XprKind = MatrixXpr;
42 RowsAtCompileTime = IsColVector ? Dynamic : 1,
43 ColsAtCompileTime = IsColVector ? 1 : Dynamic,
44 MaxRowsAtCompileTime = RowsAtCompileTime,
45 MaxColsAtCompileTime = ColsAtCompileTime,
47 SupportedAccessPatterns = InnerRandomAccessPattern
52enum { SVA_RuntimeSwitch, SVA_Inner, SVA_Outer };
54template <
typename Dest,
typename Src,
55 int AssignmentKind = !bool(Src::IsVectorAtCompileTime) ? SVA_RuntimeSwitch
56 : Src::InnerSizeAtCompileTime == 1 ? SVA_Outer
58struct sparse_vector_assign_selector;
62template <
typename Scalar_,
int Options_,
typename StorageIndex_>
65 using Base::convert_index;
68 EIGEN_SPARSE_PUBLIC_INTERFACE(SparseVector)
69 EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, +=)
70 EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, -=)
72 using Storage = internal::CompressedStorage<Scalar, StorageIndex>;
73 enum { IsColVector = internal::traits<SparseVector>::IsColVector };
75 enum { Options = Options_ };
77 EIGEN_STRONG_INLINE Index rows()
const {
return IsColVector ? m_size : 1; }
78 EIGEN_STRONG_INLINE Index cols()
const {
return IsColVector ? 1 : m_size; }
79 EIGEN_STRONG_INLINE Index innerSize()
const {
return m_size; }
80 EIGEN_STRONG_INLINE Index outerSize()
const {
return 1; }
82 EIGEN_STRONG_INLINE
const Scalar* valuePtr()
const {
return m_data.valuePtr(); }
83 EIGEN_STRONG_INLINE Scalar* valuePtr() {
return m_data.valuePtr(); }
85 EIGEN_STRONG_INLINE
const StorageIndex* innerIndexPtr()
const {
return m_data.indexPtr(); }
86 EIGEN_STRONG_INLINE
StorageIndex* innerIndexPtr() {
return m_data.indexPtr(); }
88 inline const StorageIndex* outerIndexPtr()
const {
return 0; }
90 inline const StorageIndex* innerNonZeroPtr()
const {
return 0; }
94 constexpr Storage& data() {
return m_data; }
96 constexpr const Storage& data()
const {
return m_data; }
98 inline Scalar coeff(Index
row, Index
col)
const {
99 eigen_assert(IsColVector ? (
col == 0 &&
row >= 0 &&
row < m_size) : (
row == 0 &&
col >= 0 &&
col < m_size));
100 return coeff(IsColVector ?
row :
col);
102 inline Scalar coeff(Index i)
const {
103 eigen_assert(i >= 0 && i < m_size);
107 inline Scalar& coeffRef(Index
row, Index
col) {
108 eigen_assert(IsColVector ? (
col == 0 &&
row >= 0 &&
row < m_size) : (
row == 0 &&
col >= 0 &&
col < m_size));
109 return coeffRef(IsColVector ?
row :
col);
119 eigen_assert(i >= 0 && i < m_size);
126 using ReverseInnerIterator =
typename Base::ReverseInnerIterator;
128 inline void setZero() { m_data.clear(); }
131 inline Index
nonZeros()
const {
return m_data.size(); }
133 inline void startVec(Index outer) {
134 EIGEN_UNUSED_VARIABLE(outer);
135 eigen_assert(outer == 0);
138 inline Scalar& insertBackByOuterInner(Index outer, Index inner) {
139 EIGEN_UNUSED_VARIABLE(outer);
140 eigen_assert(outer == 0);
141 return insertBack(inner);
143 inline Scalar& insertBack(Index i) {
144 m_data.append(Scalar(0), i);
145 return m_data.value(m_data.size() - 1);
148 Scalar& insertBackByOuterInnerUnordered(Index outer, Index inner) {
149 EIGEN_UNUSED_VARIABLE(outer);
150 eigen_assert(outer == 0);
151 return insertBackUnordered(inner);
153 inline Scalar& insertBackUnordered(Index i) {
154 m_data.append(Scalar(0), i);
155 return m_data.value(m_data.size() - 1);
158 inline Scalar& insert(Index row, Index col) {
159 eigen_assert(IsColVector ? (col == 0 && row >= 0 && row < m_size) : (row == 0 && col >= 0 && col < m_size));
161 Index inner = IsColVector ? row : col;
162 Index outer = IsColVector ? col : row;
163 EIGEN_ONLY_USED_FOR_DEBUG(outer);
164 eigen_assert(outer == 0);
165 return insert(inner);
167 Scalar& insert(Index i) {
168 eigen_assert(i >= 0 && i < m_size);
171 Index p = Index(m_data.size()) - 1;
173 m_data.resize(p + 2, 1);
175 while ((p >= startId) && (m_data.index(p) > i)) {
176 m_data.index(p + 1) = m_data.index(p);
177 m_data.value(p + 1) = m_data.value(p);
180 m_data.index(p + 1) = convert_index(i);
181 m_data.value(p + 1) = Scalar(0);
182 return m_data.value(p + 1);
185 inline void reserve(Index reserveSize) { m_data.reserve(reserveSize); }
187 inline void finalize() {}
190 Index
prune(
const Scalar& reference,
const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision()) {
191 return prune([&](
const Scalar& val) {
return !internal::isMuchSmallerThan(val, reference, epsilon); });
204 Index n = m_data.size();
205 for (Index i = 0; i < n; ++i) {
206 if (keep_predicate(m_data.value(i))) {
207 m_data.value(k) = std::move(m_data.value(i));
208 m_data.index(k) = m_data.index(i);
225 eigen_assert((IsColVector ? cols : rows) == 1 &&
"Outer dimension must equal 1");
226 resize(IsColVector ? rows : cols);
252 if (newSize < m_size) {
254 while (i < m_data.size() && m_data.index(i) < newSize) ++i;
260 void resizeNonZeros(Index size) { m_data.resize(size); }
262 inline SparseVector() : m_size(0) { resize(0); }
264 explicit inline SparseVector(Index size) : m_size(0) { resize(size); }
266 inline SparseVector(Index rows, Index cols) : m_size(0) { resize(rows, cols); }
268 template <
typename OtherDerived>
269 inline SparseVector(
const SparseMatrixBase<OtherDerived>& other) : m_size(0) {
270#ifdef EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
271 EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN
273 *
this = other.derived();
276 inline SparseVector(
const SparseVector& other) : Base(other), m_size(0) { *
this = other.derived(); }
282 inline void swap(SparseVector& other) {
283 std::swap(m_size, other.m_size);
284 m_data.swap(other.m_data);
288 template <
int OtherOptions>
289 inline void swap(SparseMatrix<Scalar, OtherOptions, StorageIndex>& other) {
290 eigen_assert(other.outerSize() == 1);
291 std::swap(m_size, other.m_innerSize);
292 m_data.swap(other.m_data);
294 template <
int OtherOptions>
295 friend EIGEN_DEVICE_FUNC
void swap(SparseVector& a, SparseMatrix<Scalar, OtherOptions, StorageIndex>& b) {
298 template <
int OtherOptions>
299 friend EIGEN_DEVICE_FUNC
void swap(SparseMatrix<Scalar, OtherOptions, StorageIndex>& a, SparseVector& b) {
303 inline SparseVector& operator=(
const SparseVector& other) {
304 if (other.isRValue()) {
305 swap(other.const_cast_derived());
307 resize(other.size());
308 m_data = other.m_data;
313 template <
typename OtherDerived>
314 inline SparseVector& operator=(
const SparseMatrixBase<OtherDerived>& other) {
315 SparseVector tmp(other.size());
316 internal::sparse_vector_assign_selector<SparseVector, OtherDerived>::run(tmp, other.derived());
321 inline SparseVector(SparseVector&& other) : SparseVector() { this->swap(other); }
323 template <
typename OtherDerived>
324 inline SparseVector(SparseCompressedBase<OtherDerived>&& other) : SparseVector() {
325 *
this = other.derived().markAsRValue();
328 inline SparseVector& operator=(SparseVector&& other) {
333 template <
typename OtherDerived>
334 inline SparseVector& operator=(SparseCompressedBase<OtherDerived>&& other) {
335 *
this = other.derived().markAsRValue();
340 friend std::ostream& operator<<(std::ostream& s,
const SparseVector& m) {
341 for (Index i = 0; i < m.nonZeros(); ++i) s <<
"(" << m.m_data.value(i) <<
"," << m.m_data.index(i) <<
") ";
352 EIGEN_DEPRECATED_WITH_REASON(
"Use .setZero() and .reserve() instead.") void startFill(Index reserve) {
354 m_data.reserve(reserve);
358 EIGEN_DEPRECATED_WITH_REASON(
"Use .insertBack() instead.") Scalar& fill(Index r, Index c) {
359 eigen_assert(r == 0 || c == 0);
360 return fill(IsColVector ? r : c);
364 EIGEN_DEPRECATED_WITH_REASON(
"Use .insertBack() instead.") Scalar& fill(Index i) {
365 m_data.append(Scalar(0), i);
366 return m_data.value(m_data.size() - 1);
370 EIGEN_DEPRECATED_WITH_REASON(
"Use .insert() instead.") Scalar& fillrand(Index r, Index c) {
371 eigen_assert(r == 0 || c == 0);
372 return fillrand(IsColVector ? r : c);
376 EIGEN_DEPRECATED_WITH_REASON(
"Use .insert() instead.") Scalar& fillrand(Index i) {
return insert(i); }
379 EIGEN_DEPRECATED_WITH_REASON(
"Use .finalize() instead.") void endFill() {}
383 EIGEN_DEPRECATED_WITH_REASON(
"Use .data() instead.") Storage& _data() {
return m_data; }
385 EIGEN_DEPRECATED_WITH_REASON(
"Use .data() instead.") const Storage& _data()
const {
return m_data; }
387#ifdef EIGEN_SPARSEVECTOR_PLUGIN
388#include EIGEN_SPARSEVECTOR_PLUGIN
392 EIGEN_STATIC_ASSERT(NumTraits<StorageIndex>::IsSigned, THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE)
393 EIGEN_STATIC_ASSERT((Options_ & (ColMajor | RowMajor)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS)
401template <
typename Scalar_,
int Options_,
typename Index_>
402struct evaluator<SparseVector<Scalar_, Options_, Index_> > : evaluator_base<SparseVector<Scalar_, Options_, Index_> > {
403 using SparseVectorType = SparseVector<Scalar_, Options_, Index_>;
404 using Base = evaluator_base<SparseVectorType>;
405 using InnerIterator =
typename SparseVectorType::InnerIterator;
406 using ReverseInnerIterator =
typename SparseVectorType::ReverseInnerIterator;
408 enum { CoeffReadCost = NumTraits<Scalar_>::ReadCost, Flags = SparseVectorType::Flags };
410 evaluator() : Base() {}
412 explicit evaluator(
const SparseVectorType& mat) : m_matrix(&mat) { EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost); }
414 inline Index nonZerosEstimate()
const {
return m_matrix->nonZeros(); }
416 operator SparseVectorType&() {
return m_matrix->const_cast_derived(); }
417 operator const SparseVectorType&()
const {
return *m_matrix; }
419 const SparseVectorType* m_matrix;
422template <
typename Dest,
typename Src>
423struct sparse_vector_assign_selector<Dest, Src, SVA_Inner> {
424 static void run(Dest& dst,
const Src& src) {
425 eigen_internal_assert(src.innerSize() == src.size());
426 using SrcEvaluatorType = internal::evaluator<Src>;
427 SrcEvaluatorType srcEval(src);
428 for (
typename SrcEvaluatorType::InnerIterator it(srcEval, 0); it; ++it) dst.insert(it.index()) = it.value();
432template <
typename Dest,
typename Src>
433struct sparse_vector_assign_selector<Dest, Src, SVA_Outer> {
434 static void run(Dest& dst,
const Src& src) {
435 eigen_internal_assert(src.outerSize() == src.size());
436 using SrcEvaluatorType = internal::evaluator<Src>;
437 SrcEvaluatorType srcEval(src);
438 for (Index i = 0; i < src.size(); ++i) {
439 typename SrcEvaluatorType::InnerIterator it(srcEval, i);
440 if (it) dst.insert(i) = it.value();
445template <
typename Dest,
typename Src>
446struct sparse_vector_assign_selector<Dest, Src, SVA_RuntimeSwitch> {
447 static void run(Dest& dst,
const Src& src) {
448 if (src.outerSize() == 1)
449 sparse_vector_assign_selector<Dest, Src, SVA_Inner>::run(dst, src);
451 sparse_vector_assign_selector<Dest, Src, SVA_Outer>::run(dst, src);
459template <
typename Scalar,
int Options,
typename StorageIndex>
460class Serializer<SparseVector<Scalar, Options, StorageIndex>, void> {
462 using SparseMat = SparseVector<Scalar, Options, StorageIndex>;
465 typename SparseMat::Index size;
469 EIGEN_DEVICE_FUNC
size_t size(
const SparseMat& value)
const {
470 return sizeof(Header) + (
sizeof(Scalar) +
sizeof(StorageIndex)) * value.nonZeros();
473 EIGEN_DEVICE_FUNC uint8_t* serialize(uint8_t* dest, uint8_t* end,
const SparseMat& value) {
474 if (EIGEN_PREDICT_FALSE(dest ==
nullptr))
return nullptr;
475 if (EIGEN_PREDICT_FALSE(dest + size(value) > end))
return nullptr;
477 const size_t header_bytes =
sizeof(Header);
478 Header header = {value.innerSize(), value.nonZeros()};
479 EIGEN_USING_STD(memcpy)
480 memcpy(dest, &header, header_bytes);
481 dest += header_bytes;
484 std::size_t data_bytes =
sizeof(StorageIndex) * header.num_non_zeros;
485 if (data_bytes != 0) {
486 memcpy(dest, value.innerIndexPtr(), data_bytes);
491 data_bytes =
sizeof(Scalar) * header.num_non_zeros;
492 if (data_bytes != 0) {
493 memcpy(dest, value.valuePtr(), data_bytes);
500 EIGEN_DEVICE_FUNC
const uint8_t* deserialize(
const uint8_t* src,
const uint8_t* end, SparseMat& value)
const {
501 if (EIGEN_PREDICT_FALSE(src ==
nullptr))
return nullptr;
502 if (EIGEN_PREDICT_FALSE(src +
sizeof(Header) > end))
return nullptr;
504 const size_t header_bytes =
sizeof(Header);
506 EIGEN_USING_STD(memcpy)
507 memcpy(&header, src, header_bytes);
511 value.resize(header.size);
512 value.resizeNonZeros(header.num_non_zeros);
515 std::size_t data_bytes =
sizeof(StorageIndex) * header.num_non_zeros;
516 if (EIGEN_PREDICT_FALSE(src + data_bytes > end))
return nullptr;
517 if (data_bytes != 0) {
518 memcpy(value.innerIndexPtr(), src, data_bytes);
523 data_bytes =
sizeof(Scalar) * header.num_non_zeros;
524 if (EIGEN_PREDICT_FALSE(src + data_bytes > end))
return nullptr;
525 if (data_bytes != 0) {
526 memcpy(value.valuePtr(), src, data_bytes);
An InnerIterator allows to loop over the element of any matrix expression.
Definition CoreIterators.h:38
SparseCompressedBase()=default
typename NumTraits< Scalar >::Real RealScalar
Definition SparseMatrixBase.h:128
constexpr RowXpr row(Index i)
Definition SparseMatrixBase.h:1094
typename internal::traits< SparseVector< Scalar_, Options_, StorageIndex_ > >::StorageIndex StorageIndex
Definition SparseMatrixBase.h:45
constexpr ColXpr col(Index i)
Definition SparseMatrixBase.h:1081
a sparse vector class
Definition SparseVector.h:63
void resize(NoChange_t, Index cols)
Definition SparseVector.h:230
void resize(Index rows, NoChange_t)
Definition SparseVector.h:233
void conservativeResize(Index newSize)
Definition SparseVector.h:251
Scalar & coeffRef(Index i)
Definition SparseVector.h:118
Index prune(const Scalar &reference, const RealScalar &epsilon=NumTraits< RealScalar >::dummy_precision())
Definition SparseVector.h:190
void resize(Index rows, Index cols)
Definition SparseVector.h:224
void swap(SparseVector &other)
Definition SparseVector.h:282
Index prune(F &&keep_predicate)
Prunes the entries of the vector based on a predicate
Definition SparseVector.h:202
Index nonZeros() const
Definition SparseVector.h:131
void resize(Index newSize)
Definition SparseVector.h:239
Scalar sum() const
Definition SparseRedux.h:41
constexpr unsigned int LvalueBit
Definition Constants.h:149
constexpr unsigned int RowMajorBit
Definition Constants.h:71
constexpr unsigned int CompressedAccessBit
Definition Constants.h:196