GNU Octave 2.1.x 日本語マニュアル/関数とスクリプトファイル

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動

13 関数とスクリプトファイル[編集]

込み入ったOctave プログラムは,関数を定義することにより,しばしば単純化することができます。

関数は,対話的Octave セッションの間にコマンドラインから,あるいは外部ファイル内で直接定義することができ,組み込み関数のように呼び出すことができます。

13.1 関数の定義[編集]

その最も単純な形式において,name という名前の関数の定義は,以下のように見えます。

	function name
		body
	endfunction

妥当な関数名は,妥当な変数名のようなものです。 すなわち,連続する文字,数字およびアンダース コアであって,先頭が数字ではないものです。 関数は,名前のプールを変数と共有します。

関数の本体body は,Octave ステートメントから構成されます。 これは,定義の最も重要な部分です。 なぜならば,この部分は,関数が実際に何を実行するべきかを述べているからです。 たとえば,実行時に,端末のベルを鳴らす関数を示します(それが実行可能であると仮定します)。

	function beep
		printf ("\a");
	endfunction

printfステートメント(Chapter 16 [Input and Output]を参照)は,単にOctaveに文字列"\a"を表示するように伝えます。 特殊文字"\a" は,警告文字(アスキーコード7)を表します。 Chapter 5 [Strings]を参照してください。 一度この関数を定義すると,関数名を打ち込むことにより,Octave にそれを評価するように伝えることができます。 普通なら,自分が定義した関数に,何らかの情報を渡したいと思うでしょう。 Octaveでは,ある関数にパラメータを渡すための文法は,

	function name (arg-list)
		body
	endfunction

となります。 ここでarg-list は,関数の引数をカンマで区切ったリストです。 関数を呼び出すとき,引数の名前は,その呼び出しにおいて与えた引数値を保持するために使用されます。 引数のリストは空でもかまいません。 この場合,この形式は,最初に示した形式と同じものになります。 ベルを鳴らすとともにメッセージを表示するには,beep関数を,以下に示すように変更すればよいのです。

	function wakeup (message)
		printf ("\a%s\n", message);
	endfunction

以下のようなステートメントを用いて,この関数を呼び出すと,

	wakeup ("Rise and shine!");

Octave は,端末のベルを鳴らし,‘Rise and shine!’というメッセージを表示して改行(printfステートメントの最初の引数にある‘\n’)します。 大部分の場面において,自分で定義した関数から,何らかの情報を得たいこともあるはずです。 ある1 つの値を返す関数を書くための文法は,以下のようなものです。

	function ret-var = name (arg-list)
		body
	endfunction

ret-varは,関数によって返される値を保持することになる変数名です。 この変数は,関数が値を返すようにするために,関数本体の終わりまでに定義されていなければなりません。 関数の本体において使用される変数は,その関数に対してローカルなものです。 arg-listおよびret-varに名前を挙げた変数も,その関数内のローカルなものです。 関数内からグローバル変数にアクセスするための方法について,より多くの情報は,Section 9.1 [Global Variables]を参照してください。 たとえば,あるベクトルの要素の平均値を計算する関数を示します。

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

もし,代わりに以下のようなavgを書いたとして,

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

