mir.pe (일반/밝은 화면)
최근 수정 시각 : 2024-01-18 16:35:55

MATLAB/문법

파일:상위 문서 아이콘.svg   상위 문서: MATLAB
프로그래밍 언어 문법
{{{#!wiki style="margin: -16px -11px; word-break: keep-all" <colbgcolor=#0095c7><colcolor=#fff,#000> 언어 문법 C( 포인터 · 구조체 · size_t) · C++( 자료형 · 클래스 · 이름공간 · 상수 표현식 · 특성) · C# · Java · Python( 함수 · 모듈) · Kotlin · MATLAB · SQL · PHP · JavaScript · Haskell( 모나드)
마크업 문법 HTML · CSS
개념과 용어 함수( 인라인 함수 · 고차 함수 · 람다식) · 리터럴 · 상속 · 예외 · 조건문 · 참조에 의한 호출 · eval
기타 #! · == · === · deprecated · NaN · null · undefined · 배커스-나우르 표기법
프로그래밍 언어 예제 · 목록 · 분류 }}}

1. 개요2. 자료형
2.1. 자료형 변환
3. 행렬
3.1. 행렬 생성3.2. 행렬 인덱싱3.3. 벡터화 연산
4. 시각화
4.1. 그래프 창4.2. 2차원 그래프4.3. 3차원 그래프
4.3.1. plot34.3.2. mesh, surf
5. 조건문
5.1. if-elseif-else-end5.2. switch-case
6. 반복문
6.1. for문6.2. while문
7. 함수
7.1. 사용자 정의 함수7.2. 로컬함수7.3. 익명함수7.4. 함수함수 (function functions)
8. 기타
8.1. searchpath

1. 개요

MATLAB의 문법을 설명한다.

2. 자료형

MATLAB은 동적 언어로, 자료형을 지정하지 않은 숫자는 자동으로 double 자료형이 된다. 그 외에 숫자(numeric) 자료형, 문자형, 논리형에 대한 기본 자료형 목록은 아래와 같다.
문자형은 홑따옴표로 정의하는데('a', 'qwerty' 등) numeric 자료형과 연산이 가능하다. 예를 들어 'a'-0은 소문자 'a'를 아스키 코드값으로 변환하여 97이 되고, 'A'*2는 대문자 'A'의 아스키 코드값인 65를 가져와 130이 된다.[1]

그 외에 cell(파이썬의 list와 유사), struct(C언어의 구조체와 유사), table(판다스의 데이터프레임과 유사), datatime(파이썬의 datatime과 유사), string(홑따옴표 대신 겹따옴표로 정의, 파이썬의 문자열과 비슷), function handle(파이썬의 함수 객체와 비슷), sym(기호수학의 미지수/식 표현) 등 다양한 자료형이 있다.

2.1. 자료형 변환

자료형 간 변환(캐스팅, Casting)은 다음 예시를 따른다. 다음 예시는 double 타입인 98을 문자 'b'로 변환한다.
    char( 97 + 1 )
결과:
    ans =
    'b'

다른 자료형으로의 변환은 char 대신 원하는 자료형을 적으면 된다. 단어를 끊지 않는 한, 띄어쓰기는 이 문법에 영향을 주지 않는다.

3. 행렬

MATLAB은 모든 것을 행렬로 인식한다. 숫자 하나도 1x1의 행렬로 인식하며 행렬로 확장이 가능하다. 문자열(char array) 또한 행렬로 인식한다. 예를 들어 'matlab'은 1x6 행렬이 된다.

3.1. 행렬 생성

대괄호 안에 요소를 집어넣음으로써 행렬을 만들 수 있다. 꼭 반점을 쓸 필요 없이 띄어쓰는 것만으로도 열을 구분지을 수 있다.
대괄호 안에서 세미콜론으로 새로운 행을 시작할 수 있다.
    >> a = [0,1,2,3]
a =
     0     1     2     3
>> a = [a; 4,5,6,7]
a =
     0     1     2     3
     4     5     6     7
>> 


콜론 연산자로 벡터(1차원 행렬)를 생성할 수 있다. 시작값:간격:끝값의 형태로 생성 가능하다. 간격은 생략하면 1이 들어간다.
>> a = 1:3:11
a =
     1     4     7    10
>> 


linspace로도 벡터를 생성할 수 있다. linspace(시작값, 끝값, 개수)의 문법으로 사용 가능하다. 개수는 생략하면 100이 들어간다.
>> a = linspace(0,5,6)
a =
     0     1     2     3     4     5
>> 


zeros(m,n)으로 m x n의 영행렬을, ones(m,n)으로 m x n의 모든 원소가 1인 행렬을, eye(n)으로 n x n의 단위행렬(identity matrix)을 만들 수 있다.

