여기에서는 이전 포스트에 이어서 기본적인 행렬 생성의 기본적인 내용을 설명하겠다. 행렬 X가 다음과 같이 복소행렬(행렬의 요소 중 하나 이상이 복소수인 행렬)이라고 하자.

아래와 같이 입력하면 화면에 행렬 X가 나타난다. j 대신 i가 쓰일 수도 있다.


>> X=[1 j;-5j 2]
X =
  1 + 0i   0 + 1i
 -0 - 5i   2 + 0i


위와 같이 MATLAB에서 허수를 나타내기 위해서 ‘i’ 혹은 ‘j'를 사용한다. 그러므로 변수 이름으로 ‘i’와 ‘j'를 사용하지 않아야 한다.


>> i
0.0000 + 1.0000i
>> a = 2 + 3i
a =
2.0000 + 3.0000i


수식 입력의 편의를 위해서 복소수를 입력할 때에는 위에서와 같이 ‘3i’를 입력해도 가능하다. 그러나 i 가 허수단위가 아닐 때에는 불가능하며 앞에서도 설명한 바 있듯이 'i3'으로 입력하면 안된다는 것이 유의하자. i3은 변수명으로 해석하기 때문이다.

 만약 ‘i’를 행렬 이름으로 (즉, 변수로) 사용했을 때는 그 행렬이 존재하는 한 ‘i’는 행렬 이름이며 허수가 아니다.


>> i = [1 2 3] 󰎠
i =
1 2 3
>> a = 10 + i 󰎠
a =
11 12 13


‘i’를 다음과 같이 지우면 다시 허수로 사용할 수 있다.


>> clear i 󰎠
>> i 󰎠
0.0000 + 1.0000i


여기서 clear 명령어는 그 뒤에 오는 변수를 메모리에서 지우는 일을 수행한다. 만약  ‘i’가 행렬 변수로 사용되고 있을 때는 ‘sqrt(-1)’을 이용하여 허수를 만들 수 있다.


>> i = [1 2 3]
i =
1 2 3

>> i
1 2 3

>> a = [1+i 1-i] % 'i'는 행렬로 인식된다.
a =
2 3 4 0 -1 -2

>> a = [1+sqrt(-1) 1-sqrt(-1)]
a =
1.0000 + 1.0000i 1.0000 - 1.0000i


하지만 ‘i’ 나 ‘j’는 MATLAB에서는 일종의 예약어(keyword)이므로 변수명으로 사용하는 것은 피하는 것이 바람직하다.


 MATLAB에서 복소수를 취급하는 기본적인 함수들은 다음 표와 같다.


[표 1] 복소수 관련 내장 함수들

함수명

기능

실행 예

(a=3+4j 일 경우)

결과

real()

복소수의 실수부를 구한다

real(a)

3

imag()

복소수의 허수부를 구한다

imag(a)

4

abs()

복소수의 크기를 구한다

abs(a)

5

angle()

복소수의 각(라디안)을 구한다

angle(a)

0.9273

conj()

켤레복수소를 구한다

conj(a)

3-i4


 만약 각도의 결과를 라디안에서 도(degree)로 바꾸고 싶다면 angle()함수의 결과값에 360/2π 를 곱하면 된다.


>> angle(3+4i)
ans =
0.9273
>> ans*360/(2*pi)
ans =
53.1301


 복소행렬의 전치를 구할 때는 약간의 주의가 필요하다. 복소전치행렬(complex conjugate transpose)을 구할 수도 있고 그냥 전치행렬을 구할 수도 있다. 복소전치행렬은 각 행렬 요소들의 공액 복소수(complex conjugate, 허수부의 부호만 바뀐 복소수)를 구한 다음 전치를 하는 것이다. 이전 포스트에서 설명한 (‘)연산자가 실은 복소전치행렬을 구하는 연산자이다. 다음 예에서 이것을 확인할 수 있다.


>> X=[1 j;-5j 2]
X =
  1 + 0i   0 + 1i
 -0 - 5i   2 + 0i

>> Y=X'
Y =
  1 - 0i  -0 + 5i
  0 - 1i   2 - 0i


