관계 연산이나 논리연 산에서는 C언어에서와 유사하게 MATLAB은 0을 거짓으로 0이 아닌 다른 수(보통은 1이 쓰임)를 참으로 간주한다. 모든 관계 연산과 논리 연산에서 참이면 1, 거짓이면 0을 그 결과로서 반환한다. MATLAB에서의 관계 연산자는 다음 표와 같다.


[표 1] 관계 연산자

관계 연산자

의미

<

작다.

<=

작거나 같다.

>

크다.

>=

크거나 같다.

==

같다.

~=

다르다.


위의 표에서 ‘같다’와 ‘다르다’에 주의해야 한다. C언어를 처음 배울 때도 대입연산자(=)와 관계연산자(==)를 혼동해서 논리적 오류를 범하는 경우가 많은데 여기에서도 그렇다. 두 연산자를 잘 구분해야 한다. 그리고 ‘다르다’는 (!=)가 아니고 (~=)임에 유의하자.


 관계연산자의 피연산자는 두 개인데 다음의 두 가지 경우가 있을 수 있다.

① 둘 다 행렬일 경우 - 이 경우는 두 행렬의 차수가 같아야 하고 각 행렬의 요소간의 관계가 검색된다. 결과로는 같은 차수의 행렬이 생성된다.

② 하나는 행렬 다른 하나는 스칼라인 경우 - 스칼라와 행렬의 각 요소간의 관계가 검색되며 결과로는 행렬과 같은 차수의 행렬이 생성된다.

 다음의 예를 보자.


>> A=1:4, B=4-A
A =
1 2 3 4
B =
3 2 1 0

>> C = A>2
C =
0 0 1 1

>> D = (A==B)
D =
0 1 0 0

>> E = A<=B
E =
1 1 0 0


첫 번째 예에서는 행렬 A와 스칼라 2를 비교했다(A>2). 따라서 행렬 A의 각 요소와 2를 비교해서 그 요소가 크면 1을 그렇지 않으면 0을 가지는 행렬을 만들어서 C에 대입하는 것이다. (A==B)에서는 둘 다 행렬이고 이 경우에 두 행렬의 크기는 같아야 한다. 같은 위치에 있는 요소를 비교하여 같으면 1 다르면 0을 갖는 행렬을 반환하게 된다.


 다음과 같이 관계연산자와 산술연산자를 혼용할 수도 있다.


>> B-(A>2) 󰎠
3 2 0 -1


위의 예에서 (A>2)의 결과는 0과 1로 이루어진 보통의 행렬이기 때문에 산술연산(이 경우 뺄셈)에 사용될 수 있음을 보여주는 것이다. 다음 예제를 보자.


>> x1=-1:1
x =
-1 0 1

>> x2=x1+(x1==0)*eps
x2 =
-1.0000 0.0000 1.0000


위의 예제에서 벡터 x1을 [-1 0 1]로 생성시키고 두 번째 명령에서 x1에서 0인 요소를 찾아서 0대신 eps를 대입한 후 x2에 대입한 것이다. eps는 MATLAB에서 표현할 수 있는 가장 작은 수이다. 이제 다음을 보자.


>> sin(x1)./x1
0.8415 NAN 0.8415


위에서 두 번째 요소가 NAN인데 이것은 x1의 두 번째 요소가 0이고 sin(0)도 0이기 때문에 0/0 인 결과가 되어서 그렇다. 올바른 극한값 1을 얻기 위해서는 x1의 0을 eps로 치환한 x2를 이용하면 된다.


>> sin(x2)./x2 󰎠
0.8415 1.0000 0.8415



Posted by 살레시오

 여기에서는 행렬-스칼라 그리고 행렬-행렬간의 산술 연산에 대해서 설명을 하겠다. 다음의 예를 보자.


>> G=[1 2 3 4;5 6 7 8]
G =
1 2 3 4
5 6 7 8

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

>> -2+G
-1 0 1 2 3 4 5 6


이 예에서 변수 G는 행렬이고 2는 스칼라이다. 기본적으로 (수학적인) 행렬의 덧셈 뺄셈은 두 행렬의 차수가 같아야 하지만 한쪽이 스칼라이고 다른 한쪽이 행렬이면 행렬의 모든 요소에서 그 스칼라를 더하거나 빼준 행렬을 결과로 내보낸다.


>> 2*G-1 󰎠
1 3 5 7
9 11 13 15


