我想知道是否可以有效地在稀疏矩阵中找到最大/最小系数。
似乎稀疏矩阵没有实现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;
}
答案 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);
其中mat
是Eigen::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类。