简体   繁体   English

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

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

I have created a sparse matrix mat in C++ using the Eigen package. 我已经使用Eigen包在C ++中创建了一个稀疏矩阵mat The matrix works fine, but I am trying to convert it into an array to use as a bitmap. 矩阵工作正常,但我试图将其转换为数组以用作位图。 The size of mat is N+1. mat的大小为N + 1。

Naively, I tried doing the following: 天真的,我尝试执行以下操作:

  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);
          }
  }

But this is gives me an exception when I debug: 但这在调试时给了我一个例外:

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

Any thoughts? 有什么想法吗?

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

This is what is causing you trouble. 这就是给您造成麻烦的原因。 Declaring a large matrix as a local variable in a function is not a good idea. 在函数中将大矩阵声明为局部变量并不是一个好主意。 Local variables are allocated on the stack. 局部变量在堆栈上分配。 Many machines limit the size of the stack to a smallish amount of data. 许多机器将堆栈的大小限制为少量的数据。 On my machine, the stack limit is about 8 megabytes. 在我的机器上,堆栈限制约为8兆字节。 That means a value of N larger than about a thousand will immediately result in stack overflow. 这意味着大于约一千的N值将立即导致堆栈溢出。 A value of N larger than several hundred (but smaller than a thousand) will result in a hard-to-trace stack overflow somewhere further down the call tree. 大于数百(但小于一千)的N值将导致在调用树下方的某个位置难以跟踪堆栈溢出。

Don't allocate large amounts of data on the stack. 不要在堆栈上分配大量数据。 Some alternatives are to 一些替代方法是

  • Declare the variable at namespace scope, 在名称空间范围内声明变量,
  • Allocate (and later free) the matrix using new and delete , 使用newdelete分配(然后释放)矩阵,
  • Use an ordinary Eigen matrix, which does the new and delete for you. 使用普通的本征矩阵,它会为您做newdelete的。

David Hammen's answer is the correct one ( double zmat[N+1][N+1]; is too large for the stack). David Hammen的答案是正确答案( double zmat[N+1][N+1];对于堆栈来说太大了)。 However, I feel the need to throw in my two cents regarding your usage. 但是,我觉得有必要就您的用法投入两美分。

The double loop is unnecessarily verbose and slow. 双循环是不必要的冗长和缓慢。 Even worse, using coeffref on each element of the matrix is actually making the matrix effectively dense. 更糟糕的是,在矩阵的每个元素上使用coeffref实际上会使矩阵有效地密集。 In the documentation for coeffRef it says: coeffRef文档中说:

If the element does not exist then it is inserted via the insert(Index,Index) function which itself turns the matrix into a non compressed form if that was not the case. 如果该元素不存在,则通过insert(Index,Index)函数将其插入,如果不是这种情况,则该函数本身会将矩阵转换为非压缩形式。
This is a O(log(nnz_j)) operation (binary search) plus the cost of insert(Index,Index) function if the element does not already exist. 如果元素尚不存在,则这是一个O(log(nnz_j))操作(二进制搜索)加上insert(Index,Index)函数的开销。

This means that not only is it verbose, it's going to add to your memory requirements and may become a bottleneck. 这意味着它不仅冗长,还将增加您的内存需求,并可能成为瓶颈。 You can instead use 您可以改用

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

or 要么

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

This is not only more readable, but much more efficient as well. 这不仅更具可读性,而且效率更高。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM