SturdyCobble's Study Note

[MATLAB] 05. 제어식과 논리 첨자 본문

프로그래밍/MATLAB

[MATLAB] 05. 제어식과 논리 첨자

StudyingCobble 2019. 8. 12. 13:26

NOTICE : 독학인 만큼, 잘못된 내용이 있을 수 있습니다. 내용 지적은 언제나 환영합니다.

더 이상 이 블로그에는 글을 올리지는 않을 예정입니다. 그렇지만 댓글을 달아주시면 최대한 답변드리고자 노력하겠습니다.


※ 이 글은 최소한 Python과 같은 프로그래밍 언어를 한 번 이상 접한 사람을 독자로 가정하여 작성되었습니다. 사용버전은 R2019a기준입니다. 또한 기본적인 프로그램 조작보다는 프로그래밍에 초점을 맞추어 작성하였습니다.

다른 프로그래밍 언어와 마찬가지로 조건부 제어문과 루프 제어문이 모두 MATLAB에 존재합니다. 다음과 같은 형태로 존재합니다.

%IF문

if 조건문
    실행 내용1
elseif 조건문
    실행 내용2
else
    실행 내용3
end

if문은 조건문을 판단해서 참인 경우 실행내용1을 실행하고, else if는 연결된 if문이 거짓인 경우 조건을 판단해 실행내용2를 실행합니다. else if는 여러개가 사용될 수 있으며, 나머지 상황에 대해서는 else를 통해 처리해줍니다. end는 각 if문을 마무리하는 키워드입니다.(물론 행렬의 마지막 요소를 참조하는 키워드이기도 합니다.)

  아래는 숫자를 조건에 따라 분류하여 분류 결과를 출력합니다.

a = 7;
if a > 10
	"a는 10보다 큽니다."
    if a > 100
    	"a는 100보다도 큽니다."
    end
elseif a <= 10
	"a는 10보다 작거나 같습니다."
else
	"삐빕.에러입니다."
end

---------출력 결과------------
ans = 

    "a는 10보다 작거나 같습니다."

 

%SWITCH문

switch 비교변수
   case 값1
      실행내용1
   case 값2
      실행내용2
   otherwise
      실행내용3
end

switch문은 비교변수의 값을 판단해서 일치하는 값에 대해 해당하는 실행 내용을 실행하고, 일치하는 값이 없는 경우 otherwise의 내용을 실행합니다.

 아래는 숫자에 따라 준비된 문장을 출력합니다.

a = 7.1;
switch a
    case 1
        disp("Hello")
    case 2
        disp("Nice")
    otherwise
        disp("Hmm..")
end
---------출력 결과----------
Hmm..

 

 

%WHILE문

while 조건식
    실행 내용
end

while문은 조건식이 참일때 실행할 내용을 반복하여 실행합니다.

 

 아래 예시는 랜덤으로 얻은 숫자가 0.8보다 크거나 작은 경우에만 반복문을 탈출하는 코드입니다. 즉 0.8미만일 때 반복문을 탈출하지 못합니다.

a = 0;
while a < 0.8
    a = rand();
    disp("실패")
end
disp("성공")
---------- 출력 결과 (랜덤이기 때문에 실패의 갯수는 차이가 있을 수 있음) ----------
실패
실패
실패
실패
실패
실패
실패
성공

 

%FOR문

for 제어변수 = 배열(또는 행렬)
    실행 내용
end

for문은 배열이나 행렬에서 한 요소씩(행렬이나 2차원 배열의 경우 하나의 열씩 가져옵니다. 즉 열벡터를 가지고옵니다.) 차례로 가지고 와서 제어변수에 대입시키는 방식으로 반복하며, 모든 요소를 다 읽을 때까지 반복합니다.

아래 예시는 행렬의 열벡터를 가지고 와서, 출력하는 예시입니다.

A = eye(3);
for colv = A
	disp(colv)
end

----------출력-------------
     1
     0
     0

     0
     1
     0

     0
     0
     1

 

또한, 반복문을 제어하기 위한 break문과 continue문도 존재합니다.

%반복문 안에서
break
continue

break문은 해당 반복문을 완전히 종료하며, continue문은 만나는 동시에 반복문 내의 continue문 뒤의 내용을 무시하게 합니다. 다만, break문과는 다르게 반복은 계속 진행됩니다.

 

 아래 예시는 break문과 continue문의 사용을 보여줍니다.

