簡體   English   中英

SuiteSparse(4.5.1)的SPQR-調用cholmod_allocate_triplet始終返回NULL

[英]SuiteSparse(4.5.1)'s SPQR - calling to cholmod_allocate_triplet always returns NULL

我正在嘗試使用SuiteSparse SPQR求解線性方程組x = A \\ b; 我的A矩陣很稀疏,它是一個矩形矩陣,所以我選擇了SPQR來解決這個問題。 我使用https://github.com/jlblancoc/suitesparse-metis-for-windows提供的Windows 7 x64在Windows 7 x64上使用MS Visual Studio 2012構建了SuiteSparse。

為了測試該功能,我修改了spqr_example項目以在轉換為稀疏矩陣之前分配三元組,而不是最初從stdin讀取輸入來創建稀疏矩陣。 我輸入了一個小的A和b矩陣進行測試。 程序編譯成功。 我調試了程序,發現對cholmod_allocate_triplet()的調用失敗,因為在此函數的聲明中,其代碼如下:

RETURN_IF_NULL_COMMON (NULL) ;

這總是返回false(即使我的普通用戶成功啟動了)。

我不想顯式地更改此行,因為我可能在某個地方犯了錯誤,或者因為我是新來使用該庫而忘記做必須做的事情。

有人可以給我一些有關如何使我的程序正常運行的建議嗎? 我下面的代碼是從提供的spqr_example中修改的。 非常感謝你。

#include <iostream>
#include "SuiteSparseQR.hpp"

int main (int argc, char **argv)
{
cholmod_common Common, *cc ;
cholmod_sparse *A ;
cholmod_dense *X, *B, *Residual ;
double rnorm, one [2] = {1,0}, minusone [2] = {-1,0} ;
int mtype ;
// start CHOLMOD
cc = &Common ;
cholmod_l_start (cc) ;

// load A
//A = (cholmod_sparse *) cholmod_l_read_matrix (stdin, 1, &mtype, cc) ;

        // A = [ 1  0  0  0; 
        //      -1  1  0  0; ...
        //       0 -1  1  0; ...
        //       0  0 -1  1; ...
        //       0  0  0 -1];
        int row[] = {0, 1, 1, 2, 2, 3, 3, 4};
        int col[] = {0, 0, 1, 1, 2, 2, 3, 3};
        double val[] = {1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0};
        int numEq = 5;
        int numElement = 8;
        int numSol = 4;
        double b[] = {5.0, -5.0, 2.0, 1.0, 0.0};

cholmod_triplet* triplet = cholmod_allocate_triplet(5,4,5*4,0,CHOLMOD_REAL,cc);
int * triplet_i = (int *)(triplet->i);
int * triplet_j = (int *)(triplet->j);
double * triplet_x = (double *)(triplet->x);
for (int ne=0; ne<numElement; ne++)
{
    triplet_i[triplet->nnz] = row[ne];
    triplet_j[triplet->nnz] = col[ne];
    triplet_x[triplet->nnz] = val[ne];

    triplet->nnz++;
}

// Convert triplet to sparse matrix
A = cholmod_triplet_to_sparse(triplet, numElement, cc);
cholmod_free_triplet(&triplet, cc);

// B = ones (size (A,1),1)
//B = cholmod_l_ones (A->nrow, 1, A->xtype, cc) ;
B = cholmod_l_zeros(numEq, 1, CHOLMOD_REAL, cc);
for (int ne=0; ne<numEq; ne++)
{
    ((double *)(B->x))[ne] = val[ne];
}

// X = A\B
X = SuiteSparseQR<double>(A,B,cc);
//X = SuiteSparseQR <double> (A, B, cc) ;

// Print out the result
double *sol = static_cast<double *>(malloc(sizeof(X->x)));
sol = (double *)(X->x);
for (int r=0; r<numSol; r++)
{
    std::cout << "x[" << r << "] = " << sol << std::endl;
    sol++;
}

///// END HERE

// rnorm = norm (B-A*X)
Residual = cholmod_l_copy_dense (B, cc) ;
cholmod_l_sdmult (A, 0, minusone, one, X, Residual, cc) ;
rnorm = cholmod_l_norm_dense (Residual, 2, cc) ;
printf ("2-norm of residual: %8.1e\n", rnorm) ;
printf ("rank %ld\n", cc->SPQR_istat [4]) ;
// free everything and finish CHOLMOD
cholmod_l_free_dense (&Residual, 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) ;
}

我終於找到了為什么我的程序在下面的行之后中斷了

cholmod_triplet *三元組= cholmod_allocate_triplet(5,4,5 * 4,0,CHOLMOD_REAL,cc);

作為cholmod_allocate_triplet()內部調用RETURN_IF_NULL_COMMON(NULL)(返回false)的結果。

原因是我開始流程調用

cholmod_l_start(cc);

這是cholmod_start()的long int版本。

要解決此問題,我必須調用cholmod_l_allocate_triplet()而不是cholmod_allocate_triplet(),並更改所有其他函數以使用cholmod_l而不是僅調用cholmod_

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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