跳至内容

MatMul

MatMul

MatMul 方法支持矩阵和向量的乘法,具有若干个重载。

矩阵乘以矩阵: matrix[M][K] * matrix[K][N] = matrix[M][N]

matrix  matrix::MatMul(
  const matrix&  b      // 第二个矩阵
   );

向量乘以矩阵: horizontalvector[K] * matrix[K][N] = horizontalvector[N]

vector  vector::MatMul(
  const matrix&  b      // 矩阵
   );

矩阵乘以向量: matrix[M][K] * verticalvector[K] = verticalvector[M]

vector  matrix::MatMul(
  const vector&  b      // 向量
   );

标量向量乘法: horizontalvector * verticalvector = dotvalue

scalar  vector::MatMul(
  const vector&  b      // 第二个向量
   );

参数

b

[输入] 矩阵或向量。

返回值

矩阵、矢量或标量,具体取决于所使用的方法。

注意

矩阵应兼容乘法,即第一个矩阵中的列数应等于第二个矩阵中的行数。 矩阵乘法不支持交换律:在一般情况下,将第一个矩阵乘以第二个矩阵的结果不等于将第二个矩阵乘以第一个矩阵的结果。

矩阵积由第一个矩阵的行向量和第二个矩阵的列向量的标量积的所有可能组合组成。

在标量乘法中,向量必须具有相同的长度。

当向量和矩阵相乘时,向量的长度必须与矩阵中的列数完全匹配。

以 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]]
*/

水平向量乘以矩阵的示例

//+------------------------------------------------------------------+
//| 脚本程序 start 函数                                                |
//+------------------------------------------------------------------+
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;
        }
     }
//---
  }

矩阵如何乘以垂直向量的示例

//+------------------------------------------------------------------+
//| 脚本程序 start 函数                                                |
//+------------------------------------------------------------------+
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
    */
  }

参见

Dot, GeMM