名前空間
変種
操作

std::experimental::parallel::transform_reduce

From cppreference.com
 
 
 
 
ヘッダ <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 が範囲 [firstlast) 内の要素を変更したり、イテレータを無効にしたりした場合、動作は未定義です。

目次

[編集] パラメータ

first, last - アルゴリズムを適用する要素の範囲
init - 一般化された合計の初期値
policy - 実行ポリシー
unary_op - 入力範囲の各要素に適用される単項演算。戻り値の型は binary_op の入力として受け入れ可能でなければなりません。
binary_op - unary_op の結果、他の binary_op の結果、および init に、不定な順序で適用される二項演算。
型要件
-
InputItLegacyInputIterator の要件を満たす必要があります。

[編集] 戻り値

initunary_op(*first), unary_op(*(first + 1)), ..., unary_op(*(last - 1)) の、binary_op による一般化された和。一般化された和 GSUM(op, a1, ..., aN) は以下のように定義されます。

  • N = 1 の場合、 a1
  • N > 1 の場合、 op(GSUM(op, b1, ..., bK), GSUM(op, bM, ..., bN))。ここで
  • b1, ..., bNa1, ..., aN の任意の順列であり、
  • 1 < K + 1 = M ≤ N

つまり、 unary_op の結果は任意にグループ化および並べ替えることができます。

[編集] 計算量

O(last - first) 回の unary_op および binary_op の適用。

[編集] 例外

  • アルゴリズムの一部として呼び出された関数が例外をスローした場合、
  • policyparallel_vector_execution_policy の場合、 std::terminate が呼び出されます。
  • policysequential_execution_policy または parallel_execution_policy の場合、アルゴリズムは、すべての捕捉されていない例外を含む exception_list を伴って終了します。捕捉されていない例外が 1 つだけだった場合、アルゴリズムはそれを exception_list でラップせずに再スローする可能性があります。例外が最初に検出されてからアルゴリズムが戻るまでに実行される処理の量は不定です。
  • policy がその他の型の場合、動作は実装定義です。
  • アルゴリズムがメモリの割り当てに失敗した場合(自身のため、またはユーザー例外を処理する際の exception_list の構築のため)、 std::bad_alloc がスローされます。

[編集] 注意

unary_opinit には適用されません。

範囲が空の場合、 init が変更されずに返されます。

  • policysequential_execution_policy のインスタンスである場合、すべての操作は呼び出しスレッドで実行されます。
  • policyparallel_execution_policy のインスタンスである場合、操作は不定数のスレッドで実行される可能性があり、互いに不定な順序でシーケンスされます。
  • policyparallel_vector_execution_policy のインスタンスである場合、実行は並列化およびベクトル化される可能性があります。関数本体の境界は尊重されず、ユーザーコードは任意の順序でオーバーラップおよび結合される可能性があります(特に、ユーザー提供の Callable は共有リソースにアクセスするためにミューテックスを取得してはならないことを意味します)。

[編集]

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

[編集] 関連項目

範囲の要素を合計または畳み込む
(関数テンプレート) [編集]
範囲内の要素に関数を適用し、結果を結果範囲に格納する
(関数テンプレート) [編集]
(並列処理 TS)
std::accumulate に似ているが、順序不同
(関数テンプレート) [編集]
English 日本語 中文(简体) 中文(繁體)