스칼라와 벡터/행렬의 곱은 수학적인 의미 그대로이며 연산 우선순위도 스칼라연산과 같다. 위의 경우 곱을 먼저 행하고 뺄셈을 행하게 된다.


 행렬 간의 덧셈, 뺄셈은 두 연산자의 차수가 같아야 한다. 다음과 같이 행렬 G와 H를 입력해보자.


>> G=[1 2 3 4; 5 6 7 8; 9 10 11 12] 󰎠
G =
1 2 3 4
5 6 7 8
9 10 11 12

>> H=[1 1 1 1;2 2 2 2; 3 3 3 3] 󰎠
H =
1 1 1 1
2 2 2 2
3 3 3 3


그리고 다음과 같이 덧셈, 뺄셈을 수행해 보라.


>> G+H
2 3 4 5
7 8 9 10
12 13 14 15

>> ans-H
1 2 3 4
5 6 7 8
9 10 11 12

>> 2*G-H
1 3 5 7
8 10 12 14
15 17 19 21


 곱셈의 경우 곱셈기호(*)앞의 행렬의 열수와 뒤 행렬의 행수가 같아야 계산이 수행된다. 따라서 위의 두 행렬 G와 H는 곱셈을 할 수 없다. Ht라는 행렬을 다음과 같이 정의하면


>> Ht=h'
Ht =
1 2 3
1 2 3
1 2 3
1 2 3


이제 행렬 G(차원)와 Ht(차원)간의 곱셈은 가능해진다.


>> G*Ht
10 20 30
26 52 78
42 84 126


 다른 연습 예제로서 다음과 같은 행렬 A와 B가 있을 때,

두 행렬의 곱 AB, BA, ATBT, BTAT 를 각각 구해보라.

 MATLAB에서 행렬간의 곱셈은 이와 같은 보통 행렬 간 곱셈뿐만 아니라 행렬 요소 간의 곱셈도 가능하다. 행렬 요소 간 곱셈을 행하는 연산자는 (.*)이고 이 연산자 앞뒤에 오는 피연산자들의 차원은 같아야 한다.


>> G.*H
1 2 3 4
10 12 14 16
27 30 33 36


행렬 간의 나눗셈은 무슨 의미 일까? 예를 들어서


>> A=[1 2;3 4]
A =
1 2
3 4

>> B=[5 6;7 8]
B =
5 6
7 8



와 같이 정의된 정방행렬 A와 B에 대해서 A/B 또는 B\A는 무슨 의미일까? 결과를 확인해 보자.


>> A/B
3.0000 -2.0000
2.0000 -1.0000
>> B\A
5.0000 4.0000
-4.0000 -3.0000


스칼라의 경우를 생각해 보자. 4/3은 4에게 3의 역수를 곱하는 계산 즉, 4x3-1이다. 마찬가지로 3\4은 3의 역수를 4에 곱하는 것(3-1x4)이다. 행렬의 경우도 마찬가지이다. A/B는 행렬 A에 B의 역행렬을 곱하는 것이고, B\A는 B의 역행렬에 A행렬을 곱하는 것이다. 두 결과가 같다고 생각하기 쉽지만  '행렬에서는 교환법칙이 성립하지 않는다'는 것에 유의해야 한다. 위의 결과를 보아도 서로 다르다는 것을 알 수 있다. 즉 A/B와 B\A는 A와 B가 스칼라라면 같은 수이지만 행렬이라면 서로 다른 행렬이 된다.


 MATLAB에서 역행렬을 구하는 함수는 inv()이다. (inverse 의 줄임말을 함수명으로 채용)


>> A*inv(B)
3.0000 -2.0000
2.0000 -1.0000

>> inv(B)*A
5.0000 4.0000
-4.0000 -3.0000


위의 결과와 이전의 그것과 같다는 것을 알 수 있다. 여기서는 정방행렬의 경우만 다루고 있는데 정방행렬이 아닌 행렬의 가역행렬(pseudo-inverse matrix)를 구하는 함수로 pinv()가 있다. 이에 대해서는 다음에 다루도록 한다.


 나눗셈의 경우도 행렬 요소간 나눗셈이 가능하다. 연산자(./)와 (.\)가 바로 그러한 역할을 한다.


>> A./B 󰎠
0.2000 0.3333
0.4286 0.5000

>> B.\A 󰎠
0.2000 0.3333
0.4286 0.5000


