Main Content

スクリプトと関数

概要

MATLAB® は、対話形式の計算環境と同様に強力なプログラミング言語を提供します。MATLAB コマンド ラインから 1 つずつ言語のコマンドを入力するか、MATLAB 関数を実行するように一連のコマンドをファイルにして実行できます。関数ファイルを作成するには、MATLAB エディターまたはその他のテキスト エディターを使用します。その他の MATLAB 関数またはコマンドを呼び出すのと同様に、これらの関数を呼び出します。

プログラム ファイルには 2 種類のものがあります。

  • スクリプト、このファイルは、入力引数を受け入れたり、出力引数を出力したりしません。このファイルは、ワークスペースの中のデータで機能します。

  • 関数、このファイルは、入力引数を受け入れ、出力引数を出力します。内部変数は、関数のローカル変数です。

MATLAB のプログラミングをはじめて行う場合は、実行するプログラム ファイルを現在のフォルダーに作成してください。ユーザー自身のファイルを多数作成したときには、他のフォルダーや個人のツールボックスにそれらをまとめて、MATLAB の検索パスに加えてください。

関数名が重複すると、MATLAB は検索パスの中で最初に現れるファイルを実行します。

たとえば、プログラム ファイル myfunction.m の内容を表示するには、次のようにします。

type myfunction

スクリプト

"スクリプト" を読み込むと、MATLAB は、単にファイルの中のコマンドを実行します。スクリプトは、ワークスペースの中に存在するデータを取り扱う、または演算するための新しいデータを作成します。スクリプトは、出力引数を出力しませんが、作成する変数はワークスペースに残り、その後の計算に使われます。加えて、スクリプトは、plot コマンド等を使って、グラフィカル出力を作成することができます。

たとえば、次の MATLAB コマンドを含んだ magicrank.m と呼ばれるファイルを作成します。

% Investigate the rank of magic squares
r = zeros(1,32);
for n = 3:32
   r(n) = rank(magic(n));
end
bar(r)

ステートメント

magicrank

により、MATLAB はコマンドを実行し、最初の 30 個の魔方陣のランクを計算し、結果を棒グラフにプロット表示します。ファイルの実行が終了すると、変数 nr がワークスペースに残ります。

関数

関数は、入力引数をもち、出力引数を出力するファイルです。ファイルの名前と関数の名前は同じものにしてください。関数 M ファイルは、それ自身がもつワークスペースの中で変数を使い、MATLAB コマンド プロンプトでアクセスするワークスペースと区別します。

良い例は、rank を使って示されます。ファイル rank.m は、次のフォルダーにあります。

toolbox/matlab/matfun

ファイルの内容は、次のコマンドで表示されます。

type rank

内容は、次のとおりです。

function r = rank(A,tol)
%   RANK Matrix rank.
%   RANK(A) provides an estimate of the number of linearly
%   independent rows or columns of a matrix A.
%   RANK(A,tol) is the number of singular values of A
%   that are larger than tol.
%   RANK(A) uses the default tol = max(size(A)) * norm(A) * eps.

