#ifndef TATAMI_LAYERED_UTILS_HPP #define TATAMI_LAYERED_UTILS_HPP #include #include #include #include "../base/Matrix.hpp" #include "../base/DelayedBind.hpp" #include "../base/CompressedSparseMatrix.hpp" namespace tatami { /** * @cond */ namespace layered_utils { template int categorize_row(T v) { constexpr uint8_t max8 = std::numeric_limits::max(); constexpr uint16_t max16 = std::numeric_limits::max(); constexpr T maxv = std::numeric_limits::max(); if constexpr(maxv <= max8) { return 0; } else { if (v <= max8) { return 0; } } if constexpr(maxv <= max16) { return 1; } else { if (v <= max16) { return 1; } } return 2; } template struct RowRemapping { RowRemapping() {} RowRemapping(size_t n) : per_category(3), new_indices(n), permutation(n) {} std::vector per_category; std::vector new_indices; std::vector permutation; }; template RowRemapping compute_new_indices(const std::vector& category) { RowRemapping output(category.size()); for (size_t i = 0; i < category.size(); ++i) { auto& sofar = output.per_category[category[i]]; output.new_indices[i] = sofar; ++sofar; } // Computing the permutation, while we're here. O offset[3]; offset[0] = 0; offset[1] = output.per_category[0]; offset[2] = offset[1] + output.per_category[1]; for (size_t i = 0; i < category.size(); ++i){ output.permutation[i] = offset[category[i]] + output.new_indices[i]; } return output; } template RowRemapping create_empty(size_t n) { RowRemapping output(n); std::iota(output.new_indices.begin(), output.new_indices.end(), 0); std::iota(output.permutation.begin(), output.permutation.end(), 0); return output; } template void counts_to_offsets(std::vector& counts) { for (size_t i = 1; i < counts.size(); ++i) { counts[i] += counts[i-1]; } return; } template std::shared_ptr > consolidate_submatrices(std::vector > > collated, size_t ncol) { if (collated.size() == 0) { typedef CompressedSparseColumnMatrix CSCMatrix; return std::shared_ptr >(new CSCMatrix(0, ncol, std::vector(), std::vector(), std::vector())); } else if (collated.size() == 1) { return collated[0]; } else { return make_DelayedBind<0>(std::move(collated)); } } template std::shared_ptr > consolidate_submatrices( const std::vector& per_category, std::vector row8, std::vector dat8, std::vector ptr8, std::vector row16, std::vector dat16, std::vector ptr16, std::vector row32, std::vector dat32, std::vector ptr32) { std::vector > > collated; size_t NC = ptr8.size() - 1; if (per_category[0]) { typedef CompressedSparseColumnMatrix CSCMatrix8; collated.emplace_back(new CSCMatrix8(per_category[0], NC, std::move(dat8), std::move(row8), std::move(ptr8))); } if (per_category[1]) { typedef CompressedSparseColumnMatrix CSCMatrix16; collated.emplace_back(new CSCMatrix16(per_category[1], NC, std::move(dat16), std::move(row16), std::move(ptr16))); } if (per_category[2]) { typedef CompressedSparseColumnMatrix CSCMatrix32; collated.emplace_back(new CSCMatrix32(per_category[2], NC, std::move(dat32), std::move(row32), std::move(ptr32))); } return consolidate_submatrices(std::move(collated), NC); } } /** * @endcond */ } #endif