요소 간 연산인 경우에는 항상 두피연산자의 차수가 같아야 한다. 위의 결과를 보면 A./B와 B.\A의 계산결과는 같다는 것을 알 수 있다.(왜일까?)


 행렬의 거듭제곱을 구하는 데는 (^)연산자가 사용되며 행렬의 요소 각각의 거듭제곱을 구하는 데는 (.^)연산자가 사용된다.


>> A^2
7 10
15 22

>> A.^2
1 4
9 16

>> A.^-1
1.0000 0.5000
0.3333 0.2500

>> 2.^A
2 4
8 16

>> A.^B
1 64
2187 65536


이 예에서 A^2과 A.^2 그리고 2.^A의 차이를 확실히 구별해야 한다. 곱셈(*)과 나눗셈(/혹은\) 그리고 거듭제곱(^)을 수행하는 연산자 앞에 ‘점(.)이 붙으면 요소간 연산’이라는 사실을 기억해야 한다.



Posted by 살레시오

 MATLAB은 극소값이나 무한대 값, π 등을 표현하는 상수들이 있으며, 이러한 특수한 값을 표현하는 변수들을 예약어(keyword)dl므로 사용자 변수로 이용하지 않아야 한다.


[표 1] MATLAB 상수들

상수

의미

i 혹은 j

허수

e

자연 상수 (exponential constant)

pi

원주율 π

inf / Inf

무한대 (0이 아닌 수를 0으로 나눌 때 발생)

nan / NaN

Not a Number (0을 0으로 나눌 때 발생)

realmax

realmin

표현할수 있는 가장 작은 실수 값

표현할수 있는 가장 큰 실수 값

eps

이 eps에 설정되어 있는 수 보다 작은 수를 0으로 간주함 (기본값은 2.2204x10-16)

ans

이전에 계산한 결과값들 중 변수에 저장되지 않은 값

computer

현재 구동 시스템의 종류를 출력

version

MATLAB의 버전을 출력


 원주율이나 자연상수 값을 확인하고 싶으면 명령어창에서 입력하면 알 수 있다.


>> format long

>> e
ans =  2.71828182845905

>> pi
ans =  3.14159265358979

>> realmin
ans =   2.22507385850720e-308

>> realmax
ans =   1.79769313486232e+308


 내부 변수 ans는 이전 단계에 계산한 결과값들 중 변수에 저장되지 않은 값을 가지고 있다.


>> [1 2; 3i 4+5j] % 변수에 저장하지 않았다.
1.0000 2.0000
0 + 3.0000i 4.0000 + 5.0000i
>> ans 󰎠
1.0000 2.0000
0 + 3.0000i 4.0000 + 5.0000i


명령어 computer는  현재 컴퓨터의 종류를 반환한다.


>> computer 󰎠
PCWIN


그리고 ver  현재 MATLAB의 버전을 반환한다.


>> ver
5.0.020613




Posted by 살레시오

 MATLAB에서 행렬의 원소로 문자열을 사용하는 것이 가능하다. 문자열은 작은 따옴표나 큰따옴표로 묶는다.


>> A=['hi']
A = hi
>> B="there"
B = there


두 번째 예를 보면 문자열은 그 자체로 행벡터임을 알 수 있다.. 벡터의 각 요소는 하나의 문자인 것이다. 따라서 행렬의 인덱싱도 가능하다.


>> size(B)
ans =
  1   5

>> B(3)
ans = e

>> B(1)="T"
B = There


따라서 다음과 같이 두 행렬을 한 행렬로 표현함으로써 문자열의 합성도 가능하다.


>> C=[A B]
C = hiThere


문자열 행렬도 생성 가능한데 문자열 자체가 행벡터이므로 한 행에 하나의 문자열을 지정해 주면 된다.


>> D=['hi';'there']
D =
hi
there

>> size(D)
ans =
  2   5


위의 예에서 행렬 D는 첫 번째 행의 크기는 2(문자)이고 두번째 행의 크기는 5(문자)인데 행렬이 구성되었다. 이경우 빈 곳은 공백문자로 채워진다.


 문자열 관련 함수들은 다음과 같다.


[표 1] 문자열 관련 함수들

함수

기능

strcat(s1, s2, …)

strvcat(s1,s2,...)

문자열들을 하나의 행벡터로 합친다.

문자열들을 한 행렬로 합친다.(각 문자열을 별도의 행으로 지정)

char(x)

숫자(아스키코드) 행렬로 부터 문자열을 생성한다.

ischar(x)

x가 문자열이면 논리1(true)반

num2str(x)

숫자를 문자열로 바꾼다.

sprintf(FORMAT, A,B,...)

