본문 바로가기
매트랩(Matlab)/매트랩 강의

[Matlab / 매트랩] 8. m-file 만들기 // 행렬 입력 고급편

by freezkim 2010. 2. 3.

[Matlab / 매트랩] 매트랩 강의 8번째 

m-file 만들기 시리즈 (1) // 행렬 입력&출력 고급편  

검색어 노출을 위해 제목에 한글로 매트랩이란 글자를 집어넣었습니다 하핫 

저번 시간 맛배기로나마 m-file을 다뤄 보았는데요.  

이번 시간 부터는 한 3 강좌 정도, 직접 m-file 코딩 하는 걸 해볼까 합니다. 

아, 대체 어떻게 어디부터 시작해야 할지 굉장히 고민이 됐는데요. 

뭐 에휴 모르겠습니다ㅋㅋ 

흠... 코드를 짤때 중요하다 싶은 명령어들 위주로 설명하는걸로 해볼까 해요. 

크게 입력//연산//출력 요렇게 3파트로 나눠서 주로 쓰이는 명령어를 다뤄볼까 합니다. 

그리고 예제를 몇개 적는 걸로 한번 해보죠 흐흐 

  

오늘은 m-file에서 데이터를 입력 받는 파트를 다뤄볼까 하는데요.
매트랩은 기본적으로 데이터를 행렬형식으로 구성하므로, 행렬의 입력&출력 방법을 세밀하게 다뤄볼까 합니다. 

다루기 전에 일단 왜 행렬의 입력&출력만 하면 딴건 뭐 볼거도 없는건지 이유나 한번 알아보도록 하죠.
그래야 뭔가 강의가 좀 의미있지.....않을까요? 

앞서 말했듯이 매트랩은 데이터를 행렬형식으로 구성합니다.
뭔소리냐면 어떤 데이터 A를 지정한다면 그 데이터는 기본적으로 m by n의 행렬로 구성이 된다는 말입니다. 

어으 이게 뭔소리여 일단 걍 직접 매트랩에 쳐 봅시다. 

>> A=1
A =

     1 

자 그리고 이쯤에서 적절하게 Workspace를 스윽 봅시다 

 요기서 빨갛게 밑줄 친 A를 한번 더블클릭해볼까요 

 헐 그랬더니 쩌는 결과가 나옵니다.  

Array Editor-A라는 이름의 창이 뜨면서 이건 뭐 액셀 저리가라 수준의 뭐시기 거시기가 뜹니다. 

자 요걸 보시면, A라는게 행렬이지만  (1,1)행렬 원소만 1로 지정되어 있고 나머지 칸은 전부비워져 있는 것을 볼 수 있습니다. 

즉 우리가 A=1 이라고 지정했더라도, A라는 게 1이라는 단순한 숫자가 아니라 

1 by 1 크기의 A 행렬의 (1,1) 성분에 1을 지정한다. 라는 의미가 되는 겁니다. 

다시말해. 단순 숫자를 지정하더라도, 매트랩은 "행렬 형식"으로 받아들인다. 요 의미죠. 

그러니깐 뭔 짓거리를 하던지 

행렬만 정복하여라, 매트랩을 정복할 것이다. 우하하하허허허허 

라고 해도 과언이 아닐겁니다. 

  

자 그렇기에, 행렬의 입력, 출력만으로도 일단은(...) 충분하게 되는 것입니다. 

그럼 바로 시작하겠습니다. 

1. 행렬 입력&출력 고급편  

1강에서 이미 행렬을 만드는 방법은 했습니다.  하지만 문자 그대로 "기초" 만 다뤘었습니다. 

행렬에 입력에 대해 훗날만을 기약했었는데요. 이제 오늘 여기서 감히 행렬에 관련된 모든것(?)을 해보고자 합니다. 

1) 행렬의 입력방법,         -   행렬이름 = [처음값:값 증가량:끝값]    - 

어떤 행렬을 만들때는
행렬 이름 = [행렬의 원소] 
형식으로 만든다는 것은 이미 앞의 강의에서 다뤘었습니다.
이 행렬의 원소를 지정할 때 쓰이는 방법을 다뤄보도록 할게요.
설명없이 바로 예제로 시작해보겠습니다. 

>> A=[1:1:5]
A =
     1     2     3     4     5
 