repmat(a, m, n)은 행렬 a를 행방향(아래 방향)으로 m번, 열방향(가로방향)으로 n번 복제한다.
>> a = [0,1;2,3];
>> repmat(a,3,2)
ans =
     0     1     0     1
     2     3     2     3
     0     1     0     1
     2     3     2     3
     0     1     0     1
     2     3     2     3
>> 


reshape의 동작은 약간 복잡하다. reshape(a, m, n)은 우선 행렬 a를 각 column을 이어붙인 column vector 형태로 만든다. (a(:)로도 이런 형태를 만들 수 있다.) 그 후 이걸 다시 m x n 행렬로 만든다. m x n 행렬로 만들 때도 (1,1) 위치에서 시작해 첫 번째 column을 먼저 채우고, 그 다음 두 번째 column을 채우는 순서로 채워진다. a의 원소가 m x n과 같지 않으면 오류가 발생한다.
>> reshape(1:20, 4,5)
ans =
     1     5     9    13    17
     2     6    10    14    18
     3     7    11    15    19
     4     8    12    16    20
>>      


변수명에 홑따옴표 하나를 붙이면 transpose를 할 수 있다.
     >> a = 1:5;
>> a'
ans =
     1
     2
     3
     4
     5
>> 

3.2. 행렬 인덱싱

MATLAB의 인덱스는 1부터 시작한다. 변수명(행번호, 열번호)의 형태로 원소에 접근 가능하다. 행번호와 열번호에는 자연수 범위가 들어갈 수 있다.
    >> a = reshape(1:20,4,5)
a =
     1     5     9    13    17
     2     6    10    14    18
     3     7    11    15    19
     4     8    12    16    20
>> a(2,3)
ans =
    10
>> a(1:3,2:4)
ans =
     5     9    13
     6    10    14
     7    11    15
>> 


end 키워드는 행 또는 열의 마지막을 뜻한다. end-1은 끝에서 하나 전까지를 뜻한다.
    >> a = reshape(1:20,4,5)
a =
     1     5     9    13    17
     2     6    10    14    18
     3     7    11    15    19
     4     8    12    16    20
>> a(2:end, 2:end-1)
ans =
     6    10    14
     7    11    15
     8    12    16
>> 


1차원 행렬(벡터)인 경우 인덱스는 하나만 쓸 수 있다.
     >> a = 1:10;
>> a(2:5)
ans =
     2     3     4     5
>> 

3.3. 벡터화 연산


행렬연산의 특이한 경우로, 행렬간의 곱을 행렬곱이 아닌 원소별 곱셈을 할 수 있다. *가 행렬곱이라면, 점을 붙인 .*는 원소별 곱셈이 된다.
     >> a = magic(3)
a =
     8     1     6
     3     5     7
     4     9     2
>> a*a
ans =
    91    67    67
    67    91    67
    67    67    91
>> a.*a
ans =
    64     1    36
     9    25    49
    16    81     4
>> 


이와 비슷한 방식으로 원소별 나눗셈, 원소별 거듭제곱을 할 수 있다. 역시 마찬가지로 연산자 앞에 점을 붙인다.
     >> a = magic(3)
a =
     8     1     6
     3     5     7
     4     9     2
>> b = reshape(1:9,3,3)
b =
     1     4     7
     2     5     8
     3     6     9
>> a./b
ans =
    8.0000    0.2500    0.8571
    1.5000    1.0000    0.8750
    1.3333    1.5000    0.2222
>> 

     >> [1,2,3].^3
ans =
     1     8    27
>> 

     >> [4,3,2].^[3,4,5]
ans =
    64    81    32
>> 

4. 시각화

4.1. 그래프 창

매트랩에서 그래프를 그리는 창을 figure라고 한다.
figure에 좌표공간(axes)을 생성하고 그 위에 그래프를 그린다.

새 figure를 여는 명령어는 다음과 같다.
    figure

figure를 핸들링할 때 사용하는 핸들 값이라는 개념이 있다. figure의 핸들 값은 독특하게도 정수로만 정해진다.
원하는 핸들 값을 갖는 figure를 열거나 선택하기 위한 명령어는 다음과 같다. 가령 예시는 10번 figure를 연다.
    figure(10)


그래프 창에 좌표공간(axes)을 나타낼 수 있다.
좌표공간을 초기화하는 명령어는 다음과 같다.
    cla


따라서 그래프를 그리기에 앞서 그래프 창과 좌표 공간을 준비해두고 싶다면 가령 다음과 같이 사용할 수 있다.
    figure
cla


이후 좌표공간에 대한 여러 명령어를 사용할 수 있다.
    figure, cla
    title('My Axes')
    xlabel('time [sec]')
    ylabel('velocity [m]')
    hold on
    grid on