이와 다르게 행렬의 복소수 요소의 공액복소수를 취하지 않고 단순히 비대각요소의 위치만 전치하고 싶다면 (.‘)연산자를 사용한다.


>> Z=X.'
Z =
  1 + 0i  -0 - 5i
  0 + 1i   2 + 0i


 두  전치연산자 (‘)와 (.’)의 차이에 주의해야 한다.



Posted by 살레시오
,

 여기에서는 이전 포스트에 이어서 기본적인 행렬 생성의 기본적인 내용을 설명하겠다.

함수의 행렬

 행렬을 입력하는 또 다른 예로, 아래와 같이 주어진 행렬 C를 생각해보자.

위 행렬은 다음과 같이 입력될 수 있다.


>> C = [1 exp(-0.02); sqrt(2) 3]; 󰎠
>> C 󰎠
C =
1.0000 0.9802
1.4142 3.0000


여기서 exp(x)함수는 ex 값(exponetial)을 구하는 함수이고, sqrt(x)함수는 제곱근(square root)을 구하는 함수이다. exp(x)함수나 sqrt(x)함수의 용법이 궁금하다면 help 명령어를 사용하면 된다. help exp 명령을 내리면 exp()함수에 대한 기본 설명, 유사한 함수들 그리고 오버로드(overload)된 함수들에 대한 설명이 나오는 것을 알 수 있다. 유사한 함수들의 목록에 expm()함수가 있는데 함수명 끝의 m은 이 함수가 행렬연산을 한다는 것을 나타내며 스칼라 연산 함수들은 보통 대응하는 행렬 연산 함수를 가지고 있다.


※ 스칼라 연산이란 예를 들어 A=[1 2; 3 4]이고 exp(A)를 수행하면 결과값이 [exp(1) exp(2); exp(3) exp(4)]와 같이 행렬 각 요소에다가 함수값을 취하는 겻을 의미한다. 이와 달리 행렬 연산 함수 expm(A)는 다음과 같은 Taylor급수 정의식에 의한 결과값을 계산하게 된다.


[그림 1] Octave 4.0에서 help exp 명령을 수행한 결과


전치 행렬 (transpose)

 어떤 행렬의 전치행렬(transpose)을 만드는 방법은 행렬의 끝에 작은따옴표 (‘)를 붙이는 것이다. 예를 들어서 C행렬의 전치행렬을 만들어 D에 입력하고 싶다면 다음과 같이 한다.


>> D=C'
D =
1.0000 1.4142
0.9802 3.0000


어떤 행렬의 대각 요소(diagonal element)란 행 인덱스와 열 인덱스가 같은 요소를 그리고 비대각요소(off-diagonal element)는 같지 않은 요소를 의미한다. 위의 예에서 행렬 C의 비대각요소의 위치가 대칭적으로 바뀌어서 D에 저장되었음을 알 수 있다.

 또는 행렬을 입력할 때 마지막에 (‘)을 추가하면 입력되는 행렬의 전치행렬이 바로 구해진다.


>> D=[1 exp(-0.02); sqrt(2) 3]'
D =
1.0000 1.4142
0.9802 3.0000


이와 같이 전치 행렬은 행렬의 끝에 작은 따옴표로 쉽게 구해진다.



Posted by 살레시오
,

 MATLAB은 수치해석(numerical analysis)을 수행하는 대표적인 프로그램이다. 원래 MATLAB은 Cleve Moler에 의해 처음에는 Fortran으로 작성되어 DOS상에서 구동 가능한 소규모 수치해석 프로그램으로 출발하였으나, 현재는 미국의 MathWorks사에 의해 java virtual machine 위에서 구동되는 (따라서 대부분의 OS를 지원한다.) 대규모 패키지 프로그램으로 발전하였다.



 MATLAB은 수치 해석에 특화된 언어 문법을 가지고 있으며 친숙한 수학적인 기호와 간단한 문법으로 복잡한 계산을 수행할 수 있다. 전형적인 이용 범위는 다음과 같다.

  • 수학과 관련된 계산

  • 알고리즘 개발

  • 상황 모델링과 data분석

  • 여러 가지 과학과 공학적인 그래픽적 표현

  • GUI(Graphical User Interface)에 의한 에플리케이션 개발

 현재 MATLAB은 학계나 연구소등에서 광범위하게 사용되고 있으며 사실상 수치해석툴의 표준으로 자리잡고 있다. 이 프로그램은 범용으로 사용되는 프로그램언어인 C나 C++과는 달리 전문적으로 수치 계산을 하기 위한 프로그램이다.


 간단한 예로 행렬의 곱셈을 들어 보자. 두 개의 행렬을 곱셈하는 프로그램을 C언어로 작성하려고 한다면 2차원 배열을 두 개 잡아서 두 행렬을 각각 저장한 후 반복문 (for 나 while 같은 반복문 명령)을 중첩해서 사용해야 계산 결과를 얻어낼 수 있다. 계산결과를 화면에 출력하거나 파일로 저장하는 추가적인 루틴도 작성해야 한다.



