Path Tracer
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 namespace Eigen {
14 
26 template<typename Derived>
27 template<typename OtherDerived>
28 inline const Product<Derived,OtherDerived,AliasFreeProduct>
30 {
31  return Product<Derived,OtherDerived,AliasFreeProduct>(derived(), other.derived());
32 }
33 
34 namespace internal {
35 
36 // sparse * sparse
37 template<typename Lhs, typename Rhs, int ProductType>
38 struct generic_product_impl<Lhs, Rhs, SparseShape, SparseShape, ProductType>
39 {
40  template<typename Dest>
41  static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
42  {
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, typename enable_if<is_same<typename evaluator_traits<Dest>::Shape,DenseShape>::value,int*>::type* = 0)
49  {
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);
55  typename remove_all<RhsNested>::type, Dest>::run(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, typename enable_if<is_same<typename evaluator_traits<Dest>::Shape,DenseShape>::value,int*>::type* = 0)
61  {
62  addTo(dst, -lhs, rhs);
63  }
64 
65 protected:
66 
67  // sparse = sparse * sparse
68  template<typename Dest>
69  static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, SparseShape)
70  {
71  typedef typename nested_eval<Lhs,Dynamic>::type LhsNested;
72  typedef typename nested_eval<Rhs,Dynamic>::type RhsNested;
73  LhsNested lhsNested(lhs);
74  RhsNested rhsNested(rhs);
76  typename remove_all<RhsNested>::type, Dest>::run(lhsNested,rhsNested,dst);
77  }
78 
79  // dense = sparse * sparse
80  template<typename Dest>
81  static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, DenseShape)
82  {
83  dst.setZero();
84  addTo(dst, lhs, rhs);
85  }
86 };
87 
88 // sparse * sparse-triangular
89 template<typename Lhs, typename Rhs, int ProductType>
91  : public generic_product_impl<Lhs, Rhs, SparseShape, SparseShape, ProductType>
92 {};
93 
94 // sparse-triangular * sparse
95 template<typename Lhs, typename Rhs, int ProductType>
97  : public generic_product_impl<Lhs, Rhs, SparseShape, SparseShape, ProductType>
98 {};
99 
100 // dense = sparse-product (can be sparse*sparse, sparse*perm, etc.)
101 template< typename DstXprType, typename Lhs, typename Rhs>
102 struct Assignment<DstXprType, Product<Lhs,Rhs,AliasFreeProduct>, internal::assign_op<typename DstXprType::Scalar,typename Product<Lhs,Rhs,AliasFreeProduct>::Scalar>, Sparse2Dense>
103 {
105  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &)
106  {
107  Index dstRows = src.rows();
108  Index dstCols = src.cols();
109  if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
110  dst.resize(dstRows, dstCols);
111 
112  generic_product_impl<Lhs, Rhs>::evalTo(dst,src.lhs(),src.rhs());
113  }
114 };
115 
116 // dense += sparse-product (can be sparse*sparse, sparse*perm, etc.)
117 template< typename DstXprType, typename Lhs, typename Rhs>
118 struct Assignment<DstXprType, Product<Lhs,Rhs,AliasFreeProduct>, internal::add_assign_op<typename DstXprType::Scalar,typename Product<Lhs,Rhs,AliasFreeProduct>::Scalar>, Sparse2Dense>
119 {
121  static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &)
122  {
123  generic_product_impl<Lhs, Rhs>::addTo(dst,src.lhs(),src.rhs());
124  }
125 };
126 
127 // dense -= sparse-product (can be sparse*sparse, sparse*perm, etc.)
128 template< typename DstXprType, typename Lhs, typename Rhs>
129 struct Assignment<DstXprType, Product<Lhs,Rhs,AliasFreeProduct>, internal::sub_assign_op<typename DstXprType::Scalar,typename Product<Lhs,Rhs,AliasFreeProduct>::Scalar>, Sparse2Dense>
130 {
132  static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &)
133  {
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 {
143  typedef typename XprType::PlainObject PlainObject;
145 
146  explicit unary_evaluator(const XprType& xpr)
147  : m_result(xpr.rows(), xpr.cols())
148  {
149  using std::abs;
150  ::new (static_cast<Base*>(this)) Base(m_result);
151  typedef typename nested_eval<Lhs,Dynamic>::type LhsNested;
152  typedef typename nested_eval<Rhs,Dynamic>::type RhsNested;
153  LhsNested lhsNested(xpr.nestedExpression().lhs());
154  RhsNested rhsNested(xpr.nestedExpression().rhs());
155 
157  typename remove_all<RhsNested>::type, PlainObject>::run(lhsNested,rhsNested,m_result,
158  abs(xpr.reference())*xpr.epsilon());
159  }
160 
161 protected:
162  PlainObject m_result;
163 };
164 
165 } // end namespace internal
166 
167 // sparse matrix = sparse-product (can be sparse*sparse, sparse*perm, etc.)
168 template<typename Scalar, int _Options, typename _StorageIndex>
169 template<typename Lhs, typename Rhs>
171 {
172  // std::cout << "in Assignment : " << DstOptions << "\n";
173  SparseMatrix dst(src.rows(),src.cols());
174  internal::generic_product_impl<Lhs, Rhs>::evalTo(dst,src.lhs(),src.rhs());
175  this->swap(dst);
176  return *this;
177 }
178 
179 } // end namespace Eigen
180 
181 #endif // EIGEN_SPARSEPRODUCT_H
Eigen
Namespace containing all symbols from the Eigen library.
Definition: LDLT.h:16
Eigen::SparseMatrix
A versatible sparse matrix representation.
Definition: SparseMatrix.h:98
Eigen::DenseShape
Definition: Constants.h:524
Eigen::internal::sparse_sparse_product_with_pruning_selector
Definition: SparseSparseProductWithPruning.h:84
Eigen::internal::SparseTriangularShape
Definition: SparseUtil.h:137
Eigen::internal::generic_product_impl
Definition: ProductEvaluators.h:86
Eigen::SparseView::nestedExpression
const internal::remove_all< MatrixTypeNested >::type & nestedExpression() const
Definition: SparseView.h:66
Eigen::internal::true_type
Definition: Meta.h:63
Eigen::internal::sparse_sparse_to_dense_product_selector
Definition: ConservativeSparseSparseProduct.h:304
Eigen::internal::Sparse2Dense
Definition: SparseAssign.h:62
Eigen::SparseShape
Definition: Constants.h:533
Eigen::internal::IteratorBased
Definition: Constants.h:541
Eigen::Product
Expression of the product of two arbitrary matrices or vectors.
Definition: Product.h:75
Eigen::internal::evaluator
Definition: CoreEvaluators.h:91
Eigen::internal::conservative_sparse_sparse_product_selector
Definition: ConservativeSparseSparseProduct.h:131
Eigen::internal::assign_op
Definition: AssignmentFunctors.h:21
Eigen::internal::sub_assign_op
Definition: AssignmentFunctors.h:67
Eigen::internal::unary_evaluator
Definition: CoreEvaluators.h:65
Eigen::internal::Assignment
Definition: AssignEvaluator.h:814
Eigen::SparseView
Expression of a dense or sparse matrix with zero or too small values removed.
Definition: SparseView.h:46
Eigen::SparseMatrixBase
Base class of any sparse matrices or sparse expressions.
Definition: SparseMatrixBase.h:28
Eigen::internal::is_same
Definition: Meta.h:115
Eigen::internal::add_assign_op
Definition: AssignmentFunctors.h:46
Eigen::internal::enable_if
Definition: Meta.h:234
Eigen::Index
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:42