Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
48 lines
1.3 KiB
C++
48 lines
1.3 KiB
C++
#include "Decimate.h"
|
|
|
|
#include <algorithm>
|
|
|
|
namespace udpscope {
|
|
|
|
void MinMaxDecimate(const double* t, const double* v, size_t n,
|
|
size_t maxPoints, Series& out) {
|
|
out.clear();
|
|
if (n == 0 || t == nullptr || v == nullptr) {
|
|
return;
|
|
}
|
|
if (n <= maxPoints || maxPoints < 4) {
|
|
out.t.assign(t, t + n);
|
|
out.v.assign(v, v + n);
|
|
return;
|
|
}
|
|
|
|
/* Two points per bucket, so the bucket count is half the budget. */
|
|
const size_t buckets = maxPoints / 2;
|
|
out.t.reserve(buckets * 2);
|
|
out.v.reserve(buckets * 2);
|
|
|
|
for (size_t b = 0; b < buckets; b++) {
|
|
const size_t begin = (n * b) / buckets;
|
|
size_t end = (n * (b + 1)) / buckets;
|
|
if (end <= begin) { end = begin + 1; }
|
|
if (end > n) { end = n; }
|
|
|
|
size_t lo = begin, hi = begin;
|
|
for (size_t i = begin + 1; i < end; i++) {
|
|
if (v[i] < v[lo]) { lo = i; }
|
|
if (v[i] > v[hi]) { hi = i; }
|
|
}
|
|
|
|
const size_t first = std::min(lo, hi);
|
|
const size_t second = std::max(lo, hi);
|
|
out.t.push_back(t[first]);
|
|
out.v.push_back(v[first]);
|
|
if (second != first) {
|
|
out.t.push_back(t[second]);
|
|
out.v.push_back(v[second]);
|
|
}
|
|
}
|
|
}
|
|
|
|
} /* namespace udpscope */
|