MATLAB 완벽가이드

MATLAB 완벽가이드

머리말

앞으로, 전개해 나갈 내용은 Matlab4.0 ∼ 5.1까지에 대한 내용인데, 주로 Matlab5.1에 기준을 두고 강의를 하려고 합니다. 그러나, 대부분의 학생들이 Matlab4.2c이하 버전을 가지고 있는 경우를 고려하여, 내용 전개 중에 버전사이의 차이가 있는 경우 이점을 밝힐 것입니다. 이 내용의 대상은 대학생은 물론, 고등학생도 쉽게 배울 수 있고, 이해할 수 있는 내용입니다.

앞으로, 매일 A4용지 5장 정도로 해서 Matlab의 기본을 습득하기에 충분한 내용을 전개해 나갈 것입니다. 또한, 조만간 출판사와 협약을 하여 □Matlab 완벽 가이드□라는 제목으로 책도 출간할 계획입니다.

기호 표시와 뜻
	중요사항		메모
	주의사항		새로운 기능
	알리는 글

왜 Matlab을 배워야 하는가?

만일, 여러분에게 고등학교 수학 책에 나오는 정적분 문제, 즉,

[eqn: y=int_0^pi sin(x)dx]    ..............................(1.1식)

을 계산하는 프로그램을 작성하라는 과제가 주어 졌다면, 물론, 대부분의 학생은

현재 나와 있는 여러 수치 해석 책을 보고 쉽게 작성 할 수 있을 것입니다.

그러나, 만일,

[eqn: y=int sin(x)dx]    ..............................(1.2식)

(1.2식)과 같은 부정 적분을 계산하여 y=-cos(x)와 같은 결과가 나오고, 그 결과를 그림으로 나타내보라고 하면, 문제는 달라 질 것입니다. 설령, 할 수 있다고 하더라도 상당한 시간을 요할 것입니다. 그러나, Matlab에서는 (1.2식)과 같은 문제는 간단히 해결됩니다. 즉,

□y=int('sin(x)');

□ezplot(y);

라고 하면 되기 때문입니다. 이처럼 Matlab은 강력한 수학적인 능력을 갖고 있고, 또한, 쉽게 주어진 상황을 코딩화 할 수 있습니다.

그 동안, 여러분은 mathematica 또는 mathcad와 같은 여러 수학관련 도구(tool)를 들어 보았을 것입니다. 필자도, 처음에는 mathcad, mathematica를 다루어 보았지만 Matlab만큼 강력하지는 않았습니다.  지금 현재 서방 여러 나라에서도 모든 코딩이 거의 다 Matlab으로 방향을 전환하려는 추세인 것만 봐도 그 강력한 능력을 알 수 있을 것입니다.

Matlab은 무엇인가?

원래 Matlab은 Cleve Moler에 의해 Fortran으로 작성되었으나, 현재는 미국의 MathWorks사에 의해 C++로 작성되었습니다.

Matlab 코딩 체계는 우리에게 친숙한 수학적인 기호와 간단한 C문법으로 행해지는데, 전형적인 이용 범위는 다음과 같습니다.

수학과 관련된 계산

알고리즘 개발

상황 모델링과 data분석

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

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

Matlab의 기본 데이터 요소는 차원의 제한이 없는 array(배열)입니다. 즉, 기존의 High-level 언어에서는 행렬 연산의 경우, 연산에 대한 해당 함수를 만들어 주어야 했지만 Matlab에서는 기본 피 연산자가 array이므로 한번에 일괄적으로 계산할 수 있습니다.

	Matlab 4.2c까지는 array가 2차원적인 경우만 되었다. 그러나, Matlab5.0부터는 다차원 배열이 가능하다.

Matlab은 이용하고자 하는 분들의 전공에 도움을 주고자 toolbox를 가지고 있습니다. toolbox란 신호 처리, 통계학, 영상 처리, 제어, fuzzy logic, 재정, 화학 공정, 등등, 즉, toolbox란, 해당 전공 부분의 내용을 심도 있게 지원하는 함수들의 도서관과 같은 것입니다. 특별히, simulink라는 것이 있는데 이 디렉토리의 내용은 주로 동적 시스템의 simulation에 이용되는 부분입니다.

Matlab은 외부 프로그램, 즉, C, Fortran과 link해서 이용할 수 있는 기능도 제공하고 있습니다.

installation

Matlab은 PC뿐만 아니라, UNIX, MAC.에서도 사용 할 수 있으며 이용 방법은 거의 같다고 보아도 됩니다. 필자도 PC, UNIX를 번갈아 가며 Matlab을 이용하여 보았지만 거의 용법의 차이를 보지 못했습니다.

여기서는 window95에 기반을 둔 PC의 경우만 예를 들겠습니다.

기본 사양:

Intel 486 프로세서이상으로 math coprocessor를 포함한 것 이상 일 것.

→

486DX이상은 math coprocessor가 포함되어 있으므로 상관없지만, 만일, 독자가 GUI를 이용한 응용 프로그램을 작성하고자 원한다면 필자의 경험상 실행 속도 때문에 Pentium133이상은 되어야 한다고 봅니다.

RAM은 16MB이상은 되야 정상적으로 영상 처리등을 이용할 수 있습니다.

Help file에는 HTML문서와 .PDF문서가 있는데, .PDF 문서는 CD에 포함되어 있는 Adobe Acrobat Reader를 이용하거나, www.adobe.com에 접속하여 관련 정     보를 얻을 수 있습니다.

→

.PDF문서에는 Matlab에 관한 reference가 잘 정리되어 있으므로 꼭 한번 살펴보길 바랍니다.

installation :

Matlab CD는 CD-ROM에 넣으면 자동 실행되지만, 안 되는 경우, setup.exe icon을 double-click해도 됩니다.

installation이 실행되면 초기 화면이 다음과 같이 나올 것이다.

그림 1.1 matlab installation

software license에 동의한다고 하면 다음과 같은 [그림 1.2]가 나올 것이다.

여기서, install하고자 하는 버전을 선택하고, network에 연결해서 사용할 것인지를 결정한다. license번호를 정확히 기입한 후 next 버튼을 누르면 다음의 화면으로 들어간다.

그림 1-2. matlab installation

[그림 1.3]에서는 여러분이 install하고자 하는 Matlab성분을 선택해야 하는데, 필자가 추천 해주고 싶은 공통 부분은 Matlab, Matlab tour, simulink, symbolic math, statistical, signal processing, image processing, control이다. 이중에서 대부분의 학생들이 symbolic math를 안 설치하는데 그것은 상당히 잘못된 생각이다.

그림 1.3 Matlab installation

symbolic math란 일종의 변수 자체를 계산하는 것으로, 일종의 부정 적분과 같이 답이 변수로 나오게 하는 것이다. MathWorks사가 Maple사에 license를 주고 사온 maple 프로그램이 이곳에 설치되어 있으므로 만일, 독자중에서 Maple을 다루어 본 적이 있는 분에게는 상당히 유용한 toolbox가 될 것이다. 또한, statistical toolbox는 비록 통계학 전용 tool인 SAS에 비해서는 다소 기능이 떨어지지만, 본인도 수리 통계학을 공부 해본 결과, 아무런 불편 없이 자료를 분석할 수 있었습니다.

optimization toolbox는 비 선형 정합 문제를 다루는 것으로 toolbox중 ident. toolbox 다음으로 수학적인 지식을 많이 필요로 하는 toolbox이다.

여기서, Matlab toolbox는 따로 사는 것이라는데 주의하자!

Matlab toolbox는 해당 분야에 권위 있는 대학교수나 전문가를 초빙하여 알고리즘을 개발하여 만든 것으로, 각각의 해당 toolbox 매뉴얼을 보면 여러분은 전공도 배우고 시뮬레이션도 배우는 일석이조의 기쁨을 얻을 수 있다.

[그림 1.4]에서는 독자에게 MS word를 갖고 있는 경우, notebook을 설치할 것을 권하는 문장이 나온다.

그림 1.4 Matlab installation

Matlab은 여러분이 MS word를 이용하여 문서를 작성하는 경우, 문서 내에서 작성한 수식을 Matlab이 계산하여 그 결과를 MS word에 곧 바로 나타내주는 기능을 갖고 있다. 즉, Matlab 코딩체계를 MS word에서 하면, 그 결과가 MS word에 나온다는 것이다. 만일, notebook을 설치하면 MS word에 추가된 icon을 볼 수 있을 것이며, M-file이라는 새로운 text양식이 추가 된 것을 볼 수 있다. 그러나, 필자의 생각으로는 설치하지 않는 것을 권한다. 그 이유는 MS word로 문서를 작성하고, Matlab으로 계산하려면, 결국, word와 Matlab을 동시에 실행해야 하므로 자원의 낭비가 심하며, 무엇보다, debuging과정이 쉽지 않다.

→ UNIX, Window NT, MAC.에서도 installation이 어렵지는 않을 것이다.

	다음 이 시간의 강의 내용 : matlab으로 행렬을 다루는 전반적인 내용을 배우게 될 것이다.

다. 경로 설정 :

여러분이 Matlab을 성공리에 installation을 한 뒤, Matlab을 실행시키면 다음과 같은 화면이 나올 것이다.

그림1.5 Matlab 실행시의 화면

[그림1.5]에서 알 수 있듯이, Matlab이 실행되면 초기 작업 디렉토리가 □c:\Matlab\bin"으로 결정된다. 결국, 여러분이 앞으로 작성할 모든 Matlab파일은 전부 □c:\Matlab\bin"에 저장되므로 원래 □c:\Matlab\bin"에 있던 파일과 혼동을 할 우려가 있다. Matlab4.2c이하 버전에서는 □Matlabrc.m"이라는 파일이 있어서 이곳에 모든 Matlab경로와 환경을 사용자가 설정할 수 있도록 해주었다. 그러나, Matlab5.0이후 버전에서는 이와 같은 경로와 환경설정을 보다 간편히 할 수 있도록 새로운 □path browser"라는 tool을 제공해준다. 우선 □c:\Matlab\toolbox\local"디렉토리에 있는 "Matlabrc.m"이라는 파일을 열어서 맨 아래 부분을 보면, 다음과 같은 내용을 볼 수 있을 것이다.

그림 1.6. Matlabrc.m파일의 맨 아래 부분의 내용

[그림 1.6]의 내용은 □만일, Matlab이 초기 실행 될 때, □startup.m"이 있으면 그 내용을 우선 실행하라는 뜻□이다. 그러므로, 여러분은 우선, □stratup.m"이라는 파일을 만들어서 그곳에 여러분이 원하는 경로나 환경을 설정 해줄 수 있다. 사실, □Matlabrc.m"내에서 환경을 설정해 줄 수도 있지만, "Matlabrc.m"의 내용은 편집하지 않는 것이 좋다. [그림1.7]에서는 간단한 경로만 설정해주는 "startup.m"파일을 보여주고 있다.

그림 1.7. startup.m파일의 내용

이제, "stratup.m"을 Matlab의 □bin"디렉토리에 저장한 후, □c:\Matlab\limspace"디렉토리를 새로 만들고, Matlab을 다시 실행하여 [그림1.5]와 같이 명령어 □□cd"을 행하면 □c:\Matlab\limspace으로 작업 디렉토리가 옮겨 진 것을 알 수 있을 것이다.   Matlab을 installation 한 후에 □*.m file"의 icon을 보면 아직 link될 프로그램이 설정  되어 있지 않은 것을 알 수 있다. 그러므로, file 탐색기의 옵션 메뉴를 이용하여 □*.m file"을 Matlab에 link시켜주도록 하자. 여러 가지 link시켜주는 방법이 있겠지만 여기서는 그 중에서 하나의 방법을 보여 주겠다.

임의의 □*.m file"을 mouse 왼쪽 키로 한번 클릭한다.

file 탐색기의 보기 메뉴에서 □옵션□을 선택한다.

옵션에서 □파일 형식□을 선택한다.

□새 형식□을 클릭한다.

□파일 형식 설명□란에 □m-file"이라 쓴다.

□연결된 확장명□에는 □.m"이라고 쓴다.

□새 명령□을 누른다.

□명령□에는 □open with Matlab"이라고 쓴다.

□명령을 실행할 응용 프로그램□에는 옆에 있는 □찾아 보기□를 눌러서 Matlab.exe를 찾아 더블 클릭한다.

□확인□을 클릭하고, 이어서 □아이콘 바꾸기□로 Matlab icon으로 바꾸어 준다.

□확인□을 클릭하면, □파일 형식 정보□에 여러분이 바꾸어 준 정보가 나올 것이다. 그리고, 동시에 □*.m file"파일의 icon들이 여러분이 설정한 icon으로 모두 바뀌는 것을 알 수 있을 것이다.

이제, □*.m file"파일은 클릭한 장소에 관계없이 항상 Matlab을 실행시킬 것이며, 동시에 □c:\Matlab\limspace"로 작업 디렉토리를 설정 해줄 것이다.

지금까지 여러분은 Matlab의 기본 installation과정과 간단한 경로 설정 방법을 배웠다. 다음 단원부터는 본격적으로 Matlab을 이용한 수치 계산과 그에 따른 그래픽 표현을 배우게 될 것이다.

Matlab의 행렬연산 방법.

원칙적으로 행렬(matrix)과 배열(array)은 의미상 차이가 있지만, 편의상, 앞으로 이들 행렬과 배열은 같은 의미로 생각하겠다.

기본적으로, "= (즉, assignment operator)"왼쪽에는 저장할 변수(variable), 오른쪽에는 저장할 행렬수식으로 이루어진다. 즉,

□변수명(variable) = 수식(expression)

여기서, 변수란 double형, char형, cell형, struct형, sparse형, user_defined형을 말하며, 수식이란, Matlab이 해석할 수 있는 numeric and nonnumeric형의 수식을 말한다.

	변수의 형(type)중에서, cell형과, struct형, user_defined형은 Matlab5.0이후 버전에서만 지원된다. 또한, 다차원 배열도 Matlab5,0이후 버전에서만 지원된다.

* Matlab에서 행렬을 만드는 방법은 다음과 같다.

1. 명확한 행렬요소를 작성한다.

2. 외부 데이터 파일로부터 행렬을 load한다.

3. M-files로 행렬을 생성한다.

→ 이번 단원에서는 1.번만 알아보고, 2.,3.번 내용은 추후에 알아보도록 한다.

행렬의 합과 transpose

Matlab으로 행렬을 만드는 경우, 행(row)의 원소들은 blanks또는 commas로 구분을 한다. 열(column)의 원소들은 semicolon(즉, ; )으로 구분하거나 □enter 키□를 누르면 된다. 다 작성한 행렬요소는 square brackets(즉, [ ] )으로 닫아 준다. 예를 들어서, 3행3열의 다음과 같은 행렬 A를 만들어 보자.

	앞으로 참고 해야할 내용은 □%□기호 다음에 작성할 것이다. Matlab은 주석을 □%□기호 다음에 쓰게 되어있다. 또한, □ □□기호는 □enter 키□를 누르라는 뜻이다.

