Matlab - 从包含0的矩阵中删除行和列

时间:2014-09-26 21:18:15

标签: arrays matlab matrix

我正在处理涉及光束偏转的问题(它不太有趣:P)

我需要将全局刚度矩阵减少到结构刚度矩阵中,我这样做是通过从包含0的原始矩阵中删除任何行和列。

所以,如果我有一个这样的矩阵(让我们称之为K):

0   0   5   3   0   0
0   0   7   8   0   0
7   1   2   6   2   1
3   8   6   9   5   3
0   0   4   5   0   0
0   0   1   8   0   0 

简化矩阵(让我们称之为S)只是

2   6
6   9

这是我到目前为止所写的将全局矩阵K减少到刚度矩阵S

的原因
S = K;

for i = 1:length(S(:,1))
    for j = 1:length(S(1,:))
        if  S(i,j) == 0
            S(i,:) = [];
            S(:,j) = [];
            break;
        end
    end
end

然而,我得到"指数超过矩阵维度"在包含" if"的行上声明,我不确定我的想法是否正确删除所有行和列的最佳方法。感谢任何反馈!

4 个答案:

答案 0 :(得分:3)

易:

S = K(all(K,2), all(K,1));

答案 1 :(得分:2)

对于nxn矩阵,您也可以尝试基于矩阵乘法的方法 -

K=[
    0   0   5   3   2   0
    0   0   7   8   7   0
    7   1   6   6   2   1
    3   8   6   8   5   3
    0   0   4   5   5   0
    5   3   7   8   1   6]  %// Slightly different than the one in question

K1 = double(K~=0)
K2 = K1*K1==size(K,1)
K3 = K(K2)
S = reshape(K3,max(sum(K2,1)),max(sum(K2,2)))

输出 -

S =
     6     6     2
     6     8     5
     7     8     1

答案 2 :(得分:0)

问题是,当您删除某些行或列时,不应该增加i或j,但MATLAB for循环会自动更新它们。此外,您的算法无法处理如下情况:

0 1 0
1 1 1
1 1 1

它只会因为中断条件而删除第一列,因此您需要删除它,但不知何故正确处理索引。另一种方法可能是首先获取行和列的乘积然后检查那些产品并在产品的元素为零时移除相应的行和列。 MATLAB中的示例实现可能如下:

function [S] = stiff(K)
S = K;
% product of each row, rows(k) == 0 if there is a 0 in row k
rows = prod(S,2);
% product of each column, cols(k) == 0 if there is a 0 in column k
cols = prod(S,1);

这里我们计算每行和每列的乘积

% firstly eliminate the rows
% row numbers in the new matrix
ii=1;
for i = 1:size(S,1),
    if rows(i) == 0,
        S(ii, :) = []; % delete the row
    else
        ii = ii + 1; % skip the row
    end
end

这里我们通过手动更新索引来删除包含零的行(注意ii)。

% handle the columns now
ii = 1;
for i = 1:size(S,2),
    if cols(i) == 0,
        S(:, ii) = []; % delete the row
    else
        ii = ii + 1; % skip the row
    end
end
end

这里我们对剩余的列应用相同的操作。

答案 3 :(得分:0)

我可以建议的另一种方法是将矩阵K转换为逻辑矩阵,否则任何非零的都是10。然后,您将对此矩阵执行列总和,然后检查是否有任何列不与您拥有的行数相加。您删除这些列,然后在中间矩阵上执行行和,并检查是否有任何行不与您拥有的列数相加。您删除这些行以留下最终矩阵。就这样:

Kbool = K ~= 0;
colsToRemove = sum(Kbool,1) ~= size(Kbool,1);
K(colsToRemove,:) = [];
rowsToRemove = sum(Kbool,2) ~= size(Kbool,2);
K(:,rowsToRemove) = [];