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 && \
128 __cpp_lib_ranges_enumerate >= 202302L && !defined(__clang__)
129#define ALPAQA_HAVE_COO_CSC_CONVERSIONS 1
133 auto &&inner_idx,
auto &&outer_ptr,
I idx_0 = 0) {
135 assert(std::size(rows) == std::size(inner_idx));
137 std::ranges::ref_view
rows_vw = rows;
147template <
auto cmp,
class... Ts>
149 auto indices = std::views::zip(std::ranges::ref_view{
triplets}...);
150 auto t0 = std::chrono::steady_clock::now();
151 std::ranges::sort(indices,
cmp);
152 auto t1 = std::chrono::steady_clock::now();
153 std::cout <<
"Sorting took: "
154 << std::chrono::duration<double>{
t1 - t0}.count() * 1
e6
159template <
class... Ts>
162 auto cmp = [](
const auto &
a,
const auto &b) {
163 return std::tie(std::get<1>(
a), std::get<0>(
a)) <
164 std::tie(std::get<1>(b), std::get<0>(b));
170template <
class... Ts>
173 auto cmp = [](
const auto &
a,
const auto &b) {
174 return std::get<1>(
a) < std::get<1>(b);
183 if (outer_ptr.size() == 0)
186 auto cmp = [](
const auto &
a,
const auto &b) {
187 return std::get<0>(
a) < std::get<0>(b);
189 for (
decltype(outer_ptr.size()) c = 0; c < outer_ptr.size() - 1; ++c) {
192 auto indices = std::views::zip(
195 std::ranges::sort(indices,
cmp);
201template <
class... Ts>
203 auto indices = std::views::zip(std::ranges::ref_view{
triplets}...);
204 return std::ranges::adjacent_find(indices, std::equal_to<>{}) ==
205 std::ranges::end(indices);
210template <
class Outer,
class Inner>
212 if (outer_ptr.size() == 0)
217 std::ranges::subrange{std::ranges::begin(inner) +
inner_start,
219 return std::ranges::adjacent_find(indices, std::equal_to<>{}) ==
220 std::ranges::end(indices);
222 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