MatMul

Метод MatMul для выполнения произведения матриц и векторов  имеет несколько перегрузок.

Умножение матрицы на матрицу: matrix[M][K] * matrix[K][N] = matrix[M][N]

matrix  matrix::MatMul(
  const matrix&  b      // вторая матрица
   );

Умножение вектора на матрицу: horizontal vector[K] * matrix[K][N] = horizontal vector[N]

vector  vector::MatMul(
  const matrix&  b      // матрица
   );

Умножение матрицы на вектор: matrix[M][K] * vertical vector[K] = vertical vector[M]

vector  matrix::MatMul(
  const vector&  b      // вектор
   );

Скалярное умножение векторов: horizontal vector * vertical vector = dot value

scalar  vector::MatMul(
  const vector&  b      // второй вектор
   );

Параметры

b

[in]  Матрица или вектор.

Возвращаемое значение

Матрица, вектор или скаляр в зависимости от используемого метода.

Примечание

Перемножаемые матрицы должны быть совместимы, количество столбцов первой матрицы должно быть равно количеству строк второй матрицы. Перемножение матриц некоммутативно, умножение первой матрицы на вторую в общем случае не равно умножению второй матрицы на первую.

Произведение матриц состоит из всех возможных комбинаций скалярных произведений вектор-строк первой матрицы и вектор-столбцов второй матрицы.

При скалярном умножении векторов их длины должны совпадать.

При умножении вектора и матрицы длина вектора должна точно соответствовать количеству столбцов матрицы.

 

Наивный алгоритм перемножения матриц на MQL5:

matrix MatrixProduct(const matrixmatrix_aconst matrixmatrix_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=0m<Mm++)
      for(ulong k=0k<Kk++)
         for(ulong n=0n<Nn++)
            matrix_c[m][n]+=matrix_a[m][k]*matrix_b[k][n];
 
   return(matrix_c);
  }

 

Пример умножения матриц

   matrix a={{100},
             {010}};
   matrix b={{41},
             {22},
             {13}};
   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]]
*/

 

Пример умножения горизонтального вектора на матрицу

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- создадим матрицу 3x5
   matrix m35;
   m35.Init(35Arange);
//---
   vector v3 = {123};
   Print("Произведение горизонтального вектора v на матрицу m[3,5]");
   Print("Слева вектор v3 = "v3);
   Print("Справа матрица m35 = \n"m35);
   Print("v3.MatMul(m35) = горизонтальный вектор v[5] \n"v3.MatMul(m35));
 
   /* Результат
    Произведение горизонтального вектора v3 на матрицу m[3,5]
    Слева вектор v3 = [1,2,3]
    Справа матрица m35 =
    [[0,1,2,3,4]
     [5,6,7,8,9]
     [10,11,12,13,14]]
    v3.MatMul(m35) = горизонтальный вектор v[5]
    [40,46,52,58,64]
   */
  }
//+------------------------------------------------------------------+
//|  Заполнение матрицы нарастающими значениями                      |
//+------------------------------------------------------------------+
void Arange(matrix & mdouble start = 0double step = 1)
  {
//---
   ulong cols = m.Cols();
   ulong rows = m.Rows();
   double value = start;
   for(ulong r = 0r < rowsr++)
     {
      for(ulong c = 0c < colsc++)
        {
         m[r][c] = value;
         value += step;
        }
     }
//---
  }

 

Пример умножения матрицы на вертикальный вектор

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- создадим матрицу 3x5
   matrix m35;
   m35.Init(35Arange);
//---
   Print("Произведение матрицы m[3,5] на вертикальный вектор v[5]");
   vector v5 = {1,2,3,4,5};
   Print("Слева m35 = \n",m35);
   Print("Справа v5 = ",v5);
   Print("m35.MatMul(v5) = вертикальный вектор v[3] \n",m35.MatMul(v5));
 
   /* Результат
   Произведение матрицы m[3,5] на вертикальный вектор v[5]
   Слева m35 = 
   [[0,1,2,3,4]
    [5,6,7,8,9]
    [10,11,12,13,14]]
   Справа v5 = [1,2,3,4,5]
   m35.MatMul(v5) = вертикальный вектор v[3
   [40,115,190]
   */
  }
//+------------------------------------------------------------------+
//|  Заполнение матрицы нарастающими значениями                      |
//+------------------------------------------------------------------+
void Arange(matrix & mdouble start = 0double step = 1)
  {
//---
   ulong cols = m.Cols();
   ulong rows = m.Rows();
   double value = start;
   for(ulong r = 0r < rowsr++)
     {
      for(ulong c = 0c < colsc++)
        {
         m[r][c] = value;
         value += step;
        }
     }
//---
  }

 

Пример скалярного умножения векторов

void OnStart()
  {
//--- скалярное умножение горизонтального и вертикального векторов
   vector a= {123};  // горизонтальный вектор
   vector b= {456};  // вертикальный вектор
   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]
   1a.MatMul(b) = 32.0
   2a.Dot(b) = 32.0
    */
  }

 

Смотри также

Dot, GeMM