26 static std::vector<std::vector<U>>
normalize(
const std::vector<std::vector<U>>& jagged) {
32 for (
const auto& row : jagged) {
33 max_size = std::max(max_size, row.size());
37 std::vector<std::vector<U>> normalized;
38 normalized.reserve(jagged.size());
40 for (
const auto& row : jagged) {
41 std::vector<U> normalized_row = row;
42 normalized_row.resize(max_size, U{});
43 normalized.push_back(std::move(normalized_row));
49 static std::vector<std::vector<std::vector<U>>>
50 normalize_3d(
const std::vector<std::vector<std::vector<U>>>& jagged_3d) {
51 if (jagged_3d.empty())
55 size_t max_rows = 0, max_cols = 0;
56 for (
const auto& matrix : jagged_3d) {
57 max_rows = std::max(max_rows, matrix.size());
58 for (
const auto& row : matrix) {
59 max_cols = std::max(max_cols, row.size());
64 std::vector<std::vector<std::vector<U>>> normalized;
65 normalized.reserve(jagged_3d.size());
67 for (
const auto& matrix : jagged_3d) {
68 std::vector<std::vector<U>> norm_matrix;
69 norm_matrix.reserve(max_rows);
71 for (
const auto& row : matrix) {
72 std::vector<U> norm_row = row;
73 norm_row.resize(max_cols, U{});
74 norm_matrix.push_back(std::move(norm_row));
77 while (norm_matrix.size() < max_rows) {
78 norm_matrix.push_back(std::vector<U>(max_cols));
81 normalized.push_back(std::move(norm_matrix));
91 throw std::invalid_argument(param +
" must be greater than 0");
96 std::vector<std::vector<T>> result;
97 result.reserve((data_.size() + size - 1) / size);
99 for (
size_t i = 0; i < data_.size(); i += size) {
100 size_t chunk_end = std::min(i + size, data_.size());
101 result.emplace_back(data_.begin() + i, data_.begin() + chunk_end);
108 for (
size_t i = 0; i < data_.size(); i += chunk_size_) {
109 std::vector<T> chunk;
110 for (
size_t j = 0; j < chunk_size_ && i + j < data_.size(); ++j) {
111 chunk.push_back(data_[i + j]);
113 chunks_.push_back(chunk);
118 template <
typename U>
121 return 1 + get_depth<typename U::value_type>();
126 explicit Chunk(
size_t chunk_size = 1) : chunk_size_(chunk_size) {
127 validate_size(chunk_size,
"Chunk size");
130 void add(
const T& element) {
131 data_.push_back(element);
135 void add(
const std::vector<T>& elements) {
136 data_.insert(data_.end(), elements.begin(), elements.end());
142 throw std::invalid_argument(
"Cannot chunk empty data");
145 throw std::invalid_argument(
"Chunk size cannot be zero");
147 return make_chunks(size);
152 throw std::invalid_argument(
"Cannot chunk empty data");
154 if (data_.size() < chunk_size_) {
155 throw std::invalid_argument(
"Input size must be at least chunk size");
157 if (threshold <= T{}) {
158 throw std::invalid_argument(
"Threshold must be positive");
161 std::vector<std::vector<T>> result;
162 std::vector<T> current_chunk;
165 for (
const T& value : data_) {
166 if (running_sum + value > threshold && !current_chunk.empty()) {
167 result.push_back(current_chunk);
168 current_chunk.clear();
171 current_chunk.push_back(value);
172 running_sum += value;
175 if (!current_chunk.empty()) {
176 result.push_back(current_chunk);
191 return (data_.size() + chunk_size_ - 1) / chunk_size_;
202 validate_size(new_size,
"Chunk size");
203 chunk_size_ = new_size;
208 template <
typename U = T>
209 std::enable_if_t<is_vector<U>::value>
add(
const U& nested_data) {
212 throw std::invalid_argument(
"Jagged arrays are not supported");
218 reinterpret_cast<const std::vector<
219 std::vector<std::vector<typename U::value_type::value_type>
>>&>(
221 throw std::invalid_argument(
"Jagged 3D arrays are not supported");
225 data_.push_back(nested_data);
231 return get_depth<T>();
235 template <
typename U>
243 template <
typename U>
244 std::vector<std::vector<std::vector<U>>>
252 template <
typename U>
257 auto normalized = handle_jagged_2d(data);
258 if (expected_size > 0 && normalized.size() != expected_size) {
259 throw std::invalid_argument(
"Inconsistent dimensions after normalization");
267 reinterpret_cast<const std::vector<
268 std::vector<std::vector<typename U::value_type::value_type>
>>&>(
270 auto normalized = handle_jagged_3d(data);
271 if (expected_size > 0 && normalized.size() != expected_size) {
272 throw std::invalid_argument(
273 "Inconsistent dimensions after 3D normalization");
280 if (expected_size > 0 && data.size() != expected_size) {
281 throw std::invalid_argument(
"Inconsistent dimensions in nested array");
286 validate_dimensions(data[0], data[0].size());
static std::vector< std::vector< U > > normalize(const std::vector< std::vector< U > > &jagged)
static std::vector< std::vector< std::vector< U > > > normalize_3d(const std::vector< std::vector< std::vector< U > > > &jagged_3d)
A template class for managing and processing data in chunks.
std::enable_if_t< is_vector< U >::value > add(const U &nested_data)
std::vector< std::vector< T > > make_chunks(size_t size) const
Chunk(size_t chunk_size=1)
void validate_dimensions(const std::vector< U > &data, size_t expected_size=0)
size_t chunk_count() const
static constexpr size_t get_depth()
std::vector< std::vector< T > > get_chunks() const
void add(const T &element)
size_t get_chunk_size() const
void validate_size(size_t size, const std::string ¶m) const
const std::vector< T > & get_data() const
std::vector< std::vector< T > > chunk_by_size(size_t size)
std::vector< std::vector< U > > handle_jagged_2d(const std::vector< std::vector< U > > &data)
std::vector< std::vector< T > > chunk_by_threshold(T threshold)
std::vector< std::vector< std::vector< U > > > handle_jagged_3d(const std::vector< std::vector< std::vector< U > > > &data)
void add(const std::vector< T > &elements)
void set_chunk_size(size_t new_size)
std::vector< std::vector< T > > chunks_
static constexpr size_t dimensions()
bool is_jagged(const std::vector< std::vector< T > > &data)
bool is_jagged_3d(const std::vector< std::vector< std::vector< T > > > &data)