tatami
C++ API for different matrix representations
Loading...
Searching...
No Matches
DelayedSubsetSortedUnique.hpp
Go to the documentation of this file.
1#ifndef TATAMI_DELAYED_SUBSET_SORTED_UNIQUE_HPP
2#define TATAMI_DELAYED_SUBSET_SORTED_UNIQUE_HPP
3
4#include <algorithm>
5#include <memory>
6
7#include "../base/Matrix.hpp"
8#include "../utils/copy.hpp"
9#include "utils.hpp"
10
17namespace tatami {
18
22namespace DelayedSubsetSortedUnique_internal {
23
24template<typename Index_, class SubsetStorage_>
25VectorPtr<Index_> create(const SubsetStorage_& subset) {
26 return std::make_shared<std::vector<Index_> >(subset.begin(), subset.end());
27}
28
29template<typename Index_, class SubsetStorage_>
30VectorPtr<Index_> create(const SubsetStorage_& subset, const Index_ block_start, const Index_ block_length) {
31 auto pistart = subset.begin() + block_start;
32 return std::make_shared<std::vector<Index_> >(pistart, pistart + block_length);
33}
34
35template<typename Index_, class SubsetStorage_>
36VectorPtr<Index_> create(const SubsetStorage_& subset, const VectorPtr<Index_>& indices_ptr) {
37 auto rawptr = new std::vector<Index_>;
38 VectorPtr<Index_> outptr(rawptr);
39 auto& output = *rawptr;
40
41 const auto& input = *indices_ptr;
42 output.reserve(input.size());
43 for (auto i : input) {
44 output.push_back(subset[i]);
45 }
46
47 return outptr;
48}
49
50template<bool oracle_, typename Value_, typename Index_, class SubsetStorage_>
51std::unique_ptr<DenseExtractor<oracle_, Value_, Index_> > create_parallel_dense(
52 const Matrix<Value_, Index_>& matrix,
53 const SubsetStorage_& subset,
54 const bool row,
55 MaybeOracle<oracle_, Index_> oracle,
56 const Options& opt
57) {
58 return new_extractor<false, oracle_>(matrix, row, std::move(oracle), create<Index_>(subset), opt);
59}
60
61template<bool oracle_, typename Value_, typename Index_, class SubsetStorage_>
62std::unique_ptr<DenseExtractor<oracle_, Value_, Index_> > create_parallel_dense(
63 const Matrix<Value_, Index_>& matrix,
64 const SubsetStorage_& subset,
65 const bool row,
66 MaybeOracle<oracle_, Index_> oracle,
67 const Index_ block_start,
68 const Index_ block_length,
69 const Options& opt)
70{
71 return new_extractor<false, oracle_>(matrix, row, std::move(oracle), create<Index_>(subset, block_start, block_length), opt);
72}
73
74template<bool oracle_, typename Value_, typename Index_, class SubsetStorage_>
75std::unique_ptr<DenseExtractor<oracle_, Value_, Index_> > create_parallel_dense(
76 const Matrix<Value_, Index_>& matrix,
77 const SubsetStorage_& subset,
78 const bool row,
79 MaybeOracle<oracle_, Index_> oracle,
80 VectorPtr<Index_> indices_ptr,
81 const Options& opt)
82{
83 return new_extractor<false, oracle_>(matrix, row, std::move(oracle), create<Index_>(subset, indices_ptr), opt);
84}
85
86template<bool oracle_, typename Value_, typename Index_>
87class ParallelSparse final : public SparseExtractor<oracle_, Value_, Index_> {
88public:
89 template<class SubsetStorage_>
90 ParallelSparse(
91 const Matrix<Value_, Index_>& matrix,
92 const SubsetStorage_& subset,
93 const std::vector<Index_>& remap,
94 const bool row,
95 MaybeOracle<oracle_, Index_> oracle,
96 const Options& opt
97 ) :
98 my_ext(new_extractor<true, oracle_>(matrix, row, std::move(oracle), create<Index_>(subset), opt)),
99 my_remapping(remap)
100 {}
101
102 template<class SubsetStorage_>
103 ParallelSparse(
104 const Matrix<Value_, Index_>& matrix,
105 const SubsetStorage_& subset,
106 const std::vector<Index_>& remap,
107 const bool row,
108 MaybeOracle<oracle_, Index_> oracle,
109 const Index_ block_start,
110 const Index_ block_length,
111 const Options& opt
112 ) :
113 my_ext(new_extractor<true, oracle_>(matrix, row, std::move(oracle), create<Index_>(subset, block_start, block_length), opt)),
114 my_remapping(remap)
115 {}
116
117 template<class SubsetStorage_>
118 ParallelSparse(
119 const Matrix<Value_, Index_>& matrix,
120 const SubsetStorage_& subset,
121 const std::vector<Index_>& remap,
122 const bool row,
123 MaybeOracle<oracle_, Index_> oracle,
124 VectorPtr<Index_> indices_ptr,
125 const Options& opt
126 ) :
127 my_ext(new_extractor<true, oracle_>(matrix, row, std::move(oracle), create<Index_>(subset, indices_ptr), opt)),
128 my_remapping(remap)
129 {}
130
131public:
132 SparseRange<Value_, Index_> fetch(const Index_ i, Value_* const value_buffer, Index_* const index_buffer) {
133 auto out = my_ext->fetch(i, value_buffer, index_buffer);
134 if (out.index) {
135 for (Index_ i = 0; i < out.number; ++i) {
136 index_buffer[i] = my_remapping[out.index[i]];
137 }
138 out.index = index_buffer;
139 }
140 return out;
141 }
142
143private:
144 std::unique_ptr<SparseExtractor<oracle_, Value_, Index_> > my_ext;
145 const std::vector<Index_>& my_remapping;
146};
147
148}
163template<typename Value_, typename Index_, class SubsetStorage_>
164class DelayedSubsetSortedUnique final : public Matrix<Value_, Index_> {
165public:
175 std::shared_ptr<const Matrix<Value_, Index_> > matrix,
176 SubsetStorage_ subset,
177 const bool by_row,
178 const bool check = true
179 ) :
180 my_matrix(std::move(matrix)),
181 my_subset(std::move(subset)),
182 my_by_row(by_row)
183 {
184 const auto nsub = my_subset.size();
185 if (check) {
186 for (I<decltype(nsub)> i = 1; i < nsub; ++i) {
187 if (my_subset[i] <= my_subset[i-1]) {
188 throw std::runtime_error("subset should be unique and sorted");
189 }
190 }
191 }
192
193 const Index_ mapping_dim = my_by_row ? my_matrix->nrow() : my_matrix->ncol();
194 resize_container_to_Index_size(my_mapping_single, mapping_dim);
195 for (I<decltype(nsub)> i = 0; i < nsub; ++i) {
196 my_mapping_single[my_subset[i]] = i;
197 }
198 }
199
200private:
201 std::shared_ptr<const Matrix<Value_, Index_> > my_matrix;
202 SubsetStorage_ my_subset;
203 bool my_by_row;
204 std::vector<Index_> my_mapping_single;
205
206public:
207 Index_ nrow() const {
208 if (my_by_row) {
209 return my_subset.size();
210 } else {
211 return my_matrix->nrow();
212 }
213 }
214
215 Index_ ncol() const {
216 if (my_by_row) {
217 return my_matrix->ncol();
218 } else {
219 return my_subset.size();
220 }
221 }
222
223 bool is_sparse() const {
224 return my_matrix->is_sparse();
225 }
226
227 double is_sparse_proportion() const {
228 return my_matrix->is_sparse_proportion();
229 }
230
231 bool prefer_rows() const {
232 return my_matrix->prefer_rows();
233 }
234
235 double prefer_rows_proportion() const {
236 return my_matrix->prefer_rows_proportion();
237 }
238
239 bool uses_oracle(const bool row) const {
240 return my_matrix->uses_oracle(row);
241 }
242
243 using Matrix<Value_, Index_>::dense;
244
245 using Matrix<Value_, Index_>::sparse;
246
247 /********************
248 *** Myopic dense ***
249 ********************/
250private:
251 template<typename ... Args_>
252 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > populate_myopic_dense(
253 const bool row,
254 Args_&& ... args
255 ) const {
256 if (row == my_by_row) {
257 return std::make_unique<subset_utils::MyopicPerpendicularDense<Value_, Index_, SubsetStorage_> >(
258 *my_matrix,
259 my_subset,
260 row,
261 std::forward<Args_>(args)...
262 );
263 } else {
264 return DelayedSubsetSortedUnique_internal::create_parallel_dense<false>(
265 *my_matrix,
266 my_subset,
267 row,
268 false,
269 std::forward<Args_>(args)...
270 );
271 }
272 }
273
274public:
275 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(
276 const bool row,
277 const Options& opt
278 ) const {
279 return populate_myopic_dense(row, opt);
280 }
281
282 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(
283 const bool row,
284 const Index_ block_start,
285 const Index_ block_length,
286 const Options& opt
287 ) const {
288 return populate_myopic_dense(row, block_start, block_length, opt);
289 }
290
291 std::unique_ptr<MyopicDenseExtractor<Value_, Index_> > dense(
292 const bool row,
293 VectorPtr<Index_> indices_ptr,
294 const Options& opt
295 ) const {
296 return populate_myopic_dense(row, std::move(indices_ptr), opt);
297 }
298
299 /*********************
300 *** Myopic sparse ***
301 *********************/
302private:
303 template<typename ... Args_>
304 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > populate_myopic_sparse(
305 const bool row,
306 Args_&& ... args
307 ) const {
308 if (row == my_by_row) {
309 return std::make_unique<subset_utils::MyopicPerpendicularSparse<Value_, Index_, SubsetStorage_> >(
310 *my_matrix,
311 my_subset,
312 row,
313 std::forward<Args_>(args)...
314 );
315 } else {
316 return std::make_unique<DelayedSubsetSortedUnique_internal::ParallelSparse<false, Value_, Index_> >(
317 *my_matrix,
318 my_subset,
319 my_mapping_single,
320 row,
321 false,
322 std::forward<Args_>(args)...
323 );
324 }
325 }
326
327public:
328 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
329 const bool row,
330 const Options& opt
331 ) const {
332 return populate_myopic_sparse(row, opt);
333 }
334
335 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
336 const bool row,
337 const Index_ block_start,
338 const Index_ block_length,
339 const Options& opt
340 ) const {
341 return populate_myopic_sparse(row, block_start, block_length, opt);
342 }
343
344 std::unique_ptr<MyopicSparseExtractor<Value_, Index_> > sparse(
345 const bool row,
346 VectorPtr<Index_> indices_ptr,
347 const Options& opt
348 ) const {
349 return populate_myopic_sparse(row, std::move(indices_ptr), opt);
350 }
351
352 /**********************
353 *** Oracular dense ***
354 **********************/
355private:
356 template<typename ... Args_>
357 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > populate_oracular_dense(
358 const bool row,
359 std::shared_ptr<const Oracle<Index_> > oracle,
360 Args_&& ... args
361 ) const {
362 if (row == my_by_row) {
363 return std::make_unique<subset_utils::OracularPerpendicularDense<Value_, Index_> >(
364 *my_matrix,
365 my_subset,
366 row,
367 std::move(oracle),
368 std::forward<Args_>(args)...
369 );
370 } else {
371 return DelayedSubsetSortedUnique_internal::create_parallel_dense<true>(
372 *my_matrix,
373 my_subset,
374 row,
375 std::move(oracle),
376 std::forward<Args_>(args)...
377 );
378 }
379 }
380
381public:
382 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(
383 const bool row,
384 std::shared_ptr<const Oracle<Index_> > oracle,
385 const Options& opt
386 ) const {
387 return populate_oracular_dense(row, std::move(oracle), opt);
388 }
389
390 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(
391 const bool row,
392 std::shared_ptr<const Oracle<Index_> > oracle,
393 const Index_ block_start,
394 const Index_ block_length,
395 const Options& opt
396 ) const {
397 return populate_oracular_dense(row, std::move(oracle), block_start, block_length, opt);
398 }
399
400 std::unique_ptr<OracularDenseExtractor<Value_, Index_> > dense(
401 const bool row,
402 std::shared_ptr<const Oracle<Index_> > oracle,
403 VectorPtr<Index_> indices_ptr,
404 const Options& opt
405 ) const {
406 return populate_oracular_dense(row, std::move(oracle), std::move(indices_ptr), opt);
407 }
408
409 /***********************
410 *** Oracular sparse ***
411 ***********************/
412private:
413 template<typename ... Args_>
414 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > populate_oracular_sparse(
415 const bool row,
416 std::shared_ptr<const Oracle<Index_> > oracle,
417 Args_&& ... args
418 ) const {
419 if (row == my_by_row) {
420 return std::make_unique<subset_utils::OracularPerpendicularSparse<Value_, Index_> >(
421 *my_matrix,
422 my_subset,
423 row,
424 std::move(oracle),
425 std::forward<Args_>(args)...
426 );
427 } else {
428 return std::make_unique<DelayedSubsetSortedUnique_internal::ParallelSparse<true, Value_, Index_> >(
429 *my_matrix,
430 my_subset,
431 my_mapping_single,
432 row,
433 std::move(oracle),
434 std::forward<Args_>(args)...
435 );
436 }
437 }
438
439public:
440 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
441 const bool row,
442 std::shared_ptr<const Oracle<Index_> > oracle,
443 const Options& opt
444 ) const {
445 return populate_oracular_sparse(row, std::move(oracle), opt);
446 }
447
448 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
449 const bool row,
450 std::shared_ptr<const Oracle<Index_> > oracle,
451 const Index_ block_start,
452 const Index_ block_length,
453 const Options& opt
454 ) const {
455 return populate_oracular_sparse(row, std::move(oracle), block_start, block_length, opt);
456 }
457
458 std::unique_ptr<OracularSparseExtractor<Value_, Index_> > sparse(
459 const bool row,
460 std::shared_ptr<const Oracle<Index_> > oracle,
461 VectorPtr<Index_> indices_ptr,
462 const Options& opt
463 ) const {
464 return populate_oracular_sparse(row, std::move(oracle), std::move(indices_ptr), opt);
465 }
466};
467
468}
469
470#endif
Virtual class for a matrix of some numeric type.
Delayed subsetting of a matrix with sorted, unique indices.
Definition DelayedSubsetSortedUnique.hpp:164
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Index_ block_start, const Index_ block_length, const Options &opt) const
Definition DelayedSubsetSortedUnique.hpp:390
Index_ ncol() const
Definition DelayedSubsetSortedUnique.hpp:215
double prefer_rows_proportion() const
Definition DelayedSubsetSortedUnique.hpp:235
bool uses_oracle(const bool row) const
Definition DelayedSubsetSortedUnique.hpp:239
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(const bool row, const Index_ block_start, const Index_ block_length, const Options &opt) const
Definition DelayedSubsetSortedUnique.hpp:335
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(const bool row, const Index_ block_start, const Index_ block_length, const Options &opt) const
Definition DelayedSubsetSortedUnique.hpp:282
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedSubsetSortedUnique.hpp:440
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(const bool row, const Options &opt) const
Definition DelayedSubsetSortedUnique.hpp:328
double is_sparse_proportion() const
Definition DelayedSubsetSortedUnique.hpp:227
Index_ nrow() const
Definition DelayedSubsetSortedUnique.hpp:207
DelayedSubsetSortedUnique(std::shared_ptr< const Matrix< Value_, Index_ > > matrix, SubsetStorage_ subset, const bool by_row, const bool check=true)
Definition DelayedSubsetSortedUnique.hpp:174
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(const bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetSortedUnique.hpp:291
std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(const bool row, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetSortedUnique.hpp:344
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetSortedUnique.hpp:400
bool is_sparse() const
Definition DelayedSubsetSortedUnique.hpp:223
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Index_ block_start, const Index_ block_length, const Options &opt) const
Definition DelayedSubsetSortedUnique.hpp:448
std::unique_ptr< MyopicDenseExtractor< Value_, Index_ > > dense(const bool row, const Options &opt) const
Definition DelayedSubsetSortedUnique.hpp:275
std::unique_ptr< OracularSparseExtractor< Value_, Index_ > > sparse(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, VectorPtr< Index_ > indices_ptr, const Options &opt) const
Definition DelayedSubsetSortedUnique.hpp:458
bool prefer_rows() const
Definition DelayedSubsetSortedUnique.hpp:231
std::unique_ptr< OracularDenseExtractor< Value_, Index_ > > dense(const bool row, std::shared_ptr< const Oracle< Index_ > > oracle, const Options &opt) const
Definition DelayedSubsetSortedUnique.hpp:382
Virtual class for a matrix.
Definition Matrix.hpp:59
Predict future access requests on the target dimension.
Definition Oracle.hpp:29
Copy data from one buffer to another.
Flexible representations for matrix data.
Definition Extractor.hpp:15
auto new_extractor(const Matrix< Value_, Index_ > &matrix, const bool row, MaybeOracle< oracle_, Index_ > oracle, Args_ &&... args)
Definition new_extractor.hpp:42
std::shared_ptr< const std::vector< Index_ > > VectorPtr
Definition Matrix.hpp:26
void resize_container_to_Index_size(Container_ &container, const Index_ x, Args_ &&... args)
Definition Index_to_container.hpp:92
Options for accessing data from a Matrix instance.
Definition Options.hpp:30