tatami_chunked
Helpers to create custom chunked tatami matrices
Loading...
Searching...
No Matches
mock_dense_chunk.hpp
Go to the documentation of this file.
1#ifndef TATAMI_CHUNKED_MOCK_DENSE_CHUNK_HPP
2#define TATAMI_CHUNKED_MOCK_DENSE_CHUNK_HPP
3
4#include <vector>
5
11namespace tatami_chunked {
12
16namespace MockDenseChunk_internal {
17
18template<typename InflatedValue_>
19using Workspace = std::vector<InflatedValue_>;
20
21template<class Blob_>
22class Core {
23public:
24 Core() = default;
25
26 Core(Blob_ chunk) : my_chunk(std::move(chunk)) {}
27
28private:
29 Blob_ my_chunk;
30
31 typedef typename Blob_::value_type value_type;
32
33public:
34 auto get_target_chunkdim(bool row) const {
35 if (row) {
36 return my_chunk.nrow();
37 } else {
38 return my_chunk.ncol();
39 }
40 }
41
42 auto get_non_target_chunkdim(bool row) const {
43 if (row) {
44 return my_chunk.ncol();
45 } else {
46 return my_chunk.nrow();
47 }
48 }
49
50public:
51 template<typename Index_>
52 void extract(bool row, Index_ target_start, Index_ target_length, Index_ non_target_start, Index_ non_target_length, Workspace<value_type>& work, value_type* output, size_t stride) const {
53 my_chunk.inflate(work);
54 output += static_cast<size_t>(target_start) * stride; // cast to size_t to avoid overflow.
55
56 if (my_chunk.is_row_major() == row) {
57 size_t non_target_chunkdim = get_non_target_chunkdim(row); // use size_t to avoid integer overflow with Index_.
58 auto srcptr = work.data() + static_cast<size_t>(target_start) * non_target_chunkdim + static_cast<size_t>(non_target_start);
59 for (Index_ p = 0; p < target_length; ++p) {
60 std::copy_n(srcptr, non_target_length, output);
61 srcptr += non_target_chunkdim;
62 output += stride;
63 }
64
65 } else {
66 size_t target_chunkdim = get_target_chunkdim(row); // use size_t to avoid integer overflow with Index_.
67 auto srcptr = work.data() + static_cast<size_t>(non_target_start) * target_chunkdim + static_cast<size_t>(target_start);
68 for (Index_ p = 0; p < target_length; ++p) {
69 auto copy_srcptr = srcptr;
70 auto copy_output = output;
71 for (Index_ s = 0; s < non_target_length; ++s) {
72 *copy_output = *copy_srcptr;
73 ++copy_output;
74 copy_srcptr += target_chunkdim;
75 }
76 ++srcptr;
77 output += stride;
78 }
79 }
80 }
81
82 template<typename Index_>
83 void extract(bool row, Index_ target_start, Index_ target_length, const std::vector<Index_>& non_target_indices, Workspace<value_type>& work, value_type* output, size_t stride) const {
84 my_chunk.inflate(work);
85 output += static_cast<size_t>(target_start) * stride; // cast to size_t to avoid overflow.
86
87 if (my_chunk.is_row_major() == row) {
88 size_t non_target_chunkdim = get_non_target_chunkdim(row); // use size_t to avoid integer overflow with Index_.
89 auto srcptr = work.data() + static_cast<size_t>(target_start) * non_target_chunkdim;
90 for (Index_ p = 0; p < target_length; ++p) {
91 auto copy_output = output;
92 for (auto x : non_target_indices) {
93 *copy_output = srcptr[x];
94 ++copy_output;
95 }
96 srcptr += non_target_chunkdim;
97 output += stride;
98 }
99
100 } else {
101 size_t target_chunkdim = get_target_chunkdim(row); // use size_t to avoid integer overflow with Index_.
102 auto srcptr = work.data() + static_cast<size_t>(target_start);
103 for (Index_ p = 0; p < target_length; ++p) {
104 auto copy_output = output;
105 for (size_t x : non_target_indices) {
106 *copy_output = srcptr[x * target_chunkdim];
107 ++copy_output;
108 }
109 ++srcptr;
110 output += stride;
111 }
112 }
113 }
114
115public:
116 template<typename Index_>
117 void extract(bool row, const std::vector<Index_>& target_indices, Index_ non_target_start, Index_ non_target_length, Workspace<value_type>& work, value_type* output, size_t stride) const {
118 my_chunk.inflate(work);
119
120 if (my_chunk.is_row_major() == row) {
121 size_t non_target_chunkdim = get_non_target_chunkdim(row); // use size_t to avoid integer overflow with Index_.
122 size_t offset = non_target_start;
123 for (size_t p : target_indices) {
124 auto srcptr = work.data() + p * non_target_chunkdim + offset;
125 std::copy_n(srcptr, non_target_length, output + p * stride);
126 }
127
128 } else {
129 size_t target_chunkdim = get_target_chunkdim(row); // use size_t to avoid integer overflow with Index_.
130 auto srcptr = work.data() + static_cast<size_t>(non_target_start) * target_chunkdim;
131 for (size_t p : target_indices) {
132 auto copy_srcptr = srcptr + p;
133 auto copy_output = output + p * stride;
134 for (Index_ s = 0; s < non_target_length; ++s) {
135 *copy_output = *copy_srcptr;
136 ++copy_output;
137 copy_srcptr += target_chunkdim;
138 }
139 }
140 }
141 }
142
143 template<typename Index_>
144 void extract(bool row, const std::vector<Index_>& target_indices, const std::vector<Index_>& non_target_indices, Workspace<value_type>& work, value_type* output, size_t stride) const {
145 my_chunk.inflate(work);
146
147 if (my_chunk.is_row_major() == row) {
148 size_t non_target_chunkdim = get_non_target_chunkdim(row); // use size_t to avoid integer overflow with Index_.
149 for (size_t p : target_indices) {
150 auto srcptr = work.data() + p * non_target_chunkdim;
151 auto copy_output = output + p * stride;
152 for (auto x : non_target_indices) {
153 *copy_output = srcptr[x];
154 ++copy_output;
155 }
156 }
157
158 } else {
159 size_t target_chunkdim = get_target_chunkdim(row); // use size_t to avoid integer overflow with Index_.
160 for (size_t p : target_indices) {
161 auto srcptr = work.data() + p;
162 auto copy_output = output + p * stride;
163 for (size_t x : non_target_indices) {
164 *copy_output = srcptr[x * target_chunkdim];
165 ++copy_output;
166 }
167 }
168 }
169 }
170};
171
172class MockBlob {
173public:
174 MockBlob(std::vector<double> data, size_t nrow, size_t ncol) : my_data(std::move(data)), my_nrow(nrow), my_ncol(ncol) {}
175 MockBlob() = default;
176
177 typedef double value_type;
178
179 bool is_row_major() const {
180 return true;
181 }
182
183private:
184 std::vector<double> my_data;
185 size_t my_nrow;
186 size_t my_ncol;
187
188public:
189 size_t nrow() const {
190 return my_nrow;
191 }
192
193 size_t ncol() const {
194 return my_ncol;
195 }
196
197 void inflate(std::vector<double>& buffer) const {
198 buffer.resize(my_data.size());
199 std::copy(my_data.begin(), my_data.end(), buffer.begin());
200 }
201};
202
203}
217public:
222 typedef double value_type;
223
229 struct Workspace {
233 MockDenseChunk_internal::Workspace<value_type> work;
237 };
238
243 static constexpr bool use_subset = false;
244
245public:
249 // You can construct this however you like, I don't care.
250 MockSimpleDenseChunk() = default;
251 MockSimpleDenseChunk(std::vector<double> core, size_t nrow, size_t ncol) : my_core(MockDenseChunk_internal::MockBlob(std::move(core), nrow, ncol)) {}
256private:
257 MockDenseChunk_internal::Core<MockDenseChunk_internal::MockBlob> my_core;
258
259public:
285 template<typename Index_>
287 my_core.template extract<Index_>(row, 0, my_core.get_target_chunkdim(row), non_target_start, non_target_length, work.work, output, stride);
288 }
289
313 template<typename Index_>
314 void extract(bool row, const std::vector<Index_>& non_target_indices, Workspace& work, value_type* output, size_t stride) const {
315 my_core.template extract<Index_>(row, 0, my_core.get_target_chunkdim(row), non_target_indices, work.work, output, stride);
316 }
317};
318
338template<class Blob_>
340public:
344 typedef typename Blob_::value_type value_type;
345
346 typedef MockDenseChunk_internal::Workspace<value_type> Workspace;
347
348 static constexpr bool use_subset = false;
349
350 SimpleDenseChunkWrapper() = default;
351
352 SimpleDenseChunkWrapper(Blob_ core) : my_core(std::move(core)) {}
357private:
358 MockDenseChunk_internal::Core<Blob_> my_core;
359
360public:
364 template<typename Index_>
365 void extract(bool row, Index_ non_target_start, Index_ non_target_length, Workspace& work, value_type* output, size_t stride) const {
366 my_core.extract(row, 0, my_core.get_target_chunkdim(row), non_target_start, non_target_length, work, output, stride);
367 }
368
369 template<typename Index_>
370 void extract(bool row, const std::vector<Index_>& non_target_indices, Workspace& work, value_type* output, size_t stride) const {
371 my_core.extract(row, 0, my_core.get_target_chunkdim(row), non_target_indices, work, output, stride);
372 }
376};
377
389public:
394 typedef double value_type;
395
401 struct Workspace {
405 MockDenseChunk_internal::Workspace<value_type> work;
409 };
410
415 static constexpr bool use_subset = true;
416
420 MockSubsettedDenseChunk() = default;
421 MockSubsettedDenseChunk(std::vector<double> core, size_t nrow, size_t ncol) : my_core(MockDenseChunk_internal::MockBlob(std::move(core), nrow, ncol)) {}
426private:
427 MockDenseChunk_internal::Core<MockDenseChunk_internal::MockBlob> my_core;
428
429public:
459 template<typename Index_>
463
491 template<typename Index_>
492 void extract(bool row, Index_ target_start, Index_ target_length, const std::vector<Index_>& non_target_indices, Workspace& work, value_type* output, size_t stride) const {
494 }
495
496public:
524 template<typename Index_>
525 void extract(bool row, const std::vector<Index_>& target_indices, Index_ non_target_start, Index_ non_target_length, Workspace& work, value_type* output, size_t stride) const {
527 }
528
554 template<typename Index_>
555 void extract(bool row, const std::vector<Index_>& target_indices, const std::vector<Index_>& non_target_indices, Workspace& work, value_type* output, size_t stride) const {
556 my_core.extract(row, target_indices, non_target_indices, work.work, output, stride);
557 }
558};
559
560}
561
562#endif
Mock a simple dense chunk for a CustomDenseChunkedMatrix.
Definition mock_dense_chunk.hpp:216
double value_type
Definition mock_dense_chunk.hpp:222
void extract(bool row, Index_ non_target_start, Index_ non_target_length, Workspace &work, value_type *output, size_t stride) const
Definition mock_dense_chunk.hpp:286
static constexpr bool use_subset
Definition mock_dense_chunk.hpp:243
void extract(bool row, const std::vector< Index_ > &non_target_indices, Workspace &work, value_type *output, size_t stride) const
Definition mock_dense_chunk.hpp:314
Mock a subsettable dense chunk for a CustomDenseChunkedMatrix.
Definition mock_dense_chunk.hpp:388
void extract(bool row, Index_ target_start, Index_ target_length, Index_ non_target_start, Index_ non_target_length, Workspace &work, value_type *output, size_t stride) const
Definition mock_dense_chunk.hpp:460
void extract(bool row, const std::vector< Index_ > &target_indices, const std::vector< Index_ > &non_target_indices, Workspace &work, value_type *output, size_t stride) const
Definition mock_dense_chunk.hpp:555
static constexpr bool use_subset
Definition mock_dense_chunk.hpp:415
void extract(bool row, const std::vector< Index_ > &target_indices, Index_ non_target_start, Index_ non_target_length, Workspace &work, value_type *output, size_t stride) const
Definition mock_dense_chunk.hpp:525
void extract(bool row, Index_ target_start, Index_ target_length, const std::vector< Index_ > &non_target_indices, Workspace &work, value_type *output, size_t stride) const
Definition mock_dense_chunk.hpp:492
double value_type
Definition mock_dense_chunk.hpp:394
Create a dense chunk for a CustomDenseChunkedMatrix.
Definition mock_dense_chunk.hpp:339
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_dense_chunk.hpp:229
Definition mock_dense_chunk.hpp:401