이렇게 A라는 행렬의 입력 방법 중 한가지인 [처음값:값의 증가량:끝값] 을  적는 것으로 만들었는데요.
같은 행렬인데, 요렇게도 만들 수 있습니다. 

>> B=[1:5]
B =
     1     2     3     4     5 

여기서는 값의 증가량을 지정하지 않았습니다. 하지만 그 경우 증가량은 자동적으로 1이 지정되게 됩니다.
그래서 B가 A랑 똑같은 행렬이 된거지요. 

자 그럼 다음 코드를 한번 봅시다.
>> C=[5:-1:1]
C =
     5     4     3     2     1

>> D=[-11:2:14]
D =
   -11    -9    -7    -5    -3    -1     1     3     5     7     9    11    13

C는 증가량이 -1 이니깐 5~1 순서로 출력이 되고
D는 증가량이 2니깐 -11에서 2씩 증가하여 14보다 작은 범위의 최대값인 13 까지 출력이 되게 됩니다. 

응용하면 이런식으로 행렬 만드는게 가능하겠죠.
>> E=[1:5 ; -2:2:6 ; 3:-1:-1]
E =
     1     2     3     4     5
    -2     0     2     4     6
     3     2     1     0    -1

>> F=[1, 1:3, 5]
F =
     1     1     2     3     5 

자, 요 방식을 잘 기억해두시고, 다음 단계로 넘어가 봅시다.

 
2) 행렬 원소의 출력방법,         -   행렬(i,j)  => 행렬의 i,j번째 원소    -

자 위에서 만든 행렬을 그대로 이용할 건데요.
이번엔 위의 행렬에서 직접 행렬 성분을 출력하는 걸 해볼까 합니다.
백문이 불여일견, 일단 코드를 한번 봅시다.

>> E(1,1)
ans =

     1

>> E(2,4)
ans =

     4

E 괄호하고 (1,1)이라고 쳤더니, 숫자 1이 나왔습니다. 자 여기서 E(1,1)의 의미는, "E라는 행렬의 (1,1)성분이라는 의미입니다. E(2,4)면 E 행렬의 (2,4) 성분이니 4가 결과로 출력되게 됩니다. 

자, 그럼 원소 출력 방법과 위의 1)에서 잘 기억하시라고 했던 방식을 합쳐볼게요. 

>> E(1,1:3)
ans =

     1     2     3 

자, 요 경우를 한번 봅시다. E(1, 1:3) 이라고 선택하였더니 E라는 행렬의 첫번째 행에서 1~3번째 성분이 출력 되었습니다.
요걸 분석을 한번 해봅시다.
위에서 1:3 이라는 건 이미 한번 다뤘었죠? 이 1:3 이란 것은 다음과 동일한 효과를 발휘합니다.

1:3 = [1 2 3] 

그럼 위의 E(1,1:3) 은 요런 뜻이 되는거죠.
E(1,1:3) => E행렬의 1번째 행의 1, 2, 3열 성분
따라서 1, 2, 3이 출력되게 된 겁니다.

확인을 위해 한번 더 보여드릴게요.

>> E(1:3,3)

ans =

     3
     2
     1

요 경우는 1~3행에서 3번째 열에 해당하는 원소가 출력되게 된거죠.
아실거라 믿습니다. 

자 그럼 한단계 더 나아가서 요런 코드를 보여드릴게요.

>> E(1,:)

ans =

     1     2     3     4     5

E의 1번째 행의 원소이긴 한데, 열 지정을 숫자로 해주지 않고 그냥 콜론(:) 만 쳤습니다.
이런 경우는 범위 내의 처음부터 끝값까지, 라는 의미가 됩니다. 즉 E라는 행렬은 1~5열까지 존재하므로, 1~5열 성분을 전부 선택한다. 이런 의미가 되는거죠.
 

비슷하게 이런 코드를 볼까요?

>> E(:,1)

ans =

     1
    -2
     3

네, 행을 : 로 지정했기 때문에, 존재하는 행 전체 1~3행의 1열 성분이 출력되게 된거죠. 

그럼 마지막으로 요런식으로 치면 어떤 결과가 나오는지 한번 예측해 보실래요? 

>>E(1:2,1:2:5) 
 

3) 행렬 원소의 입력방법,         -   행렬(i,j)  = 숫자   -

자, 다시 행렬의 입력으로 돌아갑니다.
이전에는 행렬을 입력할 때, 행렬 전체를 만드는 것으로 입력을 했습니다. 

즉,
행렬 이름 = [행렬의 원소]  

이런 구조였던거죠. 

하지만 행렬의 원소를 하나하나 지정해서 행렬을 만드는 방법도 있습니다.
위의 2)에서 다뤘던 출력을 응용한 건데요. 행렬(i,j) 를 치게되면 행렬의 i,j번째 성분이 출력된다는 것을 역이용해서

"행렬(i,j) = 입력할 숫자 "

를 치게되면 행렬의 (i,j)번째 성분이 "입력할 숫자"로  입력되게 되는 겁니다. 

한번 코드를 쳐보죠. 

>> M(1,1)=1

M =

     1

자, M이라는 행렬의 (1,1) 성분은 1이다. 라고 지정했더니, M이라는 행렬이 만들어지는 동시에, M행렬의 (1,1) 성분이 1로 출력된 것을 확인할 수 있습니다.

예를 한번 더 보죠.

>> N(1,5)=2

N =

     0     0     0     0     2

자, N이라는 행렬의 (1,5) 성분은 2다. 라고 지정했더니, N이라는 행렬이 만들어지는 동시에 N행렬의 (1,5)성분이 2로 출력된 것을 확인할 수 있습니다.

요때 다른 행렬 성분은 지정을 안하면 기본적으로 0으로 지정됩니다. 

이 방법을 이해하셨다면, 이제 콜론을 이용한 숫자 지정방법, 즉, [처음값:증가하는 값: 끝값] 을 응용해서 행렬을 만들 수 있겠죠? 한번 직접 만들어 보겠습니다.

>> X(1:2,1:5)=1

X =

     1     1     1     1     1
     1     1     1     1     1

1:2행, 1:5열에 해당하는 X의 원소를 1로 지정하였습니다.
여기다가, 3행의 값은 X의 원소를 2로 한번 지정해볼게요. 

>> X(3,:)=2

X =

     1     1     1     1     1
     1     1     1     1     1
     2     2     2     2     2

X(3,:) 즉, X의 3열 성분은 2로 입력을 하였더니 기존에 지정되어 있던 X 행렬에 3행이 추가되면서, 2로 저장된 것을 볼 수 있습니다.
 

자 요렇게 행렬의 입력 & 출력은 마무리가 됩니다.


정리를 하면,

콜론을 이용한 방법으로 숫자 지정을 할 수 있으며
요걸 가지고 행렬의 원소를 출력할 수도 있고
요걸 가지고 행렬의 원소에 직접 특정한 숫자를 집어넣을 수도 있다. 

라는게 오늘 강의의 전부네요. 

흐흐 진짜 한게 없군요. 밑에 오늘 한 내용으로 m-file 예제나 한번 짜보죠 뭐. 

내용이 그렇게 어려운 건 아닌데요.
처음 접하시면 좀 복잡하실 수 있을거라 생각됩니다.
 

오늘 한 내용은 정말 진짜 무지무지 중요한거니깐 단 하나라도 잊으시면 안돼요!!!!! 

저 앞으로 이 부분에 대해서는 설명없이 코딩 막 쳐버릴 겁니다. 쉬크하게 넘어갈테니 여러번 반복하면서 머리속에 꼭 기억해 두시길 바랄게요.

 

2. 행렬 입력&출력 응용 m-file 프로그래밍 

럼 위 내용을 응용해서 m-file 프로그래밍을 한번 해볼께요. 

음.......

음......

음.....
 

에이 걍 다음에 합시다.
 

이러고 싶긴한데ㅠㅠ 그럼 다음에는 또 미뤄지고 미뤄지고 하면 결국 사태는 걷잡을 수 없이 커지고 로드는 빡세지고 시험기간은 다가오고... 뭔소리여 

오늘 합시다.
 

좋아요. 요런 프로그래밍을 한번 해봅시다. 

어떤 행렬을 입력값으로 받아주면
그 행렬의 첫번째 열과, 마지막 열을 바꾼 행렬을 출력하는 프로그램한번 짜보죠.

프로그램 이름은, Shift_column 으로 하죠 뭐 까짓꺼.
 

여기서 오늘 한 강의 외에 필요한 명령어는 length() 입니다.
 

일단 코드를 한번 짜고 설명해 볼게요.

-------------------------------------m-file은 다음과 같이 짰습니다.---------------------------

function Y = Shift_column(X)    // 이 명령어에서 출력되는 데이터는 Y, 입력 받는 데이터는 X로 이름을 지정했습니다.

n=length(X(1,:));

// length는 행렬의 크기를 구해주는 명령어 입니다. 여기서 X(1,:)의 크기를 n이라는 숫자로 지정하는 거죠.  X라는 행렬이 M by N 이라면 X(1,:)는 1 by N 행렬이므로, 숫자 n은 1 by N의 크기, 즉 N으로 지정 되는 겁니다.

A=X(:,1);                      // X의 첫번째 열을 A로 저장했습니다.
B=X(:,n);                      // X의 마지막 열을 B로 저장했습니다.

Y=X;                            // 출력되는 데이터 Y는 일단 X와 똑같이 지정했습니다. 

Y(:,1)=B;                      // Y의 첫번째 열을 X의 마지막 열 B로 저장했습니다.
Y(:,n)=A;                     // Y의 마지막 열을 X의 첫번째 열 A로 저장했습니다.
---------------------------------------------------------------------------------------------- 

m-file을 Shift_column으로 저장하고, 매트랩의 Current Directory를 m-file이 존재하는 폴더로 지정한
Command window에 다음과 같이 쳐서 코드가 돌아가나 확인해 봤습니다. 

>> E=[1:5 ; -2:2:6 ; 3:-1:-1]
E =

     1     2     3     4     5
    -2     0     2     4     6
     3     2     1     0    -1
 

>> F=Shift_column(E)

F =

     5     2     3     4     1
     6     0     2     4    -2
    -1     2     1     0     3

E를 지정하였더니 그 결과가 보이죠?
그리고 Shift_column이라고 짠 함수를 거쳤더니 1열과 5열이 바뀌어서 출력된걸 확인할 수 있습니다.
하하하 잘 되는군요 후후 

프로그래밍이 생소하신 분들은 오늘 내용이 좀 어려울 수도 있을 것 같아요.
잘 이해 안가시는 부분 있으시면 질문주시고, 열심히 계속 해봅시다!!  







 

Tip!! 

1) 행렬이 1 by N 이나 M by 1 크기면 행렬 원소를 (i,j)가 아니라 (i)로 나타낼 수 있습니다. 즉, 벡터 형식으로 생각해서 i번째 원소로 표현이 가능한거죠. 예를 들어 A=[1 2 3 4 5] 라면 A의 3번째 원소는 A(3) 으로도 나타낼 수 있습니다. 

2) m-file에서 사용되는 변수는 매트랩 실행창의 command window와 별개입니다. 예를 들어 오늘 직접 만들었던 함수인 Shift_column에서 지정하였던 변수 - X, Y, A, B, n는 요 m-file 내부에서만 작동하는 임시 변수입니다. 만일 command window에서 X,Y,A,B,n이라는 이름의 데이터를 만들었다 해도 m-file 내부의 코드에 아무런 영향을 미치지 않습니다. 관계무관, 전혀 별개입니다. 

3) m-file의 입력 변수 이름과 command window에서 함수에 입력할 데이터 이름을 통일할 필요는 전혀 없습니다. 위에서 썼듯이, m-file의 변수들은 단순히 데이터의 관계를 나타내기 위해 이름을 지정한 것 뿐입니다. 즉, 위의 X라는 거도 단순히 입력변수가 들어오면 X처럼 처리하겠다. 라는 의미일 뿐입니다.

위에서도 m-file에는 X라고 입력변수가 지정되어 있지만 command window에서는 E라는 행렬을 입력값으로 넣었습니다. m-file 내부의 변수는 m-file 내부에서 끝, 이라고 알아두시면 될것 같습니다.

 

*** 단 예외가 있는데요. m-file 내부에서 데이터를 지정할 때 실제로 command window 상에서 데이터가 똑같이 선언되는 경우가 있습니다. 이 경우는 m-file을 function으로 만들지 않고 바로 m-file에 코드를 쳤을 때, 즉 m-file의 기능이 함수를 만드는 기능이 아니라 command window를 단순히 작동하는 경우일 때는 데이터가 똑같이 선언됩니다.***