さらに,引数としてベクトルの代わりに行列を用いて関数を呼び出すならば,Octave は以下のようなエラーメッセージを表示することになるでしょう。

	error: `retval' undefined near line 1 column 10
	error: evaluating index expression near line 7, column 1

なぜならば,ifステートメントの本体は決して実行されず,retval は決して定義されないからです。

このような目立たないエラーを避けるために,戻り値が常に値をもつようにいつでも確認をしたり,問題に遭遇したときに, 有用なメッセージを出すことは良い心がけです。 たとえば,avg関数は,以下のように書いてあれば良かったのです。

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

この関数には,まだもう一つの問題が存在します。 もしこの関数が引数を付けずに起動されたら?ということです。 エラーチェックを追加しなくとも,おそらくOctave は,実際にはエラーの原因を突き止める手助けにはならないような,エラーメッセージを表示するでしょう。 このようなエラーを捕獲ことができるようにするために,Octave には,各々の関数についてnarginなる自動設定変数を提供しています。 関数が呼び出されるたびに,narginは自動的に,実際に関数に渡された引数の数に初期化されます。 たとえば,avg を以下のように書き換えたとしましょう。


	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

期待したよりも多くの引数を付けてこの関数を呼び出すとき,Octave は自動的にエラーを報告しませんが,おそらく何かがおかしいことを示します。 引数の数が少なすぎるときも,Octave はエラーを自動的に報告しませんが,値を与えられていない変数を使用しようという試みは,エラーになるでしょう。 このような問題を避け,役立つメッセージを提供するためには,両方の可能性をチェックし,独自のエラーメッセージを出すようにします。

nargin ()[編集]

                                                           [Built-in Function]

nargin (fcn_name)[編集]

                                                           [Built-in Function]

ある関数の内部で,その関数に渡された引数の数を返します。 トップレベルでは,Octave に渡されたコマンドライン引数の数を返します。 もしオプション引数fcn name を付けて呼び出すならば,その関数が受け入れることのできる引数の最大数を返します。 もしその関数が不定数の引数を受け入れるならば,-1 を返します。

silent_functions[編集]

                                                           [Built-in Variable]

もしsilent_functionsの値がゼロでなければ,関数からの内部出力が抑制されます。 そうでなければ,セミコロンで終わっていない関数本体内の式の結果は,その値が出力されます。 標準状態は0です。 たとえば,もし以下の関数

	function f ()
		2 + 2
	endfunction

を実行するならば,Octave はsilent_functionsの値に依存して,‘ans = 4’と表示したり,何も表示しなかったりします。

warn_missing_semicolon[編集]

                                                           [Built-in Variable]

もしこの変数の値がゼロでないならば,関数定義内のステートメントがセミコロンで終わっていないときに警告を表示します。 標準状態は0 です。

13.2 複数の戻り値[編集]

多くの他のコンピュータ言語とは異なり,Octaveでは,1 つ以上の値を返す関数が定義できるようになっています。 複数の値を返す関数を定義するための文法は,以下のようなものです。

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

ここでname,arg-list およびbody は,以前のものと同じ意味であり,ret-list は,関数から戻った値を保持することになる変数名をカンマで区切ったリストです。 戻り値のリストは,少なくとも1つの要素を持っていなければなりません。 もしret-list が1 つの要素しか含まないならば,このfunctionステートメントの形式は,前の節で解説した形式と等価です。 あるベクトルの最大の要素と,その値がそのベクトルに最初に出現するインデックスの,2つの値を返す関数の例を示します。

	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

この具体例において,2 つの値は単一の配列の要素として返されることになります。 しかし,これが常に可能であったり便利だったりするわけではありません。 返される値は,整合性のある次元でないこともあります。 また,個々の返り値に別個の名前を与えることは,しばしば好ましいものです。 関数が呼ばれるたびにnarginをセットすることに加え,Octave は,nargoutを,返されると期待される値の数に初期化します。 これは,関数のユーザがリクエストした値の数に依存して,異なる挙動をするような関数を書くことができるようにします。 組み込み変数ansへの暗黙的な代入は,出力引数のカウントにおいて,判断されません。 ゆえに,nargoutの値はゼロになります。

svdとlu関数は,nargoutの値によって異なる挙動をする組み込み関数の例です。 ある戻り値のみをセットする関数を書くことが可能です。 たとえば,以下ある関数

	function [x, y, z] = f ()
		x = 1;
		z = 2;
	endfunction

について,以下のように呼び出すとします。

	[a, b, c] = f ()

その結果は,

	a = 1
	b = [](0x0)
	c = 2

であり,組み込み変数warn_undefined_return_valuesがゼロでないならば,警告が発生します。

nargout ()[編集]

                                                           [Built-in Function]

nargout (fcn_name)[編集]

                                                           [Built-in Function]

ある関数の内部で,呼び出し側が受け取ことを期待する値の数を返します。 もしオプション引数fcn nameを付けて呼び出すならば,その関数が返すことのできる戻り値の最大数を返します。 もしその関数が不定数の戻り値を返すならば,-1 を返します。 たとえば,

	f ()

は,関数fの内部ではnargoutが0 になり,また,

	[s, t] = f ()

この関数fの内部では,nargoutが2となります。 トップレベルでは,nargoutは定義されません。

warn_undefined_return_values[編集]

                                                           [Built-in Variable]

もしwarn_undefined_return_valuesがゼロでないならば,ある関数が期待される戻り値のリストにおいて1つでも値が定義されていないときに, 警告を表示します。

nargchk (nargin_min, nargin_max, n)[編集]

                                                           [Function File]

もしn がnargin min からnargin max までの範囲にあるならば,空行列を返します。 そうでなければ,n が大きすぎるか小さすぎるかどうかを示すメッセージを返します。 この関数は,関数に与えた引数の数が,受け入れられる範囲内にあることを確かめるために便利です。

13.3 可変長の引数リスト[編集]

13.4 可変長の戻り値リスト[編集]

13.5 関数からのリターン[編集]

ユーザ定義関数の本体は,returnステートメントを含むことができます。 このステートメントは,制御をOctave プログラムの残り部分に戻します。 それは,以下のような使い方をします。

	return

C 言語におけるreturnとは異なり,Octave のreturnステートメントは,ある関数から値を返すために使用することはできません。 かわりに,functionステートメントの一部である戻り値変数のリストに,値を割り当てなければなりません。 returnステートメントは,深く入れ子になったループあるいは条件つきステートメントから,その関数を終了することを単に容易にするものです。

あるベクトルのいずれかの要素がゼロでないかどうかを確認することを,チェックする関数の例です。

	function retval = any_nonzero (v)
		retval = 0;
		for i = 1:length (v)
			if (v (i) != 0)
				retval = 1;
				return;
			endif
		endfor
		printf ("no nonzero elements found\n");
	endfunction

この関数は,そのベクトルがゼロでない要素を含んでいるときに,メッセージの表示を回避するための余計なロジックを加えること無しに, 一度ゼロでない値を発見した場合に,ループを終了するためのbreakステートメントを使用して書き直すことができないのです。

	return [Keyword]

Octave が,ある関数内あるいはスクリプト内でreturnキーワードに遭遇するとき,直ちに制御を呼び出し元に戻します。 トップレベルでは,return ステートメントは無視されます。 returnステートメントは,どの関数定義にも末尾に仮定されます。

13.6 関数ファイル[編集]

単純な1 回完結のプログラムを除き,必要なときに毎回,必要とするすべての関数を定義しなければならないことは実用的ではありません。 かわりに,通常はそれらをファイルに保存しておきたいと思うでしょう。 そうすれば,簡単に編集することができ,後で使うために保存しておくことができます。 Octave は,使用前にファイルから関数定義を読み込む必要はありません。 Octave が発見できる場所にファイルを置いておき,単に関数定義名を入力する必要があるだけです。 Octave が未定義の識別子に遭遇すると,すでにコンパイルされて現時点でシンボルテーブルに掲載されている変数または関数を最初に探します。 もし,ここでその定義を見つけられなかったならば, 未定義の識別子と同じベース名をもち,‘.m’で終わるファイルを,組み込み変数LOADPATHによって 指定されたディレクトリのリストから検索します。 一度Octave がマッチするファイルを見つけると,ファイルの中身を読み込みます。 もし,そのファイルに1 個の関数が定義されているならば,その関数がコンパイルされて実行されます。 ある単一のファイルに複数の関数を定義するにはどうするのかについてさらなる情報はSection 13.7 [Script Files]を参照してください。

Octave が関数ファイルから関数を定義するときには,それを読み込んだファイルの完全な名前とタイムスタンプをを保存します。 その後,その関数が必要になったときに毎回,そのファイルのタイムスタンプをチェックします。 もしタイムスタンプが,最後に読み込んだ時間以降に変更されたことを示すならば,Octave は再度そのファイルを読み込みます。

タイムスタンプをチェックすることにより,Octave の実行中に,関数の定義を編集することができるようになり,Octaveセッションを再起動することなく,新たな関数定義を自動的に使用できます。 ある関数を使用するたびにタイムスタンプをチェックすることは非効率ですが,正しい関数定義を使用できるようにするために必要なのです。

変更されていないと思われる関数のタイムスタンプをチェックすることによるパフォーマンスの悪化を避けるために,Octaveは, ディレクトリ‘octave-home/share/octave/version/m’ に存在する関数ファイルは変更されないと仮定します。 ですから,それらのファイルで定義されている関数を使用するたびにチェックは行われません。 これは,普通は非常によい仮定であり,Octave とともに配布される関数ファイルについてパフォーマンスを有意に向上させます。

もしOctave を実行しているあいだに,自作の関数ファイルが変更されないことが分かっているならば, 変数ignore_function_time_stampに"all" とセットすることにより,パフォーマンスを向上させることができます。 この変数に"system"をセットすると,標準の挙動になります。 もしこれ以外の何かの値をセットするならば,Octave は全ての関数ファイルについてタイムスタンプをチェックするようになります。

DEFAULT_LOADPATH[編集]

                                                           [Built-in Variable]

関数ファイルを検索するディレクトリを,コロンで区切って並べたもの。この変数の値は,組み込み変数LOADPATHに現れた先頭, 末尾あるいは二重のコロンへと自動的に代入されます。 ‘.m’という拡張子は,Matlab との互換性のために選ばれたものです。

LOADPATH[編集]

                                                           [Built-in Variable]

関数ファイルを検索するディレクトリを,コロンで区切って並べたもの。 詳細はChapter 13[Functions and Scripts]を参照してください。 LOADPATHの値は,環境変数OCTAVE_PATHを上書きします。 これについては付記C [Installation]を参照してください。 LOADPATHは,TEX がTEXINPUTSを処理するのと同じ要領で処理されます。LOADPATHの先頭, 末尾あるいは二重に出現するコロンは,DEFAULT_LOADPATHの値で置き換えられます。 LOADPATHの初期値は":"です。 これは,DEFAULT_LOADPATHによって指定されたディレクトリを検索するようOctave に伝えるものです。 さらに,いずれかのパス項目が‘//’で終わっているならば,そのディレクトリと,それに含まれる全てのサブディレクトリに対して関数ファイルを再帰的に検索します。 これにより,Octaveが関数を最初に検索するときに,LOADPATH内で発見したファイルのリストをキャッシュしておくため,わずかに遅くなります。 その後,Octave はファイルの内部キャッシュを検索するだけなので,通常はより高速に検索します。

再帰的ディレクトリ検索のパフォーマンスを向上させるために,再帰的に検索される各ディレクトリについて,追加的なサブディレクトリあるいは関数ファイルのどちらか片方を含め,両者を混ぜないのが最善です。

Octave とともに配布される関数ファイルディレクトリの説明は,Section 13.10 [Organization of Functions]を参照してください。

 rehash ()[編集]

                                                           [Built-in Function]

Octave のディレクトリキャッシュを再初期化します。

 file_in_loadpath (file)[編集]

                                                           [Built-in Function]

 file_in_loadpath (file, "all")[編集]

                                                           [Built-in Function]

LOADPATHによって指定されたディレクトリのリストの中に,file が見つかるならば,file の絶対名を返します。 もしファイルが何も見つからないならば,空行列を返します。 もし最初の引数が文字列のセル配列ならば,セル配列の要素についてLOADPATHの各ディレクトリを検索し,マッチした最初のファイル名を返します。 もし2番めのオプション引数"all"を与えるならば,そのパスにおいて同じ名前を持つ全てのファイル名のリストを含むセル配列を返します。 もし何もファイルが見つからなければ,空のセル配列を返します。

 ignore_function_time_stamp[編集]

                                                           [Built-in Variable]

この変数は,関数ファイル内で定義された関数を検索するたびに,Octaveがシステムコールstatを実行しないようにするために使用します。 もしignore_function_time_stampが"system"であれば, Octave は‘octave-home/lib/version’のサブディレクトリに存在する関数ファイルを自動的に再コンパイルしないようになります。 たとえ,それが最後にコンパイルされたときから変更されていたとしても,です。 しかし,LOADPATHに存在するその他の関数は,変更されていれば再コンパイルされます。 この変数に"all"をセットすると,関数定義をclearで削除しない限り,Octave はどの関数ファイルも再コンパイルしないようになります。 ignore_function_time_stampにそれ以外の値をセットすると,Octave は,関数ファイルで定義された関数を再コンパイルするかどうかを,常にチェックするようになります。 ignore_function_time_stampの初期値は"system" です。

 warn_function_name_clash[編集]

                                                           [Built-in Variable]

もしwarn_function_name_clashの値がゼロでないならば,ある関数ファイル内で定義されている関数が, そのファイル名と異なることを発見したときに,警告を発生する(もし名前が合わなければ,ファイル内で宣言した関数名は無視される)。 もしこの値が0 ならば,警告を省略します。 初期値は1 です。

 warn_future_time_stamp[編集]

                                                           [Built-in Variable]

もしこの変数の値がゼロでないならば,未来のタイムスタンプを持つ関数ファイルを発見したときに警告を表示します。

 13.7 スクリプトファイル [編集]

スクリプトファイルとは,(大部分が)一連のOctave コマンドを含むファイルのことです。 これは,各々のコマンドをOctave プロンプトで打ち込んだかのように読み込まれ,評価されます。 また,スクリプトファイルは,関数には論理的になじまないコマンド群を実行するための便利な方法を提供します。 関数ファイルとは異なり,スクリプトファイルは,functionキーワードで始まりません。 もしそうなっていれば,Octave はこれが関数ファイルであって,定義されてすぐに評価されるべき1個の関数を定義してあると仮定するでしょう。 スクリプトファイルは,そのファイル内で名付けた変数がローカル変数ではなく, コマンドラインで見ることのできる変数と同じスコープであるという点においても関数ファイルとは異なっています。 あるスクリプトファイルがfunctionキーワードで始まることはないとしても,1つのスクリプトファイル内に複数の関数を定義すること, そして,それらのすべてを一度に読み出す(でも実行はしない)ことは可能です。 これを行うには,ファイルの最初のトークン(コメントと空白を無視した部分)が,function以外の何かでなければなりません。 もし評価すべきステートメントが他に無いならば,以下のように,何も効果のないステートメントを使うと良いでしょう。

	# Octave に,これが関数ファイルであると見なさない
	# ようにする:1;
	# 関数one の定義:
	function one ()
		...

これをOctave に読み込ませ,これらの関数を内部形式にするためには,このファイルをOctaveのLOADPATHに確実に置く必要があります。 その後,このコマンドを含むファイルのベース名を,単純に入力すればよいのです (Octave は,スクリプトファイルを検索するために,関数ファイルの検索と同じルールを使用します)。 もしファイル内の最初のトークン(コメントを除く)がfunctionならば,Octaveは, 空白ではない文字が関数定義の後に出現することについての警告を表示しつつ,その関数をコンパイルしてそれを実行しようとするでしょう。 評価する必要があるまで,Octave は任意の識別子の定義を調べようとしないことに注意してください。 このことは,もし以下のステートメントがスクリプトファイルに現れるか,コマンドラインで入力されるならば,Octave はそれをコンパイルすることを意味します。

	# 関数ファイルではありません:
	1;
	function foo ()
		do_something ();
	endfunction
	function do_something ()
		do_something_else ();
	endfunction

たとえ,関数fooで参照する以前にdo_somethingが定義されていないとしてもです。 この例はエラーになりません。 なぜならば,Octave はその関数が実際に実行されるまで,ある関数によって参照される全てのシンボルを解決する必要がないためです。 Octave は,必要があるまで定義を探さないので,以下のコードは,コマンドラインで直接入力されたか,スクリプトファイルから読み込まれたか, あるいは関数の本体であるかにかかわらず,常に‘bar = 3’と表示するでしょう。 たとえ,Octave のLOADPATHの‘bar.m’を呼び出す関数またはスクリプトファイルが存在したとしてもです。

	eval ("bar = 3");
	bar

関数本体内で現れるこのようなコードは,もし定義が,その関数がコンパイルされているとして解決されたならば,Octaveを惑わします。 このコードを矛盾のない方法で評価できるくらいまでOctaveを賢くすることは,不可能と言ってもいいでしょう。 パーサが,コンパイル時にevalの呼び出しを実行することができ, そして,評価されるべき文字列における全ての参照も解決されない限りは不可能であって, さらに,それは限定的すぎること(その文字列はユーザ入力に由来するかもしれないし, ある関数が評価されるまでは知り得ないことに依存するかもしれない)を要求するからです。

普通なら,Octave は‘file.m’なる名前をもつスクリプトファイルからコマンドを実行しますが, 任意のファイルからコマンドを実行するには,source関数を使用することになります。

 source (file) [編集]

                                                           [Built-in Function]

fileの内容をパースし,実行します。 これはスクリプトファイルからコマンドを実行することと等価ですが,ファイルが‘file.m’という名前である必要がありません。

 13.8 動的にリンクされる関数 [編集]

あるシステムでは,Octave は,C++言語で書かれた関数を動的にロードして実行することができます。 Octave はC++で書かれた関数を直接呼び出すことだけしかできません。 しかし,他の言語で書いた関数も,C++で書いた単純なラッパ関数から呼び出すことにより,ロードすることができます。

Octave がロードすることのできるC++関数を書くための方法の一例を,コメント付きで示します。 この関数のソースは,Octave のソース配布において,‘examples/oregonator.cc’として含めています。 この例は,Section 23.1 [Ordinary Differential Equations]の例題において使用しているのと同じ微分方程式を定義しています。 その例とこのコードを実行することにより,動的リンク関数を使用することによって期待される速度向上の性質を確認するために実行時間を比較できます。 ‘oregonator.cc’において定義された関数は,8 つのステートメントのみを含み,対応するM-ファイル (これもOctave とともに,‘examples/oregonator.m’ として配布されています)において定義されたコードと,それほど大きな違いはありません。

‘oregonator.cc’の完全なテキストです:

	#include <octave/oct.h>
	DEFUN_DLD (oregonator, args, ,
	"The `oregonator'.")
	{
		ColumnVector dx (3);
		ColumnVector x (args(0).vector_value ());
		dx(0) = 77.27 * (x(1) - x(0)*x(1) + x(0)
				- 8.375e-06*pow (x(0), 2));
		dx(1) = (x(2) - x(0)*x(1) - x(1)) / 77.27;
		dx(2) = 0.161*(x(0) - x(2));
		return octave_value (dx);
	}

