名前空間
変種
操作

std::inner_product

From cppreference.com
< cpp‎ | algorithm
 
 
アルゴリズムライブラリ
制約付きアルゴリズムとRangeアルゴリズム (C++20)
制約付きアルゴリズム、例: ranges::copy, ranges::sort, ...
実行ポリシー (C++17)
シーケンスを変更しない操作
一括操作
(C++17)
検索操作
(C++11)                (C++11)(C++11)

シーケンスを変更する操作
コピー操作
(C++11)
(C++11)
スワップ操作
変換操作
生成操作
削除操作
順序変更操作
(C++17まで)(C++11)
(C++20)(C++20)
サンプリング操作
(C++17)

ソートおよび関連操作
パーティション操作
ソート操作
二分探索操作
(パーティション化された範囲)
集合操作 (ソート済み範囲)
マージ操作 (ソート済み範囲)
ヒープ操作
最小/最大操作
(C++11)
(C++17)
辞書順比較操作
順列操作
Cライブラリ
数値演算
(C++11)
inner_product
未初期化メモリに対する操作
 
 
ヘッダー <numeric> で定義
template< class InputIt1, class InputIt2, class T >

T inner_product( InputIt1 first1, InputIt1 last1,

                 InputIt2 first2, T init );
(1) (C++20 以降 constexpr)
template< class InputIt1, class InputIt2, class T,

          class BinaryOp1, class BinaryOp2 >
T inner_product( InputIt1 first1, InputIt1 last1,
                 InputIt2 first2, T init,

                 BinaryOp1 op1, BinaryOp2 op2 );
(2) (C++20 以降 constexpr)

範囲 [first1last1) と、 std::distance(first1, last1) 個の要素からなる first2 で始まる範囲の内部積(積の和)を計算するか、順序付けられたマップ/リデュース操作を実行します。

1) アキュムレータ acc(型は T)を初期値 init で初期化し、その後、各イテレータ i1 が範囲 [first1last1) 内で順番に処理され、それに対応するイテレータ i2first2 で始まる範囲から取得される際に、式 acc = acc + (*i1) * (*i2)(until C++20)acc = std::move(acc) + (*i1) * (*i2)(since C++20) を使用して変更されます。+ および * の組み込みの意味においては、これは 2 つの範囲の内部積を計算します。
2) アキュムレータ acc(型は T)を初期値 init で初期化し、その後、各イテレータ i1 が範囲 [first1last1) 内で順番に処理され、それに対応するイテレータ i2first2 で始まる範囲から取得される際に、式 acc = op1(acc, op2(*i1, *i2))(until C++20)acc = op1(std::move(acc), op2(*i1, *i2))(since C++20) を使用して変更されます。

last2std::distance(first1, last1)番目first2 の次のイテレータである場合、以下のいずれかの条件が満たされると、動作は未定義となります。

  • TCopyConstructible ではない。
  • TCopyAssignable ではない。
  • op1 または op2 が、 [first1last1) または [first2last2) のいずれかの要素を変更する。
  • op1 または op2 が、 [first1last1] または [first2last2] のいずれかのイテレータまたはサブ範囲を無効にする。

目次

[編集] パラメータ

first1, last1 - 対象となる要素の 範囲 を定義するイテレータのペア
first2 - 2番目の要素範囲の開始位置
init - 積の和の初期値
op1 - 適用されるバイナリ演算関数オブジェクト。「合計」関数は、op2 の戻り値とアキュムレータの現在の値を取り、アキュムレータに格納される新しい値を生成します。

関数のシグネチャは以下と同等である必要があります。

 Ret fun(const Type1 &a, const Type2 &b);

シグネチャは const & を持つ必要はありません。
 Type1 および  Type2 の型は、T および Type3 の型のオブジェクトがそれぞれ  Type1 および  Type2 に暗黙的に変換可能である必要があります。Ret の型は、T の型のオブジェクトが Ret の型の値に代入可能である必要があります。​

op2 - 適用されるバイナリ演算関数オブジェクト。「積」関数は、各範囲から1つの値を取り、新しい値を生成します。

関数のシグネチャは以下と同等である必要があります。

 Ret fun(const Type1 &a, const Type2 &b);

シグネチャは const & を持つ必要はありません。
 Type1 および  Type2 の型は、InputIt1 および InputIt2 の型のオブジェクトを逆参照し、その後それぞれ  Type1 および  Type2 に暗黙的に変換可能である必要があります。Ret の型は、Type3 の型のオブジェクトが Ret の型の値に代入可能である必要があります。​

型要件
-
InputIt1, InputIt2LegacyInputIterator の要件を満たす必要がある。

[編集] 戻り値

すべての変更後の acc

[編集] 実装例

inner_product (1)
template<class InputIt1, class InputIt2, class T>
constexpr // since C++20
T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init)
{
    while (first1 != last1)
    {
        init = std::move(init) + (*first1) * (*first2); // std::move since C++20
        ++first1;
        ++first2;
    }
 
    return init;
}
inner_product (2)
template<class InputIt1, class InputIt2, class T,
         class BinaryOp1, class BinaryOp2>
constexpr // since C++20
T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init,
                BinaryOp1 op1, BinaryOp2 op2)
{
    while (first1 != last1)
    {
        init = op1(std::move(init), op2(*first1, *first2)); // std::move since C++20
        ++first1;
        ++first2;
    }
 
    return init;
}

[編集] 注記

このアルゴリズムの並列化可能なバージョンである std::transform_reduce は、op1op2 が可換かつ結合的であることを要求しますが、std::inner_product はそのような要件を課さず、常に指定された順序で操作を実行します。

[編集]

#include <functional>
#include <iostream>
#include <numeric>
#include <vector>
 
int main()
{
    std::vector<int> a{0, 1, 2, 3, 4};
    std::vector<int> b{5, 4, 2, 3, 1};
 
    int r1 = std::inner_product(a.begin(), a.end(), b.begin(), 0);
    std::cout << "Inner product of a and b: " << r1 << '\n';
 
    int r2 = std::inner_product(a.begin(), a.end(), b.begin(), 0,
                                std::plus<>(), std::equal_to<>());
    std::cout << "Number of pairwise matches between a and b: " <<  r2 << '\n';
}

出力

Inner product of a and b: 21
Number of pairwise matches between a and b: 2

[編集] 不具合報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
LWG 242 C++98 op1 および op2 は副作用を持てない それらは関係する範囲を変更できない

[編集] 関連項目

呼び出し可能オブジェクトを適用し、順序不同に縮約する
(関数テンプレート) [編集]
範囲の要素を合計または畳み込む
(関数テンプレート) [編集]
範囲の要素の部分和を計算する
(関数テンプレート) [編集]
English 日本語 中文(简体) 中文(繁體)