C 언어의 printf() 와 같은 기능을 수해하여 문자열 생성

lower(s)

upper(s)

문자열을 소문자로 변환

문자열을 대문자로 변환

strcmp(s1,s2)

s1과 s2가 같다면 논리1(true)반환, 그렇지 않다면 논리0(flase)반환

findstr(s1,s2)

둘 중 긴 문자열에서 짧은 문자열이 시작되는 인덱스 반환



Posted by 살레시오

 본 포스트에서는 각종 특수 행렬을 MATLAB 내부 함수를 이용하여 생성하는 방법을 알아본다. 앞으로 첨자로 쓰이는 m,n은 양의 정수를 표기한다. 이전에 소개되었던 특수한 행렬을 생성하는 함수들은 다음 표에 정리하였다.


[표 1] 이전에 소개되었던 특수 행렬을 반환하는 함수들 요약

함수

기능

maginc(n)

nxn 크기의 매직 행렬(임의읭 행이나 열의 요소 합이 동일) 생성

rand(n)

rand(m,n)

randn(n)

randn(m,n)

nxn 크기의 난수 행렬 생성

mxn 크기의 난수 행렬 생성

nxn 크기의 정규 분포(normally distributed) 난수 행렬 생성

mxn 크기의 정규 분포(normally distributed) 난수 행렬 생성

pascal(n)

nxn 크기의 파스칼 행렬 생성


이것들 이외의 함수들에 대해서 살펴보도록 하겠다.

영행렬과 일행렬

 MATLAB에서 다음 함수들은 특수한 행렬을 만들어낸다.


[표 2] ones()와 zeros() 함수

함수

기능

ones(n)

ones(m,n)

ones(size(A))

nxn 크기의 ‘1’로 채워진 행렬 생성

mxn 크기의 ‘1’로 채워진 행렬 생성

A행렬의 크기와 같은 ‘1’로 채워진 행렬 생성

zeros(n)

zeros(m,n)

zeros(size(A))

nxn 크기의 ‘0’으로 채워진 행렬 생성

mxn 크기의 ‘0’으로 채워진 행렬 생성

A행렬의 크기와 같은 ‘0’으로 채워진 행렬 생성


예를 들면 다음과 같다.


>> A = ones(3,2)
A =
1 1
1 1
1 1
>> A = zeros(2,3)
A =
0 0 0
0 0 0


만약 다음과 같은 행렬 A를 만들고 싶다면

A=2*ones(2,3)이라고 명령을 내리면 된다.

항등행렬 (identity matrix)

 항등행렬은 eye(n) 함수로 만들 수 있다.


>> eye(5)
ans =
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1


만약 다음과 같은 행렬 A를 만들고 싶다면

A=-eye(3)이라고 명령을 내리면 된다.

대각행렬 (diagonal matrix)


[표 3] diag() 함수의 기능과 용례들

함수

기능

용례

diag(x)

x의 요소들을 주대각 요소로 하는 정방행렬 생성

diag([11,22])

diag(3:10)

diag(x,n)

x의 요소들을 부대각 요소로 하는 정방행렬 생성

(n==0일 때 주대각 요소)

diag([1 2 3],2)

diag(x, -1)

diag(A)

행렬 A의 주대각 요소를 뽑아 열벡터 생성

diag(magic(3))

diag(A,n)

행렬 A의 부대각 요소를 뽑아 열벡터 생성

(n==0일 때 주대각 요소)

diag(A, 2)

diag(A, -1)


 만약 x를 벡터라고 하면 명령문 diag(x)는 대각선상에 x를 갖는 대각행렬을 만든다.


>> x=[11 22 33]
x =
  11   22   33

>> diag(x)
ans =
  11    0    0
   0   22    0
   0    0   33


다른 예를 들어  diag(ones(1,n)) 명령은 아래와 같은 n☓n 항등행렬을 생성한다.


>> diag(ones(1,5))
ans =
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1

 만약 A가 정방행렬이면 diag(A)는 A의 대각선 원소들로 생성되는 벡터이고, diag(diag(A))는 diag(A)의 원소를 대각선상에 갖는 대각 행렬이다. 아래의 명령을 살펴보자.


>> A = [1 2 3; 4 5 6; 7 8 9];
>> diag(A)
ans =
1
5
9

>> diag(diag(A))
ans =
1 0 0
0 5 0
0 0 9


 다른 예를 더 살펴보자.


>> diag(1:5)
ans =
1 0 0 0 0
0 2 0 0 0
0 0 3 0 0
0 0 0 4 0
0 0 0 0 5

