SparseMap.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) 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 #include "./InternalHeaderCheck.h"
14 
15 namespace Eigen {
16 
17 namespace internal {
18 
19 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
20 struct traits<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
21  : public traits<SparseMatrix<MatScalar,MatOptions,MatIndex> >
22 {
23  typedef SparseMatrix<MatScalar,MatOptions,MatIndex> PlainObjectType;
24  typedef traits<PlainObjectType> TraitsBase;
25  enum {
26  Flags = TraitsBase::Flags & (~NestByRefBit)
27  };
28 };
29 
30 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
31 struct traits<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
32  : public traits<SparseMatrix<MatScalar,MatOptions,MatIndex> >
33 {
34  typedef SparseMatrix<MatScalar,MatOptions,MatIndex> PlainObjectType;
35  typedef traits<PlainObjectType> TraitsBase;
36  enum {
37  Flags = TraitsBase::Flags & (~ (NestByRefBit | LvalueBit))
38  };
39 };
40 
41 } // end namespace internal
42 
43 template<typename Derived,
44  int Level = internal::accessors_level<Derived>::has_write_access ? WriteAccessors : ReadOnlyAccessors
45 > class SparseMapBase;
46 
51 template<typename Derived>
53  : public SparseCompressedBase<Derived>
54 {
55  public:
57  typedef typename Base::Scalar Scalar;
58  typedef typename Base::StorageIndex StorageIndex;
59  enum { IsRowMajor = Base::IsRowMajor };
60  using Base::operator=;
61  protected:
62 
63  typedef std::conditional_t<
64  bool(internal::is_lvalue<Derived>::value),
66  typedef std::conditional_t<
67  bool(internal::is_lvalue<Derived>::value),
69 
77 
78  public:
79 
81  inline Index rows() const { return IsRowMajor ? m_outerSize : m_innerSize; }
83  inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; }
85  inline Index innerSize() const { return m_innerSize; }
87  inline Index outerSize() const { return m_outerSize; }
89  inline Index nonZeros() const { return m_zero_nnz[1]; }
90 
92  bool isCompressed() const { return m_innerNonZeros==0; }
93 
94  //----------------------------------------
95  // direct access interface
97  inline const Scalar* valuePtr() const { return m_values; }
99  inline const StorageIndex* innerIndexPtr() const { return m_innerIndices; }
101  inline const StorageIndex* outerIndexPtr() const { return m_outerIndex; }
103  inline const StorageIndex* innerNonZeroPtr() const { return m_innerNonZeros; }
104  //----------------------------------------
105 
107  inline Scalar coeff(Index row, Index col) const
108  {
109  const Index outer = IsRowMajor ? row : col;
110  const Index inner = IsRowMajor ? col : row;
111 
112  Index start = m_outerIndex[outer];
113  Index end = isCompressed() ? m_outerIndex[outer+1] : start + m_innerNonZeros[outer];
114  if (start==end)
115  return Scalar(0);
116  else if (end>0 && inner==m_innerIndices[end-1])
117  return m_values[end-1];
118  // ^^ optimization: let's first check if it is the last coefficient
119  // (very common in high level algorithms)
120 
121  const StorageIndex* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end-1],inner);
122  const Index id = r-&m_innerIndices[0];
123  return ((*r==inner) && (id<end)) ? m_values[id] : Scalar(0);
124  }
125 
126  inline SparseMapBase(Index rows, Index cols, Index nnz, IndexPointer outerIndexPtr, IndexPointer innerIndexPtr,
127  ScalarPointer valuePtr, IndexPointer innerNonZerosPtr = 0)
128  : m_outerSize(IsRowMajor?rows:cols), m_innerSize(IsRowMajor?cols:rows), m_zero_nnz(0,internal::convert_index<StorageIndex>(nnz)), m_outerIndex(outerIndexPtr),
129  m_innerIndices(innerIndexPtr), m_values(valuePtr), m_innerNonZeros(innerNonZerosPtr)
130  {}
131 
132  // for vectors
133  inline SparseMapBase(Index size, Index nnz, IndexPointer innerIndexPtr, ScalarPointer valuePtr)
134  : m_outerSize(1), m_innerSize(size), m_zero_nnz(0,internal::convert_index<StorageIndex>(nnz)), m_outerIndex(m_zero_nnz.data()),
135  m_innerIndices(innerIndexPtr), m_values(valuePtr), m_innerNonZeros(0)
136  {}
137 
139  inline ~SparseMapBase() {}
140 
141  protected:
142  inline SparseMapBase() {}
143 };
144 
149 template<typename Derived>
151  : public SparseMapBase<Derived,ReadOnlyAccessors>
152 {
154 
155  public:
157  typedef typename Base::Scalar Scalar;
159  enum { IsRowMajor = Base::IsRowMajor };
160 
161  using Base::operator=;
162 
163  public:
164 
165  //----------------------------------------
166  // direct access interface
167  using Base::valuePtr;
168  using Base::innerIndexPtr;
169  using Base::outerIndexPtr;
170  using Base::innerNonZeroPtr;
172  inline Scalar* valuePtr() { return Base::m_values; }
174  inline StorageIndex* innerIndexPtr() { return Base::m_innerIndices; }
176  inline StorageIndex* outerIndexPtr() { return Base::m_outerIndex; }
178  inline StorageIndex* innerNonZeroPtr() { return Base::m_innerNonZeros; }
179  //----------------------------------------
180 
183  {
184  const Index outer = IsRowMajor ? row : col;
185  const Index inner = IsRowMajor ? col : row;
186 
187  Index start = Base::m_outerIndex[outer];
188  Index end = Base::isCompressed() ? Base::m_outerIndex[outer+1] : start + Base::m_innerNonZeros[outer];
189  eigen_assert(end>=start && "you probably called coeffRef on a non finalized matrix");
190  eigen_assert(end>start && "coeffRef cannot be called on a zero coefficient");
191  StorageIndex* r = std::lower_bound(&Base::m_innerIndices[start],&Base::m_innerIndices[end],inner);
192  const Index id = r - &Base::m_innerIndices[0];
193  eigen_assert((*r==inner) && (id<end) && "coeffRef cannot be called on a zero coefficient");
194  return const_cast<Scalar*>(Base::m_values)[id];
195  }
196 
197  inline SparseMapBase(Index rows, Index cols, Index nnz, StorageIndex* outerIndexPtr, StorageIndex* innerIndexPtr,
198  Scalar* valuePtr, StorageIndex* innerNonZerosPtr = 0)
199  : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr)
200  {}
201 
202  // for vectors
203  inline SparseMapBase(Index size, Index nnz, StorageIndex* innerIndexPtr, Scalar* valuePtr)
204  : Base(size, nnz, innerIndexPtr, valuePtr)
205  {}
206 
208  inline ~SparseMapBase() {}
209 
210  protected:
211  inline SparseMapBase() {}
212 };
213 
222 #ifndef EIGEN_PARSED_BY_DOXYGEN
223 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
224 class Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType>
225  : public SparseMapBase<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
226 #else
227 template<typename SparseMatrixType>
228 class Map<SparseMatrixType>
229  : public SparseMapBase<Derived,WriteAccessors>
230 #endif
231 {
232  public:
235  enum { IsRowMajor = Base::IsRowMajor };
236 
237  public:
238 
248  inline Map(Index rows, Index cols, Index nnz, StorageIndex* outerIndexPtr,
249  StorageIndex* innerIndexPtr, Scalar* valuePtr, StorageIndex* innerNonZerosPtr = 0)
250  : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr)
251  {}
252 #ifndef EIGEN_PARSED_BY_DOXYGEN
254  inline ~Map() {}
255 };
256 
257 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
258 class Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType>
259  : public SparseMapBase<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
260 {
261  public:
262  typedef SparseMapBase<Map> Base;
264  enum { IsRowMajor = Base::IsRowMajor };
265 
266  public:
267 #endif
273  inline Map(Index rows, Index cols, Index nnz, const StorageIndex* outerIndexPtr,
274  const StorageIndex* innerIndexPtr, const Scalar* valuePtr, const StorageIndex* innerNonZerosPtr = 0)
275  : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr)
276  {}
277 
279  inline ~Map() {}
280 };
281 
282 namespace internal {
283 
284 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
285 struct evaluator<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
286  : evaluator<SparseCompressedBase<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
287 {
288  typedef evaluator<SparseCompressedBase<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
289  typedef Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
290  evaluator() : Base() {}
291  explicit evaluator(const XprType &mat) : Base(mat) {}
292 };
293 
294 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
295 struct evaluator<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
296  : evaluator<SparseCompressedBase<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
297 {
298  typedef evaluator<SparseCompressedBase<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
299  typedef Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
300  evaluator() : Base() {}
301  explicit evaluator(const XprType &mat) : Base(mat) {}
302 };
303 
304 }
305 
306 } // end namespace Eigen
307 
308 #endif // EIGEN_SPARSE_MAP_H
RowXpr row(Index i)
This is the const version of row(). *‍/.
ColXpr col(Index i)
This is the const version of col().
#define eigen_assert(x)
Definition: Macros.h:902
int data[]
#define EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
Definition: SparseUtil.h:45
Base class for dense Map and Block expression with direct access.
Definition: MapBase.h:41
SparseMapBase< Map > Base
Definition: SparseMap.h:233
Map(Index rows, Index cols, Index nnz, const StorageIndex *outerIndexPtr, const StorageIndex *innerIndexPtr, const Scalar *valuePtr, const StorageIndex *innerNonZerosPtr=0)
Definition: SparseMap.h:273
Map(Index rows, Index cols, Index nnz, StorageIndex *outerIndexPtr, StorageIndex *innerIndexPtr, Scalar *valuePtr, StorageIndex *innerNonZerosPtr=0)
Definition: SparseMap.h:248
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:98
Map(PointerArgType dataPtr, const StrideType &stride=StrideType())
Definition: Map.h:131
MapBase< Map > Base
Definition: Map.h:101
Common base class for sparse [compressed]-{row|column}-storage format.
Common base class for Map and Ref instance of sparse matrix and vector.
Definition: SparseMap.h:54
SparseCompressedBase< Derived > Base
Definition: SparseMap.h:56
Scalar coeff(Index row, Index col) const
Definition: SparseMap.h:107
const StorageIndex * outerIndexPtr() const
Definition: SparseMap.h:101
std::conditional_t< bool(internal::is_lvalue< Derived >::value), StorageIndex *, const StorageIndex * > IndexPointer
Definition: SparseMap.h:68
const StorageIndex * innerNonZeroPtr() const
Definition: SparseMap.h:103
std::conditional_t< bool(internal::is_lvalue< Derived >::value), Scalar *, const Scalar * > ScalarPointer
Definition: SparseMap.h:65
SparseMapBase(Index rows, Index cols, Index nnz, IndexPointer outerIndexPtr, IndexPointer innerIndexPtr, ScalarPointer valuePtr, IndexPointer innerNonZerosPtr=0)
Definition: SparseMap.h:126
const StorageIndex * innerIndexPtr() const
Definition: SparseMap.h:99
SparseMapBase(Index size, Index nnz, IndexPointer innerIndexPtr, ScalarPointer valuePtr)
Definition: SparseMap.h:133
SparseMapBase(Index size, Index nnz, StorageIndex *innerIndexPtr, Scalar *valuePtr)
Definition: SparseMap.h:203
SparseMapBase(Index rows, Index cols, Index nnz, StorageIndex *outerIndexPtr, StorageIndex *innerIndexPtr, Scalar *valuePtr, StorageIndex *innerNonZerosPtr=0)
Definition: SparseMap.h:197
Scalar & coeffRef(Index row, Index col)
Definition: SparseMap.h:182
MapBase< Derived, ReadOnlyAccessors > ReadOnlyMapBase
Definition: SparseMap.h:153
SparseMapBase< Derived, ReadOnlyAccessors > Base
Definition: SparseMap.h:156
Base class of any sparse matrices or sparse expressions.
internal::traits< Derived >::StorageIndex StorageIndex
internal::traits< Derived >::Scalar Scalar
static const lastp1_t end
@ ReadOnlyAccessors
Definition: Constants.h:378
@ WriteAccessors
Definition: Constants.h:380
const unsigned int LvalueBit
Definition: Constants.h:146
IndexDest convert_index(const IndexSrc &idx)
Definition: XprHelper.h:64
: InteropHeaders
Definition: Core:139
const unsigned int NestByRefBit
Definition: Constants.h:171
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:41