我正在尝试计算以下内容:
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系统
提前致谢
亚历
答案 0 :(得分:1)
默认情况下,Eigen::SparseMatrix
使用int
来存储大小和索引(用于紧凑性)。但是,对于大量的行,您需要为sp
和sp.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=
。也许你可以避免复制。