MatMul
Phương thức MatMul
, cho phép nhân ma trận và vector, có nhiều biến thể.
Nhân ma trận với ma trận: matrix[M][K] * matrix[K][N] = matrix[M][N]
matrix matrix::MatMul(
const matrix& b // ma trận thứ hai
);
2
3
Nhân vector với ma trận: horizontal vector[K] * matrix[K][N] = horizontal vector[N]
vector vector::MatMul(
const matrix& b // ma trận
);
2
3
Nhân ma trận với vector: matrix[M][K] * vertical vector[K] = vertical vector[M]
vector matrix::MatMul(
const vector& b // vector
);
2
3
Nhân vô hướng giữa hai vector: horizontal vector * vertical vector = dot value
scalar vector::MatMul(
const vector& b // vector thứ hai
);
2
3
Tham số
b
Mô tả tham số
[in] Ma trận hoặc vector.
Giá trị trả về
Ma trận, vector hoặc giá trị vô hướng, tùy thuộc vào phương thức được sử dụng.
Ghi chú
Các ma trận cần tương thích để nhân, tức là số cột của ma trận đầu tiên phải bằng số hàng của ma trận thứ hai. Phép nhân ma trận không có tính giao hoán: kết quả của việc nhân ma trận đầu tiên với ma trận thứ hai không bằng kết quả của việc nhân ma trận thứ hai với ma trận đầu tiên trong trường hợp tổng quát.
Tích ma trận bao gồm tất cả các tổ hợp có thể của tích vô hướng giữa các vector hàng của ma trận đầu tiên và các vector cột của ma trận thứ hai.
Trong phép nhân vô hướng, các vector phải có cùng độ dài.
Khi nhân một vector với một ma trận, độ dài của vector phải khớp chính xác với số cột của ma trận.
Thuật toán nhân ma trận đơn giản trong 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);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Ví dụ về nhân ma trận
matrix a={{1, 0, 0},
{0, 1, 0}};
matrix b={{4, 1},
}
```cpp
{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]]
*/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Ví dụ về nhân vector ngang với ma trận
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- create a 3x5 matrix
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));
/* Result
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]
*/
}
//+------------------------------------------------------------------+
//| Fill the matrix with increasing values |
//+------------------------------------------------------------------+
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;
}
}
//---
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Ví dụ về cách nhân ma trận với vector dọc
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- create a 3x5 matrix
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));
/* Result
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]
*/
}
//+------------------------------------------------------------------+
//| Fill the matrix with increasing values |
//+------------------------------------------------------------------+
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;
}
}
//---
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Ví dụ về tích vô hướng (dot) của các vector
void OnStart()
{
//--- scalar product of a horizontal vector and a vertical one
vector a= {1, 2, 3}; // horizontal vector
vector b= {4, 5, 6}; // vertical vector
Print("a = ", a);
Print("b = ", b);
Print("1) a.MatMul(b) = ", a.MatMul(b));
//--- see that the Dot method generates the same result
Print("2) a.Dot(b) = ", a.Dot(b));
/* Result
a = [1,2,3]
b = [4,5,6]
1) a.MatMul(b) = 32.0
2) a.Dot(b) = 32.0
*/
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Xem thêm