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

1dkrff03  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(165)

我想用特征块表达式从四个不同的矩阵中创建一个大矩阵。
然而,在左上角添加第一个矩阵会导致错误:

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

nafvub8i

nafvub8i1#

the tutorial explains
关于读访问,稀疏矩阵公开与密集矩阵相同的API来访问子矩阵,如块、列和行。有关详细介绍,请参阅块操作。但是,出于性能原因,写入子稀疏矩阵的限制要多得多,目前仅限于连续的列集此外,这些信息必须在编译时已知,而不考虑像block(...)corner*(...)这样的方法。
对于你想要初始化左上角的特定用例,你可以使用这样一个事实,即在初始化之后,未初始化的矩阵元素隐式为零。所以这是可行的:

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

字符串
但是当你想初始化最下面的行时,这并没有帮助。假设你想用子矩阵初始化所有4个角,我建议你构建一个三元组的大向量(参见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;


(显然,你会尝试重新排列表达式,以避免行为主<->列为主的变化在可能的情况下)

相关问题