tot = 0;
num = 0;
x = 0 ;
y = 0;
while 1
    tot = tot + 1;
    x = rand();
    y = rand();
    if( x.^2 + y.^2 > 1)
        continue
    end
    num = num + 1;
    if tot >= 10000000000
        disp((num/tot)*4)
        break
    end
end
------------실행 결과-------------
3.1426





각 제어문의 의미는 Python에서의 해당 제어문의 의미와 매우 비슷합니다. 단, Switch문의 경우 C/C++, Java 등에서의 해당 제어문과 의미가 일맥상통합니다. 

제어문에 들어가는 조건식에는 논리값이 들어가야 합니다. 즉 1, true 또는 0, false가 들어가야 합니다. 이와 같은 값을 직접 넣어줄 수도 있지만, 관계 및 논리 연산자를 가지고 해당값을 반환하는 식을 작성할 수도 있습니다.


아래 예시들은 제어문들을 어떻게 사용하는지 보여줍니다.

아래는 조건식에 자주 사용되는 여러가지 연산자 및 함수에 대한 표입니다.

 

...더보기
연산자 또는 함수 의미 예시(≫는 입력을 표시)

여러 요소 사이 관계를 판단하는 함수와 연산자

==, eq함수

스칼라의 경우 동일한지

행렬의 경우 요소별 동일성을 나타내는 행렬 반환

eq함수와 동일함.
(a == b는 eq(a,b)와 동일)

%a = 10, b =1일때
a == b
ans =
  logical
   0

%A = [1 2 ; 3 4], B = [1 0 ; 3 4]일때

≫A == B
ans = 
  2×2 logical 배열 
   1   0 
   1   1

 

isequal 함수

isequaln 함수

두 값의 일치여부 반환

isequaln은 NaN을 서로 동일하다고 판단

%A = [1 2 ; 3 4], B = [1 0 ; 3 4]일때
≫isequal(A,B)
ans = 
   logical
   0

부등호
>, <, >=, <=
gt, lt, ge, le 함수

부등호

>, <, ≥, ≤

행렬의 경우 요소별로 비교해 성립 여부를 나타내는 행렬 반환

각각에 대한 함수 버전과 동일
( a > b 는 gt(a,b)와 동일 )


%a = 10, b = 3일때

≫a >= b
ans = 

   logical

   1

%A = [1 2 ; 3 4], B = [1 0 ; 7 4]일때
≫A > B
ans =

   2×2 logical 배열

   0   1

   0   0

~=
ne 함수

같지 않은지 판단

행렬의 경우 요소별로 비교해 논리 행렬 반환

≫10 ~= 9
ans = 
   logical
   1

isempty

비어있는지 판단

≫isempty([ ])
ans = 
   logical
   1

논리적 연산을 진행하는 함수 및 연산자

&
and함수

여러 조건식이 모두 참인 경우 참을, 나머지는 거짓을 반환

논리 배열의 경우 요소별로 판단해 논리 행렬 반환

(크기가 같지 않은 경우 행렬을 확장하여 연산.(자연수 번 행 또는 열 방향으로 확장하여 연산))

a>0 & b<0는 and(a>0,b<0)과 동일

≫10>0 & 8<0
ans =
   logical
   0
≫10>0 & -3<0 & 2<7
ans =
   logical
   1

I
or함수

여러 조건식이 모두 거짓인 경우 거짓을, 나머지는 참을 반환

논리 배열의 경우 요소별로 판단해 논리 행렬 반환
(크기가 같지 않은 경우 행렬을 확장하여 연산.)

a>0 | b<0는 or(a>0,b<0)과 동일

≫10>0 | 8<0
ans =
   logical
   1
≫[true false]|[true ; true]
ans =
   2×2 logical 배열
   1   1
   1   1

&&

Short-Circuit AND

※ 왼쪽부터 조건을 판단하며 해당 조건으로는 전체 조건을 계산할 수 없는 경우에만 다음 조건 판단

≫10>0 || "a"<0
ans =
   logical
   1
단, 계산 과정에서 10>0만으로 이미 참임이 결정되므로 "a"<0을 판단하지 않아 오류 발생 X

||

Short-Circuit OR

~
not함수

주어진 논리값(논리 행렬)을 반전시킴.

%A = [1 2 ; 3 4], B = [1 0 ; 3 4]일때
≫~(A == B)
ans = 
  2×2 logical 배열 
   0   1 
   0   0

xor함수

논리 배타적 OR

0이 아닌 요소가 한쪽에만 있는 경우 참

xor([true false], [false ; false])
ans = 
   2×2 logical 배열
   1   0
   1   0

all함수

벡터인 경우 모든 요소가 0이 아닌 경우 1 반환
비어있는 0×0행렬의 경우 1 반환
행렬의 경우 열벡터를 가져와 판단한 뒤 행벡터 반환

논리 행렬 A에 대해서 all(A,1)은 열벡터 기준, all(A,2)는 행벡터 기준 비교.

(AND의 확장판)

% A = [0 3 1; 3 1 2; 1 0 3] 일때
all(A)
ans = 
   1×3 logical 배열
   0   0   1

any함수

all과 비슷하나 OR의 확장판.

% A = [0 3 1; 3 1 2; 1 0 3] 일때
any(A)
ans = 
   1×3 logical 배열
   1   1   1

 

 

이러한 연산자 사이에는 우선 순위가 있는데요, 이에 관해서는 공식 문서를 참고해보세요.
https://kr.mathworks.com/help/matlab/matlab_prog/operator-precedence.html


혹시라도 표로 깔끔하게 보고 싶은 분들을 위해 표로도 정리해봤습니다.

 

우선순위 연산자
1 괄호 ()
2 전치(.'), 거듭제곱(.^), 켤레 복소수 전치('), 행렬 거듭제곱(^)
3 단항 마이너스 거듭제곱(.^-), 단항 플러스 거듭제곱(.^+), 논리적 부정 거듭제곱(.^~), 단항 마이너스 행렬 거듭제곱(^-), 단항 플러스 행렬 거듭제곱(^+), 논리적 부정 행렬 거듭제곱(^~).
(두번째 연산자부터 시작하여 왼쪽으로 진행함. 즉 A^~1은 A^(~1), 다시 말해 A^0과 동일)
4 단항 플러스(+), 단항 마이너스(-), 논리적 부정(~)
5 곱셈(.*), 오른쪽 나눗셈(./), 왼쪽 나눗셈(.\), 행렬 곱셈(*), 행렬 오른쪽 나눗셈(/), 행렬 왼쪽 나눗셈(\)
6 덧셈(+), 뺄셈(-)
7 콜론 연산자(:)
8 보다 작음(<), 보다 작거나 같음(<=), 보다 큼(>), 보다 크거나 같음(>=), 같음(==), 같지 않음(~=)
9 요소별 AND(&)
10 요소별 OR(|)
11 쇼트서킷 AND(&&)
12 쇼트서킷 OR(||)

 

단순히 전체를 외우기 보다는 쓸 때마다 참고하면서 자연스럽게 익히거나 괄호를 써서 우선 순위를 명시하는 것을 추천드립니다.


 

 

MATLAB에는 논리 첨자라는 문법이 있어서 논리식에 맞는 행렬의 요소만 추출하는 것이 가능합니다. 아래 예시를 참고해봅시다.

A = [11 23 32 ; 14 45 16 ; 77 108 102];
A(A>100) = 100;
A

점수를 저장하는 행렬인데, 오류로 100이 넘는 점수가 저장되었다고 합시다. 이때 100 이상의 요소만 인덱싱해서 100을 대입한 결과는 다음과 같습니다.

A =
    11    23    32
    14    45    16
    77   100   100

이와 같이 인덱싱할 때 숫자 첨자 대신 논리식을 통해서 논리 첨자를 사용할 수 있습니다.

 

만약 논리 조건을 만족하는 인덱스를 구하기 위해서는 find함수를 이용합니다.

A = [11 23 32 ; 14 45 16 ; 77 108 102];
find(A>100)'
%열벡터를 반환하나 행벡터로 만들기 위해 전치함.

결과는 다음과 같습니다.

ans = 
   
   6   9

 

선형 인덱스로 출력한 것을 볼 수 있습니다. 반대로, 이 값을 첨자로 줘서 다음과 같이 논리 첨자와 같은 효과를 낼 수 있습니다.

A = [11 23 32 ; 14 45 16 ; 77 108 102];
k = find(A>100);
A(k) = 100;
A

 

아래는 결과 입니다.

A =
    11    23    32
    14    45    16
    77   100   100

 

 

Comments