当矩阵很大时,无法使用CXSparse中的cs_qrsol来解决C ++中的x = A \ b

时间:2016-03-07 00:18:06

标签: c++ opencv sparse-matrix least-squares suitesparse

我正在尝试使用Tim Davis(http://faculty.cse.tamu.edu/davis/suitesparse.html)的CXSparse库来求解线性方程组x = A \ b。我使用Windows 7 x64上的MS Visual Studio 2012开发我的C ++程序(使用OpenCV)。

我有一个A矩阵,它是一个稀疏矩阵和b矩阵。我想找到x = A \ b。我的A矩阵大小约为700,000 x 30,000。由于这不是方形矩阵,我调用函数cs_qrsol(因为这个函数接受非方形mx​​n矩阵。

我已经尝试使用cs_qrsol来解决一个小问题,使用下面的代码,它会给出预期的结果。但是,当我尝试使用我的真实A矩阵应用它时,函数总是返回0.(我已经尝试了order = 0到3)。

为了证明我的问题A,b有一个解x,我在MATLAB中输入矩阵A,b,我可以成功得到结果。

所以,我想知道我的代码可能有问题,或者对函数有任何限制?如果有人能指出我做错了什么,我真的很感激。非常感谢你。

bool sparseSolve(cv::Mat& i, cv::Mat& j, cv::Mat& s, cv::Mat& d, int k, int n)
{
// Solve linear equations: x = A\b
// i,j,s are (k x 1) matrices - (i,j) are row and col, s are values so the trippet is (i,j,s)
// d is an (n x 1) matrix - this is the b matrix

cs *T, *A;
double * b;
int y, m, status;

// Assign the sparse matrix A
T = cs_spalloc (0, 0, 1, 1, 1) ; 
for (y = 0; y < k; y++)
{
    if (!cs_entry (T, i.at<int>(y,0), j.at<int>(y,0), s.at<double>(y,0)))
    {
        cs_spfree(T);
        std::cout << "Failed to add entry to the matrix A at " << y << std::endl;
        return false;
    }
}

A = cs_compress(T);
cs_spfree(T);
if (!A)
{
    std::cout << "Failed to create A as the compressed-column form of T" << std::endl;
    return false;   
}
m = A->m;   // # rows of A

if (n != m)
    std::cout << "# rows of A (" << m << ") not equal # equations (" << n << ")" << std::endl;

// Allocate the b matrix
b = static_cast<double *>(malloc(n*sizeof(double)));
if (!b)
{
    std::cout << "Failed to allocate the b matrix" << std::cout;
    cs_spfree(A);
    return false;
}

// Assign the b matrix
for (y = 0; y < n; y++)
{
    b[y] = d.at<double>(y,0);
}

// Obtain the results x=A\b in the b matrix
status = cs_cholsol(0, A, b); // This returns 0 as failed.

cs_spfree(A);
free(b);

return (1==status);
}

1 个答案:

答案 0 :(得分:0)

现在,我可以解决自己的问题。 我更改了我的程序来调用版本cs_dl_ *而不是cs_ *函数。而且,我机器中的内存非常重要。为了使它工作,我必须关闭所有打开的应用程序,以确保我有足够的内存空间用于cs_spalloc或cs_dl_spalloc。