[英]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
一些替代方法是
new
and delete
, new
和delete
分配(然后释放)矩阵, new
and delete
for you. new
和delete
的。 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.