0Pricing
C++ Academy · レッスン

数値アルゴリズム:accumulate、reduce、transform_reduce

accumulate、reduce、並列処理に適したtransform_reduceで数値範囲を集約します。

「数値アルゴリズム:accumulate、reduce、transform_reduce」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。

<numeric> ヘッダー

数値アルゴリズムは、数値の範囲を操作します。これらは <numeric> に定義されています。

std::accumulate

代表的な畳み込みアルゴリズムです。デフォルトでは合計を計算します。別の畳み込みを行うには、カスタムの二項演算を渡します。

#include <numeric>
std::vector<int> v = {1, 2, 3, 4, 5};
int sum = std::accumulate(v.begin(), v.end(), 0);
// sum = 15

カスタム畳み込み

初期値と二項演算を指定します。

int product = std::accumulate(v.begin(), v.end(), 1,
    std::multiplies<int>{});
// product = 120

初期値の型が重要

アキュムレーターの型は初期値から推論されます。倍精度浮動小数点値を double 型として累積するには、0.0 を指定します。

std::vector<double> v = {1.5, 2.5, 3.5};
double sum_d = std::accumulate(v.begin(), v.end(), 0.0);    // 7.5
int    sum_i = std::accumulate(v.begin(), v.end(), 0);      // truncates to 6

std::reduce (C++17)

accumulate と似ていますが、並列評価を可能にするため、演算が結合的かつ交換可能でなければなりません。

#include <numeric>
#include <execution>
std::vector<int> v(1000);
int sum = std::reduce(std::execution::par,
    v.begin(), v.end(), 0);

reduce と accumulate の違い

主な違いは2つあります。

  • reduce は並列実行される場合があります
  • reduce は演算の順序を保証しません。+ や * には適していますが、文字列連結のような結合的でない演算では正しく動作しません

std::transform_reduce (C++17)

変換と畳み込みを1回の走査で組み合わせます。transform と reduce を別々に実行するより高速で、意図も明確になります。

// Dot product
std::vector<int> a = {1, 2, 3}, b = {4, 5, 6};
int dot = std::transform_reduce(
    a.begin(), a.end(), b.begin(),
    0,
    std::plus<int>{},          // reduce
    std::multiplies<int>{}     // transform
);
// dot = 1*4 + 2*5 + 3*6 = 32

std::inner_product

transform_reduce の旧来の対応物です。2つの範囲の内積を計算します。汎用性は低いものの、API はよりシンプルです。

std::partial_sum

累積合計を出力範囲に書き込みます。

std::vector<int> v = {1, 2, 3, 4};
std::vector<int> sums(4);
std::partial_sum(v.begin(), v.end(), sums.begin());
// sums = {1, 3, 6, 10}

std::adjacent_difference

partial_sum の反対で、連続する要素間の差分を出力します。

std::vector<int> v = {1, 3, 6, 10};
std::vector<int> diffs(4);
std::adjacent_difference(v.begin(), v.end(), diffs.begin());
// diffs = {1, 2, 3, 4}

浮動小数点数に関する注意

浮動小数点数では丸め誤差のため、累積する順序が重要です。reduce は評価順序が未規定であるため、accumulate とわずかに異なる結果になる場合があります。

実際の利用例

数値アルゴリズムは、次のような処理を支えます。

  • 合計と積の計算
  • 統計的な集計(平均、分散)
  • 線形代数における内積とノルム
  • 累積クエリのための累積和

理解度チェック

1回の関数呼び出しで範囲を並列に畳み込む C++17 のアルゴリズムはどれですか。

まとめ

<numeric> には、数値の畳み込みや累積処理のための accumulate、reduce、transform_reduce、partial_sum、adjacent_difference が用意されています。並列性が必要な場合は reduce、決定的な順序が必要な場合は accumulate を選びます。

よくある質問

「数値アルゴリズム:accumulate、reduce、transform_reduce」レッスンは無料ですか?

はい。「数値アルゴリズム:accumulate、reduce、transform_reduce」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。

「数値アルゴリズム:accumulate、reduce、transform_reduce」で何を学びますか?

accumulate、reduce、並列処理に適したtransform_reduceで数値範囲を集約します。 ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C++ Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「数値アルゴリズム:accumulate、reduce、transform_reduce」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC++ Academyレッスンでコードを書いて実行できますか?

はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 非変更アルゴリズム:find、count、all_of
  2. 変更アルゴリズム:transform、copy_if、replace
  3. ソートとパーティション:sort、stable_partition
  4. 数値アルゴリズム:accumulate、reduce、transform_reduce
← C++ Academyに戻る