查找稀疏矩阵(本征)最大值的有效方法

时间:2019-08-14 07:07:41

标签: c++ eigen

我想知道是否可以有效地在稀疏矩阵中找到最大/最小系数。

似乎稀疏矩阵没有实现minCoeff()/ maxCoeff()函数,这有点奇怪。

我找到了这个答案here,但我找不到答案。

 using Tmp = typename remove_cv_ref<decltype(matrix)>::type;
 if constexpr(std::is_base_of<Eigen::SparseMatrixBase<Tmp>, Tmp>::value)
 max = Eigen::Map<const Vector>(matrix.valuePtr(), matrix.size()).maxCoeff();
 else
    max = matrix.maxCoeff();

编辑: 这是我的尝试,我不确定效率。

typedef Eigen::SparseMatrix<int, Eigen::RowMajor> SRI;
int maxCoeff(const SparseMatrix<int, RowMajor> &A)
{
    size_t row = A.rows();
    size_t col = A.cols();
    int max_value = -10000000;
    for (size_t k = 0; k < row; k++)
    {
        for (SRI::InnerIterator it(A, k); it; ++it)
        {
            if (it.value() > max_value)
                max_value = it.value();
        }
    }
    return max_value;
}

2 个答案:

答案 0 :(得分:3)

这些函数不容易使用,因为是否应该考虑隐式零可能是模棱两可的。例如,如果所有非零均为负数,maxCoeff是否应返回0

如果您只想考虑显式存储的元素,并且稀疏矩阵处于压缩模式,则可以编写:

auto max = matrix.coeffs().maxCoeff();

coeff方法等效于RHertel的答案。

答案 1 :(得分:2)

尝试使用此模板化函数以获得Eigen::SparseMatrix的最大非零值:

template <class T>
T sparseMax (SparseMatrix<T>& mat) { 
  return Map<Matrix<T, Dynamic, 1> >(mat.valuePtr(), mat.nonZeros()).maxCoeff();
}

此处的原理在于将稀疏矩阵的非零元素映射到向量(一维Eigen::Matrix)上,然后使用.maxCoeff()从中提取最大值。这应该是确定矩阵最大值的非常有效的方法。请注意,矩阵需要压缩,此方法才能起作用。

在代码中,函数sparseMax()可以这样调用:

if (!mat.isCompressed()) mat.makeCompressed();
auto max = sparseMax(mat);

其中matEigen::SparseMatrix

因此,链接中的答案几乎是正确的,但是.size()应该替换为.nonZeros(),它不能确保矩阵被压缩。如果您知道要处理SparseMatrix,则不需要链接答案中提到的if/else结构。


修改

以上解决方案适用于具有默认列主要存储顺序的SparseMatrix。对于RowMajor存储,可以将模板更改为

template <class T>
 T sparseMax_RM (SparseMatrix<T,RowMajor>& mat) { 
 return Map<Matrix<T, Dynamic, 1> >(mat.valuePtr(), mat.nonZeros()).maxCoeff();
}

如@ggael所指出的,一种更可靠的方法是使用成员函数.coeffs().coeffs()函数适用于RowMajor和ColMajor存储顺序这两种类型的压缩SparseMatrix类。