GeMM

GeMM (General Matrix Multiply)メソッドは、2つの行列の一般的な乗算を実装します。演算はC ← α A B + β Cとして定義されます。ここで、A行列とB行列はオプションで転置できます。行列ABの通常の乗算(MatMul)では、alphaスカラーは1に等しいと想定され、ベータはゼロに等しくなります。

効率におけるGeMMとMatMulの主な違いは、MatMulは常に新しい行列/ベクトルオブジェクトを作成するのに対し、GeMMは既存の行列オブジェクトで動作し、再作成しないことです。したがって、GeMMを使用して対応する行列にメモリを事前に割り当てると、同じ行列サイズで作業している間、メモリの再割り当ては行われません。これは、たとえば、ストラテジーテスターで最適化を実行する場合やニューラルネットワークをトレーニングする場合など、バルクコンピューティングにおけるGeMMの重要な利点となります。

MatMulと同様に、GeMMにも4つのオーバーロードがあります。ただし、4番目のオーバーロードのセマンティクスは、垂直ベクトルと水平ベクトルの乗算を可能にするために変更されています。

既存の行列/ベクトルオブジェクトでは、メモリを事前に割り当てる必要はありません。メモリは、最初のGeMM呼び出しで割り当てられ、ゼロで埋められます。

行列と行列の乗算   matrix C[M][N] = α * ( matrix A[M][K] * matrix B[K][N]) + β * matrix C[M][N]

bool  matrix::GeMM(
  const matrix &A,    // 1番目の行列
  const matrix &B,    // 2番目の行列
double alpha,      // 積ABのアルファ乗数
double beta,       // 行列Cのベータ乗数
uint  flags       // 行列A、B、Cが転置されるかどうかを決定するENUM_GEMM値の組み合わせ(ビットOR)
  );

ベクトルと行列の乗算 vector C[N] = α * ( vector A[K] * matrix B[K][N]) + β * vector C[N]

bool  vector::GeMM(
  const vector &A,    // 水平ベクトル
  const matrix &B,    // 行列
double alpha,      // 積ABのアルファ乗数
double beta,       // ベクトルCのベータ乗数
uint  flags       // 行列Aが転置されるかどうかを決定するENUM_GEMM列挙値
  );

行列とベクトルの乗算 vector C[M] = α * ( matrix A[M][K] * vector B[K] * ) + β * vector C[M]

bool  vector::GeMM(
  const matrix &A,    // 行列
  const vector &B,    // 垂直ベクトル
double alpha,      // 積ABのアルファ乗数
double beta,       // ベクトルCのベータ乗数
uint  flags       // 行列Bが転置されるかどうかを決定するENUM_GEMM列挙値
  );

ベクトルとベクトルの乗算: matrix C[M][N] = α * ( vector A[M] * vector B[N] * ) + β * matrix C[M][N]. このオーバーロードは、スカラーを返すMatMulとは異なり、行列を返します。

bool  matrix::GeMM(
  const vector &A,    // 1番目のベクトル
  const vector &B,    // 2番目のベクトル
double alpha,      // 積ABのアルファ乗数
double beta,       // 行列Cのベータ
uint  flags       // 行列Cが転置されるかどうかを決定するENUM_GEMM列挙値
  );

パラメータ

A

[in] 行列/ベクトル

B

[in] 行列/ベクトル

alpha

[in] AB積のアルファ乗数

beta

[in] 結果のC行列のベータ乗数

フラグ

[in] 行列A、B、Cが転置されるかどうかを決定するENUM_GEMM列挙値

戻り値

成功の場合はtrue、それ以外の場合はfalse

ENUM_GEMM

GeMMメソッドのフラグの列挙

ID

説明

TRANSP_A

転置行列Aを使用

TRANSP_B

転置行列Bを使用

TRANSP_C

転置行列Cを使用

注意事項

float、double、complex型の行列とベクトルは、パラメータAとBとして使用できます。GeMMメソッドのテンプレートバリアントは次のとおりです。

bool matrix<T>::GeMM(const matrix<T> &A,const matrix<T> &B,T alpha,T beta,ulong flags);
bool matrix<T>::GeMM(const vector<T> &A,const vector<T> &B,T alpha,T beta,ulong flags);
 
bool vector<T>::GeMM(const vector<T> &A,const matrix<T> &B,T alpha,T beta,ulong flags);
bool vector<T>::GeMM(const matrix<T> &A,const vector<T> &B,T alpha,T beta,ulong flags);

基本的に、一般的な行列乗算関数は次のように記述されます。

C[m,n] = α *Sum(A[m,k]*B[k,n]) + β*C[m,n]

行列AはM x K、行列BはK x N、行列CはM x Nです。

したがって、行列は乗算に対応している必要があります。つまり、1番目の行列の列数は2番目の行列の行数と等しくなければなりません。行列の乗算は可換ではありません。一般に、1番目の行列に2番目の行列を掛けた結果は、2番目の行列に最初の行列を掛けた結果と等しくありません。

 

例:

void OnStart()
 {
  vector vector_a= {1, 2, 3, 4, 5};
  vector vector_b= {4, 3, 2, 1};
  matrix matrix_c;
//--- 2つのベクトルのGeMMを計算する
  matrix_c.GeMM(vector_a, vector_b, 1, 0);
  Print("matrix_c:\n ", matrix_c, "\n");
  /*
  matrix_c:
   [[4,3,2,1]
   [8,6,4,2]
   [12,9,6,3]
   [16,12,8,4]
   [20,15,10,5]]
  */
//--- 行列をベクトルとして作成する
  matrix matrix_a(5, 1);
  matrix matrix_b(1, 4);
  matrix_a.Col(vector_a, 0);
  matrix_b.Row(vector_b, 0);
  Print("matrix_a:\n ", matrix_a);
  Print("matrix_b:\n ", matrix_b);
  /*
  matrix_a:
  [[1]
  [2]
  [3]
  [4]
  [5]]
  matrix_b:
  [[4,3,2,1]]
  */
//-- 2つの行列のGeMMを計算し、同じ結果を得る
  matrix_c.GeMM(matrix_a, matrix_b, 1, 0);
  Print("matrix_c:\n ", matrix_c);
  /*
  matrix_c:
   [[4,3,2,1]
   [8,6,4,2]
   [12,9,6,3]
   [16,12,8,4]
   [20,15,10,5]]
  */
 }

 

参照

MatMul