1#ifndef TATAMI_CONVERT_TO_COMPRESSED_SPARSE_H
2#define TATAMI_CONVERT_TO_COMPRESSED_SPARSE_H
23namespace convert_to_compressed_sparse_internal {
25template<
typename Value_,
typename Index_,
typename Count_>
26void count_compressed_sparse_non_zeros_consistent(
const tatami::Matrix<Value_, Index_>* matrix, Index_ primary, Index_ secondary,
bool row, Count_* output,
int threads) {
29 opt.sparse_extract_value =
false;
30 opt.sparse_extract_index =
false;
31 opt.sparse_ordered_index =
false;
33 parallelize([&](
int, Index_ start, Index_ length) ->
void {
34 auto wrk = consecutive_extractor<true>(matrix, row, start, length, opt);
35 for (Index_ x = 0; x < length; ++x) {
36 auto range = wrk->fetch(NULL, NULL);
37 output[start + x] = range.number;
42 parallelize([&](
int, Index_ start, Index_ length) ->
void {
43 std::vector<Value_> buffer_v(secondary);
44 auto wrk = consecutive_extractor<false>(matrix, row, start, length);
45 for (Index_ p = start, pe = start + length; p < pe; ++p) {
46 auto ptr = wrk->fetch(buffer_v.data());
48 for (Index_ s = 0; s < secondary; ++s) {
49 count += (ptr[s] != 0);
57template<
typename Value_,
typename Index_,
typename Count_>
58void count_compressed_sparse_non_zeros_inconsistent(
const tatami::Matrix<Value_, Index_>* matrix, Index_ primary, Index_ secondary,
bool row, Count_* output,
int threads) {
59 std::vector<std::vector<Count_> > nz_counts(threads - 1);
60 for (
auto& x : nz_counts) {
66 opt.sparse_extract_value =
false;
67 opt.sparse_ordered_index =
false;
69 parallelize([&](
int t, Index_ start, Index_ length) ->
void {
70 std::vector<Index_> buffer_i(primary);
71 auto wrk = consecutive_extractor<true>(matrix, !row, start, length, opt);
72 auto my_counts = (t > 0 ? nz_counts[t - 1].data() : output);
74 for (Index_ x = 0; x < length; ++x) {
75 auto range = wrk->fetch(NULL, buffer_i.data());
76 for (Index_ i = 0; i < range.number; ++i) {
77 ++my_counts[range.index[i]];
80 }, secondary, threads);
83 parallelize([&](
int t, Index_ start, Index_ length) ->
void {
84 auto wrk = consecutive_extractor<false>(matrix, !row, start, length);
85 std::vector<Value_> buffer_v(primary);
86 auto my_counts = (t > 0 ? nz_counts[t - 1].data() : output);
88 for (Index_ x = 0; x < length; ++x) {
89 auto ptr = wrk->fetch(buffer_v.data());
90 for (Index_ p = 0; p < primary; ++p) {
91 my_counts[p] += (ptr[p] != 0);
94 }, secondary, threads);
97 for (
auto& y : nz_counts) {
98 for (Index_ p = 0; p < primary; ++p) {
104template<
typename InputValue_,
typename InputIndex_,
typename Po
inter_,
typename StoredValue_,
typename StoredIndex_>
105void fill_compressed_sparse_matrix_consistent(
108 InputIndex_ secondary,
110 const Pointer_* pointers,
111 StoredValue_* output_value,
112 StoredIndex_* output_index,
117 opt.sparse_ordered_index =
false;
119 parallelize([&](
int, InputIndex_ start, InputIndex_ length) ->
void {
120 std::vector<InputValue_> buffer_v(secondary);
121 std::vector<InputIndex_> buffer_i(secondary);
122 auto wrk = consecutive_extractor<true>(matrix, row, start, length, opt);
124 for (InputIndex_ p = start, pe = start + length; p < pe; ++p) {
130 auto range = wrk->fetch(buffer_v.data(), buffer_i.data());
131 auto offset = pointers[p];
132 std::copy_n(range.value, range.number, output_value + offset);
133 std::copy_n(range.index, range.number, output_index + offset);
135 }, primary, threads);
138 parallelize([&](
int, InputIndex_ start, InputIndex_ length) ->
void {
139 std::vector<InputValue_> buffer_v(secondary);
140 auto wrk = consecutive_extractor<false>(matrix, row, start, length);
142 for (InputIndex_ p = start, pe = start + length; p < pe; ++p) {
143 auto ptr = wrk->fetch(buffer_v.data());
144 auto offset = pointers[p];
145 for (InputIndex_ s = 0; s < secondary; ++s) {
148 output_value[offset] = val;
149 output_index[offset] = s;
154 }, primary, threads);
158template<
typename InputValue_,
typename InputIndex_,
typename Po
inter_,
typename StoredValue_,
typename StoredIndex_>
159void fill_compressed_sparse_matrix_inconsistent(
162 InputIndex_ secondary,
164 const Pointer_* pointers,
165 StoredValue_* output_value,
166 StoredIndex_* output_index,
171 opt.sparse_ordered_index =
false;
173 parallelize([&](
int, InputIndex_ start, InputIndex_ length) ->
void {
174 std::vector<InputValue_> buffer_v(length);
175 std::vector<InputIndex_> buffer_i(length);
176 auto wrk = consecutive_extractor<true>(matrix, !row,
static_cast<InputIndex_
>(0), secondary, start, length, opt);
177 std::vector<Pointer_> offset_copy(pointers + start, pointers + start + length);
179 for (InputIndex_ x = 0; x < secondary; ++x) {
180 auto range = wrk->fetch(buffer_v.data(), buffer_i.data());
181 for (InputIndex_ i = 0; i < range.number; ++i) {
182 auto& pos = offset_copy[range.index[i] - start];
183 output_value[pos] = range.value[i];
184 output_index[pos] = x;
188 }, primary, threads);
191 parallelize([&](
int, InputIndex_ start, InputIndex_ length) ->
void {
192 std::vector<InputValue_> buffer_v(length);
193 auto wrk = consecutive_extractor<false>(matrix, !row,
static_cast<InputIndex_
>(0), secondary, start, length);
194 std::vector<Pointer_> offset_copy(pointers + start, pointers + start + length);
196 for (InputIndex_ x = 0; x < secondary; ++x) {
197 auto ptr = wrk->fetch(buffer_v.data());
198 for (InputIndex_ p = 0; p < length; ++p) {
201 auto& pos = offset_copy[p];
202 output_value[pos] = val;
203 output_index[pos] = x;
208 }, primary, threads);
232template<
typename Value_,
typename Index_,
typename Count_>
234 Index_ NR = matrix->
nrow();
235 Index_ NC = matrix->
ncol();
236 Index_ primary = (row ? NR : NC);
237 Index_ secondary = (row ? NC : NR);
238 std::fill_n(output, primary, 0);
241 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_consistent(matrix, primary, secondary, row, output, threads);
243 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_inconsistent(matrix, primary, secondary, row, output, threads);
266template<
typename InputValue_,
typename InputIndex_,
typename Po
inter_,
typename StoredValue_,
typename StoredIndex_>
270 const Pointer_* pointers,
271 StoredValue_* output_value,
272 StoredIndex_* output_index,
275 InputIndex_ NR = matrix->
nrow();
276 InputIndex_ NC = matrix->
ncol();
277 InputIndex_ primary = (row ? NR : NC);
278 InputIndex_ secondary = (row ? NC : NR);
281 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_consistent(matrix, primary, secondary, row, pointers, output_value, output_index, threads);
283 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_inconsistent(matrix, primary, secondary, row, pointers, output_value, output_index, threads);
297template<
typename Value_,
typename Index_,
typename Po
inter_ =
size_t>
333template<
typename StoredValue_,
typename StoredIndex_,
typename StoredPo
inter_ =
size_t,
typename InputValue_,
typename InputIndex_>
336 auto& output_v = output.
value;
337 auto& output_i = output.
index;
340 InputIndex_ NR = matrix->
nrow();
341 InputIndex_ NC = matrix->
ncol();
342 InputIndex_ primary = (row ? NR : NC);
343 InputIndex_ secondary = (row ? NC : NR);
348 const auto& store_v = frag.value;
349 const auto& store_i = frag.index;
351 output_p.resize(
static_cast<size_t>(primary) + 1);
352 for (InputIndex_ p = 0; p < primary; ++p) {
353 output_p[p + 1] = output_p[p] + store_v[p].size();
356 output_v.reserve(output_p.back());
357 output_i.reserve(output_p.back());
358 for (InputIndex_ p = 0; p < primary; ++p) {
359 output_v.insert(output_v.end(), store_v[p].begin(), store_v[p].end());
360 output_i.insert(output_i.end(), store_i[p].begin(), store_i[p].end());
365 output_p.resize(
static_cast<size_t>(primary) + 1);
366 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_consistent(matrix, primary, secondary, row, output_p.data() + 1, threads);
367 for (InputIndex_ i = 1; i <= primary; ++i) {
368 output_p[i] += output_p[i - 1];
372 output_v.resize(output_p.back());
373 output_i.resize(output_p.back());
374 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_consistent(
387 output_p.resize(
static_cast<size_t>(primary) + 1);
388 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_inconsistent(matrix, primary, secondary, row, output_p.data() + 1, threads);
389 for (InputIndex_ i = 1; i <= primary; ++i) {
390 output_p[i] += output_p[i - 1];
394 output_v.resize(output_p.back());
395 output_i.resize(output_p.back());
396 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_inconsistent(
428 typename Value_ = double,
429 typename Index_ = int,
430 typename StoredValue_ = Value_,
431 typename StoredIndex_ = Index_,
432 typename InputValue_,
437 return std::shared_ptr<Matrix<Value_, Index_> >(
441 std::vector<StoredValue_>,
442 std::vector<StoredIndex_>,
447 std::move(comp.value),
448 std::move(comp.index),
449 std::move(comp.pointers),
460template <
bool row_,
typename Value_,
typename Index_,
typename InputValue_,
typename InputIndex_>
465template <
bool row_,
typename Value_,
typename Index_,
typename StoredValue_ = Value_,
typename StoredIndex_ = Index_,
typename InputValue_,
typename InputIndex_>
466std::shared_ptr<Matrix<Value_, Index_> >
convert_to_compressed_sparse(
const Matrix<InputValue_, InputIndex_>* matrix,
bool two_pass =
false,
int threads = 1) {
Compressed sparse matrix representation.
Compressed sparse matrix representation.
Definition CompressedSparseMatrix.hpp:492
Virtual class for a matrix.
Definition Matrix.hpp:59
virtual Index_ ncol() const =0
virtual Index_ nrow() const =0
virtual bool prefer_rows() const =0
virtual bool is_sparse() const =0
Convert a matrix into a fragmented sparse format.
Flexible representations for matrix data.
Definition Extractor.hpp:15
std::shared_ptr< Matrix< Value_, Index_ > > convert_to_compressed_sparse(const Matrix< InputValue_, InputIndex_ > *matrix, bool row, bool two_pass=false, int threads=1)
Definition convert_to_compressed_sparse.hpp:435
void parallelize(Function_ fun, Index_ tasks, int threads)
Definition parallelize.hpp:42
CompressedSparseContents< StoredValue_, StoredIndex_, StoredPointer_ > retrieve_compressed_sparse_contents(const Matrix< InputValue_, InputIndex_ > *matrix, bool row, bool two_pass, int threads=1)
Definition convert_to_compressed_sparse.hpp:334
FragmentedSparseContents< StoredValue_, StoredIndex_ > retrieve_fragmented_sparse_contents(const Matrix< InputValue_, InputIndex_ > *matrix, bool row, int threads=1)
Definition convert_to_fragmented_sparse.hpp:66
void fill_compressed_sparse_contents(const tatami::Matrix< InputValue_, InputIndex_ > *matrix, bool row, const Pointer_ *pointers, StoredValue_ *output_value, StoredIndex_ *output_index, int threads)
Definition convert_to_compressed_sparse.hpp:267
void count_compressed_sparse_non_zeros(const tatami::Matrix< Value_, Index_ > *matrix, bool row, Count_ *output, int threads)
Definition convert_to_compressed_sparse.hpp:233
Parallelized iteration over a tatami::Matrix.
Compressed sparse contents.
Definition convert_to_compressed_sparse.hpp:298
std::vector< Index_ > index
Definition convert_to_compressed_sparse.hpp:307
std::vector< Value_ > value
Definition convert_to_compressed_sparse.hpp:302
std::vector< Pointer_ > pointers
Definition convert_to_compressed_sparse.hpp:312