在Eigen::SparseMatrix的转置处的std::bad_alloc
std::bad_alloc at transpose of Eigen::SparseMatrix
我正在尝试计算以下内容:
A=X^t*X我使用的是Eigen::SparseMatrix,在transpose()操作中得到一个std::bad_alloc错误:
Eigen::SparseMatrix<double> trans = sp.transpose();
sp也是一个特征::稀疏矩阵矩阵,但它非常大,在一个较小的数据集上,命令
std::cout << "Rows: " << sp.rows() << std::endl;
std::cout << "Rows: " << sp.cols() << std::endl;
给出以下结果:
行数:2061565968
Cols:600
(在开始填充之前,我预先计算了这个矩阵的大小)
这样一个矩阵可以容纳多少个条目有限制吗?我使用的是一个带有g++的64位Linux系统
提前感谢
Alex
ggael的答案稍作修改:
在SparseMatrix的定义中,不能忽略选项,因此正确的typedef是
typedef SparseMatrix<double, 0, std::ptrdiff_t> SpMat;
0也可以交换为1,0表示列主,1表示行主
感谢您的帮助
默认情况下,Eigen::SparseMatrix
使用int
存储大小和索引(为了紧凑)。然而,对于如此庞大的行数,您需要对sp
和sp.transpose()
:使用64个整数
typedef SparseMatrix<double, 0, std::ptrdiff_t> SpMat;
注意,你可以直接写:
SpMat sp, sp2;
sp2 = sp.transpose() * sp;
即使CCD_ 5无论如何都必须被评估为临时的。
我认为在当前状态下不可能回答您的问题。
有两件事。矩阵的大小——数学对象,以及它所占据的内存大小。在稠密矩阵中,它们几乎相同(线性相关)。但在稀疏情况下,内存占用与矩阵的大小无关,而是与非零元素的数量有关。
因此,从技术上讲,您有几乎无限的大小限制——等于Size
类型。然而,当然,当涉及到(非零)元素的数量时,您仍然受到内存的约束。
很明显,你复制了一个矩阵。因此,您可以尝试计算矩阵对象需要保存的数据的大小,看看它是否适合您的内存。
这不是很琐碎,但文档说存储是一个非零元素的列表。因此,一个好的估计可能是(2*sizeof(Index)+sizeof(Scalar))*sp.nonZeros()
-(x,y,value)。
你也可以在调用转置之前监控RAM的使用情况,如果你加倍,看看它是否在限制范围内
注意:换位可能不是罪魁祸首,而是operator=
。也许你可以避免复制。
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- 获取错误:在抛出"std::bad::alloc"的实例后终止调用 what(): std::bad_alloc
- "std::vector"在调整大小时引发"bad allocation"异常
- 成员函数 bad() 的 std::ftsream 用于检查
- 正在使用std::string而不是char*bad
- 在抛出 'std::bad _alloc' 的实例后调用终止 what(): std::bad_alloc 在 c++ 中
- What is Scala for: getline(), std::cin.eof(), std::cin.bad()