>> diag(0:4)
ans =
0 0 0 0 0
0 1 0 0 0
0 0 2 0 0
0 0 0 3 0
0 0 0 0 4


따라서 diag(1:5)-diag(0:4)는 다음과 같이 항등행렬이다.


>> diag(1:5)-diag(0:4)
ans =
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1


마찬가지로 diag(3:7)-diag(2:6)의 결과도 항등행렬이다.


 일반적으로 diag(x,n)은 x원소을 n번째 대각선에 위치시킨다. n이 0이면 주대각선을 n>0이면 그 위의 대각선, n<0이면 그 밑의 대각선을 지정한다. 그리고 diag()함수의 반환 행렬은 항상 정방행렬이다.


>> diag([11,22,33],1)
ans =
   0   11    0    0
   0    0   22    0
   0    0    0   33
   0    0    0    0

>> diag([11,22,33],-2)
ans =
   0    0    0    0    0
   0    0    0    0    0
  11    0    0    0    0
   0   22    0    0    0
   0    0   33    0    0


따라서 두 번째 n이 생략되면 기본값으로 0이 사용된다는 것을 알 수 있다.



Posted by 살레시오

 MATLAB에서 어떤 행렬의 크기를 구하고자할 때 사용하는 함수가 size()함수와 length()함수이다.


>> A=[1 2 3 4; 5 6 7 8]
A =
1 2 3 4
5 6 7 8
>> s=size(A)
s =
2 4

출력 파라메터가 하나일 때는 size()함수는 행수와 열수를 요소로 하는 행벡터를 반환한다. 출력 파라메터가 두 개일 때는 다음과 같이 첫 번째 파라메터에는 행을 두 번째 파라메터는 열수를 담아서 반환한다.


>> [row col]=size(A)
row = 2
col = 4


만약 두 개의 입력 파라메터가 주어진다면 행수 혹은 열수를 반환한다. 다음 예제를 보면 이를 알 수 있다.


>> r=size(A,1) % 행수를 반환
r =
2
>> r=size(A,2) %열수를 반환
r =
4


크기를 구하고자 하는 것이 벡터라면 length()함수를 이용하면 된다.



>> B=pi:0.01:2*pi;
>> length(B)
315
>> size(B)
1 315


이 예에서 벡터 B는 315의 크기를 가지는 행벡터임을 알 수 있다.만약 length()함수의 입력 파라메터로 행렬이 들어간다면 행수와 열수 중에서 큰 값이 반환된다.


>> A
1 2 3 4
5 6 7 8
>> length(A)
4


즉, length(A)함수는 max(size(A))명령과 동일한 일을 수행하게 된다.



Posted by 살레시오

 행렬의 원하는 부분을 치환하기 위해서는 치환하고자 하는 행렬의 원소에 값을 입력한다. 먼저 다음과 같이 행렬 A를 생성하자


>> A = [ 1 2 3 4 5;
6 7 8 9 10;
9 9 9 9 9;
0 0 0 0 0;
1 1 1 1 1];


이제 행렬 A에 대해서 다음 예제들과 같이 조작할 수 있다.


>> A(1,2) = 100 󰎠 % (1,2) 원소가 100이 된다.
A =
1 100 3 4 5
6 7 8 9 10
9 9 9 9 9
0 0 0 0 0
1 1 1 1 1
>> A(:,2) = [1 1 1 1 1]' 󰎠 % 2열의 원소들을 치환한다.
A =
1 1 3 4 5
6 1 8 9 10
9 1 9 9 9
0 1 0 0 0
1 1 1 1 1

>> A(1:4,2) = [2 2 2 2]' 󰎠 % 1행~4행의 2열 원소들을 2로 치환
A =
1 2 3 4 5
6 2 8 9 10
9 2 9 9 9
0 2 0 0 0
1 1 1 1 1

>> A(1,2) = 100 󰎠 % (1,2) 원소가 100이 된다.
A =
1 100 3 4 5
6 7 8 9 10
9 9 9 9 9
0 0 0 0 0
1 1 1 1 1
>> A(:,2) = [1 1 1 1 1]' 󰎠 % 2열의 원소들을 치환한다.
A =
1 1 3 4 5
6 1 8 9 10
9 1 9 9 9
0 1 0 0 0
1 1 1 1 1

>> A(1:4,2) = [2 2 2 2]' 󰎠 % 1행~4행의 2열 원소들을 2로 치환
A =
1 2 3 4 5
6 2 8 9 10
9 2 9 9 9
0 2 0 0 0
1 1 1 1 1


 아직 생성되지 않은 행렬의 특정한 요소에 값을 대입할 수 있다. 이때 지정되지 않은 원소는 모두 0 으로 출력된다. 예를 들어 아직 작업 공간에 D라는 변수가 없는 경우 다음과 같이 명령을 내리면,


>> D(3,3)=3 󰎠
D =
0 0 0
0 0 0
0 0 3


와 같이 D가 새로 생성되고 (3,3)자리에 3이 대입되며 지정되지 않은 다른 자리에는 0으로 채워진다. 만약 이 상태에서 다음과 같이 추가적으로 명령을 내리면


>> D(5,5)=5 󰎠
D =
0 0 0 0 0
0 0 0 0 0
0 0 3 0 0
0 0 0 0 0
0 0 0 0 5


지정되지 않은 위치의 요소들은 0으로 초기화되는 것을 알 수 있다.


 또 다른 예로서, C라는 행렬을 새로 생성시키는데, 두 번째 행을 [1 2 3]으로 하고 싶으면 다음과 같이 한다.


>> C(2,:)=[1 2 3] 󰎠
C =
0 0 0
1 2 3


이때 지정되지 않은 첫 번째 행의 값은 0으로 초기화됨을 알 수 있다. 만약 A라는 행렬이 3X3 크기의 행렬로 작업공간에 존재한다면


>> a=A(4,4) 󰎠
??? Index exceeds matrix dimensions.


는 보다시피 에러가 발생한다. 하지만 다음 명령어는 새로운 변수가 생성되는 것과 비슷한 규칙이 적용된다.


>> A(4,4)=10 󰎠
A =
1 2 3 0
4 5 6 0
7 8 9 0
0 0 0 10


즉, 지정된 위치를 만들어 값을 대입하고 값이 없는 위치에는 0을 대입한다.




Posted by 살레시오

 여기에서는 이전 포스트에 이어서 행렬의 인덱싱에 대해서 설명하겠다. 행렬의 인덱스에 콜론(:) 연산자를 이용하여 여러 개의 행이나 열을 동시에 선택할 수도 있다.


>> A(2, 1:3) % 2행의 1열에서 3열까지의 원소
4 5 6


위의 예에서 콜론 연산자가 단독으로 쓰이는 경우와는 다르다는 것을 알 수 있다. 여기에서 콜론 연산자는 이전 포스트에서 설명한 수열을 생성하는 연산자로서 행벡터를 생성한다. 즉 위의 명령은 다음과 완전히 동일하다.


>> A(2, [1 2 3])


다음 명령을 보자.


>> A(1:3, :) 󰎠 % 1행(전체)부터 3행(전체)까지
>> A([1 2 3], :) 󰎠


이 명령어의 행인덱스 1:3 와 열인덱스 : 에 똑같은 콜론(:)문자가 쓰였지만 전혀 다른 연산자이다. 앞에 콜론은 수열을 생성하는 연산자이고 뒤의 연산자는 인덱스로서 단독으로 쓰였기 때문에 ‘모두’의 의미를 갖는다. 즉, 둘 다 같은 명령이다.


 행렬의 마지막 요소를 지정하는 데에는 end연산자가 사용된다. 다음 예를 보자.


>> f=1:2:10 󰎠
f =
1 3 5 7 9
>> f(end)
9


위에서는 f벡터의 끝 요소 만을 참조하려면 f(5)라고 하면 되지 않겠느냐고 생각할 수도 있으나 end연산자는 참조하려는 행렬의 크기를 모르는 경우 제일 끝의 행(또는 열)만을 지정하고 싶을 때 유용하다. MATLAB 프로그래밍을 하다 보면 참조하려는 행렬의 크기가 불확실한 경우가 자주 발생하게 된다. 다음의 예제도 잘 살펴보기 바란다.


>> F=magic(5)
F =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9

>> F(end)
9

>> F(2:end, :)
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9

>> F(1:3, 3:end)
1 8 15
7 14 16
13 20 22


위에서 magic(n)함수는 (n은 홀수) nxn 차원의 정방 행렬을 만드는데 생성된 행렬은 특정한 행(또는 열)의 모든 요소의 합이 일정하다. 대각선 방향의 합도 역시 같다. (자세한 설명은 help magic 명령으로 살펴볼 수 있다.)


 만일 어떤 행렬에서 특정한 행 또는 열을 없애려면 다음과 같이 하면 된다.


>> A=magic(3)
A =
8 1 6
3 5 7
4 9 2

>> A(2,:)=[]
A =
8 1 6
4 9 2

>> A(:,3)=[]
A =
8 1
4 9


위에서 [ ] 명령은 공행렬(empty matrix)을 생성하는데 이는 크기가 0인 행렬을 뜻한다. 예를 들어 행렬 A에서 2행을 없앤 행렬을 B에 대입하려면 다음과 같이 하면 될 것이다.


>> A=pascal(3) 󰎠
A =
1 1 1
1 2 3
1 3 6

>> B=A([1 3],:) 󰎠
B =
1 1 1
1 3 6


공행렬과 영행렬(zero matrix)은 구별해야 하는데 공행렬은 크기가 0인 행렬을 의미하며 MATLAB에서는 ‘[]’로 생성한다. 영행렬은 행렬의 모든 요소가 0인 행렬을 의미하며 zeros()함수를 이용하면 생성할 수 있다.


 find(X)함수는 입력행렬 X의 요소 중 0이 아닌 것의 인덱스를 반환한다. 즉, 행렬의 0이 아닌 요소의 인덱스를 찾는 함수가 find()함수이다. (help find󰎠명령으로 확인해 보라.) 이 함수의 반환값은 하나, 둘 그리고 세 개가 될 수 있다.


>> X=[0 1 3; 3 0 4; 0 5 0]
X =
0 1 3
3 0 4
0 5 0

>> m=find(X)
m =
2
4
6
7
8


위의 결과를 이해하려면 MATLAB에서 이차원 행렬의 요소들은 내부적으로 일차원 배열로 저장됨을 이해해야 한다. 그 일차원 배열의 0이 아닌 요소의 인덱스를 find()함수가 만약 출력변수가 한 개라면 반환하는 것이다. 위의 경우 행렬 X의 내부 인덱스를 도시하면 다음 그림과 같다.


[그림 2] X행렬의 내부 요소 인덱스


이 그림을 보면 앞의 예제에서 find()함수의 결과값이 이해가 갈 것이다.




Posted by 살레시오

 MATLAB에서 벡터의 원소를 참조하거나 벡터의 원하는 위치에 값을 설정하려고 할때는 아래와 같이 한다.


>> b = a(k)
>> a(k) = b


위에서 첫 번째 명령은 a벡터의 k번째 요소를 변수b에 저장하라는 것이고 두 번째 명령은 b변수값을 a벡터의 k번째 자리에 저장하라는 것이다. 여기서 a벡터는 행벡터이든 열벡터이든 동일하게 적용된다. 아래의 예를 보자


>> a=[8:-2:2]’
a =
8
6
4
2

>> b=a(3)
b =
4

>> a(2)=0
a =
8
0
4
2


 행렬의 한 원소에 접근하여 원하는 위치에 값을 읽어오거나 바꿀려고 할 때는 아래와 같이 괄호 안에 행 수와 열 수를 콤마(,)로 구별하여 지정한다.


>> B = A(k1,k2)
>> A(k1,k2) = B


즉, 행렬 A의 k1행 k2열 원소를 참조하고자 할 때 A(k1,k2)로 입력한다.


>> A = [ 1 2 3; 4 5 6; 7 8 9 ]
A =
1 2 3
4 5 6
7 8 9
>> A(1,2) 󰎠 % 1행 2열 원소
2
>> A(1,3) 󰎠 % 1행 3열 원소
3
>> A(3,3) 󰎠 % 3행 3열 원소
9


만약 어떤 행이나 어떤 열의 모든 원소를 선택하고자 하면, 선택하고자 하는 해당 열이나 행을 지정할 때 콜론(:)을 단독으로 사용한다. 행렬의 지정자로 콜론(:)이 단독으로 쓰이면 ‘전부(all)’라는 의미를 갖는다. 다음 예를 보자.


>> A(1,:) 󰎠 % 1행의 모든 원소
1 2 3

>> A(:,3) 󰎠 % 3열의 모든 원소
ans =
3
6
9


여기서 A(1,:)는 ‘1행, 전체’를 가리키고 A(:,3)은 ‘3열,전체’를 가리킨다.


행이나 열의 특정한 부분만 선택하고자 하면 선택하고자 하는 해당 열이나 행를 벡터로 지정해주면 된다. 예를 들어


>> A([1 3], :) %1행과 3행만 선택
1 2 3
7 8 9
>> A(:, [2 3]) %2열과 3열만 선텍
2 3
5 6
8 9
>> A([1 3], [2 3])
2 3
8 9


