GNU Octave 함수와 스크립트

GNU Octave 함수와 스크립트

Octave에서 계산을 재사용하려면 함수로 만들거나, 명령 묶음을 스크립트 파일로 저장해요. 함수 파일과 스크립트 파일은 둘 다 MATLAB 호환을 위해 .m 확장자를 가져요. 함수를 반복해서 호출하고 결과를 돌려받는 방법부터, 인자 개수가 유동적인 함수 만드는 법까지 살펴볼게요.

출처: GNU Octave 함수와 스크립트

본문

함수 정의

가장 단순한 함수 정의 형태는 이렇게 생겼어요.

function name
  body
endfunction

유효한 함수 이름은 유효한 변수 이름과 같아요. 숫자로 시작하지 않는 글자·숫자·밑줄의 연속이고, 함수와 변수는 같은 이름 풀을 공유해요. 함수 본문은 Octave 문장들로, 함수가 실제로 무엇을 하는지 정하는 가장 중요한 부분이에요.

인자를 받는 함수는 이렇게 정의해요.

function name (arg-list)
  body
endfunction

인자 목록은 쉼표로 구분한 함수 인자들이에요. 호출할 때 이 이름들이 전달된 인자 값을 담아요. 함수 안에서 쓰는 변수는 그 함수에 지역적이에요.

값을 하나 돌려주는 함수는 반환 변수를 이렇게 붙여요.

function retval = avg (v)
  retval = sum (v) / length (v);
endfunction

반환 변수는 함수 본문이 끝나기 전에 정의되어야 값이 반환돼요. 반환 변수가 정의되지 않으면 error: value on right hand side of assignment is undefined 같은 애매한 오류가 나요. 그래서 항상 반환 변수가 값을 갖게 하고, 문제가 생기면 의미 있는 오류 메시지를 내는 게 좋아요.

함수 정의 주의점: Octave는 인자를 너무 많이 받은 호출을 자동으로 오류 처리하지만, 인자를 너무 적게 받은 호출은 자동으로 오류를 보고하지 않아요. 함수에 기본 인자가 있을 수 있기 때문인데, 값을 주지 않은 변수를 사용하려 하면 오류가 나요.

nargin 과 nargout

Octave는 호출될 때마다 각 함수에 nargin이라는 자동 변수를 넣어줘요. 실제로 전달된 인자 개수가 담겨 있어요. 이를 이용해 인자 개수를 검사하고 usage로 사용법을 알려줄 수 있어요.

function retval = avg (v)
  retval = 0;
  if (nargin != 1)
    usage ("avg (vector)");
  endif
  if (isvector (v))
    retval = sum (v) / length (v);
  else
    error ("avg: expecting vector argument");
  endif
endfunction

nargin (fcn)은 함수가 받을 수 있는 선언된 인자 개수를 반환해요. 마지막 인자가 varargin이면 음수로 나와요. nargout은 호출자가 기대하는 반환 값 개수를 담아요. 함수가 요청된 반환 값 수에 따라 다르게 동작하게 만들 수 있어요. 예를 들어 hist는 출력 변수 없이 호출하면 히스토그램을 그리고, 출력이 있으면 히스토그램 대신 빈도수·구간 중심을 반환해요.

여러 값 반환하기

Octave는 다른 언어와 달리 여러 값을 반환하는 함수를 정의할 수 있어요.

function [ret-list] = name (arg-list)
  body
endfunction

반환 목록은 쉼표로 구분한 변수 이름들이에요. 벡터의 최대값과 그 첫 위치를 함께 반환하는 예시예요.

function [max, idx] = vmax (v)
  idx = 1;
  max = v (idx);
  for i = 2:length (v)
    if (v (i) > max)
      max = v (i);
      idx = i;
    endif
  endfor
endfunction

nthargout로 특정 반환 값만 얻을 수도 있어요. 다만 Octave는 ~ 문자로 출력을 무시하는 기능을 인터프리터 차원에서 제공해서, [~, idx] = max (...)처럼 쓰는 편이 더 효율적이에요.

가변 길이 인자: varargin / varargout

함수를 정의할 때 인자 개수를 모르는 경우가 있어요. 모든 입력 인자 중 가장 작은 값을 반환하는 함수를 예로 들어볼게요. 특수 파라미터 이름 varargin을 파라미터 목록 끝에 넣으면 함수가 가변 개수의 입력 인자를 받는다는 뜻이에요.

function val = smallest (varargin)
  val = min ([varargin{:}]);
endfunction

함수 본문에서 varargin은 모든 입력 인자를 담은 셀 배열이에요. 인자를 하나씩 찍어보는 함수는 이렇게 만들어요.

function print_arguments (varargin)
  for i = 1:length (varargin)
    printf ("Input argument %d: ", i);
    disp (varargin{i});
  endfor
endfunction

parseparams는 일반 숫자 인자와 속성/값(name-value) 쌍으로 주는 추가 인자를 분리할 때 써요. 셀 배열에서 첫 문자열 원소까지를 reg로, 그 이후를 prop로 나눠줘요.

함수와 스크립트 파일

명령 묶음을 파일에 저장하면 스크립트 파일, 함수를 파일에 저장하면 함수 파일이에요. 한 파일에 독립적인 함수가 여러 개 있으려면 반드시 스크립트 파일이어야 하고, 그 함수를 쓰려면 먼저 스크립트 파일을 실행해야 해요.

더 알아보기