Parallel Algorithms Practical

std::transform_reduce() Overload

  • We can use our own binary functions

    • Instead of the default + and * operations for the elements
  • We can replace the * operator by a "transform" function

    • Takes two arguments of the element type
    • Returns a value of its result type
  • We can replace the + operator by a "reduce" function

    • Takes two arguments of the transform's return type
    • Returns a value of the final result type

Overload Example

  • The results of a scientific experiment are stored in a vector

  • Another vector contains the theoretically predicted values

  • We want to find the biggest "error"

    • The maximum difference between an expected result and the actual result
  • We can do this using an overloaded version of std::transform_reduce()

  • Replacement of the * operator

// Find the difference between corresponding elements
[](auto exp, auto act) { return std::abs(act * exp); }
  • Replacement of the + operator
// Find the largest difference
[](auto diff1, auto diff2) { return std::max(diff1, diff2); }

#include <algorithm>
#include <execution>
#include <iostream>
#include <numeric>
#include <vector>

int main() {
  std::vector<double> expected{0.1, 0.2, 0.3, 0.4, 0.5};
  std::vector<double> actual{0.09, 0.22, 0.27, 0.41, 0.52};

  auto max_diff = std::transform_reduce(
      std::execution::par, begin(expected), end(expected), begin(actual), 0.0,
      // "Reduce" operation
      [](auto diff1, auto diff2) { return std::max(diff1, diff2); },
      // "Transform" operation
      [](auto exp, auto act) { return std::abs(act - exp); });

  std::cout << "max difference is: " << max_diff << '\n';
}