$darkmode
Eigen  5.0.1-dev
SparseMap.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 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_SPARSE_MAP_H
11 #define EIGEN_SPARSE_MAP_H
12 
13 // IWYU pragma: private
14 #include "./InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
18 namespace internal {
19 
20 template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
21 struct traits<Map<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> >
22  : public traits<SparseMatrix<MatScalar, MatOptions, MatIndex> > {
23  typedef SparseMatrix<MatScalar, MatOptions, MatIndex> PlainObjectType;
24  typedef traits<PlainObjectType> TraitsBase;
25  enum { Flags = TraitsBase::Flags & (~NestByRefBit) };
26 };
27 
28 template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
29 struct traits<Map<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> >
30  : public traits<SparseMatrix<MatScalar, MatOptions, MatIndex> > {
31  typedef SparseMatrix<MatScalar, MatOptions, MatIndex> PlainObjectType;
32  typedef traits<PlainObjectType> TraitsBase;
33  enum { Flags = TraitsBase::Flags & (~(NestByRefBit | LvalueBit)) };
34 };
35 
36 } // end namespace internal
37 
38 template <typename Derived,
39  int Level = internal::accessors_level<Derived>::has_write_access ? WriteAccessors : ReadOnlyAccessors>
40 class SparseMapBase;
41 
46 template <typename Derived>
47 class SparseMapBase<Derived, ReadOnlyAccessors> : public SparseCompressedBase<Derived> {
48  public:
50  typedef typename Base::Scalar Scalar;
51  typedef typename Base::StorageIndex StorageIndex;
52  enum { IsRowMajor = Base::IsRowMajor };
53  using Base::operator=;
54 
55  protected:
56  typedef std::conditional_t<bool(internal::is_lvalue<Derived>::value), Scalar*, const Scalar*> ScalarPointer;
57  typedef std::conditional_t<bool(internal::is_lvalue<Derived>::value), StorageIndex*, const StorageIndex*>
58  IndexPointer;
59 
60  Index m_outerSize;
61  Index m_innerSize;
62  Array<StorageIndex, 2, 1> m_zero_nnz;
63  IndexPointer m_outerIndex;
64  IndexPointer m_innerIndices;
65  ScalarPointer m_values;
66  IndexPointer m_innerNonZeros;
67 
68  public:
70  inline Index rows() const { return IsRowMajor ? m_outerSize : m_innerSize; }
72  inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; }
74  inline Index innerSize() const { return m_innerSize; }
76  inline Index outerSize() const { return m_outerSize; }
78  inline Index nonZeros() const { return m_zero_nnz[1]; }
79 
81  bool isCompressed() const { return m_innerNonZeros == 0; }
82 
83  //----------------------------------------
84  // direct access interface
86  inline const Scalar* valuePtr() const { return m_values; }
88  inline const StorageIndex* innerIndexPtr() const { return m_innerIndices; }
90  inline const StorageIndex* outerIndexPtr() const { return m_outerIndex; }
92  inline const StorageIndex* innerNonZeroPtr() const { return m_innerNonZeros; }
93  //----------------------------------------
94 
96  inline Scalar coeff(Index row, Index col) const {
97  const Index outer = IsRowMajor ? row : col;
98  const Index inner = IsRowMajor ? col : row;
99 
100  Index start = m_outerIndex[outer];
101  Index end = isCompressed() ? m_outerIndex[outer + 1] : start + m_innerNonZeros[outer];
102  if (start == end)
103  return Scalar(0);
104  else if (end > 0 && inner == m_innerIndices[end - 1])
105  return m_values[end - 1];
106  // ^^ optimization: let's first check if it is the last coefficient
107  // (very common in high level algorithms)
108 
109  const StorageIndex* r = std::lower_bound(&m_innerIndices[start], &m_innerIndices[end - 1], inner);
110  const Index id = r - &m_innerIndices[0];
111  return ((*r == inner) && (id < end)) ? m_values[id] : Scalar(0);
112  }
113 
114  inline SparseMapBase(Index rows, Index cols, Index nnz, IndexPointer outerIndexPtr, IndexPointer innerIndexPtr,
115  ScalarPointer valuePtr, IndexPointer innerNonZerosPtr = 0)
116  : m_outerSize(IsRowMajor ? rows : cols),
117  m_innerSize(IsRowMajor ? cols : rows),
118  m_zero_nnz(0, internal::convert_index<StorageIndex>(nnz)),
119  m_outerIndex(outerIndexPtr),
120  m_innerIndices(innerIndexPtr),
121  m_values(valuePtr),
122  m_innerNonZeros(innerNonZerosPtr) {}
123 
124  // for vectors
125  inline SparseMapBase(Index size, Index nnz, IndexPointer innerIndexPtr, ScalarPointer valuePtr)
126  : m_outerSize(1),
127  m_innerSize(size),
128  m_zero_nnz(0, internal::convert_index<StorageIndex>(nnz)),
129  m_outerIndex(m_zero_nnz.data()),
130  m_innerIndices(innerIndexPtr),
131  m_values(valuePtr),
132  m_innerNonZeros(0) {}
133 
135  inline ~SparseMapBase() {}
136 
137  protected:
138  inline SparseMapBase() {}
139 };
140 
145 template <typename Derived>
146 class SparseMapBase<Derived, WriteAccessors> : public SparseMapBase<Derived, ReadOnlyAccessors> {
148 
149  public:
151  typedef typename Base::Scalar Scalar;
152  typedef typename Base::StorageIndex StorageIndex;
153  enum { IsRowMajor = Base::IsRowMajor };
154 
155  using Base::operator=;
156 
157  public:
158  //----------------------------------------
159  // direct access interface
160  using Base::innerIndexPtr;
161  using Base::innerNonZeroPtr;
162  using Base::outerIndexPtr;
163  using Base::valuePtr;
165  inline Scalar* valuePtr() { return Base::m_values; }
167  inline StorageIndex* innerIndexPtr() { return Base::m_innerIndices; }
169  inline StorageIndex* outerIndexPtr() { return Base::m_outerIndex; }
171  inline StorageIndex* innerNonZeroPtr() { return Base::m_innerNonZeros; }
172  //----------------------------------------
173 
175  inline Scalar& coeffRef(Index row, Index col) {
176  const Index outer = IsRowMajor ? row : col;
177  const Index inner = IsRowMajor ? col : row;
178 
179  Index start = Base::m_outerIndex[outer];
180  Index end = Base::isCompressed() ? Base::m_outerIndex[outer + 1] : start + Base::m_innerNonZeros[outer];
181  eigen_assert(end >= start && "you probably called coeffRef on a non finalized matrix");
182  eigen_assert(end > start && "coeffRef cannot be called on a zero coefficient");
183  StorageIndex* r = std::lower_bound(&Base::m_innerIndices[start], &Base::m_innerIndices[end], inner);
184  const Index id = r - &Base::m_innerIndices[0];
185  eigen_assert((*r == inner) && (id < end) && "coeffRef cannot be called on a zero coefficient");
186  return const_cast<Scalar*>(Base::m_values)[id];
187  }
188 
189  inline SparseMapBase(Index rows, Index cols, Index nnz, StorageIndex* outerIndexPtr, StorageIndex* innerIndexPtr,
190  Scalar* valuePtr, StorageIndex* innerNonZerosPtr = 0)
191  : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr) {}
192 
193  // for vectors
194  inline SparseMapBase(Index size, Index nnz, StorageIndex* innerIndexPtr, Scalar* valuePtr)
195  : Base(size, nnz, innerIndexPtr, valuePtr) {}
196 
198  inline ~SparseMapBase() {}
199 
200  protected:
201  inline SparseMapBase() {}
202 };
203 
213 #ifndef EIGEN_PARSED_BY_DOXYGEN
214 template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
215 class Map<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>
216  : public SparseMapBase<Map<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> >
217 #else
218 template <typename SparseMatrixType>
219 class Map<SparseMatrixType> : public SparseMapBase<Derived, WriteAccessors>
220 #endif
221 {
222  public:
223  typedef SparseMapBase<Map> Base;
224  EIGEN_SPARSE_PUBLIC_INTERFACE(Map)
225  enum { IsRowMajor = Base::IsRowMajor };
226 
227  public:
237  inline Map(Index rows, Index cols, Index nnz, StorageIndex* outerIndexPtr, StorageIndex* innerIndexPtr,
238  Scalar* valuePtr, StorageIndex* innerNonZerosPtr = 0)
239  : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr) {}
240 #ifndef EIGEN_PARSED_BY_DOXYGEN
241 
242  inline ~Map() {}
243 };
244 
245 template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
246 class Map<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>
247  : public SparseMapBase<Map<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> > {
248  public:
249  typedef SparseMapBase<Map> Base;
250  EIGEN_SPARSE_PUBLIC_INTERFACE(Map)
251  enum { IsRowMajor = Base::IsRowMajor };
252 
253  public:
254 #endif
255 
260  inline Map(Index rows, Index cols, Index nnz, const StorageIndex* outerIndexPtr, const StorageIndex* innerIndexPtr,
261  const Scalar* valuePtr, const StorageIndex* innerNonZerosPtr = 0)
262  : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr) {}
263 
265  inline ~Map() {}
266 };
267 
268 namespace internal {
269 
270 template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
271 struct evaluator<Map<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> >
272  : evaluator<SparseCompressedBase<Map<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> > > {
273  typedef evaluator<SparseCompressedBase<Map<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> > >
274  Base;
275  typedef Map<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> XprType;
276  evaluator() : Base() {}
277  explicit evaluator(const XprType& mat) : Base(mat) {}
278 };
279 
280 template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
281 struct evaluator<Map<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> >
282  : evaluator<SparseCompressedBase<Map<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> > > {
283  typedef evaluator<
284  SparseCompressedBase<Map<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> > >
285  Base;
286  typedef Map<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> XprType;
287  evaluator() : Base() {}
288  explicit evaluator(const XprType& mat) : Base(mat) {}
289 };
290 
291 } // namespace internal
292 
293 } // end namespace Eigen
294 
295 #endif // EIGEN_SPARSE_MAP_H
Index innerSize() const
Definition: SparseMap.h:74
~Map()
Definition: SparseMap.h:265
const StorageIndex * innerNonZeroPtr() const
Definition: SparseMap.h:92
static constexpr lastp1_t end
Definition: IndexedViewHelper.h:79
const StorageIndex * innerIndexPtr() const
Definition: SparseMap.h:88
Definition: Constants.h:374
Scalar & coeffRef(Index row, Index col)
Definition: SparseMap.h:175
Map(Index rows, Index cols, Index nnz, const StorageIndex *outerIndexPtr, const StorageIndex *innerIndexPtr, const Scalar *valuePtr, const StorageIndex *innerNonZerosPtr=0)
Definition: SparseMap.h:260
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:96
Common base class for Map and Ref instance of sparse matrix and vector.
Definition: SparseMap.h:47
const StorageIndex * outerIndexPtr() const
Definition: SparseMap.h:90
bool isCompressed() const
Definition: SparseMap.h:81
const unsigned int LvalueBit
Definition: Constants.h:148
Namespace containing all symbols from the Eigen library.
Definition: B01_Experimental.dox:1
Scalar coeff(Index row, Index col) const
Definition: SparseMap.h:96
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:43
Map(PointerArgType dataPtr, const StrideType &stride=StrideType())
Definition: Map.h:123
Index nonZeros() const
Definition: SparseMap.h:78
StorageIndex * innerIndexPtr()
Definition: SparseMap.h:167
internal::traits< Derived >::StorageIndex StorageIndex
Definition: SparseMatrixBase.h:44
Map(Index rows, Index cols, Index nnz, StorageIndex *outerIndexPtr, StorageIndex *innerIndexPtr, Scalar *valuePtr, StorageIndex *innerNonZerosPtr=0)
Definition: SparseMap.h:237
StorageIndex * outerIndexPtr()
Definition: SparseMap.h:169
Definition: Constants.h:372
StorageIndex * innerNonZeroPtr()
Definition: SparseMap.h:171
Base class of any sparse matrices or sparse expressions.
Definition: ForwardDeclarations.h:481
Base class for dense Map and Block expression with direct access.
Definition: MapBase.h:41
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
Index rows() const
Definition: SparseMap.h:70
Scalar * valuePtr()
Definition: SparseMap.h:165
Index outerSize() const
Definition: SparseMap.h:76
~SparseMapBase()
Definition: SparseMap.h:198
Common base class for sparse [compressed]-{row|column}-storage format.
Definition: SparseCompressedBase.h:19
const Scalar * valuePtr() const
Definition: SparseMap.h:86
Index cols() const
Definition: SparseMap.h:72