このファイルの最初の行,

	#include <octave/oct.h>

これは,必要になるであろう,Octave の内部関数の全てに対する定義をインクルードしています。 もし標準C++あるいはCライブラリからの他の関数が必要ならばmここで必要なヘッダファイルをインクルードできます。 次の2行,

	DEFUN_DLD (oregonator, args, ,
	"The `oregonator'.")

これは,関数を宣言しています。 マクロDEFUN_DLD,およびこのマクロが依存するマクロ群はファイル‘defun-dld.h’,‘defun.h’および‘defun-int.h’ (これらのファイルは,‘octave/oct.h’でインクルードされています)で定義されています。 DEFUN_DLDに対する3番めの引数(nargout)は使用されませんので,未使用の関数パラメータに関するgcc からの警告を避けるためには, 引数リストから省略します。

次の行,

	ColumnVector dx (3);

これは,単に微分方程式の右辺を格納するためのオブジェクトを宣言しています。 また,ステートメント

	ColumnVector x (args(0).vector_value ());

これは,1 番めの入力引数からベクトルを展開します。 vector_value メソッドが使用された結果,関数の利用者は行ベクトルまたは列ベクトルのどちらも渡すことができます。 ColumnVectorコンストラクタは必要です。 なぜならば,ODE クラスは,列ベクトルを必要とするからです。 変数argsは,DEFUN_DLDでoctave_value_listオブジェクトとして定義された関数に渡されます。 これは,リストの長さを得たり,個々の要素を展開するためのメソッドを含みます。 この例において,エラーをチェックしていませんが,それは難しいことではありません。 Octaveの組み込み関数の全ては,その引数についてある形式のチェックを行っています。 ですから,それらChapter 13: 関数とスクリプトファイル97 関数のソースコードをチェックすれば,与えられた引数の数と型を照合する様々な方法の例が得られます。

