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