Eigen  3.3.0
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)
189  {
190  construct(expr.derived(), typename Traits::template match<Derived>::type());
191  }
192 
193  inline Ref(const Ref& other) : Base(other) {
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) {
199  construct(other.derived(), typename Traits::template match<OtherRef>::type());
200  }
201 
202  protected:
203 
204  template<typename Expression>
205  void construct(const Expression& expr,internal::true_type)
206  {
207  if((Options & int(StandardCompressedFormat)) && (!expr.isCompressed()))
208  {
209  TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes);
210  ::new (obj) TPlainObjectType(expr);
211  Base::construct(*obj);
212  }
213  else
214  {
215  Base::construct(expr);
216  }
217  }
218 
219  template<typename Expression>
220  void construct(const Expression& expr, internal::false_type)
221  {
222  TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes);
223  ::new (obj) TPlainObjectType(expr);
224  Base::construct(*obj);
225  }
226 
227  protected:
228  char m_object_bytes[sizeof(TPlainObjectType)];
229 };
230 
231 
232 
242 #ifndef EIGEN_PARSED_BY_DOXYGEN
243 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
244 class Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType >
245  : public internal::SparseRefBase<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType > >
246 #else
247 template<typename SparseVectorType>
248 class Ref<SparseVectorType>
249  : public SparseMapBase<Derived,WriteAccessors>
250 #endif
251 {
252  typedef SparseVector<MatScalar,MatOptions,MatIndex> PlainObjectType;
253  typedef internal::traits<Ref> Traits;
254  template<int OtherOptions>
255  inline Ref(const SparseVector<MatScalar,OtherOptions,MatIndex>& expr);
256  public:
257 
258  typedef internal::SparseRefBase<Ref> Base;
259  EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
260 
261  #ifndef EIGEN_PARSED_BY_DOXYGEN
262  template<int OtherOptions>
264  {
265  EIGEN_STATIC_ASSERT(bool(Traits::template match<SparseVector<MatScalar,OtherOptions,MatIndex> >::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
266  Base::construct(expr.derived());
267  }
268 
269  template<typename Derived>
270  inline Ref(const SparseCompressedBase<Derived>& expr)
271  #else
272 
273  template<typename Derived>
275  #endif
276  {
277  EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
278  EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
279  Base::construct(expr.const_cast_derived());
280  }
281 };
282 
283 // this is the const ref version
284 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
285 class Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType>
286  : public internal::SparseRefBase<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
287 {
288  typedef SparseVector<MatScalar,MatOptions,MatIndex> TPlainObjectType;
289  typedef internal::traits<Ref> Traits;
290  public:
291 
292  typedef internal::SparseRefBase<Ref> Base;
293  EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
294 
295  template<typename Derived>
296  inline Ref(const SparseMatrixBase<Derived>& expr)
297  {
298  construct(expr.derived(), typename Traits::template match<Derived>::type());
299  }
300 
301  inline Ref(const Ref& other) : Base(other) {
302  // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
303  }
304 
305  template<typename OtherRef>
306  inline Ref(const RefBase<OtherRef>& other) {
307  construct(other.derived(), typename Traits::template match<OtherRef>::type());
308  }
309 
310  protected:
311 
312  template<typename Expression>
313  void construct(const Expression& expr,internal::true_type)
314  {
315  Base::construct(expr);
316  }
317 
318  template<typename Expression>
319  void construct(const Expression& expr, internal::false_type)
320  {
321  TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes);
322  ::new (obj) TPlainObjectType(expr);
323  Base::construct(*obj);
324  }
325 
326  protected:
327  char m_object_bytes[sizeof(TPlainObjectType)];
328 };
329 
330 namespace internal {
331 
332 // FIXME shall we introduce a general evaluatior_ref that we can specialize for any sparse object once, and thus remove this copy-pasta thing...
333 
334 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
335 struct evaluator<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
336  : evaluator<SparseCompressedBase<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
337 {
338  typedef evaluator<SparseCompressedBase<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
339  typedef Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
340  evaluator() : Base() {}
341  explicit evaluator(const XprType &mat) : Base(mat) {}
342 };
343 
344 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
345 struct evaluator<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
346  : evaluator<SparseCompressedBase<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
347 {
348  typedef evaluator<SparseCompressedBase<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
349  typedef Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
350  evaluator() : Base() {}
351  explicit evaluator(const XprType &mat) : Base(mat) {}
352 };
353 
354 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
355 struct evaluator<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
356  : evaluator<SparseCompressedBase<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
357 {
358  typedef evaluator<SparseCompressedBase<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
359  typedef Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
360  evaluator() : Base() {}
361  explicit evaluator(const XprType &mat) : Base(mat) {}
362 };
363 
364 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
365 struct evaluator<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
366  : evaluator<SparseCompressedBase<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
367 {
368  typedef evaluator<SparseCompressedBase<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
369  typedef Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
370  evaluator() : Base() {}
371  explicit evaluator(const XprType &mat) : Base(mat) {}
372 };
373 
374 }
375 
376 } // end namespace Eigen
377 
378 #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:92
const unsigned int LvalueBit
Definition: Constants.h:139
Namespace containing all symbols from the Eigen library.
Definition: Core:287
SparseMatrix< _Scalar, _Options, _Index > & derived()
Definition: EigenBase.h:44
const unsigned int RowMajorBit
Definition: Constants.h:61
Base class of any sparse matrices or sparse expressions.
Definition: ForwardDeclarations.h:281
Definition: SparseRef.h:16
a sparse vector class
Definition: SparseUtil.h:54
A matrix or vector expression mapping an existing expression.
Definition: Ref.h:190
Ref(SparseCompressedBase< Derived > &expr)
Definition: SparseRef.h:165
Definition: Eigen_Colamd.h:50
const int Dynamic
Definition: Constants.h:21
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:274