我想使用 Eigen 的块表达式从四个不同的矩阵创建一个大矩阵。
但是,在左上角添加第一个矩阵会导致错误:
error: static assertion failed: THIS_SPARSE_BLOCK_SUBEXPRESSION_IS_READ_ONLY
451 | EIGEN_STATIC_ASSERT(sizeof(T)==0, THIS_SPARSE_BLOCK_SUBEXPRESSION_IS_READ_ONLY);
我无法找到导致此问题的确切原因。不要将矩阵转换为密集表示,这一点非常重要。这是我的代码:
Eigen::SparseMatrix<double> top_left = K + Eigen::SparseMatrix<double>(K.transpose());
Eigen::SparseMatrix<double> block_laplacian_sq;
block_laplacian_sq.resize(top_left.rows() + C.rows(), top_left.cols() + C.rows());
block_laplacian_sq.topLeftCorner(top_left.rows(), top_left.cols()) = top_left;
// error here^^^
正如教程所解释的那样:
关于读取访问,稀疏矩阵与稠密矩阵公开相同的 API 来访问子矩阵,例如块、列和行。详细介绍请参见块操作。然而,出于性能原因,写入子稀疏矩阵受到更多限制,目前只有列主(或行主)
的连续列(或行)集是可写的。此外,这些信息必须在编译时已知,而忽略诸如SparseMatrix
和block(...)
之类的方法。corner*(...)
对于您想要初始化左上角的特定用例,您可以利用以下事实:调整大小后,未初始化的矩阵条目隐式为零。所以这有效:
top_left.conservativeResize(block_laplacian_sq.rows(), top_left.cols());
block_laplacian_sq.leftCols(top_left.cols()) = top_left;
但是当您想要初始化底部行时,这对您没有帮助。假设您想用子矩阵初始化所有 4 个角,我建议构建一个大的三元组向量(请参阅将特征矩阵转换为 C++ 形式的三元组),然后一次性初始化最终矩阵。