能否直接访问Eigen稀疏矩阵的OuterStarts及相关内部数组?
嘿,这个问题问到点子上了——Eigen的稀疏矩阵底层接口其实设计得很灵活,我来给你理清楚:
直接访问Eigen稀疏矩阵的OuterStarts及其他底层数组?
一、能不能直接获取这些底层数组?
当然可以!不过要注意Eigen的稀疏矩阵分压缩格式和非压缩格式,不同格式的接口略有区别:
压缩格式(默认存储方式,比如CompressedRowMajor/CompressedColumnMajor)
这是最常用的存储格式,底层没有单独的InnerNNZs数组(信息已整合到外层索引里),其他三个数组可以直接通过成员函数获取:
OuterStarts(外层起始索引数组):用mat.outerIndexPtr(),返回Index*类型指针,直接指向底层数组InnerIndices(内层索引数组):mat.innerIndexPtr()Values(数值数组):mat.valuePtr()
非压缩格式(比如不带Compressed前缀的RowMajor/ColMajor)
这种格式保留了InnerNNZs数组,四个数组都能直接获取:
OuterStarts:依旧是mat.outerIndexPtr()InnerIndices:mat.innerIndexPtr()Values:mat.valuePtr()InnerNNZs:mat.innerNonZeroPtr()
这些接口都是Eigen官方提供的,高效且安全,优先用它们就好,不用自己造轮子。
二、如果特殊情况没法直接获取,怎么简洁实现?
如果因为某些限制(比如非常旧的Eigen版本)没法用上述接口,自己生成OuterStarts数组的话,可以优化你提到的遍历方法,不用逐个元素计数(当然逐个计数也没问题,只是下面的方式更高效):
// 示例:生成OuterStarts数组 Eigen::SparseMatrix<double> mat; // 假设mat已经完成初始化 std::vector<Eigen::Index> outer_starts(mat.outerSize() + 1, 0); Eigen::Index total_nnz = 0; for (Eigen::Index k = 0; k < mat.outerSize(); ++k) { outer_starts[k] = total_nnz; // 非压缩格式可以直接用innerNonZeroPtr获取当前外层的非零数 total_nnz += mat.innerNonZeroPtr()[k]; // 如果是压缩格式,就遍历当前外层的所有元素计数 // for (Eigen::SparseMatrix<double>::InnerIterator it(mat, k); it; ++it) { // total_nnz++; // } } outer_starts[mat.outerSize()] = total_nnz;
这样生成的outer_starts数组就和底层的OuterStarts完全一致了。
内容的提问来源于stack exchange,提问作者Mindong
相关产品推荐
相关产品推荐