위에서 마지막 예제의 결과는 다음 그림을 보면 쉽게 이해할 수 있다.


[그림 1] 선이 겹치는 부분이 선택된다.

A행렬에서 지정한 행과 열이 겹치는 곳에 위치한 요소만 선택이 되어진다는 것을 [그림 1]을 보면 쉽게 이해할 수 있다. 즉 [그림 1]에서 1행과 3행에 가로선을 그리고 2열과 3열에 가로선을 그어보면 선들이 겹치는 부분만 선택되는 것이다.


 A([1 3], :) 명령어를 읽을 때 ‘A행렬의 1행 전체, 3행 전체’라고 읽으면 정확하고 결과값도 1행 밑에 3행이 위치한다. 그런데 다음 예제롤 하나 더 보고 넘어가자.


>> A([3 1], :) %3행과 1행만 선택
7 8 9
1 2 3
>> A(:, [3 2]) %3열과 2열만 선텍
3 2
6 5
7 8


A([3 1], :)명령어와 그 결과를 보면 ‘3행 먼저, 그 다음 1행’순으로 인덱스 벡터에 써준 순서대로 요소를 뽑아낸다는 것을 알 수 있다. A(:, [3 2])도 마찬가지로 ‘3열 먼저. 그 옆에 2열’이라는 것을 알 수 있다.




Posted by 살레시오

 열벡터란 세로로 세워져 있는 모양의 벡터고, 행벡터는 가로로 길쭉한 벡터이다. 보통 그냥 벡터라고 하면 열벡터를 의미한다. 여기에서도 앞으로 열벡터는 그냥 벡터라고 지칭한다.


nx1 (열)벡터

1xn 행벡터


MATLAB 명령어창에서 nx1 행렬을 입력하면 열벡터를, 1,n 행렬을 입력하면 행벡터를 만들 수 있다.


>> a=[1 2 3 4] 󰎠
a =
1 2 3 4

>> a=[1;2;3;4] 󰎠
a =
1
2
3
4

>> a=[1 2 3 4]‘ #행벡터의 전치는 열벡터가 된다.
a =
1
2
3
4


행벡터 혹은 열벡터를 입력하거나, 생성시켜야 하는 경우에 각 벡터 요소들의 증가 혹은 감소분이 일정하다면, 각 요소들을 다 입력할 필요 없이 초기값, 최종값, 증감값으로 생성시킬 수 있다. 여기에서 사용되는 것이 콜론(:)연산자이다. 이 연산자는 여러모로 쓸모가 많으므로 잘 숙지해 두어야 한다. 입력형식은 아래와 같다.


>> 변수명 = 초기값:증감값:최종값


이 명령은 초기값으로부터 최종값까지 증감값만큼 증감시킨 수열을 요소로 갖는 행벡터를 생성하여 변수에 저장하게 된다. (행벡터를 생성한다는데 주의하자!) 예를 들어, 변수이름 a로 1부터 10까지 1의 간격으로 행벡터를 만들고자 한다면 다음과 같이 입력하여 실행한다.


>> a=1:1:10
a =
   1    2    3    4    5    6    7    8    9   10


증가분이 1이라면 증감값을 생략할 수 있다. 즉 위의 명령은 다음과 같다.


>> a=1:10
a =
   1    2    3    4    5    6    7    8    9   10


즉, 증감값이 생략된 다음과 같은 형태라면


>> 변수명 = 초기값:최종값


증감값은 1이라는 것을 의미하며 초기값부터 최종값까지 1씩 증가시켜서 행벡터를 만든다.


 만약 8부터 2까지 2씩 감소하는 간격으로 열벡터를 만들고자 한다면 다음과 같이 입력하여 실행한다.


>> a=[8:-2:2]' % 또는 a=(8:-2:2)'
a =
8
6
4
2

전술한 바와 같이 콜론 연산자를 사용하면 기본적으로 행벡터가 생성되므로 열벡터를 얻기 위해서는 ‘전체’ 벡터의 전치를 취해야 한다. 다음과 같이 입력하면 어떻게 되는지 한번 수행해 보자.


>> a=8:-2:2'
a =
  8   6   4   2


여기에서 2’은 2와 같다. MATLAB에서 전치 연산자(‘)와 콜론(:) 연산자 중에서 전치 연산자의 우선 순위가 더 높으므로 위 명령은 a=8:-2:2 와 동일한 동작을 수행한다.




Posted by 살레시오