하지만 MATLAB에서는 간단하게 한 줄의 명령으로 이를 수행할 수 있다.



또한 미분방정식의 해나 적분등도 쉽게 계산할 수 있으며 그 결과를 그래픽으로 보여주는 기능 또한 다양하다. 이러한 수학 계산들을 C 혹은 C++이나 다른 범용 프로그래밍 언어로 구현하려고 한다면 고려해야할 사항이 한두 가지가 아닐 것이다.


 이처럼 MATLAB은 강력한 수학적인 능력을 갖고 있고 다양한 분야에 특화된 여러 toolbox(일종의 라이브러리임)를 갖추고 있으며 simulink라는 비쥬얼 모의 실험 환경과 같은 특수한 툴들을 갖추고 있다. 이러한 장점들에 의해서 수치 해석 툴의 강자로 자리매김하고 있다.



Posted by 살레시오
,

 수치 해석(numerical analysis)분야에서 독보적인 위치를 차지하고 있는 툴은 단연 MATLAB이다. 수치 해석에 특화된 독자적인 스크립트 언어를 가지고 있고 (문법 구조가 robust하지 않다는 평이 있긴 하지만) 다양한 분야에 적용가능한 toolbox와 폭넓은 이용자층, 개발사의 적극적 지원 등 장점이 많은 툴이다. java로 개발되어서 실행하려면 jvm을 먼저 설치해야 한다. (물론 jvm의 성능이 비약적으로 향상되었긴 하지만 속도면에서 불리한 면이 있지 않을까하는 짐작이 든다.)



 단점은 역시 꽤 고가의 툴이라는 점이며 이 점때문에 학부생들이나 가볍게 배워보려는 이들에게는 실습 도구로 사용하기에 적합하지 않다. 개발사인 mathwork사에서 라이센스를 꽤 엄격하게 관리하고 있기도 하다. (라즈베리파이에는 무료로 제공된다는 얘기도 있는데 아직 확인을 못 해 봤다. 그리고 그 사양 위에서 matlab이 원활하게 실행될 것 같지도 않다.) 국내에서 출판된 공학 수학 교재들 중에 MATLAB을 보조적으로 사용하는 것들이 있는데 이런 점에서 적절치 않다고 생각한다.


 다른 대안이 없는 것은 아니다.일단 Octave라는 걸출한 오픈 소스 프로그램이 있는데 Matlab과의 문법 호환성이 거의 100%라서 기본적인 코드는 거의 변환 없이 실행이 가능할 정도이므로 학부생들의 기초 교육은 이것을 사용하면 된다. 그동안 gui 환경이 갖춰지지 않아서 불편했는데 (베타 버전이긴 하지만) 최근에는 gui환경도 지원하기 시작해서 더욱 고무적이다.


 그 외에도 scilab이 있는데 scilab은 유럽 등지에서는 꽤 유명하고 널리 쓰이는 수치해석 툴로써 무료로 사용할 수 있는 프리웨어이다. 하지만 개인적으로는 matlab과는 많이 동떨어진 문법을 가지고 있고 익히기도 꽤 어려웠다는  경험이 있다. 그리고 freemat 이라는 것도 있는데 matlab과 100%호환되는 툴을 지향하고 개발되기 시작했으나 2013년 이후로 개발이 중지된 것 같다. 최근에는 python+numpy 라는 (역시 오픈소스) 떠오르는 방법도 있다. (필자는 이것을 가장 추천하는 편이다.)


 모든 개발 환경이 클라우드로 옮겨가고 있는 추세이다. matlab은 아니지만 가장 간편하게 (무료로) matlab 코드를 실행시킬 수 있는 방법은 온라인 옥타브이다. 접속하면 바로 코딩이 가능하고 그 결과를 즉시로 확인해 볼 수 있다.



