17#include <Eigen/Sparse>
26template <
class SpMat,
class MaskVec>
29 using row_iter_t =
typename SpMat::InnerIterator;
33 return static_cast<typename MaskVec::value_type
>(it.row());
37 std::ranges::ref_view{
mask},
41 return std::get<0>(std::forward<T>(
tup));
48template <
class SpMat,
class MaskVec>
51 using row_iter_t =
typename SpMat::InnerIterator;
55 return static_cast<typename MaskVec::value_type
>(it.row());
60 static constexpr auto proj_mask = [](
const auto &
tup) ->
decltype(
auto) {
61 return std::get<1>(
tup);
69 requires(std::is_rvalue_reference_v<T &&>)
82template <
class SpMat,
class Mat,
class MaskVec>
88 R(
ri,
ci) += r.value();
92template <
class SpMat,
class Mat,
class MaskVec>
94 using index_t =
typename SpMat::Index;
99 S(
ri, c) += r.value();
103template <
class SpMat,
class CVec,
class Vec,
class MaskVec>
111 for (
auto &&[r,
ri] : select_rows_in_col_iota(R,
mask_J, c))
112 out(
ri) += r.value() *
v(c);
116template <
class SpMat,
class CVec,
class Vec,
class MaskVec>
119 using index_t =
typename SpMat::Index;
121 for (
index_t c = 0; c < S.cols(); ++c)
124 out(c) += r.value() *
v(r.row());
127#if __cpp_lib_ranges_zip >= 202110L && __cpp_lib_ranges_enumerate >= 202302L
128#define ALPAQA_HAVE_COO_CSC_CONVERSIONS 1
132 auto &&inner_idx,
auto &&outer_ptr,
I idx_0 = 0) {
134 assert(std::size(rows) == std::size(inner_idx));
136 std::ranges::ref_view
rows_vw = rows;
146template <
auto cmp,
class... Ts>
148 auto indices = std::views::zip(std::ranges::ref_view{
triplets}...);
149 auto t0 = std::chrono::steady_clock::now();
150 std::ranges::sort(indices,
cmp);
151 auto t1 = std::chrono::steady_clock::now();
152 std::cout <<
"Sorting took: "
153 << std::chrono::duration<double>{
t1 - t0}.count() * 1
e6
158template <
class... Ts>
161 auto cmp = [](
const auto &
a,
const auto &b) {
162 return std::tie(std::get<1>(
a), std::get<0>(
a)) <
163 std::tie(std::get<1>(b), std::get<0>(b));
169template <
class... Ts>
172 auto cmp = [](
const auto &
a,
const auto &b) {
173 return std::get<1>(
a) < std::get<1>(b);
182 if (outer_ptr.size() == 0)
185 auto cmp = [](
const auto &
a,
const auto &b) {
186 return std::get<0>(
a) < std::get<0>(b);
188 for (
decltype(outer_ptr.size()) c = 0; c < outer_ptr.size() - 1; ++c) {
191 auto indices = std::views::zip(
194 std::ranges::sort(indices,
cmp);
200template <
class... Ts>
202 auto indices = std::views::zip(std::ranges::ref_view{
triplets}...);
203 return std::ranges::adjacent_find(indices, std::equal_to<>{}) ==
204 std::ranges::end(indices);
209template <
class Outer,
class Inner>
211 if (outer_ptr.size() == 0)
216 std::ranges::subrange{std::ranges::begin(inner) +
inner_start,
218 return std::ranges::adjacent_find(indices, std::equal_to<>{}) ==
219 std::ranges::end(indices);
221 return std::transform_reduce(std::begin(outer_ptr), std::end(outer_ptr) - 1,
auto select_rows_in_col(const SpMat &sp_mat, MaskVec &mask, auto column)
Returns a range over the row indices in the given column of sp_mat that are also in mask.
auto select_rows_in_col_iota(const SpMat &sp_mat, MaskVec &mask, auto column)
Like select_rows_in_col, but returns a range of tuples containing the Eigen InnerIterator and a linea...
void sparse_matvec_add_masked_rows_cols(const SpMat &R, const CVec &v, Vec &&out, const MaskVec &mask_J, const MaskVec &mask_K)
out += R(mask_J,mask_K) * v(mask_K);
void sparse_add_masked_rows(const SpMat &S_full, Mat &&S, const MaskVec &mask)
S += S_full(mask,:)
auto enumerate(Rng &&rng)
void sparse_add_masked(const SpMat &R_full, Mat &&R, const MaskVec &mask)
R += R_full(mask,mask)
void sparse_matvec_add_transpose_masked_rows(const SpMat &S, const CVec &v, Vec &&out, const MaskVec &mask)
out += S(mask,:)ᵀ * v(mask);
set_intersection_iterable< std::ranges::views::all_t< R1 >, std::ranges::views::all_t< R2 >, Comp, Proj1, Proj2 > iter_set_intersection(R1 &&r1, R2 &&r2, Comp comp={}, Proj1 proj1={}, Proj2 proj2={})
typename Conf::index_t index_t