在矩阵中找到最稀疏的行

时间:2018-11-06 18:14:40

标签: matlab matrix sparse-matrix

我在MATLAB中有一个矩阵,我想确定哪一行包含最多零。也就是说,我想在矩阵中找到最稀疏的行(和列)。有什么方法比使用mat(sum(mat==0,i)==i,:)循环更有效吗?还是这是首选方法?

我将其用于通过使用“最小度排序启发式”求解线性系统来实现LU分解。

2 个答案:

答案 0 :(得分:7)

如果我正确解释的话,要找到“最稀疏”的行,这意味着您要查找具有最多零个数的行。您可以将sum以矢量化方式与max结合使用来解决这一问题:

[~, row] = max(sum(mat == 0, 2));

mat == 0会将整个矩阵转换为true/false,以使true为零值,而false为零,然后我们使用sum并求和逐行。这将减少这样的问题,即每个元素计算每行遇到多少个零元素。因此,使用max的第二个输出,row将包含具有最大零个数的行。我们将忽略第一个输出,因为这将输出实际的最大值,对于您的问题,我们将不在乎。

如果您担心速度,可以对向量为true/false的转换后的ones矩阵执行矩阵向量乘法。这样,它将为您执行求和,因此矩阵将提升为double精度:

[~, row] = max((mat == 0)*ones(size(mat, 2), 1)));

次要音符

请注意,如果存在共享相同数目的最大零个数的多个行,则此方法的局限性在于它将返回满足此条件的 first 行。就您的目标而言,我认为这应该足够了。另请注意,如果矩阵不包含没有零,则此方法的输出将默认为第一行。在某些极端情况下,我没有考虑到这些情况,但是我不确定您需要在多大程度上进行检查,因此为了简单起见,我将其省略。

答案 1 :(得分:2)

我不知道可以矢量化方式逐行执行此功能的函数(也就是说,直到我看到rayryeng's ingenious solution为止),但是遍历nnz的过程应该相当快。自从新引擎R2016a推出以来,循环不再非常缓慢。

[["header","content","test"],["header","content","test"],["header","content","test"]]

请注意:我反对使用tmp = zeros(size(mat,1),1); for ii = 1:size(mat,1) tmp(ii) = nnz(mat(ii,:)); end 作为变量as it denotes the imaginary unit