10#ifndef EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H
11#define EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H
14#include "./InternalHeaderCheck.h"
20template <
typename Lhs,
typename Rhs,
typename ResultType>
21static void conservative_sparse_sparse_product_impl(
const Lhs& lhs,
const Rhs& rhs, ResultType& res,
22 bool sortedInsertion =
false) {
23 typedef typename remove_all_t<Lhs>::Scalar LhsScalar;
24 typedef typename remove_all_t<Rhs>::Scalar RhsScalar;
25 typedef typename remove_all_t<ResultType>::Scalar ResScalar;
28 Index rows = lhs.innerSize();
29 Index cols = rhs.outerSize();
30 eigen_assert(lhs.outerSize() == rhs.innerSize());
32 ei_declare_aligned_stack_constructed_variable(
bool, mask, rows, 0);
33 ei_declare_aligned_stack_constructed_variable(ResScalar, values, rows, 0);
34 ei_declare_aligned_stack_constructed_variable(Index, indices, rows, 0);
36 std::memset(mask, 0,
sizeof(
bool) * rows);
38 evaluator<Lhs> lhsEval(lhs);
39 evaluator<Rhs> rhsEval(rhs);
47 Index estimated_nnz_prod = lhsEval.nonZerosEstimate() + rhsEval.nonZerosEstimate();
50 res.reserve(
Index(estimated_nnz_prod));
52 for (Index j = 0; j < cols; ++j) {
55 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) {
59 Index i = lhsIt.index();
60 LhsScalar x = lhsIt.value();
70 if (!sortedInsertion) {
72 for (Index k = 0; k < nnz; ++k) {
74 res.insertBackByOuterInnerUnordered(j, i) = values[i];
79 const Index t200 = rows / 11;
80 const Index t = (rows * 100) / 139;
88 if ((nnz < 200 && nnz < t200) || nnz * numext::log2(
int(nnz)) < t) {
89 if (nnz > 1) std::sort(indices, indices + nnz);
90 for (Index k = 0; k < nnz; ++k) {
92 res.insertBackByOuterInner(j, i) = values[i];
97 for (Index i = 0; i < rows; ++i) {
100 res.insertBackByOuterInner(j, i) = values[i];
114template <
class Source,
int Order>
115using WithStorageOrder = SparseMatrix<typename Source::Scalar, Order, typename Source::StorageIndex>;
117template <
typename Lhs,
typename Rhs,
typename ResultType,
121struct conservative_sparse_sparse_product_selector;
123template <
typename Lhs,
typename Rhs,
typename ResultType>
124struct conservative_sparse_sparse_product_selector<Lhs, Rhs, ResultType, ColMajor, ColMajor, ColMajor> {
125 typedef remove_all_t<Lhs> LhsCleaned;
126 typedef typename LhsCleaned::Scalar Scalar;
128 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res) {
129 using RowMajorMatrix = WithStorageOrder<ResultType, RowMajor>;
130 using ColMajorMatrixAux = WithStorageOrder<ResultType, ColMajor>;
135 if (lhs.rows() > rhs.cols()) {
136 using ColMajorMatrix =
typename sparse_eval<ColMajorMatrixAux, ResultType::RowsAtCompileTime,
137 ResultType::ColsAtCompileTime, ColMajorMatrixAux::Flags>::type;
138 ColMajorMatrix resCol(lhs.rows(), rhs.cols());
140 internal::conservative_sparse_sparse_product_impl<Lhs, Rhs, ColMajorMatrix>(lhs, rhs, resCol,
true);
141 res = resCol.markAsRValue();
143 ColMajorMatrixAux resCol(lhs.rows(), rhs.cols());
145 internal::conservative_sparse_sparse_product_impl<Lhs, Rhs, ColMajorMatrixAux>(lhs, rhs, resCol,
false);
146 RowMajorMatrix resRow(resCol);
147 res = resRow.markAsRValue();
152template <
typename Lhs,
typename Rhs,
typename ResultType>
154 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res) {
155 using RowMajorRhs = WithStorageOrder<Rhs, RowMajor>;
156 using RowMajorRes = WithStorageOrder<ResultType, RowMajor>;
157 RowMajorRhs rhsRow = rhs;
158 RowMajorRes resRow(lhs.rows(), rhs.cols());
159 internal::conservative_sparse_sparse_product_impl<RowMajorRhs, Lhs, RowMajorRes>(rhsRow, lhs, resRow);
164template <
typename Lhs,
typename Rhs,
typename ResultType>
166 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res) {
167 using RowMajorLhs = WithStorageOrder<Lhs, RowMajor>;
168 using RowMajorRes = WithStorageOrder<ResultType, RowMajor>;
169 RowMajorLhs lhsRow = lhs;
170 RowMajorRes resRow(lhs.rows(), rhs.cols());
171 internal::conservative_sparse_sparse_product_impl<Rhs, RowMajorLhs, RowMajorRes>(rhs, lhsRow, resRow);
176template <
typename Lhs,
typename Rhs,
typename ResultType>
178 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res) {
179 using RowMajorRes = WithStorageOrder<ResultType, RowMajor>;
180 RowMajorRes resRow(lhs.rows(), rhs.cols());
181 internal::conservative_sparse_sparse_product_impl<Rhs, Lhs, RowMajorRes>(rhs, lhs, resRow);
186template <
typename Lhs,
typename Rhs,
typename ResultType>
188 typedef typename traits<remove_all_t<Lhs>>::Scalar Scalar;
190 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res) {
191 using ColMajorRes = WithStorageOrder<ResultType, ColMajor>;
192 ColMajorRes resCol(lhs.rows(), rhs.cols());
193 internal::conservative_sparse_sparse_product_impl<Lhs, Rhs, ColMajorRes>(lhs, rhs, resCol);
198template <
typename Lhs,
typename Rhs,
typename ResultType>
200 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res) {
201 using ColMajorLhs = WithStorageOrder<Lhs, ColMajor>;
202 using ColMajorRes = WithStorageOrder<ResultType, ColMajor>;
203 ColMajorLhs lhsCol = lhs;
204 ColMajorRes resCol(lhs.rows(), rhs.cols());
205 internal::conservative_sparse_sparse_product_impl<ColMajorLhs, Rhs, ColMajorRes>(lhsCol, rhs, resCol);
210template <
typename Lhs,
typename Rhs,
typename ResultType>
212 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res) {
213 using ColMajorRhs = WithStorageOrder<Rhs, ColMajor>;
214 using ColMajorRes = WithStorageOrder<ResultType, ColMajor>;
215 ColMajorRhs rhsCol = rhs;
216 ColMajorRes resCol(lhs.rows(), rhs.cols());
217 internal::conservative_sparse_sparse_product_impl<Lhs, ColMajorRhs, ColMajorRes>(lhs, rhsCol, resCol);
222template <
typename Lhs,
typename Rhs,
typename ResultType>
224 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res) {
225 using ColMajorRes = WithStorageOrder<ResultType, ColMajor>;
226 using RowMajorRes = WithStorageOrder<ResultType, RowMajor>;
227 RowMajorRes resRow(lhs.rows(), rhs.cols());
228 internal::conservative_sparse_sparse_product_impl<Rhs, Lhs, RowMajorRes>(rhs, lhs, resRow);
230 ColMajorRes resCol(resRow);
239template <
typename Lhs,
typename Rhs,
typename ResultType>
240static void sparse_sparse_to_dense_product_impl(
const Lhs& lhs,
const Rhs& rhs, ResultType& res) {
241 typedef typename remove_all_t<Lhs>::Scalar LhsScalar;
242 typedef typename remove_all_t<Rhs>::Scalar RhsScalar;
243 Index cols = rhs.outerSize();
244 eigen_assert(lhs.outerSize() == rhs.innerSize());
246 evaluator<Lhs> lhsEval(lhs);
247 evaluator<Rhs> rhsEval(rhs);
249 for (Index j = 0; j < cols; ++j) {
250 for (
typename evaluator<Rhs>::InnerIterator rhsIt(rhsEval, j); rhsIt; ++rhsIt) {
251 RhsScalar y = rhsIt.value();
252 Index k = rhsIt.index();
253 for (
typename evaluator<Lhs>::InnerIterator lhsIt(lhsEval, k); lhsIt; ++lhsIt) {
254 Index i = lhsIt.index();
255 LhsScalar x = lhsIt.value();
256 res.coeffRef(i, j) += x * y;
266template <
typename Lhs,
typename Rhs,
typename ResultType,
269struct sparse_sparse_to_dense_product_selector;
271template <
typename Lhs,
typename Rhs,
typename ResultType>
272struct sparse_sparse_to_dense_product_selector<Lhs, Rhs, ResultType, ColMajor, ColMajor> {
273 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res) {
274 internal::sparse_sparse_to_dense_product_impl<Lhs, Rhs, ResultType>(lhs, rhs, res);
278template <
typename Lhs,
typename Rhs,
typename ResultType>
279struct sparse_sparse_to_dense_product_selector<Lhs, Rhs, ResultType, RowMajor, ColMajor> {
280 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res) {
281 using ColMajorLhs = WithStorageOrder<Lhs, ColMajor>;
282 ColMajorLhs lhsCol(lhs);
283 internal::sparse_sparse_to_dense_product_impl<ColMajorLhs, Rhs, ResultType>(lhsCol, rhs, res);
287template <
typename Lhs,
typename Rhs,
typename ResultType>
288struct sparse_sparse_to_dense_product_selector<Lhs, Rhs, ResultType, ColMajor, RowMajor> {
289 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res) {
290 using ColMajorRhs = WithStorageOrder<Rhs, ColMajor>;
291 ColMajorRhs rhsCol(rhs);
292 internal::sparse_sparse_to_dense_product_impl<Lhs, ColMajorRhs, ResultType>(lhs, rhsCol, res);
296template <
typename Lhs,
typename Rhs,
typename ResultType>
297struct sparse_sparse_to_dense_product_selector<Lhs, Rhs, ResultType, RowMajor, RowMajor> {
298 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType& res) {
299 Transpose<ResultType> trRes(res);
300 internal::sparse_sparse_to_dense_product_impl<Rhs, Lhs, Transpose<ResultType>>(rhs, lhs, trRes);
@ ColMajor
Definition Constants.h:318
@ RowMajor
Definition Constants.h:320
const unsigned int RowMajorBit
Definition Constants.h:70
Namespace containing all symbols from the Eigen library.
Definition Core:137
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:83