//+------------------------------------------------------------------+
//| 脚本程序开始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 矩阵的加法和乘法操作
CMatrix A(3),B(3),C();
//--- 准备数组行
double a1[3]={1,2,3}, a2[3]={2,3,1}, a3[3]={3,1,2};
double b1[3]={3,2,1}, b2[3]={1,3,2}, b3[3]={2,1,3};
//--- 填补矩阵
A[0]=a1; A[1]=a2; A[2]=a3;
B[0]=b1; B[1]=b2; B[2]=b3;
//--- 在专家日志输出矩阵
Print("---- Elements of matrix A");
Print(A.String());
Print("---- Elements of matrix B");
Print(B.String());
//--- 矩阵加法
Print("---- Addition of matrices A and B");
C=A+B;
//--- 输出格式化字符串表示
Print(C.String());
//--- 矩阵乘法
Print("---- Multiplication of matrices A and B");
C=A*B;
Print(C.String());
//--- 现在我们展示如何在动态数组matrix[i][j]风格下得到值
Print("Output the values of matrix C elementwise");
//--- 通过矩阵行 - CRow 对象 - 循环
for(int i=0;i<3;i++)
{
string com="| ";
//--- 形成矩阵的行值
for(int j=0;j<3;j++)
{
//--- 通过行数和列数获得矩阵元素
double element=C[i][j];// [i] - 在数组 m_rows[]访问CRow ,
// [j] - 重载CRow索引操作符
com=com+StringFormat("a(%d,%d)=%G ; ",i,j,element);
}
com+="|";
//--- 输出行值
Print(com);
}
}
//+------------------------------------------------------------------+
//| 类 "行" |
//+------------------------------------------------------------------+
class CRow
{
private:
double m_array[];
public:
//--- 构造函数和析构函数
CRow(void) { ArrayResize(m_array,0); }
CRow(const CRow &r) { this=r; }
CRow(const double &array[]);
~CRow(void){};
//--- 行的元素数
int Size(void) const { return(ArraySize(m_array));}
//--- 返回一个字符串值
string String(void) const;
//--- 索引操作符
double operator[](int i) const { return(m_array[i]); }
//--- 赋值操作符
void operator=(const double &array[]); // 数组
void operator=(const CRow & r); // 另一个 CRow 对象
double operator*(const CRow &o); // CRow 对象乘法
};
//+------------------------------------------------------------------+
//| 构造函数初始化数组行 |
//+------------------------------------------------------------------+
void CRow::CRow(const double &array[])
{
int size=ArraySize(array);
//--- 如果数组不为空
if(size>0)
{
ArrayResize(m_array,size);
//--- 填值
for(int i=0;i<size;i++)
m_array[i]=array[i];
}
//---
}
//+------------------------------------------------------------------+
//| 数组赋值操作 |
//+------------------------------------------------------------------+
void CRow::operator=(const double &array[])
{
int size=ArraySize(array);
if(size==0) return;
//--- 填充数组值
ArrayResize(m_array,size);
for(int i=0;i<size;i++) m_array[i]=array[i];
//---
}
//+------------------------------------------------------------------+
//| CRow 赋值操作 |
//+------------------------------------------------------------------+
void CRow::operator=(const CRow &r)
{
int size=r.Size();
if(size==0) return;
//--- 填充数组值
ArrayResize(m_array,size);
for(int i=0;i<size;i++) m_array[i]=r[i];
//---
}
//+------------------------------------------------------------------+
//| 另一行乘法的操作符 |
//+------------------------------------------------------------------+
double CRow::operator*(const CRow &o)
{
double res=0;
//--- 验证
int size=Size();
if(size!=o.Size() || size==0)
{
Print(__FUNCSIG__,": Failed to multiply two matrices, their sizes are different");
return(res);
}
//--- 乘以数组elementwise 并添加产品
for(int i=0;i<size;i++)
res+=m_array[i]*o[i];
//--- 结果
return(res);
}
//+------------------------------------------------------------------+
//| 返回格式化字符串表示方式 |
//+------------------------------------------------------------------+
string CRow::String(void) const
{
string out="";
//--- 如果数组大小大于零
int size=ArraySize(m_array);
//--- 我们只使用一个非零的数组元素
if(size>0)
{
out="{";
for(int i=0;i<size;i++)
{
//--- 收集字符串的值
out+=StringFormat(" %G;",m_array[i]);
}
out+=" }";
}
//--- 结果
return(out);
}
//+------------------------------------------------------------------+
//| 类 "Matrix" |
//+------------------------------------------------------------------+
class CMatrix
{
private:
CRow m_rows[];
public:
//--- 构造函数和析构函数
CMatrix(void);
CMatrix(int rows) { ArrayResize(m_rows,rows); }
~CMatrix(void){};
//--- 得到矩阵大小
int Rows() const { return(ArraySize(m_rows)); }
int Cols() const { return(Rows()>0? m_rows[0].Size():0); }
//--- 以CRow行的形式返回列的值
CRow GetColumnAsRow(const int col_index) const;
//--- 返回字符串矩阵值
string String(void) const;
//--- 索引操作符返回一个字符串数字
CRow *operator[](int i) const { return(GetPointer(m_rows[i])); }
//--- 加法操作符
CMatrix operator+(const CMatrix &m);
//--- 乘法操作符
CMatrix operator*(const CMatrix &m);
//--- 赋值操作符
CMatrix *operator=(const CMatrix &m);
};
//+------------------------------------------------------------------+
//| 默认构造函数,创建和零行的数组 |
//+------------------------------------------------------------------+
CMatrix::CMatrix(void)
{
//--- 零矩阵的行数
ArrayResize(m_rows,0);
//---
}
//+------------------------------------------------------------------+
//| 返回CRow形式的列值 |
//+------------------------------------------------------------------+
CRow CMatrix::GetColumnAsRow(const int col_index) const
{
//--- 获得列值的变量
CRow row();
//--- 矩阵的行数
int rows=Rows();
//--- 如果大于零的行数,执行操作
if(rows>0)
{
//--- 接收col_index索引列的值的数组
double array[];
ArrayResize(array,rows);
//--- 填充数组
for(int i=0;i<rows;i++)
{
//--- 检查i行的列数 - 它可能超过数组的限制
if(col_index>=this[i].Size())
{
Print(__FUNCSIG__,": Error! Column number ",col_index,"> row size ",i);
break; // 行将是未初始化对象
}
array[i]=this[i][col_index];
}
//--- 基于数组值创建CRow行
row=array;
}
//--- 结果
return(row);
}
//+------------------------------------------------------------------+
//| 两个矩阵的加法 |
//+------------------------------------------------------------------+
CMatrix CMatrix::operator+(const CMatrix &m)
{
//--- 通过矩阵的行数和列数
int cols=m.Cols();
int rows=m.Rows();
//--- 接收相加结果的矩阵
CMatrix res(rows);
//--- 矩阵大小必须匹配
if(cols!=Cols() || rows!=Rows())
{
//--- 无法相加
Print(__FUNCSIG__,": Failed to add two matrices, their sizes are different");
return(res);
}
//--- 辅助数组
double arr[];
ArrayResize(arr,cols);
//--- 通过行相加
for(int i=0;i<rows;i++)
{
//--- 写下数组中矩阵字符串的加法结果
for(int k=0;k<cols;k++)
{
arr[k]=this[i][k]+m[i][k];
}
//--- 将数组放在矩阵行
res[i]=arr;
}
//--- 返回矩阵相加结果
return(res);
}
//+------------------------------------------------------------------+
//| 两个矩阵的乘法 |
//+------------------------------------------------------------------+
CMatrix CMatrix::operator*(const CMatrix &m)
{
//--- 第一个矩阵的列数,通过矩阵的行数
int cols1=Cols();
int rows2=m.Rows();
int rows1=Rows();
int cols2=m.Cols();
//--- 接收相加结果的矩阵
CMatrix res(rows1);
//--- 矩阵应该协调
if(cols1!=rows2)
{
//--- 不能相乘
Print(__FUNCSIG__,": Failed to multiply two matrices, format is not compatible "
"- number of columns in the first factor should be equal to the number of rows in the second");
return(res);
}
//--- 辅助数组
double arr[];
ArrayResize(arr,cols1);
//--- 在矩阵乘法中填写该行
for(int i=0;i<rows1;i++)// 通过行
{
//--- 重置接收数组
ArrayInitialize(arr,0);
//--- 通过行的元素
for(int k=0;k<cols1;k++)
{
//--- 利用m矩阵的k列的值用于CRow
CRow column=m.GetColumnAsRow(k);
//--- 两行相乘,在i-th元素写下矢量标量乘法的结果
arr[k]=this[i]*column;
}
//--- 将数组arr[]至于矩阵i-th行
res[i]=arr;
}
//--- 返回两个矩阵的产物
return(res);
}
//+------------------------------------------------------------------+
//| 赋值操作 |
//+------------------------------------------------------------------+
CMatrix *CMatrix::operator=(const CMatrix &m)
{
//--- 查找和设置行数
int rows=m.Rows();
ArrayResize(m_rows,rows);
//--- 填充我们传递矩阵行值的行
for(int i=0;i<rows;i++) this[i]=m[i];
//---
return(GetPointer(this));
}
//+------------------------------------------------------------------+
//| 矩阵的字符串表示 |
//+------------------------------------------------------------------+
string CMatrix::String(void) const
{
string out="";
int rows=Rows();
//--- 形成字符串的字符串
for(int i=0;i<rows;i++)
{
out=out+this[i].String()+"\r\n";
}
//--- 结果
return(out);
}
|