위 그림에서와 같이 plot()명령의 결과도 바로 확인할 수 있다. 단, scrip파일을 작성하려면 로그인을 해야 한다.


mathclouds 라는 사이트도 있다. 여기에서도 matlab 문법을 지원한다.


matlab 실습을 가장 간편하게 할 수 있는 방법은 이러한 서비스들을 사용하는 것이다.



Posted by 살레시오
,

 MATLAB에서 취급되는 모든 데이터형은 기본적으로 행렬(matrix)이다. 스칼라(scalar)값은 1☓1차원의 행렬이고 벡터는 n☓1차원의 행렬이다. 일반적으로 수학 교재에서 그냥 벡터라 하면 열벡터(column vector)를 의미하는 경우가 많다. 이 책에서도 앞으로 그냥 벡터라고 하면 열벡터를 의미하는 것으로 한다. 심지어 문자열도 그 문자 각각의 아스키(ASCII)코드값의 행렬(벡터)로 표시하며 다항식은 계수들의 행렬(벡터)로 표시한다. 함수에 넘겨주는 입력 파라메터도 행렬이고 함수의 수행 결과 생성되는 출력값도 역시 행렬이다. 앞으로 다음과 같이 구분하도록 하겠다. (m,n은 양의 정수)

       ① 스칼라 : 1x1차원의 행렬

       ② 벡터 : nx1차원의 행렬 (행벡터 : 1xn 차원 행렬)

       ③ 행렬 : mxn 차원의 행렬

 이제 행렬을 저장하는 변수를 만드는 기본적인 방법을 설명한다. MATLAB에 행렬을 입력하는 방법의 하나는 원소들을 대괄호 안에 입력하는 것으로 각 원소들은 공란 또는 콤마로 분리되어야 한다. 예를 들어 다음과 같은 행렬은

아래와 같이 한 줄에 입력할 수 있다.


>> A = [1.2 10 15; 3 5.5 2; 4 6.8 7] 󰎠
A =
1.2000 10.0000 15.0000
3.0000 5.5000 2.0000
4.0000 6.8000 7.0000


위에서 보듯 행렬의 원소들을 대괄호 안에 입력해야한다. 모든 행의 원소들은 공란 또는 ‘,’로 분리되어야 하며, 마지막 행을 제외한 각 행의 끝은 세미콜론으로 구분한다.


 크기가 큰 행렬은 몇 개의 입력 줄로 펼쳐서 나타낼 수 있다. 예를 들어 다음과 같은 행렬 B를 생각해보자.

이 행렬은 다음과 같은 네 줄로 나눠서 입력할 수 있다.

>> B = [1.5630 2.4572 3.1113 4.1051;
3.2311 1.0000 2.5000 3.2601;
1.0000 2.0000 0.6667 0.0555;
0.2345 0.9090 1.0000 0.3333];


여기서 ‘]’뒤에 세미콜론 ‘;’를 사용하였는데 끝에 세미콜론을 할 경우 처리 결과를 출력하지 않는다. 또한 각행의 마지막에 세미콜론 ‘;’을 사용하였는데, 이것을 생략하여도 같은 행렬로 입력된다.

