Reputation: 185
I'm working on a problem involving beam deflections (it's not too fun :P)
I need to reduce the global stiffness matrix into the structure stiffness matrix, I do this by removing any rows and columns from the original matrix that contain a 0.
So if I have a matrix like so (let's call it 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
The reduced matrix (let's call it S) would be just
2 6
6 9
Here's what I have written so far to reduce global matrix K to stiffness matrix 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
However I get "Index exceeds matrix dimensions" on the line containing the "if" statement, and I'm not sure my thinking is correct on the best way to remove all rows and columns. Appreciate any feedback!
Upvotes: 2
Views: 1599
Reputation: 221564
For nxn
matrix, alternatively you can try out matrix multiplication based approach -
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)))
Output -
S =
6 6 2
6 8 5
7 8 1
Upvotes: 2
Reputation: 104503
Another method I can suggest is by converting the matrix K
into a logical matrix where anything that is non-zero is 1
and 0
otherwise. You would then do a column sum on this matrix then check to see if any columns don't sum to the number of rows you have. You remove these columns, then do a row sum on the intermediate matrix and check if any rows don't sum to the number of columns you have. You remove these rows to be left with your final matrix. As such:
Kbool = K ~= 0;
colsToRemove = sum(Kbool,1) ~= size(Kbool,1);
K(colsToRemove,:) = [];
rowsToRemove = sum(Kbool,2) ~= size(Kbool,2);
K(:,rowsToRemove) = [];
Upvotes: 0
Reputation: 79
The problem is when you remove some row or column you should not increase i or j but MATLAB's for loop automatically updates them. Also your algorithm cannot handle the cases like:
0 1 0
1 1 1
1 1 1
It will only remove the first column due to break condition so you need to remove it but handle indexes properly somehow. Another approach may be firstly taking product of rows and columns then checking those products and removing the corresponding rows and columns when an element of a product is zero. An example implementation in MATLAB might be like:
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);
Here we compute the product of each row and each column
% 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
Here we remove rows that contain zeros by updating the index manually (notice 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
Here we apply same operation to remaining columns.
Upvotes: 0