$darkmode
Eigen  5.0.1-dev
SparseProduct.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-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 
10 #ifndef EIGEN_SPARSEPRODUCT_H
11 #define EIGEN_SPARSEPRODUCT_H
12 
13 // IWYU pragma: private
14 #include "./InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
29 template <typename Derived>
30 template <typename OtherDerived>
32  const SparseMatrixBase<OtherDerived>& other) const {
34 }
35 
36 namespace internal {
37 
38 // sparse * sparse
39 template <typename Lhs, typename Rhs, int ProductType>
40 struct generic_product_impl<Lhs, Rhs, SparseShape, SparseShape, ProductType> {
41  template <typename Dest>
42  static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs) {
43  evalTo(dst, lhs, rhs, typename evaluator_traits<Dest>::Shape());
44  }
45 
46  // dense += sparse * sparse
47  template <typename Dest, typename ActualLhs>
48  static void addTo(Dest& dst, const ActualLhs& lhs, const Rhs& rhs,
49  std::enable_if_t<is_same<typename evaluator_traits<Dest>::Shape, DenseShape>::value, int*>* = 0) {
50  typedef typename nested_eval<ActualLhs, Dynamic>::type LhsNested;
51  typedef typename nested_eval<Rhs, Dynamic>::type RhsNested;
52  LhsNested lhsNested(lhs);
53  RhsNested rhsNested(rhs);
54  internal::sparse_sparse_to_dense_product_selector<remove_all_t<LhsNested>, remove_all_t<RhsNested>, Dest>::run(
55  lhsNested, rhsNested, dst);
56  }
57 
58  // dense -= sparse * sparse
59  template <typename Dest>
60  static void subTo(Dest& dst, const Lhs& lhs, const Rhs& rhs,
61  std::enable_if_t<is_same<typename evaluator_traits<Dest>::Shape, DenseShape>::value, int*>* = 0) {
62  addTo(dst, -lhs, rhs);
63  }
64 
65  protected:
66  // sparse = sparse * sparse
67  template <typename Dest>
68  static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, SparseShape) {
69  typedef typename nested_eval<Lhs, Dynamic>::type LhsNested;
70  typedef typename nested_eval<Rhs, Dynamic>::type RhsNested;
71  LhsNested lhsNested(lhs);
72  RhsNested rhsNested(rhs);
73  internal::conservative_sparse_sparse_product_selector<remove_all_t<LhsNested>, remove_all_t<RhsNested>, Dest>::run(
74  lhsNested, rhsNested, dst);
75  }
76 
77  // dense = sparse * sparse
78  template <typename Dest>
79  static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, DenseShape) {
80  dst.setZero();
81  addTo(dst, lhs, rhs);
82  }
83 };
84 
85 // sparse * sparse-triangular
86 template <typename Lhs, typename Rhs, int ProductType>
87 struct generic_product_impl<Lhs, Rhs, SparseShape, SparseTriangularShape, ProductType>
88  : public generic_product_impl<Lhs, Rhs, SparseShape, SparseShape, ProductType> {};
89 
90 // sparse-triangular * sparse
91 template <typename Lhs, typename Rhs, int ProductType>
92 struct generic_product_impl<Lhs, Rhs, SparseTriangularShape, SparseShape, ProductType>
93  : public generic_product_impl<Lhs, Rhs, SparseShape, SparseShape, ProductType> {};
94 
95 // dense = sparse-product (can be sparse*sparse, sparse*perm, etc.)
96 template <typename DstXprType, typename Lhs, typename Rhs>
97 struct Assignment<
98  DstXprType, Product<Lhs, Rhs, AliasFreeProduct>,
99  internal::assign_op<typename DstXprType::Scalar, typename Product<Lhs, Rhs, AliasFreeProduct>::Scalar>,
100  Sparse2Dense> {
101  typedef Product<Lhs, Rhs, AliasFreeProduct> SrcXprType;
102  static void run(DstXprType& dst, const SrcXprType& src,
103  const internal::assign_op<typename DstXprType::Scalar, typename SrcXprType::Scalar>&) {
104  Index dstRows = src.rows();
105  Index dstCols = src.cols();
106  if ((dst.rows() != dstRows) || (dst.cols() != dstCols)) dst.resize(dstRows, dstCols);
107 
108  generic_product_impl<Lhs, Rhs>::evalTo(dst, src.lhs(), src.rhs());
109  }
110 };
111 
112 // dense += sparse-product (can be sparse*sparse, sparse*perm, etc.)
113 template <typename DstXprType, typename Lhs, typename Rhs>
114 struct Assignment<
115  DstXprType, Product<Lhs, Rhs, AliasFreeProduct>,
116  internal::add_assign_op<typename DstXprType::Scalar, typename Product<Lhs, Rhs, AliasFreeProduct>::Scalar>,
117  Sparse2Dense> {
118  typedef Product<Lhs, Rhs, AliasFreeProduct> SrcXprType;
119  static void run(DstXprType& dst, const SrcXprType& src,
120  const internal::add_assign_op<typename DstXprType::Scalar, typename SrcXprType::Scalar>&) {
121  generic_product_impl<Lhs, Rhs>::addTo(dst, src.lhs(), src.rhs());
122  }
123 };
124 
125 // dense -= sparse-product (can be sparse*sparse, sparse*perm, etc.)
126 template <typename DstXprType, typename Lhs, typename Rhs>
127 struct Assignment<
128  DstXprType, Product<Lhs, Rhs, AliasFreeProduct>,
129  internal::sub_assign_op<typename DstXprType::Scalar, typename Product<Lhs, Rhs, AliasFreeProduct>::Scalar>,
130  Sparse2Dense> {
131  typedef Product<Lhs, Rhs, AliasFreeProduct> SrcXprType;
132  static void run(DstXprType& dst, const SrcXprType& src,
133  const internal::sub_assign_op<typename DstXprType::Scalar, typename SrcXprType::Scalar>&) {
134  generic_product_impl<Lhs, Rhs>::subTo(dst, src.lhs(), src.rhs());
135  }
136 };
137 
138 template <typename Lhs, typename Rhs, int Options>
139 struct unary_evaluator<SparseView<Product<Lhs, Rhs, Options> >, IteratorBased>
140  : public evaluator<typename Product<Lhs, Rhs, DefaultProduct>::PlainObject> {
141  typedef SparseView<Product<Lhs, Rhs, Options> > XprType;
142  typedef typename XprType::PlainObject PlainObject;
143  typedef evaluator<PlainObject> Base;
144 
145  explicit unary_evaluator(const XprType& xpr) : m_result(xpr.rows(), xpr.cols()) {
146  using std::abs;
147  internal::construct_at<Base>(this, m_result);
148  typedef typename nested_eval<Lhs, Dynamic>::type LhsNested;
149  typedef typename nested_eval<Rhs, Dynamic>::type RhsNested;
150  LhsNested lhsNested(xpr.nestedExpression().lhs());
151  RhsNested rhsNested(xpr.nestedExpression().rhs());
152 
153  internal::sparse_sparse_product_with_pruning_selector<remove_all_t<LhsNested>, remove_all_t<RhsNested>,
154  PlainObject>::run(lhsNested, rhsNested, m_result,
155  abs(xpr.reference()) * xpr.epsilon());
156  }
157 
158  protected:
159  PlainObject m_result;
160 };
161 
162 } // end namespace internal
163 
164 // sparse matrix = sparse-product (can be sparse*sparse, sparse*perm, etc.)
165 template <typename Scalar, int Options_, typename StorageIndex_>
166 template <typename Lhs, typename Rhs>
167 SparseMatrix<Scalar, Options_, StorageIndex_>& SparseMatrix<Scalar, Options_, StorageIndex_>::operator=(
168  const Product<Lhs, Rhs, AliasFreeProduct>& src) {
169  // std::cout << "in Assignment : " << DstOptions << "\n";
170  SparseMatrix dst(src.rows(), src.cols());
171  internal::generic_product_impl<Lhs, Rhs>::evalTo(dst, src.lhs(), src.rhs());
172  this->swap(dst);
173  return *this;
174 }
175 
176 } // end namespace Eigen
177 
178 #endif // EIGEN_SPARSEPRODUCT_H
Expression of the product of two arbitrary matrices or vectors.
Definition: Product.h:198
Namespace containing all symbols from the Eigen library.
Definition: B01_Experimental.dox:1
Base class of any sparse matrices or sparse expressions.
Definition: ForwardDeclarations.h:481
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
std::enable_if_t< std::is_base_of< DenseBase< std::decay_t< DerivedA > >, std::decay_t< DerivedA > >::value &&std::is_base_of< DenseBase< std::decay_t< DerivedB > >, std::decay_t< DerivedB > >::value, void > swap(DerivedA &&a, DerivedB &&b)
Definition: DenseBase.h:667
constexpr Derived & derived()
Definition: EigenBase.h:49
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)