1#ifndef TATAMI_CONVERT_TO_COMPRESSED_SPARSE_H
2#define TATAMI_CONVERT_TO_COMPRESSED_SPARSE_H
8#include "../utils/Index_to_container.hpp"
25namespace convert_to_compressed_sparse_internal {
27template<
typename Value_,
typename Index_,
typename Count_>
28void count_compressed_sparse_non_zeros_consistent(
const tatami::Matrix<Value_, Index_>& matrix, Index_ primary, Index_ secondary,
bool row, Count_* output,
int threads) {
31 opt.sparse_extract_value =
false;
32 opt.sparse_extract_index =
false;
33 opt.sparse_ordered_index =
false;
35 parallelize([&](
int, Index_ start, Index_ length) ->
void {
36 auto wrk = consecutive_extractor<true>(matrix, row, start, length, opt);
37 for (Index_ x = 0; x < length; ++x) {
38 auto range = wrk->fetch(NULL, NULL);
39 output[start + x] = range.number;
44 parallelize([&](
int, Index_ start, Index_ length) ->
void {
45 std::vector<Value_> buffer_v(secondary);
46 auto wrk = consecutive_extractor<false>(matrix, row, start, length);
47 for (Index_ p = start, pe = start + length; p < pe; ++p) {
48 auto ptr = wrk->fetch(buffer_v.data());
50 for (Index_ s = 0; s < secondary; ++s) {
51 count += (ptr[s] != 0);
59template<
typename Value_,
typename Index_,
typename Count_>
60void count_compressed_sparse_non_zeros_inconsistent(
const tatami::Matrix<Value_, Index_>& matrix, Index_ primary, Index_ secondary,
bool row, Count_* output,
int threads) {
61 auto nz_counts = sanisizer::create<std::vector<std::vector<Count_> > >(threads - 1);
62 for (
auto& x : nz_counts) {
68 opt.sparse_extract_value =
false;
69 opt.sparse_ordered_index =
false;
71 parallelize([&](
int t, Index_ start, Index_ length) ->
void {
72 auto wrk = consecutive_extractor<true>(matrix, !row, start, length, opt);
73 auto buffer_i = create_container_of_Index_size<std::vector<Index_> >(primary);
74 auto my_counts = (t > 0 ? nz_counts[t - 1].data() : output);
76 for (Index_ x = 0; x < length; ++x) {
77 auto range = wrk->fetch(NULL, buffer_i.data());
78 for (Index_ i = 0; i < range.number; ++i) {
79 ++my_counts[range.index[i]];
82 }, secondary, threads);
85 parallelize([&](
int t, Index_ start, Index_ length) ->
void {
86 auto wrk = consecutive_extractor<false>(matrix, !row, start, length);
87 auto buffer_v = create_container_of_Index_size<std::vector<Value_> >(primary);
88 auto my_counts = (t > 0 ? nz_counts[t - 1].data() : output);
90 for (Index_ x = 0; x < length; ++x) {
91 auto ptr = wrk->fetch(buffer_v.data());
92 for (Index_ p = 0; p < primary; ++p) {
93 my_counts[p] += (ptr[p] != 0);
96 }, secondary, threads);
99 for (
auto& y : nz_counts) {
100 for (Index_ p = 0; p < primary; ++p) {
106template<
typename InputValue_,
typename InputIndex_,
typename Po
inter_,
typename StoredValue_,
typename StoredIndex_>
107void fill_compressed_sparse_matrix_consistent(
110 InputIndex_ secondary,
112 const Pointer_* pointers,
113 StoredValue_* output_value,
114 StoredIndex_* output_index,
119 opt.sparse_ordered_index =
false;
121 parallelize([&](
int, InputIndex_ start, InputIndex_ length) ->
void {
122 auto wrk = consecutive_extractor<true>(matrix, row, start, length, opt);
123 auto buffer_v = create_container_of_Index_size<std::vector<InputValue_> >(secondary);
124 auto buffer_i = create_container_of_Index_size<std::vector<InputIndex_> >(secondary);
126 for (InputIndex_ p = start, pe = start + length; p < pe; ++p) {
132 auto range = wrk->fetch(buffer_v.data(), buffer_i.data());
133 auto offset = pointers[p];
134 std::copy_n(range.value, range.number, output_value + offset);
135 std::copy_n(range.index, range.number, output_index + offset);
137 }, primary, threads);
140 parallelize([&](
int, InputIndex_ start, InputIndex_ length) ->
void {
141 std::vector<InputValue_> buffer_v(secondary);
142 auto wrk = consecutive_extractor<false>(matrix, row, start, length);
144 for (InputIndex_ p = start, pe = start + length; p < pe; ++p) {
145 auto ptr = wrk->fetch(buffer_v.data());
146 auto offset = pointers[p];
147 for (InputIndex_ s = 0; s < secondary; ++s) {
150 output_value[offset] = val;
151 output_index[offset] = s;
156 }, primary, threads);
160template<
typename InputValue_,
typename InputIndex_,
typename Po
inter_,
typename StoredValue_,
typename StoredIndex_>
161void fill_compressed_sparse_matrix_inconsistent(
164 InputIndex_ secondary,
166 const Pointer_* pointers,
167 StoredValue_* output_value,
168 StoredIndex_* output_index,
173 opt.sparse_ordered_index =
false;
175 parallelize([&](
int, InputIndex_ start, InputIndex_ length) ->
void {
176 auto wrk = consecutive_extractor<true>(matrix, !row,
static_cast<InputIndex_
>(0), secondary, start, length, opt);
177 auto buffer_v = create_container_of_Index_size<std::vector<InputValue_> >(length);
178 auto buffer_i = create_container_of_Index_size<std::vector<InputIndex_> >(length);
179 std::vector<Pointer_> offset_copy(pointers + start, pointers + start + length);
181 for (InputIndex_ x = 0; x < secondary; ++x) {
182 auto range = wrk->fetch(buffer_v.data(), buffer_i.data());
183 for (InputIndex_ i = 0; i < range.number; ++i) {
184 auto& pos = offset_copy[range.index[i] - start];
185 output_value[pos] = range.value[i];
186 output_index[pos] = x;
190 }, primary, threads);
193 parallelize([&](
int, InputIndex_ start, InputIndex_ length) ->
void {
194 auto wrk = consecutive_extractor<false>(matrix, !row,
static_cast<InputIndex_
>(0), secondary, start, length);
195 auto buffer_v = create_container_of_Index_size<std::vector<InputValue_> >(length);
196 std::vector<Pointer_> offset_copy(pointers + start, pointers + start + length);
198 for (InputIndex_ x = 0; x < secondary; ++x) {
199 auto ptr = wrk->fetch(buffer_v.data());
200 for (InputIndex_ p = 0; p < length; ++p) {
203 auto& pos = offset_copy[p];
204 output_value[pos] = val;
205 output_index[pos] = x;
210 }, primary, threads);
244template<
typename Value_,
typename Index_,
typename Count_>
246 Index_ NR = matrix.
nrow();
247 Index_ NC = matrix.
ncol();
248 Index_ primary = (row ? NR : NC);
249 Index_ secondary = (row ? NC : NR);
250 std::fill_n(output, primary, 0);
253 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_consistent(matrix, primary, secondary, row, output, options.
num_threads);
255 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_inconsistent(matrix, primary, secondary, row, output, options.
num_threads);
288template<
typename InputValue_,
typename InputIndex_,
typename Po
inter_,
typename StoredValue_,
typename StoredIndex_>
292 const Pointer_* pointers,
293 StoredValue_* output_value,
294 StoredIndex_* output_index,
297 InputIndex_ NR = matrix.
nrow();
298 InputIndex_ NC = matrix.
ncol();
299 InputIndex_ primary = (row ? NR : NC);
300 InputIndex_ secondary = (row ? NC : NR);
303 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_consistent(matrix, primary, secondary, row, pointers, output_value, output_index, options.
num_threads);
305 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_inconsistent(matrix, primary, secondary, row, pointers, output_value, output_index, options.
num_threads);
319template<
typename Value_,
typename Index_,
typename Po
inter_>
370template<
typename StoredValue_,
typename StoredIndex_,
typename StoredPo
inter_ = std::
size_t,
typename InputValue_,
typename InputIndex_>
379 auto& output_v = output.
value;
380 auto& output_i = output.
index;
383 InputIndex_ NR = matrix.
nrow();
384 InputIndex_ NC = matrix.
ncol();
385 InputIndex_ primary = (row ? NR : NC);
386 InputIndex_ secondary = (row ? NC : NR);
399 const auto& store_v = frag.value;
400 const auto& store_i = frag.index;
402 output_p.resize(
static_cast<std::size_t
>(primary) + 1);
403 for (InputIndex_ p = 0; p < primary; ++p) {
404 output_p[p + 1] = output_p[p] + store_v[p].size();
407 output_v.reserve(output_p.back());
408 output_i.reserve(output_p.back());
409 for (InputIndex_ p = 0; p < primary; ++p) {
410 output_v.insert(output_v.end(), store_v[p].begin(), store_v[p].end());
411 output_i.insert(output_i.end(), store_i[p].begin(), store_i[p].end());
416 output_p.resize(
static_cast<std::size_t
>(primary) + 1);
417 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_consistent(matrix, primary, secondary, row, output_p.data() + 1, options.
num_threads);
418 for (InputIndex_ i = 1; i <= primary; ++i) {
419 output_p[i] += output_p[i - 1];
423 output_v.resize(output_p.back());
424 output_i.resize(output_p.back());
425 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_consistent(
438 output_p.resize(
static_cast<std::size_t
>(primary) + 1);
439 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_inconsistent(matrix, primary, secondary, row, output_p.data() + 1, options.
num_threads);
440 for (InputIndex_ i = 1; i <= primary; ++i) {
441 output_p[i] += output_p[i - 1];
445 output_v.resize(output_p.back());
446 output_i.resize(output_p.back());
447 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_inconsistent(
498 typename StoredValue_ = Value_,
499 typename StoredIndex_ = Index_,
500 typename StoredPointer_ = std::size_t,
501 typename InputValue_,
515 return std::shared_ptr<Matrix<Value_, Index_> >(
519 std::vector<StoredValue_>,
520 std::vector<StoredIndex_>,
521 std::vector<StoredPointer_>
525 std::move(comp.value),
526 std::move(comp.index),
527 std::move(comp.pointers),
530 CompressedSparseMatrixOptions copt;
542template<
typename Value_,
typename Index_,
typename Count_>
549 CountCompressedSparseNonZerosOptions copt;
550 copt.num_threads = threads;
556template<
typename InputValue_,
typename InputIndex_,
typename Po
inter_,
typename StoredValue_,
typename StoredIndex_>
559 const Pointer_* pointers,
560 StoredValue_* output_value,
561 StoredIndex_* output_index,
571 FillCompressedSparseContentsOptions fopt;
572 fopt.num_threads = threads;
578template<
typename StoredValue_,
typename StoredIndex_,
typename StoredPo
inter_ = std::
size_t,
typename InputValue_,
typename InputIndex_>
579CompressedSparseContents<StoredValue_, StoredIndex_, StoredPointer_>
retrieve_compressed_sparse_contents(
const Matrix<InputValue_, InputIndex_>* matrix,
bool row,
bool two_pass,
int threads = 1) {
584 RetrieveCompressedSparseContentsOptions opt;
585 opt.two_pass = two_pass;
586 opt.num_threads = threads;
592template<
typename Value_ =
double,
typename Index_ =
int,
typename StoredValue_ = Value_,
typename StoredIndex_ = Index_,
typename InputValue_,
typename InputIndex_>
593std::shared_ptr<Matrix<Value_, Index_> >
convert_to_compressed_sparse(
const Matrix<InputValue_, InputIndex_>* matrix,
bool row,
bool two_pass =
false,
int threads = 1) {
598 ConvertToCompressedSparseOptions opt;
599 opt.two_pass = two_pass;
600 opt.num_threads = threads;
606template <
bool row_,
typename Value_,
typename Index_,
typename InputValue_,
typename InputIndex_>
611template <
bool row_,
typename Value_,
typename Index_,
typename StoredValue_ = Value_,
typename StoredIndex_ = Index_,
typename InputValue_,
typename InputIndex_>
612std::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:503
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
CompressedSparseContents< StoredValue_, StoredIndex_, StoredPointer_ > retrieve_compressed_sparse_contents(const Matrix< InputValue_, InputIndex_ > &matrix, bool row, const RetrieveCompressedSparseContentsOptions &options)
Definition convert_to_compressed_sparse.hpp:371
std::shared_ptr< Matrix< Value_, Index_ > > convert_to_compressed_sparse(const Matrix< InputValue_, InputIndex_ > &matrix, bool row, const ConvertToCompressedSparseOptions &options)
Definition convert_to_compressed_sparse.hpp:504
void parallelize(Function_ fun, Index_ tasks, int threads)
Definition parallelize.hpp:42
FragmentedSparseContents< StoredValue_, StoredIndex_ > retrieve_fragmented_sparse_contents(const Matrix< InputValue_, InputIndex_ > &matrix, bool row, const RetrieveFragmentedSparseContentsOptions &options)
Definition convert_to_fragmented_sparse.hpp:81
void fill_compressed_sparse_contents(const tatami::Matrix< InputValue_, InputIndex_ > &matrix, bool row, const Pointer_ *pointers, StoredValue_ *output_value, StoredIndex_ *output_index, const FillCompressedSparseContentsOptions &options)
Definition convert_to_compressed_sparse.hpp:289
void count_compressed_sparse_non_zeros(const tatami::Matrix< Value_, Index_ > &matrix, bool row, Count_ *output, const CountCompressedSparseNonZerosOptions &options)
Definition convert_to_compressed_sparse.hpp:245
Parallelized iteration over a tatami::Matrix.
Compressed sparse contents.
Definition convert_to_compressed_sparse.hpp:320
std::vector< Index_ > index
Definition convert_to_compressed_sparse.hpp:329
std::vector< Value_ > value
Definition convert_to_compressed_sparse.hpp:324
std::vector< Pointer_ > pointers
Definition convert_to_compressed_sparse.hpp:334
Options for convert_to_compressed_sparse().
Definition convert_to_compressed_sparse.hpp:465
bool two_pass
Definition convert_to_compressed_sparse.hpp:470
int num_threads
Definition convert_to_compressed_sparse.hpp:475
Options for count_compressed_sparse_non_zeros().
Definition convert_to_compressed_sparse.hpp:222
int num_threads
Definition convert_to_compressed_sparse.hpp:226
Options for fill_compressed_sparse_contents().
Definition convert_to_compressed_sparse.hpp:262
int num_threads
Definition convert_to_compressed_sparse.hpp:266
Options for retrieve_compressed_sparse_contents().
Definition convert_to_compressed_sparse.hpp:340
int num_threads
Definition convert_to_compressed_sparse.hpp:350
bool two_pass
Definition convert_to_compressed_sparse.hpp:345
Options for retrieve_fragmented_sparse_contents().
Definition convert_to_fragmented_sparse.hpp:61
int num_threads
Definition convert_to_fragmented_sparse.hpp:65