次のステートメント,

	dx(0) = 77.27 * (x(1) - x(0)*x(1) + x(0)
			- 8.375e-06*pow (x(0), 2));
	dx(1) = (x(2) - x(0)*x(1) - x(1)) / 77.27;
	dx(2) = 0.161*(x(0) - x(2));

これは方程式の右辺を定義しています。 最後に,dxを返します。

	return octave_value (dx);

実際に戻す型はoctave_value_listですが,これは戻す型をoctave_valueに変換するためだけに必要です。 なぜならば,octave_valueオブジェクトから,その型のオブジェクトを自動的に生成するデフォルトのコンストラクタが存在するからです。 ですから,かわりにそれを使うだけなのです。

このファイルを使用するためには,お使いのOctave が動的リンクをサポートしていなければなりません。 サポートの有無を確かめるには,Octave プロンプトでoctave_config_info ("dld")というコマンドを入力してください。 もしこれが1 を返したならば,動的リンクのサポートが含まれています。

このサンプルファイルをコンパイルするためには,シェルのプロンプトで‘mkoctfile oregonator.cc’と入力してください。 mkoctfileというコマンドは,Octaveとともにインストールされているはずです。 これを実行することにより,Octave によってロードすることができる‘oregonator.oct’ なるファイルが生成されるでしょう。 ファイル‘oregonator.oct’をテストするには,Octave を起動して,プロンプトから以下のコマンドを打ち込みます。

	oregonator ([1, 2, 3], 0)

Octave は以下の表示をすることによって反応を返すはずです。

	ans =
		77.269353
		-0.012942
		-0.322000

この時点で,この微分方程式を解くために,oregonator.mファイルと同じように‘oregonator.oct’が使用できるようになりました。

Linux を実行している133MHz のPentium マシンでは,Octave はSection 23.1 [Ordinary Differential Equations]で示した問題を,M-ファイルを使用した約19 秒と比較して,動的リンク関数を使用して約1.4 秒で解きました。 これと同様な実行時間の短縮は,他の関数にも期待できます。 特に,ユーザ提供関数を必要とするlsodeのような関数には適しています。

M-ファイルを同じように,動的リンク関数が最後にロードされた時間よりも,より新しくそのファ イルが定義されたときには,Octave は動的リンク関数を自動的に再ロードします。 もし1 個の‘.oct’ファイル内に複数の関数が定義されているならば,ファイルを再ロードすることによって,他の関数も強制的にクリアして再ロードします。 もし与えられた‘.oct’ファイルからロードした全ての関数をクリアするならば,Octave は自動的に‘.oct’ファイルをアンロードします。

warn_reload_forces_clear[編集]

                                                           [Built-in Variable]

もし同じファイルから複数の関数がロードされているならば,それらのどれか1 つを再ロードする前に,全ての関数をクリアしなければならない。 もし,warn_reload_forces_clearがゼロでないならば,これが発生するときに警告を発し,強制的にクリアされるその他の関数のリストを表示します。

