简体   繁体   English

SuiteSparse(4.5.1)的SPQR-调用cholmod_allocate_triplet始终返回NULL

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

I am trying to use SuiteSparse SPQR to solve a linear equation system x = A\\b; 我正在尝试使用SuiteSparse SPQR求解线性方程组x = A \\ b; my A matrix is sparse and it is a rectangular matrix so I chose SPQR to solve this. 我的A矩阵很稀疏,它是一个矩形矩阵,所以我选择了SPQR来解决这个问题。 I built SuiteSparse using MS Visual Studio 2012 on Windows 7 x64 using those provided by https://github.com/jlblancoc/suitesparse-metis-for-windows . 我使用https://github.com/jlblancoc/suitesparse-metis-for-windows提供的Windows 7 x64在Windows 7 x64上使用MS Visual Studio 2012构建了SuiteSparse。

In order to test the function, I modified the spqr_example project to allocate tripets before converting to sparse matrix, instead of originally reading input from stdin to create a sparse matrix. 为了测试该功能,我修改了spqr_example项目以在转换为稀疏矩阵之前分配三元组,而不是最初从stdin读取输入来创建稀疏矩阵。 I input a small A and b matrix for testing. 我输入了一个小的A和b矩阵进行测试。 The program compiled successfully. 程序编译成功。 I debugged the program and found that my call to cholmod_allocate_triplet() has failed because in the declaration of this function it has this code below: 我调试了程序,发现对cholmod_allocate_triplet()的调用失败,因为在此函数的声明中,其代码如下:

RETURN_IF_NULL_COMMON (NULL) ;

This always return false (even though my common starts successfully). 这总是返回false(即使我的普通用户成功启动了)。

I don't want to explicitly make change to this line, as I might have make mistake somewhere or I forgot to do something I have to do because I am new to use the library. 我不想显式地更改此行,因为我可能在某个地方犯了错误,或者因为我是新来使用该库而忘记做必须做的事情。

Can anybody help give me some suggestion on how to make my program run properly? 有人可以给我一些有关如何使我的程序正常运行的建议吗? My code below is modified from the provided spqr_example. 我下面的代码是从提供的spqr_example中修改的。 Thank you very much. 非常感谢你。

#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) ;
}

I have finally find out why my program broke after the line below 我终于找到了为什么我的程序在下面的行之后中断了

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

as the result of the cholmod_allocate_triplet() internally calling RETURN_IF_NULL_COMMON (NULL), which return false. 作为cholmod_allocate_triplet()内部调用RETURN_IF_NULL_COMMON(NULL)(返回false)的结果。

The reason is that I start the process calling 原因是我开始流程调用

cholmod_l_start (cc) ; cholmod_l_start(cc);

which is the long int version of cholmod_start(). 这是cholmod_start()的long int版本。

To fix the problem, I have to call cholmod_l_allocate_triplet() instead of cholmod_allocate_triplet() as well as change all other functions to use cholmod_l instead of only calling cholmod_ 要解决此问题,我必须调用cholmod_l_allocate_triplet()而不是cholmod_allocate_triplet(),并更改所有其他函数以使用cholmod_l而不是仅调用cholmod_

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM