C++ Eigen 只读稀疏 block 子表达式?怎么写?

标签 c++ eigen

我想使用 Eigen 的 block 表达式从四个不同的矩阵创建一个大矩阵。

但是,在左上角添加第一个矩阵会导致错误:

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^^^

最佳答案

the tutorial explains :

Regarding read-access, sparse matrices expose the same API than for dense matrices to access to sub-matrices such as blocks, columns, and rows. See Block operations for a detailed introduction. However, for performance reasons, writing to a sub-sparse-matrix is much more limited, and currently only contiguous sets of columns (resp. rows) of a column-major (resp. row-major) SparseMatrix are writable. Moreover, this information has to be known at compile-time, leaving out methods such as block(...) and corner*(...).

对于您想要初始化左上角的特定用例,您可以利用以下事实:调整大小后,未初始化的矩阵条目隐式为零。所以这有效:

top_left.conservativeResize(block_laplacian_sq.rows(), top_left.cols());
block_laplacian_sq.leftCols(top_left.cols()) = top_left;

但是当您想要初始化底部行时,这对您没有帮助。假设您想用子矩阵初始化所有 4 个角,我建议构建一个大的三元组 vector (请参阅 Convert an Eigen matrix to Triplet form C++ ),然后一次性初始化最终矩阵。

一种可能的替代方案是用完整的列子矩阵的条目填充行主矩阵。我不知道这会如何更快,但也许它对于您的用例来说更优雅。

Eigen::SparseMatrix<double, Eigen::RowMajor> left(
      block_laplacian_sq.rows(), top_left.cols());
left.topRows(top_left.rows()) = top_left;
left.bottomRows(bottom_left.rows()) = bottom_left;
block_laplacian_sq.leftCols(left.cols()) = left;

(显然,您会尝试重新排列表达式以避免可能的行主要 <-> 列主要更改)

关于C++ Eigen 只读稀疏 block 子表达式?怎么写?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77457269/

相关文章:

c++ - 将自动说明符与 Eigen::Array 对象一起使用时会出现奇怪的结果

c++ - 如何在 C++ 中读取原始音频数据?

c++ - 需要一些帮助 - 左移按位运算符

C++: Address-of dereference 和 dereference of an address-of

c++ - 头文件中的错误 C2719 - 不使用 STL :vector

c++ - 如何有效地组装 FEM 稀疏矩阵

c++ - const 对象的复制构造函数

c++ - 是否有正当理由不从复制赋值运算符返回 *this ?

c++ - C++最佳实践中的矩阵创建破坏?

c++ - 在 Eigen 中乘以变换和矩阵类型