Eigen  3.2.92
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 namespace Eigen {
14 
15 namespace internal {
16 
17 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
18 struct traits<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
19  : public traits<SparseMatrix<MatScalar,MatOptions,MatIndex> >
20 {
21  typedef SparseMatrix<MatScalar,MatOptions,MatIndex> PlainObjectType;
22  typedef traits<PlainObjectType> TraitsBase;
23  enum {
24  Flags = TraitsBase::Flags & (~NestByRefBit)
25  };
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 {
32  typedef SparseMatrix<MatScalar,MatOptions,MatIndex> PlainObjectType;
33  typedef traits<PlainObjectType> TraitsBase;
34  enum {
35  Flags = TraitsBase::Flags & (~ (NestByRefBit | LvalueBit))
36  };
37 };
38 
39 } // end namespace internal
40 
41 template<typename Derived,
42  int Level = internal::accessors_level<Derived>::has_write_access ? WriteAccessors : ReadOnlyAccessors
43 > class SparseMapBase;
44 
45 template<typename Derived>
46 class SparseMapBase<Derived,ReadOnlyAccessors>
47  : public SparseCompressedBase<Derived>
48 {
49  public:
50  typedef SparseCompressedBase<Derived> Base;
51  typedef typename Base::Scalar Scalar;
52  typedef typename Base::StorageIndex StorageIndex;
53  enum { IsRowMajor = Base::IsRowMajor };
54  using Base::operator=;
55  protected:
56 
57  typedef typename internal::conditional<
58  bool(internal::is_lvalue<Derived>::value),
59  Scalar *, const Scalar *>::type ScalarPointer;
60  typedef typename internal::conditional<
61  bool(internal::is_lvalue<Derived>::value),
62  StorageIndex *, const StorageIndex *>::type IndexPointer;
63 
64  Index m_outerSize;
65  Index m_innerSize;
66  Array<StorageIndex,2,1> m_zero_nnz;
67  IndexPointer m_outerIndex;
68  IndexPointer m_innerIndices;
69  ScalarPointer m_values;
70  IndexPointer m_innerNonZeros;
71 
72  public:
73 
74  inline Index rows() const { return IsRowMajor ? m_outerSize : m_innerSize; }
75  inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; }
76  inline Index innerSize() const { return m_innerSize; }
77  inline Index outerSize() const { return m_outerSize; }
78  inline Index nonZeros() const { return m_zero_nnz[1]; }
79 
80  bool isCompressed() const { return m_innerNonZeros==0; }
81 
82  //----------------------------------------
83  // direct access interface
84  inline const Scalar* valuePtr() const { return m_values; }
85  inline const StorageIndex* innerIndexPtr() const { return m_innerIndices; }
86  inline const StorageIndex* outerIndexPtr() const { return m_outerIndex; }
87  inline const StorageIndex* innerNonZeroPtr() const { return m_innerNonZeros; }
88  //----------------------------------------
89 
90  inline Scalar coeff(Index row, Index col) const
91  {
92  const Index outer = IsRowMajor ? row : col;
93  const Index inner = IsRowMajor ? col : row;
94 
95  Index start = m_outerIndex[outer];
96  Index end = isCompressed() ? m_outerIndex[outer+1] : start + m_innerNonZeros[outer];
97  if (start==end)
98  return Scalar(0);
99  else if (end>0 && inner==m_innerIndices[end-1])
100  return m_values[end-1];
101  // ^^ optimization: let's first check if it is the last coefficient
102  // (very common in high level algorithms)
103 
104  const StorageIndex* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end-1],inner);
105  const Index id = r-&m_innerIndices[0];
106  return ((*r==inner) && (id<end)) ? m_values[id] : Scalar(0);
107  }
108 
109  inline SparseMapBase(Index rows, Index cols, Index nnz, IndexPointer outerIndexPtr, IndexPointer innerIndexPtr,
110  ScalarPointer valuePtr, IndexPointer innerNonZerosPtr = 0)
111  : m_outerSize(IsRowMajor?rows:cols), m_innerSize(IsRowMajor?cols:rows), m_zero_nnz(0,internal::convert_index<StorageIndex>(nnz)), m_outerIndex(outerIndexPtr),
112  m_innerIndices(innerIndexPtr), m_values(valuePtr), m_innerNonZeros(innerNonZerosPtr)
113  {}
114 
115  // for vectors
116  inline SparseMapBase(Index size, Index nnz, IndexPointer innerIndexPtr, ScalarPointer valuePtr)
117  : m_outerSize(1), m_innerSize(size), m_zero_nnz(0,internal::convert_index<StorageIndex>(nnz)), m_outerIndex(m_zero_nnz.data()),
118  m_innerIndices(innerIndexPtr), m_values(valuePtr), m_innerNonZeros(0)
119  {}
120 
122  inline ~SparseMapBase() {}
123 
124  protected:
125  inline SparseMapBase() {}
126 };
127 
128 template<typename Derived>
129 class SparseMapBase<Derived,WriteAccessors>
130  : public SparseMapBase<Derived,ReadOnlyAccessors>
131 {
132  typedef MapBase<Derived, ReadOnlyAccessors> ReadOnlyMapBase;
133 
134  public:
135  typedef SparseMapBase<Derived, ReadOnlyAccessors> Base;
136  typedef typename Base::Scalar Scalar;
137  typedef typename Base::StorageIndex StorageIndex;
138  enum { IsRowMajor = Base::IsRowMajor };
139 
140  using Base::operator=;
141 
142  public:
143 
144  //----------------------------------------
145  // direct access interface
146  using Base::valuePtr;
147  using Base::innerIndexPtr;
148  using Base::outerIndexPtr;
149  using Base::innerNonZeroPtr;
150  inline Scalar* valuePtr() { return Base::m_values; }
151  inline StorageIndex* innerIndexPtr() { return Base::m_innerIndices; }
152  inline StorageIndex* outerIndexPtr() { return Base::m_outerIndex; }
153  inline StorageIndex* innerNonZeroPtr() { return Base::m_innerNonZeros; }
154  //----------------------------------------
155 
156  inline Scalar& coeffRef(Index row, Index col)
157  {
158  const Index outer = IsRowMajor ? row : col;
159  const Index inner = IsRowMajor ? col : row;
160 
161  Index start = Base::m_outerIndex[outer];
162  Index end = Base::isCompressed() ? Base::m_outerIndex[outer+1] : start + Base::m_innerNonZeros[outer];
163  eigen_assert(end>=start && "you probably called coeffRef on a non finalized matrix");
164  eigen_assert(end>start && "coeffRef cannot be called on a zero coefficient");
165  Index* r = std::lower_bound(&Base::m_innerIndices[start],&Base::m_innerIndices[end],inner);
166  const Index id = r - &Base::m_innerIndices[0];
167  eigen_assert((*r==inner) && (id<end) && "coeffRef cannot be called on a zero coefficient");
168  return const_cast<Scalar*>(Base::m_values)[id];
169  }
170 
171  inline SparseMapBase(Index rows, Index cols, Index nnz, StorageIndex* outerIndexPtr, StorageIndex* innerIndexPtr,
172  Scalar* valuePtr, StorageIndex* innerNonZerosPtr = 0)
173  : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr)
174  {}
175 
176  // for vectors
177  inline SparseMapBase(Index size, Index nnz, StorageIndex* innerIndexPtr, Scalar* valuePtr)
178  : Base(size, nnz, innerIndexPtr, valuePtr)
179  {}
180 
182  inline ~SparseMapBase() {}
183 
184  protected:
185  inline SparseMapBase() {}
186 };
187 
188 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
189 class Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType>
190  : public SparseMapBase<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
191 {
192  public:
193  typedef SparseMapBase<Map> Base;
194  EIGEN_SPARSE_PUBLIC_INTERFACE(Map)
195  enum { IsRowMajor = Base::IsRowMajor };
196 
197  public:
198 
199  inline Map(Index rows, Index cols, Index nnz, StorageIndex* outerIndexPtr,
200  StorageIndex* innerIndexPtr, Scalar* valuePtr, StorageIndex* innerNonZerosPtr = 0)
201  : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr)
202  {}
203 
205  inline ~Map() {}
206 };
207 
208 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
209 class Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType>
210  : public SparseMapBase<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
211 {
212  public:
213  typedef SparseMapBase<Map> Base;
214  EIGEN_SPARSE_PUBLIC_INTERFACE(Map)
215  enum { IsRowMajor = Base::IsRowMajor };
216 
217  public:
218 
219  inline Map(Index rows, Index cols, Index nnz, const StorageIndex* outerIndexPtr,
220  const StorageIndex* innerIndexPtr, const Scalar* valuePtr, const StorageIndex* innerNonZerosPtr = 0)
221  : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr)
222  {}
223 
225  inline ~Map() {}
226 };
227 
228 namespace internal {
229 
230 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
231 struct evaluator<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
232  : evaluator<SparseCompressedBase<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
233 {
234  typedef evaluator<SparseCompressedBase<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
235  typedef Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
236  evaluator() : Base() {}
237  explicit evaluator(const XprType &mat) : Base(mat) {}
238 };
239 
240 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
241 struct evaluator<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
242  : evaluator<SparseCompressedBase<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
243 {
244  typedef evaluator<SparseCompressedBase<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
245  typedef Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
246  evaluator() : Base() {}
247  explicit evaluator(const XprType &mat) : Base(mat) {}
248 };
249 
250 }
251 
252 } // end namespace Eigen
253 
254 #endif // EIGEN_SPARSE_MAP_H
Definition: Constants.h:368
const unsigned int LvalueBit
Definition: Constants.h:138
Definition: LDLT.h:16
Definition: Constants.h:366
Definition: Eigen_Colamd.h:54