TR-mbed 1.0
Loading...
Searching...
No Matches
ConservativeSparseSparseProduct.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_CONSERVATIVESPARSESPARSEPRODUCT_H
11#define EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H
12
13namespace Eigen {
14
15namespace internal {
16
17template<typename Lhs, typename Rhs, typename ResultType>
18static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res, bool sortedInsertion = false)
19{
20 typedef typename remove_all<Lhs>::type::Scalar LhsScalar;
21 typedef typename remove_all<Rhs>::type::Scalar RhsScalar;
22 typedef typename remove_all<ResultType>::type::Scalar ResScalar;
23
24 // make sure to call innerSize/outerSize since we fake the storage order.
25 Index rows = lhs.innerSize();
26 Index cols = rhs.outerSize();
27 eigen_assert(lhs.outerSize() == rhs.innerSize());
28
32
33 std::memset(mask,0,sizeof(bool)*rows);
34
35 evaluator<Lhs> lhsEval(lhs);
36 evaluator<Rhs> rhsEval(rhs);
37
38 // estimate the number of non zero entries
39 // given a rhs column containing Y non zeros, we assume that the respective Y columns
40 // of the lhs differs in average of one non zeros, thus the number of non zeros for
41 // the product of a rhs column with the lhs is X+Y where X is the average number of non zero
42 // per column of the lhs.
43 // Therefore, we have nnz(lhs*rhs) = nnz(lhs) + nnz(rhs)
44 Index estimated_nnz_prod = lhsEval.nonZerosEstimate() + rhsEval.nonZerosEstimate();
45
46 res.setZero();
47 res.reserve(Index(estimated_nnz_prod));
48 // we compute each column of the result, one after the other
49 for (Index j=0; j<cols; ++j)
50 {
51
52 res.startVec(j);
53 Index nnz = 0;
54 for (typename evaluator<Rhs>::InnerIterator rhsIt(rhsEval, j); rhsIt; ++rhsIt)
55 {
56 RhsScalar y = rhsIt.value();
57 Index k = rhsIt.index();
58 for (typename evaluator<Lhs>::InnerIterator lhsIt(lhsEval, k); lhsIt; ++lhsIt)
59 {
60 Index i = lhsIt.index();
61 LhsScalar x = lhsIt.value();
62 if(!mask[i])
63 {
64 mask[i] = true;
65 values[i] = x * y;
66 indices[nnz] = i;
67 ++nnz;
68 }
69 else
70 values[i] += x * y;
71 }
72 }
73 if(!sortedInsertion)
74 {
75 // unordered insertion
76 for(Index k=0; k<nnz; ++k)
77 {
78 Index i = indices[k];
79 res.insertBackByOuterInnerUnordered(j,i) = values[i];
80 mask[i] = false;
81 }
82 }
83 else
84 {
85 // alternative ordered insertion code:
86 const Index t200 = rows/11; // 11 == (log2(200)*1.39)
87 const Index t = (rows*100)/139;
88
89 // FIXME reserve nnz non zeros
90 // FIXME implement faster sorting algorithms for very small nnz
91 // if the result is sparse enough => use a quick sort
92 // otherwise => loop through the entire vector
93 // In order to avoid to perform an expensive log2 when the
94 // result is clearly very sparse we use a linear bound up to 200.
95 if((nnz<200 && nnz<t200) || nnz * numext::log2(int(nnz)) < t)
96 {
97 if(nnz>1) std::sort(indices,indices+nnz);
98 for(Index k=0; k<nnz; ++k)
99 {
100 Index i = indices[k];
101 res.insertBackByOuterInner(j,i) = values[i];
102 mask[i] = false;
103 }
104 }
105 else
106 {
107 // dense path
108 for(Index i=0; i<rows; ++i)
109 {
110 if(mask[i])
111 {
112 mask[i] = false;
113 res.insertBackByOuterInner(j,i) = values[i];
114 }
115 }
116 }
117 }
118 }
119 res.finalize();
120}
121
122
123} // end namespace internal
124
125namespace internal {
126
127template<typename Lhs, typename Rhs, typename ResultType,
128 int LhsStorageOrder = (traits<Lhs>::Flags&RowMajorBit) ? RowMajor : ColMajor,
129 int RhsStorageOrder = (traits<Rhs>::Flags&RowMajorBit) ? RowMajor : ColMajor,
130 int ResStorageOrder = (traits<ResultType>::Flags&RowMajorBit) ? RowMajor : ColMajor>
132
133template<typename Lhs, typename Rhs, typename ResultType>
135{
137 typedef typename LhsCleaned::Scalar Scalar;
138
139 static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
140 {
144
145 // If the result is tall and thin (in the extreme case a column vector)
146 // then it is faster to sort the coefficients inplace instead of transposing twice.
147 // FIXME, the following heuristic is probably not very good.
148 if(lhs.rows()>rhs.cols())
149 {
150 ColMajorMatrix resCol(lhs.rows(),rhs.cols());
151 // perform sorted insertion
153 res = resCol.markAsRValue();
154 }
155 else
156 {
157 ColMajorMatrixAux resCol(lhs.rows(),rhs.cols());
158 // resort to transpose to sort the entries
161 res = resRow.markAsRValue();
162 }
163 }
164};
165
166template<typename Lhs, typename Rhs, typename ResultType>
179
180template<typename Lhs, typename Rhs, typename ResultType>
193
194template<typename Lhs, typename Rhs, typename ResultType>
205
206
207template<typename Lhs, typename Rhs, typename ResultType>
220
221template<typename Lhs, typename Rhs, typename ResultType>
234
235template<typename Lhs, typename Rhs, typename ResultType>
248
249template<typename Lhs, typename Rhs, typename ResultType>
263
264} // end namespace internal
265
266
267namespace internal {
268
269template<typename Lhs, typename Rhs, typename ResultType>
270static void sparse_sparse_to_dense_product_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res)
271{
272 typedef typename remove_all<Lhs>::type::Scalar LhsScalar;
273 typedef typename remove_all<Rhs>::type::Scalar RhsScalar;
274 Index cols = rhs.outerSize();
275 eigen_assert(lhs.outerSize() == rhs.innerSize());
276
277 evaluator<Lhs> lhsEval(lhs);
278 evaluator<Rhs> rhsEval(rhs);
279
280 for (Index j=0; j<cols; ++j)
281 {
282 for (typename evaluator<Rhs>::InnerIterator rhsIt(rhsEval, j); rhsIt; ++rhsIt)
283 {
284 RhsScalar y = rhsIt.value();
285 Index k = rhsIt.index();
286 for (typename evaluator<Lhs>::InnerIterator lhsIt(lhsEval, k); lhsIt; ++lhsIt)
287 {
288 Index i = lhsIt.index();
289 LhsScalar x = lhsIt.value();
290 res.coeffRef(i,j) += x * y;
291 }
292 }
293 }
294}
295
296
297} // end namespace internal
298
299namespace internal {
300
301template<typename Lhs, typename Rhs, typename ResultType,
302 int LhsStorageOrder = (traits<Lhs>::Flags&RowMajorBit) ? RowMajor : ColMajor,
303 int RhsStorageOrder = (traits<Rhs>::Flags&RowMajorBit) ? RowMajor : ColMajor>
305
306template<typename Lhs, typename Rhs, typename ResultType>
314
315template<typename Lhs, typename Rhs, typename ResultType>
325
326template<typename Lhs, typename Rhs, typename ResultType>
336
337template<typename Lhs, typename Rhs, typename ResultType>
346
347
348} // end namespace internal
349
350} // end namespace Eigen
351
352#endif // EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H
int i
Definition BiCGSTAB_step_by_step.cpp:9
#define eigen_assert(x)
Definition Macros.h:1037
#define ei_declare_aligned_stack_constructed_variable(TYPE, NAME, SIZE, BUFFER)
Definition Memory.h:768
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition PartialRedux_count.cpp:3
int rows
Definition Tutorial_commainit_02.cpp:1
int cols
Definition Tutorial_commainit_02.cpp:1
SCALAR Scalar
Definition bench_gemm.cpp:46
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x
Definition gnuplot_common_settings.hh:12
@ ColMajor
Definition Constants.h:319
@ RowMajor
Definition Constants.h:321
const unsigned int RowMajorBit
Definition Constants.h:66
return int(ret)+1
const Scalar & y
Definition MathFunctions.h:821
@ Lhs
Definition TensorContractionMapper.h:19
@ Rhs
Definition TensorContractionMapper.h:18
int log2(int x)
Definition MathFunctions.h:1441
Namespace containing all symbols from the Eigen library.
Definition bench_norm.cpp:85
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:74
Definition BandTriangularSolver.h:13
static void run(const Lhs &lhs, const Rhs &rhs, ResultType &res)
Definition ConservativeSparseSparseProduct.h:224
static void run(const Lhs &lhs, const Rhs &rhs, ResultType &res)
Definition ConservativeSparseSparseProduct.h:238
static void run(const Lhs &lhs, const Rhs &rhs, ResultType &res)
Definition ConservativeSparseSparseProduct.h:252
static void run(const Lhs &lhs, const Rhs &rhs, ResultType &res)
Definition ConservativeSparseSparseProduct.h:169
static void run(const Lhs &lhs, const Rhs &rhs, ResultType &res)
Definition ConservativeSparseSparseProduct.h:197
traits< typenameremove_all< Lhs >::type >::Scalar Scalar
Definition ConservativeSparseSparseProduct.h:210
static void run(const Lhs &lhs, const Rhs &rhs, ResultType &res)
Definition ConservativeSparseSparseProduct.h:212
static void run(const Lhs &lhs, const Rhs &rhs, ResultType &res)
Definition ConservativeSparseSparseProduct.h:139
static void run(const Lhs &lhs, const Rhs &rhs, ResultType &res)
Definition ConservativeSparseSparseProduct.h:183
Definition ConservativeSparseSparseProduct.h:131
static void run(const Lhs &lhs, const Rhs &rhs, ResultType &res)
Definition ConservativeSparseSparseProduct.h:329
static void run(const Lhs &lhs, const Rhs &rhs, ResultType &res)
Definition ConservativeSparseSparseProduct.h:309
static void run(const Lhs &lhs, const Rhs &rhs, ResultType &res)
Definition ConservativeSparseSparseProduct.h:318
static void run(const Lhs &lhs, const Rhs &rhs, ResultType &res)
Definition ConservativeSparseSparseProduct.h:340
Definition ConservativeSparseSparseProduct.h:304
Definition ForwardDeclarations.h:17
std::ptrdiff_t j
Definition tut_arithmetic_redux_minmax.cpp:2