本人之前移植了matlab算法,想着试着用C++实现后进行对比,无意中找到了这个armadillo库,这是是一个开放源代码的线性代数库,这是它的官方网站 Armadillo。
本人使用的是VS2017 + C++,在配置这个库上,本人为了方便,直接运用vs扩展NuGet配置,教程如下:
新建项目或者打开你想配置的项目,在解决方案资源管理器中,右键项目,选中“管理NuGet程序包”
接下来只需要搜索并安装armadillo,本人选用的版本为v7.800.0。
如果你之前没有用过nuget扩展,系统会提示你完全关闭visual studio,关闭后,程序将会自动安装该扩展,安装完毕后打开刚刚配置的项目,在“管理NuGet程序包”里面就能看见犰狳库已经安装成功了。
然后我们就可以使用它了,当然别忘了它的命名空间**
#include <armadillo>
using namespace arma;
因为本人是按照matlab程序进行移植,所以就介绍一些该库中对应于matlab中矩阵操作的函数吧。
首先是构造函数,可以直接用mat,如果该矩阵为方阵,就可以用 matnn 其中n为行/列数,n = [0,9]。
//默认构造一个空矩阵。!!!不是单位矩阵!!!
mat M;
//创建一个5行3列的矩阵
mat M1(5, 3);
//用一个矩阵初始化另一个矩阵
mat M2(M1);
//用标准库容器vector也可以初始化
std::vector<double> temp;
mat M3(temp);
//构造行列规模相同的矩阵
mat22 M4;
//构造全为0的矩阵
M4.fill(0);
mat22 M5(fill::zeros);
//单位矩阵
mat33 M6(fill::eye);
//由正态分布的随机数构造的矩阵
mat33 M7(fill::randn);
//由均匀分布的随机数构造的矩阵
mat44 M8(fill::randu);
另外该库也支持对应的任意数初始化,为按行初始化,行尾需要endr,其余部分补0;
mat M9;
M9 << 1 << 2 << 3 << 4 << endr
<< 5 << 6 << 7 << endr
<< endr;;
cout << M9;
接下来是矩阵的运算,armadillo重载了操作符, +,- 操作符依旧为两个矩阵相加减
mat A(4, 4, fill::ones);
mat44 B(fill::eye);
//矩阵相加减
mat C = A + B;
mat D = A - B;
输出结果如下:
接着是矩阵的乘法,其中要注意的是犰狳库有两个矩阵相同位置元素相乘的重载:%
mat A(4, 4, fill::ones);
mat44 B(fill::eye);
B = A + B;
//矩阵乘法
mat D = A * B;
D = B * 5;
//对应元素相乘
D = A % B;
结果如下
说到矩阵的除法,我们知道计算矩阵的除法,其实就是将被除的矩阵先转化为它的逆矩阵,它的逆矩阵相当于被除的矩阵分之一,那么矩阵的除法就相当于前面的矩阵和后面的矩阵的逆矩阵相乘的乘积。说到求逆,我们也说一说转置吧,求逆操作为mat.i(),转置操作为mat.t()。
代码如下;
mat A(4, 4, fill::ones);
mat44 B(fill::eye);
B = A + B;
//B 的转置
mat D = B.t();
//B的逆矩阵
D = B.i();
//矩阵除法,乘以逆矩阵
D = A * D;
//除以常数
D = A / 2;
这里就拿csv文件来说吧。读取文件时候,第二个参数是文件的格式,arma_ascii 是以逗号分隔值隔开的格式,coord_ascii是以坐标列表格式存储的csv。保存文件时候
mat m, M;
//加载
//m.load("test.csv");
m.load("test.csv",arma_ascii);
//读取列表头为name和age的数据
field<std::string> header(A.n_cols);
header(0) = "name";
header(1) = "age";
m.load( csv_name(filename, header) )
//将M矩阵的数据以逗号隔开的格式保存到test1
M.save("test1.csv", csv_ascii);
//将M矩阵的数据和列表头保存
field<std::string> header(A.n_cols);
header(0) = "name";
header(1) = "age";
M.save( csv_name("test1.csv", header));
如有问题,欢迎各位指正。