title('문자열')은 좌표공간의 제목이다. 좌표공간 위에 표시된다.
xlabel('문자열')은 x축 아래에 표시하는 내용이다.
ylabel('문자열')은 y축 옆에 표시하는 내용이다.
hold on은 좌표공간에 그려지는 그래프를 잡아둔다는 의미다. 즉, 추가로 그래프를 그리더라도 기존 그래프가 사라지지 않고 여러 그래프가 나타날 수 있도록 허용한다는 의미다.
grid on은 좌표공간에 격자 무늬 가이드라인을 보여준다.

4.2. 2차원 그래프

기본적으로 문법은 아래와 같다.

     plot(x_data, y_data, 'lineSpec', name1, value1, name2, value2, ...)

>> x = 0:0.1:1;
>> y = x.^2;
>> plot(x,y,'b--s','linewidth',2, ...
'markersize',10, ...
'markeredgecolor',[0.4 0.5 0.6])
>> 

파일:plot2.png

4.3. 3차원 그래프

4.3.1. plot3

plot3은 plot을 3차원으로 확장한 것이다. plot과 동일하게 x좌표, y좌표, z좌표 벡터를 넣으면 각 점을 잇는 선분의 그래프를 그릴 수 있다. 문법 역시 plot과 동일하다.

plot3(x_data, y_data, z_data, 'lineSpec', name1, value1, name2, value2, ...)    


    >> t = 0:pi/20:10*pi;
>> xt = sin(t);
>> yt = cos(t);
>> plot3(xt,yt,t,'-o','Color','b','MarkerSize',10,'MarkerFaceColor','#D9FFFF')
>> 


파일:plot3.png

4.3.2. mesh, surf

2변수 함수에 대한 3차원 surface를 mesh나 surf로 그릴 수 있다. mesh는 면이 흰 색이고 edge에 colormap이 적용된다는 점, surf는 edge가 검은 색이고 면 색에 colormap이 적용된다는 점을 제외하면 큰 차이는 없다.

mesh나 surf를 제대로 쓰기 위해서는 meshgrid의 동작방식을 이해해야 한다. 간단히 설명하자면, x범위, y범위를 정의한 벡터를 meshgrid 함수에 넣으면 격자점의 x좌표만을 담은 행렬 xx가, 격자점의 y좌표만을 담은 행렬 yy가 생성된다.

    >> x = -1:3;
>> y = 1:4;
>> [xx,yy] = meshgrid(x,y)

xx =

    -1     0     1     2     3
    -1     0     1     2     3
    -1     0     1     2     3
    -1     0     1     2     3


yy =

     1     1     1     1     1
     2     2     2     2     2
     3     3     3     3     3
     4     4     4     4     4

>> 


이렇게 생성된 xx와 yy, 그리고 벡터화 연산을 이용하여 행렬 zz를 생성후, 아래와 같이 3차원 surface를 만들 수 있다.

    >> zz = xx.*yy.^2./(xx.^2+yy.^2);
>> surf(xx,yy,zz)


파일:surf.png

5. 조건문

5.1. if-elseif-else-end

if문의 기본 문법은 다음과 같다.
    if cond_expr1
    ...
    ...
elseif cond_expr2
    ...
    ...
else
    ...
    ...
end


cond_expr에는 logical 자료형이 들어간다. 다른 자료형이 들어갈 경우 logical 자료형으로 자동 변환되어 들어간다. 0, 0.0, false, 빈 배열은 logical 0, 그 외는 logical 1이 된다.

조건문에 논리연산자를 사용할 수 있다. &, |와 &&, ||의 동작이 약간 다른데, &와 |는 행렬간 연산이 가능하며, 각 위치별로 비교하여 logical array를 만든다. &&와 ||는 단락평가(short-circuit)가 이루어지는 대신 스칼라끼리의 연산만 가능하다. if나 while 뒤에 오는 &와 |는 자동으로 단락평가가 이루어진다.

5.2. switch-case

switch문의 기본 문법은 다음과 같다.

   switch SWITCH_EXPRESSION
   case CASE_EXPRESSION
      STATEMENTS
   case CASE_EXPRESSION
      STATEMENTS
    ...
   otherwise
      STATEMENTS
end

CASE_EXPRESSION에는 조건문을 쓸 수 없다. 정확히 말하자면 쓸 수는 있으나 제대로 동작하지 않는다. SWITCH_EXPRESSION과 CASE_EXPRESSION의 이 같은지를 확인하는 것이므로, CASE_EXPRESSION에 조건문이 들어가면 해당 조건문의 결과(logical 1 또는 logical 0)와 SWITCH_EXPRESSION이 같은지를 확인하게 되므로 제대로 동작하지 않는다.

