Daily bit(e) C++ #68, Обобщенный алгоритм преобразования и сокращения C++17: std::transform_reduce

Преобразование-уменьшение — обычная операция в распределенных системах. В C++17 добавлена ​​поддержка одноименного алгоритма, который предлагает шаблон преобразования-уменьшения для диапазонов.

Алгоритм требует коммутативной и ассоциативной редукции, но предлагает варианты с одним и двумя диапазонами и параллельные перегрузки.

#include <numeric>
#include <vector>
#include <execution>

std::vector<double> values{2.3, 9.1, 4.7, 7.1, 1.9, 5.2};
std::vector<double> predictions{1.0, 2.0, 3.0, 4.0, 5.0, 6.0};

// Calculate the mean square error:
auto mse = std::transform_reduce(
    values.begin(), values.end(), // all elements
    predictions.begin(), // first element from second range
    0., // starting value, also dictates the type of accumulator
    std::plus<>{}, // reduction operation
    [](double val, double pred) { // transform operation
        return (val-pred)*(val-pred);
    }) / values.size(); // calculate the mean

// Same, but computed in parallel.
auto mse_par = std::transform_reduce(std::execution::par_unseq,
    values.begin(), values.end(),
    predictions.begin(), 
    0.,
    std::plus<>{},
    [](double val, double pred) {
        return (val-pred)*(val-pred); 
    }) / values.size();

// mse == mse_par == 12.475

std::vector<int> data{1,2,3,4,5};
// Unary (single-range) version is also supported:
int sum_of_squares = std::transform_reduce(data.begin(), data.end(),
    0,
    std::plus<>{},
    [](int v) { return v*v; });
// sum_of_squares == 55

Откройте пример в Compiler Explorer.