版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/walkandthink/article/details/51914314
在有限元计算中,方程求解的运算主要针对稀疏矩阵来进行。针对稀疏矩阵计算的包,目前最快的应该是intel之家优化的mkl库,以及特别针对稀疏矩阵直接求解的库Pardiso。这两者目前都是非常成功的库,唯一的缺点就是要钱。本文这里介绍另外一个非常优秀的开源数值计算库Eigen。在使用时,无需安装,下载压缩包后解压缩,然后将该文件夹加入你的include路径里面就可以直接使用。
本文这里主要用了Dense Matrix和Sparse Matrix两种不同类型的矩阵来进行计算,计算结果与Matlab进行对比。
首先是Dense Matrix,其变量申明非常简单 MatrixXd A(n,n)就能得到一个double类型的
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "Eigen/Eigen"
#include "Eigen/Dense"
#include "Eigen/Core"
#include "Eigen/Sparse"
#include "Eigen/SparseLU"
using namespace std;
using namespace Eigen;
int main()
{
int n, i, j, k, num, ii, jj;
cout << "Input N:";
cin >> n;
MatrixXd DenseA(n, n);
SparseMatrix<double> SparseA(n, n);
VectorXd F(n), DenseX(n), SparseX(n);
srand(unsigned(time(00)));
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
DenseA(i, j) = (1 + rand() % 500) / 500.0;
SparseA.coeffRef(i, j) = (1 + rand() % 500) / 500.0;
}
F(i) = (1 + rand() % 500) / 500.0;
num = rand() % n;
for (ii = 0; ii < num; ii++)
{
jj = rand() % n;
SparseA.coeffRef(i, jj) = 0.0;
}
}
cout << "The Dense Matrix is:" << endl << DenseA << endl;
cout << "The Sparse Matrix is:" << endl << SparseA << endl;
cout << "The Vector F is:" << endl << F << endl;
//Solve the dense matrix
DenseX = DenseA.colPivHouseholderQr().solve(F);
//make sparse compress
SparseA.makeCompressed();
//use sparse ldlt solver to solve AX=F equation
SparseLU<SparseMatrix<double> > solver;
solver.compute(SparseA);
SparseX = solver.solve(F);
cout << "The dense matrix result is:" << endl << DenseX << endl;
cout << "The sparse matrix result is:" << endl << SparseX << endl;
return 0;
}
以上代码在VS2013下可以运行,如果是gcc环境可能需要做一些调整。
矩阵的具体系数以及右端项的系数在Matlab代码中可以看到,并且也做了结果对比。Matlab代码如下:
clear all;close all;clc;
DA=[0.388 0.28 0.346 0.208 0.022 0.478 0.074 0.81;
0.276 0.364 0.344 0.482 0.168 0.938 0.702 0.004;
0.748 0.862 0.53 0.552 0.854 0.906 0.55 0.886;
0.722 0.94 0.388 0.428 0.808 0.658 0.958 0.438;
0.47 0.37 0.154 0.87 0.932 0.808 0.07 0.354;
0.348 0.532 0.362 0.278 0.916 0.2 0.876 0.28;
0.232 0.442 0.26 0.81 0.224 0.656 0.618 0.926;
0.152 0.176 0.24 0.334 0.294 0.442 0.012 0.026];
SA=[0 0.226 0 0.034 0.516 0.192 0.512 0;
0.196 0.18 0.292 0.066 0.444 0.246 0 0;
0.038 0.738 0.354 0.362 0.408 0.206 0.808 0;
0.982 0 0.668 0.684 0.818 0 0.612 0;
0.038 0.496 0 0 0.618 0.552 0.264 0.168;
0 0.4 0 0.866 0.736 0.69 0.334 0.226;
0.08 0 0 0.524 0 0.2 0 0;
0.174 0.54 0 0.28 0 0.32 0.154 0];
F=[0.3;
0.886;
0.562;
0.704;
0.7;
0.656;
0.876;
0.84];
DX=DA\F;
SX=SA\F;
fprintf('Dense Result<-------->Sparse Result\n');
for i=1:size(DX,1)
fprintf('%f<----------->%f\n',DX(i),SX(i));
end
计算结果对比: