C++ で 2つのベクトルの内積を計算する
-
C++ で 2つのベクトルの内積を計算するには、
std::inner_product
を使用する -
C++ で
std::transform_reduce
を使用して 2つのベクトルの内積を計算する -
std::transform_reduce
とstd::execution::par
を利用して 2つのベクトルの内積を計算する
この記事では、C++ で 2つのベクトルの内積を計算する複数の方法を示します。
内積は、2つのベクトルの対応する要素の積の和です。2つのベクトル {1, 2, 3}
と {4, 5, 6}
があり、これらのベクトルの内積は 1*4 + 2*5 + 3*6 = 32
であるとします。
C++ で 2つのベクトルの内積を計算するには、std::inner_product
を使用する
std::inner_product
は、<numeric>
ヘッダに含まれる C++ 数値アルゴリズムライブラリに含まれます。このメソッドは、2つの範囲の積の和を計算します。最初の範囲は begin
/end
イテレーターで指定され、2 番目の範囲は begin
のみで指定されます。この関数はまた、アキュムレータの値を初期化するための 4 番目のパラメータとして init
を取ります。戻り値は与えられた範囲の最終的な内積の値です。std::inner_product
は常に指定された順序で演算を行うことに注意してください。
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
using std::copy;
using std::cout;
using std::endl;
using std::vector;
int main() {
vector<int> vec1{1, 2, 3, 4, 5};
vector<int> vec2{2, 4, 6, 8, 10};
copy(vec1.begin(), vec1.end(), std::ostream_iterator<int>(cout, "; "));
cout << endl;
copy(vec2.begin(), vec2.end(), std::ostream_iterator<int>(cout, "; "));
cout << endl;
cout << "Scalar product is: "
<< inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
cout << endl;
return EXIT_SUCCESS;
}
出力:
1; 2; 3; 4; 5;
2; 4; 6; 8; 10;
Scalar product is: 110
C++ で std::transform_reduce
を使用して 2つのベクトルの内積を計算する
前のメソッドとは異なり、std::transform_reduce
は範囲の順番を外して演算を行うことができるので、性能を最大化することができます。std::transform_reduce
は本質的に std::inner_product
アルゴリズムの並列化版です。以下の例は、前の例で渡した引数と同じ引数を用いてこの関数を実行する様子を示しています。
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
using std::copy;
using std::cout;
using std::endl;
using std::inner_product;
using std::vector;
int main() {
vector<int> vec1{1, 2, 3, 4, 5};
vector<int> vec2{2, 4, 6, 8, 10};
copy(vec1.begin(), vec1.end(), std::ostream_iterator<int>(cout, "; "));
cout << endl;
copy(vec2.begin(), vec2.end(), std::ostream_iterator<int>(cout, "; "));
cout << endl;
cout << "Scalar product is: "
<< std::transform_reduce(vec1.begin(), vec1.end(), vec2.begin(), 0);
return EXIT_SUCCESS;
}
出力:
1; 2; 3; 4; 5;
2; 4; 6; 8; 10;
Scalar product is: 110
std::transform_reduce
と std::execution::par
を利用して 2つのベクトルの内積を計算する
あるいは、std::transform_reduce
アルゴリズムの実行ポリシーを追加で指定することもできます。この方法では、このマニュアルで定義されているように、プログラムの流れを実行ルールでカスタマイズすることができるので、プログラマはより多くの制御を行うことができます。transform_reduce
を使用することで性能が向上するとはいえ、並列実行ポリシーを指定する際には、常に競合の可能性に注意しなければなりません。
#include <execution>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
using std::copy;
using std::cout;
using std::endl;
using std::inner_product;
using std::vector;
int main() {
vector<int> vec1{1, 2, 3, 4, 5};
vector<int> vec2{2, 4, 6, 8, 10};
copy(vec1.begin(), vec1.end(), std::ostream_iterator<int>(cout, "; "));
cout << endl;
copy(vec2.begin(), vec2.end(), std::ostream_iterator<int>(cout, "; "));
cout << endl;
cout << "Scalar product is: "
<< std::transform_reduce(std::execution::par, vec1.begin(), vec1.end(),
vec2.begin(), 0);
return EXIT_SUCCESS;
}
出力:
1; 2; 3; 4; 5;
2; 4; 6; 8; 10;
Scalar product is: 110