本章我们讨论矩阵的相关内容,最主要的是解线性方程组。在开始进入数值分析的内容之前,先定义好矩阵这个类。
(如果你仅仅关心数值分析的内容,可以跳过本文不看)
声明
以下代码在mathalgorithm.h中
//mathalgorithm.h
template<class DM>
class Matrix
{
public:
Matrix(int,int);
Matrix(vector<vector<DM>>, int, int);
Matrix<DM> &operator=(const Matrix<DM> &);
DM operator()(int,int);
template<class DB> friend void Disp(Matrix<DB>);
private:
vector<vector<DM>> value;
int row_num;
int column_num;
};
以上是矩阵类的声明。这里用到了模板类,就是说我暂时不管Matrix里的元素类型是什么,统统写为DM。本章我们在调用时,最常用的是Matrix<double>,但以后可能还会定义多项式类,复数类等等,它们也可以作为矩阵的元素。这是采用模板的原因。
成员变量
- value:储存矩阵的值。比如,value[i][j]表示访问第i行第j列的元素。显然,value需要用二维数组来存储,因此类型设为vector<vector<DB>>
- row_num:行数
- column_num:列数
成员函数
- 构造函数:用于初始化矩阵
- 运算符=的重载:用于矩阵的拷贝
- 运算符()的重载:用于访问矩阵的元素。如A(1,2)表示调用第1行第2列的元素,它等价于A.value[1][2]
非成员函数
- Disp():用于输出矩阵。
定义
实现以上这些并不难,不涉及任何数学的知识,仅仅涉及C++的语法知识,就不再详细解释了,直接贴代码。
以下定义在mathalgorithm.h中。
//mathalgorithm.h
template<class DB> Matrix<DB>::Matrix(int r,int c)
{
row_num=r;
column_num=c;
vector<DB> rr(c);
for(int i=0;i<r;++i)
{
value.push_back(rr);
}
}
template<class DB> Matrix<DB>::Matrix(vector<vector<DB>> a,int r,int c)
{
row_num=r;
column_num = c;
value = a;
}
template<class DB> void Disp(Matrix<DB> a)
{
cout << setiosflags(ios::left);
for (int i = 0;i<a.row_num;++i)
{
for (int j = 0;j<a.column_num;++j)
{
cout << a.value[i][j] << ' ';
}
cout << endl;
}
cout << endl;
}
template<class DB> Matrix<DB>& Matrix<DB>::operator=(const Matrix<DB> &b)
{
row_num = b.row_num;
column_num = b.column_num;
value = b.value;
return *this;
}
template<class DB> DB Matrix<DB>::operator()(int r,int c)
{
if(r>=row_num || c>=column_num)
{
cerr << "错误:矩阵下标越界" << endl;
return value[0][0];
}
return value[r][c];
}
【附注】C++不支持模板类的分离式编译,因此定义仍然是在头文件mathalgorithm.h中。由于本章所定义的函数全部需要模板,故本章不会用到mathalgorithm.cpp这个源文件。
调用
以下在main.cpp中
//main.cpp
#include <iostream>
#include "mathalgorithm.h"
using namespace std;
int main()
{
Matrix<double> A({{1,2},{3,4}},2,2);
Disp(A);
system("pause");
return 0;
}
上面这一段简短的代码的意思是:新建一个矩阵,并把它输出。
C++11标准允许我们可以用列表的方式去初始化vector。其中列表初始化{{1,2},{3,4}}的写法也符合mathematica的语法。
运行结果如下图: