2014-09-26 3 views
2

내가 (너무 재미 아니다 : P) 빔 편향과 관련된 문제에 일하고 있어요 나는 구조 강성 행렬에 전체 강성 행렬을 줄일 필요가matlab에 - 포함 행렬에서 행과 열을 제거 0의

나는 내가 지금 같은 매트릭스가 있다면 그래서 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 

는 "만약"문을 포함하는 줄에 "인덱스 매트릭스 크기를 초과하는"나는 강성 행렬 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 

내가 얻을 그러나 글로벌 매트릭스 K를 줄이기 위해 지금까지 쓴거야, 나는 내 생각이 모든 행과 열을 제거하는 최선의 방법으로 맞는지 확실하지 않습니다. 모든 의견을 감사하십시오!

답변

3

쉬운 :

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

마술과 같은 홀리 스모크! 나는 "모든"기능을 살펴 봐야 할 것이다. ..... 정말 고마워! –

+0

하하하 나는 당신의 의견을 말 그대로 크게 웃으며 말하고있다. 감사! [this] (http://www.mathworks.es/es/help/matlab/math/matrix-indexing.html)도보십시오 –

+0

@zZShort_CircuitZz 저는 수정했습니다. 업데이트 된 대답을 참조하십시오 –

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 
+0

아주 좋은 접근! 'K1 * K1'을 사용하는 것은 매우 영리합니다. '+ 0'에 대해서'double()'보다 빠르다고 생각하십니까? :-) –

+0

@LuisMendo 어느 것이 더 빨라지는지 모르지만 대부분 '굳은 느낌'은 ​​'+ 0'이되고 어쨌든 작아 보입니다. 또한 생각하는 함수 호출을 피하는 것이 좋습니다. – Divakar

+0

@LuisMendo'double()'과'+0'을 비교하는 몇 가지 테스트를 진행했습니다. 'double()'은'1000x1000' 데이터 세트의 4 % -8 % 향상으로 한계를 이겨내는 것 같아요. 그렇지 않으면 둘 중 하나를 사용할 수 있다고 생각합니다. – Divakar

0

문제는 일부 행 또는 열 제거 i 또는 j를 증가시키지 말아야하지만 MATLAB의 for 루프는 자동으로 업데이트합니다. 그것은 단지 당신이 그것을 제거하지만, 제대로 어떻게 든 인덱스를 처리 할 필요가 있도록 조건을 깰 때문에 첫 번째 열을 제거합니다

0 1 0 
1 1 1 
1 1 1 

: 또한 알고리즘은 같은 사건을 처리 할 수 ​​없습니다. 또 다른 접근법은 먼저 행과 열의 곱을 취한 다음 그 제품을 검사하고 제품의 요소가 0 일 때 해당 행과 열을 제거하는 것입니다. 같은 MATLAB에서 예를 구현 수 있습니다 : 우리는 각 행의 제품과 우리가 수동으로 인덱스를 업데이트하여 0을 포함하는 행을 제거

% 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 

다음은 각 열을 계산 여기

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); 

(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 

여기에서는 나머지 작업에 동일한 작업을 적용합니다.

0

내가 제안 할 수있는 또 다른 방법은 행렬 K을 논리 행렬로 변환하여 0이 아닌 값이 모두 1이고 0이 아닌 값으로 변환하는 것입니다. 그런 다음이 행렬에 대해 행 합계를 수행 한 다음 보유하고있는 행 수의 합이 아닌지 확인하십시오. 이 열을 제거한 다음 중간 행렬에 행 합계를 수행하고 행 수가 합계가 아닌지 확인합니다. 이 행을 제거하여 최종 행렬에 남겨 둡니다.다음과 같이 :

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