[英]Calculating the inverse of a sparse matrix using Cholmod and Cholmod-Extra
[英]Creating a sparse matrix in CHOLMOD or SuiteSparseQR
在SparseSuiteQR中,我能找到的所有示例都使用标准输入或读取的文件来创建稀疏矩阵。 有人可以提供一个简单的例子说明如何直接在 C++ 中创建一个吗?
更好的是,在 CHOLMOD 文档中,提到了 matlab 中可用的 sparse2 function,其行为与稀疏相同。 这个可以用在C++吗?
我假设您尝试求解线性系统,请参阅Tim Davies的CSparse软件包或boost矩阵库,这些库也具有数字绑定,这些接口绑定umfpack和一些lapack函数AFAIK ...
SuiteSparseQR使用的数据结构(例如cholmod_sparse)在CHOLMOD库中定义。 您可以在CHOLMOD文档中找到有关它的更多信息,该文档比SuiteSparseQR中的文档大得多。
CHOLMOD 是一个非常棒的项目——感谢 Tim Davis:)
令人惊讶的是,GitHub 上有大量使用 CHOLMOD 的代码,但您必须登录 GitHub 并知道您在寻找什么!
因此,在浏览了 CHOLMOD 文档和源代码,然后搜索 GitHub 以查找使用 CHOLMOD 的源代码之后,您会发现该怎么做。
但是对于大多数想要/需要一个快速示例的开发人员来说,下面是它。
*请注意,您的里程可能会因编译 SuiteSparse 的方式而异。 (您可能需要使用cholmod_
变体(没有l
),即不是cholmod_l_
;并使用int
进行索引,而不是long int
)。
// example.cpp
#include "SuiteSparseQR.hpp"
#include "SuiteSparse_config.h"
int main (int argc, char **argv)
{
cholmod_common Common, *cc;
cholmod_sparse *A;
cholmod_dense *X, *B;
// start CHOLMOD
cc = &Common;
cholmod_l_start (cc);
/* A =
[
1.1, 0.0, -0.5, 0.7
0.0, -2.0, 0.0, 0.0
0.0, 0.0, 0.9, 0.0
0.0, 0.0, 0.0, 0.6
]
*/
int m = 4; // num rows in A
int n = 4; // num cols in A
int nnz = 6; // num non-zero elements in A
int unsymmetric = 0; // A is non-symmetric: see cholmod.h > search for `stype` for more details
// In coordinate form (COO) a.k.a. triplet form (zero-based indexing)
int i[nnz] = {0, 1, 0, 2, 0, 3}; // row indices
int j[nnz] = {0, 1, 2, 2, 3, 3}; // col indices
double x[nnz] = {1.1, -2.0, -0.5, 0.9, 0.7, 0.6}; // values
// Set up the cholmod matrix in COO/triplet form
cholmod_triplet *T = cholmod_l_allocate_triplet(m, n, nnz, unsymmetric, CHOLMOD_REAL, cc);
T->nnz = nnz;
for (int ind = 0; ind < nnz; ind++)
{
((long int *) T->i)[ind] = i[ind]; // Notes:
((long int *) T->j)[ind] = j[ind]; // (1) casting necessary because these are void* (see cholmod.h)
((double *) T->x)[ind] = x[ind]; // (2) direct assignment will cause memory corruption
} // (3) long int for index pointers corresponds to usage of cholmod_l_* functions
// convert COO/triplet to CSC (compressed sparse column) format
A = (cholmod_sparse *) cholmod_l_triplet_to_sparse(T, nnz, cc);
// note: if you already know CSC format you can skip the triplet allocation and instead use cholmod_allocate_sparse
// and assign the member variables: see cholmod.h > cholmod_sparse_struct definition
// B = ones (size (A,1),1)
B = cholmod_l_ones (A->nrow, 1, A->xtype, cc);
// X = A\B
X = SuiteSparseQR <double> (A, B, cc);
// Print contents of X
printf("X = [\n");
for (int ind = 0; ind < n; ind++)
{
printf("%f\n", ((double *) X->x)[ind]);
}
printf("]\n");
fflush(stdout);
// free everything and finish CHOLMOD
cholmod_l_free_triplet (&T, cc);
cholmod_l_free_sparse (&A, cc);
cholmod_l_free_dense (&X, cc);
cholmod_l_free_dense (&B, cc);
cholmod_l_finish (cc);
return 0;
}
假设您已成功编译 SuiteSparse 并将example.cpp
保存在基本目录中,那么以下内容应该可以工作(在 Linux 上):
gcc example.cpp -I./include -L./lib -lcholmod -lspqr -lsuitesparseconfig -o example
#Add SuiteSpare libraries to your `ld` search path if necessary
LD_LIBRARY_PATH=$(pwd)/lib
export LD_LIBRARY_PATH
./example
Output:
X = [
0.353535
-0.500000
1.111111
1.666667
]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.