【问题标题】:std::bad_alloc at transpose of Eigen::SparseMatrix在 Eigen::SparseMatrix 转置处的 std::bad_alloc
【发布时间】:2013-11-27 21:15:14
【问题描述】:

我正在尝试计算以下内容:
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
列数:600

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

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

提前致谢

亚历克斯

【问题讨论】:

    标签: c++ eigen


    【解决方案1】:

    ggael 的回答稍作修改:

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

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

    0也可以换成1,0表示column-major,1表示RowMajor

    感谢您的帮助

    【讨论】:

      【解决方案2】:

      默认情况下Eigen::SparseMatrix 使用int 来存储大小和索引(为了紧凑)。但是,由于行数如此之多,spsp.transpose() 都需要使用 64 个整数:

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

      注意可以直接写:

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

      即使sp.transpose() 无论如何都必须被评估为临时的。

      【讨论】:

        【解决方案3】:

        我认为以目前的状态回答你的问题是不可能的。

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

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

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

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-03
          • 2013-12-20
          • 1970-01-01
          相关资源
          最近更新 更多