say I have a std::vector
with N elements. I would like to copy every n-th element of it to a new vector, or average up to that element then copy it (downsample the
You may have explicitly stated that you prefer not to use Boost, but any non-Boost solution would really be implementing exactly this sort of thing anyway, so I'll show you how I would do it in Boost. Ultimately, I think you're better off writing a simple loop.
Downsampling uses strided
boost::copy(
input | strided(2),
std::back_inserter(output));
Downsampling average additionally uses transformed, though this solution is non-generic and specifically relies upon vector
being contiguous:
boost::copy(
input | strided(2) | transformed([](auto& x){
return std::accumulate(&x, &x + 2, 0) / 2.;
}),
std::back_inserter(output));
Of course that has issues if the input isn't an exact multiple of the stride length, so it'd probably be better to do something like:
auto downsample_avg = [](auto& input, int n){
return input | strided(n) | transformed([&,n](auto& x){
auto begin = &x;
auto end = begin + std::min(n, &input.back() - begin + 1);
return std::accumulate(begin, end, 0.0) / (end - begin);
});
};
boost::copy(
downsample_avg(input, 2),
std::back_inserter(output));