Eigen  3.4.90 (git rev a4098ac676528a83cfb73d4d26ce1b42ec05f47c)
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#include "./InternalHeaderCheck.h"
14
15namespace Eigen {
16
28template<typename Derived>
29template<typename OtherDerived>
30inline const Product<Derived,OtherDerived,AliasFreeProduct>
32{
34}
35
36namespace internal {
37
38// sparse * sparse
39template<typename Lhs, typename Rhs, int ProductType>
40struct 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, typename enable_if<is_same<typename evaluator_traits<Dest>::Shape,DenseShape>::value,int*>::type* = 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<typename remove_all<LhsNested>::type,
57 typename remove_all<RhsNested>::type, 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, typename enable_if<is_same<typename evaluator_traits<Dest>::Shape,DenseShape>::value,int*>::type* = 0)
63 {
64 addTo(dst, -lhs, rhs);
65 }
66
67protected:
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<typename remove_all<LhsNested>::type,
78 typename remove_all<RhsNested>::type, 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
91template<typename Lhs, typename Rhs, int ProductType>
92struct generic_product_impl<Lhs, Rhs, SparseShape, SparseTriangularShape, ProductType>
93 : public generic_product_impl<Lhs, Rhs, SparseShape, SparseShape, ProductType>
94{};
95
96// sparse-triangular * sparse
97template<typename Lhs, typename Rhs, int ProductType>
98struct 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.)
103template< typename DstXprType, typename Lhs, typename Rhs>
104struct 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.)
119template< typename DstXprType, typename Lhs, typename Rhs>
120struct 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.)
130template< typename DstXprType, typename Lhs, typename Rhs>
131struct 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
140template<typename Lhs, typename Rhs, int Options>
141struct 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 ::new (static_cast<Base*>(this)) Base(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<typename remove_all<LhsNested>::type,
159 typename remove_all<RhsNested>::type, PlainObject>::run(lhsNested,rhsNested,m_result,
160 abs(xpr.reference())*xpr.epsilon());
161 }
162
163protected:
164 PlainObject m_result;
165};
166
167} // end namespace internal
168
169// sparse matrix = sparse-product (can be sparse*sparse, sparse*perm, etc.)
170template<typename Scalar, int Options_, typename StorageIndex_>
171template<typename Lhs, typename Rhs>
172SparseMatrix<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
Expression of the product of two arbitrary matrices or vectors.
Definition: Product.h:77
Base class of any sparse matrices or sparse expressions.
Definition: SparseMatrixBase.h:30
Namespace containing all symbols from the Eigen library.
Definition: B01_Experimental.dox:1
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:59
const int Dynamic
Definition: Constants.h:24
Derived & derived()
Definition: EigenBase.h:48