Eigen  5.0.1-dev+60122df6
 
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
10#ifndef EIGEN_SPARSEMATRIXBASE_H
11#define EIGEN_SPARSEMATRIXBASE_H
12
13// IWYU pragma: private
14#include "./InternalHeaderCheck.h"
15
16namespace Eigen {
17
23 *
24 * \tparam Derived is the derived type, e.g. a sparse matrix type, or an expression, etc.
25 *
26 * This class can be extended with the help of the plugin mechanism described on the page
27 * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_SPARSEMATRIXBASE_PLUGIN.
28 */
29template <typename Derived>
30class SparseMatrixBase : public EigenBase<Derived> {
31 public:
32 typedef typename internal::traits<Derived>::Scalar Scalar;
33
34 /** The numeric type of the expression' coefficients, e.g. float, double, int or std::complex<float>, etc.
35 *
36 * It is an alias for the Scalar type */
37 typedef Scalar value_type;
38
39 typedef typename internal::packet_traits<Scalar>::type PacketScalar;
40 typedef typename internal::traits<Derived>::StorageKind StorageKind;
42 /** The integer type used to \b store indices within a SparseMatrix.
43 * For a \c SparseMatrix<Scalar,Options,IndexType> it an alias of the third template parameter \c IndexType. */
44 typedef typename internal::traits<Derived>::StorageIndex StorageIndex;
45
46 typedef typename internal::add_const_on_value_type_if_arithmetic<typename internal::packet_traits<Scalar>::type>::type
47 PacketReturnType;
48
49 typedef SparseMatrixBase StorageBaseType;
50
51 typedef Matrix<StorageIndex, Dynamic, 1> IndexVector;
52 typedef Matrix<Scalar, Dynamic, 1> ScalarVector;
53
54 template <typename OtherDerived>
55 Derived& operator=(const EigenBase<OtherDerived>& other);
56
57 enum {
58
59 RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
62
64
65 ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
70
71 SizeAtCompileTime = (internal::size_of_xpr_at_compile_time<Derived>::ret),
75
76 MaxRowsAtCompileTime = RowsAtCompileTime,
77 MaxColsAtCompileTime = ColsAtCompileTime,
78
79 MaxSizeAtCompileTime = internal::size_at_compile_time(MaxRowsAtCompileTime, MaxColsAtCompileTime),
80
82 /**< This is set to true if either the number of rows or the number of
83 * columns is known at compile-time to be equal to 1. Indeed, in that case,
84 * we are dealing with a column-vector (if there is only one column) or with
85 * a row-vector (if there is only one row). */
87 NumDimensions = int(MaxSizeAtCompileTime) == 1 ? 0
88 : bool(IsVectorAtCompileTime) ? 1
89 : 2,
91 * and 2 for matrices.
92 */
94 Flags = internal::traits<Derived>::Flags,
99 IsRowMajor = Flags & RowMajorBit ? 1 : 0,
100
101 InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
102 : int(IsRowMajor) ? int(ColsAtCompileTime)
103 : int(RowsAtCompileTime),
105#ifndef EIGEN_PARSED_BY_DOXYGEN
106 HasDirectAccess_ = (int(Flags) & DirectAccessBit) ? 1 : 0 // workaround sunCC
107#endif
108 };
109
111 typedef std::conditional_t<NumTraits<Scalar>::IsComplex,
114 AdjointReturnType;
115 typedef Transpose<Derived> TransposeReturnType;
116 typedef Transpose<const Derived> ConstTransposeReturnType;
118 // FIXME storage order do not match evaluator storage order
122 * (e.g. int, float or double) then \a RealScalar is just the same as \a Scalar. If
123 * \a Scalar is \a std::complex<T> then RealScalar is \a T.
124 *
125 * \sa class NumTraits
126 */
127 typedef typename NumTraits<Scalar>::Real RealScalar;
128
129#ifndef EIGEN_PARSED_BY_DOXYGEN
132 typedef std::conditional_t<HasDirectAccess_, const Scalar&, Scalar> CoeffReturnType;
133
140 typedef Matrix<Scalar, internal::max_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime),
141 internal::max_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime)>
142 SquareMatrixType;
143
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 typedef EigenBase<Derived> Base;
149
150#endif // not EIGEN_PARSED_BY_DOXYGEN
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; }
195 Index outerSize() const { return (int(Flags) & RowMajorBit) ? this->rows() : this->cols(); }
198 Index innerSize() const { return (int(Flags) & RowMajorBit) ? this->cols() : this->rows(); }
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 check 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);
214
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);
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 = typename internal::remove_all<Nested>::type;
229
230 if (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;
249 }
250 }
251 }
252
253 for (Index row = 0; row < nm.outerSize(); ++row) {
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();
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);
329 Derived& operator*=(const Scalar& other);
330 Derived& operator/=(const Scalar& other);
331
332 template <typename OtherDerived>
333 struct CwiseProductDenseReturnType {
334 typedef 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 Type;
339 };
340
341 template <typename OtherDerived>
342 EIGEN_STRONG_INLINE const typename CwiseProductDenseReturnType<OtherDerived>::Type cwiseProduct(
343 const MatrixBase<OtherDerived>& other) const;
344
345 // sparse * diagonal
346 template <typename OtherDerived>
349 }
350
351 // diagonal * sparse
352 template <typename OtherDerived>
353 friend const Product<OtherDerived, Derived> operator*(const DiagonalBase<OtherDerived>& lhs,
354 const SparseMatrixBase& rhs) {
356 }
357
358 // sparse * sparse
359 template <typename OtherDerived>
360 const Product<Derived, OtherDerived, AliasFreeProduct> operator*(const SparseMatrixBase<OtherDerived>& other) const;
361
362 // sparse * dense
363 template <typename OtherDerived>
364 const Product<Derived, OtherDerived> operator*(const MatrixBase<OtherDerived>& other) const {
365 return Product<Derived, OtherDerived>(derived(), other.derived());
366 }
367
368 // dense * sparse
369 template <typename OtherDerived>
371 const SparseMatrixBase& rhs) {
372 return Product<OtherDerived, Derived>(lhs.derived(), rhs.derived());
373 }
374
376 SparseSymmetricPermutationProduct<Derived, Upper | Lower> twistedBy(
378 return SparseSymmetricPermutationProduct<Derived, Upper | Lower>(derived(), perm);
379 }
380
381 template <typename OtherDerived>
382 Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);
383
384 template <int Mode>
385 inline const TriangularView<const Derived, Mode> triangularView() const;
386
387 template <unsigned int UpLo>
388 struct SelfAdjointViewReturnType {
390 };
391 template <unsigned int UpLo>
392 struct ConstSelfAdjointViewReturnType {
394 };
395
396 template <unsigned int UpLo>
397 inline typename ConstSelfAdjointViewReturnType<UpLo>::Type selfadjointView() const;
398 template <unsigned int UpLo>
399 inline typename SelfAdjointViewReturnType<UpLo>::Type selfadjointView();
400
401 template <typename OtherDerived>
402 Scalar dot(const MatrixBase<OtherDerived>& other) const;
403 template <typename OtherDerived>
404 Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
405 RealScalar squaredNorm() const;
406 RealScalar norm() const;
407 RealScalar blueNorm() const;
408
409 TransposeReturnType transpose() { return TransposeReturnType(derived()); }
410 const ConstTransposeReturnType transpose() const { return ConstTransposeReturnType(derived()); }
411 const AdjointReturnType adjoint() const { return AdjointReturnType(transpose()); }
412
413 DenseMatrixType toDense() const { return DenseMatrixType(derived()); }
414
415 template <typename OtherDerived>
416 bool isApprox(const SparseMatrixBase<OtherDerived>& other,
417 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
418
419 template <typename OtherDerived>
420 bool isApprox(const MatrixBase<OtherDerived>& other,
421 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const {
422 return toDense().isApprox(other, prec);
423 }
424
427 * Notice that in the case of a plain matrix or vector (not an expression) this function just returns
428 * a const reference, in order to avoid a useless copy.
429 */
430 inline const typename internal::eval<Derived>::type eval() const {
431 return typename internal::eval<Derived>::type(derived());
432 }
434 Scalar sum() const;
435
436 inline const SparseView<Derived> pruned(const Scalar& reference = Scalar(0),
437 const RealScalar& epsilon = NumTraits<Scalar>::dummy_precision()) const;
438
439 protected:
440 bool m_isRValue;
441
442 static inline StorageIndex convert_index(const Index idx) { return internal::convert_index<StorageIndex>(idx); }
443
444 private:
445 template <typename Dest>
446 void evalTo(Dest&) const;
447};
448
449} // end namespace Eigen
450
451#endif // EIGEN_SPARSEMATRIXBASE_H
Generic expression where a coefficient-wise binary operator is applied to two expressions.
Definition CwiseBinaryOp.h:79
Generic expression of a matrix where all coefficients are defined by a functor.
Definition CwiseNullaryOp.h:64
Generic expression where a coefficient-wise unary operator is applied to an expression.
Definition CwiseUnaryOp.h:53
Base class for diagonal matrices and expressions.
Definition DiagonalMatrix.h:33
const Derived & derived() const
Definition DiagonalMatrix.h:57
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:52
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:186
Permutation matrix.
Definition PermutationMatrix.h:283
Base class of any sparse matrices or sparse expressions.
Definition SparseMatrixBase.h:30
internal::traits< BlockType >::StorageIndex StorageIndex
Definition SparseMatrixBase.h:44
Index size() const
Definition SparseMatrixBase.h:187
Index innerSize() const
Definition SparseMatrixBase.h:198
Index rows() const
Definition SparseMatrixBase.h:182
bool isVector() const
Definition SparseMatrixBase.h:192
RowXpr row(Index i)
Definition SparseMatrixBase.h:1085
const Product< Derived, OtherDerived, AliasFreeProduct > operator*(const SparseMatrixBase< OtherDerived > &other) const
Definition SparseProduct.h:31
const CwiseBinaryOp< internal::scalar_product_op< Derived ::Scalar, OtherDerived ::Scalar >, const Derived, const OtherDerived > cwiseProduct(const Eigen::SparseMatrixBase< OtherDerived > &other) const
Definition SparseMatrixBase.h:23
NumTraits< Scalar >::Real RealScalar
Definition SparseMatrixBase.h:127
Scalar value_type
Definition SparseMatrixBase.h:37
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:376
ColXpr col(Index i)
Definition SparseMatrixBase.h:1072
const internal::eval< Derived >::type eval() const
Definition SparseMatrixBase.h:430
@ IsVectorAtCompileTime
Definition SparseMatrixBase.h:81
@ NumDimensions
Definition SparseMatrixBase.h:87
@ ColsAtCompileTime
Definition SparseMatrixBase.h:65
@ Flags
Definition SparseMatrixBase.h:94
@ RowsAtCompileTime
Definition SparseMatrixBase.h:59
@ SizeAtCompileTime
Definition SparseMatrixBase.h:71
A versatible sparse matrix representation.
Definition SparseMatrix.h:121
Pseudo expression to manipulate a triangular sparse matrix as a selfadjoint matrix.
Definition SparseSelfAdjointView.h:52
Expression of a dense or sparse matrix with zero or too small values removed.
Definition SparseView.h:45
Expression of the transpose of a matrix.
Definition Transpose.h:56
Expression of a triangular part in a matrix.
Definition TriangularMatrix.h:167
const unsigned int DirectAccessBit
Definition Constants.h:159
const unsigned int RowMajorBit
Definition Constants.h:70
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
const Product< MatrixDerived, PermutationDerived, DefaultProduct > operator*(const MatrixBase< MatrixDerived > &matrix, const PermutationBase< PermutationDerived > &permutation)
Definition PermutationMatrix.h:474
Definition EigenBase.h:33
constexpr Derived & derived()
Definition EigenBase.h:49
Eigen::Index Index
The interface type of indices.
Definition EigenBase.h:43
Determines whether the given binary operation of two numeric types is allowed and what the scalar ret...
Definition XprHelper.h:1047