如何使用将特征稀疏矩阵转换为C++中的数组

How to convert an Eigen sparse matrix into an array in C++ using the?

本文关键字:转换 C++ 数组 何使用 特征      更新时间:2023-10-16

我已经使用Eigen包在C++中创建了一个稀疏矩阵mat。矩阵运行良好,但我正在尝试将其转换为数组以用作位图。CCD_ 2的大小为N+1。

天真地,我尝试了以下操作:

  double zmat[N+1][N+1];
  for(int i=0; i<=N; i++){
      for(int j=0; j<=N; j++){
          zmat[i][j]=mat.coeffRef(i,j);
          }
  }

但当我调试时,这给了我一个例外:

Unhandled exception at 0x0116B2C7 in Open_GL_test.exe: 0xC00000FD: Stack overflow (parameters: 0x00000000, 0x001D2000).

有什么想法吗?

double zmat[N+1][N+1];

这就是给你带来麻烦的原因。将一个大矩阵声明为函数中的局部变量不是一个好主意。在堆栈上分配局部变量。许多机器将堆栈的大小限制为少量数据。在我的机器上,堆栈限制大约是8兆字节。这意味着N的值大于1000将立即导致堆栈溢出。N的值大于几百(但小于一千(将导致调用树下某个位置出现难以跟踪的堆栈溢出。

不要在堆栈上分配大量数据。的一些替代方案

  • 在命名空间范围声明变量
  • 使用CCD_ 5和CCD_
  • 使用一个普通的特征矩阵,它为你做newdelete

David Hammen的答案是正确的(double zmat[N+1][N+1];对于堆栈来说太大(。然而,我觉得有必要为你的使用投入我的两分钱。

双循环是不必要的冗长和缓慢。更糟糕的是,在矩阵的每个元素上使用coeffref实际上使矩阵有效地稠密。在coeffRef的文档中,它说:

如果元素不存在,则通过insert(Index,Index(函数插入它,如果不是这样的话,该函数本身会将矩阵转换为非压缩形式
如果元素不存在,这是一个O(log(nnz_j((操作(二进制搜索(加上插入成本(Index,Index(函数。

这意味着它不仅冗长,还会增加内存需求,并可能成为瓶颈。您可以使用

MatrixXd::Map(&zmat[0], (N+1), (N+1)) = mat.toDense();

MatrixXd::Map(zmat, (N+1), (N+1)) = mat.toDense();  // double zmat = new ...

这不仅可读性更强,而且效率也高得多。