$darkmode
Eigen  5.0.1-dev
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 
16 namespace Eigen {
17 
29 template <typename Derived>
30 class SparseMatrixBase : public EigenBase<Derived> {
31  public:
32  typedef typename internal::traits<Derived>::Scalar Scalar;
33 
37  typedef Scalar value_type;
38 
39  typedef typename internal::packet_traits<Scalar>::type PacketScalar;
40  typedef typename internal::traits<Derived>::StorageKind StorageKind;
41 
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 
50 
53 
54  template <typename OtherDerived>
55  Derived& operator=(const EigenBase<OtherDerived>& other);
56 
57  enum {
58 
59  RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
65  ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
71  SizeAtCompileTime = (internal::size_of_xpr_at_compile_time<Derived>::ret),
76  MaxRowsAtCompileTime = RowsAtCompileTime,
77  MaxColsAtCompileTime = ColsAtCompileTime,
78 
79  MaxSizeAtCompileTime = internal::size_at_compile_time(MaxRowsAtCompileTime, MaxColsAtCompileTime),
80 
87  NumDimensions = int(MaxSizeAtCompileTime) == 1 ? 0
88  : bool(IsVectorAtCompileTime) ? 1
89  : 2,
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;
118  // FIXME storage order do not match evaluator storage order
128 
129 #ifndef EIGEN_PARSED_BY_DOXYGEN
130 
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
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) {
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();
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>
347  const Product<Derived, OtherDerived> operator*(const DiagonalBase<OtherDerived>& other) const {
349  }
350 
351  // diagonal * sparse
352  template <typename OtherDerived>
353  friend const Product<OtherDerived, Derived> operator*(const DiagonalBase<OtherDerived>& lhs,
354  const SparseMatrixBase& rhs) {
355  return Product<OtherDerived, Derived>(lhs.derived(), rhs.derived());
356  }
357 
358  // sparse * sparse
359  template <typename OtherDerived>
361 
362  // sparse * dense
363  template <typename OtherDerived>
364  const Product<Derived, OtherDerived> operator*(const MatrixBase<OtherDerived>& other) const {
366  }
367 
368  // dense * sparse
369  template <typename OtherDerived>
370  friend const Product<OtherDerived, Derived> operator*(const MatrixBase<OtherDerived>& lhs,
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 
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
const Derived & derived() const
Definition: DiagonalMatrix.h:57
Generic expression of a matrix where all coefficients are defined by a functor.
Definition: CwiseNullaryOp.h:63
SparseSymmetricPermutationProduct< Derived, Upper|Lower > twistedBy(const PermutationMatrix< Dynamic, Dynamic, StorageIndex > &perm) const
Definition: SparseMatrixBase.h:376
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
Index innerSize() const
Definition: SparseMatrixBase.h:198
Index cols() const
Definition: SparseMatrixBase.h:184
constexpr Derived & derived()
Definition: EigenBase.h:49
Expression of the product of two arbitrary matrices or vectors.
Definition: Product.h:198
A versatible sparse matrix representation.
Definition: SparseMatrix.h:121
Expression of the transpose of a matrix.
Definition: Transpose.h:56
const unsigned int DirectAccessBit
Definition: Constants.h:159
RowXpr row(Index i)
Definition: SparseMatrixBase.h:1085
Namespace containing all symbols from the Eigen library.
Definition: B01_Experimental.dox:1
Pseudo expression to manipulate a triangular sparse matrix as a selfadjoint matrix.
Definition: SparseSelfAdjointView.h:52
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:232
Index outerSize() const
Definition: SparseMatrixBase.h:195
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:43
const unsigned int RowMajorBit
Definition: Constants.h:70
bool isVector() const
Definition: SparseMatrixBase.h:192
Definition: EigenBase.h:33
Index size() const
Definition: SparseMatrixBase.h:187
const SparseView< Derived > pruned(const Scalar &reference=Scalar(0), const RealScalar &epsilon=NumTraits< Scalar >::dummy_precision()) const
Definition: SparseView.h:219
internal::traits< Derived >::StorageIndex StorageIndex
Definition: SparseMatrixBase.h:44
Generic expression where a coefficient-wise binary operator is applied to two expressions.
Definition: CwiseBinaryOp.h:75
Index rows() const
Definition: SparseMatrixBase.h:182
Base class of any sparse matrices or sparse expressions.
Definition: ForwardDeclarations.h:481
Definition: SparseMatrixBase.h:59
Definition: SparseMatrixBase.h:71
Definition: SparseMatrixBase.h:65
Definition: SparseMatrixBase.h:87
Expression of a dense or sparse matrix with zero or too small values removed.
Definition: ForwardDeclarations.h:177
Scalar value_type
Definition: SparseMatrixBase.h:37
constexpr Derived & derived()
Definition: EigenBase.h:49
Definition: SparseMatrixBase.h:94
Base class for diagonal matrices and expressions.
Definition: DiagonalMatrix.h:33
Expression of a triangular part in a matrix.
Definition: TriangularMatrix.h:166
Determines whether the given binary operation of two numeric types is allowed and what the scalar ret...
Definition: XprHelper.h:1042
const internal::eval< Derived >::type eval() const
Definition: SparseMatrixBase.h:430
ColXpr col(Index i)
Definition: SparseMatrixBase.h:1072
Generic expression where a coefficient-wise unary operator is applied to an expression.
Definition: CwiseUnaryOp.h:52
NumTraits< Scalar >::Real RealScalar
Definition: SparseMatrixBase.h:127
Definition: SparseMatrixBase.h:81
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:52