Eigen  5.0.1
 
Loading...
Searching...
No Matches
SparseMatrixBase.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2008-2014 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_SPARSEMATRIXBASE_H
12#define EIGEN_SPARSEMATRIXBASE_H
13
14// IWYU pragma: private
15#include "./InternalHeaderCheck.h"
16
17namespace Eigen {
18
30template <typename Derived>
31class SparseMatrixBase : public EigenBase<Derived> {
32 public:
33 using Scalar = typename internal::traits<Derived>::Scalar;
34
38 using value_type = Scalar;
39
40 using PacketScalar = typename internal::packet_traits<Scalar>::type;
41 using StorageKind = typename internal::traits<Derived>::StorageKind;
42
45 using StorageIndex = typename internal::traits<Derived>::StorageIndex;
47 using PacketReturnType = std::conditional_t<internal::is_arithmetic<PacketScalar>::value, PacketScalar,
48 internal::add_const_on_value_type_t<PacketScalar>>;
49
50 using StorageBaseType = SparseMatrixBase;
51
52 using IndexVector = Matrix<StorageIndex, Dynamic, 1>;
53 using ScalarVector = Matrix<Scalar, Dynamic, 1>;
54
55 template <typename OtherDerived>
56 Derived& operator=(const EigenBase<OtherDerived>& other);
57
58 enum {
59
60 RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
61 /**< The number of rows at compile-time. This is just a copy of the value provided
62 * by the \a Derived type. If a value is not known at compile-time,
63 * it is set to the \a Dynamic constant.
64 * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */
65
66 ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
69
71
72 SizeAtCompileTime = (internal::size_of_xpr_at_compile_time<Derived>::value),
73 /**< This is equal to the number of coefficients, i.e. the number of
74 * rows times the number of columns, or to \a Dynamic if this is not
75 * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */
76
77 MaxRowsAtCompileTime = RowsAtCompileTime,
78 MaxColsAtCompileTime = ColsAtCompileTime,
80 MaxSizeAtCompileTime = internal::size_at_compile_time(MaxRowsAtCompileTime, MaxColsAtCompileTime),
81
83 /**< This is set to true if either the number of rows or the number of
84 * columns is known at compile-time to be equal to 1. Indeed, in that case,
85 * we are dealing with a column-vector (if there is only one column) or with
86 * a row-vector (if there is only one row). */
87
88 NumDimensions = int(MaxSizeAtCompileTime) == 1 ? 0
89 : bool(IsVectorAtCompileTime) ? 1
90 : 2,
93 */
94
95 Flags = internal::traits<Derived>::Flags,
97
99
100 IsRowMajor = Flags & RowMajorBit ? 1 : 0,
101
102 InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
103 : int(IsRowMajor) ? int(ColsAtCompileTime)
104 : int(RowsAtCompileTime),
105
106#ifndef EIGEN_PARSED_BY_DOXYGEN
107 HasDirectAccess_ = (int(Flags) & DirectAccessBit) ? 1 : 0 // workaround sunCC
108#endif
109 };
110
111
112 using AdjointReturnType =
113 std::conditional_t<NumTraits<Scalar>::IsComplex,
116 using TransposeReturnType = Transpose<Derived>;
117 using ConstTransposeReturnType = Transpose<const Derived>;
118
119 // FIXME: storage order may not match evaluator storage order.
121
122 /** This is the "real scalar" type; if the \a Scalar type is already real numbers
123 * (e.g. int, float or double) then \a RealScalar is just the same as \a Scalar. If
124 * \a Scalar is \a std::complex<T> then RealScalar is \a T.
125 *
126 * \sa class NumTraits
127 */
128 using RealScalar = typename NumTraits<Scalar>::Real;
129
130#ifndef EIGEN_PARSED_BY_DOXYGEN
133 using CoeffReturnType = std::conditional_t<HasDirectAccess_, const Scalar&, Scalar>;
137
140 /** type of the equivalent square matrix */
141 using SquareMatrixType = Matrix<Scalar, internal::max_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime),
142 internal::max_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime)>;
144 inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
145 inline Derived& derived() { return *static_cast<Derived*>(this); }
146 inline Derived& const_cast_derived() const { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); }
147
148 using Base = EigenBase<Derived>;
149
150#endif // not EIGEN_PARSED_BY_DOXYGEN
151
152#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase
153#ifdef EIGEN_PARSED_BY_DOXYGEN
154#define EIGEN_DOC_UNARY_ADDONS(METHOD, \
155 OP)
157#define EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
158 sparse matrices. \sa \ref TutorialSparse_SubMatrices "Sparse block \
159 operations" </p> */
160#define EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF( \
161 COND)
163#else
164#define EIGEN_DOC_UNARY_ADDONS(X, Y)
165#define EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
166#define EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(COND)
167#endif
168#include "../plugins/CommonCwiseUnaryOps.inc"
169#include "../plugins/CommonCwiseBinaryOps.inc"
170#include "../plugins/MatrixCwiseUnaryOps.inc"
171#include "../plugins/MatrixCwiseBinaryOps.inc"
172#include "../plugins/BlockMethods.inc"
173#ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN
174#include EIGEN_SPARSEMATRIXBASE_PLUGIN
175#endif
176#undef EIGEN_CURRENT_STORAGE_BASE_CLASS
177#undef EIGEN_DOC_UNARY_ADDONS
178#undef EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
179#undef EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF
180
182 inline Index rows() const { return derived().rows(); }
184 inline Index cols() const { return derived().cols(); }
187 inline Index size() const { return rows() * cols(); }
192 inline bool isVector() const { return rows() == 1 || cols() == 1; }
193 /** \returns the size of the storage major dimension,
194 * i.e., the number of columns for a column major matrix, and the number of rows otherwise */
195 Index outerSize() const { return (int(Flags) & RowMajorBit) ? this->rows() : this->cols(); }
198 Index innerSize() const { return (int(Flags) & RowMajorBit) ? this->cols() : this->rows(); }
199
200 bool isRValue() const { return m_isRValue; }
201 Derived& markAsRValue() {
202 m_isRValue = true;
203 return derived();
204 }
205
206 SparseMatrixBase() : m_isRValue(false) { /* TODO: validate traits flags. */
207 }
208
209 template <typename OtherDerived>
210 Derived& operator=(const ReturnByValue<OtherDerived>& other);
211
212 template <typename OtherDerived>
213 inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other);
215 inline Derived& operator=(const Derived& other);
216
217 protected:
218 template <typename OtherDerived>
219 inline Derived& assign(const OtherDerived& other);
220
221 template <typename OtherDerived>
222 inline void assignGeneric(const OtherDerived& other);
223
224 public:
225#ifndef EIGEN_NO_IO
226 friend std::ostream& operator<<(std::ostream& s, const SparseMatrixBase& m) {
227 using Nested = typename Derived::Nested;
228 using NestedCleaned = internal::remove_all_t<Nested>;
230 EIGEN_IF_CONSTEXPR (Flags & RowMajorBit) {
231 Nested nm(m.derived());
232 internal::evaluator<NestedCleaned> thisEval(nm);
233
234 // compute global width
235 std::size_t width = 0;
236 {
237 std::ostringstream ss0;
238 ss0.copyfmt(s);
239 ss0 << Scalar(0);
240 width = ss0.str().size();
241 for (Index row = 0; row < nm.outerSize(); ++row) {
242 for (typename internal::evaluator<NestedCleaned>::InnerIterator it(thisEval, row); it; ++it) {
243 std::ostringstream ss;
244 ss.copyfmt(s);
245 ss << it.value();
246
247 const std::size_t potential_width = ss.str().size();
248 if (potential_width > width) width = potential_width;
250 }
251 }
252
253 for (Index row = 0; row < nm.outerSize(); ++row) {
254 Index col = 0;
255 for (typename internal::evaluator<NestedCleaned>::InnerIterator it(thisEval, row); it; ++it) {
256 for (; col < it.index(); ++col) {
257 s.width(width);
258 s << Scalar(0) << " ";
259 }
260 s.width(width);
261 s << it.value() << " ";
262 ++col;
263 }
264 for (; col < m.cols(); ++col) {
265 s.width(width);
266 s << Scalar(0) << " ";
267 }
268 s << std::endl;
269 }
270 } else {
271 Nested nm(m.derived());
272 internal::evaluator<NestedCleaned> thisEval(nm);
273 if (m.cols() == 1) {
274 // compute local width (single col)
275 std::size_t width = 0;
276 {
277 std::ostringstream ss0;
278 ss0.copyfmt(s);
279 ss0 << Scalar(0);
280 width = ss0.str().size();
281 for (typename internal::evaluator<NestedCleaned>::InnerIterator it(thisEval, 0); it; ++it) {
282 std::ostringstream ss;
283 ss.copyfmt(s);
284 ss << it.value();
285
286 const std::size_t potential_width = ss.str().size();
287 if (potential_width > width) width = potential_width;
288 }
289 }
290
291 Index row = 0;
292 for (typename internal::evaluator<NestedCleaned>::InnerIterator it(thisEval, 0); it; ++it) {
293 for (; row < it.index(); ++row) {
294 s.width(width);
295 s << Scalar(0) << std::endl;
296 }
297 s.width(width);
298 s << it.value() << std::endl;
299 ++row;
300 }
301 for (; row < m.rows(); ++row) {
302 s.width(width);
303 s << Scalar(0) << std::endl;
304 }
305 } else {
306 SparseMatrix<Scalar, RowMajorBit, StorageIndex> trans = m;
307 s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit, StorageIndex>>&>(trans);
308 }
309 }
310 return s;
311 }
312#endif
313
314 template <typename OtherDerived>
315 Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
316 template <typename OtherDerived>
317 Derived& operator-=(const SparseMatrixBase<OtherDerived>& other);
318
319 template <typename OtherDerived>
320 Derived& operator+=(const DiagonalBase<OtherDerived>& other);
321 template <typename OtherDerived>
322 Derived& operator-=(const DiagonalBase<OtherDerived>& other);
323
324 template <typename OtherDerived>
325 Derived& operator+=(const EigenBase<OtherDerived>& other);
326 template <typename OtherDerived>
327 Derived& operator-=(const EigenBase<OtherDerived>& other);
328
329 Derived& operator*=(const Scalar& other);
330 Derived& operator/=(const Scalar& other);
331
332 template <typename OtherDerived>
333 struct CwiseProductDenseReturnType {
334 using Type = CwiseBinaryOp<
335 internal::scalar_product_op<typename ScalarBinaryOpTraits<
336 typename internal::traits<Derived>::Scalar, typename internal::traits<OtherDerived>::Scalar>::ReturnType>,
337 const Derived, const OtherDerived>;
338 };
339
340 template <typename OtherDerived>
341 EIGEN_STRONG_INLINE const typename CwiseProductDenseReturnType<OtherDerived>::Type cwiseProduct(
342 const MatrixBase<OtherDerived>& other) const;
343
344 // sparse * diagonal
345 template <typename OtherDerived>
346 const Product<Derived, OtherDerived> operator*(const DiagonalBase<OtherDerived>& other) const {
348 }
349
350 // diagonal * sparse
351 template <typename OtherDerived>
352 friend const Product<OtherDerived, Derived> operator*(const DiagonalBase<OtherDerived>& lhs,
353 const SparseMatrixBase& rhs) {
354 return Product<OtherDerived, Derived>(lhs.derived(), rhs.derived());
356
357 // sparse * sparse
358 template <typename OtherDerived>
359 const Product<Derived, OtherDerived, AliasFreeProduct> operator*(const SparseMatrixBase<OtherDerived>& other) const;
360
361 // sparse * dense
362 template <typename OtherDerived>
363 const Product<Derived, OtherDerived> operator*(const MatrixBase<OtherDerived>& other) const {
364 return Product<Derived, OtherDerived>(derived(), other.derived());
365 }
366
367 // dense * sparse
368 template <typename OtherDerived>
369 friend const Product<OtherDerived, Derived> operator*(const MatrixBase<OtherDerived>& lhs,
370 const SparseMatrixBase& rhs) {
371 return Product<OtherDerived, Derived>(lhs.derived(), rhs.derived());
372 }
373
375 SparseSymmetricPermutationProduct<Derived, Upper | Lower> twistedBy(
377 return SparseSymmetricPermutationProduct<Derived, Upper | Lower>(derived(), perm);
378 }
379
380 template <typename OtherDerived>
381 Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);
382
383 template <int Mode>
384 inline const TriangularView<const Derived, Mode> triangularView() const;
385
386 template <unsigned int UpLo>
387 struct SelfAdjointViewReturnType {
389 };
390 template <unsigned int UpLo>
391 struct ConstSelfAdjointViewReturnType {
392 using Type = const SparseSelfAdjointView<const Derived, UpLo>;
393 };
394
395 template <unsigned int UpLo>
396 inline typename ConstSelfAdjointViewReturnType<UpLo>::Type selfadjointView() const;
397 template <unsigned int UpLo>
398 inline typename SelfAdjointViewReturnType<UpLo>::Type selfadjointView();
399
400 template <typename OtherDerived>
401 Scalar dot(const MatrixBase<OtherDerived>& other) const;
402 template <typename OtherDerived>
403 Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
404 RealScalar squaredNorm() const;
405 RealScalar norm() const;
406 RealScalar blueNorm() const;
407
408 TransposeReturnType transpose() { return TransposeReturnType(derived()); }
409 const ConstTransposeReturnType transpose() const { return ConstTransposeReturnType(derived()); }
410 const AdjointReturnType adjoint() const { return AdjointReturnType(transpose()); }
411
412 DenseMatrixType toDense() const { return DenseMatrixType(derived()); }
413
414 template <typename OtherDerived>
415 bool isApprox(const SparseMatrixBase<OtherDerived>& other,
416 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
417
418 template <typename OtherDerived>
419 bool isApprox(const MatrixBase<OtherDerived>& other,
420 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const {
421 return toDense().isApprox(other, prec);
422 }
423
429 inline const typename internal::eval<Derived>::type eval() const {
430 return typename internal::eval<Derived>::type(derived());
431 }
432
433 Scalar sum() const;
434
435 inline const SparseView<Derived> pruned(const Scalar& reference = Scalar(0),
436 const RealScalar& epsilon = NumTraits<Scalar>::dummy_precision()) const;
438 protected:
439 bool m_isRValue;
440
441 static inline StorageIndex convert_index(const Index idx) { return internal::convert_index<StorageIndex>(idx); }
442
443 private:
444 template <typename Dest>
445 void evalTo(Dest&) const;
446};
447
448} // end namespace Eigen
449
450#endif // EIGEN_SPARSEMATRIXBASE_H
Generic expression where a coefficient-wise binary operator is applied to two expressions.
Definition CwiseBinaryOp.h:80
Generic expression of a matrix where all coefficients are defined by a functor.
Definition CwiseNullaryOp.h:65
Generic expression where a coefficient-wise unary operator is applied to an expression.
Definition CwiseUnaryOp.h:55
Base class for diagonal matrices and expressions.
Definition DiagonalMatrix.h:34
const Derived & derived() const
Definition DiagonalMatrix.h:60
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:53
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:188
Permutation matrix.
Definition PermutationMatrix.h:346
Expression of the product of two arbitrary matrices or vectors.
Definition Product.h:203
Base class of any sparse matrices or sparse expressions.
Definition SparseMatrixBase.h:31
Index size() const
Definition SparseMatrixBase.h:187
Index innerSize() const
Definition SparseMatrixBase.h:198
Index rows() const
Definition SparseMatrixBase.h:182
typename NumTraits< Scalar >::Real RealScalar
Definition SparseMatrixBase.h:128
bool isVector() const
Definition SparseMatrixBase.h:192
Scalar value_type
Definition SparseMatrixBase.h:38
const Product< Derived, OtherDerived, AliasFreeProduct > operator*(const SparseMatrixBase< OtherDerived > &other) const
Definition SparseProduct.h:32
constexpr RowXpr row(Index i)
Definition SparseMatrixBase.h:1094
constexpr const CwiseBinaryOp< internal::scalar_product_op< Derived ::Scalar, OtherDerived ::Scalar >, const Derived, const OtherDerived > cwiseProduct(const Eigen::SparseMatrixBase< OtherDerived > &other) const
Definition SparseMatrixBase.h:25
typename internal::traits< BlockType >::StorageIndex StorageIndex
Definition SparseMatrixBase.h:45
Index outerSize() const
Definition SparseMatrixBase.h:195
const SparseView< Derived > pruned(const Scalar &reference=Scalar(0), const RealScalar &epsilon=NumTraits< Scalar >::dummy_precision()) const
Definition SparseView.h:219
Index cols() const
Definition SparseMatrixBase.h:184
SparseSymmetricPermutationProduct< Derived, Upper|Lower > twistedBy(const PermutationMatrix< Dynamic, Dynamic, StorageIndex > &perm) const
Definition SparseMatrixBase.h:375
const internal::eval< Derived >::type eval() const
Definition SparseMatrixBase.h:429
constexpr ColXpr col(Index i)
Definition SparseMatrixBase.h:1081
@ IsVectorAtCompileTime
Definition SparseMatrixBase.h:82
@ NumDimensions
Definition SparseMatrixBase.h:88
@ ColsAtCompileTime
Definition SparseMatrixBase.h:66
@ Flags
Definition SparseMatrixBase.h:95
@ RowsAtCompileTime
Definition SparseMatrixBase.h:60
@ SizeAtCompileTime
Definition SparseMatrixBase.h:72
A versatile sparse matrix representation.
Definition SparseMatrix.h:122
Pseudo expression to manipulate a triangular sparse matrix as a selfadjoint matrix.
Definition SparseSelfAdjointView.h:53
Expression of a dense or sparse matrix with zero or too small values removed.
Definition SparseView.h:46
Expression of the transpose of a matrix.
Definition Transpose.h:57
Expression of a triangular part in a matrix.
Definition TriangularMatrix.h:426
constexpr unsigned int DirectAccessBit
Definition Constants.h:160
constexpr unsigned int RowMajorBit
Definition Constants.h:71
Definition EigenBase.h:34
constexpr Derived & derived()
Definition EigenBase.h:50
Eigen::Index Index
The interface type of indices.
Definition EigenBase.h:44
Determines whether the given binary operation of two numeric types is allowed and what the scalar ret...
Definition XprHelper.h:1062