在Eigen :: SparseMatrix转置时的std :: bad_alloc

时间:2013-11-25 13:23:43

标签: c++ eigen

我正在尝试计算以下内容:
A = X ^ t * X. 我正在使用Eigen :: SparseMatrix并在transpose()操作上得到一个std :: bad_alloc错误:

Eigen::SparseMatrix<double> trans = sp.transpose();

sp也是一个Eigen :: SparseMatrix矩阵,但它在一个较小的数据集上非常大,命令

std::cout << "Rows: " << sp.rows() << std::endl;
std::cout << "Rows: " << sp.cols() << std::endl;

给出以下结果:

行:2061565968
Cols:600

(在开始填充之前,我预先计算了这个矩阵的大小)

这样的矩阵可以容纳多少条目是否有限制? 我正在使用带有g ++的64位Linux系统

提前致谢

亚历

3 个答案:

答案 0 :(得分:1)

默认情况下,Eigen::SparseMatrix使用int来存储大小和索引(用于紧凑性)。但是,对于大量的行,您需要为spsp.transpose()使用64个整数:

typedef SparseMatrix<double, 0, std::ptrdiff_t> SpMat;

请注意,您可以直接写:

SpMat sp, sp2;
sp2 = sp.transpose() * sp;

即使sp.transpose()无论如何都必须进行临时评估。

答案 1 :(得分:1)

ggael的回答稍作修改:

在SparseMatrix的定义中,不能省略选项,所以正确的typedef是

typedef SparseMatrix<double, 0, std::ptrdiff_t> SpMat;

0也可以换成1,0表示列主要,1表示RowMajor

感谢您的帮助

答案 2 :(得分:0)

我认为现在无法回答你的问题。

有两件事。矩阵的大小 - 数学对象,以及它所占据的内存大小。在密集矩阵中,几乎相同(线性依赖)。但在稀疏的情况下,内存占用与矩阵的大小无关,而与非零元素的数量有关。

因此,从技术上讲,你有几乎无限的大小限制 - 等于Size类型。但是,当涉及到(非零)元素的数量时,你仍然受到内存的约束。

你明显地复制了一个矩阵。因此,您可以尝试计算矩阵对象需要保存的数据大小,并查看它是否适合您的内存。

这不是很简单,但文档说存储是一个非零元素列表。所以一个好的估计可能是(2*sizeof(Index)+sizeof(Scalar))*sp.nonZeros() - 对于(x,y,value)。

您还可以在调用转置之前监控RAM使用情况,如果将其翻倍,还可以查看它是否保持在限制范围内。

注意:换位可能不是那里的罪魁祸首,而是operator=。也许你可以避免复制。