如何使用 C++ 将特征稀疏矩阵转换为数组?
How to convert an Eigen sparse matrix into an array in C++ using the?
我使用 Eigen 包在 C++ 中创建了一个稀疏矩阵 mat
。矩阵工作正常,但我正在尝试将其转换为数组以用作位图。 mat
的大小为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];
对于堆栈来说太大了)。但是,我觉得有必要在您的使用方面投入我的两分钱。
双循环不必要地冗长和缓慢。更糟糕的是,在矩阵的每个元素上使用 coeffref
实际上会使矩阵变得有效密集。在 coeffRef
的 documentation 中,它说:
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.
这意味着它不仅冗长,而且会增加您的内存需求并可能成为瓶颈。您可以改用
MatrixXd::Map(&zmat[0], (N+1), (N+1)) = mat.toDense();
或
MatrixXd::Map(zmat, (N+1), (N+1)) = mat.toDense(); // double zmat = new ...
这不仅更具可读性,而且效率也更高。
double zmat[N+1][N+1];
这就是给你带来麻烦的原因。将大矩阵声明为函数中的局部变量不是一个好主意。局部变量分配在堆栈上。许多机器将堆栈的大小限制为少量数据。在我的机器上,堆栈限制约为 8 兆字节。这意味着 N
的值大于大约一千将立即导致堆栈溢出。 N
的值大于几百(但小于一千)将导致难以跟踪调用树下方某处的堆栈溢出。
不要在堆栈上分配大量数据。一些替代方案是
- 在命名空间范围内声明变量,
- 使用
new
和 delete
、 分配(然后释放)矩阵
- 使用普通的特征矩阵,它会为你做
new
和 delete
。
我使用 Eigen 包在 C++ 中创建了一个稀疏矩阵 mat
。矩阵工作正常,但我正在尝试将其转换为数组以用作位图。 mat
的大小为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];
对于堆栈来说太大了)。但是,我觉得有必要在您的使用方面投入我的两分钱。
双循环不必要地冗长和缓慢。更糟糕的是,在矩阵的每个元素上使用 coeffref
实际上会使矩阵变得有效密集。在 coeffRef
的 documentation 中,它说:
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.
这意味着它不仅冗长,而且会增加您的内存需求并可能成为瓶颈。您可以改用
MatrixXd::Map(&zmat[0], (N+1), (N+1)) = mat.toDense();
或
MatrixXd::Map(zmat, (N+1), (N+1)) = mat.toDense(); // double zmat = new ...
这不仅更具可读性,而且效率也更高。
double zmat[N+1][N+1];
这就是给你带来麻烦的原因。将大矩阵声明为函数中的局部变量不是一个好主意。局部变量分配在堆栈上。许多机器将堆栈的大小限制为少量数据。在我的机器上,堆栈限制约为 8 兆字节。这意味着 N
的值大于大约一千将立即导致堆栈溢出。 N
的值大于几百(但小于一千)将导致难以跟踪调用树下方某处的堆栈溢出。
不要在堆栈上分配大量数据。一些替代方案是
- 在命名空间范围内声明变量,
- 使用
new
和delete
、 分配(然后释放)矩阵
- 使用普通的特征矩阵,它会为你做
new
和delete
。