簡體   English   中英

在 CHOLMOD 或 SuiteSparseQR 中創建稀疏矩陣

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM