MQL5 中的矩阵和向量

向量(vector)是一个一维的双精度型(double)数组。 针对向量定义了以下运算:加法和乘法,以及获取向量长度或模(module)的范数(Norm)。 在程序化过程中,向量通常由同质元素的数组来表示,针对这些不能定义非规则向量运算,即数组不能相加或相乘,并且它们没有范数。

在数学中,向量可以表示为行向量,即由一行和 n 列组成的数组,以及字符串向量,即由一列和 n 行组成的矩阵。 在 MQL5 中,“vector(向量)”类型没有行和列子类型,因此程序员必须了解特定运算中所用的是哪种向量类型。

使用以下内置方法创建和初始化向量。

方法NumPy 类比说明
void vector.Init( ulong size);创建指定长度的向量,其中的值未定义
static vector vector::Ones(ulong size); ones创建指定长度的向量,用一填充
static vector vector::Zeros(ulong size); zeros创建指定长度的向量,用零填充
static vector vector::Full(ulong size,double value); full创建指定长度的向量,并用指定值填充
operator =返回向量的副本
void vector.Resize(const vector v);往结尾添加新值来调整向量大小 

矢量创建示例:

void OnStart(){
//--- vector initialization examplesvector v;v.Init(7);Print("v = ", v); vector v1=vector::Ones(5);Print("v1 = ", v1);vector v2=vector::Zeros(3);Print("v2 = ", v2);vector v3=vector::Full(6, 2.5);Print("v3 = ", v3);vector v4{1, 2, 3};Print("v4 = ", v4);  v4.Resize(5);Print("after Resize(5) v4 = ", v4);  vector v5=v4;Print("v5 = ", v5);  v4.Fill(7);Print("v4 = ", v4, "   v5 =",v5);  }/*
Execution resultv = [4,5,6,8,10,12,12]
v1 = [1,1,1,1,1]
v2 = [0,0,0]
v3 = [2.5,2.5,2.5,2.5,2.5,2.5]
v4 = [1,2,3]
after Resize(5) v4 = [1,2,3,7,7]
v5 = [1,2,3,7,7]
v4 = [7,7,7,7,7]   v5 =[1,2,3,7,7]*/ 

Init() 方法不仅可用于为向量分配内存,还可依据函数值来初始化向量元素。 在这种情况下,向量大小作为第一个参数传递给 Init,函数名作为第二个参数。 如果函数包含参数,则应在函数名后立即指定这些参数,并用逗号分隔。

函数本身必须包含向量的引用,且作为第一个参数传入。 在 Init 调用期间不应传递向量。 我们以 Arange 函数为例来查看方法的运算。 此函数模仿 numpy.arange。

void OnStart(){
//---vector v;v.Init(7,Arange,10,0,0.5); // 3 parameters are passed with Arange callPrint("v = ", v);Print("v.size = ",v.Size());}
//+------------------------------------------------------------------+
//|  Values are generated within the half-open interval [start, stop)|
//+------------------------------------------------------------------+
void Arange(vector& v, double stop, double start = 0, double step = 1) // the function has 4 parameters{if(start >= stop){PrintFormat("%s wrong parameters! start=%G  stop=%G", __FILE__,start, stop);return;}
//---int size = (int)((stop - start) / step);v.Resize(size);double value = start;for(ulong i = 0; i < v.Size(); i++){v[i] = value;value += step;}}/*
Execution resultv = [0,0.5,1,1.5,2,2.5,3,3.5,4,4.5,5,5.5,6,6.5,7,7.5,8,8.5,9,9.5]
v.size = 20*/

Arange 函数有两个可选参数,“start” 和 “stop”。 因此,Init(7,Arange,10) 的另一个可能调用和相关结果如下:

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(){
//---vector v;v.Init(7,Arange,10);Print("v = ", v);Print("v.size = ",v.Size());}
.../*v = [0,1,2,3,4,5,6,7,8,9]
v.size = 10*/

向量运算

通常可以在向量上执行使用标量的加、减、乘、除运算。

//+------------------------------------------------------------------+
//|                                              vector2_article.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(){
//---vector v= {1, 2, 3, 4, 5};Print("Examples without saving vector changes");Print("v = ", v);Print("v+5 = ", v+5);Print("v-Pi= ", v-M_PI);Print("v*2.0= ", v*2);Print("v/3.0= ", v/3.0);Print("Save all vector changes");Print("v = ", v);Print("v+5 = ", v=v+5);Print("v-Pi= ", v=v-M_PI);Print("v*2.0= ", v= v*2);Print("v/3.0= ", v= v/3.0);}
/*
Execution resultExamples without saving vector changes
v = [1,2,3,4,5]
v+5 = [6,7,8,9,10]
v-Pi= [-2.141592653589793,-1.141592653589793,-0.1415926535897931,0.8584073464102069,1.858407346410207]
v*2.0= [2,4,6,8,10]
v/3.0= [0.3333333333333333,0.6666666666666666,1,1.333333333333333,1.666666666666667]
Save all vector changes
v = [1,2,3,4,5]
v+5 = [6,7,8,9,10]
v-Pi= [2.858407346410207,3.858407346410207,4.858407346410207,5.858407346410207,6.858407346410207]
v*2.0= [5.716814692820414,7.716814692820414,9.716814692820414,11.71681469282041,13.71681469282041]
v/3.0= [1.905604897606805,2.572271564273471,3.238938230940138,3.905604897606805,4.572271564273471]*/
//+------------------------------------------------------------------+

向量支持两个大小相同向量的元素加法、减法、乘法和除法运算。

void OnStart(){
//---vector a = {1, 2, 3};vector b = {2, 4, 6};Print("a + b = ", a + b);Print("a - b = ", a - b);Print("a * b = ", a * b);Print("b / a = ", b / a);}/*
Execution resulta + b = [3,6,9]
a - b = [-1,-2,-3]
a * b = [2,8,18]
b / a = [2,2,2]*/

为这些数据类型定义了四种运算。

void OnStart(){
//---vector a={1, 2, 3};vector b={4, 5, 6};Print("a = ", a);Print("b = ", b);Print("1) a.Dot(b) = ", a.Dot(b));Print("2) a.MatMul(b) = ", a.MatMul(b));Print("3) a.Kron(b) = ", a.Kron(b));Print("4) a.Outer(b) = \n", a.Outer(b));}
/*
Execution resulta = [1,2,3]
b = [4,5,6]
1) a.Dot(b) = 32.0
2) a.MatMul(b) = 32.0
3) a.Kron(b) = [[4,5,6,8,10,12,12,15,18]]
4) a.Outer(b) = 
[[4,5,6][8,10,12][12,15,18]]*/

如您从示例中所见,Outer 方法返回一个矩阵,其中行数和列数对应于相乘向量的大小。 Dot 和 MatMul 的操作方式相同。

向量范数

向量和矩阵范数表示向量长度(量级)和绝对值。 计算向量范数的三种可能方法已罗列在 ENUM_VECTOR_NORM 枚举之中。

void OnStart(){
//---struct str_vector_norm{ENUM_VECTOR_NORM  norm;int               value;};str_vector_norm vector_norm[]={{VECTOR_NORM_INF,       0},{VECTOR_NORM_MINUS_INF, 0},{VECTOR_NORM_P,         0},{VECTOR_NORM_P,         1},{VECTOR_NORM_P,         2},{VECTOR_NORM_P,         3},{VECTOR_NORM_P,         4},{VECTOR_NORM_P,         5},{VECTOR_NORM_P,         6},{VECTOR_NORM_P,         7},{VECTOR_NORM_P,        -1},{VECTOR_NORM_P,        -2},{VECTOR_NORM_P,        -3},{VECTOR_NORM_P,        -4},{VECTOR_NORM_P,        -5},{VECTOR_NORM_P,        -6},{VECTOR_NORM_P,        -7}};vector v{1, 2, 3, 4, 5, 6, 7};double norm;Print("v = ", v);
//---for(int i=0; i 

利用范数,可以测量两个向量之间的距离:

void OnStart(){
//---vector a{1,2,3};vector b{2,3,4};double distance=(b-a).Norm(VECTOR_NORM_P,2);Print("a = ",a);Print("b = ",b);Print("|a-b| = ",distance);   }
/*
Execution resulta = [1,2,3]
b = [2,3,4]
|a-b| = 1.7320508075688772*/

“矩阵(matrix)” 类型

向量是矩阵的特例,它实际上是一个双精度(double)型的二维数组。 故此,矩阵可以被视为大小相同的向量数组。 矩阵的行数对应于向量的数量,而列数等于向量长度。 

加法和乘法运算也适用于矩阵。 传统的编程语言使用数组来表示矩阵。 但是,常规数组之间不能相加或相乘,它们也没有范数。数学上考虑了许多不同的矩阵类型。 例如,单位矩阵、对称矩阵、斜对称矩阵、上下三角矩阵、等类型。

与向量方法类似,矩阵也能利用内置方法创建和初始化。

方法

NumPy 中的类比法

说明

void static matrix.Eye(const int rows, const int cols, const int ndiag=0)

eye

构造一个矩阵,在指定的对角线上填 1,在其它地方填 0

void matrix.Identity()

identity

在矩阵主对角线上填 1,并在其它地方填 0

void static matrix.Ones(const int rows, const int cols)

ones

根据行数和列数构造一个新的矩阵,并用 1 填充

void static matrix.Zeros(const int rows, const int cols)

zeros

根据行数和列数构造一个新的矩阵,并用 0 填充

void static matrix.Tri(const int rows, const int cols, const int ndiag=0)tri构造一个矩阵,在指定对角线上填 1,在其下和其它地方填 0 
void matrix.Diag(const vector v, const int ndiag=0) diag提取对角线或构造对角线矩阵 

void matrix.Full(const int rows, const int cols, const scalar value)

full

根据行数和列数构造一个新矩阵,并用标量值填充

void matrix.Fill(const scalar value)  用指定的值填充矩阵

矩阵构造和填充示例:

void OnStart(){
//---matrix m{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};Print("m = \n", m);matrix ones=matrix::Ones(4, 4);Print("ones = \n", ones);matrix zeros=matrix::Zeros(4, 4);Print("zeros = \n", zeros);matrix eye=matrix::Eye(4, 4);Print("eye = \n", eye);matrix identity(4, 5);Print("matrix_identity\n", identity);identity.Identity();Print("matrix_identity\n", identity);matrix tri=matrix::Tri(3, 4);Print("tri = \n", tri);Print("tri.Transpose() = \n", tri.Transpose()); // transpose the matrixmatrix diag(5, 5);Print("diag = \n", diag);vector d{1, 2, 3, 4, 5};diag.Diag(d);Print("diag = \n", diag); // insert values from the vector into the matrix diagonalmatrix fill(5, 5);fill.Fill(10);Print("fill = \n", fill);matrix full =matrix::Full(5, 5, 100);Print("full = \n", full);matrix init(5, 7);Print("init = \n", init);m.Init(4, 6);Print("init = \n", init);matrix resize=matrix::Full(2, 2, 5);  resize.Resize(5,5);Print("resize = \n", resize);  }
/*
Execution resultm =
[[1,2,3]
[4,5,6]
[7,8,9]]
ones =
[[1,1,1,1]
[1,1,1,1]
[1,1,1,1]
[1,1,1,1]]
zeros =
[[0,0,0,0]
[0,0,0,0]
[0,0,0,0]
[0,0,0,0]]
eye =
[[1,0,0,0]
[0,1,0,0]
[0,0,1,0]
[0,0,0,1]]
matrix_identity
[[1,0,0,0,0]
[0,1,0,0,0]
[0,0,1,0,0]
[0,0,0,1,0]]
matrix_identity
[[1,0,0,0,0]
[0,1,0,0,0]
[0,0,1,0,0]
[0,0,0,1,0]]
tri =
[[1,0,0,0]
[1,1,0,0]
[1,1,1,0]]
tri.Transpose() =
[[1,1,1]
[0,1,1]
[0,0,1]
[0,0,0]]
diag =
[[0,0,0,0,0]
[0,0,0,0,0]
[0,0,0,0,0]
[0,0,0,0,0]
[0,0,0,0,0]]
diag =
[[1,0,0,0,0]
[0,2,0,0,0]
[0,0,3,0,0]
[0,0,0,4,0]
[0,0,0,0,5]]
fill =
[[10,10,10,10,10]
[10,10,10,10,10]
[10,10,10,10,10]
[10,10,10,10,10]
[10,10,10,10,10]]
full =
[[100,100,100,100,100]
[100,100,100,100,100]
[100,100,100,100,100]
[100,100,100,100,100]
[100,100,100,100,100]]
resize = 
[[5,5,0,0,0][5,5,0,0,0][0,0,0,0,0][0,0,0,0,0][0,0,0,0,0]]*/


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部