You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效提取稠密Eigen::Matrix对象中的所有非零值

Eigen 稠密矩阵提取非零值的最高效实现

通用实现(兼容任意稠密矩阵,非零占比高时性能最优)

直接通过预分配内存+遍历实现,避免额外类型转换开销,完全匹配你给出的示例输出顺序:

#include <Eigen/Dense>

template <typename Scalar>
Eigen::Vector<Scalar> get_non_zero_values(const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>& mat)
{
    // 先统计非零元素总数,一次性预分配内存,避免动态扩容开销
    const Eigen::Index non_zero_count = (mat.array() != 0).count();
    Eigen::Vector<Scalar> result(non_zero_count);

    Eigen::Index pos = 0;
    // 行优先遍历,和示例输出顺序一致,需要列优先可交换两层循环顺序
    for (Eigen::Index row = 0; row < mat.rows(); ++row) {
        for (Eigen::Index col = 0; col < mat.cols(); ++col) {
            if (mat(row, col) != 0) {
                result(pos++) = mat(row, col);
            }
        }
    }
    return result;
}

这个实现是所有场景下性能基准最高的方案,不需要引入稀疏矩阵相关依赖,也没有额外的类型转换开销

低非零占比场景的简化实现

如果你的矩阵非零元素占比低于10%,可以通过转稀疏矩阵的方式简化代码,遍历效率更高:

#include <Eigen/Dense>
#include <Eigen/Sparse>

template <typename Scalar>
Eigen::Vector<Scalar> get_non_zero_values(const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>& mat)
{
    // RowMajor参数保证行优先遍历,和示例顺序一致,不需要可删除
    Eigen::SparseMatrix<Scalar, Eigen::RowMajor> sparse_mat = mat.sparseView();
    Eigen::Vector<Scalar> result(sparse_mat.nonZeros());

    Eigen::Index pos = 0;
    for (Eigen::Index outer = 0; outer < sparse_mat.outerSize(); ++outer) {
        for (typename Eigen::SparseMatrix<Scalar, Eigen::RowMajor>::InnerIterator it(sparse_mat, outer); it; ++it) {
            result(pos++) = it.value();
        }
    }
    return result;
}

测试验证

你给出的示例代码调用后输出完全符合预期:

int main()
{
    Eigen::Matrix3f m;
    m << 1, 0, 0,
         0, 5, 6,
         0, 0, 9;
    Eigen::VectorXf v = get_non_zero_values(m);
    // 按行输出匹配你的示例格式
    std::cout << v.transpose() << std::endl;
    return 0;
}

输出结果:

1 5 6 9

内容的提问来源于stack exchange,提问作者SolvedForHome

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 04:48:04