Eigen  3.2.91
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  Index m_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 
79  bool isCompressed() const { return m_innerNonZeros==0; }
80 
81  //----------------------------------------
82  // direct access interface
83  inline const Scalar* valuePtr() const { return m_values; }
84  inline const StorageIndex* innerIndexPtr() const { return m_innerIndices; }
85  inline const StorageIndex* outerIndexPtr() const { return m_outerIndex; }
86  inline const StorageIndex* innerNonZeroPtr() const { return m_innerNonZeros; }
87  //----------------------------------------
88 
89  inline Scalar coeff(Index row, Index col) const
90  {
91  const Index outer = IsRowMajor ? row : col;
92  const Index inner = IsRowMajor ? col : row;
93 
94  Index start = m_outerIndex[outer];
95  Index end = isCompressed() ? m_outerIndex[outer+1] : start + m_innerNonZeros[outer];
96  if (start==end)
97  return Scalar(0);
98  else if (end>0 && inner==m_innerIndices[end-1])
99  return m_values[end-1];
100  // ^^ optimization: let's first check if it is the last coefficient
101  // (very common in high level algorithms)
102 
103  const StorageIndex* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end-1],inner);
104  const Index id = r-&m_innerIndices[0];
105  return ((*r==inner) && (id<end)) ? m_values[id] : Scalar(0);
106  }
107 
108  inline SparseMapBase(Index rows, Index cols, Index nnz, IndexPointer outerIndexPtr, IndexPointer innerIndexPtr,
109  ScalarPointer valuePtr, IndexPointer innerNonZerosPtr = 0)
110  : m_outerSize(IsRowMajor?rows:cols), m_innerSize(IsRowMajor?cols:rows), m_nnz(nnz), m_outerIndex(outerIndexPtr),
111  m_innerIndices(innerIndexPtr), m_values(valuePtr), m_innerNonZeros(innerNonZerosPtr)
112  {}
113 
115  inline ~SparseMapBase() {}
116 };
117 
118 template<typename Derived>
119 class SparseMapBase<Derived,WriteAccessors>
120  : public SparseMapBase<Derived,ReadOnlyAccessors>
121 {
122  typedef MapBase<Derived, ReadOnlyAccessors> ReadOnlyMapBase;
123 
124  public:
125  typedef SparseMapBase<Derived, ReadOnlyAccessors> Base;
126  typedef typename Base::Scalar Scalar;
127  typedef typename Base::StorageIndex StorageIndex;
128  enum { IsRowMajor = Base::IsRowMajor };
129 
130  using Base::operator=;
131 
132  public:
133 
134  //----------------------------------------
135  // direct access interface
136  using Base::valuePtr;
137  using Base::innerIndexPtr;
138  using Base::outerIndexPtr;
139  using Base::innerNonZeroPtr;
140  inline Scalar* valuePtr() { return Base::m_values; }
141  inline StorageIndex* innerIndexPtr() { return Base::m_innerIndices; }
142  inline StorageIndex* outerIndexPtr() { return Base::m_outerIndex; }
143  inline StorageIndex* innerNonZeroPtr() { return Base::m_innerNonZeros; }
144  //----------------------------------------
145 
146  inline Scalar& coeffRef(Index row, Index col)
147  {
148  const Index outer = IsRowMajor ? row : col;
149  const Index inner = IsRowMajor ? col : row;
150 
151  Index start = Base::m_outerIndex[outer];
152  Index end = Base::isCompressed() ? Base::m_outerIndex[outer+1] : start + Base::m_innerNonZeros[outer];
153  eigen_assert(end>=start && "you probably called coeffRef on a non finalized matrix");
154  eigen_assert(end>start && "coeffRef cannot be called on a zero coefficient");
155  Index* r = std::lower_bound(&Base::m_innerIndices[start],&Base::m_innerIndices[end],inner);
156  const Index id = r - &Base::m_innerIndices[0];
157  eigen_assert((*r==inner) && (id<end) && "coeffRef cannot be called on a zero coefficient");
158  return const_cast<Scalar*>(Base::m_values)[id];
159  }
160 
161  inline SparseMapBase(Index rows, Index cols, Index nnz, StorageIndex* outerIndexPtr, StorageIndex* innerIndexPtr,
162  Scalar* valuePtr, StorageIndex* innerNonZerosPtr = 0)
163  : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr)
164  {}
165 
167  inline ~SparseMapBase() {}
168 };
169 
170 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
171 class Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType>
172  : public SparseMapBase<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
173 {
174  public:
175  typedef SparseMapBase<Map> Base;
176  _EIGEN_SPARSE_PUBLIC_INTERFACE(Map)
177  enum { IsRowMajor = Base::IsRowMajor };
178 
179  public:
180 
181  inline Map(Index rows, Index cols, Index nnz, StorageIndex* outerIndexPtr,
182  StorageIndex* innerIndexPtr, Scalar* valuePtr, StorageIndex* innerNonZerosPtr = 0)
183  : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr)
184  {}
185 
187  inline ~Map() {}
188 };
189 
190 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
191 class Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType>
192  : public SparseMapBase<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
193 {
194  public:
195  typedef SparseMapBase<Map> Base;
196  _EIGEN_SPARSE_PUBLIC_INTERFACE(Map)
197  enum { IsRowMajor = Base::IsRowMajor };
198 
199  public:
200 
201  inline Map(Index rows, Index cols, Index nnz, const StorageIndex* outerIndexPtr,
202  const StorageIndex* innerIndexPtr, const Scalar* valuePtr, const StorageIndex* innerNonZerosPtr = 0)
203  : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr)
204  {}
205 
207  inline ~Map() {}
208 };
209 
210 namespace internal {
211 
212 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
213 struct evaluator<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
214  : evaluator<SparseCompressedBase<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
215 {
216  typedef evaluator<SparseCompressedBase<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
217  typedef Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
218  evaluator() : Base() {}
219  explicit evaluator(const XprType &mat) : Base(mat) {}
220 };
221 
222 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
223 struct evaluator<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
224  : evaluator<SparseCompressedBase<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
225 {
226  typedef evaluator<SparseCompressedBase<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
227  typedef Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
228  evaluator() : Base() {}
229  explicit evaluator(const XprType &mat) : Base(mat) {}
230 };
231 
232 }
233 
234 } // end namespace Eigen
235 
236 #endif // EIGEN_SPARSE_MAP_H
Definition: Constants.h:360
const unsigned int LvalueBit
Definition: Constants.h:130
Definition: LDLT.h:16
Definition: Constants.h:358
Definition: Eigen_Colamd.h:54