2013年5月17日金曜日

matlab: 壁の外へ 1. 前置き

[執筆中,2013]

概要 


この一連の記事では,matlab での workspace 間のアクセス方法をいくつか挙げる.初回となる本記事では,matlab における workspace の概念について解説する.
  • この文章は脱線上等のポリシーのもとで作成されています. 
  • matlab において最強の文書は,matlab 付属のヘルプドキュメント群です.ともかく help を参照するに限る.ともかく matlab メニューの「ヘルプ→プロダクトのヘルプ」を読め!わからん言葉はコマンドプロンプトから >> help XX で読みまくれ!過去に色んな人に多くの質問を受けましたが,ほとんどはヘルプに書いてあるのを読んでいないだけです.ただ,ある種のことは別の切り口で見るのも有益な場合があります.本記事はそれを期待しています.

1.前置き: workspace, 関数,入出力引数

workspace について - 変数の見える範囲 -

matlab では,何か変数や関数があったとして,それらがある時点で「見える」かどうかは状況により変化する.例えば,matlab コマンドラインで変数 a に 3 という値を割り当てたとする.その後何らかの関数を呼び出しても,通常は,関数の内容によらず,関数の「中」からは「外」の,つまりコマンドラインで定義した a の存在や値は見えないし,関数内の処理は a の値に影響を与えない
例えば,関数を func1 として,その中で変数 a に値 2 を割り当て,disp(a) するとする.
ファイル func1.m:
 function func1
 a = 2;
 disp('a in func1');
 disp(a);
この関数はコマンドライン上で見える変数 a にどう影響するだろうか?実行してみると,
>> a = 3; func1; disp('a in base workspace'); disp(a);
a in func1
     2
a in base workspace
     3
となる.func1 内での a への操作は,コマンドライン上から見える変数 a には影響を及ぼしていない.
これは,コマンドライン上で見える変数と,関数 func1 内で見える変数とが,別の世界に存在しており,互いに隔絶しているからである.一丁目の山田さんと三丁目の山田さんは別人なのである.この各々の状況で見えている世界のことを,matlab では workspace という.他のプログラミング言語では名前空間 namespace やスコープ scope などと呼ぶ.コマンドラインで見えている世界のことを,base workspace という.

関数 m-file と異なり,スクリプト m-file は,固有の workspace を持たず,呼び出し元と同じ workspace を共有する.同じご町内である.

入力引数・出力引数

では,コマンドラインの世界と関数内の世界で情報をやり取りするにはどうするか.それには,通常,入力引数出力引数を用いる.

関数 func2 を
func2.m:
function y = func2(x)
y = 3 * x;
と作ったとすると,
>> a = 4; b = func2(a);
>> disp('a'); disp(a); disp('b'); disp(b);
a
     4
b
     12
となる.コマンドライン上での a の中身(=4)は,func2 での x の中身として渡され,func2 での y の中身(=12)は,コマンドライン上での b の中身として渡される.
なお,この受け渡しは,参照やポインタではなく,値のコピーが渡されることになっている(値渡し).一丁目の連絡文書が三丁目に伝達されるとき,その文書自体が渡されるのではなく,三丁目の人が文書を見ながらせっせと書き写して町内会に持って帰るのだ.一丁目の言う文書 a と,三丁目の言う文書 x は,当初の内容は同じでも物理的には別の存在なのだ.このことと,前記 workspace 間の隔絶とによって,外の世界と中の世界の交流は,入力引数と出力引数という,いわば関数呼び出し国と呼び出され関数国間の出入国ゲートのみに限定され,各々の中では他者の干渉を受けない鎖国が保たれているのである.なお,呼び出され関数国から見た関数呼び出し国のことを,matlab では caller と呼ぶ.呼び出し国の workspace のことを,caller workspace という.コマンドラインから関数を呼び出せば,関数内から見た caller workspace とは base workspace なわけだ.

workspace の効果


異なる workspace にアクセスできないことが何を意味するか.それは,裏を返せば,見えない範囲からの干渉は基本的に生じ得ないことを意味する.そのため,今自分の見えている範囲で整合性さえ取れれば大丈夫,という保証になるのだ.つまり,「今書いている関数 m-file がまともに動くこと」を積み重ねていけばいい,という世界が保証されている.一度に管理するのはエディタのそのページくらいで済むわけだ.

前置きまとめ

  • matlab では,ある時点で「見える」変数の範囲を workspace という.
  • コマンドラインから見える範囲は base workspace.
  • 関数を呼び出せば,関数内の workspace は base workspace とは別物.スクリプトを呼び出すと,workspace は元のを共有.
  • 異なる workspace 間は隔絶した鎖国関係にある.同じ名前の変数でも別々のものを指す.
  • 関数呼び出し元の workspace (=caller workspace) と呼び出された関数内の workspace とは,通常,入出力引数という出入国ゲートを介してのみ,値渡しでやり取りが成立する.
  • workspace が分かれているおかげで,目に見える範囲の整合性さえ確保すれば,おかしな矛盾が生じない仕組みになっている. 
  • 関数のアクセススコープも workspace によるのだが,matlab サーチパスも含めてよりややこしくなりそうなので本記事では割愛.

メモ

  • 関数 m-file とスクリプト m-file についてはこれを読もう:matlab のヘルプ→プロダクトのヘルプ→MATLAB->Getting Started->Programming->Scripts and Functions
  • workspace についてはこれを.同じく MATLAB->Desktop Tools and Development Environment->Workspace, Search Path, and File Operations
  • workspace は用語でもあるが,matlab で実際に workspace browser なるものを呼び出すコマンド名でもあるぞ.
  • matlab の次の性質は知っておくといいかもしれない.もっとも,プログラムの理論的な動作上は気にする必要は無い.実は matlab は毎度律儀に値渡しをメモリコピーの意味で実践してはいないようだ.大き目の行列を使って,matlab プロセスのメモリ使用量を観察しているとわかるのだが,入力引数を読むのにしか使わず,その中身を書き換えない場合は,コピー分のメモリ確保は生じていないようだった(matlab のバージョンには依存するかも).これ,気づく人は結構気づくものなんだね.Copy on Write (COW, or Lazy Copying) と言う動作で,Internal Matlab memory optimizations | Undocumented Matlab に詳しいぞ.
  • 構造化プログラミングって昔よく聞いたね.ベーマガDr.D も言ってたぞ

予告

 

workspace の安寧の中で虚偽の繁栄に酔いしれるプログラマたち.重い計算を恣(ほしいまま)にループで回す彼らは,長時間の計算中,突然天からの Ctrl+C による襲撃にさらされる.workspace 間の隔絶が仇になり,積み重ねた計算結果は日の目を見ることなく関数 workspace 内で雲散霧消してしまう.この run で受けた生を無駄にしたくない.天寿を全うできない場合でも,何とか壁の外の caller にこの情報を届けたい.越境者の自由を求め,今,餓狼たちの挑戦が始まる.次回,第2節,「workspaceをまたいだアクセス」.

※matlab では,実行中の処理は Ctrl+C で中断させることができます.Ctrl+C を押しても,あるまとまった処理が終わるまで待たされる場合もあります.
※本記事は2013年春季にノリノリで執筆しております.

2 件のコメント: