Eigen  3.3.7
SparseRef.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_REF_H
11 #define EIGEN_SPARSE_REF_H
12 
13 namespace Eigen {
14 
15 enum {
17 };
18 
19 namespace internal {
20 
21 template<typename Derived> class SparseRefBase;
22 
23 template<typename MatScalar, int MatOptions, typename MatIndex, int _Options, typename _StrideType>
24 struct traits<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> >
25  : public traits<SparseMatrix<MatScalar,MatOptions,MatIndex> >
26 {
27  typedef SparseMatrix<MatScalar,MatOptions,MatIndex> PlainObjectType;
28  enum {
29  Options = _Options,
30  Flags = traits<PlainObjectType>::Flags | CompressedAccessBit | NestByRefBit
31  };
32 
33  template<typename Derived> struct match {
34  enum {
35  StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)),
36  MatchAtCompileTime = (Derived::Flags&CompressedAccessBit) && StorageOrderMatch
37  };
38  typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type;
39  };
40 
41 };
42 
43 template<typename MatScalar, int MatOptions, typename MatIndex, int _Options, typename _StrideType>
44 struct traits<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> >
45  : public traits<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> >
46 {
47  enum {
48  Flags = (traits<SparseMatrix<MatScalar,MatOptions,MatIndex> >::Flags | CompressedAccessBit | NestByRefBit) & ~LvalueBit
49  };
50 };
51 
52 template<typename MatScalar, int MatOptions, typename MatIndex, int _Options, typename _StrideType>
53 struct traits<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> >
54  : public traits<SparseVector<MatScalar,MatOptions,MatIndex> >
55 {
56  typedef SparseVector<MatScalar,MatOptions,MatIndex> PlainObjectType;
57  enum {
58  Options = _Options,
59  Flags = traits<PlainObjectType>::Flags | CompressedAccessBit | NestByRefBit
60  };
61 
62  template<typename Derived> struct match {
63  enum {
64  MatchAtCompileTime = (Derived::Flags&CompressedAccessBit) && Derived::IsVectorAtCompileTime
65  };
66  typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type;
67  };
68 
69 };
70 
71 template<typename MatScalar, int MatOptions, typename MatIndex, int _Options, typename _StrideType>
72 struct traits<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> >
73  : public traits<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> >
74 {
75  enum {
76  Flags = (traits<SparseVector<MatScalar,MatOptions,MatIndex> >::Flags | CompressedAccessBit | NestByRefBit) & ~LvalueBit
77  };
78 };
79 
80 template<typename Derived>
81 struct traits<SparseRefBase<Derived> > : public traits<Derived> {};
82 
83 template<typename Derived> class SparseRefBase
84  : public SparseMapBase<Derived>
85 {
86 public:
87 
88  typedef SparseMapBase<Derived> Base;
89  EIGEN_SPARSE_PUBLIC_INTERFACE(SparseRefBase)
90 
91  SparseRefBase()
92  : Base(RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime, 0, 0, 0, 0, 0)
93  {}
94 
95 protected:
96 
97  template<typename Expression>
98  void construct(Expression& expr)
99  {
100  if(expr.outerIndexPtr()==0)
101  ::new (static_cast<Base*>(this)) Base(expr.size(), expr.nonZeros(), expr.innerIndexPtr(), expr.valuePtr());
102  else
103  ::new (static_cast<Base*>(this)) Base(expr.rows(), expr.cols(), expr.nonZeros(), expr.outerIndexPtr(), expr.innerIndexPtr(), expr.valuePtr(), expr.innerNonZeroPtr());
104  }
105 };
106 
107 } // namespace internal
108 
109 
121 #ifndef EIGEN_PARSED_BY_DOXYGEN
122 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
123 class Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType >
124  : public internal::SparseRefBase<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType > >
125 #else
126 template<typename SparseMatrixType, int Options>
127 class Ref<SparseMatrixType, Options>
128  : public SparseMapBase<Derived,WriteAccessors> // yes, that's weird to use Derived here, but that works!
129 #endif
130 {
132  typedef internal::traits<Ref> Traits;
133  template<int OtherOptions>
135  template<int OtherOptions>
137  public:
138 
139  typedef internal::SparseRefBase<Ref> Base;
140  EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
141 
142 
143  #ifndef EIGEN_PARSED_BY_DOXYGEN
144  template<int OtherOptions>
146  {
147  EIGEN_STATIC_ASSERT(bool(Traits::template match<SparseMatrix<MatScalar,OtherOptions,MatIndex> >::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
148  eigen_assert( ((Options & int(StandardCompressedFormat))==0) || (expr.isCompressed()) );
149  Base::construct(expr.derived());
150  }
151 
152  template<int OtherOptions>
154  {
155  EIGEN_STATIC_ASSERT(bool(Traits::template match<SparseMatrix<MatScalar,OtherOptions,MatIndex> >::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
156  eigen_assert( ((Options & int(StandardCompressedFormat))==0) || (expr.isCompressed()) );
157  Base::construct(expr.derived());
158  }
159 
160  template<typename Derived>
161  inline Ref(const SparseCompressedBase<Derived>& expr)
162  #else
163 
164  template<typename Derived>
166  #endif
167  {
168  EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
169  EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
170  eigen_assert( ((Options & int(StandardCompressedFormat))==0) || (expr.isCompressed()) );
171  Base::construct(expr.const_cast_derived());
172  }
173 };
174 
175 // this is the const ref version
176 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
177 class Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType>
178  : public internal::SparseRefBase<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
179 {
180  typedef SparseMatrix<MatScalar,MatOptions,MatIndex> TPlainObjectType;
181  typedef internal::traits<Ref> Traits;
182  public:
183 
184  typedef internal::SparseRefBase<Ref> Base;
185  EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
186 
187  template<typename Derived>
188  inline Ref(const SparseMatrixBase<Derived>& expr) : m_hasCopy(false)
189  {
190  construct(expr.derived(), typename Traits::template match<Derived>::type());
191  }
192 
193  inline Ref(const Ref& other) : Base(other), m_hasCopy(false) {
194  // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
195  }
196 
197  template<typename OtherRef>
198  inline Ref(const RefBase<OtherRef>& other) : m_hasCopy(false) {
199  construct(other.derived(), typename Traits::template match<OtherRef>::type());
200  }
201 
202  ~Ref() {
203  if(m_hasCopy) {
204  TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes);
205  obj->~TPlainObjectType();
206  }
207  }
208 
209  protected:
210 
211  template<typename Expression>
212  void construct(const Expression& expr,internal::true_type)
213  {
214  if((Options & int(StandardCompressedFormat)) && (!expr.isCompressed()))
215  {
216  TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes);
217  ::new (obj) TPlainObjectType(expr);
218  m_hasCopy = true;
219  Base::construct(*obj);
220  }
221  else
222  {
223  Base::construct(expr);
224  }
225  }
226 
227  template<typename Expression>
228  void construct(const Expression& expr, internal::false_type)
229  {
230  TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes);
231  ::new (obj) TPlainObjectType(expr);
232  m_hasCopy = true;
233  Base::construct(*obj);
234  }
235 
236  protected:
237  char m_object_bytes[sizeof(TPlainObjectType)];
238  bool m_hasCopy;
239 };
240 
241 
242 
252 #ifndef EIGEN_PARSED_BY_DOXYGEN
253 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
254 class Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType >
255  : public internal::SparseRefBase<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType > >
256 #else
257 template<typename SparseVectorType>
258 class Ref<SparseVectorType>
259  : public SparseMapBase<Derived,WriteAccessors>
260 #endif
261 {
263  typedef internal::traits<Ref> Traits;
264  template<int OtherOptions>
266  public:
267 
268  typedef internal::SparseRefBase<Ref> Base;
269  EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
270 
271  #ifndef EIGEN_PARSED_BY_DOXYGEN
272  template<int OtherOptions>
274  {
275  EIGEN_STATIC_ASSERT(bool(Traits::template match<SparseVector<MatScalar,OtherOptions,MatIndex> >::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
276  Base::construct(expr.derived());
277  }
278 
279  template<typename Derived>
280  inline Ref(const SparseCompressedBase<Derived>& expr)
281  #else
282 
283  template<typename Derived>
285  #endif
286  {
287  EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
288  EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
289  Base::construct(expr.const_cast_derived());
290  }
291 };
292 
293 // this is the const ref version
294 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
295 class Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType>
296  : public internal::SparseRefBase<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
297 {
298  typedef SparseVector<MatScalar,MatOptions,MatIndex> TPlainObjectType;
299  typedef internal::traits<Ref> Traits;
300  public:
301 
302  typedef internal::SparseRefBase<Ref> Base;
303  EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
304 
305  template<typename Derived>
306  inline Ref(const SparseMatrixBase<Derived>& expr) : m_hasCopy(false)
307  {
308  construct(expr.derived(), typename Traits::template match<Derived>::type());
309  }
310 
311  inline Ref(const Ref& other) : Base(other), m_hasCopy(false) {
312  // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
313  }
314 
315  template<typename OtherRef>
316  inline Ref(const RefBase<OtherRef>& other) : m_hasCopy(false) {
317  construct(other.derived(), typename Traits::template match<OtherRef>::type());
318  }
319 
320  ~Ref() {
321  if(m_hasCopy) {
322  TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes);
323  obj->~TPlainObjectType();
324  }
325  }
326 
327  protected:
328 
329  template<typename Expression>
330  void construct(const Expression& expr,internal::true_type)
331  {
332  Base::construct(expr);
333  }
334 
335  template<typename Expression>
336  void construct(const Expression& expr, internal::false_type)
337  {
338  TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes);
339  ::new (obj) TPlainObjectType(expr);
340  m_hasCopy = true;
341  Base::construct(*obj);
342  }
343 
344  protected:
345  char m_object_bytes[sizeof(TPlainObjectType)];
346  bool m_hasCopy;
347 };
348 
349 namespace internal {
350 
351 // FIXME shall we introduce a general evaluatior_ref that we can specialize for any sparse object once, and thus remove this copy-pasta thing...
352 
353 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
354 struct evaluator<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
355  : evaluator<SparseCompressedBase<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
356 {
357  typedef evaluator<SparseCompressedBase<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
358  typedef Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
359  evaluator() : Base() {}
360  explicit evaluator(const XprType &mat) : Base(mat) {}
361 };
362 
363 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
364 struct evaluator<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
365  : evaluator<SparseCompressedBase<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
366 {
367  typedef evaluator<SparseCompressedBase<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
368  typedef Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
369  evaluator() : Base() {}
370  explicit evaluator(const XprType &mat) : Base(mat) {}
371 };
372 
373 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
374 struct evaluator<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
375  : evaluator<SparseCompressedBase<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
376 {
377  typedef evaluator<SparseCompressedBase<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
378  typedef Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
379  evaluator() : Base() {}
380  explicit evaluator(const XprType &mat) : Base(mat) {}
381 };
382 
383 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
384 struct evaluator<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
385  : evaluator<SparseCompressedBase<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
386 {
387  typedef evaluator<SparseCompressedBase<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
388  typedef Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
389  evaluator() : Base() {}
390  explicit evaluator(const XprType &mat) : Base(mat) {}
391 };
392 
393 }
394 
395 } // end namespace Eigen
396 
397 #endif // EIGEN_SPARSE_REF_H
bool isCompressed() const
Definition: SparseCompressedBase.h:107
const unsigned int CompressedAccessBit
Definition: Constants.h:186
A versatible sparse matrix representation.
Definition: SparseMatrix.h:96
const unsigned int LvalueBit
Definition: Constants.h:139
Namespace containing all symbols from the Eigen library.
Definition: Core:306
SparseMatrix< _Scalar, _Options, _StorageIndex > & derived()
Definition: EigenBase.h:45
const unsigned int RowMajorBit
Definition: Constants.h:61
Base class of any sparse matrices or sparse expressions.
Definition: ForwardDeclarations.h:277
a sparse vector class
Definition: SparseUtil.h:54
Definition: SparseRef.h:16
A matrix or vector expression mapping an existing expression.
Definition: Ref.h:193
Ref(SparseCompressedBase< Derived > &expr)
Definition: SparseRef.h:165
Definition: Eigen_Colamd.h:50
const int Dynamic
Definition: Constants.h:21
bool isCompressed() const
Definition: SparseCompressedBase.h:107
Common base class for sparse [compressed]-{row|column}-storage format.
Definition: SparseCompressedBase.h:15
Sparse matrix.
Definition: MappedSparseMatrix.h:32
Ref(SparseCompressedBase< Derived > &expr)
Definition: SparseRef.h:284