6. 반복문

6.1. for문

기본 문법은 다음과 같다.
    for i = values
    statement1;
    statement2;
    ...
    ...
end


values에 가장 많이 쓰는 패턴은 콜론연산자(1:N)이나, 임의의 배열이 들어갈 수 있다. loop이 돌면서 i에 values의 값이 하나씩 들어가는 식으로 for문이 동작한다. values가 빈 배열일 경우 for문은 돌아가지 않고 스킵한다.

6.2. while문

기본문법은 다음과 같다.
    while cond_expr
    statements
end


cond_expr에 들어가는 조건문은 if와 동일한 문법이 적용된다.

7. 함수

MATLAB은 리터럴을 제외한 대부분은 확장자가 .m인 m파일을 기반으로 동작한다. m파일의 첫 줄이 function으로 시작하면 함수, classdef로 시작하면 클래스, 그 외에는 스크립트 파일이 된다. 함수는 m파일 뿐만 아니라 함수 핸들을 직접 만들 수 있는 익명함수(anonymous function), 다른 m파일 내부에서 정의되어 그 m파일에서만 접근 가능한 로컬함수(local function) 등이 있다.

7.1. 사용자 정의 함수

사용자 정의 함수는 m파일 저장 폴더가 searchpath 기본값에 있냐 없냐의 차이만 있을 뿐, MATLAB 및 툴박스의 함수들과 정의와 사용법이 동일하다. 사용자 정의 함수는 다음과 같은 형태로 만든다.

    function [output1, output2, ...] = function_name(input1, input2, ...)
%function_name Short description of function comes here
% additional comments
% additional comments
% ...

statements;
statements;

...
...
output1 = ...;
output2 = ...;

end


마지막 end는 필수는 아니나, m파일 내에서 로컬함수가 정의된 경우, 메인 함수를 포함한 모든 함수를 end로 닫아주거나, 모두 닫지 말아야 한다.

입력인자의 개수가 가변인 경우, varargin라는 특별한 변수를 이용할 수 있다. 함수를 아래와 같이 정의하면 이 함수는 2개의 입력은 반드시 전달되어야 하는 함수가 되며 그 이상의 입력인자는 varargin에 cell array 형태로 전달된다.

    function [output1, output2, ...] = function_name(input1, input2, varargin)

statements;
statements;

...
...
output1 = ...;
output2 = ...;

end

7.2. 로컬함수

하나의 m파일 내에서 2개 이상의 함수를 정의할 수 있다. 이때 맨 처음 정의된 함수는 메인함수이며, 그 아래에 정의된 함수는 로컬함수가 된다. 로컬함수의 정의 방법은 메인함수와 동일하나, 로컬함수는 메인함수만 접근할 수 있다는 차이점이 있다.

7.3. 익명함수

익명함수는 m파일을 만들지 않고 정의한 함수이다. 아래와 같은 방법으로 정의할 수 있다. 파이썬의 람다함수와 거의 동일한 것으로 이해할 수 있다.

    mysquare = @(x) x.^2;
myangle = @(x,y) atan(y/x);


익명함수의 사용법은 일반 사용자 정의 함수와 같다.

>> mysquare(1:5)

ans =

     1     4     9    16    25

>> 


익명함수는 정의 자체가 함수 핸들이므로, 함수 핸들을 인자로 받는 함수함수(function function)에 인자로 전달할 수 있다.

    >> fplot(mysquare,[-1 1])


파일:fplot.png

m파일로 정의된 사용자 정의 함수는 파일명 앞에 @를 붙임으로써 함수핸들로 만들 수 있다.

7.4. 함수함수 (function functions)

함수함수는 함수 핸들을 입력인자로 받는 함수이다. f로 시작하는 많은 함수들이 이에 해당된다. (fplot, fsurf, fminbnd, fzero 등)

8. 기타

8.1. searchpath

MATLAB 환경에서 접근 가능한 폴더의 목록을 searchpath라고 부른다. 이 목록은 명령창에서 pathtool 명령을 통해 보거나 수정할 수 있다. 명령창이나 m파일을 통해 다른 m파일을 호출하기 위해서는 호출할 m파일이 searthpath 폴더 어딘가에 들어있어야 한다. 그렇지 않을 경우 정의되지 않은 함수 또는 변수라는 에러가 발생한다.

기본적으로 현재 폴더가 최우선이 되며, 그 다음으로 searthpath의 상단부터 순서대로 m파일을 검색한다. ( 함수 우선순위)


[1] 각 문자와 대응되는 값은 기본적으로 유니코드의 utf-8 인코딩을 따르는 것으로 설정되어 있다.