variables_can_hide_functions[編集]

                                                           [Built-in Variable]

もしこの変数の値がゼロでないならば,変数への代入は,以前に定義された同名の関数を隠すことになります。 この変数が負の値ならば警告を表示するようになるが,操作は許されます。

動的リンク関数を書くためのさらなる情報は,Octave 配布パッケージの‘src’ ディレクトリにあるファイルで入手できます。 現在では,そこには以下のようなファイルが含まれます。

	balance.cc fft2.cc inv.cc qzval.cc
	chol.cc filter.cc log.cc schur.cc
	colloc.cc find.cc lsode.cc sort.cc
	dassl.cc fsolve.cc lu.cc svd.cc
	det.cc givens.cc minmax.cc syl.cc
	eig.cc hess.cc pinv.cc
	expm.cc ifft.cc qr.cc
	fft.cc ifft2.cc quad.cc

これらのファイルは,DEFUN_DLDの代わりにDEFUN_DLD_BUILTIN マクロを使用しています。 これら2つのマクロの違いは,オペレーティングシステムが動的リンクをサポートしないならば,DEFUN_DLD_BUILTINが, 動的にロードされない組み込み関数を定義することになる,という点だけです。 現在のところ,組み込み関数において呼ぶことのできる全ての関数についての,詳細な解説はありません。 それが実現するまでのあいだ,Octave のソースコードを読む必要があるでしょう。

