std::inner_product
ヘッダ <numeric> で定義
|
||
(1) | ||
template< class InputIt1, class InputIt2, class T > T inner_product( InputIt1 first1, InputIt1 last1, |
(C++20未満) | |
template< class InputIt1, class InputIt2, class T > constexpr T inner_product( InputIt1 first1, InputIt1 last1, |
(C++20以上) | |
(2) | ||
template<class InputIt1, class InputIt2, class T, class BinaryOperation1, class BinaryOperation2> |
(C++20未満) | |
template<class InputIt1, class InputIt2, class T, class BinaryOperation1, class BinaryOperation2> |
(C++20以上) | |
範囲 [first1, last1)
および first2
から始まる範囲の内積 (積の和) の計算、または順序付けされた map/reduce 操作を行います。
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以上) |
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以上) |
|
(C++11未満) |
|
(C++11以上) |
目次 |
[編集] 引数
first1, last1 | - | 1つめの要素の範囲 |
first2 | - | 2つめの要素の範囲の先頭 |
init | - | 積を加算する初期値 |
op1 | - | 適用される二項演算関数オブジェクト。 この「加算」関数は、 op2 から返された値と、累積変数の現在の値を取り、累積変数に格納される新しい値を生成します。 関数のシグネチャは以下と同等であるべきです。 Ret fun(const Type1 &a, const Type2 &b); シグネチャが const & を持つ必要はありません。 |
op2 | - | 適用される二項演算関数オブジェクト。 この「乗算」関数は、それぞれの範囲から値を1つずつ取り、新しい値を生成します。 関数のシグネチャは以下と同等であるべきです。 Ret fun(const Type1 &a, const Type2 &b); シグネチャが const & を持つ必要はありません。 |
型の要件 | ||
-InputIt1, InputIt2 は LegacyInputIterator の要件を満たさなければなりません。
| ||
-ForwardIt1, ForwardIt2 は LegacyForwardIterator の要件を満たさなければなりません。
| ||
-T は CopyAssignable および CopyConstructible の要件を満たさなければなりません。
|
[編集] 戻り値
上で説明した通りの acc
の最終値。
[編集] 実装例
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; } |
2つめのバージョン |
template<class InputIt1, class InputIt2, class T, class BinaryOperation1, class BinaryOperation2> constexpr // since C++20 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
[編集] 関連項目
(C++17) |
不定の計算順序で、関数オブジェクトを適用した結果を reduce します (関数テンプレート) |
指定範囲の要素を合計します (関数テンプレート) | |
指定範囲の要素の部分和を計算します (関数テンプレート) |