Namespaces
Variants

std::experimental::parallel:: transform_reduce

From zh.cppreference.net
定义于头文件 <experimental/numeric>
template < class InputIt, class UnaryOp, class T, class BinaryOp >

T transform_reduce ( InputIt first, InputIt last,

UnaryOp unary_op, T init, BinaryOp binary_op ) ;
(1) (并行性TS)
template < class ExecutionPolicy,

class InputIt, class UnaryOp, class T, class BinaryOp >
T transform_reduce ( ExecutionPolicy && policy,
InputIt first, InputIt last,

UnaryOp unary_op, T init, BinaryOp binary_op ) ;
(2) (并行性TS)

对范围 [ first , last ) 中的每个元素应用 unary_op ,并将结果(可能以未指定的方式重排和聚合)与初始值 init 通过 binary_op 进行归约。

如果 binary_op 不满足结合律或交换律,则该行为是不确定的。

如果 unary_op 或 binary_op 修改了 [ first , last ) 范围内的任何元素或使任何迭代器失效,则行为未定义。

目录

参数

first, last - 应用算法处理的元素范围
init - 广义求和的初始值
policy - 执行策略
unary_op - 一元 函数对象 ,将应用于输入范围的每个元素。其返回类型必须可作为 binary_op 的输入
binary_op - 二元 函数对象 ,将以未指定顺序应用于 unary_op 的结果、其他 binary_op 的结果以及 init
类型要求
-
InputIt 必须满足 LegacyInputIterator 的要求。

返回值

init 与 unary_op ( * first ) 、 unary_op ( * ( first + 1 ) ) …… unary_op ( * ( last - 1 ) ) 在 binary_op 上的广义和, 其中广义和 GSUM(op, a 1 , ..., a N ) 定义如下:

  • 若 N = 1 , a 1 ,
  • 若 N > 1 , op(GSUM(op, b 1 , ..., b K ), GSUM(op, b M , ..., b N )) 其中
  • b 1 , ..., b N 可以是 a1, ..., aN 的任意排列,且
  • 1 < K + 1 = M ≤ N

换句话说, unary_op 的结果可以按任意顺序进行分组和排列。

复杂度

O(last - first) 次对 unary_op 和 binary_op 的各自调用。

异常

  • 如果作为算法一部分调用的函数执行抛出异常,
  • 若 policy 为 parallel_vector_execution_policy ,则调用 std::terminate 。
  • 若 policy 为 sequential_execution_policy 或 parallel_execution_policy ,算法将以包含所有未捕获异常的 exception_list 退出。若仅存在一个未捕获异常,算法可能直接重新抛出该异常而不将其包装在 exception_list 中。未指明在遇到首个异常后、返回前算法将执行多少工作。
  • 若 policy 为其他类型,其行为由实现定义。
  • 如果算法无法分配内存(无论是为自身分配还是在处理用户异常时构造 exception_list ),将抛出 std::bad_alloc 。

注释

unary_op 不应用于 init 。

如果范围为空,将返回未经修改的 init 。

  • 如果 policy 是 sequential_execution_policy 的实例,所有操作将在调用线程中执行。
  • 如果 policy 是 parallel_execution_policy 的实例,操作可能在未指定数量的线程中执行,彼此之间以不确定的顺序进行。
  • 如果 policy 是 parallel_vector_execution_policy 的实例,执行可能同时并行化和向量化:函数体边界不被遵守,用户代码可能以任意方式重叠和组合(特别地,这意味着用户提供的可调用对象不得通过获取互斥锁来访问共享资源)。

示例

transform_reduce 可用于并行化 std::inner_product :

#include <boost/iterator/zip_iterator.hpp>
#include <boost/tuple.hpp>
#include <experimental/execution_policy>
#include <experimental/numeric>
#include <functional>
#include <iostream>
#include <iterator>
#include <vector>
int main()
{
    std::vector<double> xvalues(10007, 1.0), yvalues(10007, 1.0);
    double result = std::experimental::parallel::transform_reduce(
        std::experimental::parallel::par,
        boost::iterators::make_zip_iterator(
            boost::make_tuple(std::begin(xvalues), std::begin(yvalues))),
        boost::iterators::make_zip_iterator(
            boost::make_tuple(std::end(xvalues), std::end(yvalues))),
        [](auto r) { return boost::get<0>(r) * boost::get<1>(r); }
        0.0,
        std::plus<>()
    );
    std::cout << result << '\n';
}

输出:

10007

另请参阅

对一系列元素进行求和或折叠
(函数模板)
将一个函数应用于一系列元素,并将结果存储在目标范围内
(函数模板 & 算法函数对象)
(parallelism TS)
与 std::accumulate,只是无序
(函数模板)