C++ で 2つのベクトルの内積を計算する

胡金庫 2023年10月12日
  1. C++ で 2つのベクトルの内積を計算するには、std::inner_product を使用する
  2. C++ で std::transform_reduce を使用して 2つのベクトルの内積を計算する
  3. std::transform_reducestd::execution::par を利用して 2つのベクトルの内積を計算する
C++ で 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_reducestd::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
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C++ Vector