Main Content

無名関数

無名関数とは

無名関数はプログラム ファイルには "保存されません" が、データ型が function_handle の変数に関連付けられている関数です。無名関数は複数の入力を受け入れることができ、1 つの出力を返します。実行可能ステートメントは 1 つしか含むことができません。

メモ

関数dealを使用して、複数の出力を返す無名関数を作成できます。例については、無名関数から複数の出力を返すを参照してください。

たとえば、数値の二乗を計算する無名関数のハンドルを作成します。

sqr = @(x) x.^2;

変数 sqr は関数ハンドルです。@ 演算子でハンドルを作成し、@ 演算子の直後にある小かっこ () に関数入力引数を含めます。この無名関数は 1 つの入力 x を受け取り、二乗する値を格納する x と同じサイズの配列を、1 つの出力として暗黙的に返します。

入力引数を標準の関数に渡すように値を関数ハンドルに渡して、特定の値 (5) の二乗を計算します。

a = sqr(5)
a =
   25

多くの MATLAB® 関数は関数ハンドルを入力として受け取るので、関数を値の範囲で評価できます。ハンドルは、無名関数またはプログラム ファイル内の関数に対して作成できます。無名関数を使用する利点は、簡単な定義のみが必要な関数に対してファイルを編集したり保守する必要がないことです。

たとえば、関数ハンドルを関数 integral に渡し、関数 sqr0 から 1 までの積分を計算します。

q = integral(sqr,0,1);

ワークスペースで変数を作成して無名関数を保存する必要はありません。その代わり、式の中で一時的な関数ハンドルを、以下の関数 integral の呼び出しのように作成できます。

q = integral(@(x) x.^2,0,1);

式内の変数

関数ハンドルは、式のほかに、式の評価に必要な変数も保存できます。

たとえば、係数 ab および c を必要とする無名関数のハンドルを作成します。

a = 1.3;
b = .2;
c = 30;
parabola = @(x) a*x.^2 + b*x + c;

parabola の作成時に ab および c を使用できるので、関数ハンドルはこれらの値を取り込みます。関数ハンドル内の値は、変数をクリアしてもそのまま存続します。

clear a b c
x = 1;
y = parabola(x)
y =
   31.5000

係数に異なる値を指定するには、新しい関数ハンドルを作成しなければなりません。

a = -3.9;
b = 52;
c = 0;
parabola = @(x) a*x.^2 + b*x + c;

x = 1;
y = parabola(x)
y =
   48.1000

関数ハンドルと関連値を MAT ファイルに保存して、関数 saveload を使用して後続の MATLAB セッションで読み込むことができます。

save myfile.mat parabola

無名関数を作成する場合は、明示的な変数のみを使用してください。無名関数が引数リストまたは本体で明示的に参照されていない変数または入れ子関数にアクセスする場合、その関数を呼び出すと MATLAB はエラーをスローします。暗黙的な変数や、関数の暗黙的な呼び出しは、多くの場合 evalevalinassignin および load などの関数で発生します。無名関数の本体では、これらの関数の使用は避けてください。

複数の無名関数

無名関数の式に、別の無名関数を含めることができます。これは、値の範囲で評価している関数に異なるパラメーターを渡すときに便利です。たとえば、次の等式

An equation for the function g of c which is equal to the integral from 0 to 1 of x squared plus c times x plus 1 times d x.

は、2 つの無名関数を組み合わせることにより、c の値が変更されても解くことができます。

g = @(c) (integral(@(x) (x.^2 + c*x + 1),0,1));

このステートメントを導き出すには、次の手順に従います。

  1. 無名関数として被積分関数を記述します。

    @(x) (x.^2 + c*x + 1)
  2. 関数ハンドルを integral に渡して 0 ~ 1 で関数を評価します。

    integral(@(x) (x.^2 + c*x + 1),0,1)
  3. 式全体に無名関数を作成し、c に値を指定します。

    g = @(c) (integral(@(x) (x.^2 + c*x + 1),0,1));

最後の関数を使うと、任意の c の値に対して式を解くことができます。以下に例を示します。

g(2)
ans =
   2.3333

入力のない関数

関数に入力が不要な場合、無名関数を定義するときおよび呼び出すときに空の小かっこを使用します。以下に例を示します。

t = @() datestr(now);
d = t()
d =
26-Jan-2012 15:11:47

代入ステートメントで小かっこを省略すると別の関数ハンドルが作成され、関数が実行されません。

d = t
d = 
    @() datestr(now)

複数の入力または出力のある関数

無名関数では、標準の関数と同様に入力引数を明示的に指定し、複数の入力がある場合はコンマで区切る必要があります。たとえば、次の関数は 2 つの入力 xy を受け取ります。

myfunction = @(x,y) (x^2 + y^2 + x*y);

x = 1;
y = 10;
z = myfunction(x,y)
z = 
111

ただし、無名関数は 1 つの出力のみを返します。関数内の式が複数の出力を返す場合、関数ハンドルを呼び出すときに要求することができます。

たとえば、関数 ndgrid は入力ベクトルと同数の出力を返すことができます。ndgrid を呼び出すこの無名関数は、1 つの出力 (mygrid) のみを返します。mygrid を呼び出して、関数 ndgrid によって返された出力にアクセスします。

c = 10;
mygrid = @(x,y) ndgrid((-x:x/c:x),(-y:y/c:y));
[x,y] = mygrid(pi,2*pi);

mygrid からの出力を使用して、メッシュまたは表面プロットを作成します。

z = sin(x) + cos(y);
mesh(x,y,z)

Figure contains an axes object. The axes object contains an object of type surface.

無名関数の配列

ほとんどの MATLAB 基本データ型は多次元配列をサポートしますが、関数ハンドルはスカラー (1 つの要素) でなければなりません。ただし、cell 配列または構造体配列を使用して複数の関数ハンドルを格納できます。最も一般的な方法は、以下のように cell 配列を使用します。

f = {@(x)x.^2;
     @(y)y+10;
     @(x,y)x.^2+y+10};

cell 配列を作成するとき、MATLAB は空白を列区切りとして解釈することに留意してください。前のコードで示されているように式から空白を削除するか、または以下のように式を小かっこで囲みます。

f = {@(x) (x.^2);
     @(y) (y + 10);
     @(x,y) (x.^2 + y + 10)};

中かっこを使用して、セルの内容にアクセスします。たとえば、f{1} は最初の関数ハンドルを返します。関数を実行するには、小かっこで囲まれた入力値を中かっこの後に渡します。

x = 1;
y = 10;

f{1}(x)
f{2}(y)
f{3}(x,y)
ans =
     1

ans =
    20

ans =
    21

関連するトピック