【问题标题】:Sparse matrix without knowing size不知道大小的稀疏矩阵
【发布时间】:2021-03-10 00:23:18
【问题描述】:

如果大小未知,Eigen 是否支持将元素插入到稀疏矩阵中?

我有一个数据流进入,我试图稀疏地存储它,但我不知道数据的索引(行/列)的最大值提前(我可以猜到,但是不保证)。查看 Eigen 的插入代码,它有一个断言 (1130, SparseMatrix.h),您希望插入的索引是

我真的需要等到我拥有所有数据才能开始使用 Eigen 的稀疏矩阵代码吗?然后我必须采用的设计要求我等待所有数据,然后扫描找到最大索引,这对我的应用程序来说并不理想。我目前不需要完整的矩阵来开始工作 - 使用当前可用数据的有限矩阵就可以了。

除非您有答案,否则请不要关闭此问题,链接的答案适用于密集矩阵,而不是稀疏矩阵,它们具有不同的内部存储...

我还在寻找关于矩阵大小在运行时而不是在编译时立即可用的情况的信息,并且 olny 表示稀疏。

【问题讨论】:

  • @πάνταῥεῖ 我同意 OP,重复是关于密集矩阵。
  • 插入到SparseMatrix 初始化通常效率低下,除非您按顺序执行并且理想情况下使用正确的预分配矩阵。我建议积累一个三元组列表并使用setFromTriplets
  • @chtz 好吧,我没有看得太近,但好消息是,他们现在在他们的问题中更好地澄清了这一点。 THX 通知。 @OP 您方面的研究工作可能会更好地记录/呈现。
  • @OP 您确实应该澄清您的问题,例如,“开始工作 [使用矩阵]”是什么意思?您多久获得一次新数据(与您使用这些数据所做的工作量相比)?太大的矩阵会有多糟糕(最后一行/列中只有零)?

标签: c++ eigen


【解决方案1】:

建议仍然将值存储到中间三元组容器中,并在最后构建稀疏矩阵。如果您不想读取所有流...那么只需读取第一个 nnn 三元组直到您想要的条件,然后使用 setFromTriplets() 和部分三元组列表。

但是,如果您仍然不想读取完整的矩阵来开始工作,您可以猜测矩阵的大小并使其增长,以防您使用 @ 读取无法以当前大小存储的值987654321@.

#include <Eigen/Sparse>
#include <iostream>
 
Eigen::SparseMatrix<double> mat;
mat.resize(100,100); //Initial size guess. Could be 1, 10, 1000, etc...


fstream inputStream ("filename.txt", "r"):
while(inputStream)
{
    //Read position and value from stream
    unsigned i, j;
    double v;
    inputStream >> i >> j >> v;

   //check current size of the matrix and make it grow if necessary
   if ( (i >= mat.rows()) || (j >= mat.cols()) )
      mat.conservativeResize(std::max(i+1, mat.rows()), std::max(j+1, mat.cols()) );

   //store the value in matrix
   mat.coeffRef(i,j) = v;

   //Insert here your condition to break before of read all the stream
   if (mat.nonZeros() > 150 )
      break;
}

//Do some clean-up in case you think is necessary
mat.makeCompressed();

【讨论】:

  • 啊,保持不变的矩阵条目对于保守调整大小很重要,我没有看到。我原以为它破坏了原始数据。太好了。
  • 您还可以使用mat.reserve() 为一些预期的非零条目预分配一些存储空间。这与std::vector::reserve 的工作方式类似,这对于构建三元组形式的稀疏矩阵也很有用。
猜你喜欢
  • 2016-12-13
  • 2021-09-22
  • 2014-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-19
  • 1970-01-01
相关资源
最近更新 更多