7 if (window_size == 0 || hop_size == 0)
11 return data_size >= 3;
15 const std::vector<std::pair<size_t, size_t>>& intervals)
17 if (intervals.empty())
20 auto sorted = intervals;
21 std::ranges::sort(sorted, [](
const auto&
a,
const auto&
b) {
return a.first <
b.first; });
23 std::vector<std::pair<size_t, size_t>> merged;
24 merged.push_back(sorted[0]);
26 for (
size_t i = 1; i < sorted.size(); ++i) {
27 auto& last = merged.back();
28 const auto& cur = sorted[i];
29 if (cur.first <= last.second) {
30 last.second = std::max(last.second, cur.second);
32 merged.push_back(cur);
40 std::span<const double> data,
41 const std::vector<std::pair<size_t, size_t>>& intervals)
43 std::vector<double> out;
44 for (
const auto& [s, e] : intervals) {
45 if (s < data.size() && e <= data.size() && s < e) {
46 out.insert(out.end(), data.begin() + s, data.begin() + e);
53 const std::vector<size_t>& positions,
57 std::vector<std::pair<size_t, size_t>> out;
58 out.reserve(positions.size());
59 for (
size_t pos : positions) {
60 const size_t s = (pos >= half_region) ? pos - half_region : 0;
61 const size_t e = std::min(pos + half_region, data_size);
63 out.emplace_back(s, e);
69 const std::vector<size_t>& window_starts,
73 std::vector<std::pair<size_t, size_t>> out;
74 out.reserve(window_starts.size());
75 for (
size_t s : window_starts) {
76 const size_t e = std::min(s +
static_cast<size_t>(window_size), data_size);
78 out.emplace_back(s, e);
84 std::span<const double> data,
88 if (window_size == 0 || overlap < 0.0 || overlap >= 1.0 || data.size() < window_size)
91 const auto hop = std::max(1U,
static_cast<uint32_t
>(window_size * (1.0 -
overlap)));
92 std::vector<double> out;
93 out.reserve(((data.size() - window_size) / hop + 1) * window_size);
95 for (
size_t start = 0; start + window_size <= data.size(); start += hop)
96 out.insert(out.end(), data.begin() + start, data.begin() + start + window_size);
102 std::span<const double> data,
103 const std::vector<size_t>& window_starts,
104 uint32_t window_size)
106 std::vector<double> out;
107 if (window_size == 0)
110 out.reserve(window_starts.size() * window_size);
111 for (
size_t s : window_starts) {
112 if (s + window_size <= data.size()) {
113 out.insert(out.end(), data.begin() + s, data.begin() + s + window_size);
std::vector< double > overlapping_windows(std::span< const double > data, uint32_t window_size, double overlap)
Extract overlapping windows as a flat concatenated vector.
std::vector< double > windowed_by_indices(std::span< const double > data, const std::vector< size_t > &window_starts, uint32_t window_size)
Extract windows at specific starting indices as a flat concatenated vector.
bool validate_window_parameters(uint32_t window_size, uint32_t hop_size, size_t data_size) noexcept
Validate window/hop parameters for windowed processing.
std::vector< std::pair< size_t, size_t > > merge_intervals(const std::vector< std::pair< size_t, size_t > > &intervals)
Merge overlapping or adjacent half-open intervals.
std::vector< std::pair< size_t, size_t > > intervals_from_window_starts(const std::vector< size_t > &window_starts, uint32_t window_size, size_t data_size)
Build [start, end) intervals from window start indices.
std::vector< double > slice_intervals(std::span< const double > data, const std::vector< std::pair< size_t, size_t > > &intervals)
Copy data from a set of half-open intervals into a flat vector.
std::vector< std::pair< size_t, size_t > > regions_around_positions(const std::vector< size_t > &positions, size_t half_region, size_t data_size)
Build [start, end) intervals centred on a set of positions.