[eqn: A= BMATRIX { { 1}& {1 }& {1 }# { 1}& {2 }& {3 }# {1 }& {3 }& {6 } }] .......................... (1.1식)

□A=[1 1 1;1 2 3;1 3 6] □

□A=

A =

1     1     1

1     2     3

1     3     6

이제, 행렬A의 합을 구해 본다. 기본적으로 Matlab의 모든 연산과 함수의 입력 data처리는 □열 벡터□ 방향이다. 즉,

□sum(A) □를 하면 결과는 각각의 열을 더한 결과가 행 벡터 형태로 나온다.

ans =

3     6    10

여기서, 여러분은 재차 Matlab이 □열 벡터□방향으로 연산한다는데 주의해야 한다.

Matlab은 출력 변수를 설정하지 않은 경우 변수 □ans(answer의 약식)□에 값을 할당한다. 또한, □ □y=sum(A); "와 같이 문장 맨 뒤에 semicolon을 쓰면 출력 결과가 표시되지 않는다. 행렬의 transpose( i×j행렬을 j×i행렬로 바꾸는 연산자)에는 두 가지가 있다.

1. 복소 벡터나 행렬 Z의 □ □Z' "은 복소 공액(complex conjugate) transpose를 나타낸다.

2. 복소 벡터나 행렬 Z의 □ □Z.' "은 일반적인 행렬의 transpose를 나타낸다.

→ 결국 □ . (즉, dot )□가 있는가 없는가에 따라 뜻이 달라진다.

□z=[1+2i 3+4i] □

z =

1.0000 + 2.0000i   3.0000 + 4.0000i

□z' □

ans =

1.0000 - 2.0000i

3.0000 - 4.0000i

□z.' □

ans =

1.0000 + 2.0000i

3.0000 + 4.0000i

이 된다.

이밖에 다른 여러 가지 연산, 예를 들어서 □cos 함수"에 대한 이용방법을 알려면

□help cos □  %즉, □ help topic_name "의 양식!

위와 같이 하면 자세히 그 함수에 대한 설명이 나온다.

만일, 여러분이 " fft "에 관련된 여타 함수들의 정보를 알고 싶다면,

" □lookfor topic_name "이라고 하면 된다. 즉, " help "는 주어진 topic에 관한 내용만 제공해주고, □ lookfor "는 Matlab이 지원하는 모든 함수에 대한 정보를 제공해 준다. ( 단, □path browser"에 등록된 경로내의 함수들만 해당된다. 그러나, □overloaded"된 함수나 연산자는 정보를 제공해준다.)

□lookfor fft □

FFT Discrete Fourier transform.

FFT2 Two-dimensional discrete Fourier Transform.

FFTN N-dimensional discrete Fourier Transform.

FFTSHIFT Shift DC component to center of spectrum.

IFFT Inverse discrete Fourier transform.

… 생략 …

여기서, □help"와 □lookfor"에서 제공되는 함수 정보는 M-file의 주석 내용들이다.

(단, □lookfor"의 경우에는 주석문의 제일 윗줄만 해당된다.)

이제, 여러분이 만든 변수와 데이터에 대한 정보를 알아보자. 현재, A라는 3×3행렬과 Z라는 복소 행렬 그리고 출력 변수를 정하지 않아서 생긴 □ ans □행렬 이렇게 3가지를 만들었다.

데이터에 대한 정보를 알려면, □ whos "라는 명령어를 사용하면 된다.

□whos □

Name	Size	Bytes  Class

A	3x3             72	double array

ans	3x1             24	double array

z	1x2             32	double array (complex)

Grand total is 14 elements using 128 bytes

위와 같은 데이터의 정보가 나오는데, 만일, □ ans "행렬을 base workspace( Matlab의 command window에서 행한 변수를 저장하는 메모리 공간, 이밖에도, 함수 workspace, callback workpsace가 있다.)에서 지우려면,

□clear ans □

하면 □ ans "변수가 지워진다. 또는, Matlab의 □workspace browser"를 이용한다.

[그림1.8] Matlab command window toolbar를 보여 주고 있다. 여기서, □workspace browser" icon을 click한다.

그림 1.8 command window toolbar

그림 1.9 Matlab workspace browser

[그림 1.9]는 □workspace browser"를 이용한 예를 보여 준다.

	다음 이 시간의 강의 내용 : 제3회에서는 *Matlab의 행렬연산을 전반적으로 정리하고, 제4회에서는 *Matlab의 그래픽 기능을 배우게 될 것이다.

나. 행렬을 구성하는 원소들의 참조 방법.(첨자:subscript)

행렬의 원소들은 임의의 Matlab식이 될 수 있다. 여기서, 말하는 식이란 Matlab함수들도 포함된다.

□x=[-1.3 sqrt(3) (1+2+3)*4/5] □

x =

-1.3000    1.7321    4.8000

□ X "개개의 성분을 얻으려면 □ ( ) □안에 해당 원소의 위치(subscript)를 넣어 주면 된다.

□x(3) □

ans =

4.8000

그런데, 만일, 다음과 같은 명령을 주면 어떻게 될까?

□x(5)=abs(x(1)) □

x =

-1.3000    1.7321    4.8000         0    1.3000

결국, □ X "의 크기는 새로운 5번째 원소를 수용하기 위해서 증가해버린다. 그리고, 4번째 원소는 □ 0 □으로 채워진다. 앞으로 배울 다차원 행렬뿐만 아니라, cell형이나 struct형들도 새로운 데이터를 수용하도록 자동으로 증가하고, 빈 부분에는 □ 0 □이나 빈 행렬(empty matrix)로 채워준다는 사실을 알게 될 것이다.

작은 행렬로 큰 행렬을 만드는 경우도 있다.

□x=[-1.3 sqrt(3) (1+2+3)*4/5]; □

□y=pascal(3); □  % "pascal(3)"는 고3수학 책에 나오는 pascal의 삼각형을 구해                     % 주는 함수이다.

□xy=[y ; x]; □

여기서, □ xy "는 어떻게 출력될까? 잠시 생각해 보기 바란다.

semicolon은 새로운 행(row)를 만들어주는 연산자라고 하였다. 그렇다면, □ y "가

3×3행렬이므로 4×3행렬이 될 것이다. 원소간의 배치는 □ y "행렬 다음에 □ x " 벡터가 나오므로 □ xy "행렬은 다음과 같이 된다.

□xy □

xy =

1.0000    1.0000    1.0000

1.0000    2.0000    3.0000

1.0000    3.0000    6.0000

-1.3000    1.7321    4.8000

그러나, □ □xy=[y ; x'] □"를 하면은 어떻게 될까?

□ y "는 3×3행렬인데, 새로운 x' 3×1 열 벡터가 □ y □행렬 밑에 놓이는 모양이 되므로 행렬의 모양을 이루지 못하여 □ error "가 발생한다.

□xy=[y ; x'] □

???  All rows in the bracketed expression must have the same

number of columns.

다. The colon operator.

Colon(즉, □ : □ )은 Matlab연산자중에서 가장 중요한 연산자중에 하나이다. 사실, Matlab coding을 얼마다 효율적으로 했는가는 이 □ colon "의 사용 방법에 달려 있다고 보아도 과언이 아니다.

□x=1:10 □

x =

1     2     3     4     5     6     7     8     9    10

□ x "가 1부터 하나씩 증가하여 10까지 증가한다. 만일, 최소값을 □min_val", 최대값을 □max_val"이라고 하고, 증분을 □delta"라고 하면 다음과 같은 형태를 취한다.

□x=min_val : delta : max_val □

Colon 연산자는 행렬의 subscript로도 사용할 수 있다.

□x=-3:-1; □

□y=pascal(3); □

□y(1,1:3)=x □  % " □y(1:3,1)=x "라고 하면 □error"가 발생한다. 그 이유는 ?

y =

-3    -2    -1

1     2     3

1     3     6

" y "의 1행 원소가 모두 바뀌었다.

	처음 Matlab을 배우려는 대다수의 학생들은 행과 열의 조작에 무척 당황해 하고 지겨워한다. 그것은 필자도 마찬가지였다. 그러나, 행과 열의 자연스러운 조작 기법을 배우는 것이, 비단, Matlab만을 위한 것보다는 행렬계산의 능률면에서 중요한 도구가 된다.

새로 만들어진 □ y "행렬 모든 원소의 summation(합)을 구해 보자!

□sum_y=sum(sum(y)) □

sum_y =

10

Matlab에는 " end "라는 연산자가 있다. 이 연산자는 □ for, while, switch and if "와 연결되어 C언어에서와 같이 제어의 흐름을 조종하기도 하고, 행이나 열 벡터의 마지막 index를 나타내주기도 한다.

□sum_r=sum(y(end,:)) □

sum_r =

10

여기서, □ 10 □은 □ y "의 마지막 행(1, 3, 6)의 합이다.

□sum_c=sum(y(:,end)) □

sum_c =

8

여기서, □ 8 □은 □ y "의 마지막 열(-1, 3, 6)의 합이다.

이제, " y "의 평균을 구해 보자!

□mean_y=sum(sum(y))/prod(size(y)) □ % " prod "함수는 원소들간의 곱을 반환,

mean_y =                              % " size "함수는 행렬의 크기를 행

% 벡터의 모양으로 반환한다.

1.1111

□[r,c]=size(y) □

r =

3

c =

3

다음과 같은 행렬의 조작법도 있으니 잘 숙고 해 보자!

□B=magic(4) □

B =

16     2     3    13

5    11    10     8

9     7     6    12

4    14    15     1

□A=B(:,[1 3 2 4]); □

과연, 이 명령이 무엇을 뜻할까?

해석 해보면, □ 행렬 B의 각각의 행들에 대한 열들을 1, 3, 2, 4로 재배치하라는 뜻이다.□

□A □

A =

16     3     2    13

5    10    11     8

9     6     7    12

4    15    14     1

	변수의 이름을 만일 □ cos "이라고 하면 앞으로 □ cos "함수는 사용할 수 없다는데 주의하라! 다시 말해서, 함수의 이름을 변수 이름으로 쓰면 그 함수는 더 이상 재 기능을 못하므로 변수의 이름을 정할 때나 M-files의 이름을 정할 때는 각별히 주의해서 사용 해주기 바란다.

지금까지 Matlab에서 행렬을 조작하는 간단한 방법을 배웠다. 주의 할 것은 [그림 1.8]과같은 □command window toolbar"는 Matlab5.0이후 버전에만 있다는 것을 명심하자! 다음 단원  □라.□에서는 보다 구체적인 행렬 연산에 대해 학습한다.

라. Matlab에 의한 행렬 연산.

행렬의 덧셈과 뺄셈 :

Matlab은 행렬을 하나의 기본 피 연산자로 간주한다. 그러므로, 행렬의 덧셈과 뺄셈도 마치 스칼라(scalar)간의 연산과 같이 간단히 표현된다.

□A=pascal(3); □

□B=magic(3); □ % pascal 과 magic등은 Matlab이 지원하는 일종의 데모 행렬.

□Y=A+B □     % Matlab은 변수의 이름에 대한 대·소문자를 구분한다.

Y =

9     2     7

4     7    10

5    12     8

뺄셈도 마찬가지 방법으로 행한다. 그러나, 두 개의 피 연산자는 같은 크기의 차원을 가지거나, 또는 , 스칼라(scalar)이어야 한다.

	만일, 여러분이 help topic_name을 행한 경우, 간혹, 어떤 함수는 입력매개변수로 □DIM"이라고 하여 차원을 입력하게 하는 것이 있다. 이때, □DIM=1"인 경우 는 열 벡터를 의미하고, □DIM=2"인 경우 행 벡터를 의미한다. 이것은 Matlab이 열 벡터 위주의 계산을 행하기 때문이다. 여러분이 신호 처리 toolbox를 이용할 때 이 문제는 중요한 관건이 된다.

□C=ones(2,3); □  % "ones"함수는 모든 원소가 □1□인 입력 매개변수 크기의 행렬                    % 을 만든다.

□X=A+C □

??? Error using ==> +

Matrix dimensions must agree.

두 개의 피 연산자의 크기가 행렬의 덧셈 상 맞지 않다. 앞으로, 여러분이 M-files를 만드는 경우 위와 같은 error는 빈번히 발생 할 것이다.

□X=A+2 □

X =

11     4     9

6     9    12

7    14    10

행렬에 scalar를 더하거나 빼는 경우, 이것은 반대편 행렬의 모든 원소에 그 scalar를 더하거나 뺀 효과가 된다.

행렬의 곱셈과 나눗셈 :

□A=pascal(3); □

□B=ones(3,2); □

□C=1:3; □

□D=2:4; □

□X=A*B □

X =

3     3

6     6

10    10

위와 같이 □ X "는 행렬 □ A "와 □ B "의 크기가 곱셈 상 맞으면, 곱셈이 행해  진다.

□X=C*D □

??? Error using ==> *

Inner matrix dimensions must agree.

그러나, 위와 같이 곱셈 상 크기가 맞지 않으면, error가 발생한다. 그런데, 곱셈 기호 □ * □ 대신에 □ .* □를 이용하면 다음과 같은 결과가 생긴다.

□X=C.*D □

X =

2     6    12

결과를 잘 살펴보면, C는 [1 2 3]이고, D는 [2 3 4]일 때, 연산 결과 X는 [2 6 12]이므로 □ .* □은 원소 대 원소(element-by-element)곱셈인 것을 알 수 있다. 그러므로 연산자 □ .* □은 두 개의 피 연산자인 행렬들의 크기가 같기만 하면 원소 대 원소의 곱셈을 행한다. 같은 방식으로 나눗셈을 행할 수 있다.

□X=C/D □ %여기서 대부분의 학생은 벡터 대 벡터의 나눗셈이 가능한가 의문을                %가질 것이다.

X =

0.6897

그러나, 결과는 계산이 가능하며 그 값은 0.6897이라고 나왔다. 사실, 행렬간의 나눗셈은, 이 경우 벡터□ D "가 역 행렬을 가져야 된다. 그러나, □ D "는 벡터로 역 행렬을 갖질 수 없다. 그런데도 계산 결과가 나왔다. 그 이유는 무엇일까?

필자의 생각으로는 독자가 만일, 공학 석사 수준이라면 왜 계산 결과가 나왔는지 유추 할 수 있다고 본다. Matlab은 □ D "의 역 행렬을 구한 것이 아니라 의사 역 행렬(pseudoinverse)구하여 계산한 것이다. 의사 역 행렬을 간단히 설명하면, 미지수에 비해 방정식이 많을 때, 우리는 least squares soultion을 구한다. 이때, 마치, 역 행렬과 같은 기능을 하는 행렬이 만들어지는데 이 행렬을 의미한다. 사실, 이 행렬은 overdetermined system의 해를 구하는 데 필요한 행렬이다. 만일, 시간이 허락  한다면 시스템 론과 간단한 선형 대수학을 논할 것이다.

	□JOHN WILEY & SONS, INC."에서 1996년 출간한 □statistical digital signal processing and modeling"의 page33을 보면 pseudoinverse문제를 잘 설명하고 있다. 또한, □Prentice-Hall International, Inc."에서 1995년 출간한 □Lessons in estimation theory for signal processing, communication, and control"의 단원 4를 보면 더욱 일반적인 내용까지 잘 설명이 되어 있다.

Matlab에서는 □pinv"라는 의사 역 행렬을 구해주는 함수가 있다.

□inv_D=pinv(D); □

□new_X=C * inv_D □

new_X =

0.6897

위에서 얻은 □ X "와 같은 결과를 얻는다. □ ./ □은 원소 대 원소의 나눗셈을 행한다.

□X=C ./ D □

X =

0.5000    0.6667    0.7500

	다음 이 시간의 강의 내용 : 계속해서 행렬연산에 대해서 배우게 될 것이다. → Matlab을 배우다가 모르는 사항이 있으면 질문을 하기 바랍니다.

3. 행렬의 거듭 제곱 :

곱셈과 나눗셈처럼 거듭제곱에도 두 가지 연산자가 제공된다. 즉, □ ^ □과 □ .^ □

□A=pascal(3); □

□Y=A^2 □

Y =

3     6    10

6    14    25

10    25    46

위의 결과는 □Y=A*A와 같다.

□X=A.^2 □

X =

1     1     1

1     4     9

1     9    36

위의 결과는 행렬 A의 각 원소를 거듭 제곱한 것과 같다. 이밖에도 □sqrtm"과 □expm"과 같은 함수가 있다.

□X=sqrtm(A) □

X =

0.8775    0.4387    0.1937

0.4387    1.0099    0.8874

0.1937    0.8874    2.2749

위의 결과는 행렬의 고유치(eigenvalues)의 분포에 좌우된다.

□Y=sqrt(A) □

X =

1.0000    1.0000    1.0000

1.0000    1.4142    1.7321

1.0000    1.7321    2.4495

위의 결과는 행렬A의 각 원소에 대한 square roots를 구한 것이다. 결국, □sqrtm(A)"함수는 □A^(1/2)"와 같은 의미이고, □sqrt(A)"함수는 □A.^(1/2)"와 같은 의미이다.

□C=1:3; □

□D=2:4; □

□Z=2.^[C D] □

위의 결과는 어떻게 나올지 생각해 보기 바란다.

Z =

2     4     8     4     8    16

독자가 생각한데로 잘 나왔는가? 그렇다면 다음 단원으로 넘어간다.

4. 여러 가지 특수 행렬 함수들:

단위행렬(또는, 항등 행렬, identity matrix) :

단위 행렬을 만들어 주는 함수는 □ eye "이다.

□iden=eye(3) □

iden =

1     0     0

0     1     0

0     0     1

빈 행렬(empty matrix) :

만일, 3×3행렬에서 2행의 모든 원소를 없애 버리려면 어떻게 해야 할까?

□A=pascal(3) □

A =

1     1     1

1     2     3

1     3     6

□A(2,:)=[] □

A =

1     1     1

1     3     6

위와 같이 제거하려는 행이나, 열에 □[ ]□을 대입하면 된다.

matlab에서는 0×0행렬 즉, 원소가 없는 행렬만 empty matrix라고 하지는 않는다.

m×0×n행렬처럼 어느 하나의 벡터가 없는 것도 모두 empty matrix라고 부른다.

행렬의 판별식( determinant )의 값을 구하는 함수:

행렬의 판별식의 값은 □det"라는 함수로 구할 수 있다.

□A=pascal(3); □

□det_A=det(A) □

det_A =

1

그밖에도, 다음과 같은 행렬이 있다.

inv(A)는 행렬의 역 행렬을 구한다.

eig(A)는 행렬의 고유치와 고유 vector를 구한다.

jordan(A)는 행렬의 jordan형을 구한다.

svd(A)는 행렬의 singular value decomposition을 행한다.

5. matlab이 표현하는 데이터의 format

"format"명령어는 matlab에 의해 표현되는 수치의 형태를 제어한다.

	□format"명령어는 단지 screen에 표현되는 데이터의 표현 양식만 바꾸어주는 것이지 결코, 계산상의 정밀도를 바꾸어 주는 것은 아니다. matlab의 모든 계산상의 정밀도는 □ double 형 (8바이트, 정확히 15자리)□에 기준을 두고 있다. → 아래의 [표 1] 참고.

이제부터, 2개의 원소를 갖는 벡터에 대해 여러 가지 □ format "명령어에 따른 출력 양식을 알아 볼 것이다.

□format short  □          % 기본적인 수치표현 양식!

□X=[4/3 1.2345e-6] □

X =

1.3333    0.0000

□format short  e □

□X □

X =

1.3333e+000  1.2345e-006

□format long □

□X □

X =

1.33333333333333   0.00000123450000

□format bank □ % 소수 두 번째 자리까지 표시.

□X □

X =

1.33          0.00

□format rat □  % 분수식 표현!

□X □

X =

4/3          1/810045

□format hex □  % 16진법에 의한 표현!

□X □

X =

3ff5555555555555   3eb4b6231abfd271

□format compact □  % 변수의 값을 출력하는 경우 발생하는 많은 blank(공백)을                        % 지워준다. 그래서 더 많은 정보를 screen 또는 window에                        % 표현할 수 있도록 해준다!

□X □

X =

1.3333    0.0000

6. M-files를 작성할 때 이용할 수 있는 특수 값 :

몇몇 함수는 여러분이 M-files를 작성 할 때 유용하게 이용할 수 있는 특수한 값(special values)을 반환한다. 특수 값은 matlab의 □ elmat " 디렉토리에 위치하고 있다.

다음의 [표 1]은 특수 값을 요약 정리 한 것이다.

[표 1]의 특수 값 중에서 □ computer "와 □ eps "에 대한 예제를 다루어 보자.

□[C , MaxSize]=computer □

C =

PCWIN

MaxSize =        %임의의 한 행렬이 수용할 수 있는 원소 갯수의 최대 값

268435455

□ computer "라는 함수는 여러분의 computer 형(type)이 무엇인지를 반환함과 동시에, 여러분이 현재 쓰고 있는 matlab버전이 지원할 수 있는 최대 크기의 행렬 원소 갯수를 나타내준다.

	여러분이 matlab command window([그림 1.5])에서 작업하는 경우 잘못 typing하여 □return key "를 치고, 다시 typing하는 경우가 있을 것이다. 이때, matlab은 □ editing keys "를 제공하여 여러분의 편집 과정을 돕는다. 다음의 [표 2]는 □ editing keys "중 몇 개를 정리하였다. 또한, 한 명령어 라인이 긴 경우가 있을 것이다. 이 경우, □ ... □를 사용한다. □ ... □는 명령어 라인이 다음 라인에 계속됨을 나타낸다.

□s=1 - 1/2 + 1/3 - 1/4  + 1/5 - 1/6  + 1/17 ... □  %다음 라인에 계속!

-1/8 + 1/9 - 1/10 + 1/11 - 1/12; □

matlab은 한 개의 라인에서 최대 4096개의 문자를 작성 할 수 있게 한다.

표 1  matlab의 특수 값 요약

특수 값 반환 함수 및 상수	각각의 특수 값에 대한 설명
eps	matlab이 수치계산 할 때 발생하는 허용 오차 ( tolerance )
realmax	여러분의 컴퓨터가 표현 할 수 있는 가장 큰 부동 소수점을 반환한다. (Largest floating-point number)
realmin	여러분의 컴퓨터가 표현 할 수 있는 가장 작은 부동 소수점을 반환한다. (Smallest floating-point number)
pi	3.1415926535897...
i 와 j	허수의 단위(즉, i^2 = -1), 그러므로, 가능하면, i와 j는 변수로 취하지 않는 것이 좋겠다.
inf	무한대(infinity)를 반환한다. ---> (임의의 nonzeros 수치) / 0
NaN	수치가 안임(Not-a-number)을 나타낸다. ---> 0 / 0 또는 inf / inf
computer	여러분의 컴퓨터 형(type)을 반환한다. (예, pcwin 등등)
flops	부동 소수점 연산의 횟수를 반환한다.
version	여러분이 현재 사용하는 matlab의 버전을 반환한다.

표 2  matlab 편집 키들의 요약

key symbol	편집 키들에 대한 설명
↑	이전 명령 라인을 되부른다. (Recall previous line)
↓	다음 명령 라인을 되부른다. (Recall next line)
home	명령 라인의 처음으로 커서를 옮긴다. (Move to beginning of line)
end	명령 라인의 끝으로 커서를 옮긴다. (Move to end of line)

	다음 이 시간에는 기본적인 그래픽을 활용하면서 계속해서 matlab의 행렬 연산을 배우게 될 것이다.

7. Matlab의 연산자(operators) :

Matlab이 지원하는 연산자(operator)에는 다른 High level언어(예, C, Pascal 등등)에서처럼 3가지 종류의 연산자가 있다.

산술 연산자(Arithmetic Operators) :

수치 계산을 행하는 연산자로써, 사칙연산이나 거듭 제곱 등을 말한다.

관계 연산자(Relational operators) :

배열을 구성하는 각각의 원소에 대한, □작다(less), 같지 않다(not equal to) 등"을 비교하는 데 이용한다.

논리 연산자(Logical Operators) :

"AND", "OR"등의 논리 연산을 행하며 □TRUE", "FALSE"와 같은 결과를 알려 준다.

연산자 우선 순위 :

산술 연산자가 가장 우선 순위가 높고, 그 다음으로 관계 연산자이며, 마지막으로 논리 연산자 순서이다. 그러나, 만일, 같은 우선 순위를 갖는 연산자이면, 왼쪽에 위치한 연산자부터 계산해 나간다. 물론, □ ( ) □를 수식에 취하면 가장 높은 연산 순위를 갖는다.

산술 연산자 (Arithmetic operators) :

산술 연산자 내에서의 연산 우선 순위는 다음과 같다.

transpose( " .' " ), power ( " .^ " ), 복소 공액 transpose( " ' " ),

행렬의 power( " ^ " )

unary plus( " + " ), unary minus( " - " )

곱셈( " * " ), 오른쪽 나눗셈( " . / " ), 왼쪽 나눗셈( " . \ " ), 행렬의 곱( " * " ), 행렬의 오른쪽 나눗셈( " / " ), 행렬의 왼쪽 나눗셈( " \ " )

덧셈( " + " ), 뺄셈( " - " )

colon 연산자( " : " )

이제 연산자 우선 순위에 대한 예를 들어보자.

□A=[3 9 5];

□B=[2 1 5];

□C1=A./B.^2 □ % 우선, B.^2을 계산하고 이어서, A./을 계산한다.

C1 =

0.7500    9.0000    0.2000

□C2=(A./B).^2 □ % 우선, 괄호 안의 식(A./B)를 계산하고 나서, .^2를 계산한다.

C2 =

2.2500   81.0000    1.0000

연산자 우선 순위에 의해서 C1과 C2의 결과가 다르다는 데 주의하자.

이미, 앞에서 언급하였듯이, 행렬에 대한 산술 연산의 경우에는, 두 피 연산자인 행렬들의 크기가 같아야 한다. 그러나, 두 개의 피 연산자중 하나가 스칼라인 경우에는 그 스칼라를 다른 피 연산자의 모든 원소에 적용하여 계산한다. 이와 같이 스칼라를 행렬에 적용하여 계산할 수 있는 성질을 □스칼라의 확장성(scalar expansion)"이라 한다.

	어제 후배가 필자에게 본인은 Matlab을 거의 다 아는 데 GUI coding하는 것만 모르니 그것만 가르쳐 달라고 하였다. 그런데, 대부분의 학생은 필자의 후배처럼 Matlab 행렬 연산에 대한 충분한 지식과 경험도 없이 무리하게 포장만 하려는 경향이 있다. 또한, C언어를 잘 한다고 하여, 반드시 Matlab을 잘한다고 말할 수는 없다. 왜냐하면 C언어는 행렬을 곧바로 계산할 수 없기 때문이다. 대부분의 C언어 잘 하는 학생이 작성한 M-file을 보면, Matlab의 행렬 연산을 무시한 C언어 양식 그대로 작성한 경우가 많다. 물론, 그렇다고 프로그램이 돌아가지 않는 건 아니지만 속도 면에서 상당한 차이가 발생한다. 여러분이 필자의 강의를 순서대로 따라간다면 Matlab을 효과적으로 다룰 수 있다고 본다.

관계 연산자(Relational Operators) :

관계 연산자에는 6가지 종류가 있다. 이들 6개의 관계 연산자는 같은 크기의 두 배열에 대한 해당 원소를 비교한다. 관계 연산자에서도 scalar expansion은 적용된다.

주어진 관계가 사실인 경우(TRUE) 해당 위치에는 □1□을 반환하고, 거짓인 경우(FALSE)에는 해당 위치에 □0□을 반환한다. 관계 연산자는 논리 연산자와 함께 앞으로 M-files를 작성 할 때, " if , while, for, switch "등과 더불어 실행순서를 제어하는 데 귀하게 쓰일 것이다.

	관계 연산자는 항상 원소 대 원소(element-by-element)로 연산한다.

표 3 Matlab의 관계 연산자들

관계 연산자의 종류	해당 연산자에 대한 설명
<	□보다 적다(Less than)"
<=	"적거나 같다(Less than or equal to)"
>	"보다 크다(Greater than)"
>=	"크거나 같다(Greater than or equal to)"
==	"같다(Equal to)"
~=	"같지 않다(Not equal to)"

	C언어에서는 □같지 않다(Not equal to)□가 □ != □인 데, Matlab에서는 □ ~= □이라는 것에 주의하자!

□A=[2 7 6;9 0 -1;3 .5 6]; □ % Matlab에서는 소숫점 앞의 □0□은 무시한다.

% 즉, □0.123□과 □.123□은 같은 뜻이다.

□B=[8 0.2 0;-3 2 5;4 -1 7]; □

□rel_AB= A<B □

rel_AB =

1     0     0

0     1     1

1     0     1

행렬 A와 B를 비교하여, A의 원소 중 B의 원소보다 더 작은 것은 □참(TRUE)□이므로 해당 위치에 □1□을 넣고, 그렇지 않은 곳(거짓:FALSE)에는 □0□을 넣는다.

결국, 여러분은 rel_AB의 결과로부터 행렬 A의 원소 중에서 어느 원소가 행렬B의 원소보다 더 작은 지, 해당 위치를 알 수 있다.

	관계 연산자는 임의의 크기를 가진 배열에 대해 적용할 수 있다. 그러나, □A == [ ] □과 같이 빈 행렬(empty matrix)에 대한 관계는 경고나, error를 발생한다. 만일, 여러분이 빈 행렬에 대해 테스트하고자 한다면 □ isempty "함수를 이용하라! □ isempty "함수는 빈 행렬인 경우 □1□을 반환한다.

□A=[]; □

□isempty(A) □

ans =

1

이제, 관계 연산자 뿐만 아니라, 논리 연산자에서도 유용하게 사용되는 □ find "라는 함수에 대해서 알아보자

*find 함수 :

" find " 함수는 주어진 관계에 맞는 배열의 원소 위치를 알려 준다.

만일, 주어진 배열이 벡터이면 출력 변수는 한 개로 하다. 또한, 주어진 배열이 행렬이고, 출력 변수를 하나로 설정하면, " find " 함수는 주어진 행렬을 □열 벡터□로 변환 한 뒤, 해당 원소의 위치를 반환한다.

□A=magic(4) □ % magic 행렬은 어느 방향으로 더하던지 그 합이 같은 행렬이	% 다.

A =

16     2     3    13

5    11    10     8

9     7     6    12

4    14    15     1

□index=find(A > 8); □

□A(index)=100 □

A =

100     2     3   100

5   100   100     8

100     7     6   100

4   100   100     1

논리 연산자(Logical operators) :

Matlab의 논리 연산자는 □ AND, OR, and NOT"을 수행한다.

표 4. Matlab의 논리 연산자의 종류

논리 연산자의 종류	해당 연산자의 설명
&	AND
|	OR
~	NOT

	비트 연산자(bitwise logical operations)에 대해서는 □ bitfun "디렉토리에 있으니 □ help "명령어로 참고하기 바란다.

논리 연산자에 대해서도 scalar expansion은 적용된다.

" AND " 연산자는 두 개의 피 연산자가 참이면 □참(반환하는 값 : 1 )□을 반환한다. 여기서, 참이라 함은 영이 아닌 수치(nonzero number)를 말한다.

□U=[-1 0 2 3 0 5]; □

□V=[5 6 1 0 0 7]; □

□U & V □

ans =

1     0     1     0     0     1

위의 결과에서도 알 수 있듯이 □0□일 때만 거짓으로 보고, 부호와 숫자의 크기는 참·거짓과 관계없다는 데 주의하자!

□ OR " 연산자는 적어도 한 개의 피 연산자가 참이면 □참(반환하는 값 : 1)□을 반환한다.

□U | V □

ans =

1     1     1     1     0     1

" NOT " 연산자는 피 연산자의 부정을 행할 때 이용된다.

□~U □

ans =

0     1     0     0     1     0

논리 함수(Logical functions) :

Matlab은 논리 연산자 외에, 여러 논리 함수를 제공한다.

표 5. Matlab의 논리 함수들

논리 함수의 종류	해당 함수에 대한 설명
xor	exclusive OR연산을 행한다.
all	주어진 벡터의 모든 원소가 □참(nonzero)□인 경우에만 □1□을 반환한다.
any	주어진 벡터의 임의의 원소가 □참(nonzero)□인 경우에 □1□을 반환한다.
isnan	주어진 벡터의 원소 중에서 □NaN□이 위치한 곳에는 □1□을 반환한다.
isfinite	주어진 벡터의 원소 중에서 유한한 크기를 갖는 수치, 또는 NaN이 아닌 곳에는 □1□을 반환한다.
isinf	주어진 벡터의 원소 중에서 유한한 크기를 갖는 곳에는 □1□을 반환한다.

[표 5]의 논리 함수 중에서, □ all "함수와 □ any "함수는 특별히 중요한 함수이다.

만일, □ all "함수와 □ any "함수에 주어진 입력 변수가 벡터가 아니고, 행렬이면 각각의 □ 열 방향 □에 대해서 연산한다.

□U=[1:4 0]; □

□all(U) □

ans =

0

□A=[0 1 2;3 5 0] □

A =

0     1     2

3     5     0

□all(A) □

ans =

0     1     0   % 행렬 A의 각각의 □열 방향□으로 논리 계산을 행한 데 주                        % 의!

□any(A) □

ans =

1     1     1

지금까지 여러분은 Matlab의 행렬연산에 대하여 많은 것을 공부하였다. 비록, 여러 부분이 빠지긴 했지만, □Matlab 행렬 연산II"를 따로 분류하여 이곳에서 설명하지 않은 □다항식 계산과 데이터 분석 등□은 뒤에서 다룰 것이다.

이제, 단원을 바꿔서 □2. M-file Programming"에 대하여 다루겠다.

	다음 이 시간의 강의 내용: M-file Programming

M-file이란 무엇인가?

전체적인 의미로 M-file이란 Matlab언어로 쓰여진 파일들(files)을 말한다.

또한, M-file은 연속적인 Matlab문장들(명령어들)을 수행하는 script 양식(script mode)과 입력 매개변수와 출력 매개변수를 다루는 함수 양식(function mode)이 있다. 이와 같은 M-file은 Matlab이 제공하는 text editor를 이용하여 작성 할 수 있고, 또한, 다른 여러 종류의 ASCII text editor를 이용할 수도 있다. 그러나, 앞으로의 M-file 작성은 모두 Matlab이 제공하는 text editor를 이용하여 작성 할 것이다.

Matlab에서 M-file의 이용과정은 다음과 같다.

1. text editor를 이용하여 M-file을 작성한다.

2. command window에서 M-file을 부르거나, 또는 다른 M-file내에서 호출 할 수 도 있다.

[표2.1]은 script mode의 M-file과 function mode의 M-file에 대한 비교이다.

표 2.1 M-file 종류 비교

script mode의 M-file	function mode의 M-file
파일 이름은 어떠한 이름으로도 할 수 있다.	파일의 이름은 function이름과 가능 한한 같게 한다.
base workspace에 있는 data에 대해서 연산한다.	function workspace에 있는 data에 대해서 연산한다.

[표2.1]에서 base workspace란 Matlab command window에 있는 변수 공간을 의미한다. 즉, 지금까지 여러분이 [그림 1.5]에 보여준 Matlab command window에서 생성한 변수들로써, [그림1.9]에 나타나는 변수(A, ans, z 따위)를 의미한다. 그리고, function workspace란 여러분이 작성한 function mode의 M-file내에서만 존재하는 내부 변수를 의미한다. 물론, 전역 변수나, userdata를 이용하면, function workspace 변수를 base workspace에서도 볼 수 있다. 그러나, base workspace와 function workspace의 보다 편리한 데이터 교환은 출력 변수와 입력 변수를 이용하는 것이다. Matlab은 이처럼 변수를 연산하는 작업공간이 따로 설정되어 있다는 것을 알아두자! 일반적으로 그냥, workspace라고 하면 □ base workspace "를 의미한다.

Matlab 4.2c이전 버전들에서는, M-file mode에 따라 저장하는 파일 이름에도 차이가 있었다. script mode의 M-file은 어떠한 이름으로도 파일 이름을 설정할 수 있지만, function mode의 M-file은 function이름과 같은 이름의 M-file로 저장해야 했었다. 그러나, Matlab5.0이후 버전에서는 이러한 제한요소가 없어졌다. 만일, 함수 정의 부에 있는 이름과 파일 이름이 다르다면, Matlab은 함수 정의 부에 있는 이름을 무시하고, 파일이름을 이용한다. 그러나, 가능한한 function mode M-file의 경우, 파일 이름은 함수이름과 같게 하는 것이 좋겠다.

이제, function mode M-file과 script mode M-file의 예를 각각 살펴보자!

간단한 function mode M-file :

[그림 2-1]의 □ New File " icon을 클릭 한다.

그림 2-1. command window toolbar

□ New File "icon을 클릭 하면, [그림 2-2]와 같은 □ Matlab editor/debugger " text editor가 뜰 것이다.

그림 2-2 Text editor/debugger

[그림 2-2]에서 작성한 M-file은 □ n! "을 구하는 함수이다.

Matlab에서 function mode M-file을 작성하려면,

□ function 출력 변수 = 함수 이름(입력 변수) □의 형태로 함수를 정의한다.

□ % □으로 시작하는 주석을 단다.

→

함수 정의 부(part) 바로 다음에 나오는 첫 번째 주석 문은 □ Lookfor " 를 이용한 M-file의 검색시 나오는 정보 부분이다. (□ lookfor "에 대한 내용은 page.15 참고)

□ Help "명령 다음에 나오는 정보들은 함수 정의 부분과 첫 번째 비 주석문(즉, Matlab 명령어 또는 빈 공간(blank))사이에 있는 주석문들 이다.

[그림 2-2]의 경우에서는 □%FACT ∼ 표시 된다.□까지가 □help fact"할 때 나      오는 정보 내용이다.

□ y=prod(1:n) "은 함수의 본체이다.

→ □ prod "함수에 대해서는 page. 20을 참고,

가 ∼ 라. 는 function mode M-file작성 시, 기본적인 부분이다.

이제, M-file을 다 작성했으면, 함수이름인 □ fact "로 파일 이름을 정한 뒤 저장한다. 물론, 확장자는 □ .m "이다.

	Matlab4.2c이전 버전에서는 함수나 변수 이름이 8자 이상이 되는 것을 허용하지 않았다. 그러나, Matlab5.0이후 버전에서는 변수나, 함수 이름을 31자 이내에서 만들 수 있게 되었다. Matlab에서도 다른 언어에서와 마찬가지로 변수나 함수이름의 첫 글자는 문자(letter)이어야한다.

[표2.2]는 Matlab에서 자주 쓰이는 명령어들을 간단히 설명하고 있다. 보다 자세한 이용법은 앞으로 배워나갈 것이다.

표 2.2 Matlab의 주요 명령어들

Matlab 명령어	명령어에 대한 설명
close 해당 그림의 핸들	활성화된 그림을 지운다. →" close all "하면 모든 그림이 지워짐!
clear 변수 이름	base workspace에 있는 변수들을 지운다. →□ clear all "모든 변수와 핸들이 지워짐
dir	□DOS"에서의 □dir"과 거의 같은 기능을 한다. →wildcards이용 가능!
clc	□DOS"에서의 □cls□와 같은 기능! →변수와 핸들에는 영향이 없음

□ dir "대신 □UNIX"운영 체계에서 쓰는 □ ls "를 사용해도 command window의 내용을 다 지운다. 그러나, 역시, 변수와 핸들에는 영향을 주지 않는다.

□ 핸들(handle) "에 대해서는 뒤에서 따로 단원을 분리하여 □ 객체(object) "와 함께 설명하겠다. 본 단원에서는 핸들의 정의와 기본적인 이용법만 다루겠다.

만일, 여러분이 앞에서 설명한 □ startup.m "내의 디렉토리를 그대로 기본 작업 디렉토리로 하고, 부가적으로 또 다른 작업 디렉토리를 설정하고 싶으면, 다음과 같이 행한다.

1. 원하는 위치에 작업 디렉토리를 만든다.

→ 여기서는, □ c:\Matlab\limspace\mbook "으로 정하였다.

2. [그림 2-1]의 command window toolbar에서 □path browser" icon을 클릭 한다. 그러면 [그림 2-3]과 같은 □Matlab path" window가 뜰 것이다.

3. □Matlab path" window내의 □add to path..." 버튼을 클릭 한다.

그러면 [그림 2-4]와 같은 □add to path" window가 뜰 것이다.

4. 새로 만든 디렉토리(여기서는 □mbook")를 클릭 한 후, □add to front" 또는,

□add to back" 둘 중 하나를 클릭 한다. 그리고 나서, □OK" 버튼을 클릭 한다.

5. □Matlab path" window내의 □save settings" 버튼을 클릭 한다. 그러면,

□path"라는 title안에 여러분이 새로 만든 디렉토리가 Matlab의 다른 여러 디렉토리와 링크된(linked) 것을 알 수 있을 것이다.

그림 2-3 □Matlab path" window

그림 2-4. □add to path" window

[그림 2-5]는 command window에서 □ fact.m "을 실행한 예를 보여 주고 있다.

[그림 2-2]에서 알 수 있듯이, □ fact.m "함수는 적당한 입력 매개변수 값을 주면, 그 입력 매개변수에 대한 factorial을 계산한다. 그리고, 그 결과를 출력 매개변수를 통하여 base workspace로 반환한다.

→ [그림 2 - 5]는 함수□ fact.m "이 □ 3! =6 □을 계산한 결과이다.

[그림 2-5]에서 알 수 있듯이, 함수에 보내주는 이름은 [그림 2-2]에서 보여준 입력 매개변수이름(즉, □ n ")과 달라도 된다.

그림 2-5 □fact.m"함수의 실행 예

간단한 script mode M-file :

function mode M-file과 달리, □script mode M-file"내에 있는 모든 변수는 □base workspace" 메모리 공간에 저장된다. 즉, script mode M-file내에 있는 변수는 command window내에 있는 변수와 데이터 교환이 가능하다. 그러므로, □text editor"에 간단히 □y=prod(1:n)"이라고 한 뒤, □script_fact.m"으로 저장하고, command window에서 [그림 2-6]과 같이 실행하면, 위에서 얻은 □fact(3)"와 같은 결과를 얻는다.

그림 2-6 □script_fact.m"의 실행 예

"script_fact.m" 파일을 실행한 뒤 □ whos □명령어를 실행하면, base workspace에 □ n, y "변수가 새로 생긴 것을 알 수 있을 것이다.

명령어의 흐름 제어(Flow Control) :

Matlab5.0에는 명령어의 흐름을 제어하는 4가지 방법이 있다.

if, else와 elseif :

전형적인 사용법(syntax) :

if 논리적인 식

명령어 문장

elseif 논리적인 식

명령어 문장

else

명령어 문장

end

[그림 2-7] □ if문장 □의 기본 형태

만일, □if 문장□의 논리적인 식이 □1(TRUE)"이면, Matlab은 명령어를 수행한다. 그러나, 논리적인 식의 값이 □0(FALSE)"이면 명령어 문장을 건너뛴다.(skip)

	참(TRUE)과 거짓(FALSE)에 대해서는 이미 앞에서 자세히 언급하였다.

[그림 2-7]에서 □elseif□와 □else"명령어의 차이점은 논리적인 식을 갖는가 갖지 않는가 하는 점이다.

	만일, 논리적인 식의 값이 scalar가 아니라 배열(array)로 주어진다면, 그 배열의 모든 원소가 □참(TRUE)"이어야 □참(TRUE)"이다. 즉,

if 배열

명령어 문장

end

(a)의 경우

if all(배열(:))

명령어 문장

end

(b)의 경우

(a)의 경우와 (b)의 경우는 같다. 또한, 논리적인 식의 값이 빈 행렬(empty matrix)이면 □거짓(FALSE)"에 해당한다.

[예제 1] 벡터 x의 평균을 구하라!

function y=average(x)

%AVERAGE   Mean of vector elements.

%average(x)는 벡터 x의 평균을 반환하며,

%만일, 입력이 없으면 error를 내보낸다.

[m,n]=size(x);

if (∼((m==1) | (n==1)) | (m==1 & n== 1))

error('입력은 값이 있는 벡터여야 한다.□);

end

y=sum(x)/length(x);  %실제, 계산하는 부분!

[그림 2-8] □average.m"파일의 내용

[그림 2-8]에서 □error('메세지□)"함수는 □메세지□내용을 screen에 내보낸(display) 뒤 해당 함수의 실행을 멈추고, base workspace로 연산을 옮긴다. 여기서, 주의 할 점은 □string"을 표시하기 위해서 단일 인용부호(즉, □ □ ,□ □)가 쓰였다는 데 주의하자! C언어에서는 □string"을 표시하는 데, 이중 인용부호를 사용한다는 점에서 다르다. 유사 함수로 □warning('메세지□)"함수가 있다.

[그림 2-8]에 있는 내용은 쉽게 이해가 가리라고 본다.

	만일, 여러분 중에서 [그림 2-8]의 M-file내용을 작성하기 싫다고 해서, 내용을 copy한 후 Matlab의 text editor에 paste하면 아마, 낭패를 당할 것이다. Matlab은 한글로 된 명령어를 받으면 치명적인 error에 빠진다. 필자가 Matlab4.2c를 사용할 때 였다. 실수로 command window에 한글로 명령어를 작성하고, return key를 누르자 화면이 정지하고, 아무 반응이 없는 것이었다. □Ctrl-Alt-del"key를 눌러도 시스템에 반응이 없었다. 결국, □reset" switch를 누른 후 다시 Matlab을 시동시키자 이번에는 속도가 무척 떨어졌었다. [그림 2-8]에도 한글로 작성된 한 개의 문자가 있다. 그러니, 꼭 여러분 손으로 직접 작성하기 바란다.

[그림 2-9]는 □average.m"함수를 실행한 예이다.

그림 2-9. □average.m"을 실행한 예

	다음 이 시간에는 나머지 제어문과 debugging요령을 배우게 될 것이다.

나. switch 문 : Matlab5.0이후 버전에만 있다.

전형적인 사용법(syntax) :

[그림 2-10] □switch 문□의 기본 형태

switch 변수 또는 식

case 값1	%만일, 변수 또는 식이 □값1□인 경우!

명령어 문장

case 값2	%만일, 변수 또는 식이 □값2□인 경우!

명령어 문장

... 임의의 수의 case 문들 ...

otherwise	%만일, 변수 또는 식의 값이

%어떠한 case 값들과도 맞지 않을 때

명령어 문장

end

C언어에서의 □switch 문□과는 달리 Matlab에서의 switch문은 변수 또는 식의 값과 맞는 □case문□의 명령어만 수행하므로 C언어에서처럼 □break□명령어가 따로 필요 없다. 또한, C언어에서의 □switch□문에 있는 □default□명령어는 Matlab에서 □otherwise□에 해당한다.

[예제 2] 입력 변수 x의 짝수·홀수를 판별하는 M-file을 작성 할 것.

[풀이]

간단하게 입력 변수 □x□의 값이 □2□로 나누어지면, 짝수이고, 그렇지 않으면, 홀수로 판단하는 알고리즘을 생각할 수 있다. 또한, 각각의 결과를 메시지로 내보내는 M-file을 작성할 수 있다.

다음은 M-file 작성 시, 필요할지도 모를 함수를 정리하였다.

Matlab 함수들 :

□disp('메세지□)□함수는 단순히 screen에 □메세지□를 내보내는 기능을 한다.

□rem(a , b)□함수는 □a ÷ b□에 대한 나머지를 반환한다.

□fix(x)□함수는 □x□가 소수인 경우, 소수점 이하를 버린 정수를 반환한다.

이제, 여러분은 앞에서 배운 □error□함수를 이용하여 M-file을 작성 할 수 있을 것이다. [그림 2-11]은 필자가 작성한 M-file이다.

function PM_c(x)

%PM_c(x) 부호를 판별하는 M-file.

if x ~=abs(x)

error('입력 값은 양의 실수이어야 한다.');

elseif x ~= fix(x)

error('정수가 아니다.');

end

y=rem(x,2);

switch y

case 0

disp('입력 값은 짝수!');

otherwise

disp('입력 값은 홀수!');

end

[그림 2-11] □PM_c.m"파일의 내용

다. for 문 :

전형적인 사용법(syntax) :

for 지수(index)=초기치 : 증분 : 최종치

명령어 문장들

end

[그림 2-12] □for 문"의 기본 형태

기본적으로 증분량을 지정하지 않으면, 매번 반복할 때마다 증분하는 양은 □1□로 된다.

	Matlab은 배열의 첫 번째 요소를 다른 언어에서처럼 □0□으로 잡는 것이 아니라 □1□로 잡는다. 그러므로 초기치가 □0□부터 시작한다면 배열의 subcript로는 사용될 수 없다.(배열에 대한 subscript에 대해서는 이전에 자세히 설명하였다.)

[예제 3] 선형상계수미분 방정식(Linear, Constant coefficient, Ordinary equations)에 의해 표현되는 시스템은 다음과 같이 간단히 표시 될 수 있다.

[eqn: dx/dt=Ax~]

(2-1식)

여기서, [eqn: x=x(t)~]는 □t(즉, time)"의 함수이다. 그리고, A는 □t"에 독립적인 행렬이다.

식(2-1)로 표현되는 시스템의 해(solution), x(t) ,를 구하라.

단, 계수 행렬 [eqn: A= BMATRIX { {0 }& {-6 }& {-1 }# {6 }& { 2}& { -16}# { -5}& {20 }& {-10 } }],      초기조건 [eqn: x(0)= BMATRIX { { 1}# { 1}# {1 } }]이라고 하자.

[풀이]

약간은 어려운 문제일지도 모른다. 하여튼, (2-1)식은 공업 수학 앞부분을 보면 쉽게 풀을 수 있다.

[eqn: x(t)=e^{t A} x(0)]

(2-2식)

식(2-2)식은 행렬 지수(matrix exponential)로 표현된다.

여기서, □expm(a)"함수는 행렬지수(matrix exponential)를 계산하여 반환하는 함수이다. (page. 26 참고)

□plot3"는 3차원 데이터를 그려주는 함수인데 여기서는 간단한 사용법만 알아보고 다음 단원에서 모든 그래픽을 자세히 알아보자.

전형적인 사용법(syntax) : plot3.m

□plot3(x,y,z,'linestyle')"

→"x, y, z"에 각각의 데이터를 넣는데, 같은 크기의 배열이어야 한다.

→□linestyle'에는 여러분이 원하는 선의 모양(style)과 색을 정하여	→지정한다.

이제, 시간 구간 [eqn: 0<= t <= 1] 사이에서 101점(point)을 취하여 해(solution), x(t),를 구하는 M-file을 작성하면 [그림 2-13]과 같다.

%이 프로그램은 [예제 3]에 대한 내용들이다.

close all

clear all

X=[];

X0=[1 1 1]';

A=[0 -6 -1;6 2 -16;-5 20 -10];

for t=0:.01:1

X=[X expm(t*A)*X0];

end

plot3(X(1,:),X(2,:),X(3,:),'-o')

grid on

[그림 2-13] □ex3_sys.m"에 대한 내용

이제, □ex3_sys.m"을 실행하여 보자!

[그림 2-14] □ex3_sys.m"을 실행 한 예

[그림 2-13]의 내용에서 맨 아랫줄에 있는 □grid on"은 [그림 2-14]에서처럼 격자(grid)를 첨가하라는 뜻이다.

라. while 문 :

전형적인 사용법(syntax) :

while 논리적인 조건

명령어 문장들

end

[그림 2-15] □while 문"의 기본 형태

논리적인 조건이 □참(TRUE)□이어야 명령어 문장을 실행한다. □while 문□에서의

□참일 조건□은 □if 문□에서의 □참일 조건□과 같으니 중복 설명은 하지 않겠다.

	Matlab에서도 C언어에 있는 □break"명령어가 있는 데, 기능은 서로 같다고 보아도 된다.

[예제 4] 100보다 작은 첫 번째 □n!"의 □n"을 구하라

[풀이]

역시, □prod.m"함수를 이용하자.

n=1;

while prod(1:n) < 100

n=n+1;

end

result=n-1

[그림 2-16] □ex4.m"에 대한 내용

M-file의 debugging 방법 :

Matlab4.2c이전 버전에서 debugging하는 과정은 command window에서 일일이 해당 debug명령어를 typing해야 했었다. 그러나, Matlab5.0이후 버전에서는

□Matlab editor/debugger"window에서 간편하게 수행할 수 있게 되었다.

우선, 간단한 예제 프로그램을 작성 한 후 시작 해본다.

[예제 5] 다음과 같은 식으로 표현되는 신호를 □sinc"신호라고 한다.

[eqn: y= pile{left{ &~~~~1,~~~~~~~~~~~~~t=0. # left{ &{sin(pi*t)} over {(pi*t)},~~~~~~~~t != 0}]

(2-3식)

여기서, □t"는 시간을 의미하는 데, 시간 구간은 [eqn: -2<= t<=2]이고, 샘플링 비율(sampling rate)은 1/1000이라고 한다. 결과를 그림으로 나타내어라!

(2-3식)의 결과를 그리기 위해서는 □plot.m"함수를 이용하여라.

전형적인 사용법(syntax) : plot.m

□plot(x,y,'linestyle')"

→"x, y"에 각각의 데이터를 넣는데, 같은 크기의 배열이어야 한다.

→□linestyle'에는 여러분이 원하는 선의 모양(style)과 색을 정하여	→지정한다.

[풀이]

□for 문"과 □if 문"을 적당히 사용하면 쉽게 coding할 수 있을 것이다.

파일 이름은 □msinc2.m"이라고 정하였다.

[그림 2-17]은 M-file의 내용을 보여주고 있다.

%SINC   sinc신호를 만들어 내는 M-file.

t=(-2:1/1000:2)';

for index=1:length(t);

if t(index)== 0

y(index)=1;

else

y(index)=sin(pi*t)/(pi*t(index));

end

end

plot(t,y)

[그림 2-17] □msinc2.m"함수의 내용

그런데, [그림 2-17]에는 잘못 작성한 부분이 있다. 물론, M-file을 자주 만들어 본  독자라면 쉽게 잘못 된 부분을 찾아 낼 수 있을 것이다. 그러나, 잘 못된 부분이 어딘지 잘 모르는 경우, debugging을 해 본다. 우선 그림 [2-18]과 같이 □Matlab Editor/debugger□ window에 있는 □set/clear breakpoint□ icon을 클릭하여, 의심

이 가는 부분에 □breakpoint□를 정한다.

[그림 2-18] □Editor/debugger"를 이용한 debugging 과정

□breakpoint"를 설정하였으면 command window에서 해당 M-file을 실행한다.

□msinc2 □

그러면, command window에 나타나는 Matlab prompt(즉, □□□)가 □k□□로 바뀔 것이다. 이제, □step in, single step, continue, quit debugging□과 같은 debugger 명령어를 이용하여 debugging을 해나가면 된다. Visual C++보다는 상당히 원시적인 방법이긴 하지만 그런데로 쓸만하다.

□single step□ icon을 이용하여, debugging을 계속해 나가다 보면, □Line 13□에서 □error□가 발생하는 것을 알 수 있을 것이다.

사실, □line 13□은 □y(index)=sin(pi*t(index))/(pi*t(index));□이 되어야 한다.

[그림 2-19]는 □msinc2.m"의 실행 결과를 보여 주고 있다.

[그림 2-19] □msinc2.m"의 실행 결과

M-file의 실행 속도 비교 :

Matlab에서는 가능한 한 반복 loop문들(즉, □while, for 문□)을 사용하지 않는 것이 좋다. 왜냐하면, Matlab은 다른 High-level 언어보다 반복 loop문장에서 속도가 상당히 떨어지기 때문이다. 만일, 여러분에게 [그림 2-17]의 □msinc2.m" 파일에서 반복 루프를 사용하지 말고 다시 작성 해보라고 하면 할 수 있겠는가? 만일, 쉽게 할 수 있다면 여러분은 이미 Matlab의 행렬연산에 대해 상당히 익숙해 졌다고 봐도 된다.

반복 루프를 사용하지 않고 배열만 사용하면, Matlab의 실행 속도는 반복 루프를 사용할 때보다 거의 10배 이상 더 빨라진다. 심지어 실행 파일(즉, *.exe 등등)보다도 더 빨라진다. [그림 2-20]은 [그림 2-17]의 반복 루프를 없앤 경우의 M-file로 실행 결과는 서로 같다. 파일 이름은 □msinc.m"이다.

%

%SINC   sinc신호를 만들어 내는 M-file.

%--->배열만 이용한 경우!

%1997.1.25        By Lim Jong_Su

t=(-2:1/1000:2)';

y=zeros(size(t));

t_pos=find(t==0);

t(t_pos)=[];

y(1:end-1)=sin(pi*t)./(pi*t);

y(t_pos+1:end)=y(t_pos:end-1);

t(t_pos+1:end+1)=t(t_pos:end);

t(t_pos)=0;

y(t_pos)=1;

plot(t,y)

[그림 2-20] □msinc.m"의 내용

[그림 2-20]의 내용이 쉽게 이해가 간다면, 과연, [그림 2-17]의 □msinc2.m"이

[그림 2-20]의 msinc.m"보다 얼마나 느린가 알아 볼 필요가 있다.

M-file의 실행 속도를 알아보려면 □profile.m"이라는 함수를 이용하면 된다.

전형적인 사용법(syntax) : profile.m

□profile 키워드"

→키워드가 "파일 이름"인 경우, profile을 가동할 준비를 한다.

→키워드가 □done"인 경우, profile의 기능을 정지시킨다.	→키워드가 □report"인 경우, 주어진 M-file의 각 라인에 대한	→속도를 요약한 정보를 보여 준다.

[그림 2-21]은 □msinc.m"에 대해 □profile.m"의 실행한 결과를 보여 주고 있다.

[그림 2-21] □msinc.m"에 대한 □profile.m"의 실행 결과

[그림 2-21]에서 알 수 있듯이 □msinc.m"의 실행 소요 시간은 □0.32초□이다. 또한, 각각의 라인마다 소요되는 시간을 □초□와 □백분율□로 나타내고 있다.

	[그림 2-21]에 나오는 소요 시간들은 사용하는 시스템에 따라 다르다.

[그림 2-22]는 □msinc2.m"에 대한 □profile.m"의 실행한 결과를 보여 주고 있다. 그림에서 알 수 있듯이 대부분의 시간이 반복 루프에서 소요되고 있다.

결국, 반복 루프를 사용하지 않는 것이 훨씬 능률적이라는 것을 알 수 있을 것이다.

Matlab을 더욱 효율적으로 사용하려면 최대한 반복 루프를 이용하지 않는 것이 좋다.

[그림 2-22] □msinc2.m"에 대한 □profile.m"의 실행 결과

서브 함수(subfunctions) : matlab5.0이후 버전에만 있음.

matlab5.0이후 버전부터는 다른 High_level언어에서처럼 서브함수(subfunctions)를 정의 할 수 있게 되었다. function mode M-files의 첫 번째 함수를 □primary function"이라 하고, 또한, primary function의 이름이 해당 M-files의 파일 이름이 된다. 그리고, primary function 안에 새롭게 정의된 함수들을 □subfunctions"라고 한다. subfunction은 해당 primary function안에서, 또는 같은 파일 안에 있는 subfunction에서만 참조가 가능하다.

각각의 subfunctions 또한, 자신만의 함수 정의 부를 소유 해야한다.

[예제 6] 벡터 in의 평균(average)과 중간 값(median value)을 구하는 함수를 작성하라.

[풀이] 이전에 벌써 평균을 구하는 coding은 충분히 배웠고, 또한, 여러분 실력으로 볼 때, 중간 값을 구하는 coding도 어렵지 않을 것이라고 본다.

[그림 2-23]은 해당 coding을 보여 주고 있다.

function [avg,med]=newstats(in)

%NEWSTATS  서브 함수를 이용하여 평균과 중간 값을 구하는 함수.

n=length(in);

avg=newmean(in,n);

med=newmedian(in,n);

%서브 함수들.

function a=newmean(in,n)

%평균을 계산 한다.

a=sum(in)/n;

function m=newmedian(v,n)

%중간 값을 계산한다.

w=sort(v);

if rem(n,2)==1

m=w((n+1)/2);

else

m=(w(n/2)+w(n/2+1))/2;

end

[그림 2-23] □newstats.m"파일의 내용

전역 변수(global) :

앞에서 설명하였듯이, M-files는 mode에 따라서 각각의 workspace를 가지고 있다. 즉, command prompt에서 사용되는 base workspace와 function mode에서 사용되는 function workspace가 있다. 또한, 임의의 mode에서 정의된 변수는 지역변수로써 해당 workspace에서만 참조가 가능하다. 그러나, 만일, 함수간에 또는, 서로 다른 workspace간에 데이터를 교환하기 위해서는 입·출력 매개변수를 이용하거나 본 절에서 설명할 전역 변수를 이용해야 한다.

전역 변수(global)를 사용하기 위해서는 해당 workspace에서 변수를 □global"로 선언하면 된다.

구체적으로 여러분의 M-files에서 전역 변수를 사용하는 방법은 다음과 같다.

function workspace간의 데이터 교환 시:

각각의 해당 function의 정의 부 아래에 □global 변수 이름들"의 형태로 전역 변수를 선언한다.

function workspace와 base workspace간의 데이터 교환 시 :

각각의 해당 function의 정의 부 아래에 □global 변수 이름들"의 형태로 전역 변수를 선언하고, command prompt에도 □global 변수 이름들"의 형태로 참조하고자 하는 변수를 전역 변수화 한다.

	대개의 전역 변수는 대문자로 쓰는 것이 통례인데, 이때, 함수의 이름은 대·소문자를 구별하지 않지만, 변수의 이름은 대·소문자를 구별한다는데 주의한다.

[예제 7] [그림 2-23]의 M-file을 전역 변수를 이용하여 다시 작성 해 보자!

[풀이]

[그림 2-24]는 해당 code를 보여 주고 있다.

	앞으로 여러분은 정적분을 계산할 때나 미분 방정식의 풀 때 전역 변수를 많이 이용하게 될 것이다.

function [avg,med]=newstats2(in)

%NEWSTATS  서브 함수를 이용하여 평균과 중간 값을 구하는 함수.

global n;

n=length(in);

avg=newmean(in);

med=newmedian(in);

%서브 함수들.

function a=newmean(in)

%평균을 계산 한다.

global n;

a=sum(in)/n;

function m=newmedian(v)

%중간 값을 계산한다.

global n;

w=sort(v);

if rem(n,2)==1

m=w((n+1)/2);

else

m=(w(n/2)+w(n/2+1))/2;

end

[그림 2-24] □newstats2.m"파일의 내용

입·출력 매개 변수의 갯수를 제어하는 □nargin, nargout"함수 :

function mode M-files에서 □nargin, nargout"함수들은 얼마나 많은 입·출력 매개변수가 사용되고 있는 지를 알려 준다. 결국, 여러분은 □nargin, nargout"함수들을 이용하여 입·출력 매개변수에 따라 다른 일을 수행할 수 있는 함수를 작성 할 수 있다.

	입·출력 매개 변수의 갯수를 임의로 설정하는 것을 가능하게 하는 □varargin, varargout"함수는 M-file programming II에서 다룰 것이다.

[예제 8] [그림 2-24]에서 주어진 □newstats2.m"파일을 출력 변수가 하나 일 때는 평균을 반환하고, 둘 일 때는 평균과 중간 값을 반환하는 함수로 고치시오.

[풀이]

function [avg,med]=newstats3(in)

%NEWSTATS  서브 함수를 이용하여 평균과 중간 값을 구하는 함수.

global n;

n=length(in);

if nargout ==1

avg=newmean(in);

else

avg=newmean(in);

med=newmedian(in);

end

%서브 함수들.

function a=newmean(in)

%평균을 계산 한다.

global n;

a=sum(in)/n;

function m=newmedian(v)

%중간 값을 계산한다.

global n;

w=sort(v);

if rem(n,2)==1

m=w((n+1)/2);

else

m=(w(n/2)+w(n/2+1))/2;

end

[그림 2-25] □newstats3.m"파일의 내용

[예제 9] 벡터 X와 벡터 H에 대한 컨버루션(convolution)을 구하는 함수를 작성해 보시오.

[풀이]

컨버루션은 신호 처리 분야뿐만 아니라, 공학에서 기본적으로 많이 이용되는 공식이다.  (식 2-1)은 컨버루션에 대한 공식이다.

[eqn: y(n)=sum_k=-inf^inf x(k) h(n-k)=sum_m-inf^inf h(m) x(n-m)~]

(2-1식)

만일, 시간 n에서, 벡터 X가 신호이고, 벡터 H가 시스템의 계수라고 하면 벡터 Y는 주어진 시스템의 응답이 된다. (식 2-1)에서 알 수 있듯이 컨버루션은 교환법칙이 적용된다. 이제, (식 2-1)을 반복 루프 없이, 작성 해 보자! 할 수 있겠는가?

아래에 필자가 작성한 code를 보지 말고 우선, 여러분이 작성을 해보고, 필자가 작성한 coding과 여러분이 작성한 coding의 속도를 앞에서 배운 □profile"함수로 비교해 보라!

물론, matlab이 지원하는 □conv.m"함수와 기능이 같아야 옳게 작성한 것이다.

전형적인 사용법(syntax) : conv.m

□c=conv(a,b)"

→벡터 a와 b의 컨버루션을 구한다.

→반환되는 출력 벡터 c의 길이, 즉, length(c)=length(a)+length(b)-1

function z=limconv(x,h)

%LIMCONV(X,H)    X와 H의 콘버루션(convolution)을 구하는 함수 이다.

len_h=length(h);

len_x=length(x);

len=2*len_h+len_x-1;

N=len-len_h;

inv_x=zeros(len-1,1);

inv_x(len_h:N)=x(end:-1:1);

for i=0:N-1;

z(i+1)=sum(inv_x(N-i:end-i).*h(:));

end

[그림 2-26] □limconv.m"파일의 내용

혹시, 여러분은 컨버루션 행렬(convolution matrix)라는 것을 들어 본적이 있는가?

matlab에서는 주어진 벡터의 컨버루션을 구하는데 두 가지 방법을 제공한다. 그 중한 가지가 앞에서 학습한 □conv.m"함수를 이용하는 것이고, 다른 하나는 □convmtx.m"함수로 컨버루션 행렬을 만들어 이용하는 것이다.

다음은 주어진 벡터 a와b에 대한 컨버루션을 구하는 방법을 비교한 것이다.

"conv.m"함수를 이용한 방법	"convmtx.m"함수를 이용한 방법
□x=1:3; □	□x=1:3; □
□y=2:4; □	□y=2:4; □
□c=conv(x,y); □	□n=length(x); □
	□c=x×convmtx(y,n); □

	□convmtx.m"함수를 이용하는 것보다는, □conv.m"함수를 이용하는 것이 더 능률적이다.

[예제 10] 주어진 벡터 X에 대해 출력 변수가 하나면 컨버루션 결과를 반환하고, 출력 변수가 두 개이면 컨버루션 결과와 공 분산(covariance)을 반환하는 함수를 작성하시오. 단, (식 2-2)는 공 분산을 구하는 공식이다.

[eqn: C_xy =Cov(x,y)=E left{[x-m_x ][y-m_y ]^* right} =E left {x y^* right} - m_x m_y^* ~]

(식 2-2)

여기서, E{X}는 벡터 X의 평균을 의미한다.

*는 해당 벡터의 복소 공액(complex conjugate)을 의미한다.

[풀이]

필자가 보기에는 (2-1식)을 해결한 독자라면 (2-2식)은 그리 어렵지 않을 것이라고 본다.

!참고 문헌:

아래에 열거한 참고 문헌은 매우 우수한 서적들이다.

전자공학을 공부하는 학생이라면 한 번쯤 볼만한 서적들이니 참고하기 바란다.

* 컨버루션 행렬 : □statistical digital signal processing and modeling" 1996년

저자: Monson H. Hayes,  출판사: John Wiley & Sons, Inc.

*공 분산(covariance) : "수리 통계학□1995년.

저자: 허 문열, 송 문섭,     출판사: 博英社

*컨버루션 공식:□Introduction to digital signal processing"1989년

저자: Johnny R. Johnson,    출판사:Prentice-Hall

[그림 2-27]은 필자가 나름대로 작성해 본 code이다. 여러분이 작성한 code와 비교해 보기 바란다. [그림 2-27]에 보여준 code는 너무 길어서 한 장에 표현이 안되므로 두 페이지에 걸쳐 제시했다.

function [con_mat,cov_mat]=concov(x,y,p)

%

%CONCOV   컨버루션 행렬과 공분산을 구하는 함수.

%

%1998.1.30   By Lim Jong_Su

%

if (nargin==3) & (nargout==1)

con_mat=convm(x,p);

elseif  (nargin==3) & (nargout==2)

con_mat=convm(x,p);

cov_mat=covariance(x,y);

else

error('입,출력 매개변수의 갯수가 맞지 않음!');

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%서브 함수들 :

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function y=convm(x,p)

%

%CONVM   컨버루션 행렬을 구하는 함수.

%

%1998.1.30   By Lim Jong_Su

%

N=length(x);

index=N+2*p-1;

y=zeros(N+p-1,p);

x=x(:);

xpad=[zeros(p-1,1);x;zeros(p-1,1)];

for i=1:p

y(:,i)=xpad(p-i+1:index-i);

end

y=y';

[그림 2-27] □concov.m"파일의 내용: 아래에 계속

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function z=covariance(x,y)

%

%COVARIANCE   주어진 두 벡터의 공분산을 구하는 함수.

%

%1998.1.30   By Lim Jong_Su

%

if length(x) ~= length(y)

error('입력 벡터들의 크기는 같아야 한다.');

end

x=[x(:) y(:)];

[n,p]=size(x);

x=x-repmat(sum(x)/n,n,1);

z=x'*x/(n-1);

[그림 2-27] □concov.m"파일의 내용

	matlab의 함수들 중에서 공 분산을 구하는 함수로는 □cov.m"함수가 있다. 또한, 컨버루션 행렬을 구하는 함수로는 □convmtx.m"함수가 있다. 그러므로, 여러분이 작성한 code는 이들, □cov.m, convmtx.m"과 기능이 같아야 옳게 작성한 것이다. [그림 2-27]에 있는 서브 함수들 중에서 covariance함수는 □cov.m"과 같은 기능을 하고, convm함수는 □convmtx.m"와 같은 기능을 한다.

	앞으로 내용 설명 도중에, 여러분에게 [문제]를 제시 할 것이다. 필자가 생각하건 데, 한 번쯤 여러분이 생각해야 하는 부분을 [문제]로 지정 한 것이다. 가능하면, 꼭! 자신이 해결해 보기 바란다.

다차원 배열(multidimensional array) : matlab5.0이후 버전에만 있음

기존의 Matlab4.2c이전 버전에서는 2차원 이하의 배열, 즉, 벡터와 행렬만이 연산 할 수 있는 대상이었다. 그러나, Matlab5.0이후 버전부터는 다차원 배열의 정의와 연산이 가능하게 되었다.

다차원 배열(multidimensional array)이란 2개이상의 차원을 가질 수 있는 배열로써, 기존에 여러분이 2차원 행렬에 대해 이용했던 방법을 그대로 다차원 배열에서도 이용할 수 있다. 게다가, Matlab은 다차원 배열을 만드는데 유용한 함수들을 제공한다. 그렇다면, 다차원 배열은 구체적으로 어디에 이용되는가?

2차원 데이터를 하나의 평면 또는 페이지(page)로 간주하고, 이들 페이지들로 이루어진 새로운 행렬에 대해 연산을 하고 싶은 경우

예 : 이미지(image) 처리 등등

다변수 또는 다차원 데이터를 이용해야 하는 항공역학이나, 온도 측정분야 따위.

예 : 비행 중에 있는 날개의 각 요소에서 발생하는 압력을 측정하는 경우, 움직이는 물체를 추적하는 경우 등등

다차원 배열을 구성하는 각각의 요소로는 수치(numeric), 문자(character), 셀(cell), 구조체(structure) 등등, Matlab이 지원하는 모든 종류(class)의 데이터 type들이 될 수 있다.

다차원 배열 :

Matlab에서의 다차원 배열은 일반적인 2차원 행렬에 대한 확장이다.

[그림 2-28] 2차원 행렬의 예

[그림 2-28]은 2차원 행렬을 보여 주는데, 임의의 원소를 참조하기 위해서는 2개의 첨자(subscript)가 필요하다.

첫 번째 첨자는 행에 대한 index를 표현하며, 두 번째 첨자는 열에 대한 index를 표현한다.

다차원 배열의 경우에는 더 많은 첨자를 이용한다. [그림 2-29]는 3차원 배열을 보여 주고 있다.

[그림 2-29] 3차원 행렬의 예

3차원 배열은 3개의 첨자를 이용한다.

첫 번째 첨자는 □차원(dimension) 1"인, 행(row)에 대한 index를 표현하며, 두 번째 첨자는 □차원(dimension) 2"인, 열(column)에 대한 index를 표현하고, 세 번째 첨자는 □차원(dimension) 3"인, page에 대한 index를 나타낸다.

만일, 여러분이 크기가 3×3×2인 배열A에서 page2의 2행 3열의 원소를 참조하고 싶다면, [그림 2-30]에서 알 수 있듯이, (2, 3, 2)로 indexing하면 된다.

[그림 2-30] 3차원 배열에서의 indexing방법

배열(array)에서 indexing의 의미 :

Matlab은 실제 데이터의 차원(즉, 벡터는 1차원, 행렬은 2차원 등등)에 관계없이 주어진 배열을 □열 벡터(column vector)"의 형태로 저장한다. 예를 들어서, Matlab은 다음과 같은 행렬 A를 실제로는 열 벡터 A의 형태로 저장한다.

□A=[2 6 9;4 2 8;3 0 1]; □

□[eqn: A= BMATRIX { { 2}&# {4 }&# { 3}&# { 6}&# { 2}&# { 0}&# { 9}&# { 8}&# { 1}& }]       %실제로 행렬 A가 저장되는 모양!

즉, 행렬 A의 2행 3열원소인 □8□을 참조하기 위해서는 이전에 설명하였듯이 □A(2,3)"와 같이 할 수도 있지만, □A(8)"로 해도 2행 3열 원소를 참조 할 수 있다. 즉, Matlab은 임의의 크기를 갖는 배열이 주어지면, 그 배열을 열 벡터 형태로 바꾸어 저장한다. 이 개념은 Matlab의 indexing에서 아주 중요한 개념이다. 또한, 이 개념은 다차원 배열에서도 그대로 적용된다.

만일, 여러분이 주어진 다차원 배열의 원소를 참조하기 위해 여러 개의 첨자들(subscripts)을 이용했다면, Matlab은 그 여러 개의 첨자를, 저장형태인 열 벡터에 대한 새로운 index를 계산한다. 여기서, 새로운 index는 주어진 다차원 배열에 할당된 배열의 크기에 기본을 두고 계산된다.

예를 들어서, 2차원 배열 A의 크기가 [d1 d2]로 주어졌다고 하자. 물론, d1은 배열 A의 행(row)의 수이고, d2는 배열 A의 열(column)의 수이다. 이제, 배열 A의 (i, j)원소를 참조하고 싶다고 하자. 그러면, Matlab은 우선 배열 A를 열 벡터로 저장하고, 배열 A의 (i, j) index는 새로운 index인 □(j-1)*d1 + i"로 바뀐 뒤, 실제로 저장된 열 벡터에서 □(j-1)*d1 + i"만큼 아래로 count하여 참조한다. 결국, □(j-1)*d1 + i = offset"의 개념이다.

앞에서 주어진 행렬A의 (2, 3)원소를 참조하기 위해서 Matlab은 우선, 열 벡터형태로 저장된 배열에 대해 □offset"을 계산하여, 그 수(즉, offset)만큼 아래로 count하여 참조한다. 즉, □(3-1)*3+2=8□, 그래서, A(2, 3)원소는 A(8)로도 참조 할 수 있게 되는 것이다.

[예제 11] 행렬 A=randn(3,4)에서 A(7)을 A(i, j)의 형태로 표현한다면, i, j의 값은 무엇이 되겠는가?

전형적인 사용법(syntax) : randn.m

□randn(m, n, p,...) or randn([m, n, p,...])"

→정규 분포된 난수 배열(normally distributed random array)을 생성.	→입력 변수 벡터로 배열의 크기 결정.

[풀이]

우선, A는 열 벡터의 형태로 저장되므로, offset을 계산해야 한다.

행의 크기 : 3(즉, d1=3), 열의 크기 : 4(즉, d2=4), 또한, 7/3의 나머지는 1이므로, i=1이 된다. 그러므로, (j-1)*d1+i=(j-1)*3+1=7, j=3이 된다. 결국, A(7)은 A(1, 3)과 같다.

□A=randn(3,4) □

A =

0.0000   -1.8740    0.7310    0.6771

-0.3179    0.4282    0.5779    0.5689

1.0950    0.8956    0.0403   -0.2556

□A(7) □

ans =

0.7310

□A(1,3) □

ans =

0.7310

다차원 배열의 생성 : indexing을 이용하는 방법

indexing을 이용하여 다차원 배열을 만들기 위해서는 먼저, 2차원 배열을 만들고, 그리고 나서, 그 2차원 배열을 확장한다. 예를 들어서, 2차원 배열 A가 다음과 같이 주어졌다고 하자.

□A=[5 7 8;0 1 9;4 3 6];□

행렬 A는 3×3행렬이다. 즉, 2차원 행렬이다. 이제, 이 행렬A에 세 번째 차원을 첨가해 보자.

□A(:,:,2)=[1 0 4;3 5 6;9 8 7] □

A(:,:,1) =

5     7     8

0     1     9

4     3     6

A(:,:,2) =

1     0     4

3     5     6

9     8     7

□size(A) □

ans =

3     3     2

결국, 원래 3×3인 행렬A가 3×3×2인 3차원 배열A가 되었다.

앞에서 배운 scalar expansion capabilities가 기억 나는가?

다차원 배열에서도 2차원 행렬에서처럼 scalar expansion capabilities가 이용 될 수 있다.

□A(:,:,3)=5; □

□A(:,:,3) □

ans =

5     5     5

5     5     5

5     5     5

그러므로, scalar expansion capabilities는 colon 연산자와 함께, 임의의 배열을 단일 값(single value)으로 채우는데 이용할 수 있다. 이제, 3차원 배열 A를 크기가 3×3×3×2인 4차원 배열A로 바꾸기 위해서는 어떻게 해야 하는지, 우선, 여러분이 생각해 보기 바란다.

앞에서, 2차원 행렬A를 3차원 배열A로 만들어 준 방법과 같은 방식으로 하면 된다. 즉,

□A(:,:,1,2)=[1 2 3;4 5 6;7 8 9];□

□A(:,:,2,2)=[9 8 7;6 5 4;3 2 1];□

□A(:,:,3,2)=[1 0 1;1 1 0;0 1 1];□

	indexing에 의한 방법으로 다차원 배열을 만드는 경우, 첨가해주는 배열의 크기는 전체적인 배열의 모양을 이룰 수 있어야 한다.

[예제 12] [그림 2-30]에서 주어진 배열A의 (2, 3, 2)원소를 A(i)의 형태로 참조하고자 한다. i의 값을 구하시오.

[풀이]

이번 예제는 [예제 11]에 대한 일반화이다.

	간혹, 여러분 중에서는 그냥, 첨자 배열, 즉, A(2,3,2)로 참조하면 되지, 구태여, 까다롭게 A(i)형태로 참조하는 방법을 알아서 무엇하는가? 하는 의문을 갖을지도 모른다. 그러나, 만일, 여러분이 matlab에서 만든 데이터가 아닌 외부데이터(즉, 실험치, 다른 High-level언어로 만든 데이터 따위)를 □fscanf.m"등과 같은 함수로 파일 읽기를 행한다면, 입력 형식을 어떻게 정하던 간에 모든 데이터는 열 벡터형태로 읽혀진다. 그때, 읽혀진 열 벡터를 다시 원하는 임의의 배열로 만들기 위해서는 지금 설명하는 방법을 알아야한다. 사실, 이 방법은 다른 어떠한, 언어(예: C, Pascal, Basic 등등)에서 다차원 배열을 정의 할 때도 유사하게 적용될 수 있는 방법이다.

우선, 배열A는 3차원 배열이므로 최상위 차원인 1차원 page 벡터부터 고려해야 한다.

현재, 참조하고자하는 page벡터의 원소(즉, (2,3,2)에서 세 번째 원소인 □2□)는 두 번째에 위치하므로 1을 빼준 값에 3*3을 곱해주어야 한다.

[문제1] 왜? 1을 빼주고 3*3을 해주어야 하는가?

그리고 한 단계 밑인 2차원 행렬에서 참조하고자하는 원소는 2행3열에 위치하므로 결국, i=(2-1)*3*3+(3-1)*3+2=17이 된다. 이제, 맞게 계산을 했는지, 확인해 보도록 하자.

□A=[1 0 3;4 -1 2;8 2 1];□

□A(:,:,2)=[6 8 3;4 3 6;5 9 2] □

A(:,:,1) =

1     0     3

4    -1     2

8     2     1

A(:,:,2) =

6     8     3

4     3     6

5     9     2

□A(2,3,2) □

ans =

6

□A(17) □

ans =

6

실행해본 결과, A(2,3,2)=A(17)이다. 그러므로, 옳게 계산 한 것이다.

이제, 여러분은 Matlab이 어떻게 데이터를 해당 workspace에 저장하는 지 알게 되었다.  또한, page의 개념도 알게 되었다.

일반적으로, 임의의 subscript(s1, s2, s3, ..... ,sn)에 대해, 크기가 [d1 d2 d3 .... dn]인 배열(즉, n차원의 배열)의 원소를 참조하기 위한 □offset 공식□은 다음과 같다.

[eqn: &(s_n - 1) (d_n-1 )(d_n-2 )~.....~(d_1 )+(s_n - 1) (d_n-2 )~.....~(d_1 )+~ # &.....~+(s_2 -1)(d_1 ) + s_1]

...................................................................................     (2-3식)

(2-3식)은 높은 차원에 대한 index를 먼저 계산하고 차례로 하위 index를 계산해 나가는 방식을 설명 해 주고 있다.

다차원 배열을 만들어 주는 함수 :

Matlab은 다차원 배열을 만드는 데, 유용한 함수들을 제공한다.

그 중에서 특히 앞으로 많이 사용 할, ones.m, zeros.m, rand.m, randn.m, repmat.m, cat.m, reshape.m을 간단히 알아보자.

전형적인 사용법(syntax) : ones.m

□ones(m, n, p,...) or ones([m, n, p,...])"

→모든 원소가 □1□로만 이루어진 배열이다.

→입력 변수에 따라서, 생성되는 배열의 크기는 m×n×p×....이 된다.

"zeros.m"함수는 □ones.m"과 같은 기능을 하는데, 단지, 모든 원소가 □0□으로만 구성된다.

□randn.m"함수가 정규 분포된 난수(normally distributed random number)를 발생하는 반면, □rand.m"함수는 균등하게 분포된 난수(uniformally distributed random number)를 발생하는 함수이다. 여러분도 알다시피, 난수에는 지수난수, 포아송 난수, 등 여러 가지 난수가 있다. 이들 난수는 신호 처리분야에서 잡음(noise)의 역할을 한다. Matlab의 toolbox 중에서 통계 toolbox에서는 난수를 분석하기 위한 많은 특수 함수들이 제공되며, 통신 toolbox에서는 simulink와 연결된 유용한 특수 함수가 제공된다. 필자의 생각으로는 양이 상당히 많지만, □통신□을 전공하는 분이라면 통신 toolbox를 한번쯤 공부하기를 권한다.

전형적인 사용법(syntax) : repmat.m

□B=repmat(A, [m, n, p,...])"

→블록 배열(block array)A로 구성된 배열 B를 생성한다.

→블록 배열A는 임의의 차원을 가질 수 있다.

→작은 배열을 큰 배열로 만들고 싶을 때 이용.

→유사한 기능을 가진 함수로는 □kron.m"함수가 있다.

사용 예 :

□a=[1 2;3 4] □

□b=repmat(a,[2,3]) □

b =

1     2     1     2     1     2

3     4     3     4     3     4

1     2     1     2     1     2

3     4     3     4     3     4

□c=kron(eye(2),a) □

c =

1     2     0     0

3     4     0     0

0     0     1     2

0     0     3     4

→즉, □kron.m"함수는 eye(2)의 각 원소에 배열 a를 곱한 것과 같다.

전형적인 사용법(syntax) : cat.m

□B=cat(dim, A1, A2, A3, ...)"

→배열A1, A2, A3, ...를 차원이 dim인 새로운 배열 B로 합성한다.

→cat(1, A, B)는 1차원 배열로 배열 A, B를 합성하므로

→ [A ; B]와 같다.

→cat(2, A, B)는 2차원 배열로 배열 A, B를 합성하므로

→ [A  B]와 같다.

사용 예 :

□a=[1 2;3 4] □

□b=[5 6;7 8] □

□c=cat(3, a, b) □

c(:,:,1) =

1     2

3     4

c(:,:,2) =

5     6

7     8

□d=size(c) □

d =

2     2     2

→결국, □cat.m"함수는 배열 a와 b를 합성하여 3차원 배열을 만들었다.

만일, 주어진 배열 A의 원소는 그대로 보존하면서 크기나 배열 형태를 바꾸고 싶다면 □reshape.m"함수를 이용하라! 필자가 생각하기에 무척 유용한 함수이다.

예를 들어서, 크기가 3×5×2인 3차원 배열 M이 있다고 하자, 이 3차원 배열을 크기가 6×5인 2차원 행렬의 형태로 바꾸고 싶다면 [그림 2-31]에서 보여준 것처럼, □reshape(M,[6 5])"하면 된다.

[그림 2-31] □reshape.m"함수의 이용 예

여기서, 중요한 것은 reshape된 배열의 원소의 수는 원래 배열의 원소의 수와 같아야 한다는 것이다.

[그림 2-31]에서 알 수 있듯이, "reshape.m"함수는 각각의 page에 대해 열 벡터방향으로 원소를 추출한다.

전형적인 사용법(syntax) : reshape.m

□B=reshape(A, m, n, p,...) or B=reshape(A, [m, n, p,...])"

→임의의 배열A를 차원이 m, n, p, ...인 새로운 배열 B로 재배치한다.

[예제 13] 다차원 배열에 대한 좋은 예제로 RGB image처리를 들 수 있다. Matlab은 하나의 RGB image에 대한 데이터를 [그림 2-32]에서 보여준 것처럼 3차원 배열에 저장한다.

[그림 2-32] RGB image 데이터

[그림 2-32]에서 CData란 각각의 pixel에 주어진 색채의 농도를 말한다.

Matlab은 여러분이 image를 공부하는데 유용한 여러 가지 image 데이터를 제공하고 있다. 그 중에서 □ngc6543a.jpg"그림을 예로 들어보겠다.

본 예제에서 □imread.m"과 □image.m"라는 함수를 이용할 것인데, 이 함수에 대한 구체적인 내용은 다음 단원인 □Matlab graphic"에서 다루겠다. 두 함수에 대해 간단히 요약 해보자.

전형적인 사용법(syntax) : imread.m

□B=reshape(파일이름.확장자)□

→파일에 있는 image데이터를 일어서 배열 B에 저장한다.

전형적인 사용법(syntax) : image.m

□image(image 데이터 C)□

→image 데이터인 배열 C를 screen에 image로 합성하여 보여준다.

□RGB=imread('ngc6543a.jpg'); □

□image(RGB)□

[그림 2-33] □ngc6543a.jpg"의 모습

□size(RGB) □

ans =

650   600     3

결국, [그림 2-33]을 표현하는 데이터 RGB는 [그림 2-32]에서 나타낸 것처럼 3차원 배열인 것을 알 수 있다.

문자열(string) :

문자열의 정의 :

문자열(text strings)은 단일 인용부호(single quotes □, □)로 둘러싸여 표현된다.

	C언어에서는 문자열을 표현하기 위해 이중 인용부호(double quotes □, □)가 사용된다는데 주의!

예를 들어보면,

□s='Hello' □

s =

Hello

결국, 변수 s에 문자열 □Hello"가 저장된다.

이제, 문자열이 어떻게 변수에 저장되는지 알아보기 위해 변수의 크기를 알려주는 □size.m"함수를 이용해보자.

□len_s=size(s) □

len_s =

1     5

변수 len_s로부터 여러분은 matlab이 문자열을 행 벡터방향으로 저장한다는 것을 알 수 있을 것이다. 또한, 배열 len_s의 원소가 5개인 사실로부터 문자 하나 하나가 배열의 원소가 된다는 것도 알 수 있을 것이다.

matlab은 문자들을 해당하는 ASCII 값으로 바꾸어서 저장한다.

이 사실을 알아보기 위해, 입력 변수 값을 double형으로 바꾸어주는 □double.m"함수를 이용하자. 물론, 입력 변수 값을 char형으로 바꾸어주는 함수로는 □char.m"이 있다.

	M-file programming II에서 여러분은 원하는 특성을 가진 새로운 데이터 타입을 정의하는 방법을 배우게 될 것이다. 이와 같은 새로운 data type을 user_defined data type이라고 하는데, □symbolic math.□에서 연산 대상이 새로운 데이터 타입인 □symbol□인 것을 예로 들 수 있다.

□s_val=double(s) □

s_val =

72   101   108   108   111

배열 s_val는 각각의 문자에 해당하는 ASCII 값을 얻었다.

보통, matlab에서 표현할 수 있는 ASCII 문자들은 (32:127)10범위에 있는 것들이다. 결국, 96개의 문자를 표현 할 수 있다.

[예제 14] matlab이 표현할 수 있는 96개의 문자를 3×32행렬로 나타내시오.

[풀이]

ASCII code값 32:127, 즉, 96개의 원소를 3×32행렬로 나타내기 위해 앞에서 배운 □reshape.m"함수를 이용한다.

□F=reshape(32:127,32,3)'; □

□ascii=char(F) □

ascii =

!"#$%&'()*+,-./0123456789:;<=>?

@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_

`abcdefghijklmnopqrstuvwxyz{|}~

	matlab command window의 toolbar에 있는 File메뉴에서 Preferences를 선택하면 [그림 2-34]와 같은 window가 생성 될 것이다. General part에 있는 numeric format은 지금 사용되고 있는 format을 조정할 수 있게 해준다. 또한, matlab이 제공하는 □editor"외에 다른 □editor"를 사용할 수 있도록 option을 제공한다. Command Window Font part를 click하면 현재 사용하고 있는 font를 조정할 수 있게 해준다. 그러나, 여기서 설정하는 font는 모든 command window문자들에게 영향을 주므로 특수문자나 symbol을 일정 부분에서만 이용하기에는 부적절하다. Copying Options part에서는 clipboard format을 설정하게 해준다.

[그림 2-34] □Preference"의 사용 예

그렇다면, 수학 기호 또는, 그리스 문자는 표현할 수 없는가?

물론, 표현 할 수 있다. 여러 특수 문자와 심볼(symbol)들을 모두 표현 할 수 있는데, 사용 방법이 조금 다르다. 이것은 다음 단원(3. matlab graphics)에서 자세히 다루겠다.

문자열의 합성 :

주어진 여러 개의 문자열을 합성하는 경우, □square brackets(즉, [ ])□를 이용한다.

□x='seoul' □

□y='korea' □

□z=[x y] □

z =

seoulkorea

행 벡터 z에는 seoulkorea가 할당되는데, seoul과 korea에서 한 칸 띄우려면,  seoul문자열 다음에 spacebar를 넣으면 된다. 즉,

□x='seoul ' □   %문자열 □seoul□다음에 한 칸(spacebar) 띄우고 있다.

%여기서, spacebar(ASCII code 값:32)도 문자라는데 주의한다.

□z=[x y] □

z =

seoul korea

그런데, 만일, □□z=[x ; y] □□하면 어떻게 되겠는가?

□z=[x;y] □

???  All rows in the bracketed expression must have the same

number of columns.

□error□가 발생한다. error 메시지를 보면, 행렬을 이루는 각 행의 열의 수가 틀리다는 것이다. 즉, 변수 □x□의 원소는 6개인데, □y□는 5개로 행렬의 모양을 이루지 못한다. 그러므로, 여러 개의 문자열을 합하여 행렬을 이루려면 각 행의 원소의 수가 같도록 spacebar로 맞추어 주어야 한다.

□x='seoul '; □  %len_x=length(x)는 □6□이다.

%즉, 변수 □x"는 6개의 원소를 갖는다.

□y='korea '; □  %len_y=length(y)는 □6□으로, spacebar를 첨가하였다.

%이제, 두 변수 x, y가 같은 길이를 가지므로

%행렬을 이룰 수가 있다.

□z=[x ; y]  □   %z=['seoul ' ; 'korea ']와 같은 표현이다.

z =

seoul

korea

그러나, 이렇게 매번 spacebar로 문자열의 길이를 맞추어 주는 것은 어려운 일이다. 그래서, 문자열을 되돌려 주는 함수□char.m"을 사용한다. 이 함수는 각각의 행을 이루는 문자열의 길이가 같도록 spacebar를 자동 첨가 시켜준다.

□a='apple'; □

□b='orange'; □

□c='bananas'; □

□abc=char(a,b,c); □

abc =

apple

orange

bananas

이밖에도 cell, struct를 사용하는 방법도 많이 사용되는데, M-file programming.II에서 다루고자 한다.

문자열로 표현된 수식의 연산 :

여기서 배울 □eval.m"함수와 "feval.m"함수는 나중에 여러분이 grahical user interface(GUI)용 프로그램을 작성하기 위하여 uicontrol과 uimenu를 사용하는 경우, 꼭 필요한 함수들이므로 특별히 잘 알아두기 바란다. 그래서, 여러 가지 예제를 다룰 것이다. 만일, 여러분이 GUI를 이용한 프로그램을 만들고 싶다면, 앞으로 제시할 예제들은 상당히 유용하게 사용 될 것이다.

현재 저의 홈페이지에서 제공하는 □lim97b.m(ver4.2c용)"함수는 사용자가 임의로 제공하는 수식 열을 그대로 실행할 수 있는데, 소스를 보면, "eval.m"함수가 있을 것이다. 이 함수가 주어진 수식 열(문자열)을 연산하는 부분이다.

eval.m 함수 :

□matlab의 수식, 문장, 함수 호출(function call)□을 포함하는 문자열(string)을 계산한다.

전형적인 사용법(syntax) : eval.m

(1) a=eval('수식□)

→주어진 수식을 계산한 결과를 반환한다.

(2) [a1, a2, a3 ... ]=eval('수식□) 또는,

eval('[a1, a2, a3 ... ]=수식□)

→주어진 수식의 결과 값이 여러 개 일 때,

→출력 변수 a1, a2, ... 에 순서대로 반환한다.

(3) [a1, a2, a3 ... ]=eval('수식', '두 번째 수식')

→만일, 주어진 수식에 문제가 없어서 잘 계산되면

→그 결과 값을 출력 변수 a1, a2, ... 에 순서대로 반환한다.

→ 만일, 주어진 수식에 문제가 있는 경우, 두 번째 수식을 계산하여

→ 그 결과 값을 출력 변수 a1, a2, ... 에 순서대로 반환한다.

우선, 각각의 경우에 대한 간단한 예제부터 다루어 본다.

□X=2+sin(90*pi/180); □     %matlab은 모든 각도를 radians로 표현한다.

%현재, 각도를 degree 단위로 바꾸었다.

□Y=3+log10(100); □        %"log10.m"은 상용 로그이고,

%□log.m"은 자연 로그이다.

□Z=eval('X+Y') □

Z =

8

문자열(수식열) □X+Y□를 □eval.m□함수가 계산하여, 그 결과를 변수 Z에 반환하고 있다.

□[row, col]=eval('size(rand(2,3))') □  %출력 변수가 한 개 이상인 경우.

row =

2

col =

3

□A=1:3; □

□B=2:4; □

□Z=eval('A*B', 'A.*B') □ %'A*B'는 연산이 안 되므로, □A.*B'를 연산하고 있다.

Z =

2     6    12

[예제 15] matlab은 파형을 발생시켜주는 여러 가지 함수를 가지고 있다. 이들 파형 발생 함수들은 대부분 시간 벡터를 필요로 한다. 예를 들어서, 1000[Hz] sampling frequency를 갖는 데이터를 만들기 위해서는, 우선 다음과 같은 시간 벡터(time vector)를 먼저 만들어야 한다.

□t=(0:0.001:1)'; □

벡터 □t□는 모두 1001개의 원소로 이루어진 열 벡터인데, 시간 구간은

0 ∼ 1[sec]까지 1[msec]단위로 증가하는 경우에 해당한다.

[문제 ]

왜? 벡터 □t□를 열 벡터로 표현했는가? 이 문제는 matlab을 이용하여 신호처리를 하는 경우 아주 중요한 문제이다.

이제, 주어진 시간 벡터 □t□로 50[Hz]와 120[Hz]를 가진 2개의 정현파를 만들어 보자

□y=sin(2*pi*50*t)+2*sin(2*pi*120*t); □

새로 만들어진 벡터 □y□도 1001개의 원소로 이루어진 열 벡터이다. 이제, 신호 벡터 □y□에 통신에서 많이 이용되는 AWGN(additive white Gaussian noise)을 섞어보자.

	AWGN(additive white Gaussian noise)에 대해서는 □Bernard Sklar□가 쓴 □Digital Communications Fundamentals and Applications□의 page29 ∼ 30 을 참고하기 바란다. 출판사는 □Prentice_Hall□이다.

□yn=y+0.5*randn(size(t)); □  %□randn.m□함수에 대해서는 앞에서 설명하였다.

잡음이 섞인 열 벡터 □yn□의 원소 중에서 처음 50개만, □plot.m□함수로 도시하여 보자.

전형적인 사용법(syntax) : plot.m

□plot(x,y,'linestyle')"

→"x, y"에 각각의 데이터를 넣는데, 같은 크기의 배열이어야 한다.

→□linestyle'에는 여러분이 원하는 선의 모양(style)과 색을 정하여	→지정한다.

□plot(t(1:50),yn(1:50)) □

□xlabel('time[msec]') □

□ylabel('진폭') □

□title([□주파수가 □ □50□ □ ,□ □120□ □인 경우!□]) □

□title.m□함수의 입력으로는 모두 5개의 문자와 문자열이 square bracket(즉, [ ])로 합성되어 하나의 행 벡터로 되었다.

전형적인 사용법(syntax) : xlabel('문자열')

□xlabel('문자열').m"

→임의의 모양으로 그려진 그래프에 주어진 □문자열□을

→ □x□축 라벨로 첨가한다.

마찬가지로,  □ylabel('문자열').m□함수는 주어진 □문자열□을 □y□축 라벨로 첨가한다.

전형적인 사용법(syntax) : title('문자열')

□title('문자열').m"

→임의의 모양으로 그려진 그래프에 주어진 □문자열□을

→ □title□로 첨가한다.

[그림 2-35]는 결과를 나타내주고 있다.

[그림 2-35] [예제 15]의 실행 결과

[그림 2-36]은 [예제 15]의 내용을 정리한 M-file이다.

파일 이름은 □ex2_15.m□이라고 하였다.

clear all

close all

t=(0:.001:1)';    %시간 벡터 t.

f1=50;              %주파수 벡터 f1, f2

f2=120;

y=sin(2*pi*f1*t)+2*sin(2*pi*f2*t);

yn=y+0.5*randn(size(t));

plot(t(1:50),yn(1:50))

xlabel('time[msec]');

ylabel('진폭');

title(['주파수가 ' '50' ' ,' '120' '인 경우!'])

[그림 2-36] □ex2_15.m□파일의 내용

[예제 16] 이번 예제에서는 [예제 15]에서 알아본 내용 중, 변수 □y□를 계산하는 과정을 바꾸어 보고자 한다.

[그림 2-36]에 주어진 □ex2_15.m□파일에서 나타나는 수식 가운데

□y=sin(2*pi*f1*t)+2*sin(2*pi*f2*t);□을 문자열로 변환하여 □eval.m□함수로 계산할 것이다. 아주 간단한 기법이다. 그러나, 이 기법은 앞으로 여러분이 GUI프로그램을 작성 할 때 자주 이용하게 될 것이다.

우선, □num2str.m□함수와 □str2num.m□함수에 대해서 알아 둘 필요가 있다. 아주 중요한 함수들이므로 상세하게 설명하였다.

전형적인 사용법(syntax) : num2str.m

(1) str = num2str(A)

→배열 A를 문자열(string)로 변환 한 뒤 출력 변수 str에 반환한다.

→이 함수는 labeling 또는 titling을 할 때 유용하다.

(2) str = num2str(A, 정밀도(precision))

→배열 A를 문자열(string)로 변환 할 때, 주어진 정밀도에 따라

→출력 변수 str에 반환한다.

→default는 4개의 숫자로 표현하는 것이다.

(2) str = num2str(A, 형식(format))

→배열 A를 문자열(string)로 변환 할 때, 주어진 형식에 따라

→출력 변수 str에 반환한다.

→default는 □%11.4g"로 숫자를 표현하는 것인데,

→ 좀더 자세한 사항은 □파일 입·출력□ 단원에서 다루겠다.

전형적인 사용법(syntax) : str2num.m

"A = str2num('str')"

→문자열(string) str을 matlab의 수치 표현으로 바꾼다.

→문자열 str은 수치(numeric)를 표현하는 것이어야 한다.

주어진 수식"y=sin(2*pi*f1*t)+2*sin(2*pi*f2*t);"에서 변수 f1, f2 그리고, 배열 t는 수식 이전에 정의되었다. 그러므로, 수식"y=sin(2*pi*f1*t)+2*sin(2*pi*f2*t);"을 문자열로 나타내면 □eval.m□함수로 계산 할 수 있다. 앞에서 이미, 배웠듯이, 문자열로 나타내려면 단일 인용부호를 좌우에 붙여주기만 하면 된다. 그리고, 변환된 문자열을 □eval.m□함수에 입력 변수로 넣어 주기만 하면 계산이 되는 것이다. 즉,

□y=eval('sin(2*pi*f1*t)+2*sin(2*pi*f2*t)'); □

이제, 여러분은 □ex2_15.m□파일의 내용 중에서, 문자열을 이용하여 □y□를 계산하도록 프로그램을 바꿀 수 있게 되었다. 또한, □title.m□함수의 입력부에 앞에서 설명한 □num2str.m□함수를 이용해 보자.

[그림 2-37]은 필자가 작성해 본 프로그램이다. 쉽게 이해하리라 본다.

파일이름은 □ex2_16.m□이라고 하였다.

%[예제 2-16]의 내용을 정리 한 M-file.

clear all

close all

t=(0:.001:1)';    %시간 벡터 t.

f1=50;              %주파수 벡터 f1, f2

f2=120;

y=eval('sin(2*pi*f1*t)+2*sin(2*pi*f2*t)');

yn=y+0.5*randn(size(t));

plot(t(1:50),yn(1:50))

xlabel('time[msec]');

ylabel('진폭');

title(['주파수가 ' num2str(f1) ' , ' num2str(f2) ' 인 경우!']);

[그림 2-37] □ex2_16.m"파일의 내용

[예제 17] 간단한 예제를 하나 더 들어보았다. 이번 예제에서는 3개의 magic 행렬을 만드는 것이다.

%이름이 M1 부터 M3인 magic 행렬을 만다.

for n=1:3	%1번 line

eval(['M' int2str(n) '=magic(n)'])	%2번 line

end

[그림 2-35] □ex2_15.m"파일의 내용

주어진 M-file에서 2번 라인을 잘 관찰해보자.

"eval(['M' int2str(n) '=magic(n)'])"

2번 라인에서, □M'이라는 문자, 수치 n이 문자열로 변환된 문자, 그리고, 문자열 '=magic(n)', 이렇게 3개의 문자와 문자열이 하나의 문자열(행 벡터)로 합성(square brackets, □[ ]□에 의해서)된 것을 알 수 있다. 결국, 합성된 문자열이 문자열 연산 함수 □eval.m□에 의해 계산된다.

"n=1"인 경우, □eval.m□함수는 □M1=magic(1)□을 계산한다. 결국, 출력 변수 M1에 magic(1)의 값이 할당된다. 이런 방식으로 M3까지 계산한다. 여기서는, □eval.m□함수의 출력 변수들(M1 ∼ M3)이 입력 변수로 주어지고 있다. 또한, semicolon(즉, ; )이 없으므로 출력 값이 그대로 화면에 출력된다. 결과를 살펴보자.

□ex2_15 □

M1 =

1

M2 =

1     3

4     2

M3 =

8     1     6

3     5     7

4     9     2

이제, 여러분은 대충, □eval.m□함수의 사용방법과 문자열(string)의 개념을 잡을 수 있을 것이다.

□t=-2*pi:1/100:2*pi; □

□y='sin(t)*cos(t)'; □

□z=eval(y); □

결과는 어떻게 되겠는가?

쉽게 알 수 있듯이,  □sin(t)*cos(t)□는 둘 다 행 벡터로 벡터 곱을 행할 수 없는 경우이다. 즉, error가 발생한다. 그러나, □sin(t)*cos(t)□를 원소 대 원소의 곱(즉, □.*□)으로 바꾸어주면 계산이 가능해 진다.

□y='sin(t) .* cos(t)'; □

□z=eval(y); □

이처럼, 문자열로 표현된 수식을 계산하는 경우, 대부분 배열 연산보다는 원소 대 원소연산을 행하는 경우가 많다. 예를 들어서, 필자가 제작한 □lim97b.m□에 수식을 쓸 때도 원소 대 원소연산을 행하는 경우가 많다.

앞에서 이미 원소 대 원소연산에 대해서는 충분히 설명하였지만, 다시 간단히 [표2-3]에 그 종류를 나열하였다.

[표 2 - 3] 원소 대 원소연산들

원소 대 원소연산	각 연산에 대한 설명
. *	원소 대 원소의 곱
. /	원소 대 원소의 나눗셈
. \	원소 대 원소의 왼쪽 나눗셈
. ^	원소 대 원소의 멱승(power)

matlab5.0이후 버전에서는 이런 원소 대 원소연산 시 발생하는 □.□문제를 해결하기 위해 □vectorize.m□함수를 제공하고 있다. 그 사용 예를 알아보자.

□exp='x*y+y/z^3'; □	%만일, x, y, z가 모두 행 벡터이면,

%당연히, 연산이 되지 않는다.

□exp_s=vectorize(exp) □

exp_s =

x.*y+y./z.^3

결국, □vectorize.m□함수는 입력 문자열을 원소 대 원소연산으로 바꾸어 주어서 3개의 입력 벡터의 크기만 같으면, 원소 대 원소 연산을 할 수 있게 자동으로 □.□을 적절하게 첨가시켜 준다.

□x=1:4; □

□y=2:5; □

□exp='x*y'; □

□result=eval(exp) □	%2개의 벡터가 모두 행 벡터이므로 곱셈이 안됨.

??? Error using ==> *

Inner matrix dimensions must agree.

□result_v=eval(vectorize(exp)) □

result_v =

2     6    12    20

feval.m 함수 :

만일, 여러분이 어떠한, 함수, 즉, y=fun(x1, x2)의 기능을 하는 □fun.m□함수를 만들었다고 하자. 이 함수를 실행하는 방법은 많이 있겠지만, 여기서는 자주 사용되고 있는 2가지 방법을 보여주겠다.

□x1=a; x2=b; □

(a)□y=fun(x1, x2);  □	%지금까지 사용하여 온 방법!

(b)□y=feval('fun', x1, x2);  □

전형적인 사용법(syntax) : feval.m

"[y1, y2, ... ]=feval('함수 이름□, x1, ... xn)"

→주어진 함수의 입력 변수 값들(즉, x1, ... xn)로 함수를 계산하여,

→그 결과 값을 순서대로 출력 변수들(즉, y1, y2, ... )에게 반환한다.

라. M-file 작성 시 유용한 함수들 :

이제, M-file작성 시 유용한 몇 가지 함수들을 알아보고, M-file programming.I을 끝내고자 한다.

input 함수 :

전형적인 사용법(syntax) : input.m

(a) "R=input('prompt', 's')"

→"input.m"함수는 실행 시, □prompt' string이 나오고,

→사용자가 문자열을 입력할 때까지 기다린다.

→사용자가 문자열을 입력하면, 그 입력된 문자열은

→출력 변수 R에 반환된다.

→단, 문자열이 수식을 표현하는 경우 계산되지 않는다.

(b) "R=input('prompt')"

→"input.m"함수는 실행 시, □prompt' string이 나오고,

→사용자가 수식이나 변수이름을 입력할 때까지 기다린다.

→입력된 것이 수식인 경우에는 base workspace에 있는 변수들에

→기반을 두고 계산하여 그 결과 값을 출력 변수 R에 반환한다.

사용 예 :

□x=2; y=3; □

□R=input('아무 문자나 입력하시오! ','s') □

아무 문자나 입력하시오! test

R =

test

□R=input('가능 한한 변수 이름이나 수식을 입력하시오! ') □

가능 한한 변수이름이나 수식을 입력하시오! x+y

R =

5

특별히,  "input.m"함수는 입력 변수가 한 개인 경우, 즉, □R=input('prompt')□인 경우, □prompt□다음에는 임의의 M-files를 포함한 수식이 나올 수 있고, 그 계산 결과를 반환한다. 만일, 여러 개의 결과 값을 반환하는 M-files가 □prompt□다음에 사용되는 경우, □input.m□함수는 해당하는 여러 개의 결과 값을 반환한다. 이 기능은 □R=input('prompt', 's')□의 형태(format)에서는 적용되지 않는다 데 주의하라!

[예제 18]

주어진 임의의 수치집합(numeric set)에서 어떠한 원소(또는, 사건(event))가 발생한 각각의 횟수와 발생 비율을 백분율로 [그림 2-39]와 같이 나타내는 함수를 작성해 보자.

주어진 임의의 집합 T=[2 0 7 7 9 4 5 8 0 1 5 7 0 4 1 4 7 6 9 8]이라고 하자.

[그림 2-39] [예제 18]의 실행 결과

[그림 2-39]의 실행 결과로부터 여러분은 이전에 배운 □disp.m□함수를 사용해야 된다는 것을 알 수 있을 것이다.  또한, 각각의 수치를 오름차순(ascending order)으로 정렬하는 함수가 필요하다. 물론,  여러분이 직접 데이터를 정렬하는 함수를 말들 수도 있겠지만. matlab에서는 □sort.m□라는 데이터 정렬 함수가 있다.  그 사용법은 다음과 같다.

전형적인 사용방법(syntax) : sort.m

(a)□Y=sort(X)□

→벡터 X를 오름차순(ascending order)으로 정렬하여 반환한다.

(b)□[Y, I]=sort(X)□

→벡터 X를 오름차순(ascending order)으로 정렬하여 반환하고,

→각각의 원소가 벡터 X에서 위치하는 곳을 출력 변수 I에 반환한다.

사용 예 :

X=[2 4 3 1]; □

[Y, I]=sort(X) □

Y =

1     2     3     4  %벡터 X의 오름차순 정렬

I =

4     1     3     2   %벡터 X에서의 원래 위치

그러나, 만일, X가 행렬인 경우, 각각의 열(column)에 대해서 오름차순으로 정렬하고, 출력 변수가 두 개인 경우, 행렬 X안에 있는, 각각의 열에 대한 원래의 위치를 반환한다. 이제, [예제 18]을 수행하는 M-file을 작성할 모든 준비가 되었다.

여러 가지 방법이 있겠지만, 필자는 우선 벡터 T를 입력 변수로 하고, 오름차순으로 정렬된 벡터와 각각의 발생 횟수를 출력 변수로 하는 함수(function mode M-file)와 [그림 2-39]와 같은 형태(format)로 출력하는 M-file(script mode M-file), 이렇게 두 개의 M-file을 만들어서 해결 할 생각이다.

	script mode M-file과 function mode M-file은 같은 이름의 M-file안에 동시에 존재 할 수 없다.

우선, function mode M-file의 내용은 [그림 2-40a]과 같다.

파일 이름은 □csort.m□이다.

function d = csort(T)

%

%CSORT       벡터 T에 대한 발생 횟수와 중복이 없는 수치를 정렬하여 반환한다.

%

T=T(:)';

P=ones(size(T));

D = [T;P];

[Y,I] = sort(T);

X = D(:,I);

m = length(T);

TI = X(1,:);

PI = X(2,:);

j = 1;

t(1) = TI(1);

p(1) = PI(1);

for i = 1:(m - 1)

if abs(TI(i) - TI(i+1)) < 1e-6    %두 원소의 차가 1e-6보다 작으면

j = j;	%같다고 본다.

p(j) =  p(j) + PI(i+1);

else

j = j+1;

t(j) = TI(i+1);

p(j) = PI(i+1);

end

end

d = [t;p];

[그림 2-40a] □csort.m□함수의 내용

그렇게 어려운 내용은 아니지만, 위에서 13번째 줄, 즉, □X = D(:,I);□은 page20 맨 아래에 설명된 내용을 참고하면 쉽게 이해가 될 것이다. 꽤 유용한 기법이니 잘 알아두자.

[그림 2-40b]는 □csort.m□함수로부터 얻은 결과를 [그림 2-39]와 같이 screen에 표시 해주는 script mode M-file이다.

파일 이름은 □freq.m□이다. 여기서는 특별히 □disp.m□함수의 사용법에 주목하자.

%

%FREQ     함수 csort.m에의해 반환된 행 벡터에대해 목록을 list한다.

%!주의 : csort.m함수를 필요로 한다.

%

T = input('List 될 행 벡터를 입력 하시요! :');

n = length(T);

H = csort(T)';

A = [H H(:,2)/n];

disp(' ')	%한 줄 띄우기!

disp(['List안에 있는 원소의 수 :  ',num2str(n)] )

disp(' ')

disp('각각의 수치  발생 횟수 발생 비율')

disp(A)

[그림 2-40b] □freq.m□ script mode M-file의 내용

□menu.m□ 함수 :

전형적인 사용법(syntax) : menu.m

"R=input('menu title', '선택1','선택2', ... ,'선택3')"

→주어진 'menu title'을 가진 menu window를 생성한다.

→선택1, ... ,선택2 항목은 각각 □push" 버튼의 label로 나타난다.

→임의의 □push"버튼을 click하면 해당하는

→선택n의 번호를 반환한다.

[예제 19]

배열 □t=-2*pi:1/100:2*pi□이고, □y=sin(t)□일 때, □menu.m□함수를 이용하여 선의 색을 □red, green, blue□중에서 하나를 선택할 수 있게 하고, □plot.m□함수로 도시(plot) 할 수 있도록 작성하라.

또한, 문자 □y□가 입력되면 실행이 중단 되도록 작성하라.

[풀이]

앞에서 배운 □input.m□함수와 □break.m□함수를 이용하여 코딩하였다.

[그림 2-41]은 주어진 예제를 수행하는 M-file의 내용이다.

함수의 이름은 □ex2_16.m□이라고 하였다.

□lower.m□함수는 입력된 문자를 소문자로 변환하여 반환한다.

□upper.m□함수는 입력된 문자를 대문자로 변환하여 반환한다.

%

%이 예제는 menu.m함수 사용법을 설명하기 위한 것이다.

%

line_color=['r','g','b'];

str='y';

t=-2*pi:1/100:2*pi;

y=sin(t);

while(1)

if str=='y'

k=menu('선의 색을 결정','red','green','blue');

plot(t,y,line_color(k))

R=input('계속하려면 ''y''를 type!  :','s');

str=lower(R);

else

break;

end

end

close all

[그림 2-41]□ex2_16.m"파일의 내용

[그림 2-42a]는 □ex2_16.m□을 실행하였을 때의 command window 화면을 보여 주고 있다.

[그림 2-42a] "ex2_16.m"을 실행한 경우의 command window

[그림 2-42b]는 □ex2_16.m□을 실행하였을 때, 생성되는 □menu window□이다.

□push□버튼을 click하면, 선택한 색으로 선의 모양이 바뀐다.

[그림 2-42b]

[그림 2-42c]는 □ex2_16.m□을 실행하였을 때, 생성되는 plot인데, menu window에서 □red□버튼이 click된 경우이다.

[그림 2-42c] "ex2_16.m"의 plot.

command window에 나오는 □prompt□에 □y□가 아닌 다른 문자를 type하면 실행을 중단한다.

dialog형(type) 함수들 :

여러 가지 dialog모양을 제공하는 함수들이 있는데, 그 사용법은 거의 비슷하다.

그래서, 여기서는 대표적으로, □questdlg.m□함수와 □msgbox.m□함수만 다루어 보겠다.

그 밖의 dialog형 함수들로는 다음과 같은 함수들이 있다.

helpdlg, inputdlg, pagedlg, printdlg, errordlg, warndlg

	dialog형 함수가 직접적으로 dialog형 함수를 제어하게 만들면 시스템에 따라서 프로그램을 불안하게 만든다. 즉, 실행 중 error가 발생 할 수 있다. 그러므로, dialog형 함수들 간에는 직접적인 데이터 교환은 하지 말도록 하자!

전형적인 사용방법(syntax): questdlg.m

R = questdlg('qstring','title','str1','str2','default')

→질문형 dialog box를 만들고,

→두 개의 'str1','str2' labels를 가진 □push□버튼을 만든다.

→"default"버튼은 default상태를 지정하게 해 준다.

→default상태는'str1','str2' 둘 중에서 정한다.

→□str□은 하나 더 사용 할 수 있다.

→선택된 'str'이 출력 변수 R로 반환된다.

전형적인 사용방법(syntax): msgbox.m

msgbox(message,title,'icon')

→title을 box이름으로 하고, message를 표시하는 box를 만든다.

→message box안에 표현할 icon모양을 결정한다.

"msgbox.m"함수의 icon 종류 :

icon의 종류로는 보통 3가지를 사용하는데, 'error', 'help', 'warn'을 주로 이용한다. 아래 그림을 참고하기 바란다.

[그림 2-43] "msgbox.m"함수의 icon 종류

[예제 20]

[예제 16]에서 사용한 □input.m□함수의 기능을 □questdlg.m□함수로 대체한 프로그램을 작성하시오.

[풀이]

[그림 2-44]은 □ex2_17.m□파일의 내용이다. 쉽게 이해 할 수 있다고 본다.

%

%이 예제는 menu.m, questdlg.m함수의 사용법을 설명하기 위한 것이다.

%

line_color=['r','g','b'];

str='Yes';

t=-2*pi:1/100:2*pi;

y=sin(t);

while(1)

if strcmp(str, 'Yes')

k=menu('선의 색을 결정','red','green','blue');

plot(t,y,line_color(k))

str=questdlg('계속하기를 원합니까?','선택사항','Yes','No','No');

else

break;

end

end

close all

[그림 2-44]□ex2_17.m□파일의 내용

[그림 2-45]는 □ex2_17.m□파일을 실행하였을 때 생성되는 □questdlg.m□함수의 window이다. 여러분이 □Yes□를 누르면 계속해서 선의 모양을 바꾸어 줄 수 있다.

[그림 2-45]

[예제 21]

page51 [예제 2]의 □pm_c.m□함수에 있는 □error.m□함수를 □msgbox.m□함수로 대체하여 다시 작성해 보시오.

[풀이]

독자 중에 한 분이 □pm_c.m□함수에 문제가 있다고, 지적을 해주었다. 그래서,  □pm_c.m□함수를 다시 작성하는 도중에, □msgbox.m□함수를 한 번 이용해 보았다.

[그림 2-46]은 다시 작성한 □pm_cb.m□함수의 내용이다.

function PM_cb(x)

%짝,홀수를 판별하는 M-file.

%

if x ~=abs(x)

msgbox('입력 값은 양의 실수이어야 한다.','에러','error');

return;

%   error('입력 값은 양의 실수이어야 한다.');

elseif x ~= fix(x)

msgbox('정수가 아니다.','에러','error');

return;

end

y=rem(x,2);

switch y

case 0

disp('입력 값은 짝수!');

otherwise

disp('입력 값은 홀수!');

end

[그림 2-46] □pm_cb.m□함수의 내용

[그림 2-47]는 □msgbox.m□함수가 생성하는 메시지 box인데, 다음과 같은 명령을 실행했을 때 발생하는 메시지 box이다.

□pm_cb(-2) □

[그림 2-47]

그 밖에 많이 사용되는 함수들 :

대표적인 두 개의 함수를 설명하겠다.

이들 함수들은 앞으로 자주 이용하게 될 것이다.

전형적인 사용법(syntax) : fliplr.m

"B=fliplr(A)"

→배열 A에서 각 행의 원소 나열 순서가 좌우 뒤바뀐다.

사용 예 : X=[2 5 1 8 3]; □

Y=fliplr(X) □

Y =

3     8     1     5     2

유사한 함수로 상·하 순서가 뒤바뀌는 □flipud.m□함수도 있다.

마. P-code Files : matlab5.0이후 버전에만 있음

그 동안, M-file은 모든 소스를 다른 사람들이 쉽게 볼 수가 있어서, 프로그램을 보호 할 수가 없었다. 개인마다 다르겠지만, 힘들게 만든 프로그램을 다른 사람에게 그냥, 무상으로 제공하는 것은 어쩌면, 프로그램 개발의욕을 떨어뜨릴 수도 있다. 그래서, 나온 것이 □pcode.m□함수이다. 이 함수는 모든 M-files를 저장하기 전에 parsing하여 저장한다.

	parsing(구문 해석): 구문 구조를 해석하는 것. 컴퓨터 분야에 있어서는 컴파일러 프로세서 안의 구문해석 루틴동작을 가리켜서 파싱(parsing)이라고 한다.

matlab은 모든 M-files를 저장하기 전에 parsing하여 pseudocode로 변환하여 그 결과를 메모리에 저장한다.

	pseudocode(의사 코드): 실행에 앞서서 번역을 필요로 하는 코드. 프로그램밍을 쉽게 하기 위해서 사용하는 대용 코드로서 실행하기 전에 기계코드로 번역된다.

"pcode.m"함수는 주어진 M-files를 □pseudocode□로 변환하여 확장자가 □.p□인 P-files로 저장한다. 물론, P-files도 M-files처럼 matlab에서 잘 수행된다. 또한, p-code화 한, M-files는 parsing이 이미 된 것이므로 재차 parsing을 하지 않는다. 그러므로, 대응하는 M-files보다 실행 속도가 더 빠르다.

그러나, matlab은 상당히 빨리 parsing을 수행하므로 P-files와 M-files의 실행 속도는 거의 같다고 봐도 된다. 만일, 여러분이 큰 GUI프로그램을 만든 경우에는 P-files가 빠르다는 것을 알 수 있을 것이다.

전형적인 사용방법(syntax) : pcode.m

(a) "pcode fun1 fun2 ..."

→주어진 함수1, 2를 p-files로 저장한다.

(b) "pcode *.m"

→현재 디렉토리에 있는 모든, M-files를 p-files로 바꾼다.

[그림 2-48]은 [예제 21]에서 만든 □pm_cb.m□함수에 대한 p-file을 만드는 과정을 보여 주고 있다.

[그림 2-48] □pm_cb.m□파일을 □pm_cb.p□파일로의 전환

[그림 2-48]에서 알 수 있듯이 □pcode pm_cb.m□명령을 command window에서 실행하면 □pm_cb.p□파일이 새로 생긴다. 물론, □pm_cb.m□파일은 그대로 남아 있다. 그러므로, 남에게 소스나 알고리즘을 보여 주고 싶지 않으면, P-files를 주면 된다.

Mathworks회사에서는 matlab에서 이용되는 그래프들의 체계를 위해 □Handle Graphics system□이라는 새로운 용어를 만들어 냈다. 또한, 컴퓨터 screen을 포함한 개개의 모든 그림 창(figure window)들과 좌표축들 그리고 patch(그림 성분)들은 □graphics object□라고 부른다. 즉, 앞으로 배울 line, text, image, user interface controls, 그리고, user interface pulldown menus 등등은 모두 □graphics object□이다.

□graphics objects□는 모두 9가지로 분류되는 데, Handle Graphics system에서 복잡한 그림을 만들기 위해 사용되는 성분들이라고 생각하면 좋을 것이다.

[그림 3-1]은 이들 □graphics objects□의 종류와 해당하는 예를 보여 주고 있다.

(a) figure object

(c) Line object

(b) Axes object

(d) Patch object

(e) Surface object

(g) Text object

(f) Image object

(h) Uicontrol object

(i) Uimenu object

이들 개개의 object(앞으로는 □객체□라고 이름 할 것이다.)를 정교하게 제어 할 수 있는 경우와 없는 경우에 의해서, 다시금 matlab 그래픽 함수들을 3가지로 분류 할 수 있다. 우선, 3가지 분류 사항을 배우기 전에 객체들의 계층 조직(hierarchy)을 이해 할 필요가 있다. 앞으로 여러분이 GUI 프로그램을 작성 할 때, 이들 객체의 의미와 또한, 객체간의 계층 조직을 이해해야 작성 할 수 있다.

사실, 개개의 객체에 대한 정확한 설명을 하려면, 상당량의 지면을 요구하므로, 강의를 진행해 나가면서 중간 중간에서 여러분이 이해 할 수 있도록 설명하는 식으로 해 나가겠다.

[그림 3-2]는 [그림 3-1]에서 보여준 객체간의 계층도 이다.

[그림 3-2] matlab 계층도

앞으로, [그림 3-1]과 [그림 3-2]는 자주 설명하는데, 인용될 것이다. 우선, [그림 3-2]에서 알 수 있듯이, Root가 가장 높은 level을 갖는다. 가장 높은 level을 갖는 다는 뜻은 어떠한 matlab graphics를 만들건 반드시 해당 그래프에 존재해야 한다는 뜻이다. 이것은 마치, [그림 3-2]에서 보여준 계층도의 나무에서 Root를 없앤다면 나머지 객체들 즉, Figure, Axes, Uimenu, 등도 모두 없어진다는 뜻이 된다. 그렇다면, 이처럼 모든 graphics에 반드시 있어야하는 객체인 Root는 어떤 것을 의미할 까? 생각해 보기 바란다.

Root라는 객체가 의미하는 것은 바로, 여러분의 컴퓨터 screen이다. 만일, 컴퓨터 screen이 없다면, 어떠한, 그래프로 그릴 수 없기 때문이다.

그러므로, 상위 level을 지우면 하위 level의 객체는 자동으로 소멸된다. 그러나, 하위 level을 지운 경우, 상위 level의 객체는 영향을 안 받는다. 즉, Axes를 없앤다고 해서 Figure도 같이 사라지는 것은 아니다.

정리하면 다음과 같다.

1) matlab 그래프들은 객체들의 조합으로 만들어진다.

2) 객체들은 계층도에 의해 분류된다.

3) 상위 객체는 하위 객체들을 제어 할 수 있다. 그러나, 하위 객체는 상위 객체에     영향을 주지 못한다.

4) 객체들은 같은 level의 객체들(siblings)을 소유 할 수 있다.

자! 이제, 여러분은 이들 객체를 제어하는 방법을 알 고 싶을 것이다.

Handle Graphics.

각각의 matlab 그래프 함수는 객체들을 제어 할 수 있도록, 새로 만들어지는 객체마다 고유한 숫자를 반환한다. 이들 고유한 숫자들을 handle이라고 부른다.

handle은 보통 figure object인 경우에는 양의 정수를 반환하고, 다른 하위 level에서는 부동 소숫점(floating point number)을 반환한다.

예를 들어보자.

□h_fig=figure □

h_fig =

1

h_fig는 □1□이라는 양의 정수를 반환한다. 또한, 현재 열려 있는 figure가 없다면, 새로 figure를 만들어 낸다. 어쨌든, 바로 □1□이 생성된 figure의 handle value이다.

[그림3-3]은 현재 열려 있는 figure가 없는 경우, 새로 만들어 진 figure이다.

[그림 3-3] 새로 생성된 figure

[그림 3-3]에서 □Figure No. 1□이라는 글자가 보일 것이다. 여기서, □1□이 바로 h_fig값 □1□과 같은 값이다.  그러므로, □□h_fig2=figure(2) □□를 하면, □Figure No. 2□이라는 글자가 있는 새로운 figure가 생긴다.

일단, handle value가 할당된 객체는 자신의 handle value를 바꿀 수 없으며, 해당 객체가 사라질 때까지 handle value는 보존된다. 또한, 같은 종류의 객체라도 handle value는 서로 다르다. 그래야, 각각의 객체를 독립적으로 제어 할 수 있기 때문이다. 그러나, Root object의 handle value는 항상 □0□이다. 왜냐하면, matlab graphics를 만들 screen은 하나 뿐이기 때문이다.

만일, matlab에서 처음으로 □handle□과 □object□라는 용어(term)를 들은 분은 잘 이해가 가지 않을 지도 모른다. 그러므로, □handle□과 □object□에 대한 간단한 다른 예제를 다루어 보겠다.

먼저, handle을 이용하여 각각의 객체 성질(propertyname)을 조정 해주는 □set.m□함수와 해당 객체의 성질에 할당된 값(propertyvalue)을 얻게 해주는 □get.m□함수의 이용법을 간단히 알아보자.

전형적인 사용법 : set.m

"set(handle, propertyname, propertyvalue)"

→주어진 handle에 해당하는 객체의 propertyname을

→새로운 propertyvalue로 고쳐준다.

전형적인 사용법 : get.m

"propertyvalue=get(handle, propertyname)"

→주어진 handle에 해당하는 객체의 propertyname을

→새로운 propertyvalue로 고쳐준다.

□close all	%열려 있는 figure(active figure)를 모두 지운다.

□h_fig1=figure(1) □

h_fig1 =	%□Figure No. 1□이라는 figure가 생길 것이다.

1

[그림 3-4]에서 보여준 □Figure No. 1□을 □numbertitle□이라고 부른다. 이때, □numbertitle□을 주어진 figure의 □propertyname□이라고 하며, □Figure No. 1□을 □propertyvalue□라고 한다.

정리하면, 주어진 객체 figure의 성질(propertyname)들 중에서 □numbertitle□에 할당된 □propertyvalue□는 □Figure No. 1□이라는 뜻이다.

[그림 3-4] □numbertitle□이 □Figure No. 1□

이제, □Figure No. 1□대신에 □By Lim Jong_Su□라고 하고 싶다. 그러기 위해서는 우선, propertyname인 numbertitle을 없애고, 새로운 이름(name)인 □By Lim Jong_Su□을 할당해 주어야 한다.  여기서, 주의 할 것은 □numbertitle□과 □name□은 서로 다른 propertyname임이라는 것이다.

이 작업은 2단계로 이루어진다.

propertyname인 numbertitle을 없애기 위해서 propertyvalue에 □off□를 할당한다.

새로운 이름을 할당하기 위해서 propertyname인 □name□에 대한 propertyvalue 에 □By Lim Jong_Su□를 할당한다.

	propertyname인 □numbertitle□에 대한 propertyvalue에 □off□대신 비슷한 단어인 □none, no, 등등□을 사용하면 다음과 같은 error가 나타난다. ??? Error using ==> set Bad value for figure property: 'NumberTitle'. 즉, □numbertitle□에 할당 할 수 있는 propertyvalue는 이미 지정되어 있는 □on 또는, off□뿐이다.

propertyname과 propertyvalue을 조정하기 위해서는 앞에서 설명한 □set.m□함수를 이용해야 한다.

□set(h_fig1,'numbertitle','off','name','By Lim Jong_Su') □

h_fig1	주어진 figure의 handle
numbertitle, name	주어진 figure의 propertyname
off, By Lim Jong_Su	주어진 figure의 propertyvalue

이제, 주어진 figure의 □Figure No. 1□은 □By Lim Jong_Su□로 바뀔 것이다.

[그림 3-5]에서 결과를 볼 수 있다.

[그림 3-5] □name□이 □By Lim Jong_Su□

만일, handle이 h_fig1인 figure의 크기를 알고 싶다면, 다음과 같이 하면 된다.

□h_size=get(h_fig1,'position') □

h_size =

189   304   390   246

모든 객체의 propertyname과 propertyvalue는 여기서 알아본 방식으로 □set.m□함수와 □get.m□함수를 이용하여 조정한다.

객체 figure는 여기서 언급한 propertyname외에도 수많은 propertyname이 있고, 각각의 propertyname마다 할당 할 수 있는 propertyvalue가 지정되어 있다. 게다가, [그림3-1]에서 언급한 객체마다 서로 다르거나, 또는 공통인 객체가 많이 존재한다.

만일, 여러분이 훌륭한 matlab GUI프로그램을 작성하고 싶다면, 각각의 객체마다 존재하는 propertyname의 정의와 할당 할 수 있는 propertyvalue를 모두 기억해야하고 이해해야한다. 그렇다면, 객체 figure의 propertyname과 할당할 수 있는 propertyvalue의 종류는 무엇이 있을까?

□set(h_fig1) □

BackingStore: [ {on} | off ]

CloseRequestFcn

Color

Colormap

CurrentAxes

CurrentObject

CurrentPoint

Dithermap

DithermapMode: [ auto | {manual} ]

IntegerHandle: [ {on} | off ]

InvertHardcopy: [ {on} | off ]

KeyPressFcn

MenuBar: [ none | {figure} ]

MinColormap

Name

NextPlot: [ {add} | replace | replacechildren ]

NumberTitle: [ {on} | off ]

PaperUnits: [ {inches} | centimeters | normalized | points ]

PaperOrientation: [ {portrait} | landscape ]

PaperPosition

PaperPositionMode: [ auto | {manual} ]

PaperType: [ {usletter} | uslegal | a3 | a4letter | a5 | b4 | tabloid ]

Pointer: [ crosshair | fullcrosshair | {arrow} | ibeam | watch | topl | topr | botl |                  botr | left | top | right | bottom | circle | cross | fleur | custom ]

PointerShapeCData

PointerShapeHotSpot

Position

Renderer: [ {painters} | zbuffer ]

RendererMode: [ {auto} | manual ]

Resize: [ {on} | off ]

ResizeFcn

ShareColors: [ {on} | off ]

Units: [ inches | centimeters | normalized | points | {pixels} ]

WindowButtonDownFcn

WindowButtonMotionFcn

WindowButtonUpFcn

WindowStyle: [ {normal} | modal ]

ButtonDownFcn

Children

Clipping: [ {on} | off ]

CreateFcn

DeleteFcn

BusyAction: [ {queue} | cancel ]

HandleVisibility: [ {on} | callback | off ]

Interruptible: [ {on} | off ]

Parent

Selected: [ on | off ]

SelectionHighlight: [ {on} | off ]

Tag

UserData

Visible: [ {on} | off ]

아마도, 조금 당황하였을 것이다. 단지 figure객체의 propertyname과 할당할 수 있는 propertyvalue의 조합이 이렇게 많은 데, [그림 3-1]에서 보여준 나머지 8개의 객체에 대한 propertyname과 propertyvalue를 합친다면, 9개 객체에 대한 propertyname과 propertyvalue를 전부 이해하고 기억한다는 것이 장난이 아니라는 것을 알 수 있을 것이다. 그러므로, 훌륭한 matlab GUI 프로그램을 만드는 것이 C++보다 훨씬 쉬운 것이 아니라는 것을 알아두자.

Low_level functions.

원칙적으로 좀더 다루기가 쉬운 high level function(예: plot.m, mesh.m etc)을 먼저 강의하는 것이 보편적인 방법이지만, 필자의 생각으로는 Matlab graphics system의 기본인 handles를 정교하게 다룰 수 있는 low_level functions를 배우는 것이 Matlab의 graphic 체계를 전반적으로 이해하는 데 중요하다고 생각하여 low_level functions를 우선 다루기로 하였다.

low_level functions는 객체(Object) 지향적인 Matlab의 graphic 체계를 의미하는데, 이들 low_level graphic functions를 이용하여 모든 high_level graphic functions를 만들 수 있으며, 또한, 여러분이 원하는 다른 graphic functions를 작성 할 수도 있다.

Handle Graphic functions라고도 불리는 이들 low_level functions의 종류로는 [그림 3-1]에서 언급한 객체마다 해당하는 함수들 즉, 9가지가 있다. 본 단원에서는 이들 9가지 함수들을 전반적으로 자세하게 다루지는 않을 것이다. 왜냐하면, 이전에 언급하였듯이 각각의 함수에 해당하는 propertyname과 propertyvalue가 상당히 많고, 그렇게 자세하게 알아 둘 필요는 없다고 보기 때문이다. 그래서, 이들 함수에 대한 중요한 이용법만 설명하겠다. 또한, Matlab의 help 디렉토리에 HTML양식으로 또는, PDF양식으로 모두 설명되어 있으니 부족한 부분은 참고하기 바란다.

	앞으로의 내용 전개는 다소 복잡하고, 중요하게 보이지 안을지도 모른다. 그러나, □부록□에서 다룰 □GUI 프로그램 작성법□에서 필수적인 부분이다. 또한, □set.m□함수와 □get.m□함수의 이용법은 매우 중요하므로, 이번에 꼭 배워두기 바란다.

Root Object

Root Object에 해당하는 직접적인 함수는 없다. 또한, 다른 low_level functions보다 상당히 적은 propertyname/propertyvalue pairs를  갖는데, Matlab command window에서도 직접 얻을 수 있다.

	이제부터 설명하는 부분은 Root Object뿐만 아니라, 모든 object에 대한 내용이다 또한, 여러분이 Matlab manual을 보거나, GUI 프로그램을 작성 할 때, 자주 참고하여야 할 propertyname/propertyvalue에 대한 자료를 보는 방법이므로 자세히 알아 둘 필요가 있다.

□set(0) □

위와 같은 명령을 실행하면 Root Object에 대한 자료를 볼 수 있다. 이전에, figure object의 handles value는 항상 양의 정수라고 하였다. 그런데, Root Object의 handle value는 항상 □0□이라는 것에 주의하자! 또한, command window에서 display되는 Root Object에 대한 자료를 보는 데 있어서, 몇 가지 주의 사항이 있다.

나열되는 자료 중에 다음과 같은 항들이 있을 것이다.

*Diary: [ on | off ]                         .......................... (줄 1)

*ShowHiddenHandles: [ on | {off} ]         ..........................  (줄 2)

(줄 1)과 (줄 2)에서 □[ ]□은 해당 propertyname(여기서는 diary와 ShowHiddenHandles을 의미한다.)에서 이용 할 수 있는 지정어(즉, propertyvalue)이다. 다시 말해서, 해당 propertyname을 제어 할 수 있는 지정어로서 다른 비슷한 용어를 사용하면 안되고, 반드시 지정해준 □on, off□만 사용하여야 한다. 그런데, (줄 2)에는 □{ }□으로 □off□라는 지정어(propertyvalue)를 둘러싸고 있는데, 이것은 □default propertyvalue□를 의미한다. 즉, Matlab이 자동으로 propertyvalue를 설정한 경우를 의미한다. 물론, □set.m□함수로 default propertyvalue□를 바꿀 수도 있다.

□get(0,'units') □          %propertyname □units□에 설정된 □propertyvalue□를

%□get.m□함수를 이용하여 얻는다.

ans =

pixels	%propertyname인 □units□에 해당하는

%default propertyvalue이다.

%□units□에 대해서는 □figure object□에서 언급하겠다.

□set(0,'units','nor') □     %□propertyvalue□를 □nor□로 □set.m□함수를

%이용하여 바꾼다.

□get(0,'units') □          %"propertyvalue를 다시 확인한다.

ans =

normalized

	propertyname은 대·소문자를 구분하지 않으며, 또한, □normalized□를 □nor□와 같이 약식 표현해도 된다. 단, □nor□로 시작되는 다른 propertyname이 없다는 전제하에서 가능하다. 만일, 여러분이 propertyname에대해 많이 알고 있다면 상관없는데, 그렇지 안다면, 약식 표현은 자칫 error의 원인이 되므로 사용하지 말 것을 권한다.

(줄 1)에는 Matlab이 자동으로 설정해준다는 표현인 □{ }□이 없다. 또한, 여러 개의 항들에서 □{ }□이 없는 항들을 볼 수 있다. 이것은 Matlab 회사에서 잘못표시 한 것으로서 반드시 모든 propertyname에는 default propertyvalue가 존재해야 한다. 그 사실은 Matlab에서 제공하는 help manual을 보면 알 수 있을 것이다. 사실, (줄 1)은 □Diary: [on | {off}]□로 표시해야 옳은 표현이다.

마지막으로 박스 안에 표시된 것과 같이 AutomaticFileUpdates과 ButtonDownFcn사이에 한 줄을 띄운 것을 볼 수 있다. 한 줄띄운 아래에 나오는 모든 propertyname은 □universal properties□를 의미한다. 즉, 모든 object가 다 갖고 있는 공통된 properties이다. 그런데, ButtonDownFcn은 옆에 아무런 지정어나, 또는 사용할 수 있는 format(예를 들어서 □string□, □number□ 등등)이 없다. 그것은 현 object인 Root Object에서는 사용 할 수 없는 propertyname을 의미한다.

.............. 생략 ................

AutomaticFileUpdates: [ on | off ]

ButtonDownFcn

............. 생략 ....................

figure object

간단한 예제를 다루어 가며 설명하겠다.

□h=figure □

h =

1

위와 같은 명령을 실행하면, [그림3-6]과 같은 figure object가 생성 될 것이다.

[그림 3-6] original figure의 모양

이제, [그림 3-6]을 [그림3-7]과 같이 변형하여 보자.

[그림 3-7] 변형된 figure의 모양

우선, [그림 3-6]과 비교하여, 이전에 언급한 □numbertitle□을 없애고(propertyvalue는 □off□), □name□을 □By Lim Jong_Su□로 바꾸었다. 또한, figure의 크기를 바꿀 수 없도록 □figure를 확대시켜 주는 icon□이 사라졌다.

figure의 크기를 마음대로 조정 할 수 있고, 없고는 □resize□라는 propertyname이 결정한다. 지정어로는 □[{on} | off]□가 있다.

그리 중요한 예제는 아니지만 □set.m□함수를 이용하는 방법에 익숙해진다는 생각으로 한 번 해보기 바란다.

□set.m□함수와 □get.m□함수는 주어진 객체의 handles를 조정하는데, 필수적인 함수이다.

□set(h,'numbertitle','off','name', ...     %이전에 설명한 " ... "명령어가

%기억나는가 ?

'ByLime Jonfg_Su','menubar','none','resize','off')  □

이번에는 [그림3-6]에 주어진 figure의 크기를 알아보고, Matlab의 □units□ 체계에 대해서도 알 보자.

□fig_size=get(h) □

fig_size =

165   114   470   279

□get(h,'units') □

ans =

pixels

주어진 그림의 크기를 알기 위해서 figure object의 propertyname중 □position(약식 표현:□pos□)□를 이용하였다.

Matlab에서 figure의 크기는 왼쪽 하단을 원점으로 하여 폭과 높이로 정해진다. 즉,  [left bottom width height]와 같은 형식을 갖는다.

앞으로 여러분이 GUI프로그램을 작성하는 경우, □slider, radio button, push button 등등□은 그림에서 차지할 위치를 지정해 주어야 한다. 그때, 사용되는 위치 지정법이기도 하다.

자세한 사항은 [그림 3-8]을 참고하기 바란다.

[그림 3-8] figure의 위치 지정법

그러므로, [그림 3-6]의 크기인 fig_size의 해당 숫자는 각각 다음과 같다.

[표 3-1] figure의 위치

Left	165
Bottom	114
width	470
Height	279

Matlab에서 사용 할 수 있는 units의 종류로는 5가지가 있다.

a)inches b)centimeters c)normalized d)points e){pixels}

또한, Matlab에서 지원되는 모든 units체계는 window의 왼쪽하단([그림3-8]참고)을 원점으로 정하고 측정하는데, Normalized units는 왼쪽 하단이 (0,0)에 해당하며, 오른쪽 상단은 (1.0 1.0)에 해당한다.

모든 객체는 각각 units를 정의한 뒤에 생성할 수 있다.

보통 출판업 종사하는 분들이 즐겨 쓰는 units인 □points□는 1/72inches에 해당한다.

Axes object

만일, 여러분이 여러 개의 객체를 생성했다고 하자! 이때, 원하는 객체의 특성을 바꾸고 싶다면, 직접 해당 객체의 handle value를 반환하는 functions를 이용하면 쉬울 것이다.

gcf (get current figure) :현재 active 상태인 figure handle을 반환한다.

	active 상태 만일, 여러분이 여러 개의 figure 객체를 만들었다고 해도, mouse로 한 번에 클릭 할 수 있는 figure는 하나뿐이다. mouse로 클릭된 figure의 numbertitle부는 녹색을 띄며, (그림[3-8]참고) 이와 같은 상태를 active 상태라고 한다. 객체의 특성을 바꾸려면 객체가 속해 있는 figure가 active 상태이어야 한다.

gca (get current axes) : active 상태의 figure안에 있는 axes의 해당 handles를 반환한다.

□t=-2*pi:1/100:2*pi; □

□y=sin(t); □

□plot(t,y) □

위와 같은 일련의 명령어를 실행하면, [그림 3-9]와 같은 figure가 생성 될 것이다.

[그림 3-9] sample figure

[그림3-9]에서 알 수 있듯이 line의 끝이 좌표축에 붙지 않고 있다.

Axes Object
propertyname	propertyvalue
xlim, ylim, zlim	각각의 좌표축에 대한 경계를 정한다.

□set(gca,'xlim', [min(t) max(t)],'ylim',[-1.5 1.5]) □

%항상, 최소 값이 먼저 나와야 한다.

[그림 3-10] sample figure에 대한 좌표축의 경계 변환

gco (get current object) : active figure에서 가장 최근에 생성된 객체 또는, mouse로 가장 최근에 클릭 된 객체의 handle을 돌려준다.

□t=-2*pi:1/100:2*pi; □

□y1=sin(t); □

□y2=cos(t); □

□plot(t,y1,'k',t,y2,'k') □    %'k'는 검은 색을 의미한다.

%□plot.m□함수에 대해서는 앞에서 배웠다.

□set(gca,'xlim', [min(t) max(t)],'ylim',[-1.5 1.5]) □

[그림 3-11] sample figure

[그림 3-11]에서 보여준 것처럼, 여러 개의 선들이 같은 색으로 지정되어 있다든지 또는, 어느 한 선을 강조해서 표현하고 싶을 때가 있을 것이다. 그렇다면, 먼저 강조하고 싶은 선을 mouse로 클릭한다.

	mouse로 객체를 클릭하여 선택하려면, 객체를 구성하는 각각의 모서리로부터 5 pixles 바깥쪽까지 클릭한 것이 유효하다. 5 pixels를 벗어나서 클릭하면, 해당 객체 선택이 안 된다.

이제, 강조하고 싶은 선을 클릭하였다면, 다음과 같은 명령어를 사용하라. 그러면, 클릭한 선의 색이 붉은 색으로 바뀐 것을 볼 수 있을 것이다. 또한, 선의 두께도 굵어 진 것을 알 수 있을 것이다.

Line Object
propertyname	propertyvalue
Color	선의 색을 변경하여 준다.
Linewidth	number

□set(gco,'color','r','Linewidth',15) □

위와 같은 명령을 실행하면, [그림3-11]이 [그림3-12]와 같이 클릭한 선의 모양만 바뀐 것을 알 수 있다. 이 기법은 buttondown 종류의 propertyname과 연결해서 GUI프로그램작성 시 자주 이용된다.

[그림 3-12] gco함수의 효과

여러분 중에서, Matlab의 □hold on/off□명령을 아시는 분이 계실 것이다. 물론, 현재의 그래프와 앞으로 만들 그래프를 겹쳐 표현하는 데 있어서, 사용하기에 아주 간단한 함수이다. 그러나, GUI 프로그램 작성 할 때는 적절하지 못한 함수이다.

Axes Object
propertyname	propertyvalue
Nextplot	간단히 설명하면, □add□인 경우에는 □hold on□효과를, □replace□이면, □hold off□의 효과를 준다.

□t=-2*pi:1/100:2*pi; □

□y1=sin(t); □

□y2=cos(t); □

□plot(t,y1,'r') □

□set(gca,'nextplot','add','xlim',[min(t) max(t)]) □

□plot(t,y2,'b:') □

위와 같은 일련의 명령을 실행하면, [그림 3-13]을 얻을 수 있다.

[그림 3-13] Axes Object의 nextplot 이용법

	figure object에 있는 □nextplot"과는 다른 기능을 한다는데 주의하라!

라. text object :

원칙적으로는 □uicontrol, uimenu□objects를 다루어야 하지만, 이들 objects에 대해서는 부록에 실은 □GUI 프로그램 작성법□을 참고하기 바란다. 또한, 다른 □line, path, image, surface, light□ objects에 대해서는 다루지 않겠다. image object를 제외한 objects들은 고급 그래픽 interface에서나 이용하는 방법이고, 별로, 중요하지 않다고 생각하기 때문이다.

[그림 3-1]의 (g)text object는 □한글□로 작성 한 것이 아니라, Matlab을 이용하여 작성 한 것이다. 이처럼 여러 가지 특수 symbol을 그래픽에 첨가해야 하는 경우가 자주 있다. 이때, 사용되는 대표적인 함수가 □text.m□함수 이다.

전형적인 사용법(syntax) : text.m

(a)"text_handle=text(x,y,'string')"

→주어진 좌표축에 기반을 두고, 좌표(x,y)에 "string"을 display한다.

(b)"text_handle=text(x,y,z,'string')"

→주어진 좌표축에 기반을 두고, 3차원 좌표(x,y,z)에

→"string"을 display한다.

(c)"text_handle=text(x,y,z,'propertyname','propertyvalue')"

→주어진 좌표(x,y,z)에 특성을 첨가하거나, 바꾸어 준다.

→2차원인 경우에는 (x,y)만 설정해 주면 된다.

□text.m□함수의 여러 가지 특성 중에서 여기서는 특수 symbol을 이용하는 방법만 알아보겠다.

[그림3-14]를 통하여 설명을 전개해 나가겠다.

[그림 3-14] 특수 symbol 사용법

[그림 3-14]를 만들기 위해서는 다음과 같은 일련의 명령어가 필요하다.

□t=0:900; □

□plot(t,.25*exp(-.005*t)) □

□h=text(300,.25*exp(-.005*300),...

'\bullet\leftarrow\fontname{times}0.25{\ite}^{-0.005{\itt}}  .at {\itt}=300');

"\bullet, \leftarrow"가 무엇을 의미하는 지는 [표3-2]를 참고하면 알 수 있을 것이다.

[표3-2] 특수 문자표

□한글□에서 수식을 넣는 방법과 거의 같다.

이들 문자들은 □Latex□문자 체계들로써, text object의 interpreter가 □tex□인 경우에만 특수문자로 변환된다.

□get(h,'interpreter') □

ans =

tex

만일, 다음과 같이 명령을 하면, □string'이 특수문자로 변환되지 않고, typing한 그대로 figure안에 display된다.

□set(h,'interpreter','none') □

또한, figure에 display되는 문자의 □font□도 바꾸어 줄 수 있다.

□h=text(300,.25*exp(-.005*300),...

'\bullet\leftarrow\fontname{times}0.25{\ite}^{-0.005{\itt}}  .at {\itt}=300');

[표 3-3] font의 종류

font의 종류	주어진 font에 대한 설명
\bf	Bold Font
\it	italics font
\sl	oblique font(거의 이용 안 함)
\rm	normal font
\fontname(fontname}	위에 주어진 font외의 다른 font들

이들 특수 문자 지정어들은 □{ }□으로 구분한다.

또한, 아래첨자는 □ _ □으로 만들고, 윗 첨자는 □ ^ □으로 만든다.

	□\, {, }, _, ^□문자들은 모두 앞에 □ \ □을 첨가하면 display 될 수 있다. 즉, □\\, \{, \}, \_, \^□의 형태를 취하면 된다.

이번에는 문자의 정렬방법에 대해서 알아보자.

[그림 3-15]는 sample용 figure이다.

[그림 3-15] 문자열의 정렬 방법

문자열(string)의 정렬을 관장하는 propertyname으로는 □HorizontalAlignment, VerticalAlignment□ 2가지가 있다.

[표 3-4]와 [그림3-16]을 참고하면 쉽게 이해 할 수 있을 것이다.

[표 3-4] 문자열의 정렬방법

Text Object
propertyname	propertyvalue
HorizontalAlignment	{left} | center | right
VerticalAlignment	top | cap | {middle} | baseline | Bottom

[그림3-16 (a)]는 HorizontalAlignment에 대한 설명이고, [그림3-16(b)]는 VerticalAlignment에 대한 설명이다.

(a) "HorizontalAlignment"의 경우.

(b) "VerticalAlignment"의 경우.

[그림3-16]문자열의 정렬 방법

그런데, "Text.m"함수에서 지정한 정확한 좌표에 문자열이 위치하는 것은 아니라 약간, 벗어난 지점에 문자열이 나타난다. 왜? 약간 벗어난 위치에 문자열이 나타나는 지, 그 이유에 대해서는 mathworks.com에서 언급하지 않은 것으로 알고 있다.

그러나, 정확한 좌표에서의 이탈양은 상당히 작으므로 여러분은 신경 쓰지 않아도 될 것이다.

[표 3-5] 화면의 확대 축소 기능

Matlab 명령어	해당 명령어의 설명
zoom on	확대시키고 싶은 영역에서 mouse의 왼쪽 버튼을 click하면 화면이 확대된다. 오른쪽 버튼을 누르면 축소된다.
zoom off	Zoom기능을 없앤다.
zoom xon	x축에 대해서만 확대를 한다. mouse 버튼 기능은 □zoom on□과 같다.
zoom yon	x축에 대해서만 확대를 한다. mouse 버튼 기능은 □zoom on□과 같다.
zoom out	원래의 figure로 돌아간다.

[표3-5]에서 언급한 □zoom.m□함수를 이용하여, [그림 3-15]에서 나타낸 작은 원과 점(dot) 부분을 확대하여 본다. 그러면, 점이 작은 원의 중심이 아니라는 것을 알 수 있을 것이다.

[표3-4]와 [그림 3-16]을 참고하면, 여러분이 직접 [그림3-15]를 생성하는 M-file을 작성 할 수 있다고 본다.

[그림 3-17]은 [그림 3-15]를 만드는 데, 이용한 M-file이다.

파일이름은 □fig3_17.m□이다.

%[그림 3-15]를 만드는 데, 이용되는 M-file.

%"text.m"함수의 이용 방법.

close all

clear all

t=0:pi/100:2*pi;

y=sin(t);

plot(t,y)

xlabel('t=0 to 2\pi','fontsize',16)

ylabel('sin(t)','fontsize',16)

title('\it{Value of the Sine from Zero to Two Pi}')

set(gcf,'color','w')

text(3*pi/4,sin(3*pi/4),'\bullet\leftarrowsin(t)=0.707')

set(gca,'nextplot','add')

plot(3*pi/4,sin(3*pi/4),'ro')

text(pi,sin(pi),'\leftarrowsin(t)=0')

text(5*pi/4,sin(5*pi/4),...

'sin(t)=-0.707\rightarrow','Horizontalalignment','right')

set(gca,'nextplot','replace')

[그림 3-17] □fig3_17.m□파일 내용

	만일, 여러분이 □figure Object, Axes Object□처럼 상위 Level의 default property value를 바꾸었다면, □fig3_17.m□ 파일의 맨 아래 줄에 있는 □set(gca,'nextplot','replace')□와 같이, 다시 default propertyvalue로 환원 해주는 것을 잊지 말자! 만일, 환원해 주지 않으면, 앞으로 만들어지는 모든 Axes Object의 하위 Level과 같은 Axes level의 함수들은 동일한 화면에 그림들을 그려주기 때문이다.

지금까지 여러분은 Matlab Graphics system중 Handle graphics에 해당하는 Low_Level functions에 대해서 알아보았다.

이제, 좀 쉬운 High_level functions에 대해서 알아보자!

라. High_level functions.

High_level functions에 속하는 그래픽 함수들은 일반적으로 데이터를 화면에 display하기 위해 사용되는 함수들이다.

상당히 많은 종류의 그래픽 함수들이 존재하는 데, 이들 함수들은 Low_level functions처럼 데이터를 display하는데, 필요한 여러 가지 propertyname /propertyvalue를 묻지 않고, 자동으로 좌표의 크기 조절(axis scaling)과 선의 색(Line color)등을 설정해준다.

본 단원에서는 그래픽 함수들의 특성에 따라서 3가지 부류로 나누어 이들 그래픽 함수들을 다루고자 한다.

다음과 같은 대표적인 그래픽 함수들을 설명하겠다.

"plot.m, plot3.m, contour.m, contour3.m, contourf.m,  clabel.m, stem.m, stem3.m, stairs.m, compass.m, feather.m, comet.m, comet3.m,scatter.m, scatter3.m, polar.m, rose.m, "

다음과 같은 대표적인 3 차원 그래픽 함수들을 설명하겠다.

"surf.m, surfc.m, mesh.m, meshc.m, meshz.m, view.m, meshgrid.m, colormap.m, colorbar.m"

그 밖의 유용한 그래픽 함수들을 설명하겠다.

"pie.m, pie3.m, bar.m, barh.m, bar3.m, bar3h.m, area.m, errobar.m, ezplot.m"

그밖에도 하나의 그래프를 완성하는데 필요한, "legend.m, subplot.m, 등등"의 설명도 첨부해 나갈 것이다. 그러나, 모든 함수들을 자세히 설명하지는 않을 것이다. 몇몇 대표적인 함수들만 자세히 강의하고, 나머지는 그 사용법만 간단히 답습해나가는 식으로 하겠다.

위에 열거한 그래프 함수들 정도면, 충분히 모든 상황을 표현할 수 있다고 본다.

일반적으로 많이 이용되는 그래픽 함수들 :

plot.m : 제 1 부류

지금까지 □plot.m□함수는 많이 이용하여 왔다. 그런데, 이번에는 좀 더 자세히 그 이용법을 알아보겠다.

전형적인 사용법(Syntax) : plot.m

a) plot(Y)

→만일, Y가 실수이면, x축은 Y의 index이고, y축은 Y의 열 벡터들로	→이루어진다. 그러나, Y가 복소수이면, x축은 real(Y), y축은	→imag(Y)로 이루어진다.

b) plot(X1,Y1,...)

→X1의 열 벡터와 Y1의 열 벡터가 각각의 line을 구성한다.

c) plot(X1,Y1,LineSpec,...)

→LineSpec은 color, linestyle, maker로 구성되어 선의 style을	→	결정한다.

d) plot(...,'PropertyName',PropertyValue,...)

→"Line"object에 있는 propertyname/propertyvalue로 선의 style을	→결정한다.

e) h = plot(...)

→여러 개의 Line들이 있는 경우, 각각의 Line에 할당된

→handle value가 열 벡터의 모양으로 반환된다.

□X=[1:10; 0.7*[1:10]; 0.5*[1:10]; 0.25*[1:10])'; □

□plot(X) □

□xlabel('x axis','fontsize',15) □

□ylabel('y axis','fontsize',15) □

□title('\bf{''plot.m''함수의 이용법}','fontsize',15) □

위와 같은 일련의 명령어를 실행하면 어떻게 그래프가 만들어지겠는가?

[그림 3-18] "plot.m"함수의 이용법

[그림3-18]에서 알 수 있듯이 행렬 X에 대한 각각의 원소들이 Y축을 이루고 있고, 행렬 X에 대한 index가 X축을 이루고 있다.(즉, x=1:length(X))

만일, 여러분이 선(line)들의 색이나 type을 정해주지 않으면, 자동으로 default값에 의해 결정되어 진다.

이들 선들의 색에 대한 default값은 다음과 같은 방법으로 얻을 수 있다.

□Line_Color =get(gca,'colororder') □

Line_Color =

0         0    1.0000

0    0.5000         0

1.0000         0         0

0    0.7500    0.7500

0.7500         0    0.7500

0.7500    0.7500         0

0.2500    0.2500    0.2500

또한, 선들의 type에 대한 default값은 다음과 같은 방법으로 역시 얻을 수 있다.

□Line_Type =get(gca,'Linestyleorder') □

Line_Type =

-

이들 Line_Color 행렬과 Line_Type 벡터의 조합으로 모든 선(Line)들의 style이 결정된다.

결정 방법은 다음과 같다.

(a) Line_Type의 첫 번째 원소와 선들의 색에 대한 행렬인 Line_Color의 모든 색      을 순환하며 각각의 선들을 구성한다.

(b) Line_Type의 두 번째 원소와 선들의 색에 대한 행렬인 Line_Color의 모든 색      을 순환하며 각각의 선들을 구성한다.

.........................    반  복    ......................

그런데, 대부분의 학생들은 컬러 프린터기를 사용하지 못하고 있다고 본다. 그러므로, □plot.m□함수에 의해서 그려지는 선들의 색은 검은 색으로 일정하고 type만 바꾸어 가며 line을 그리기를 원할 것이다. 그러기 위해서는 default값인 □Line_Color, Line_Type 배열의 원소들□을 바꾸어 주어야한다.

□set(0,'DefaultAxesColororder',[0 0 0],'DefaultAxesLineStyleOrder','-|-.|--|:') □

위와 같은 명령어를 실행하고, 다시 [그림3-18]을 만드는 일련의 명령어를 똑같이 실행하면 [그림 3-19]와 같은 figure가 만들어 질 것이다.

	앞에서 보여준 □set.m□함수는 Root Object에 대한 propertyname/propertyvalue를 조정해주고 있다. Root Object는 최상위의 Level을 갖는 Object이다. 그러므로, matlab을 재 시동할 때까지는 모든 선들의 style이 위에서 결정된 사항을 따르게 된다. 또한, □startup.m□파일 안에 위와 같은 명령어를 삽입하면 matlab을 재실행하여도 선들의 style은 위에서 결정한 모양을 계속 따른다. 단! 윤곽선을 표현하는 □contour.m□함수 부류는 위에서 결정한 선들의 style을 따르지 않는다. 그것은 □contour.m□함수 내부에서 다시 선들의 style을 정의하기 때문이다.

[그림 3-19] 선들의 style에 대한 default값을 변경한 경우

여러분 중에서 데이터를 그래프로 표현하고자 하는 경우, 한쪽 데이터의 범위(range)는 일정한 경계 값으로 고정시키고, 다른 쪽은 데이터의 모든 양을 표현하고 싶을 때가 있을 것이다. 즉, 어느 구간만 보고 싶은 경우가 있을 것이다.

이처럼 어떠한 좌표의 한쪽은 경계치로 고정시키고, 다른 쪽은 모두 표현하고 싶을 때는 □axis.m□함수를 이용하여 보라. 물론, 어떠한 좌표의 양쪽을 일정한 경계치로 고정시킬 수도 있다.

앞에서, Axes object를 배울 때, propertyname 중에서 □xlim, ylim, zlim□에 대해서 학습하였다. 이것과 같은 기능을 하는 함수가 바로 □axis.m□함수이다.

전형적인 사용 방법(syntax) : axis.m

axis([xmin xmax ymin ymax zmin zmax])

→좌표의 범위(range)를 결정해준다.

→2차원 그래프인 경우에는 □zmin zmax□만 빼주면 된다.

□t=-5:1/100:5; □

□y=1./((t-0.3).^2+0.01)+1./((t-0.9).^2+0.04)-6; □  %y는 humps function.

□plot(t,y) □

앞에서와 같은 일련의 명령어를 실행하면, [그림 3-20]을 얻을 수 있다.

[그림 3-20] □axis.m□함수의 사용 예

이제, t축의 범위를 [0 ∞]으로 바꾸고자 한다. 그렇게 하기 위해서는 다음과 같은 명령을 실행하면 된다.

□axis([0 inf -inf inf]) □

[그림 3-21]은 t축의 범위를 [0 ∞]으로 바꾼 경우의 그래프이다.

앞에서 배운 Axes Object의 propertyname/propertyvalue를 이용하여 t축의 범위를 [0 ∞]까지 바꾸려면 어떻게 해야 하는가?

필자의 생각으로는 여러분이 충분히 할 수 있다고 본다.

□set(gca,'xlim',[0 inf],'ylim',[-inf inf]) □

위와 같은 명령어를 실행하여도 [그림 3-21]이 만들어진다.

[그림 3-21]을 보면 데이터가 0≤ t ≤2 사이에 많이 분포하고 있는 것을 알 수 있다. 그러므로, 0≤ t ≤2 구간에서는 0.4간격마다 tick을 표시하고 싶다. 그러기 위해서는 다음과 같이 한다.

Axes Object
propertyname	propertyvalue
xtick, ytick, ztick	Tick mark를 위치시킬 수치 vector

□set(gca,'xtick',[0:0.4:2 2.5 3 3.5 4 4.5 5]) □

결과는 [그림 3-22]에서 볼 수 있다.

결국, □tick□의 위치는 불균등하게 놓을 수 있다.

[그림 3-22] Tick의 위치 변경 방법

그런데, 만일, t축의 ticklabel(즉, 0, 0.4, 0.8 따위)을 수치가 아닌 문자열로 표현하고 싶을 때가 있을 것이다.

Axes Object
propertyname	propertyvalue
xticklabel, yticklabel, zticklabel	Tick mark의 위치에 놓을 문자열(string)

x(y,z)ticklabel을 이용하는 경우 Tick mark들의 숫자만큼 문자열들이 있어야 한다. 그렇지 않으면 tick의 숫자만큼 문자열을 만들기 위해 다시 같은 문자열들을 사용한다.

[그림 3-22]에서는 t축에 있는 tick의 개수가 12개이다.

□t_label=str2mat('I','II','III','IV','V','VI','VII','VIII','IX','X','XI','XII') □

□set(gca,'xticklabel',t_label) □

위와 같이 실행하면 [그림3-23]과 같이 xticklabel이 로마숫자표시로 바뀔 것이다.

[그림 3-23] xticklabel의 변경 방법

High_level graphic functions를 이용하여 하나의 figure를 만들 때, matlab은 자동으로 좌표축을 설정한다. 이때, 그래프가 window화면에서 가능한한 많은 공간을 이용할 수 있도록 Figure window와 같은 모양 율(aspect ratio)을 갖는 직사각형모양의 좌표계(rectangular axes)를 만든다. 결국, 생성된 그래프의 전체적인 크기 비율은 각각의 좌표축에 대한 aspect ratio에 따라 다르게 나온다.  예를 들어서 설명 해보도록 하겠다.

우선, 반지름이 2인 원을 만들어 보자.

□t=[0:10:360]*(pi/180); □

□x=2*cos(t); □

□y=2*sin(t); □

□xlabel('\bf{x axis}','fontsize',15) □

□ylabel('\bf{y axis}','fontsize',15) □

□title('\bf{좌표계가 default인 rectanular인 경우!}','fontsize',15) □

□plot(x,y) □

위와 같은 일련의 명령어를 실행하면 [그림  3-24]와 같은 결과가 나온다.

[그림 3-24] aspect ratio가 default(즉, □auto□)인 경우

[그림3-24]로부터 알 수 있듯이 원의 모양을 갖는다고 볼 수 없다. 원의 모양보다는 오히려, 타원의 모양을 갖고 있다. 그러므로, 원래 원하는 원의 모양을 갖고 싶으면, aspect ratio를 바꾸어 주어야 한다.

aspect ratio를 □square□로 하면, Figure window의 모양을 rectangular 좌표계가 아닌 정 사각형의 모양을 갖는 좌표계로 바꾼다.

□axis square □

[그림 3-25] aspect ratio가 □square□인 경우

[그림3-24]보다는 훨씬 더 원하는 원의 모양을 갖고 있다. 그러나, 이것은 어디까지나, Figure window를 정사각형 모양으로 바꾸어 준 결과로 나타난 것이다. 결국, 각 좌표축의 units는 무시한 결과를 초래한다.

만일, 여러분이 어떤 사물의 image를 얻어서 그것을 matlab의 □image.m□함수로 display한 경우 실제 사물의 크기 비율(aspect ratio)과 같게 하려면, 각각의 좌표축에 대한 units는 동등한 크기를 갖아야 한다. 이때, 이용되는 aspect ratio로는 □equal, image□가 있다.

좌표계의 aspect ratio를 □equal□로 하는 경우와 □image□로 하는 경우에 대한 차이는, 해당 그래프에 대한 데이터의 범위까지만 display하는 경우가 □image□에 해당한다.

사실, 해당 그래프에 대한 데이터의 범위까지만 display하는 명령어는 □tight□라는 명령어가 따로 있다. 그러므로, □image□는 □equal□명령어와 □tight□명령어의 합성 명령어라고 보면 된다.

□axis equal □

[그림 3-26] aspect ratio가 □equal□인 경우

□axis image □

[그림 3-27] aspect ratio가 □image□인 경우

그러므로, 여러분이 display하고자 하는 데이터가 어떤 실제 존재하는 사물인 경우에는 □axis equal 또는 axis image□를 사용 해주어야 실제 사물의 aspect ratio와 같아진다.

이번에는 생성한 그래프에 여러 개의 선(line)들이 있는 경우, 각각의 선들에 legend를 첨가하는 방법에 대해서 알아보자.

전형적인 사용방법(syntax): legend.m

a) h=legend('string1','string2',...)

→현 좌표계에 존재하는 각각의 데이터 집합에 대한

→legend를 첨가한다.

b) h=legend(h,'strings)

→문자열 행렬 strings에 대한 각각의 행(문자열)을 대응하는 객체에

→연결 시켜준다.

c) h=legend('off')

→현 좌표계에서 존재하는 legend를 제거한다.

d) h=legend(..., pos)

→pos에 의하여 다양한 위치에 legend를 첨가한다.

→pos에 대해서는 [표3-6]을 참고하라.

[표 3-6] □legend.m□함수에서의 □pos□값에 의한 legend 위치

pos	legend의 위치
-1	좌표계의 오른쪽 밖에 놓는다.
0	좌표계의 안쪽에 놓는다.
1	좌표계의 upper-right corner에 놓는다.
2	좌표계의 upper-left corner에 놓는다.
3	좌표계의 lower-left corner에 놓는다.
4	좌표계의 lower-right corner에 놓는다.
[XlowerLeft YlowerLeft]	normalized units 체계에서 주어진 좌표 값에 놓는다.

화면에 display된 legend는 mouse의 왼쪽 버튼을 누른 상태에서 dragging 할 수 있다.

□x=-pi:pi/20:pi; □

□plot(x, cos(x), '-r', x, sin(x), '-.b') □

□xlabel('\bf{x axis}','fontsize',12) □

□ylabel('\bf{y axis}','fontsize',12) □

□title('\bf{legend function의 이용법}','fontsize',12) □

□h=legend('cos', 'sin', 0); □

[그림 3-28] □legend.m□함수에서 pos=0인 경우

이번에는 여러 개의 그래프를 한 개의 figure안에 표현하는 함수인 □subplot.m□함수에 대해서 알아보자.

전형적인 사용 방법(syntax) : subplot.m

subplot(m,n,p)

→하나의 figure에 대해 rectangular 좌표계를 원소로 갖는 m행 n열의

→작은 좌표계를 여러 개 만들어 낸다.

□subplot(m,n,p)□표현 대신에 □subplot mnp□로 해도 같은 기능을 한다.

□x=-pi:pi/20:pi; □

□subplot(1,2,1) □

□plot(x, cos(x), '-r') □

□xlabel('\bf{x axis}','fontsize',12) □

□ylabel('\bf{y axis}','fontsize',12) □

□title('\bf{subplot 121에 대한 그래프}','fontsize',12) □

□subplot(1,2,2) □

□plot(x, sin(x), '-.b') □

□xlabel('\bf{x axis}','fontsize',12) □

□ylabel('\bf{y axis}','fontsize',12) □

□title('\bf{subplot 122에 대한 그래프}','fontsize',12) □

위와 같은 일련의 명령어를 실행하면 [그림 3-29]를 얻는다.

[그림 3-29] □subplot.m□함수에 대한 사용 방법

간혹, 그래프를 작성하는 경우, x 축이 오른쪽에서 왼쪽으로 증가하는 그래프가 필요 할 때가 있을 것이다. 즉, 지금까지 작성한 그래프의 좌표 값에 대한 증가 방향을 반대로 할 필요가 있을 것이다. 이와 같은 경우에는 □Axes object□의 propertyname 중에서 □XDir, YDir, ZDir□을  이용하면 된다.

□t=0:900; □

□subplot(121) □

□plot(t,0.25*exp(-0.05*t)) □

□xlabel('\bf{x axis}','fontsize',12) □

□ylabel('\bf{y axis}','fontsize',12) □

□title('\bf{보통의 x 축 방향!}','fontsize',12) □

□subplot(122) □

□plot(t,0.25*exp(-0.05*t)) □

□xlabel('\bf{x axis}','fontsize',12) □

□ylabel('\bf{y axis}','fontsize',12) □

□title('\bf{x 축 방향이 반대인 경우!}','fontsize',12) □

□set(gca,'xdir','rev') □

□plot(t, 0.25*exp(-0.05*t)) □

위와 같은 명령을 실행하면 [그림 3-30]의 결과를 얻을 수 있다.

[그림 3-30] x 축 방향이 서로 다른 그래프

y 축과 z축도 같은 방식으로 행하면, 보통의 증가 방향과 반대 방향으로 좌표 값이 증가한다.

이번에는 한 개의 그래프에 서로 다른 범위(range)를 갖는 데이터를 동시에 display하는 방법을 알아보자.

역시, Axes object의 propertyname 중에서 Xaxislocation, Yaxislocation은 x 축과 y 축을 그래프상의 어디에 위치시킬 것인지를 결정한다.

이번 예제에서는 서로 다른 두 개의 데이터 중에서 하나는 figure의 왼쪽 모서리를 y축으로 하고, bottom을 x축으로 하는 그래프, 그리고, 또 다른 데이터는 오른쪽 모서리를 y 축으로 하고, top을 x 축으로 하는 그래프를 작성 할 것이다.

여기서는 □plot.m□함수보다는 propertyname/propertyvalue를 정교하게 조정할 수 있는 low_level graphic function인 □Line.m□함수를 이용 할 것이다. 또한, 앞에서 배운 Axes object도 사용 할 것이다.

[그림 3-31]은 필자가 한 번 작성한 그래프이다. 또한, [그림 3-32]는 [그림 3-31]을 만들기 위한 M-file이다.

전형적인 사용법(syntax) : Line.m

h=line(x,y,z,'propertyname','propertyvalue')

→propertyname/propertyvalue로 특성 지워진 선을 데이터 x, y, z에

→의거하여 그린다.

→단, 2차원인 경우에는 x, y만 사용!

[그림 3-31] 두 개의 서로 다른 데이터에 대한 표현 방법

%[그림 3-31]을 만들기 위한 M-file.

close all

clear all

x1=0:1/1000:1;

y1=exp(-5*x1).*sin(200*x1);

hl1=line(x1,y1,'color','r');

y1_text=ylabel('y1');

x1_text=xlabel('x1');

ax1=gca;

set(y1_text,'rotation',0)

set(ax1,'xcolor','r','ycolor','r');

ax2=axes('pos',get(ax1,'pos'),'xaxislocation','top','yaxislocation','right',...

'color','none','xcolor','k','ycolor','k');

x2=0+eps:1/1000:.1;

y2=cos(2*pi*10*x2);

hl2=line(x2,y2,'color','k','parent',ax2);

y2_text=ylabel('y2');

x2_text=xlabel('x2');

set(y2_text,'rotation',0)

xlimits=get(ax1,'xlim');

ylimits=get(ax1,'ylim');

xinc=(xlimits(2)-xlimits(1))/10;

yinc=(ylimits(2)-ylimits(1))/10;

set(ax1,'xtick',[xlimits(1):xinc:xlimits(2)],...

'ytick',[ylimits(1):yinc:ylimits(2)])

grid on

[그림 3-32] 서로 다른 데이터를 한 개의 figure에 표현하는 방법

이번에는 그래프에 첨가해주는 □grid□에 대해서 알아보자.

대부분의 학생들이 matlab을 이용하여 그래프를 작성하는 경우, 보통, □grid on/off□명령어만 사용하는 것을 보았다. 그러나, □hold on/off□함수처럼 GUI 프로그램을 작성하는 경우에는 적절하지 못한 함수이다. 또한, □grid"의 종류 자체에도 여러 가지 효과를 줄 수 있다.

Axes Object
propertyname	propertyvalue
xgrid, ygrid, zgrid	각각의 좌표축에만 □grid□를 첨가시킨다.
Gridlinestyle	"grid" Line의 style을 변경 할 수 있게 해준다.

□t=0:1/1000:1; □

□beta=200; □

□alpha=20; □

□y=exp(-alpha*t).*sin(beta*t); □

□plot(t,y) □

□xlabel('\bf{Time[msec]}','fontsize',12) □

□ylabel('\bf{Amplitude}','fontsize',12) □

□title('{\bf{\ite}^{-\alphat}sin(\betat)  \alpha << \beta}','fontsize',12) □

□set(gcf,'color','w') □

위와 같은 일련의 명령어를 실행하면, [그림 3-33]의 결과를 얻는다.

물론, x, y축 모두 dotted line style(즉, :)의 □grid□를 첨가시키려면 단순히

□grid on □

과 같이 명령하면 된다.

왜냐하면, dotted line style의 grid가 default이기 때문이다.

또한, active figure에서 □grid line□을 제거하려면 단순히,

□grid off □

라고 명령하면 된다.

[그림 3-33] □grid□의 여러 효과를 알기 위한 sample

이제, x 축에만 style이 □ -. □인 □grid□를 첨가시킬 것이다.

[그림 3-34]는 그 결과를 보여 주고 있다.

□set(gca, 'xgrid', 'on', 'gridlinestyle', '-.') □

[그림 3-34] x 축에만 □grid□를 첨가시킴

만일, [그림 3-34]와 같은 figure안에 다른 그래프를 첨가하려면, [그림3-34]를 생성한 뒤에 □□hold on □□하면 된다. 그러면, [그림 3-34]의 figure가 사라질 때까지  앞으로 나오는 모든 그래프는 [그림 3-34]의 figure에 합쳐져서 나타난다. 그러나, 더 이상 같은 figure에 그래프를 첨가시키고 싶지 않으면 □□hold off □□라고 명령한다. 그러면, 이 후 만들어지는 그래프는 새로운 figure에 나타난다.

그러나, Axes Object를 설명 할 때, 언급하였듯이 가능하면, nextplot propertyname을 사용하기를 바란다.

나) plot3.m : 제 1 부류

□plot3.m□함수는 3차원 그래프를 구성하기 위해, z 축에 대한 데이터를 필요로 하는 점을 제외하고는 □plot.m□함수와 사용방법이 같다.

□t=0:.1:10*pi;

□x=exp(-t/20).*cos(t);

□y=exp(-t/20).*sin(t);

□z=t;

□plot3(x,y,z)

□grid on

□xlabel('x');

□ylabel('y');

□zlabel('z');

□title('\bf{''plot3.m'' function의 이용법!}','fontsize',12)

□set(gcf,'color','w')

위와 같은 일련의 명령어를 실행하면, [그림 3-35]와 같은 결과를 얻는다.

[그림 3-35] □plot3.m"함수의 사용법

그런데, [그림 3-35]에서, z 축 label이 x , y축 label의 방향과 다르다. 그러므로, z 축 label의 방향을 x, y축의 label 방향과 같게 해보자.

□xlabel.m, ylabel.m, zlabel.m□은 text object에 대한 handle을 돌려준다.

Text Object
propertyname	propertyvalue
Rotation	Degrees의 단위로 text string의 방향을 결정한다. default=0 positive angle은 시계 반대 방향에 상응한다.

□h=zlabel('z');

□set(h,'rotation',180);

위와 같이 명령하면 z 축 label의 방향이 x, y축의 label 방향과 같게 된다.

물론, x, y, z 축에 대한 label들의 방향은 위와 같은 방법으로 마음대로 설정 할 수 있다.

또한, Axes Object는 □Box□라는 propertyname이 있어서, □on□명령을 하면 주어진 그림에 □Box□를 씌워준다. 물론, □off□라고 propertyvalue를 설정하면 □Box□는 사라진다.

□set(gca,'box','on');

[그림 3-36]은 z 축 label의 방향과 □Box□ propertyname을 □on□으로 조정해준 결과이다.

[그림 3-36] □label□ 방향과 □Box□ propertyname의 조정 방법

	책에는 제 2 부류에 속하는 □surf.m, surfc.m, mesh.m, meshc.m, meshz.m, view.m, meshgrid.m, colormap.m, colorbar.m□함수가 이 부분에서 설명된다. 또한, 그림이 12개가 첨부되고, 표가 3개 첨가된다. 그러므로, □contour.m□함수에 있는 그림들은 [그림 3-49]부터 시작한다. 그리고, 표는 [표3-11]부터 시작한다.

다) contour.m : 제 1 부류

□contour.m□함수는 여러분이 가지고 있는 3차원 데이터에 대한 등고선들을 구하는 함수이다.

전형적인 사용방법(syntax) : contour.m

a) [C, h]=contour(Z)

→행렬 Z는 x-y 평면대한 높이로 해석된다.

→Contour 행렬 C와 handle value를 반환한다.

→"clabel.m"함수를 이용하여 각각의 등고선에 label을 붙인다.

b) [C, h]=contour(Z, n)

→행렬 Z에 대한 n개의 등고선을 그린다.

c) [C, h]=contour(Z, v)

→행렬 Z에 대한 등고선을 벡터 v의 값에 근거하여 그려 준다.

d) [C, h]=contour(X, Y, Z), [C, h]=contour(X, Y, Z, n(or, v))

→행렬 X, Y는 x, y축의 범위를 정한다.

e) [C, h]=contour(...., LineSpec)

→LineSpec에 근거하여 각각의 등고선들을 그린다.

□contour.m□함수로 등고선들을 작성한 경우, 각각의 등고선에 □label□을 붙여 주어야 등고선이 갖는 의미를 알 수 있을 것이다. 이와 같이 각각의 등고선에 □label□을 붙여주는 함수로는 □clabel.m□이라는 함수가 있다.

각각의 contour label은 일종의 높이를 나타내는 수치의 형태를 갖는다.

그러나, □clabel.m□함수는 각각의 label에 대한 text object에 해당하는 handle을 반환하므로 □set.m, get.m□함수로 다른 문자열의 형태로 변환 할 수도 있다.

□clabel.m□함수는 입력 매개변수로 contour matrix를 필요로 한다. contour matrix는 □contour.m, contour3.m, contourf.m□함수에 의해 반환되는 행렬이다.

전형적인 사용방법(syntax) : clabel.m

a) clabel(C, v)

→contour matrix에 대해, 벡터 v의 값을 label로 하여 해당 등고선에	→label을 첨가한다.

(b) clabel(C, 'manual') 또는, clabel(C, h, 'manual')

→label을 붙이고자 원하는 등고선에서 mouse의 왼쪽 버튼을 누르면

→해당 등고선에 새로운 label이 첨가된다.

→return key를 누르면 labeling 작업이 종료된다.

이밖에도, clabel에 대한 다른 여러 가지 사용 방법이 있지만, 필자의 생각으로는 권장하고 싶지 않다.

□Z=peaks; □      %matlab이 제공하는 sample 함수.

□[c,h]=contour(Z); □

□set(gcf,'color','w') □

□title('\bf{''contour.m''함수의 사용법!}','fontsize',12) □

위와 같은 일련의 명령을 실행하면 [그림 3-49]와 같은 결과가 나온다.

[그림 3-49] □contour.m□함수의 사용 방법

이제, [그림 3-49]에 나타나는 등고선의 수를 5개로 제한하고자 한다.

□[c,h]=contour(Z, 5); □

위와 같이 명령하면, [그림 3-50]과 같은 5개의 등고선을 얻을 수 있다.

[그림 3-50] 등고선의 개수 조정 방법

이제, [그림 3-50]에 있는 등고선들에 대해 각각의 label을 원하는 위치에 놓고자 한다.

□con_hndl=clabel(c, h, 'manual'); □

을 하면, [그림 3-50]은 [그림 3-51]과 같은 figure로 바뀐다. 이때, 원하는 등고선에서 mouse의 왼쪽 key를 누르면 해당 등고선에 label이 생긴다.

labeling을 끝내려면, return key만 누르면 된다.

	□□con_hndl=clabel(c, h, 'manual'); □□처럼 contour에 대한 handle value h를 첨가해주면 각각의 등고선에 대한 label이 알맞게 회전하여 위치한다. 그러나, handle value h를 첨가시켜주지 않으면, □ + □기호 위에 일괄적으로 labeling을 한다.

[그림 3-51] 원하는 등고선에만 labeling을 하는 방법

만일, 높이가 0.01인 등고선(-10dB)에 대해서만 그리기 원하고, 또한, 등고선 style은 검은 색에 dotted line(즉, :)이기 원하면 다음과 같이 명령하면 된다.

□[c,h]=contour(Z, [0.01 0.01], 'k-'); □   %검은 색은 □ k □로 표시한다.

결국, 하나의 등고선을 나타내려면,  □[0.01 0.01]□과 같이 원하는 등고선 값을 두 번 써주어야 한다.

□con_hndl=clabel(c, h, 'manul') □

Please wait a moment...

Carefully select contours for labeling.

When done, press RETURN while the Graph window is the active window.

con_hndl =

10.0021

위와 같은 일련의 명령어를 실행하면, [그림 3-52]와 같은 그림을 얻는다. 물론, label이 있는 곳에서 mouse로 click한 것이다.

[그림 3-52] 등고선이 하나인 경우

이제, 0.01을 문자열인 □10[dB]□로 바꾸고자 한다. 그러기 위해서는 앞에서 얻은 labeling에 대한 handle value를 이용해야 한다.

□set(con_hndl, 'string','10[dB]');

[그림 3-53] 수치 labeling을 문자열로 변환하는 방법

이제, 높이가 [2 4 6]인 등고선만 표현하려고 한다. 그러기 위해서는 다음과 같이 하면 된다.

□[c, h]=contour(Z, [2:2:6]); □

□clabel(c); □

위와 같은 명령을 수행하면 [그림 3-54]를 얻을 수 있다.

[그림 3-54] 주어진 높이만 표현하는 방법

라) contour3.m : 제 1 부류

3차원 contour plot을 작성해주는 함수이다.

앞에서 배운 □contour.m□함수와 사용 방법이 비슷하다.

전형적인 사용방법(syntax) : contour3.m

a) [C, h]=contour3(Z)

*행렬 Z는 x-y 평면대한 높이로 해석된다.

Contour 행렬 C와 Line object에 해당하는

handle value, h를 반환한다.

*"clabel.m"함수를 이용하여 각각의 등고선에 label을 붙인다.

b) [C, h]=contour3(Z, n)

*행렬 Z에 대한 n개의 등고선을 그린다.

c) [C, h]=contour3(Z, v)

*행렬 Z에 대한 등고선을 벡터 v의 값에 근거하여 그려 준다.

d) [C, h]=contour3(X, Y, Z), [C, h]=contour3(X, Y, Z, n(or, v))

*행렬 X, Y는 x, y축의 범위를 정한다.

e) [C, h]=contour3(...., LineSpec)

*LineSpec에 근거하여 각각의 등고선들을 그린다.

□LineSpec□은 line의 style을 결정하는 지정어들의 조합이다.

다음에 나오는 □stem3.m□함수 설명부분에 있는 □LineSpec□ 용어 설명부분을 참고하기 바란다.

□[X,Y]=meshgrid([-2:.25:2]);

□Z=X.*exp(-X.^2-Y.^2);

□contour3(X,Y,Z,30)

□hold on

□h=surf(X,Y,Z);

□set(h,'edgecolor',[.8 .8 .8],'facecolor','none')

□hold off

□grid off

□view(-15,25)      %방위각:-15, 고도:25

□colormap cool

□set(gcf,'color','w')

□xlabel('x');

□ylabel('y');

□zlabel('z');

□title('\bf{''contour3.m'' function의 이용법!}','fontsize',12)

위와 같은 일련의 명령어를 실행하면, [그림 3-55]와 같은 결과를 얻는다.

앞에서 언급하였듯이, □surf.m□함수는 surface object에 해당하는 handle을 돌려준다.

Surface Object
propertyname	propertyname에 대한 설명
EdgeColor	Surface를 구성하는 각각의 patch에 대한 모서리의 색을 결정한다. default는 검은 색이다.
FaceColor	Surface를 구성하는 각각의 patch에 대한 표면의 색을 결정한다.

그러므로, □□set(h,'edgecolor',[.8 .8 .8],'facecolor','none')□ 명령에서 □edgecolor□가

[.8 .8 .8]인 것은 모서리 색을 [.8 .8 .8]로 하고, □facecolor□가 □none□이라는 것은 표면을 그리지 말라는 뜻이다.

[그림 3-55] □contour3.m□함수의 사용 방법

마) contourf.m : 제 1 부류

□contourf.m□함수는 2차원 contour plot을 그려주는 데, 등고선들 사이의 면적들(areas)에 일정한 색을 첨가해 준다. 이들 색은 현재 적용되고 있는 colormap에 의해 결정된다.

전형적인 사용방법(syntax) : contourf.m

a) [C, h, CF]=contourf(Z)

→행렬 Z는 x-y 평면대한 높이로 해석된다.

→Contour 행렬 C와 Line Object에 해당하는 handle value, h를 반환한다.

→CF는 주어진 □colormap□에 의해 채워진 면적들에 대한

→contour matrix이다.

→"clabel.m"함수를 이용하여 각각의 등고선에 label을 붙일 수 있다.

b) [C, h, CF]=contourf(Z, n)

→행렬 Z에 대한 n개의 등고선을 그린다.

c) [C, h, CF]=contourf(Z, v)

→행렬 Z에 대한 등고선을 벡터 v의 값에 근거하여 그려 준다.

d) [C, h, CF]=contourf(X, Y, Z), [C, h]=contourf(X, Y, Z, n(or, v))

→행렬 X, Y, Z는 x, y, z축의 범위를 정한다.

다음과 같은 예제를 생각해보자.

□[C,H,CF]=contourf(peaks(20),10);

□colormap gray

□xlabel('x')

□ylabel('y')

□title('\bf{''contourf.m''function의 사용 방법!}','fontsize',12)

□set(gcf,'color','w')

위와 같은 일련의 명령을 실행하면, colormap □gray□에 의거하여 등고선들 사이에 지정된 색을 채워준다.

[그림 3-56]은 그 결과를 보여 주고 있다.

[그림 3-56] □contourf.m□함수의 사용 방법!

바) stem.m : 제 1 부류

모든 불연속 데이터의 열(discrete sequence data)을 표현하는데 이용되는 함수이다.

전형적인 사용방법(syntax) :stem.m

h=stem(x,y)

→벡터 y를 각각의 벡터 x에 대해서 표현 해준다.

→Line Object에 해당하는 handle, h를 돌려준다.

h=stem(x,y,'fill')

→각각의 marker에 색을 채워준다.

h=stem(..., LineSpec)

→stem plot에 대한 선, marker, color의 style을 결정 해준다.

사실, □stem.m□함수는 디지털 신호처리 분야에서 데이터를 표현하는데 많이 이용되는 함수이다.

□y=linspace(0, 2, 10);    % 0 ∼ 2사이를 균등하게 10개의 데이터로 나눔!

□stem(exp(-y), 'fill', '-.')

□axis([0 11 0 1])

위와 같은 일련의 명령어를 실행하면 [그림 3-57]을 얻는다.

[그림 3-57] □stem.m□ function의 사용 방법

사) stem3.m : 제 1 부류

□stem.m□함수에 대한 3차원 표현 방법이다.

전형적인 사용방법(syntax) :stem3.m

a) h=stem3(x,y,z)

*벡터 z를 각각의 벡터 x, y에 대해서 표현 해준다.

*Line Object에 해당하는 handle, h를 돌려준다.

b) h=stem3(x,y,z,'fill')

*각각의 marker에 색을 채워준다.

c) h=stem3(..., LineSpec)

*stem3 plot에 대한 선, marker, color의 style을 결정 해준다.

다음과 같은 예제를 통하여 □stem3.m□함수의 사용 방법을 알아두자.

[예 제] 임의의 데이터를 FFT(Fast Fourier Transform)한 결과는 복소 평면상의 단위 원(unit circle)상에 분포하는 magnitude로 표현된다. 그러므로, 주어진 데이터에 대한 FFT의 결과가 단위 원주 상에서 어떻게 분포하는지 알아보는 것은 매우 흥미로운 일이 될 것이다.

step function의 주파수 응답에 대한 magnitude가 단위원주 상에서 어떻게 분포하는지 조사하여라.

[풀이]

우선, 단위 원을 만들기 위한 데이터를 구성한다.

□th=(0:127)/128*2*pi;       %여기서는 128 point의 데이터를 취했다.

□x=cos(th);

□y=sin(th);

이제, step function의 주파수 응답에 대한 magnitude를 계산 해보자.

□f=abs(fft(ones(10,1),128));    %step function을 128-point FFT하여,

%그 결과에 대한 magnitude를 계산.

□stem3(x, y, f','d','fill');

□view([-65 30])          %데이터의 분포를 보다 명확히 보기 위해서

%관측 점의 위치를 바꾸어 보았다.

□xlabel('\bf{Real}','fontsize',12);

□ylabel('\bf{Imaginary}','fontsize',12);

□zlabel('\bf{Amplitude}','fontsize',12);

□title('\bf{Magnitude Frequency Response}','fontsize',12)

□stem3.m□함수에서 입력 매개변수로 사용된 □d'는 marker type을 diamond로 하라는 뜻이다.

[표 3-11]은 marker symbol의 종류와 각각의 marker를 지정하는 방법에 대해서 요약한 것이다.

그런데, 이들 지정어(specifier)들은 모두 string이므로, 단일 인용부호(즉, □ □)로 둘러싸야 한다.

[표 3-11] □marker□ symbols의 종류

보통, Line Object에 해당하는 handle을 돌려주는 함수들은 line에 대한 color([표3-9]참고), marker symbol([표3-11]), line type([표3-12])의 지정어들을 조합하여 line의 style을 결정한다. 이들 line의 style을 결정하는 지정어들의 조합을 보통, □LineSpec□이라고 한다.

이들 marker symbols의 지정어(specifier)들에 대한 약식 표기는 머릿글자이다.

그러므로, □diamond□대신에 □d□, □hexagram□대신에 □h□라고 하여도 된다.

[표3-12]는 Line type을 지정하는 방법과 종류가 요약되어 있다.

[표 3-12] □Line□ type의 종류와 지정 방법

결국, 이들 [표 3-9], [표3-11], [표3-12]는 모든 Line Object에 해당하는 handle을 돌려주는 함수들에서 Line style을 결정하는데 사용할 수 있다.

□stem3.m□함수를 이용하여 계산된 magnitude는 [그림 3-58]에서 볼 수 있다.

아) stairs.m : 제 1 부류

□stairs.m□함수는 sampling 된 신호에 대한 time-history를 작성하는데 유용한 함수이다. 즉, 불연속 데이터를 □sample-and-hold□회로에 통과시킨 결과를 작성하는데 필요한 함수이다.

전형적인 사용 방법 : stairs.m

a) h=stairs(Y)

→Y가 벡터인 경우의 X축 범위는 1 ∼ length(Y)이고,

→Y가 행렬인 경우에는 각각의 열 벡터가 하나의 신호를 표현하며,

→x 축의 범위는 1부터 행렬 Y의 행의 수가된다.

→Line Object에 해당하는 handle, h를 반환한다.

b) h=stairs(X, Y)

→배열 Y에 대한 각각의 열 벡터를 배열 X에 대해 표현한다.

c) stairs(..., LineSpec)

→stairs 그래프를 구성하는 선(Line)들의 style을 결정한다.

d) [xb, yb]=stairs(Y), [xb, yb]=stairs(X, Y)

→그래프를 만드는 대신에 벡터 xb와 yb를 반환하여

→다른 그래픽 함수에서 이용 할 수 있도록 한다.

→예 : plot(xb, yb)

앞에서도 언급하였듯이 하나의 배열로 구성된 신호들의 집합은 주어진 배열에 대해 각각의 열 벡터로 표현된다. 결국, 주어진 배열이 m개의 열을 가지고 있다면, 그 배열은 종류가 m개인 신호데이터를 갖고 있다고 볼 수 있다.

Matlab은 거의 대부분의 함수들이 column-wise 연산을 행한다는 데 주의하자!

[그림 3-59]는 □stem.m□함수와 □stairs.m□함수를 동시에 표현한 것이다.

□stem.m□함수가 데이터의 sampling 결과라면, □stairs.m□함수는 sampling 된 신호를 □Sample-and-Hold□회로에 통과시킨 결과를 나타낸다.

다음과 같은 일련의 명령어들은 [그림 3-59]를 생성 해준다.

□x=0:1/5:2*pi;

□y=sin(x);

□stem(x,y,'k')

□set(gca,'nextplot','add')	%Axes Object 내용 참고.

□h=stairs(x,y,'k');

□set(h,'linewidth',2)

□set(gcf,'color','w')

□xlabel('\bf{x}','fontsize',12)

□ylabel('\bf{y}','fontsize',12)

□title('\bf{''stairs.m'' and ''stem.m''functions comparison}','fontsize',12)

[그림 3-59] □stem.m and stairs.m□함수들의 비교

자) scatter.m : 제 1 부류

□scatter.m, scatter3.m□함수는 2, 3차원 평면상에 대해 벡터 X, Y(3차원인 경우에는 Z가 첨가됨)로 지정된 위치에 colored markers를 표현해주는 함수이다. 그러므로, 분자 구조, 유전자의 구조를 그래프화 하는 데 매우 유용한 함수이다.

전형적인 사용 방법(synatx) : scatter.m

a) h=scatter(X, Y, S, C)

*S가 scalar인 경우에는 모든 marker size를 S크기로 같게 한다.

*S가 벡터인 경우에는 벡터 X, Y와 크기가 같아야 하고,

모든 marker size가 벡터 S에 의존한다.

*C가 벡터인 경우에는 벡터 X, Y와 크기가 같아야 하고,

벡터 C의 원소들을 현재 적용되는 Colormap에 선형으로

mapping시켜서 marker color를 결정한다.

*C가 length(X)×3의 크기를 갖는 행렬이면, markers의 color를 새로 생긴 colormap            인 lebgth(X)×3의 값에 의해서 결정한다.

b) h=scatter(X, Y)

*주어진 벡터 X, Y에 의해서 결정된 위치에 marker를

default color와 size로 위치시킨다.

*Line Object에 해당하는 handle, h를 반환한다.

c) h=scatter(...,markertype)

*marker의 type을 지정해 줄 수 있다.

d) h=scatter(..., 'filled')

*markers의 표면을 주어진 색으로 채워 준다.

예제를 통하여 보다 자세히 □scatter.m□함수에 대해서 알아보자.

[예 제] 반지름이 1인 구를 □sphere.m□함수로 만든다. 만들어진 구를 여러 높이에서 수평으로 자른 경우에 해당하는 2차원 scatter그래프를 만들어 보자.

[풀이]

전형적인 사용 방법(syntax) : sphere.m

a) [X, Y, Z] = sphere(n)

*3개의 (n+1)×(n+1) 크기를 갖는 행렬 X, Y, Z를 만든다.

만들어진 행렬 X, Y, Z로 surf(X, Y, Z)는 반지름이 1인 구를 만든다.

b) [X, Y, Z]=sphere

*21×21 크기를 갖는 행렬 X, Y, Z를 만든다.

□[x, y, z]=sphere(16);

□xx=x(:);	%"xx=x(:);"의 의미는 앞에서 설명하였다.

□yy=y(:);

□S=repmat(8,prod(size(x)),1);   %"repmat.m"function은 앞에서 설명하였다.

□scatter(xx(:),yy(:),S(:),'filled')

□scatter(xx(:),yy(:),S(:),'k','filled')

□set(gcf,'color','w')

□xlabel('\bf{x}','fontsize',12)

□ylabel('\bf{y}','fontsize',12)

□title('\bf{The usage of ''scatter.m'' function}','fontsize',12)

□set(gca,'box','on')

Axes Object
propertyname	propertyvalue
Box	□on□인 경우에는 active figure에 Box를 첨가한다. □off□인 경우에는 Box를 지운다.

위와 같은 일련의 명령어를 실행하면 [그림 3-60]을 얻는다.

[그림 3-60] □scatter.m□함수의 이용법

차) scatter3.m : 제 1 부류

□scatter.m□함수의 3차원적 표현 방법이다. 사용방법은 □scatter.m□함수와 거의 같다.

전형적인 사용 방법(synatx) : scatter3.m

a) h=scatter(X, Y, Z, S, C)

*S가 scalar인 경우에는 모든 marker size를 S크기로 같게 한다.

*S가 벡터인 경우에는 벡터 X, Y, Z와 크기가 같아야 하고,

모든 marker size가 벡터 S에 의존한다.

*C가 벡터인 경우에는 벡터 X, Y, Z와 크기가 같아야 하고,

벡터 C의 원소들을 현재 적용되는 Colormap에 선형으로

mapping시켜서 marker color를 결정한다.

*C가 length(X)×3의 크기를 갖는 행렬이면, markers의 color를 새로생긴 colormap            인 length(X)×3의 값에 의해서 결정한다.

b) h=scatter3(X, Y, Z)

*주어진 벡터 X, Y, Z에 의해서 결정된 위치에 marker를

default color와 size로 위치시킨다.

*Line Object에 해당하는 handle, h를 반환한다.

c) h=scatter3(...,markertype)

*marker의 type을 지정해 줄 수 있다.

d) h=scatter3(..., 'filled')

*markers의 표면을 주어진 색으로 채워 준다.

[예 제] 앞에서 살펴본 [예 제]에서는 3차원 구를 여러 높이에 자른 결과를 알아보았다. 여기서는 반지름이 1인 구안에 반지름이 0.5인 구를 포함시킨 scatter그래프를 작성해보겠다.

[풀이]

먼저, 반지름이 1인 구를 만든 뒤에 0.5를 곱하여 반지름이 0.5인 구를 만들어보자.

□[x, y, z]=sphere(16);

□xx=[x(:)*.5 x(:)];

□yy=[y(:)*.5 y(:)];

□zz=[z(:)*.5 z(:)];

□S=repmat([1 .5]*8,prod(size(x)),1);

□scatter3(xx(:),yy(:),zz(:),S(:),'k','filled')

□set(gcf,'color','w')

□xlabel('\bf{x}','fontsize',12)

□ylabel('\bf{y}','fontsize',12)

□zlabel('\bf{z}','fontsize',12)

□title('\bf{The usage of ''scatter3.m'' function}','fontsize',12)

위와 같은 일련의 명령어를 실행하면, [그림 3-61]의 결과를 얻는다.

[그림 3-61] □scatter3.m□함수의 사용 방법

이제, 복소수를 표현해주는 함수들에 대해서 알아보자.

앞에서 배운 □plot.m□ 따위의 함수들은 real part를 x 축의 좌표로, imaginary part를 y 축의 좌표로 하여 plotting 한다고 하였다.

그러나, 대부분의 plotting 함수들은 보통 허수 부(imaginary part)를 무시하고 그래프를 작성한다. 물론, 그래프를 작성하는 도중에 허수 부를 무시하는 경우 Matlab은 다음과 같은 경고문(Warning)을 내보낸다.

□Warning: Imaginary parts of complex X and/or Y arguments ignored.□

본 단원에서는  복소수를 표현해주는 대표적인 함수로 □compass.m, feather.m,

polar.m, rose.m□과 같은 함수들을 알아 볼 것이다.

본 단원에서 살펴볼 함수들은 방향을 원소로 하는 벡터(direction vectors)와 속력을 원소로 하는 벡터(velocity vectors)로 구성된 데이터를 display하는 경우에도 사용 될 수 있다. 즉, 어떠한, 물체의 움직임 추적을 할 때 사용될 수 있는 그래픽 함수들이다.

카) compass.m : 제 1 부류

□compass.m□함수는 주어진 복소수 데이터의 각도(angle)와 크기(magnitude)를 원형 격자(circular grid)안에서 표현 해준다.

□compass.m□함수는 주어진 좌표의 원점에서 발산하는(emanating) 화살표를 만들어서 복소수를 표현한다.

화살표(arrow)의 길이는 각각의 복소수에 대한 크기를 나타내고, 화살표가 가리키는 방향(arrow's pointing direction)은 복소수의 각도를 의미한다.

전형적인 사용 방법(syntax) : compass.m

a) h=compass(X, Y)

*real 벡터 X, Y를 real(X)+imag(Y), 즉, 복소수로 간주하여

plotting한다. 주어진 벡터 X, Y의 크기는 같아야 한다.

*화살표의 개수는 벡터 X(또는, Y)가 갖고 있는 원소의 수와 같다.

*화살표의 끝(tip)은 좌표의 원점과 [X(i), Y(i)]를 이은 선(line)상에 있다.

b) h=compass(..., LineSpec)

*화살표를 주어진 LinSpec에 의거하여 그린다.

*Line Object에 해당하는 handle, h를 돌려준다.

만일, Z가 복소수를 원소로 갖는 행렬이라면, h=compass(Z)의 표현은 h=compass(real(Z), imag(Z))와 같은 표현으로 간주한다.

[예 제] 벡터 Z의 원소들은 크기가 [1:10]이고, 각도가 [1:10]*36*(pi/180)이다.

벡터 Z에 대한 10개의 원소들을 □compass.m□함수로 표현하여라.

[풀이]

□Z=[1:10].*exp(i*[1:10]*36*(pi/180));

□h=compass(Z);

□set(gcf,'color','w')

□set(h,'color','k')

위와 같은 일련의 명령어를 실행하면, 벡터 Z의 원소들인 복소수는 10개의 화살표로 표현된다. 이들 화살표의 크기는 복소수 원소들의 크기를 표현하고, 화살표의 방향은 복소수 원소들의 각도를 나타낸다.

[그림 3-62]는 결과를 보여 주고 있다.

[그림 3-62] □compass.m□함수의 사용 방법

타) feather.m : 제 1 부류

간혹, □compass.m□함수처럼 모든 화살표가 공통의 원점(origin)을 갖는 것보다는 일정하게 떨어진 수평축을 따라서 복소수를 표현하는 화살표들이 나타나기를 원하는 경우가 있을 것이다. 이와 같은 경우에 사용되는 그래픽 함수가 □feather.m□함수이다.

사용방법은 □compass.m□함수와 같다.

전형적인 사용 방법(syntax) : feather.m

a) h=feather(X, Y)

*real 벡터 X, Y를 real(X)+imag(Y), 즉, 복소수로 간주하여

plotting한다. 주어진 벡터 X, Y의 크기는 같아야 한다.

*화살표의 개수는 벡터 X(또는, Y)가 갖고 있는 원소의 수와 같다.

*화살표들은 일정한 간격으로 떨어져있다.

b) h=feather(..., LineSpec)

*화살표를 주어진 LinSpec에 의거하여 그린다.

*Line Object에 해당하는 handle, h를 돌려준다.

만일, Z가 복소수를 원소로 갖는 행렬이라면, h=feather(Z)의 표현은 h=feather(real(Z), imag(Z))와 같은 표현으로 간주한다.

[예 제] 앞에서 □compass.m□을 사용하여 살펴본 예제를 이번에는 □feather.m□함수를 이용하여 살펴보자.

[풀이]

□feather.m□함수를 사용하기 위하여 다음과 같은 명령을 실행하자.

□Z=[1:10].*exp(i*[1:10]*36*(pi/180));

□h=feather(Z);

□set(gcf,'color','w')

□set(h,'color','k')

위와 같은 일련의 명령어를 실행하면, [그림 3-63]과 같은 결과를 얻는다.

[그림 3-62] □feather.m□함수의 사용 방법

벡터 Z의 원소들인 10개의 복소수들이 화살표로 표현되어 등 간격으로 나타나고 있다. 각각의 화살표의 길이는 복소수의 크기(magnitude)를, 화살표와 수평축이 이루는 각은 복소수의 각도(angle)를 나타낸다.

지금까지 배운 모든 그래픽 함수들은 모두 직각 좌표 계(Cartesian coordinate system)를 이용하는 함수들이었다. 그러나, □rho와 theta□로 데이터를 표현하는 극 좌표 계(polar coordinate system)를 이용하여 데이터를 표현할 수도 있다. 이와 같이 주어진 데이터를 극 좌표 계에서 표현해주는 함수로는 □polar.m, rose.m□함수들이 있다.

[그림 3-58]로부터 step function을 FFT한 결과는 sinc function의 형태를 취한다.

[그림 3-58] □stem3.m□함수의 사용 방법

파) polar.m : 제 1 부류

주어진 데이터를 대응하는 각도(theta, 단위는 radian)와 크기(rho)로 변환해주면, □polar.m□을 이용하여 극 좌표 계로 데이터를 표현해 줄 수 있다.

전형적인 사용방법(syntax) : polar.m

a) h=polar(theta, rho)

*각도를 나타내주는 배열 theta와 반지름을 나타내는 배열 rho

을 가지고, polar coordinate plot을 작성한다.

*Theta는 x 축과 반지름 벡터간의 각도(단위는 radian)를 나타내 준다.

b) h=polar(theta, rho, LineSpec)

*polar plot을 구성하는 Lines의 style을 결정한다.

*Line Object에 해당하는 handle, h를 반환한다.

만일, theta와 rho가 행렬이면, theta의 열 벡터들은 rho의 열 벡터에 대해서 plotting 된다.

앞에서, 신호처리에서 사용되는 데이터 행렬은 항상 열 벡터의 단위로 계산한다고 하였다. 즉, 각각의 신호들은 행렬의 열 벡터들에 해당한다.

Matlab은 거의 대부분의 함수들이 column-wise 연산을 행한다.

[예 제] 각도가 2*pi*[0:.01:1]의 범위를 갖고, rho=0.5+cos(theta)로 정의된다고 하자. theta와 rho를 극 좌표 계로 plotting하여라.

[풀이]

다음과 같은 commands를 생각 할 수 있다.

□theta=2*pi*[0:.01:1];

□rho=0.5+cos(theta);

□polar(theta,rho,'k')

□set(gcf,'color','w')

위와 같은 일련의 명령어들을 사용하면, [그림 3-63]의 결과를 얻을 수 있다.

	만일, theta와 rho의 범위(range)를 바꾸기 위해서, 앞에서 배운 axis([min_theta max_theta min_rho max_rho])와 같은 명령을 사용하면 안 된다. 왜냐하면, □polar.m□함수는 □plot.m□함수를 이용하여 만든 것이기 때문이다. 즉, □polar.m□함수는 □plot.m□함수를 이용하여 그래프를 만들고, □axis off□ 명령어로 좌표축을 없앤 것이다. 그러므로, □axis on□이라고 명령하면, 사라졌던 좌표축이 다시 생긴다.

Matlab Command
axis on	좌표축을 screen상에 display한다.
axis off	좌표축을 screen에서 지운다.

□axis on/off□명령어는 앞에서 배운 Axes Object의 □Box on/off□명령과 같은 기능을 한다

[그림 3-63] □polar.m□함수의 사용 방법

하) rose.m : 제 1 부류

□rose.m□함수는 20개이하의 bins로 theta의 분포를 표현해주는 함수이다.

개개의 bins는 주어진 각도의 범위들 안에 포함된 theta의 개수를 의미한다.

결국, □rose.m□함수로 각도(theta)들에 대한 Histogram을 만들 수 있다.

전형적인 사용 방법(syntax) : rose.m

a) h=rose(theta)

*theta에 대한 각도 histogram을 만들어 준다.

b) h=rose(theta, x)

*length(x)는 만들어질 bins의 수를 의미하고,

벡터 x의 값들은 각각의 bins에 대한 중심각을 의미한다.

c) [tout, rout]=rose(...)

*tout과 rout벡터를 반환하여, polar(tout, rout)로부터 각도에 대한

histogram을 얻는다.

d) h=rose(theta, nbins)

*[0 2*pi]범위 안에서 균등하게 떨어진 nbins를 만들어

각도에 대한 histogram을 얻는다.

[예 제] 예를 들어서, 12시간 동안 매시간 마다 바람이 부는 방향을 측정하여 변수 wdir에 저장하였다고 하자.

wdir=[45 90 90 45 360 335 360 270 335 270 335 335];

데이터 wdir에 근거하여 바람이 부는 방향(각도)에 대한 histogram을 작성하여라.

[풀이]

우선, 주어진 데이터 wdir을 radians로 바꾸고, □rose.m□함수의 입력 변수로 넣는다.

□wdir=wdir*pi/180;

□h=rose(wdir)

□set(gcf,'color','w')

□set(gcf,'color','w')

□set(h,'color','k')

위와 같은 일련의 명령어를 실행하면, [그림 3-64]와 같은 결과를 얻는다.

[그림 3-64] □rose.m□함수의 사용 방법

[그림 3-64]로부터 바람이 12시간 동안 주로 335(degree)로 불었다는 것을 알 수 있다.

	책에는 제 3 부류에 속하는 □pie.m, pie3.m, bar.m, barh.m, bar3.m, bar3h.m, area.m, errobar.m, findobj.m ezplot.m□함수가 이 부분에서 설명된다. 단, □ezplot.m□함수는 [부록]에 실은 □symbolic math.의 사용법□에서 설명할 것이다.

제 3부류에 속하는 함수들을 설명하는 데, 그림이 23개, 표가 1개 사용되었다.

Animation :

Matlab에서 Animation이란 object를 생성하고, object의 위치를 변화시키면서 재차 생성하는 과정을 말한다.

대표적으로 demo 함수인 □lorenz.m□을 실행시키면, Matlab에서 의미하는 animation 효과를 볼 수 있다.

Matlab에서의 animation은 □EraseMode□ propertyname에 의해 여러 가지 다른 효과를 줄 수 있다.

□EraseMode□ propertyname은 주어진 object를 □언제, 어떻게□ 생성하고, 지울 것인지를 결정한다.

그런데, □EraseMode□ propertyname은 모든 object에 존재하는 것은 아니다. 단지, □lines, patches, surfaces, text□ objects에만 존재한다.

[표 3-13]에는 □EraseMode□에 대한 propertyvalue를 설명하고 있다.

[표 3-13] □EraseMode□ propertyname에 대한 설명

"EraseMode" propertyname
propertyvalue	각각의 propertyvalue에 대한 설명
normal	default propertyvalue이다. object가 갱신 될 때마다 Axes를 refresh한다. 그러므로, object에 변화가 있을 때마다 flicker가 발생한다.
background	Figure의 배경색과 같은 색으로 object를 바꾸어서 지우는 효과를 준다. 결국, 지워진 object의 데이터에 손상이 발생한다.
xor	Figure의 배경색과 object의 색에 대해 □xor□를 행하여 object를 지운다. 그러므로, 지워진 object의 데이터에 손실은 발생하지 않는다.
none	object의 변화가 있을 때, 이전 object를 지우지 않는다.

[표3-13]을 정리하면 다음과 같다.

(1) □flicker□가 발생하지 않는 animation을 만들고 싶으면, □normal□을 사용하지 말아라.

(2) □lorenz.m□함수를 실행시켜 보면, object의 변화에 따른 꼬리(trail)가 존재한다. 이와 같은 효과를 주려면 □none□을 이용하여라.

(3) 새로 생성되는 object에 의한 animation에만 관심이 있다면, □background□를 이용하여라.

(4) object의 데이터 손상을 원하지 않으면, □xor□를 이용하여라.

□fig3_65.m"는 □y=sinc(w*x)□에서 □w□의 값을 바꾸어 가면서 그래프의 변화를 살펴보는 M-file이다.

%%%%%%%%%%%%%%%%%%%% fig3_65.m %%%%%%%%%%%%%%%%%

%

%Animation에 대한 예제 :  Ani.m

%

close all

clear all

w=1;

x=-2*pi:1/100:2*pi;

y=sinc(w*x);

K=MENU('EraseMode choice : ','Xor','Normal','Background','None');

mode=str2mat('Xor','Normal','Background','None');

fig_size =[121   208   560   346];

figure('pos',fig_size);

h=plot(x,y,'erasemode',mode(K,:));

set(gcf,'color','w')

title(['Animation Type : ' mode(K,:)],'fontsize',12);

for index=1:2:20

y=sinc(index*x);

set(h,'ydata',y)

drawnow  %Figure window를 update하는 함수.

end

%%%%%%%%%%%%%%%%%%%% fig3_65.m %%%%%%%%%%%%%%%%%

앞에서 배운, □menu.m□함수를 이용하여 □EraseMode□를 선택하게 하였다.

[그림 3-66(a)]는  □Ani.m□함수를 실행 시켰을 때, 발생하는 □menu□ window이다.

이제, □Menu□ window에서 원하는 Mode를 선택하면, Matlab이 지원하는 4가지 animation mode를 볼 수 있을 것이다.

[그림 3-66(b)]는 □None□를 선택한 경우의 결과이다.

[그림 3-66(a)]

Matlab에서는 보다 편리하게, animation을 사용 할 수 있도록 □comet.m, comet3.m□함수를 제공한다.

□comet.m□함수는 하나의 작은 원(circle, comet함수의 head라고 부른다.)이 주어진 데이터를 그려나가는 함수이다. 또한, □comet.m□함수는 head가 그래프를 그려나갈 때, 긴 꼬리(trail, comet함수의 body라고 부른다.)를 갖는다.

[그림 3-66(b)] □EraseMode□가 □None□인 경우

전형적인 사용 방법(Syntax) : comet.m

comet(x, y)

→벡터 x에 대한 벡터 y값을 그려나간다.

전형적인 사용 방법(Syntax) : comet3.m

comet3(x, y, z)

→[x(i), y(i), z(i)] 점들을 통하여 하나의 곡선을 그려나간다.

[그림 3-67]는 □comet.m, comet3.m□함수들에 대한 사용 예제를 보여 주고 있다.

	□EraseMode□가 □none□인 경우, figure의 크기를 재조정하면, 가장 최근에 생성된 (또는, 그려진) object만 남고 이전에 그려진 object는 모두 소멸된다. 즉, 이전 데이터는 figure window내에서만 보일 뿐이다. 그러므로, □copy, print□ 명령을 실행하면 최종 object만 나타난다. [그림 3-67]은 screen capture로 얻은 것이다.

[그림 3-67] □comet.m, comet3.m□함수들의 사용법

Figures는 어떻게 저장되는 가?

지금까지 여러분은 많은 그래픽 tool을 배웠다. 대부분의 경우, 생성한 그래픽을 나중에 다시 보기 위하여 해당 M-file을 저장한다.

그러나, 해당 M-file을 저장하지 안고도 다시 그래프를 생성하는 방법이 있다.

이 방법은 GUI 프로그램에서도 적용되는 방법이다.

예를 들어서, [그림 3-57]을 생성 한 경우, window 화면 내의 □File□ menu를 선택하면 [그림 3-68]과 같은 결과가 나온다.

[그림 3-68] Figure에 save의 의미

이제, □Save□를 선택하면, 저장할 file 이름을 물어 볼 것이다. 알맞은 이름을 정하여 저장해본다. 여기서는, □fig3_68.m□이라고 하였다.

그러면, 해당 디렉토리에 □fig3_68.m□과 □fig3_68.mat□라는 file들이 생긴다.

여기서, 중요한 것은 □fig3_68.m□과 □fig3_68.mat□라는 file들이 갖고 있는 데이터는, 해당 그래프에 있어서 □Front-End(Layout)□에 대한 것뿐이다.

□Front-End(Layout)□은 주어진 그래프에서 눈에 보이는 부분만을 의미한다.

만일, 여러분이 GUI 프로그램을 작성하여 □Save□명령어로 저장한 경우에도 동일하게 해당 그래프에 대한 □*.m, *.mat□파일들이 생성된다. 그러나, 해당 M-file을 실행시키면 겉모습은 동일하게 생성되지만, 해당 Object를 click한 경우, GUI 프로그램이 작동하지 않는 것을 볼 수 있을 것이다.

이것은 모든 Matlab 그래프를 design하는 데는 2 가지 방법이 있기 때문이다.

(1) 눈으로 보이는 부분을 디자인하는 □Front_End layout□ part.

(2) 실제로 해당 Object에 대한 함수 기능을 디자인하는 □Coded Back_End□ part.

물론, 지금까지 설명하여 온 그래픽 함수들은 특별히 기능이 부여되지 않았으므로 □Back_End(Code)□부분은 생각하지 않아도 된다.

[부록]에 실은 □GUI 프로그램 작성법□에서는 □Back_End(Code)□부분에 대해서 알 아 볼 것이다.

[그림 3-69]는 이들 □Front_End(Layout)□part와 □Back_End(Code)□part에 대해서 설명하고 있다.

[그림 3-69] Front_End와 Back_End의 비교

일반적으로 □*.m□파일은 해당 figure를 재생산하는 M-file이고, □*.mat□파일은 text file에는 저장되기에 부적합한, 해당 figure 생성에 필요한 데이터 파일이다.

즉, □*.mat□ 파일에는 □colormap□과 □Userdata□ 따위가 저장된다.

이제, □□close all □□명령을 실행하여 모든 그림들을 command window 내에서 지운다. 그리고, □fig3_68.m□파일을 실행시키면 [그림 3-57]이 생성된다. 그런데, □title□ 부분이 만들어지지 않을 것이다. 이것은 □title□ 부분에 있는 □한글□ 때문이다.

여러분이 □guide.m□함수나 또는, 지금처럼 그래프를 저장 할 때, Matlab은 해당 그래프에 대한 M-file을 만들어 준다. 그러나, 한글이 그래프에 있으면, □한글□이 포함된 열은 cancel된다.

□fig3_68.m□파일의 내용 중에서 □한글□이 있는 부분은 글씨가 깨진 것을 볼 수 있을 것이다. 이제, □한글□이 깨진 부분을 다시 □한글□로 typing하면 □한글□이 출력 된 [그림 3-57]과 같은 화면을 얻을 수 있다.

5. 파일 입·출력

이번 단원에서는 원하는 임의의 파일을 Matlab에 읽고 쓰는 방법에 대해서 알아볼 것이다.

파일의 입·출력과 관련된 함수들

Matlab이 제공하는 파일 입·출력 함수들은 임의의 이진(arbitrary binary)파일과 형식화된(formatted) ASCII 파일을 읽고, 쓸 수 있는 여러 종류의 함수들을 제공하고 있다.

이들 함수들은 여러 가지 형식(format)으로 설정된 데이터를 읽어들이고, 또한, 다른 프로그램이나 장비에 데이터를 기록하게 해준다.

본 단원에서 살펴볼 파일 입·출력 함수들은 2가지로 분류 할 것이다.

일반적으로 많이 사용되는 □save.m, load.m□함수들에 대해서 알아본다.

이들 함수들은 다른 파일 입·출력 함수들에 비해 사용하기가 매우 용이하고, 또한, Matlab에서 데이터를 저장하고 복원할 수 있도록 제작된 최적화 된 함수들이다.

Low_level file I/O 함수들에 대해서 알아 볼 것이다.

Matlab이 제공하는 Low_level I/O 함수들의 이름은 C언어에서 제공되는 함수들과 이름이 동일하다.

그렇다면, Matlab이 제공하는 함수들과 C언어에서 제공하는 함수들간에는 어떠한 관계가 있을 가?

사실, Matlab이 제공하는 Low_level I/O함수들은 같은 이름의 C언어 입·출력 함수와 거의 동일한 기능을 한다. 여기서, □거의□라는 용어를 사용한 이유는 Matlab이 모든 피 연산자를 배열로 취급하는 반면에, C언어는 그렇지 않다는 데 있다.

즉, 기본적인 연산 단위가 Matlab에서는 배열이라는 점만 다르고, 나머지 기능은 C언어의 파일 입·출력 함수들과 동일하다고 보면 된다.

Save.m, Load.m :

보통, workspace에 있는 데이터들을 저장하는 가장 손쉬운 방법은 □save.m, load.m"함수들을 이용하는 것이다.

이제, 이들 함수들에 대해서 간략히 알아보자.

전형적인 사용 방법(syntax) : save.m

a) save filename

*모든 base workspace에 있는 데이터들을 filename에 저장한다.

b) save filename 변수들

*주어진 변수들만 filename에 저장한다.

c) save filename 변수들 option

*default format인 binary파일이 아닌, ASCII형식으로 주어진

변수들만 저장하고 싶을 때, option을 이용한다.

option에 대해서는 [표5-1]참고.

사실, □save.m, load.m"함수들을 이용하여 데이터를 저장할 때는 보통, 확장자로 □.mat"을 이용하는 것이 좋다. 또한, ASCII형식으로 저장하는 것보다는 Binary형식으로 저장하는 것이 데이터 손실도 없고 안정적이다.

만일, 복소수를 ASCII형식으로 저장한다면, 허수 부는 손실된다는 점에 유의하라!

그러므로, 필자가 권하고 싶은 데이터 파일 형식은 □확장자가 mat인 Binary"파일로 데이터를 저장할 것을 권한다.

□save.m"함수로 데이터를 저장하여 만들어진, MAT-files는 □double-precision binary MATLAB format"이다. 이들 mat-files는 다른 시스템에서도 Matlab에 의하여 쉽게 읽혀 질 수 있다. 그러나, 시스템간의 차이에 의해서 발생하는 기계적 오차(즉, eps)는 감수해야 한다.

[표 5-1]은 □save.m"함수에서 필요한 option을 정리한 것이다.

[표 5-1] □save.m"함수에서 사용되는 options

options	option에 따라 저장되는 형식
-ascii	8-digit ASCII format으로 저장한다.
-ascii -double	16-digit ASCII format으로 저장한다.
-ascii -tabs	tab에 의해서 분리된 데이터를 8-digit ASCII 형식으로 저장한다..
-ascii -double -tabs	tab에 의해서 분리된 데이터를 16-digit ASCII 형식으로 저장한다..

□save.m"함수에 의해서 저장된 데이터 파일을 복원하는 데, 사용되는 함수로는 □load.m"이라는 함수가 있다.

그 사용 방법은 다음과 같다.

전형적인 사용방법(syntax) : load.m

a) load filename

*주어진 filename에 저장된 데이터들을 복원(retrieve)한다.

b) load filename -ascii

*ASCII형식으로 저장된 filename을 복원한다.

이제, 예제를 통하여, □save.m, load.m"함수의 사용방법을 익혀 보도록 하자.

□x=magic(3)

□y='Lim Jong Su';

□z=2+3i;

□whos

Name      Size         Bytes  Class

x         3x3             72  double array

y         1x11            22  char array

z         1x1             16  double array (complex)

Grand total is 21 elements using 110 bytes

위와 같이 우선, □double"형과 □char"형의 데이터를 만들어 보자.

이제. 이들 두 가지 종류의 데이터를 확장자가 mat인 Binary파일로 저장하겠다.

□save temp_data.mat x y z	%"save temp_data.mat"라고 해도 된다.

□clear all	%"ls"명령을 실행하면, □temp_data.mat"파일이

□whos	%새로 만들어 진 것을 볼 수 있을 것이다.

□load temp_data.mat         %"clear all"명령으로 모든 데이터가 지워졌다.

□whos

Name      Size         Bytes  Class

x         3x3             72  double array

y         1x11            22  char array

z         1x1             16  double array (complex)

Grand total is 21 elements using 110 bytes

□z

z =

2.0000 + 3.0000i

결국, 데이터 x, y, z가 모두 복원되었다. 게다가, 복소수도 정확하게 복원되었다.

위에서, □save temp_data.mat"라고 해도 되는 이유는 현재 base workspace에 변수들은 모두 x, y, z뿐이기 때문이다.

확장자가 mat가 아닌 다른 확장자 명을 사용하고 싶다면 다음과 같이 하면 된다.

그러나, 확장자가 mat가 아닌 다른 파일들은 load할 때, 맨 뒤에 -mat라고 붙여 주어야 한다. -mat라고 붙여 주지 않으면, 주어진 파일을 ASCII text 파일로 간주하기 때문이다.

□save temp_data.dat x y z

□clear all

□load temp_data.dat -mat

□whos

Name      Size         Bytes  Class

x         3x3             72  double array

y         1x11            22  char array

z         1x1             16  double array (complex)

Grand total is 21 elements using 110 bytes

위와 같이 본래 데이터들이 복원되었다.

지금까지 설명한 □save.m, load.m"함수의 사용법은 사실, 더욱 간편하게 이용하는 방법이 있다.

Matlab의 command window의 File menu에 있는 □Save workspace as, Load workspace"를 사용하면 된다.

[그림 5-1]은 command window에 있는 File menu를 선택 한 경우에 나타나는 window이다.

[그림 5-1] □File□ menu

이제, base workspace에 있는 데이터들을 □limdata.mat"라는 파일에 저장하고 싶다고 하자.

base workspace에 있는 데이터들을 저장하기 위해서는 우선, □Save Workspace As..."을 선택한다. 그러면, [그림 5-2]와 같은 window가 나타날 것이다.

[그림 5-2] □Save Workspace As" window

이제, □파일 이름(N)□에 있는 □*.mat"에 □limdata.mat"라고 typing하면, □mbook□디렉토리에 새로운 파일인 □limdata.mat"라는 파일이 첨가된다.

여기서, 주의 할 것은 □limdata.mat"라는 파일에 저장되는 데이터들은 base workspace에 있는 변수들 모두라는 것이다. 그러므로, 원하는 변수들만 선택하여 저장하는 데는 부적합하다.

어쨌든. □limdata.mat"에 저장된 데이터를 복원하려면, [그림 5-1]에 있는 □Load Workspace"를 선택하면 된다.

만일, □Load Workspace"를 선택하였다면, [그림 5-3]을 얻을 수 있을 것이다.

[그림 5-3] "Load.mat file" window

이제, 복원하려는 데이터를 갖고 있는 파일이름을 □파일 이름(N)"에 typing하고, □열기(O)"버튼을 누르면, 원하는 데이터들이 base workspace에 첨가된다.

Low_level file I/O 함수들 :

사용하는 언어에 관계없이 주어진 파일을 읽고 쓰려면 제일 먼저 주어진 파일을 열어야 한다. 물론, 파일에 일고 쓰는 작업이 모두 끝났으면, 파일을 닫아 주어야 할 것이다.

이와 같은 기능을 하는 함수로는 □fopen.m, fclose.m"과 같은 함수들이 있다.

이들 함수의 이름이 꽤 눈에 익을 것이다. 바로, C언어에서도 같은 이름의 함수들이 있기 때문이다.

우선, □fopen.m"함수의 사용법을 간단히 알아보자.

전형적인 사용 방법(Syntax) : fopen.m

a) fid=fopen(파일 이름, 모드(mode))

*주어진 파일이름(확장자 포함)을 여는데(open) 성공하면,

파일 식별자(file identifier), fid에 3이상의 양의 정수를 돌려준다.

*fid는 다른 파일 I/O함수들에 첫 번째 입력 매개변수로 사용된다.

*그러나, 주어진 파일이름(확장자 포함)을 여는데(open) 실패하면,

파일 식별자(file identifier), fid에 □-1□값을 돌려준다.

b) [fid, message]=fopen(파일이름 , mode)

*만일, 주어진 파일을 읽는데 실패하면, message라는 변수에 실패한

이유가 문자열로 반환된다.

보통 Matlab 매뉴얼을 보면, 필자가 사용하는 mode라는 단어 대신에 permission이라는 단어를 사용하고 있다.

그런데, C언어에서는 permission이라는 단어보다는 mode라는 단어를 즐겨 사용한다. 그래서, 독자들로 하여금 이해를 돕기 위해서 permission이라는 단어 대신에 친숙한 mode라는 단어를 사용하고 있는 것이다.

또한, MS-Window, VMS system은 text파일과 binary파일을 읽어 들일 때, mode에 부가적인 문자를 붙여 주어야한다. 즉, text파일을 일어들일 때는 mode뒤에 □t"를 덧붙여 주어야 한다.

binary파일은 default mode이므로 □b"라고 덧붙일 필요는 없다.

그러나, Unix, Mac. system은 text파일과 binary파일의 구별이 없으므로 덧붙이는 작업은 하지 안아도 된다.

[표 5-2]는 사용할 수 있는 mode의 종류를 나타낸 것이다.

[표 5-2] mode의 종류와 설명

mode	mode에 따른 설명
□r'	default mode이고, 읽기(reading) 위해서 주어진 파일을 연다.
'r+'	읽고, 쓰기 위해서 주어진 파일을 연다.
'w'	주어진 파일 이름을 갖는 새로운 파일을 만든다. 그러나, 주어진 파일 이름과 같은 파일이 존재하면, 지우고(delete) 새로 파일을 만든다. 새롭게 만들어진 파일을 쓰기 위해서 연다.(open)
'w+'	주어진 파일 이름을 갖는 새로운 파일을 만든다. 그러나, 주어진 파일 이름과 같은 파일이 존재하면, 지우고(delete) 새롭게 파일을 만든다. 만들어진 파일을 일고, 쓰기 위해서 연다.(open)
'a'	새로운 파일을 만들고 연다(open). 그러나, 같은 이름의 파일이 존재하면, 쓰기 위해서 파일을 연다. 그리고, 파일의 끝에 데이터를 첨가해 나갈 수 있도록 해준다.(appending)
'a+'	새로운 파일을 만들고 연다(open). 그러나, 같은 이름의 파일이 존재하면, 읽고, 쓰기 위해서 파일을 연다. 그리고, 파일의 끝에 데이터를 첨가해 나갈 수 있도록 해준다.(appending)

이제, 열려있는 파일을 닫아주는 함수인 □fclose.m"에 대해서도 간단히 알아보자.

전형적인 사용 방법(Syntax) : fclose.m

a) st=fclose(fid)

*"fopen.m"함수에 의해서 반환된 파일 식별자(file identifier)를

사용하여 열려있는 파일을 닫아 준다.

*파일을 닫아 주는 데 성공하면, □0□을 돌려주고,

실패하면 □-1□을 반환한다.

b) st=fclose('all')

*열려 있는 모든 파일을 닫아 준다.

이제, 여러분은 파일을 열고 닫을 수 있는 방법을 배웠다.

이번에는 데이터 파일을 읽고, 쓰는 방법에 대해서 배워보자.

여기서는 가장 많이 사용되는 두 개의 함수들, 즉, □fprintf.m, fscanf.m"함수들에 대해서만 알아 볼 것이다.

전형적인 사용 방법(Syntax) : fscanf.m

a) count=fprintf(fid, format, A, ...)

*행렬 A에서 실수 부(real part)를 주어진 format에 맞추어

열려 있는 파일(fid)에 쓰기(write)를 행한다.

*쓰여진 bytes수는 count변수에 반환된다.

b) fprintf(format, A, ...)

*screen(standard output)에 행렬 A를 표시한다.

□fscanf.m"함수에서 언급한 □format"의 의미는 [그림 5-4]를 보면 알 수 있을 것이다.

[그림 5-4] format의 의미

즉, 주어진 배열 A를 지수형태로 변환하여, 정수부는 12자 이내로 하고, 소수부는 소수점이하 5자리까지 주어진 field안에서 왼쪽으로 맞추라는 뜻이다.

[표 5-3]은 이들 format의 형태 중에서 Escape 문자에 대한 것이다.

[표 5-3] □Escape" 문자들의 종류

Escape 문자	Escape 문자에 대한 설명
\n	New Line
\t	Horizontal tab
\b	Backspace
\r	Carriage return
\f	Form feed
\\	Backslash를 표시
\'' 또는 □□	단일 인용 부호를 표시
%%	percent 문자를 표시

또한, [표 5-4]는 Conversion Specifiers에 대한 것이다.

[표 5-4] Conversion Specifiers의 종류

Conversion Specifier	각각에 대한 설명
%c	하나의 문자로 표시
%d	십진법으로 표시(signed)
%e	지수 형태로 표시(소문자 e를 이용)
%E	지수 형태로 표시(대문자 E를 이용)
%f	고정 소수점으로 표시
%g	중요하지 않은 zeros는 표시하지 안는다. 결국, %e와 %f보다 간결한 표현
%o	8진법으로 표시(unsigned)
%s	문자열로 표시
%u	십진법으로 표시(unsigned)
%x	16진법으로 표시(소문자 a∼f를 이용)
%X	16진법으로 표시(대문자 A∼F를 이용)

이번에는 나머지 format에 관련된 문자들에 대해서 알아보자.

[표 5-5]를 참고하기 바란다.

[표 5-5] format에 관련된 문자들

format에 관련된 문자들	설명	사용 예
A minus sign(즉, - )	주어진 field의 왼쪽으로 정렬	%-5.2d
A plus sign(즉, + )	부호를 표시하게 한다. (즉, +, -)	%+5.2d
zero(즉, 0 )	주어진 field의 spaces에 zeros를 채움	%05.2d

다음은 데이터를 읽어들이는 함수인 □fscanf.m"에 대해서 알아보자.

전형적인 사용방법(Syntax) : fscanf.m

a) [A, count]=fscanf(fid, format, size)

*"fopen.m"함수에 의해서 열려있는 파일(fid)을 주어진

format에 의거하여 size에 상술된 크기로 읽어 들인다.

*count는 읽어들인 데이터의 수를 의미한다.

b) A=fscanf(fid, format)

*format에 의거하여 데이터를 읽어 들인 뒤에 열 벡터의 형태로

반환한다.

□fscanf.m"에서 언급한 size는 3가지 형태를 취할 수 있다.

다음에 나오는 내용을 보고 size가 취할 수 있는 형태에 대해서 익혀두자.

n	n개의 데이터를 열 벡터의 형태로 읽어 들인다.
inf	주어진 파일의 끝까지 읽어 들인다.
[m, n]	m×n의 크기를 갖는 행렬의 형태로 읽어 들인다. 여기서, n은 inf가 될 수 있으나, m은 될 수 없다.

이제, 여러분은 데이터를 저장하고, 읽어들이는 함수들에 대하여 학습하였다.

이번에는 배운 함수들을 사용하는 방법에 대해서 알아보자.

□X=0:.1:1;

□y=[X ; exp(X)];

□fid=fopen('exp.txt','w')	%쓰기 위해서 □exp.txt"파일을 연다.(open)

fid =

3

□count=fprintf(fid, □%6.2f %12.8f\n', y)

count =

220

□fclose('all');

위와 같이 명령하면, □exp.txt"라는 text file이 만들어진다. 그런데, 파일 식별자(fid)의 값이 □1□이 아니라, □3□이 나왔다.

그 이유는 파일 식별자가 □1□인 경에는 screen에 표시하라는 뜻이 되고, □2□인 경우에는 표준 error를 나타낸다. 그래서, 모든 파일들은 □3□부터 파일 식별자에 할당되는 것이다.

이제, □exp.txt"파일을 열어서, 데이터를 읽어보자.

□fid=fopen('exp.txt','r')	%읽기 위해서 □exp.txt"파일을 연다.(open)

□[a, count]=fscanf(fid, □%f %f\n',[2 inf]);

□a'

ans =

0    1.0000

0.1000    1.1052

0.2000    1.2214

0.3000    1.3499

0.4000    1.4918

0.5000    1.6487

0.6000    1.8221

0.7000    2.0138

0.8000    2.2255

0.9000    2.4596

1.0000    2.7183

□fclose('all');

지금까지, 여러분은 데이터를 파일에 저장하고 읽어 들이는 방법을 배웠다.

이밖에도 외부 데이터를 효율적으로 읽어 들이는 데 유용한 dialog함수들과 프린트하는 방법과 프린트 할 때 주의해야 할 점들에 대해서는 [MATLAB 완벽가이드]책에 서술하였으니 참고하기 바란다.

%%%%%%%%%%%%%%%%%   THE END    %%%%%%%%%%%%%%%%