13.9 関数ハンドルとインライン関数[編集]

ここでは,関数ハンドルとインライン関数の説明のためにとってある場所です。

13.9.1 関数ハンドル[編集]

functions (fcn_handle)[編集]

                                                           [Built-in Function]

関数ハンドルfcn handle に関する情報を含む構造体を返します。

func2str (fcn_handle)[編集]

                                                           [Built-in Function]

関数ハンドルfcn handle によって参照される関数名を含む文字列を返します。

str2func (fcn_name)[編集]

                                                           [Built-in Function]

文字列fcn name から構成される関数ハンドルを返します。

13.9.2 インライン関数

inline (str)[編集]

                                                           [Built-in Function]

inline (str, arg1, ...)[編集]

                                                           [Built-in Function]

inline (str, n)[編集]

                                                           [Built-in Function]

文字列str からインライン関数を生成します。 もし1 つの引数を付けて呼ばれたならば,生成された関数の引数は,関数それ自身から展開されます。 生成された関数の引数は,そのとき,アルファベット順になるでしょう。 引数としてi およびj は無視されることに注意してください。 これは,それが変数として使われているのか,組み込み定数として使われているかが曖昧だからです。 かっこに続く全ての引数は,関数になると見なされます。 もし2番めおよびそれ以降の引数が文字列ならば,それらは,その関数の引数の名前です。 もし2 番めの引数が整数n ならば,その引数は,"x", "P1", . . . , "PN"です。

