名前空間
変種
操作

std::inner_product

提供: cppreference.com
< cpp‎ | algorithm
 
 
アルゴリズムライブラリ
実行ポリシー (C++17)
非変更シーケンス操作
(C++11)(C++11)(C++11)
(C++17)
変更シーケンス操作
未初期化記憶域の操作
分割操作
ソート操作
(C++11)
二分探索操作
集合操作 (ソート済み範囲用)
ヒープ操作
(C++11)
最小/最大演算
(C++11)
(C++17)
順列
数値演算
(C++11)
inner_product
C のライブラリ
 
ヘッダ <numeric> で定義
template< class InputIt1, class InputIt2, class T >

T inner_product( InputIt1 first1, InputIt1 last1,

                 InputIt2 first2, T init );
(1)
template<class InputIt1, class InputIt2, class T,

         class BinaryOperation1, class BinaryOperation2>
T inner_product( InputIt1 first1, InputIt1 last1,
                 InputIt2 first2, T init,
                 BinaryOperation1 op1,

                 BinaryOperation2 op2 );
(2)

範囲 [first1, last1) および first2 から始まる範囲の内積 (積の和) の計算、または順序付けされた map/reduce 操作を行います。

1) 累積変数 acc を初期値 init で初期化し、 last1 に達するまで、

それを式 acc = acc + *first1 * *first2 で変更し、その後、式 acc = acc + *(first1+1) * *(first2+1) で再び変更し、以下同様です。

(C++20未満)

それを式 acc = std::move(acc) + *first1 * *first2 で変更し、その後、式 acc = std::move(acc) + *(first1+1) * *(first2+1) で再び変更し、以下同様です。

(C++20以上)
+ および * の組み込みの意味の場合、これは2つの範囲の内積を計算します。
2) 累積変数 acc を初期値 init で初期化し、 last1 に達するまで、

それを式 acc = op1(acc, op2(*first1, *first2)) で変更し、その後、式 acc = op1(acc, op2(*(first1+1), *(first2+1))) で再び変更し、以下同様です。

(C++20未満)

それを式 acc = op1(std::move(acc), op2(*first1, *first2)) で変更し、その後、式 acc = op1(std::move(acc), op2(*(first1+1), *(first2+1))) で再び変更し、以下同様です。

(C++20以上)

op1 および op2 は副作用を持っていてはなりません。

(C++11未満)

op1 および op2 は終端イテレータを含むいかなるイテレータも無効化してはならず、関係する範囲のいかなる要素も変更してはなりません。

(C++11以上)

目次

[編集] 引数

first1, last1 - 1つめの要素の範囲
first2 - 2つめの要素の範囲の先頭
init - 積を加算する初期値
op1 - 適用される二項演算関数オブジェクト。 この「加算」関数は、 op2 から返された値と、累積変数の現在の値を取り、累積変数に格納される新しい値を生成します。

関数のシグネチャは以下と同等であるべきです。

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

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

op2 - 適用される二項演算関数オブジェクト。 この「乗算」関数は、それぞれの範囲から値を1つずつ取り、新しい値を生成します。

関数のシグネチャは以下と同等であるべきです。

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

シグネチャが const & を持つ必要はありません。
Type1 および Type2 は、 InputIt1 および InputIt2 型のオブジェクトの逆参照からType1 および Type2 にそれぞれ暗黙に変換可能なものでなければなりません。 型 RetType3 型のオブジェクトに代入可能なものでなければなりません。 ​

型の要件
-
InputIt1, InputIt2LegacyInputIterator の要件を満たさなければなりません。
-
ForwardIt1, ForwardIt2LegacyForwardIterator の要件を満たさなければなりません。
-
TCopyAssignable および CopyConstructible の要件を満たさなければなりません。

[編集] 戻り値

上で説明した通りの acc の最終値。

[編集] 実装例

1つめのバージョン
template<class InputIt1, class InputIt2, class T>
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;
}
2つめのバージョン
template<class InputIt1, class InputIt2,
         class T,
         class BinaryOperation1, class BinaryOperation2>
T inner_product(InputIt1 first1, InputIt1 last1,
                InputIt2 first2, T init,
                BinaryOperation1 op1
                BinaryOperation2 op2)
{
    while (first1 != last1) {
         init = op1(std::move(init), op2(*first1, *first2)); // std::move since C++20
         ++first1;
         ++first2;
    }
    return init;
}

[編集] ノート

このアルゴリズムの並列化バージョン std::transform_reduce では、 op1 および op2 が交換法則と結合法則を満たすことが要求されますが、 std::inner_product にはそのような要件はなく、常に指定された順序で演算を行います。

[編集]

#include <numeric>
#include <iostream>
#include <vector>
#include <functional>
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

[編集] 関連項目

不定の計算順序で、関数オブジェクトを適用した結果を reduce します
(関数テンプレート) [edit]
指定範囲の要素を合計します
(関数テンプレート) [edit]
指定範囲の要素の部分和を計算します
(関数テンプレート) [edit]