1#ifndef TATAMI_CHUNKED_MOCK_SPARSE_CHUNK_HPP
2#define TATAMI_CHUNKED_MOCK_SPARSE_CHUNK_HPP
17namespace MockSparseChunk_internal {
19template<
typename InflatedValue_,
typename InflatedIndex_>
22 std::vector<InflatedValue_> values;
23 std::vector<InflatedIndex_> indices;
24 std::vector<size_t> indptrs;
28 std::vector<uint8_t> remap;
36 Core(Blob_ chunk) : my_chunk(std::move(chunk)) {}
41 typedef typename Blob_::value_type value_type;
43 typedef typename Blob_::index_type index_type;
46 auto get_target_chunkdim(
bool row)
const {
48 return my_chunk.nrow();
50 return my_chunk.ncol();
54 auto get_non_target_chunkdim(
bool row)
const {
56 return my_chunk.ncol();
58 return my_chunk.nrow();
62 typedef Workspace<value_type, index_type> MyWorkspace;
65 template<
typename Index_>
66 static void refine_start_and_end(
size_t& start,
size_t& end, Index_ desired_start, Index_ desired_end, Index_ max_end,
const std::vector<index_type>& indices) {
68 auto it = indices.begin();
70 start = std::lower_bound(it + start, it + end, desired_start, [](Index_ a, Index_ b) ->
bool {
return a < b; }) - it;
73 if (desired_end != max_end) {
74 if (desired_end == desired_start + 1) {
75 if (start != end &&
static_cast<Index_
>(indices[start]) == desired_start) {
81 auto it = indices.begin();
82 end = std::lower_bound(it + start, it + end, desired_end, [](Index_ a, Index_ b) ->
bool {
return a < b; }) - it;
88 template<
typename Index_>
89 static void configure_remap(MyWorkspace& work,
const std::vector<Index_>& indices,
size_t full) {
90 work.remap.resize(full);
91 for (
auto i : indices) {
97 template<
typename Index_>
98 static void reset_remap(MyWorkspace& work,
const std::vector<Index_>& indices) {
99 for (
auto i : indices) {
105 template<
bool is_block_,
typename Index_>
108 Index_ non_target_start,
109 Index_ non_target_end,
110 Index_ non_target_chunkdim,
112 const std::vector<value_type*>& output_values,
113 const std::vector<Index_*>& output_indices,
114 Index_* output_number,
117 size_t start = work.indptrs[p], end = work.indptrs[p + 1];
122 refine_start_and_end(start, end, non_target_start, non_target_end, non_target_chunkdim, work.indices);
124 auto& current_number = output_number[p];
125 const bool needs_value = !output_values.empty();
126 auto vptr = needs_value ? output_values[p] + current_number : NULL;
127 const bool needs_index = !output_indices.empty();
128 auto iptr = needs_index ? output_indices[p] + current_number : NULL;
130 if constexpr(is_block_) {
132 std::copy(work.values.begin() + start, work.values.begin() + end, vptr);
135 for (
size_t i = start; i < end; ++i, ++iptr) {
136 *iptr = work.indices[i] + shift;
139 current_number += end - start;
143 for (
size_t i = start; i < end; ++i) {
144 Index_ target = work.indices[i];
145 if (work.remap[target]) {
147 *vptr = work.values[i];
151 *iptr = target + shift;
160 template<
bool is_block_,
typename Index_>
165 Index_ target_chunkdim,
167 const std::vector<value_type*>& output_values,
168 const std::vector<Index_*>& output_indices,
169 Index_* output_number,
172 auto start = work.indptrs[s], end = work.indptrs[s + 1];
177 refine_start_and_end(start, end, target_start, target_end, target_chunkdim, work.indices);
179 bool needs_value = !output_values.empty();
180 bool needs_index = !output_indices.empty();
182 if constexpr(is_block_) {
183 for (
size_t i = start; i < end; ++i) {
184 auto p = work.indices[i];
185 auto& num = output_number[p];
187 output_values[p][num] = work.values[i];
190 output_indices[p][num] = s + shift;
197 for (
size_t i = start; i < end; ++i) {
198 Index_ target = work.indices[i];
199 if (work.remap[target]) {
200 auto& num = output_number[target];
202 output_values[target][num] = work.values[i];
205 output_indices[target][num] = s + shift;
214 template<
typename Index_>
218 Index_ target_length,
219 Index_ non_target_start,
220 Index_ non_target_length,
222 const std::vector<value_type*>& output_values,
223 const std::vector<Index_*>& output_indices,
224 Index_* output_number,
227 my_chunk.inflate(work.values, work.indices, work.indptrs);
228 Index_ target_end = target_start + target_length;
229 Index_ non_target_end = non_target_start + non_target_length;
231 if (my_chunk.is_csr() == row) {
232 Index_ non_target_chunkdim = get_non_target_chunkdim(row);
233 for (Index_ p = target_start; p < target_end; ++p) {
234 fill_target<true>(p, non_target_start, non_target_end, non_target_chunkdim, work, output_values, output_indices, output_number, shift);
237 Index_ target_chunkdim = get_target_chunkdim(row);
238 for (Index_ s = non_target_start; s < non_target_end; ++s) {
239 fill_secondary<true>(s, target_start, target_end, target_chunkdim, work, output_values, output_indices, output_number, shift);
244 template<
typename Index_>
248 Index_ target_length,
249 const std::vector<Index_>& non_target_indices,
251 const std::vector<value_type*>& output_values,
252 const std::vector<Index_*>& output_indices,
253 Index_* output_number,
256 my_chunk.inflate(work.values, work.indices, work.indptrs);
257 Index_ target_end = target_start + target_length;
259 if (my_chunk.is_csr() == row) {
261 auto non_target_start = non_target_indices.front();
262 auto non_target_end = non_target_indices.back() + 1;
263 auto non_target_chunkdim = get_non_target_chunkdim(row);
265 configure_remap(work, non_target_indices, non_target_chunkdim);
266 for (Index_ p = target_start; p < target_end; ++p) {
267 fill_target<false>(p, non_target_start, non_target_end, non_target_chunkdim, work, output_values, output_indices, output_number, shift);
269 reset_remap(work, non_target_indices);
272 Index_ target_chunkdim = get_target_chunkdim(row);
273 for (
auto s : non_target_indices) {
274 fill_secondary<true>(s, target_start, target_end, target_chunkdim, work, output_values, output_indices, output_number, shift);
280 template<
typename Index_>
283 const std::vector<Index_>& target_indices,
284 Index_ non_target_start,
285 Index_ non_target_length,
287 const std::vector<value_type*>& output_values,
288 const std::vector<Index_*>& output_indices,
289 Index_* output_number,
292 my_chunk.inflate(work.values, work.indices, work.indptrs);
293 Index_ non_target_end = non_target_start + non_target_length;
295 if (my_chunk.is_csr() == row) {
296 Index_ non_target_chunkdim = get_non_target_chunkdim(row);
297 for (
auto p : target_indices) {
298 fill_target<true>(p, non_target_start, non_target_end, non_target_chunkdim, work, output_values, output_indices, output_number, shift);
303 auto target_start = target_indices.front();
304 auto target_end = target_indices.back() + 1;
305 auto target_chunkdim = get_target_chunkdim(row);
307 configure_remap(work, target_indices, target_chunkdim);
308 for (Index_ s = non_target_start; s < non_target_end; ++s) {
309 fill_secondary<false>(s, target_start, target_end, target_chunkdim, work, output_values, output_indices, output_number, shift);
311 reset_remap(work, target_indices);
315 template<
typename Index_>
318 const std::vector<Index_>& target_indices,
319 const std::vector<Index_>& non_target_indices,
321 const std::vector<value_type*>& output_values,
322 const std::vector<Index_*>& output_indices,
323 Index_* output_number,
326 my_chunk.inflate(work.values, work.indices, work.indptrs);
328 if (my_chunk.is_csr() == row) {
330 auto non_target_start = non_target_indices.front();
331 auto non_target_end = non_target_indices.back() + 1;
332 auto non_target_chunkdim = get_non_target_chunkdim(row);
334 configure_remap(work, non_target_indices, non_target_chunkdim);
335 for (
auto p : target_indices) {
336 fill_target<false>(p, non_target_start, non_target_end, non_target_chunkdim, work, output_values, output_indices, output_number, shift);
338 reset_remap(work, non_target_indices);
342 auto target_start = target_indices.front();
343 auto target_end = target_indices.back() + 1;
344 auto target_chunkdim = get_target_chunkdim(row);
346 configure_remap(work, target_indices, target_chunkdim);
347 for (
auto s : non_target_indices) {
348 fill_secondary<false>(s, target_start, target_end, target_chunkdim, work, output_values, output_indices, output_number, shift);
350 reset_remap(work, target_indices);
357 typedef int index_type;
358 typedef double value_type;
360 bool is_csr()
const {
365 int my_nrow, my_ncol;
366 std::vector<double> my_values;
367 std::vector<int> my_indices;
368 std::vector<size_t> my_pointers;
371 MockBlob() =
default;
373 MockBlob(
int nrow,
int ncol, std::vector<double> values, std::vector<int> indices, std::vector<size_t> pointers) :
374 my_nrow(nrow), my_ncol(ncol), my_values(std::move(values)), my_indices(std::move(indices)), my_pointers(std::move(pointers)) {}
384 void inflate(std::vector<double>& vbuffer, std::vector<int>& ibuffer, std::vector<size_t>& pbuffer)
const {
385 vbuffer.resize(my_values.size());
386 std::copy(my_values.begin(), my_values.end(), vbuffer.begin());
387 ibuffer.resize(my_indices.size());
388 std::copy(my_indices.begin(), my_indices.end(), ibuffer.begin());
389 pbuffer.resize(my_pointers.size());
390 std::copy(my_pointers.begin(), my_pointers.end(), pbuffer.begin());
425 MockSparseChunk_internal::Workspace<value_type, int>
work;
450 MockSparseChunk_internal::Core<MockSparseChunk_internal::MockBlob> core;
487 template<
typename Index_>
501 core.get_target_chunkdim(
row),
544 template<
typename Index_>
557 core.get_target_chunkdim(
row),
596 typedef typename Blob_::value_type value_type;
598 typedef MockSparseChunk_internal::Workspace<value_type, typename Blob_::index_type> Workspace;
600 static constexpr bool use_subset =
false;
607 MockSparseChunk_internal::Core<Blob_> my_core;
610 template<
typename Index_>
624 my_core.get_target_chunkdim(
row),
635 template<
typename Index_>
648 my_core.get_target_chunkdim(
row),
690 MockSparseChunk_internal::Workspace<value_type, int>
work;
706 MockSubsettedSparseChunk(
int nrow,
int ncol, std::vector<double> values, std::vector<int> indices, std::vector<size_t> pointers) :
713 MockSparseChunk_internal::Core<MockSparseChunk_internal::MockBlob> my_core;
755 template<
typename Index_>
819 template<
typename Index_>
882 template<
typename Index_>
942 template<
typename Index_>
Mock a simple sparse chunk for a CustomSparseChunkedMatrix.
Definition mock_sparse_chunk.hpp:407
static constexpr bool use_subset
Definition mock_sparse_chunk.hpp:435
double value_type
Definition mock_sparse_chunk.hpp:413
void extract(bool row, Index_ non_target_start, Index_ non_target_length, Workspace &work, const std::vector< value_type * > &output_values, const std::vector< Index_ * > &output_indices, Index_ *output_number, Index_ shift) const
Definition mock_sparse_chunk.hpp:488
void extract(bool row, const std::vector< Index_ > &non_target_indices, Workspace &work, const std::vector< value_type * > &output_values, const std::vector< Index_ * > &output_indices, Index_ *output_number, Index_ shift) const
Definition mock_sparse_chunk.hpp:545
Mock a subsettable sparse chunk for a CustomSparseChunkedMatrix.
Definition mock_sparse_chunk.hpp:672
void extract(bool row, const std::vector< Index_ > &target_indices, Index_ non_target_start, Index_ non_target_length, Workspace &work, const std::vector< value_type * > &output_values, const std::vector< Index_ * > &output_indices, Index_ *output_number, Index_ shift) const
Definition mock_sparse_chunk.hpp:883
void extract(bool row, Index_ target_start, Index_ target_length, const std::vector< Index_ > &non_target_indices, Workspace &work, const std::vector< value_type * > &output_values, const std::vector< Index_ * > &output_indices, Index_ *output_number, Index_ shift) const
Definition mock_sparse_chunk.hpp:820
void extract(bool row, Index_ target_start, Index_ target_length, Index_ non_target_start, Index_ non_target_length, Workspace &work, const std::vector< value_type * > &output_values, const std::vector< Index_ * > &output_indices, Index_ *output_number, Index_ shift) const
Definition mock_sparse_chunk.hpp:756
double value_type
Definition mock_sparse_chunk.hpp:678
void extract(bool row, const std::vector< Index_ > &target_indices, const std::vector< Index_ > &non_target_indices, Workspace &work, const std::vector< value_type * > &output_values, const std::vector< Index_ * > &output_indices, Index_ *output_number, Index_ shift) const
Definition mock_sparse_chunk.hpp:943
static constexpr bool use_subset
Definition mock_sparse_chunk.hpp:700
Create a sparse chunk for a CustomSparseChunkedMatrix.
Definition mock_sparse_chunk.hpp:591
Methods to handle chunked tatami matrices.
Definition ChunkDimensionStats.hpp:4
Statistics for regular chunks along a dimension.
Definition ChunkDimensionStats.hpp:35
ChunkDimensionStats()
Definition ChunkDimensionStats.hpp:50
Definition mock_sparse_chunk.hpp:420
Definition mock_sparse_chunk.hpp:685