Eigen  3.4.90 (git rev 5a9f66fb35d03a4da9ef8976e67a61b30aa16dcf)
 
Loading...
Searching...
No Matches
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 <[email protected]>
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// IWYU pragma: private
14#include "./InternalHeaderCheck.h"
15
16namespace Eigen {
17
18enum {
20 2
21};
22
23namespace internal {
24
25template <typename Derived>
26class SparseRefBase;
27
28template <typename MatScalar, int MatOptions, typename MatIndex, int Options_, typename StrideType_>
29struct traits<Ref<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options_, StrideType_>>
30 : public traits<SparseMatrix<MatScalar, MatOptions, MatIndex>> {
31 typedef SparseMatrix<MatScalar, MatOptions, MatIndex> PlainObjectType;
32 enum { Options = Options_, Flags = traits<PlainObjectType>::Flags | CompressedAccessBit | NestByRefBit };
33
34 template <typename Derived>
35 struct match {
36 enum {
37 StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime ||
38 ((PlainObjectType::Flags & RowMajorBit) == (Derived::Flags & RowMajorBit)),
39 MatchAtCompileTime = (Derived::Flags & CompressedAccessBit) && StorageOrderMatch
40 };
41 typedef std::conditional_t<MatchAtCompileTime, internal::true_type, internal::false_type> type;
42 };
43};
44
45template <typename MatScalar, int MatOptions, typename MatIndex, int Options_, typename StrideType_>
46struct traits<Ref<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options_, StrideType_>>
47 : public traits<Ref<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options_, StrideType_>> {
48 enum {
49 Flags =
50 (traits<SparseMatrix<MatScalar, MatOptions, MatIndex>>::Flags | CompressedAccessBit | NestByRefBit) & ~LvalueBit
51 };
52};
53
54template <typename MatScalar, int MatOptions, typename MatIndex, int Options_, typename StrideType_>
55struct traits<Ref<SparseVector<MatScalar, MatOptions, MatIndex>, Options_, StrideType_>>
56 : public traits<SparseVector<MatScalar, MatOptions, MatIndex>> {
57 typedef SparseVector<MatScalar, MatOptions, MatIndex> PlainObjectType;
58 enum { Options = Options_, Flags = traits<PlainObjectType>::Flags | CompressedAccessBit | NestByRefBit };
59
60 template <typename Derived>
61 struct match {
62 enum { MatchAtCompileTime = (Derived::Flags & CompressedAccessBit) && Derived::IsVectorAtCompileTime };
63 typedef std::conditional_t<MatchAtCompileTime, internal::true_type, internal::false_type> type;
64 };
65};
66
67template <typename MatScalar, int MatOptions, typename MatIndex, int Options_, typename StrideType_>
68struct traits<Ref<const SparseVector<MatScalar, MatOptions, MatIndex>, Options_, StrideType_>>
69 : public traits<Ref<SparseVector<MatScalar, MatOptions, MatIndex>, Options_, StrideType_>> {
70 enum {
71 Flags =
72 (traits<SparseVector<MatScalar, MatOptions, MatIndex>>::Flags | CompressedAccessBit | NestByRefBit) & ~LvalueBit
73 };
74};
75
76template <typename Derived>
77struct traits<SparseRefBase<Derived>> : public traits<Derived> {};
78
79template <typename Derived>
80class SparseRefBase : public SparseMapBase<Derived> {
81 public:
82 typedef SparseMapBase<Derived> Base;
83 EIGEN_SPARSE_PUBLIC_INTERFACE(SparseRefBase)
84
85 SparseRefBase()
86 : Base(RowsAtCompileTime == Dynamic ? 0 : RowsAtCompileTime, ColsAtCompileTime == Dynamic ? 0 : ColsAtCompileTime,
87 0, 0, 0, 0, 0) {}
88
89 protected:
90 template <typename Expression>
91 void construct(Expression& expr) {
92 if (expr.outerIndexPtr() == 0)
93 internal::construct_at<Base>(this, expr.size(), expr.nonZeros(), expr.innerIndexPtr(), expr.valuePtr());
94 else
95 internal::construct_at<Base>(this, expr.rows(), expr.cols(), expr.nonZeros(), expr.outerIndexPtr(),
96 expr.innerIndexPtr(), expr.valuePtr(), expr.innerNonZeroPtr());
97 }
98};
99
100} // namespace internal
101
113#ifndef EIGEN_PARSED_BY_DOXYGEN
114template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
115class Ref<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>
116 : public internal::SparseRefBase<Ref<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>>
117#else
118template <typename SparseMatrixType, int Options>
119class Ref<SparseMatrixType, Options>
120 : public SparseMapBase<Derived, WriteAccessors> // yes, that's weird to use Derived here, but that works!
121#endif
122{
124 typedef internal::traits<Ref> Traits;
125 template <int OtherOptions>
127 template <int OtherOptions>
129
130 public:
131 typedef internal::SparseRefBase<Ref> Base;
132 EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
133
134#ifndef EIGEN_PARSED_BY_DOXYGEN
135 template <int OtherOptions>
137 EIGEN_STATIC_ASSERT(
138 bool(Traits::template match<SparseMatrix<MatScalar, OtherOptions, MatIndex>>::MatchAtCompileTime),
139 STORAGE_LAYOUT_DOES_NOT_MATCH);
140 eigen_assert(((Options & int(StandardCompressedFormat)) == 0) || (expr.isCompressed()));
141 Base::construct(expr.derived());
142 }
143
144 template <int OtherOptions>
146 EIGEN_STATIC_ASSERT(
147 bool(Traits::template match<SparseMatrix<MatScalar, OtherOptions, MatIndex>>::MatchAtCompileTime),
148 STORAGE_LAYOUT_DOES_NOT_MATCH);
149 eigen_assert(((Options & int(StandardCompressedFormat)) == 0) || (expr.isCompressed()));
150 Base::construct(expr.derived());
151 }
152
153 template <typename Derived>
154 inline Ref(const SparseCompressedBase<Derived>& expr)
155#else
157 template <typename Derived>
159#endif
160 {
161 EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
162 EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
163 eigen_assert(((Options & int(StandardCompressedFormat)) == 0) || (expr.isCompressed()));
164 Base::construct(expr.const_cast_derived());
165 }
166};
167
168// this is the const ref version
169template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
170class Ref<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>
171 : public internal::SparseRefBase<Ref<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>> {
172 typedef SparseMatrix<MatScalar, MatOptions, MatIndex> TPlainObjectType;
173 typedef internal::traits<Ref> Traits;
174
175 public:
176 typedef internal::SparseRefBase<Ref> Base;
177 EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
178
179 template <typename Derived>
180 inline Ref(const SparseMatrixBase<Derived>& expr) : m_hasCopy(false) {
181 construct(expr.derived(), typename Traits::template match<Derived>::type());
182 }
183
184 inline Ref(const Ref& other) : Base(other), m_hasCopy(false) {
185 // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
186 }
187
188 template <typename OtherRef>
189 inline Ref(const RefBase<OtherRef>& other) : m_hasCopy(false) {
190 construct(other.derived(), typename Traits::template match<OtherRef>::type());
191 }
192
193 ~Ref() {
194 if (m_hasCopy) {
195 internal::destroy_at(reinterpret_cast<TPlainObjectType*>(&m_storage));
196 }
197 }
198
199 protected:
200 template <typename Expression>
201 void construct(const Expression& expr, internal::true_type) {
202 if ((Options & int(StandardCompressedFormat)) && (!expr.isCompressed())) {
203 TPlainObjectType* obj = internal::construct_at(reinterpret_cast<TPlainObjectType*>(&m_storage), expr);
204 m_hasCopy = true;
205 Base::construct(*obj);
206 } else {
207 Base::construct(expr);
208 }
209 }
210
211 template <typename Expression>
212 void construct(const Expression& expr, internal::false_type) {
213 TPlainObjectType* obj = internal::construct_at(reinterpret_cast<TPlainObjectType*>(&m_storage), expr);
214 m_hasCopy = true;
215 Base::construct(*obj);
216 }
217
218 protected:
219 typename internal::aligned_storage<sizeof(TPlainObjectType), EIGEN_ALIGNOF(TPlainObjectType)>::type m_storage;
220 bool m_hasCopy;
221};
222
233#ifndef EIGEN_PARSED_BY_DOXYGEN
234template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
235class Ref<SparseVector<MatScalar, MatOptions, MatIndex>, Options, StrideType>
236 : public internal::SparseRefBase<Ref<SparseVector<MatScalar, MatOptions, MatIndex>, Options, StrideType>>
237#else
238template <typename SparseVectorType>
239class Ref<SparseVectorType> : public SparseMapBase<Derived, WriteAccessors>
240#endif
241{
243 typedef internal::traits<Ref> Traits;
244 template <int OtherOptions>
246
247 public:
248 typedef internal::SparseRefBase<Ref> Base;
249 EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
250
251#ifndef EIGEN_PARSED_BY_DOXYGEN
252 template <int OtherOptions>
254 EIGEN_STATIC_ASSERT(
255 bool(Traits::template match<SparseVector<MatScalar, OtherOptions, MatIndex>>::MatchAtCompileTime),
256 STORAGE_LAYOUT_DOES_NOT_MATCH);
257 Base::construct(expr.derived());
258 }
259
260 template <typename Derived>
261 inline Ref(const SparseCompressedBase<Derived>& expr)
262#else
264 template <typename Derived>
266#endif
267 {
268 EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
269 EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
270 Base::construct(expr.const_cast_derived());
271 }
272};
273
274// this is the const ref version
275template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
276class Ref<const SparseVector<MatScalar, MatOptions, MatIndex>, Options, StrideType>
277 : public internal::SparseRefBase<Ref<const SparseVector<MatScalar, MatOptions, MatIndex>, Options, StrideType>> {
278 typedef SparseVector<MatScalar, MatOptions, MatIndex> TPlainObjectType;
279 typedef internal::traits<Ref> Traits;
280
281 public:
282 typedef internal::SparseRefBase<Ref> Base;
283 EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
284
285 template <typename Derived>
286 inline Ref(const SparseMatrixBase<Derived>& expr) : m_hasCopy(false) {
287 construct(expr.derived(), typename Traits::template match<Derived>::type());
288 }
289
290 inline Ref(const Ref& other) : Base(other), m_hasCopy(false) {
291 // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
292 }
293
294 template <typename OtherRef>
295 inline Ref(const RefBase<OtherRef>& other) : m_hasCopy(false) {
296 construct(other.derived(), typename Traits::template match<OtherRef>::type());
297 }
298
299 ~Ref() {
300 if (m_hasCopy) {
301 internal::destroy_at(reinterpret_cast<TPlainObjectType*>(&m_storage));
302 }
303 }
304
305 protected:
306 template <typename Expression>
307 void construct(const Expression& expr, internal::true_type) {
308 Base::construct(expr);
309 }
310
311 template <typename Expression>
312 void construct(const Expression& expr, internal::false_type) {
313 TPlainObjectType* obj = internal::construct_at(reinterpret_cast<TPlainObjectType*>(&m_storage), expr);
314 m_hasCopy = true;
315 Base::construct(*obj);
316 }
317
318 protected:
319 typename internal::aligned_storage<sizeof(TPlainObjectType), EIGEN_ALIGNOF(TPlainObjectType)>::type m_storage;
320 bool m_hasCopy;
321};
322
323namespace internal {
324
325// FIXME shall we introduce a general evaluatior_ref that we can specialize for any sparse object once, and thus remove
326// this copy-pasta thing...
327
328template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
329struct evaluator<Ref<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>>
330 : evaluator<SparseCompressedBase<Ref<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>>> {
331 typedef evaluator<SparseCompressedBase<Ref<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>>> Base;
332 typedef Ref<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> XprType;
333 evaluator() : Base() {}
334 explicit evaluator(const XprType& mat) : Base(mat) {}
335};
336
337template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
338struct evaluator<Ref<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>>
339 : evaluator<SparseCompressedBase<Ref<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>>> {
340 typedef evaluator<SparseCompressedBase<Ref<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>>>
341 Base;
342 typedef Ref<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> XprType;
343 evaluator() : Base() {}
344 explicit evaluator(const XprType& mat) : Base(mat) {}
345};
346
347template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
348struct evaluator<Ref<SparseVector<MatScalar, MatOptions, MatIndex>, Options, StrideType>>
349 : evaluator<SparseCompressedBase<Ref<SparseVector<MatScalar, MatOptions, MatIndex>, Options, StrideType>>> {
350 typedef evaluator<SparseCompressedBase<Ref<SparseVector<MatScalar, MatOptions, MatIndex>, Options, StrideType>>> Base;
351 typedef Ref<SparseVector<MatScalar, MatOptions, MatIndex>, Options, StrideType> XprType;
352 evaluator() : Base() {}
353 explicit evaluator(const XprType& mat) : Base(mat) {}
354};
355
356template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
357struct evaluator<Ref<const SparseVector<MatScalar, MatOptions, MatIndex>, Options, StrideType>>
358 : evaluator<SparseCompressedBase<Ref<const SparseVector<MatScalar, MatOptions, MatIndex>, Options, StrideType>>> {
359 typedef evaluator<SparseCompressedBase<Ref<const SparseVector<MatScalar, MatOptions, MatIndex>, Options, StrideType>>>
360 Base;
361 typedef Ref<const SparseVector<MatScalar, MatOptions, MatIndex>, Options, StrideType> XprType;
362 evaluator() : Base() {}
363 explicit evaluator(const XprType& mat) : Base(mat) {}
364};
365
366} // namespace internal
367
368} // end namespace Eigen
369
370#endif // EIGEN_SPARSE_REF_H
A matrix or vector expression mapping an existing array of data.
Definition Map.h:96
Ref(SparseCompressedBase< Derived > &expr)
Definition SparseRef.h:158
Ref(SparseCompressedBase< Derived > &expr)
Definition SparseRef.h:265
A matrix or vector expression mapping an existing expression.
Definition Ref.h:264
Common base class for sparse [compressed]-{row|column}-storage format.
Definition SparseCompressedBase.h:43
bool isCompressed() const
Definition SparseCompressedBase.h:114
A versatible sparse matrix representation.
Definition SparseUtil.h:47
bool isCompressed() const
Definition SparseCompressedBase.h:114
a sparse vector class
Definition SparseVector.h:62
const unsigned int CompressedAccessBit
Definition Constants.h:195
Namespace containing all symbols from the Eigen library.
Definition Core:137
@ StandardCompressedFormat
Definition SparseRef.h:19
const int Dynamic
Definition Constants.h:25
Derived & derived()
Definition EigenBase.h:49