I have created a sparse matrix mat
in C++ using the Eigen package. 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.
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. That means a value of N
larger than about a thousand will immediately result in stack overflow. 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.
Don't allocate large amounts of data on the stack. Some alternatives are to
new
and delete
,new
and delete
for you.David Hammen's answer is the correct one (double zmat[N+1][N+1];
is too large for the stack). 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. In the documentation for coeffRef
it says:
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.
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.
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.
User contributions licensed under CC BY-SA 3.0