MatMul

行列とベクトルの乗算を可能にするMatMulメソッドには、いくつかのオーバーロードがあります。

Multiplying a matrix by a matrix: matrix[M][K] * matrix[K][N] = matrix[M][N]

matrix  matrix::MatMul(
  const matrix&  b      // 2番目の行列
  );

Multiplying a vector by a matrix: horizontal vector[K] * matrix[K][N] = horizontal vector[N]

vector  vector::MatMul(
  const matrix&  b      // 行列
  );

Multiplying a matrix by a vector: matrix[M][K] * vertical vector[K] = vertical vector[M]

vector  matrix::MatMul(
  const vector&  b      // ベクトル
  );

Scalar vector multiplication: horizontal vector * vertical vector = dot value

scalar  vector::MatMul(
  const vector&  b      // 2番目のベクトル
  );

パラメータ

b

[in] 行列/ベクトル

戻り値

使用するメソッドに応じて、行列、ベクトル、またはスカラー。

注意事項

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

行列積は、最初の行列の行ベクトルと 2 番目の行列の列ベクトルのスカラー積のすべての可能な組み合わせで構成されます。

スカラー乗算では、ベクトルは同じ長さでなければなりません。

ベクトルと行列を乗算する場合、ベクトルの長さは行列の列数と正確に一致する必要があります。

 

次は、MQL5での単純な行列乗算アルゴリズムです。

matrix MatrixProduct(const matrix& matrix_a, const matrix& matrix_b)
 {
  matrix matrix_c;
 
  if(matrix_a.Cols()!=matrix_b.Rows())
    return(matrix_c);
     
  ulong M=matrix_a.Rows();
  ulong K=matrix_a.Cols();
  ulong N=matrix_b.Cols();
  matrix_c=matrix::Zeros(M,N);
 
  for(ulong m=0; m<M; m++)
    for(ulong k=0; k<K; k++)
        for(ulong n=0; n<N; n++)
          matrix_c[m][n]+=matrix_a[m][k]*matrix_b[k][n];
 
  return(matrix_c);
 }

 

行列乗算例

  matrix a={{1, 0, 0},
            {0, 1, 0}};
  matrix b={{4, 1},
            {2, 2},
            {1, 3}};
  matrix c1=a.MatMul(b);
  matrix c2=b.MatMul(a);
  Print("c1 = \n", c1);
  Print("c2 = \n", c2);
/*
  c1 =
  [[4,1]
   [2,2]]
  c2 =
  [[4,1,0]
   [2,2,0]
   [1,3,0]]
*/

 

水平ベクトルに行列を乗算する例

//+------------------------------------------------------------------+
//| スクリプトプログラム開始関数                                              |
//+------------------------------------------------------------------+
void OnStart()
 {
//--- 3x5行列を作成する
  matrix m35;
  m35.Init(3, 5, Arange);
//---
  vector v3 = {1, 2, 3};
  Print("Product of horizontal vector v and matrix m[3,5]");
  Print("On the left, vector v3 = ", v3);
  Print("On the right, matrix m35 = \n", m35);
  Print("v3.MatMul(m35) = horizontal vector v[5] \n", v3.MatMul(m35));
 
  /* 結果
   Product of horizontal vector v3 and matrix m[3,5]
   On the left, vector v3 = [1,2,3]
   On the right, matrix m35 =
   [[0,1,2,3,4]
    [5,6,7,8,9]
    [10,11,12,13,14]]
  v3.MatMul(m35) = horizontal vector v[5]
   [40,46,52,58,64]
  */
 }
//+------------------------------------------------------------------+
//|  増加する値で行列を埋める                                              |
//+------------------------------------------------------------------+
void Arange(matrix & m, double start = 0, double step = 1)
 {
//---
  ulong cols = m.Cols();
  ulong rows = m.Rows();
  double value = start;
  for(ulong r = 0; r < rows; r++)
    {
    for(ulong c = 0; c < cols; c++)
       {
        m[r][c] = value;
        value += step;
       }
    }
//---
 }

 

An example of how to multiply a matrix by a vertical vector

//+------------------------------------------------------------------+
//| スクリプトプログラム開始関数                                              |
//+------------------------------------------------------------------+
void OnStart()
 {
//--- 3x5行列を作成する
  matrix m35;
  m35.Init(3, 5, Arange);
//---
  Print("Product of matrix m[3,5] and vertical vector v[5]");
  vector v5 = {1,2,3,4,5};
  Print("On the left, m35 = \n",m35);
  Print("On the right v5 = ",v5);
  Print("m35.MatMul(v5) = vertical vector v[3] \n",m35.MatMul(v5));
 
  /* 結果
  Product of matrix m[3,5] and vertical vector v[5]
  On the left, m35 =
  [[0,1,2,3,4]
   [5,6,7,8,9]
   [10,11,12,13,14]]
  On the right, v5 = [1,2,3,4,5]
  m35.MatMul(v5) = vertical vector v[3]
  [40,115,190]
  */
 }
//+------------------------------------------------------------------+
//|  増加する値で行列を埋める                                              |
//+------------------------------------------------------------------+
void Arange(matrix & m, double start = 0, double step = 1)
 {
//---
  ulong cols = m.Cols();
  ulong rows = m.Rows();
  double value = start;
  for(ulong r = 0; r < rows; r++)
    {
    for(ulong c = 0; c < cols; c++)
       {
        m[r][c] = value;
        value += step;
       }
    }
//---
 }

 

ベクトルのスカラー(ドット)積の例

void OnStart()
 {
//--- 水平ベクトルと垂直ベクトルのスカラー積
  vector a= {1, 2, 3}; // 水平ベクトル
  vector b= {4, 5, 6}; // 垂直ベクトル
  Print("a = ", a);
  Print("b = ", b);
  Print("1) a.MatMul(b) = ", a.MatMul(b));
  //--- Dotメソッドが同じ結果を生成することを確認する
  Print("2) a.Dot(b) = ", a.Dot(b));
 
  /* 結果
  a = [1,2,3]
  b = [4,5,6]
  1) a.MatMul(b) = 32.0
  2) a.Dot(b) = 32.0
   */
 }

 

参照

DotGeMM