我正在尝试使用C ++中的本征或Armadillo库构建稀疏矩阵,以求解线性方程组Ax = b。 A是维度为n * n的系数矩阵,而B是维度为n的右手向量 the Spars Matrix A is like this, see the figure
我浏览了Eigen文档,但是在C ++中定义和填充Spars Matrix时遇到问题。
能否请给我一个示例代码来定义稀疏矩阵,以及如何使用c ++中的Eigen库将值填充到矩阵中?
例如考虑一个简单的稀疏矩阵A:
1 2 0 0
0 3 0 0
0 0 4 5
0 0 6 7
int main()
{
SparseMatrix<double> A;
// fill the A matrix ????
VectorXd b, x;
SparseCholesky<SparseMatrix<double> > solver;
solver.compute(A);
x = solver.solve(b);
return 0;
}
答案 0 :(得分:1)
由于此问题也询问Armadillo,因此以下是相应的基于犰狳的代码。最好使用Armadillo版本9.100+或更高版本,并与SuperLU链接。
#include <armadillo>
using namespace arma;
int main()
{
sp_mat A(4,4); // don't need to explicitly reserve the number of non-zeros
// fill with direct element access
A(0,0) = 1.0;
A(0,1) = 2.0;
A(1,1) = 3.0;
A(2,2) = 4.0;
A(2,3) = 5.0;
A(3,2) = 6.0;
A(3,3) = 7.0; // etc
// or load the sparse matrix from a text file with the data stored in coord format
sp_mat AA;
AA.load("my_sparse_matrix.txt", coord_ascii)
vec b; // ... fill b here ...
vec x = spsolve(A,b); // solve sparse system
return 0;
}
另请参阅SpMat,element access,.load(),spsolve()的文档。
coord文件格式很简单。它存储非零值。 每行包含:
row col value
行和列的计数从零开始。示例:
0 0 1.0
0 1 2.0
1 1 3.0
2 2 4.0
2 3 5.0
3 2 6.0
3 3 7.0
1000 2000 9.0
未明确列出的值假定为零。
答案 1 :(得分:0)
可以使用.coeffRef()
成员函数将稀疏矩阵填充为帖子中提到的值,如下例所示:
SparseMatrix<double> fillMatrix() {
int N = 4;
int M = 4;
SparseMatrix<double> m1(N,M);
m1.reserve(VectorXi::Constant(M, 4)); // 4: estimated number of non-zero enties per column
m1.coeffRef(0,0) = 1;
m1.coeffRef(0,1) = 2.;
m1.coeffRef(1,1) = 3.;
m1.coeffRef(2,2) = 4.;
m1.coeffRef(2,3) = 5.;
m1.coeffRef(3,2) = 6.;
m1.coeffRef(3,3) = 7.;
m1.makeCompressed();
return m1;
}
但是,SparseCholesky
模块(SimplicialCholesky<SparseMatrix<double> >
)在这种情况下不起作用,因为矩阵不是Hermitian。该系统可用LU或BiCGStab求解器求解。另请注意,x
和b
的大小需要定义:
VectorXd b(A.rows()), x(A.cols());
对于较大的稀疏矩阵,您可能还需要查看.reserve()
函数,以便在填充元素之前分配内存。 .reserve()
函数可用于估计每列(或行,取决于存储顺序,非零)的非零条目数。默认值为comumn-major。在上面的示例中,估计值为4,但在如此小的矩阵中没有任何意义。该文档指出,最好使用overestimate the number of non-zeros per column。