10#ifndef EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H
11#define EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H
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)
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;
25 Index rows = lhs.innerSize();
26 Index cols = rhs.outerSize();
27 eigen_assert(lhs.outerSize() == rhs.innerSize());
29 ei_declare_aligned_stack_constructed_variable(
bool, mask, rows, 0);
30 ei_declare_aligned_stack_constructed_variable(ResScalar, values, rows, 0);
31 ei_declare_aligned_stack_constructed_variable(
Index, indices, rows, 0);
33 std::memset(mask,0,
sizeof(
bool)*rows);
35 evaluator<Lhs> lhsEval(lhs);
36 evaluator<Rhs> rhsEval(rhs);
44 Index estimated_nnz_prod = lhsEval.nonZerosEstimate() + rhsEval.nonZerosEstimate();
47 res.reserve(
Index(estimated_nnz_prod));
49 for (
Index j=0; j<cols; ++j)
54 for (
typename evaluator<Rhs>::InnerIterator rhsIt(rhsEval, j); rhsIt; ++rhsIt)
56 RhsScalar y = rhsIt.value();
57 Index k = rhsIt.index();
58 for (
typename evaluator<Lhs>::InnerIterator lhsIt(lhsEval, k); lhsIt; ++lhsIt)
60 Index i = lhsIt.index();
61 LhsScalar x = lhsIt.value();
76 for(
Index k=0; k<nnz; ++k)
79 res.insertBackByOuterInnerUnordered(j,i) = values[i];
86 const Index t200 = rows/11;
87 const Index t = (rows*100)/139;
95 if((nnz<200 && nnz<t200) || nnz * numext::log2(
int(nnz)) < t)
97 if(nnz>1) std::sort(indices,indices+nnz);
98 for(
Index k=0; k<nnz; ++k)
100 Index i = indices[k];
101 res.insertBackByOuterInner(j,i) = values[i];
108 for(
Index i=0; i<rows; ++i)
113 res.insertBackByOuterInner(j,i) = values[i];
127template<
typename Lhs,
typename Rhs,
typename ResultType,
131struct conservative_sparse_sparse_product_selector;
133template<
typename Lhs,
typename Rhs,
typename ResultType>
134struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,ColMajor,ColMajor>
136 typedef typename remove_all<Lhs>::type LhsCleaned;
137 typedef typename LhsCleaned::Scalar Scalar;
139 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res)
141 typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename ResultType::StorageIndex> RowMajorMatrix;
142 typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorMatrixAux;
143 typedef typename sparse_eval<ColMajorMatrixAux,ResultType::RowsAtCompileTime,ResultType::ColsAtCompileTime,ColMajorMatrixAux::Flags>::type ColMajorMatrix;
148 if(lhs.rows()>rhs.cols())
150 ColMajorMatrix resCol(lhs.rows(),rhs.cols());
152 internal::conservative_sparse_sparse_product_impl<Lhs,Rhs,ColMajorMatrix>(lhs, rhs, resCol,
true);
153 res = resCol.markAsRValue();
157 ColMajorMatrixAux resCol(lhs.rows(),rhs.cols());
159 internal::conservative_sparse_sparse_product_impl<Lhs,Rhs,ColMajorMatrixAux>(lhs, rhs, resCol,
false);
160 RowMajorMatrix resRow(resCol);
161 res = resRow.markAsRValue();
166template<
typename Lhs,
typename Rhs,
typename ResultType>
167struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,ColMajor,ColMajor>
169 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res)
171 typedef SparseMatrix<typename Rhs::Scalar,RowMajor,typename ResultType::StorageIndex> RowMajorRhs;
172 typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename ResultType::StorageIndex> RowMajorRes;
173 RowMajorRhs rhsRow = rhs;
174 RowMajorRes resRow(lhs.rows(), rhs.cols());
175 internal::conservative_sparse_sparse_product_impl<RowMajorRhs,Lhs,RowMajorRes>(rhsRow, lhs, resRow);
180template<
typename Lhs,
typename Rhs,
typename ResultType>
181struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,RowMajor,ColMajor>
183 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res)
185 typedef SparseMatrix<typename Lhs::Scalar,RowMajor,typename ResultType::StorageIndex> RowMajorLhs;
186 typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename ResultType::StorageIndex> RowMajorRes;
187 RowMajorLhs lhsRow = lhs;
188 RowMajorRes resRow(lhs.rows(), rhs.cols());
189 internal::conservative_sparse_sparse_product_impl<Rhs,RowMajorLhs,RowMajorRes>(rhs, lhsRow, resRow);
194template<
typename Lhs,
typename Rhs,
typename ResultType>
195struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,RowMajor,ColMajor>
197 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res)
199 typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename ResultType::StorageIndex> RowMajorMatrix;
200 RowMajorMatrix resRow(lhs.rows(), rhs.cols());
201 internal::conservative_sparse_sparse_product_impl<Rhs,Lhs,RowMajorMatrix>(rhs, lhs, resRow);
207template<
typename Lhs,
typename Rhs,
typename ResultType>
208struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,ColMajor,RowMajor>
210 typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar;
212 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res)
214 typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorMatrix;
215 ColMajorMatrix resCol(lhs.rows(), rhs.cols());
216 internal::conservative_sparse_sparse_product_impl<Lhs,Rhs,ColMajorMatrix>(lhs, rhs, resCol);
221template<
typename Lhs,
typename Rhs,
typename ResultType>
224 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res)
226 typedef SparseMatrix<typename Lhs::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorLhs;
227 typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorRes;
228 ColMajorLhs lhsCol = lhs;
229 ColMajorRes resCol(lhs.rows(), rhs.cols());
230 internal::conservative_sparse_sparse_product_impl<ColMajorLhs,Rhs,ColMajorRes>(lhsCol, rhs, resCol);
235template<
typename Lhs,
typename Rhs,
typename ResultType>
238 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res)
240 typedef SparseMatrix<typename Rhs::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorRhs;
241 typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorRes;
242 ColMajorRhs rhsCol = rhs;
243 ColMajorRes resCol(lhs.rows(), rhs.cols());
244 internal::conservative_sparse_sparse_product_impl<Lhs,ColMajorRhs,ColMajorRes>(lhs, rhsCol, resCol);
249template<
typename Lhs,
typename Rhs,
typename ResultType>
252 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res)
254 typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename ResultType::StorageIndex> RowMajorMatrix;
255 typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorMatrix;
256 RowMajorMatrix resRow(lhs.rows(),rhs.cols());
257 internal::conservative_sparse_sparse_product_impl<Rhs,Lhs,RowMajorMatrix>(rhs, lhs, resRow);
259 ColMajorMatrix resCol(resRow);
269template<
typename Lhs,
typename Rhs,
typename ResultType>
270static void sparse_sparse_to_dense_product_impl(
const Lhs& lhs,
const Rhs& rhs, ResultType& res)
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());
277 evaluator<Lhs> lhsEval(lhs);
278 evaluator<Rhs> rhsEval(rhs);
280 for (
Index j=0; j<cols; ++j)
282 for (
typename evaluator<Rhs>::InnerIterator rhsIt(rhsEval, j); rhsIt; ++rhsIt)
284 RhsScalar y = rhsIt.value();
285 Index k = rhsIt.index();
286 for (
typename evaluator<Lhs>::InnerIterator lhsIt(lhsEval, k); lhsIt; ++lhsIt)
288 Index i = lhsIt.index();
289 LhsScalar x = lhsIt.value();
290 res.coeffRef(i,j) += x * y;
301template<
typename Lhs,
typename Rhs,
typename ResultType,
304struct sparse_sparse_to_dense_product_selector;
306template<
typename Lhs,
typename Rhs,
typename ResultType>
307struct sparse_sparse_to_dense_product_selector<Lhs,Rhs,ResultType,
ColMajor,
ColMajor>
309 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res)
311 internal::sparse_sparse_to_dense_product_impl<Lhs,Rhs,ResultType>(lhs, rhs, res);
315template<
typename Lhs,
typename Rhs,
typename ResultType>
316struct sparse_sparse_to_dense_product_selector<Lhs,Rhs,ResultType,
RowMajor,
ColMajor>
318 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res)
320 typedef SparseMatrix<typename Lhs::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorLhs;
321 ColMajorLhs lhsCol(lhs);
322 internal::sparse_sparse_to_dense_product_impl<ColMajorLhs,Rhs,ResultType>(lhsCol, rhs, res);
326template<
typename Lhs,
typename Rhs,
typename ResultType>
327struct sparse_sparse_to_dense_product_selector<Lhs,Rhs,ResultType,
ColMajor,
RowMajor>
329 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res)
331 typedef SparseMatrix<typename Rhs::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorRhs;
332 ColMajorRhs rhsCol(rhs);
333 internal::sparse_sparse_to_dense_product_impl<Lhs,ColMajorRhs,ResultType>(lhs, rhsCol, res);
337template<
typename Lhs,
typename Rhs,
typename ResultType>
338struct sparse_sparse_to_dense_product_selector<Lhs,Rhs,ResultType,
RowMajor,
RowMajor>
340 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res)
342 Transpose<ResultType> trRes(res);
343 internal::sparse_sparse_to_dense_product_impl<Rhs,Lhs,Transpose<ResultType> >(rhs, lhs, trRes);
@ ColMajor
Definition: Constants.h:319
@ RowMajor
Definition: Constants.h:321
const unsigned int RowMajorBit
Definition: Constants.h:66
Namespace containing all symbols from the Eigen library.
Definition: Core:141
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74