s = svd(A);
if nargin==1
   tol = max(size(A)') * max(s) * eps;
end
r = sum(s > tol);

関数の最初の行は、function というキーワードで始まります。これは、関数名と引数の順序を与えるものです。この場合、入力引数は 2 つで、出力引数は 1 です。

最初の空白行または実行可能行までの数行は、ヘルプ テキストを与えるコメント行です。これらの行は、ユーザーが

help rank

と入力すると表示されます。ヘルプ テキストの最初の行は H1 ラインと呼ばれ、lookfor コマンドを使用するか、またはフォルダー上の help を呼び出すことにより MATLAB で表示されるものです。

ファイルの残りは、関数を定義している実行可能な MATLAB コードです。最初の行の中の変数 rAtol と同様に関数の中に導入されている変数 s は、すべて関数の "ローカル" 変数です。すなわち、MATLAB ワークスペースの中の変数とは異なるものです

この例は、MATLAB 関数の一つの見方を示すもので、通常の他のプログラミング言語の中には見られません。すなわち、引数の数を可変にできます。関数 rank は、種々の方法で使うことができます。

rank(A)
r = rank(A)
r = rank(A,1.e-6)

多くの関数はこのように機能します。出力引数を設定しなければ、結果は ans に保存されます。2 番目の入力引数が設定されなければ、関数は既定の値を使って計算します。関数の中で、narginnargout と名付けられた 2 つの量は、関数の中で特殊な使い方で、入力引数の数や出力引数の数を出力するものです。関数 rank は、nargin を使っていますが、nargout は使う必要がありません。

関数のタイプ

MATLAB は、プログラミングで利用する異なるタイプの関数を提供しています。

無名関数

"無名関数" は、シンプルな形式の MATLAB 関数であり、単一の MATLAB ステートメント内で定義されます。これは、単一の MATLAB 表現と任意数の入出力引数で構成されます。無名関数は、MATLAB コマンド ラインから、または関数やスクリプト内で定義できます。これは、ファイルをその都度作らなくても単純な関数を簡単に作成できる方法です。

式から無名関数を作成するための構文は、以下のとおりです。

f = @(arglist)expression

下記のステートメントは、数値のニ乗を計算する無名関数を作成します。この関数を呼び出すと、MATLAB は渡された値を変数 x に割り当て、x を使って x.^2 式を計算します。

sqr = @(x) x.^2;

関数 sqr を実行するには、次のように入力します。

a = sqr(5)
a =
   25

メイン関数とローカル関数

無名でない関数はファイル内で定義しなければなりません。各関数ファイルには、必須の "メイン関数" を先頭とし、それに続いて任意の数の "ローカル関数" が含まれます。メイン関数はローカル関数よりも広い範囲をもちます。つまり、メイン関数はそれを定義するファイルの外 (たとえば、MATLAB コマンド ラインや他のファイル内の関数など) から呼び出せますが、ローカル関数は呼び出せません。ローカル関数は、そのファイル内のメイン関数と他のローカル関数からのみ参照できます。

関数の節に示した関数 rank は、メイン関数の例です。

プライベート関数

"プライベート関数" は、メイン関数の 1 つのタイプです。プライベート関数の固有な特徴は、他の関数の限られたグループからのみ、見ることができる点です。このタイプの関数は、関数へのアクセスを制限する場合、または関数のインプリメンテーションを外部に見えないように選択する場合に有効です。

プライベート関数は特別な名前 private でサブフォルダーに格納されます。これらは親フォルダー内の関数のみが参照できる関数です。たとえば、フォルダー newmath が MATLAB 検索パス上にあると仮定します。private という newmath のサブフォルダーには、newmath 内にある関数のみから呼び出せる関数を含めることができます。

プライベート関数は親フォルダーの外からは参照できないため、他のフォルダー内で同じ関数名を使用できます。この機能は、他のフォルダーに元の関数を残したまま、特定の関数の固有バージョンを作成する場合に便利です。MATLAB では、標準のファイル関数よりも先にプライベート関数が検索されるため、プライベートではないファイル test.m より先に、test.m というプライベート関数が検索されます。

入れ子関数

他の関数の本体内で関数を定義できます。これらは、外部関数の "入れ子" と呼ばれます。入れ子関数には、他の関数のいずれか、またはすべてが含まれています。次の例では、関数 B は関数 A の入れ子です。

function x = A(p1, p2)
...
B(p2)
   function y = B(p3)
   ...
   end
...
end

他の関数と同様に、入れ子関数は、関数が用いる変数を格納する独自のワークスペースをもちます。しかし、入れ子になっているすべての関数のワークスペースにもアクセスします。そのため、たとえば、メイン関数によって割り当てられた値をもつ変数は、メイン関数内の任意のレベルの入れ子関数によって読み込み、または上書きすることができます。同様に、入れ子関数内に代入された変数は、その関数を含む任意の関数によって読み込み、または上書きすることができます。

グローバル変数

1 つの変数の単一コピーを共有し、複数の関数で使いたい場合、変数をすべての関数の中で単に global として宣言してください。変数をアクセスするために基本ワークスペースを使う場合、コマンド ラインで同じこと (グローバル宣言) をします。グローバル宣言は、変数が実際に関数の中で使われる前に行わなければなりません。絶対に必要ではありませんが、大文字を使うことにより、他の変数と区別できて便利です。たとえば、falling.m というファイルに新しい関数を作成します。

function h = falling(t)
global GRAVITY
h = 1/2*GRAVITY*t.^2;

そして、対話的にステートメントを入力します。

global GRAVITY
GRAVITY = 32;
y = falling((0:.1:5)');

2 つのグローバル ステートメントが、関数の内部で利用可能なコマンド プロンプトで GRAVITY に値を割り当てます。いくつかのファイルを編集しないで、対話的に GRAVITY を変更して、新しい解を得ることもできます。

コマンドと関数構文

かっこや引用符を使わずに文字引数を受け取る MATLAB 関数を作成することができます。つまり、MATLAB は

foo a b c

として

foo('a','b','c')

ただし、引用符なしのコマンド形式を使う場合、MATLAB は出力引数を返せません。たとえば、次の例を考えてみましょう。

legend apples oranges

は、applesoranges をラベルとして使用してプロットに凡例を作成します。legend コマンドにより出力引数を出力させたい場合は、引用符付きの形式を使う必要があります。

[legh,objh] = legend('apples','oranges');

さらに、引数のいずれかが文字ベクトルでない場合も引用符付きの形式を使用しなければなりません。

注意

引用符なしのコマンド構文は便利である一方、MATLAB がエラーを出す原因とならないながらも、不適切に使用される場合があります。

コード内での文字引数の作成

引用符付きの関数形式を使って、コード内で文字引数を作成することができます。次の例は、複数のデータ ファイル、August1.datAugust2.dat 等を処理します。ファイル名を作成するために整数を文字に変換する関数 int2str を使っています。

for d = 1:31
   s = ['August' int2str(d) '.dat'];
   load(s) 
   % Code to process the contents of the d-th file
end