Произведения матриц и векторов

Умножение матриц является одной из базовых операций в различных численных методах. Например, она часто применяется при реализации прямого и обратного распространения сигнала в слоях нейронных сетей.

К разряду матричных произведений можно отнести также различного рода свертки. Группа таких функций в MQL5 выглядит следующим образом:

  • MatMul — матричное произведение двух матриц;
  • Power — возведение квадратной матрицы в указанную целочисленную степень;
  • Inner — внутреннее произведение двух матриц;
  • Outer — внешнее произведение двух матриц или двух векторов;
  • Kron — произведение Кронекера двух матриц, матрицы и вектора, вектора и матрицы или двух векторов;
  • CorrCoef — вычисление корреляции Пирсона между строками или столбцами матрицы, или между векторами;
  • Cov — вычисление ковариационной матрицы строк или столбцов матрицы, или между двумя векторами;
  • Correlate — вычисление взаимной корреляции (кросс-корреляции) двух векторов;
  • Convolve — вычисление дискретной линейной свертки двух векторов;
  • Dot — скалярное произведение двух векторов.

Чтобы дать общее представление, как управлять этими методами, приведем их прототипы (в порядке от матричных, через смешанные матрично-векторные, к векторным).

matrix<T> matrix<T>::MatMul(const matrix<T> &m)

matrix<T> matrix<T>::Power(const int power)

matrix<T> matrix<T>::Inner(const matrix<T> &m)

matrix<T> matrix<T>::Outer(const matrix<T> &m)

matrix<T> matrix<T>::Kron(const matrix<T> &m)

matrix<T> matrix<T>::Kron(const vector<T> &v)

matrix<T> matrix<T>::CorrCoef(const bool rows = true)

matrix<T> matrix<T>::Cov(const bool rows = true)

matrix<T> vector<T>::Cov(const vector<T> &v)

                 T vector<T>::CorrCoef(const vector<T> &v)

vector<T> vector<T>::Correlate(const vector<T> &v, ENUM_VECTOR_CONVOLVE mode)

vector<T> vector<T>::Convolve(const vector<T> &v, ENUM_VECTOR_CONVOLVE mode)

matrix<T> vector<T>::Outer(const vector<T> &v)

matrix<T> vector<T>::Kron(const matrix<T> &m)

matrix<T> vector<T>::Kron(const vector<T> &v)

                 T vector<T>::Dot(const vector<T> &v)

Вот простой пример матричного произведения двух матриц с помощью метода MatMul:

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

Умножать между собой можно матрицы вида A[M,N] * B[N,K] = С[M,K], то есть количество столбцов в матрице слева должно быть равно количеству строк в матрице справа. Если размеры не согласованы, результатом будет пустая матрица.

При умножении матрицы и вектора допустимы два варианта:

  • горизонтальный вектор (строка) умножается на матрицу справа, длина вектора равна количеству строк матрицы;
  • матрица умножается на вертикальный вектор (столбец) справа, длина вектора равна количеству столбцов матрицы.

Векторы также можно перемножать между собой. В MatMul это всегда эквивалентно скалярному произведению (метод Dot) вектора-строки на вектор-столбец, а вариант, когда вектор-столбец умножается на вектор-строку и получается матрица, поддерживается другим методом — Outer.

Продемонстрируем Outer-произведение вектора v5 на вектор v3 и в обратной последовательности. В обоих случаях слева подразумевается вектор-столбец, а справа — вектор-строка.

vector v3 = {123};
vector v5 = {12345};
Print("v5 = \n"v5);
Print("v3 = \n"v3);
Print("v5.Outer(v3) = m[5,3] \n"v5.Outer(v3));
Print("v3.Outer(v5) = m[3,5] \n"v3.Outer(v5));
/*
   v5 =
   [1,2,3,4,5]
   v3 =
   [1,2,3]
   v5.Outer(v3) = m[5,3]
   [[1,2,3]
    [2,4,6]
    [3,6,9]
    [4,8,12]
    [5,10,15]]
   v3.Outer(v5) = m[3,5]
   [[1,2,3,4,5]
    [2,4,6,8,10]
    [3,6,9,12,15]]
*/