Eigen数学库介绍及Qt配置
https://m.toutiao.com/is/Jppeerk/
Eigen是一个高层次的C ++库,有效支持线性代数,矩阵和矢量运算,数值分析及其相关的算法。Eigen是一个开源库,从3.1.1版本开始遵从MPL2许可。
我最近在写有限元程序,本来一个基本的框架,已经在python里写好了,但是后来想想还是得使用C++。自然要用到矩阵运算的库,我选择了Eigen。
前几天,问了在大学教计算数学的师妹,他们写论文用什么库,师妹说用Matlab。好吧,这也许就是我们为什么写了大量的代码,不能有产品级的迭代的原因了吧。
1、我为什么要自己写库?
想要写一个自己的方程求解的库,是很早就有的想法了。最近正好我的师兄何晓明教授,在天元基金东北中心做公开课,我也就好好跟师兄学习了一下。希望这次能走的更远一些,做一些基本的库出来。
我们为什么要自己去写库呢?
国外的库有很多,都是开源的。为什么还要自己写呢?因为,不管别人汽车跑得多快,从爬行到走路,还是得我们自己亲自来做的。别人替代不了。否则,我们只能是一个残障人士了。
2、做一个数值仿真的软件,需要哪些方面?
一个数值仿真软件,其实是一个很庞大的系统。涉及到的东西很多。简单说来包含三个部分。
(1)前处理
前处理,负责建立几何模型,也就是CAD的工作。我们熟知的solidworks,UG,3DMax等,都是可以玩成这样的工作。国内的,中望也有3D建模软件。包括,开源的像FreeCAD等。这个事本身就挺复杂的。
(2)计算
这个部分,包含网格剖分,和求解器两大部分。
网格剖分的软件,除了商业软件的内置的外,开源的,有gmsh,tetgen等。
求解器,就很多了,开源的有Calculix等。
计算部分的工作就是求解出方程的解来。也就是计算仿真的数据。然后交给后处理去处理。
(3)后处理
后处理的工作,就是做数据的分析和可视化的工作。以针对问题,对数据进行分析,并用我们可以理解的方式呈现出来。后处理就是为大家使用数据讲一个数据故事,提供工具。
3、代数计算和Eigen库
那么我们的主角Eigen库的作用是什么呢?
Eigen库是做矩阵运算和矩阵处理的。
每一个仿真计算,都是对方程的求解。一个方程的物理量是一个无穷维空间的事,通过有限元或者有限体积或者有限差分等方法,可以将无穷维空间的事,简化成一个有限维空间的事。这也就是为什么这些方法前面都要加一个“有限”两个字的原因。
数学里有一个定理,任何有限维空间的算子,都是一个矩阵。
这就是为什么,我们在数值计算中要用到矩阵的原因,也就是为什么今天要说Eigen这个库。
4、Eigen库
上面这个列表,大概可以看出Eigen库的强大的功能。其主要的用途,就是求解矩阵方程。包括,特征值等矩阵的一系列的特征问题。稀疏矩阵的处理,等等。
以下是一些特性:
- 支持整数、浮点数、复数,使用模板编程,可以为特殊的数据结构提供矩阵操作。比如在用ceres-solver进行做优化问题(比如bundle adjustment)的时候,有时候需要用模板编程写一个目标函数,ceres可以将模板自动替换为内部的一个可以自动求微分的特殊的double类型。而如果要在这个模板函数中进行矩阵计算,使用Eigen就会非常方便。
5、Qt上的配置
我使用Qt来写,其实也不一定,只是习惯了。调用Eigen库的方式很简单。我就不在编译上花太多时间了。Eigen的官方地址提供了windows下的包。下载下来,就可以直接调用。
Qt里只要在pro文件中增加库的地址就可以直接调用。非常方便。我是直接把eigen库放在qt根目录的,其实这样不好,可以单独做一个外部库的目录存放。
这样,我们就可以做一个简单的测试了。这个案例包含,矩阵定义,向量定义,数据库的提取。
#include <QCoreApplication>#include <iostream>#include <Eigen/Dense>typedef Eigen::MatrixXd Matrix ;typedef Eigen::VectorXd Vector ;using namespace std;int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); Matrix m(3,3) ; m<<1,2,3, 4,5,6, 7,8,9; Vector v(3); v<<1,2,3;// cout<< 'm*v'<<endl<<m*v<<endl; cout<<m.block(0,0,2,2)<<endl; cout<<m.block<2,2>(0,0)<<endl; //从0,0位置开始,向下向右,取1行2列。 cout<<m.block(0,0,1,2)<<endl; cout<<m.block(0,0,3,1)<<endl; cout<<m.row(2)<<endl; m.row(2)<<11,12,13; cout<<m.row(2)<<endl; cout<<m<<endl; Matrix mm;// mm.resize(1,3);// mm<<4,5,6; mm=m; cout<<mm<<endl; return a.exec();}
输出结果为:
6、结束
一个有限元库,需要大量的其他的第三方库的帮助。在求解器这个层面,最重要的库就是Eigen这样的矩阵运算库了。而做数值计算,最大的运算的时间也就在这个矩阵运算上了。
最后,做一个调查,你知道的前处理,计算,后处理的库,都有哪些呢?软件都有哪些呢?
请在下方留言。
非常感谢您的支持和关注,我是张麟博士。