argnames (fun)[編集]

                                                           [Built-in Function]

インライン関数fun の引数の名前を含む文字列のセル配列を返します。

formula (fun)[編集]

                                                           [Built-in Function]

インライン関数fun を表す文字列を返します。 char (fun)は,formula (fun)と等しいことに注意してください。

argnames (fun)[編集]

                                                           [Built-in Function]

登場する全ての*や/などを,.*, や./などに置き換えることにより,インライン関数fun のベクトル化バージョンを生成します。

 13.10 Octave とともに配布される関数の構成 [編集]

Octave の標準関数の多くは,関数ファイルとして配布されています。 それらは,‘octavehome/lib/octave/version/m’のサブディレクトリ以下にあり,見つけやすくするためにトピックによって緩く構成されています。 以下に示すものは,関数ファイルサブディレクトリと,そこで見つけたいと思う関数の型の全てのリストです。

‘audio’[編集]

音声を再生したり録音するための関数です。

‘control’[編集]

自動制御のシミュレーションをデザインするための関数です。

‘elfun’[編集]

初等関数です。

‘general’[編集]

flipud,rot90,triuのような雑多な行列操作関数のほか,ismatrixやnargchkな どのような基本的な関数を含みます。

‘image’[編集]

画像処理ツールです。 これらの関数にはX Windows System が必要です。

‘io’[編集]

入出力関数です。

‘linear-algebra’[編集]

線形代数のための関数です。

‘miscellaneous’[編集]

このほかのどこにも属さない関数です。

‘plot’[編集]

Matlab ライクなプロット関数を実装した関数群です。

‘polynomial’[編集]

多項式を操作するための関数です。

‘set’[編集]

一意な値の集合を生成したり操作するための関数です。

‘signal’[編集]

信号処理アプリケーションのための関数です。

‘specfun’[編集]

特殊な関数です。

‘special-matrix’[編集]

特殊な行列構造を作るための関数です。

‘startup’[編集]

Octave のシステム寄りのスタートアップファイルです。

‘statistics’[編集]

統計関数です。

‘strings’[編集]

雑多な文字列処理関数です。

‘time’[編集]

時間に関連する関数です。