Eigen  5.0.1
 
Loading...
Searching...
No Matches
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// SPDX-License-Identifier: MPL-2.0
10
11#ifndef EIGEN_SPARSE_MAP_H
12#define EIGEN_SPARSE_MAP_H
13
14// IWYU pragma: private
15#include "./InternalHeaderCheck.h"
16
17namespace Eigen {
18
19namespace internal {
20
21template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
22struct traits<Map<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> >
23 : public traits<SparseMatrix<MatScalar, MatOptions, MatIndex> > {
24 using PlainObjectType = SparseMatrix<MatScalar, MatOptions, MatIndex>;
25 using TraitsBase = traits<PlainObjectType>;
26 enum { Flags = TraitsBase::Flags & (~NestByRefBit) };
27};
28
29template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
30struct traits<Map<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> >
31 : public traits<SparseMatrix<MatScalar, MatOptions, MatIndex> > {
32 using PlainObjectType = SparseMatrix<MatScalar, MatOptions, MatIndex>;
33 using TraitsBase = traits<PlainObjectType>;
34 enum { Flags = TraitsBase::Flags & (~(NestByRefBit | LvalueBit)) };
35};
36
37} // end namespace internal
38
39template <typename Derived,
40 int Level = internal::accessors_level<Derived>::has_write_access ? WriteAccessors : ReadOnlyAccessors>
41class SparseMapBase;
42
47template <typename Derived>
48class SparseMapBase<Derived, ReadOnlyAccessors> : public SparseCompressedBase<Derived> {
49 public:
50 using Base = SparseCompressedBase<Derived>;
51 using Scalar = typename Base::Scalar;
52 using StorageIndex = typename Base::StorageIndex;
53 enum { IsRowMajor = Base::IsRowMajor };
54 using Base::operator=;
55
56 protected:
57 using ScalarPointer = std::conditional_t<bool(internal::is_lvalue<Derived>::value), Scalar*, const Scalar*>;
58 using IndexPointer =
59 std::conditional_t<bool(internal::is_lvalue<Derived>::value), StorageIndex*, const StorageIndex*>;
60
61 Index m_outerSize;
62 Index m_innerSize;
63 Array<StorageIndex, 2, 1> m_zero_nnz;
64 IndexPointer m_outerIndex;
65 IndexPointer m_innerIndices;
66 ScalarPointer m_values;
67 IndexPointer m_innerNonZeros;
68
69 public:
71 inline Index rows() const { return IsRowMajor ? m_outerSize : m_innerSize; }
73 inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; }
75 inline Index innerSize() const { return m_innerSize; }
77 inline Index outerSize() const { return m_outerSize; }
79 inline Index nonZeros() const { return m_zero_nnz[1]; }
80
82 bool isCompressed() const { return m_innerNonZeros == 0; }
83
84 //----------------------------------------
85 // direct access interface
87 inline const Scalar* valuePtr() const { return m_values; }
89 inline const StorageIndex* innerIndexPtr() const { return m_innerIndices; }
91 inline const StorageIndex* outerIndexPtr() const { return m_outerIndex; }
93 inline const StorageIndex* innerNonZeroPtr() const { return m_innerNonZeros; }
94 //----------------------------------------
95
97 inline Scalar coeff(Index row, Index col) const {
98 const Index outer = IsRowMajor ? row : col;
99 const Index inner = IsRowMajor ? col : row;
100
101 Index start = m_outerIndex[outer];
102 Index end = isCompressed() ? m_outerIndex[outer + 1] : start + m_innerNonZeros[outer];
103 if (start == end)
104 return Scalar(0);
105 else if (end > 0 && inner == m_innerIndices[end - 1])
106 return m_values[end - 1];
107 // ^^ optimization: let's first check if it is the last coefficient
108 // (very common in high level algorithms)
109
110 const StorageIndex* r = std::lower_bound(&m_innerIndices[start], &m_innerIndices[end - 1], inner);
111 const Index id = r - &m_innerIndices[0];
112 return ((*r == inner) && (id < end)) ? m_values[id] : Scalar(0);
113 }
114
115 inline SparseMapBase(Index rows, Index cols, Index nnz, IndexPointer outerIndexPtr, IndexPointer innerIndexPtr,
116 ScalarPointer valuePtr, IndexPointer innerNonZerosPtr = 0)
117 : m_outerSize(IsRowMajor ? rows : cols),
118 m_innerSize(IsRowMajor ? cols : rows),
119 m_zero_nnz(0, internal::convert_index<StorageIndex>(nnz)),
120 m_outerIndex(outerIndexPtr),
121 m_innerIndices(innerIndexPtr),
122 m_values(valuePtr),
123 m_innerNonZeros(innerNonZerosPtr) {}
124
125 // for vectors
126 inline SparseMapBase(Index size, Index nnz, IndexPointer innerIndexPtr, ScalarPointer valuePtr)
127 : m_outerSize(1),
128 m_innerSize(size),
129 m_zero_nnz(0, internal::convert_index<StorageIndex>(nnz)),
130 m_outerIndex(m_zero_nnz.data()),
131 m_innerIndices(innerIndexPtr),
132 m_values(valuePtr),
133 m_innerNonZeros(0) {}
134
135 protected:
136 inline SparseMapBase() = default;
137};
138
143template <typename Derived>
144class SparseMapBase<Derived, WriteAccessors> : public SparseMapBase<Derived, ReadOnlyAccessors> {
145 public:
146 using Base = SparseMapBase<Derived, ReadOnlyAccessors>;
147 using Scalar = typename Base::Scalar;
148 using StorageIndex = typename Base::StorageIndex;
149 enum { IsRowMajor = Base::IsRowMajor };
150
151 using Base::operator=;
152
153 public:
154 //----------------------------------------
155 // direct access interface
156 using Base::innerIndexPtr;
157 using Base::innerNonZeroPtr;
158 using Base::outerIndexPtr;
159 using Base::valuePtr;
161 inline Scalar* valuePtr() { return Base::m_values; }
163 inline StorageIndex* innerIndexPtr() { return Base::m_innerIndices; }
165 inline StorageIndex* outerIndexPtr() { return Base::m_outerIndex; }
167 inline StorageIndex* innerNonZeroPtr() { return Base::m_innerNonZeros; }
168 //----------------------------------------
169
177 inline Scalar& coeffRef(Index row, Index col) {
178 const Index outer = IsRowMajor ? row : col;
179 const Index inner = IsRowMajor ? col : row;
180
181 Index start = Base::m_outerIndex[outer];
182 Index end = Base::isCompressed() ? Base::m_outerIndex[outer + 1] : start + Base::m_innerNonZeros[outer];
183 eigen_assert(end >= start && "you probably called coeffRef on a non finalized matrix");
184 eigen_assert(end > start && "coeffRef cannot be called on a zero coefficient");
185 StorageIndex* r = std::lower_bound(&Base::m_innerIndices[start], &Base::m_innerIndices[end], inner);
186 const Index id = r - &Base::m_innerIndices[0];
187 eigen_assert((*r == inner) && (id < end) && "coeffRef cannot be called on a zero coefficient");
188 return const_cast<Scalar*>(Base::m_values)[id];
189 }
190
191 inline SparseMapBase(Index rows, Index cols, Index nnz, StorageIndex* outerIndexPtr, StorageIndex* innerIndexPtr,
192 Scalar* valuePtr, StorageIndex* innerNonZerosPtr = 0)
193 : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr) {}
194
195 // for vectors
196 inline SparseMapBase(Index size, Index nnz, StorageIndex* innerIndexPtr, Scalar* valuePtr)
197 : Base(size, nnz, innerIndexPtr, valuePtr) {}
198
199 protected:
200 inline SparseMapBase() = default;
201};
202
212#ifndef EIGEN_PARSED_BY_DOXYGEN
213template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
214class Map<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>
215 : public SparseMapBase<Map<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> >
216#else
217template <typename SparseMatrixType>
218class Map<SparseMatrixType> : public SparseMapBase<Derived, WriteAccessors>
219#endif
220{
221 public:
222 using Base = SparseMapBase<Map>;
223 EIGEN_SPARSE_PUBLIC_INTERFACE(Map)
224 enum { IsRowMajor = Base::IsRowMajor };
225
226 public:
236 inline Map(Index rows, Index cols, Index nnz, StorageIndex* outerIndexPtr, StorageIndex* innerIndexPtr,
237 Scalar* valuePtr, StorageIndex* innerNonZerosPtr = 0)
238 : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr) {}
239#ifndef EIGEN_PARSED_BY_DOXYGEN
240};
241
242template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
243class Map<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>
244 : public SparseMapBase<Map<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> > {
245 public:
246 using Base = SparseMapBase<Map>;
247 EIGEN_SPARSE_PUBLIC_INTERFACE(Map)
248 enum { IsRowMajor = Base::IsRowMajor };
249
250 public:
251#endif
257 inline Map(Index rows, Index cols, Index nnz, const StorageIndex* outerIndexPtr, const StorageIndex* innerIndexPtr,
258 const Scalar* valuePtr, const StorageIndex* innerNonZerosPtr = 0)
259 : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr) {}
260};
261
262namespace internal {
263
264template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
265struct evaluator<Map<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> >
266 : evaluator<SparseCompressedBase<Map<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> > > {
267 using Base = evaluator<SparseCompressedBase<Map<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>>>;
268 using XprType = Map<SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>;
269 evaluator() = default;
270 explicit evaluator(const XprType& mat) : Base(mat) {}
271};
272
273template <typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
274struct evaluator<Map<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> >
275 : evaluator<SparseCompressedBase<Map<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType> > > {
276 using Base =
277 evaluator<SparseCompressedBase<Map<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>>>;
278 using XprType = Map<const SparseMatrix<MatScalar, MatOptions, MatIndex>, Options, StrideType>;
279 evaluator() = default;
280 explicit evaluator(const XprType& mat) : Base(mat) {}
281};
282
283} // namespace internal
284
285} // end namespace Eigen
286
287#endif // EIGEN_SPARSE_MAP_H
Map(Index rows, Index cols, Index nnz, const StorageIndex *outerIndexPtr, const StorageIndex *innerIndexPtr, const Scalar *valuePtr, const StorageIndex *innerNonZerosPtr=0)
Definition SparseMap.h:257
Map(Index rows, Index cols, Index nnz, StorageIndex *outerIndexPtr, StorageIndex *innerIndexPtr, Scalar *valuePtr, StorageIndex *innerNonZerosPtr=0)
Definition SparseMap.h:236
A matrix or vector expression mapping an existing array of data.
Definition Map.h:97
constexpr Map(PointerArgType dataPtr, const StrideType &stride=StrideType())
Definition Map.h:124
Common base class for sparse [compressed]-{row|column}-storage format.
Definition SparseCompressedBase.h:44
Scalar & coeffRef(Index row, Index col)
Definition SparseMap.h:177
Scalar * valuePtr()
Definition SparseMap.h:161
StorageIndex * innerNonZeroPtr()
Definition SparseMap.h:167
StorageIndex * outerIndexPtr()
Definition SparseMap.h:165
StorageIndex * innerIndexPtr()
Definition SparseMap.h:163
A versatile sparse matrix representation.
Definition SparseMatrix.h:122
@ ReadOnlyAccessors
Definition Constants.h:377
@ WriteAccessors
Definition Constants.h:379
constexpr unsigned int LvalueBit
Definition Constants.h:149