当 A 矩阵很大时,无法使用 CXSparse 中的 cs_qrsol 求解 C++ 中的 x=A\b
Failed to use cs_qrsol from CXSparse to solve x=A\b in C++ when A matrix is large
我正在尝试使用 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(因为此函数接受非方 mxn 矩阵。
我已经尝试 cs_qrsol 使用下面的代码解决一个小问题,它给出了预期的结果。但是,当我尝试将它应用于我的真实 A 矩阵时,函数总是 returns 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);
}
现在,我可以解决我自己的问题了。
我更改了我的程序以调用版本 cs_dl_* 而不是 cs_* 函数。另外,我机器中的内存确实很重要。为了让它工作,我必须关闭所有打开的应用程序以确保我有足够的 space 内存用于 cs_spalloc 或 cs_dl_spalloc.
我正在尝试使用 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(因为此函数接受非方 mxn 矩阵。
我已经尝试 cs_qrsol 使用下面的代码解决一个小问题,它给出了预期的结果。但是,当我尝试将它应用于我的真实 A 矩阵时,函数总是 returns 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);
}
现在,我可以解决我自己的问题了。 我更改了我的程序以调用版本 cs_dl_* 而不是 cs_* 函数。另外,我机器中的内存确实很重要。为了让它工作,我必须关闭所有打开的应用程序以确保我有足够的 space 内存用于 cs_spalloc 或 cs_dl_spalloc.