※ 다른 언어(C/C++/JAVA/C# 등등)와 달리 MATLAB에서는 하나의 명령어 끝에 반드시 세미콜론 ‘;’을 붙여야 하는 것은 아니다. MATLAB의 명령 줄의 끝에 세미콜론 ‘;’ 을 붙이면 명령을 수행한 결과 값을 화면에 표시하지 않으며 세미콜론을 붙이지 않으면 명령을 수행한 결과 값을 화면에 표시한다. 명령어들 간에 구분을 하기 위해서는 콤마‘,’를 사용하며 세미콜론으로도 명령어들을 구분하나 바로 앞의 명령어의 출력을 억제한다. 다음 예를 보자.

>> a=1, b=2; c=3 󰎠
a =
1
c =
3


 이미 만들어진 행렬을 이용하여 새로운 행렬을 만들 수도 있다.


>> A1=[A; 11 22 33]
A1 =
   1.2000   10.0000   15.0000
   3.0000    5.5000    2.0000
   4.0000    6.8000    7.0000
  11.0000   22.0000   33.0000


이 예에서는 이미 만들어진 행렬 A를 이용하여 A행 밑에 한 행을 추가하여 새로운 행렬 A1을 생성하였다.


[그림 1]  행렬 A1의 구조


새로운 열을 A행렬 오른편에 추가하고 싶다면 다음과 같이 하면 된다.


>> B=[0.5; 2; 100] 󰎠
B =
0.5000
2.0000
100.0000
>> A2=[A B] 󰎠
A2 =
1.2000 10.0000 15.0000 0.5000
3.0000 5.5000 2.0000 2.0000
4.0000 6.8000 7.0000 100.0000


또는 다음과 같이 한 번에 같은 일을 수행할 수도 있다.


>> A2 = [A [0.5; 2; 100] ]
A2 =
1.2000 10.0000 15.0000 0.5000
3.0000 5.5000 2.0000 2.0000
4.0000 6.8000 7.0000 100.0000


 다른 예로 A행렬을 두 번 이용하여 다음과 같이 새로운 AA라는 행렬을 만들 수도 있다.

>> AA=[A A]
AA =
   1.2000   10.0000   15.0000    1.2000   10.0000   15.0000
   3.0000    5.5000    2.0000    3.0000    5.5000    2.0000
   4.0000    6.8000    7.0000    4.0000    6.8000    7.0000

 

위에서 행렬 A를 옆으로 나란히 붙어서 새로운 행렬 AA를 만들었다. 또는


>> AA2=[A; A]
AA2 =
   1.2000   10.0000   15.0000
   3.0000    5.5000    2.0000
   4.0000    6.8000    7.0000
   1.2000   10.0000   15.0000
   3.0000    5.5000    2.0000
   4.0000    6.800      7.0000


위에서는 행렬 A를 밑으로 나란히 붙어서 새로운 행렬 AA2를 만들었다. 위와 같이 기존에 생성된 행렬들을 합성하여 새로운 행렬을 만들 때는 그 행렬들의 차원에 주의해야 한다. 다음의 예를 보자.


>> A=[1 2; 3 4] 󰎠
A =
1 2
3 4
>> B=[5 6 7;8 9 10; 10 11 12] 󰎠
B =
5 6 7
8 9 10
10 11 12
>> AB=[A B] 󰎠
오류 내용 : 행렬에서 dimension이나 type이 일치하지 않습니다.
>> AB_=[A; B] 󰎠
오류 내용 : 행렬에서 dimension이나 type이 일치하지 않습니다.

 

두 행렬을 옆으로 연결할 때는 행수가 같아야 하고 밑으로 붙일 때는 열수가 같아야 한다. 그렇지 않으면 위와 같이 오류가 발생한다.



Posted by 살레시오
,

  Matlab은 수치해석 분야에서 독보적인 응용프로그램이지만 고가의 상용프로그램이라 학생들이 사용하기에는 무리가 있다.  하지만 똑같은 문법을 가지고 프로그램을 개발할 수 있는 대안이 있으니 바로 GNU Octave 이다.


  GNU Octave 3.8버전에 GUI 가 포함되었다! 그 동안 외부 그룹에서 octave 의 GUI를 개발하다가 중지되고 했던 것들이 몇 가지 있었는데 쓸만한 게 없었다. (특히나 윈도 환경에서는 더욱 그랬다.) 그런데 퍼스트 그룹에서 이것을 지원하기 시작했다는 것이 고무적이다. 아직 불안정한 알파 버전이고 4.0에 정식 버전이 포함될거라고는 하지만 획기적인 도약인 것 같다.



현재(2015년 4월)에는 3.8.2가 최신 버전으로 포함된 GUI는 아직도 알파버전이다. 4.0부터는 정식으로 채용될 거라니 기대가 된다.


Posted by 살레시오
,