1#ifndef TATAMI_CONVERT_TO_COMPRESSED_SPARSE_H
2#define TATAMI_CONVERT_TO_COMPRESSED_SPARSE_H
12#include "../utils/Index_to_container.hpp"
26namespace convert_to_compressed_sparse_internal {
28template<
typename Value_,
typename Index_,
typename Count_>
29void count_compressed_sparse_non_zeros_consistent(
32 const Index_ secondary,
39 opt.sparse_extract_value =
false;
40 opt.sparse_extract_index =
false;
41 opt.sparse_ordered_index =
false;
43 parallelize([&](
const int,
const Index_ start,
const Index_ length) ->
void {
44 auto wrk = consecutive_extractor<true>(matrix, row, start, length, opt);
45 for (Index_ x = 0; x < length; ++x) {
46 const auto range = wrk->fetch(NULL, NULL);
47 output[start + x] = range.number;
52 parallelize([&](
const int,
const Index_ start,
const Index_ length) ->
void {
53 auto buffer_v = create_container_of_Index_size<std::vector<Value_> >(secondary);
54 auto wrk = consecutive_extractor<false>(matrix, row, start, length);
55 for (Index_ p = start, pe = start + length; p < pe; ++p) {
56 const auto ptr = wrk->fetch(buffer_v.data());
58 for (Index_ s = 0; s < secondary; ++s) {
59 count += (ptr[s] != 0);
67template<
typename Value_,
typename Index_,
typename Count_>
68void count_compressed_sparse_non_zeros_inconsistent(
71 const Index_ secondary,
76 auto nz_counts = sanisizer::create<std::vector<std::vector<Count_> > >(threads - 1);
77 for (
auto& x : nz_counts) {
83 opt.sparse_extract_value =
false;
84 opt.sparse_ordered_index =
false;
86 parallelize([&](
const int t,
const Index_ start,
const Index_ length) ->
void {
87 auto wrk = consecutive_extractor<true>(matrix, !row, start, length, opt);
88 auto buffer_i = create_container_of_Index_size<std::vector<Index_> >(primary);
89 const auto my_counts = (t > 0 ? nz_counts[t - 1].data() : output);
91 for (Index_ x = 0; x < length; ++x) {
92 const auto range = wrk->fetch(NULL, buffer_i.data());
93 for (Index_ i = 0; i < range.number; ++i) {
94 ++my_counts[range.index[i]];
97 }, secondary, threads);
100 parallelize([&](
const int t,
const Index_ start,
const Index_ length) ->
void {
101 auto wrk = consecutive_extractor<false>(matrix, !row, start, length);
102 auto buffer_v = create_container_of_Index_size<std::vector<Value_> >(primary);
103 const auto my_counts = (t > 0 ? nz_counts[t - 1].data() : output);
105 for (Index_ x = 0; x < length; ++x) {
106 const auto ptr = wrk->fetch(buffer_v.data());
107 for (Index_ p = 0; p < primary; ++p) {
108 my_counts[p] += (ptr[p] != 0);
111 }, secondary, threads);
114 for (
auto& y : nz_counts) {
115 for (Index_ p = 0; p < primary; ++p) {
121template<
typename InputValue_,
typename InputIndex_,
typename Po
inter_,
typename StoredValue_,
typename StoredIndex_>
122void fill_compressed_sparse_matrix_consistent(
124 const InputIndex_ primary,
125 const InputIndex_ secondary,
127 const Pointer_*
const pointers,
128 StoredValue_*
const output_value,
129 StoredIndex_*
const output_index,
134 opt.sparse_ordered_index =
false;
136 parallelize([&](
const int,
const InputIndex_ start,
const InputIndex_ length) ->
void {
137 auto wrk = consecutive_extractor<true>(matrix, row, start, length, opt);
138 auto buffer_v = create_container_of_Index_size<std::vector<InputValue_> >(secondary);
139 auto buffer_i = create_container_of_Index_size<std::vector<InputIndex_> >(secondary);
141 for (InputIndex_ p = start, pe = start + length; p < pe; ++p) {
147 const auto range = wrk->fetch(buffer_v.data(), buffer_i.data());
148 const auto offset = pointers[p];
149 std::copy_n(range.value, range.number, output_value + offset);
150 std::copy_n(range.index, range.number, output_index + offset);
152 }, primary, threads);
155 parallelize([&](
const int,
const InputIndex_ start,
const InputIndex_ length) ->
void {
156 auto buffer_v = create_container_of_Index_size<std::vector<InputValue_> >(secondary);
157 auto wrk = consecutive_extractor<false>(matrix, row, start, length);
159 for (InputIndex_ p = start, pe = start + length; p < pe; ++p) {
160 const auto ptr = wrk->fetch(buffer_v.data());
161 auto offset = pointers[p];
162 for (InputIndex_ s = 0; s < secondary; ++s) {
163 const auto val = ptr[s];
165 output_value[offset] = val;
166 output_index[offset] = s;
171 }, primary, threads);
175template<
typename InputValue_,
typename InputIndex_,
typename Po
inter_,
typename StoredValue_,
typename StoredIndex_>
176void fill_compressed_sparse_matrix_inconsistent(
178 const InputIndex_ primary,
179 const InputIndex_ secondary,
181 const Pointer_*
const pointers,
182 StoredValue_*
const output_value,
183 StoredIndex_*
const output_index,
188 opt.sparse_ordered_index =
false;
190 parallelize([&](
const int,
const InputIndex_ start,
const InputIndex_ length) ->
void {
191 auto wrk = consecutive_extractor<true>(matrix, !row,
static_cast<InputIndex_
>(0), secondary, start, length, opt);
192 auto buffer_v = create_container_of_Index_size<std::vector<InputValue_> >(length);
193 auto buffer_i = create_container_of_Index_size<std::vector<InputIndex_> >(length);
194 std::vector<Pointer_> offset_copy(pointers + start, pointers + start + length);
196 for (InputIndex_ x = 0; x < secondary; ++x) {
197 const auto range = wrk->fetch(buffer_v.data(), buffer_i.data());
198 for (InputIndex_ i = 0; i < range.number; ++i) {
199 auto& pos = offset_copy[range.index[i] - start];
200 output_value[pos] = range.value[i];
201 output_index[pos] = x;
205 }, primary, threads);
208 parallelize([&](
const int,
const InputIndex_ start,
const InputIndex_ length) ->
void {
209 auto wrk = consecutive_extractor<false>(matrix, !row,
static_cast<InputIndex_
>(0), secondary, start, length);
210 auto buffer_v = create_container_of_Index_size<std::vector<InputValue_> >(length);
211 std::vector<Pointer_> offset_copy(pointers + start, pointers + start + length);
213 for (InputIndex_ x = 0; x < secondary; ++x) {
214 const auto ptr = wrk->fetch(buffer_v.data());
215 for (InputIndex_ p = 0; p < length; ++p) {
216 const auto val = ptr[p];
218 auto& pos = offset_copy[p];
219 output_value[pos] = val;
220 output_index[pos] = x;
225 }, primary, threads);
259template<
typename Value_,
typename Index_,
typename Count_>
263 Count_*
const output,
266 const Index_ NR = matrix.
nrow();
267 const Index_ NC = matrix.
ncol();
268 const Index_ primary = (row ? NR : NC);
269 const Index_ secondary = (row ? NC : NR);
270 std::fill_n(output, primary, 0);
273 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_consistent(matrix, primary, secondary, row, output, options.
num_threads);
275 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_inconsistent(matrix, primary, secondary, row, output, options.
num_threads);
308template<
typename InputValue_,
typename InputIndex_,
typename Po
inter_,
typename StoredValue_,
typename StoredIndex_>
312 const Pointer_*
const pointers,
313 StoredValue_*
const output_value,
314 StoredIndex_*
const output_index,
317 const InputIndex_ NR = matrix.
nrow();
318 const InputIndex_ NC = matrix.
ncol();
319 const InputIndex_ primary = (row ? NR : NC);
320 const InputIndex_ secondary = (row ? NC : NR);
323 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_consistent(matrix, primary, secondary, row, pointers, output_value, output_index, options.
num_threads);
325 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_inconsistent(matrix, primary, secondary, row, pointers, output_value, output_index, options.
num_threads);
339template<
typename Value_,
typename Index_,
typename Po
inter_>
390template<
typename StoredValue_,
typename StoredIndex_,
typename StoredPo
inter_ = std::
size_t,
typename InputValue_,
typename InputIndex_>
399 auto& output_v = output.
value;
400 auto& output_i = output.
index;
403 const InputIndex_ NR = matrix.
nrow();
404 const InputIndex_ NC = matrix.
ncol();
405 const InputIndex_ primary = (row ? NR : NC);
406 const InputIndex_ secondary = (row ? NC : NR);
408 output_p.resize(sanisizer::sum<I<
decltype(output_p.size())> >(primary, 1));
421 const auto& store_v = frag.value;
422 const auto& store_i = frag.index;
424 for (InputIndex_ p = 0; p < primary; ++p) {
425 output_p[p + 1] = output_p[p] + store_v[p].size();
428 output_v.reserve(output_p.back());
429 output_i.reserve(output_p.back());
430 for (InputIndex_ p = 0; p < primary; ++p) {
431 output_v.insert(output_v.end(), store_v[p].begin(), store_v[p].end());
432 output_i.insert(output_i.end(), store_i[p].begin(), store_i[p].end());
437 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_consistent(matrix, primary, secondary, row, output_p.data() + 1, options.
num_threads);
438 for (InputIndex_ i = 1; i <= primary; ++i) {
439 output_p[i] += output_p[i - 1];
443 output_v.resize(output_p.back());
444 output_i.resize(output_p.back());
445 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_consistent(
458 convert_to_compressed_sparse_internal::count_compressed_sparse_non_zeros_inconsistent(matrix, primary, secondary, row, output_p.data() + 1, options.
num_threads);
459 for (InputIndex_ i = 1; i <= primary; ++i) {
460 output_p[i] += output_p[i - 1];
464 output_v.resize(output_p.back());
465 output_i.resize(output_p.back());
466 convert_to_compressed_sparse_internal::fill_compressed_sparse_matrix_inconsistent(
517 typename StoredValue_ = Value_,
518 typename StoredIndex_ = Index_,
519 typename StoredPointer_ = std::size_t,
520 typename InputValue_,
538 return std::shared_ptr<Matrix<Value_, Index_> >(
542 std::vector<StoredValue_>,
543 std::vector<StoredIndex_>,
544 std::vector<StoredPointer_>
548 std::move(comp.value),
549 std::move(comp.index),
550 std::move(comp.pointers),
553 CompressedSparseMatrixOptions copt;
565template<
typename Value_,
typename Index_,
typename Count_>
572 CountCompressedSparseNonZerosOptions copt;
573 copt.num_threads = threads;
579template<
typename InputValue_,
typename InputIndex_,
typename Po
inter_,
typename StoredValue_,
typename StoredIndex_>
582 const Pointer_* pointers,
583 StoredValue_* output_value,
584 StoredIndex_* output_index,
594 FillCompressedSparseContentsOptions fopt;
595 fopt.num_threads = threads;
601template<
typename StoredValue_,
typename StoredIndex_,
typename StoredPo
inter_ = std::
size_t,
typename InputValue_,
typename InputIndex_>
602CompressedSparseContents<StoredValue_, StoredIndex_, StoredPointer_>
retrieve_compressed_sparse_contents(
const Matrix<InputValue_, InputIndex_>* matrix,
bool row,
bool two_pass,
int threads = 1) {
607 RetrieveCompressedSparseContentsOptions opt;
608 opt.two_pass = two_pass;
609 opt.num_threads = threads;
615template<
typename Value_ =
double,
typename Index_ =
int,
typename StoredValue_ = Value_,
typename StoredIndex_ = Index_,
typename InputValue_,
typename InputIndex_>
616std::shared_ptr<Matrix<Value_, Index_> >
convert_to_compressed_sparse(
const Matrix<InputValue_, InputIndex_>* matrix,
bool row,
bool two_pass =
false,
int threads = 1) {
621 ConvertToCompressedSparseOptions opt;
622 opt.two_pass = two_pass;
623 opt.num_threads = threads;
629template <
bool row_,
typename Value_,
typename Index_,
typename InputValue_,
typename InputIndex_>
634template <
bool row_,
typename Value_,
typename Index_,
typename StoredValue_ = Value_,
typename StoredIndex_ = Index_,
typename InputValue_,
typename InputIndex_>
635std::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:581
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.
Copy data from one buffer to another.
Flexible representations for matrix data.
Definition Extractor.hpp:15
void count_compressed_sparse_non_zeros(const tatami::Matrix< Value_, Index_ > &matrix, const bool row, Count_ *const output, const CountCompressedSparseNonZerosOptions &options)
Definition convert_to_compressed_sparse.hpp:260
void parallelize(Function_ fun, const Index_ tasks, const int threads)
Definition parallelize.hpp:42
FragmentedSparseContents< StoredValue_, StoredIndex_ > retrieve_fragmented_sparse_contents(const Matrix< InputValue_, InputIndex_ > &matrix, const bool row, const RetrieveFragmentedSparseContentsOptions &options)
Definition convert_to_fragmented_sparse.hpp:82
CompressedSparseContents< StoredValue_, StoredIndex_, StoredPointer_ > retrieve_compressed_sparse_contents(const Matrix< InputValue_, InputIndex_ > &matrix, const bool row, const RetrieveCompressedSparseContentsOptions &options)
Definition convert_to_compressed_sparse.hpp:391
void fill_compressed_sparse_contents(const tatami::Matrix< InputValue_, InputIndex_ > &matrix, const bool row, const Pointer_ *const pointers, StoredValue_ *const output_value, StoredIndex_ *const output_index, const FillCompressedSparseContentsOptions &options)
Definition convert_to_compressed_sparse.hpp:309
std::shared_ptr< Matrix< Value_, Index_ > > convert_to_compressed_sparse(const Matrix< InputValue_, InputIndex_ > &matrix, const bool row, const ConvertToCompressedSparseOptions &options)
Definition convert_to_compressed_sparse.hpp:523
Parallelized iteration over a tatami::Matrix.
Compressed sparse contents.
Definition convert_to_compressed_sparse.hpp:340
std::vector< Index_ > index
Definition convert_to_compressed_sparse.hpp:349
std::vector< Value_ > value
Definition convert_to_compressed_sparse.hpp:344
std::vector< Pointer_ > pointers
Definition convert_to_compressed_sparse.hpp:354
Options for convert_to_compressed_sparse().
Definition convert_to_compressed_sparse.hpp:484
bool two_pass
Definition convert_to_compressed_sparse.hpp:489
int num_threads
Definition convert_to_compressed_sparse.hpp:494
Options for count_compressed_sparse_non_zeros().
Definition convert_to_compressed_sparse.hpp:237
int num_threads
Definition convert_to_compressed_sparse.hpp:241
Options for fill_compressed_sparse_contents().
Definition convert_to_compressed_sparse.hpp:282
int num_threads
Definition convert_to_compressed_sparse.hpp:286
Options for retrieve_compressed_sparse_contents().
Definition convert_to_compressed_sparse.hpp:360
int num_threads
Definition convert_to_compressed_sparse.hpp:370
bool two_pass
Definition convert_to_compressed_sparse.hpp:365
Options for retrieve_fragmented_sparse_contents().
Definition convert_to_fragmented_sparse.hpp:62
int num_threads
Definition convert_to_fragmented_sparse.hpp:66