数値計算用インタプリタを作るのは難しいことではない。2001年前期の早稲田大学理工学部情報学科における2つの講義(数値計算,現代応用解析B)においては,数値計算インタプリタを作成せよとの課題を課した。その成果(学生がどのように反応してくれたか)の一端を,講義を社会に還元する意味でも,ここにまとめておくことにする。
プログラミング言語の売りは「何がすごいところか」である。したがって,数値計算用インタプリタを作るとしたら,その売りは「すごい数値計算用のプログラムが含まれる」というところになる。その意味で,数値計算用のプログラムパッケージとして,プロが何を開発してきて,何が成功しているかを知らなくてはならない。この知識に関しては本ホームページのもう一つの柱のコーナー精度保証付き数値計算に詳しく解説している(学生の講義では,数値計算アルゴリズムの理論も解説したが,情報学科における数値計算ということで,成功した数値計算パッケージの思想を体得してもらうために,さまざまな観点から演習を課した)。
さて,数値計算パッケージの研究,実用化においては,もちろん色々な成果があるが,その筆頭の一つは
LAPACK+最適化BLAS
であろう。このパッケージが組み込まれた使いやすいインタプリタというのが,ここでの作成の目標となるインタプリタである。実はこのようなインタプリタは世の中に存在する。商用のインタプリタMATLAB6である。したがって,これはよい手本となる。
コンピュータサイエンスの進展は著しい。実は,目玉のパッケージがある場合には,その目玉のよさを発揮させるインタプリタやコンパイラの作成理論とツールは非常によく発達しているのである。この理論とツールを生かして,「LAPACK+最適化BLASを売りとする数値計算ツール」を作ることを目標に,2つの講義を展開した。
まず,3年の数値計算での出題の概要を示す。
今回の課題は「数値計算用インタプリタを作れ 」である。このインタプリタを記述する言語は原則としてCとする。GUIなどにJavaを利用して,ポータビリティを持たせることは問題ない。一部C++なども利用してよい。
以下,Linux,Windows+cygwin,Mac OSX(Developing Toolはインストール済みとする)などUnix系OSを利用していると想定する。これらの環境では,通常bison(yacc),flex(lex)などのコンパイラ作成ツールがもともとインストール済みである。また,メモリのガーべージコレクションのためのgcもGPLライセンスで利用できる(のでダウンロードして利用できる)。ここでは,これらのツールを使うことを前提に数値計算用インタープリタを作っていく方法を説明する。
C言語を用いて数値計算用のインタプリタを作るとき,flexは字句解析用のCプログラムを自動生成するツールで,bisonは構文解析用のCプログラムを自動生成するツールである。それぞれ,lexおよびyaccの上位コンパチである(使い方はbisonとyaccで若干異なる)。flexとbisonについてはweb上に解説があるのでそれらをまず読んでみて欲しい。
これらには簡単な電卓用のプログラムが附いている。これを実行させて解説すれば40点となる。今回のレポートの最低ラインはここである。すなわち,
(1) bisonの機能を用いて,かけ算わり算を足し算引き算より優先させて計算する倍精度浮動小数点数を用いた電卓を作れ。
(1+) 実部,虚部がともにdoubleの複素数が扱える,電卓をつくれ。
(1++) 行列(double)が扱えるようにする。ただし,加減乗算にはBLASの関数を用いること。
(1+++) 行列(複素数)が扱えるようにする。ただし,加減乗算にはBLASの関数を用いること。
(1++++) 変数を扱えるようにする。
(1+++++) sin,cosなどやべき乗もできるようにする。
(2) 制御文(if文やwhile文やfor文)を扱えるようにする。
(3) ユーザが関数を定義できるようにする。
(2),(3)の問題を解くためには,解説1,2では不十分となる。これらができるようになるための説明のあるwebをリンクしよう。
ずばり,面白いページは次である。
前橋和弥氏のページ ここの「電卓を作ってみよう」がとても面白い。
これを丁寧に解説して,コピーすると上の評価基準ではほぼ満点かそれを越える。もちろんコピーしただけでは満点は保証できない。ということで
(M+) 前橋氏の電卓にsin,cos,べき乗などの関数を組み込んでみよう。また,ユーザ定義関数の返す値を指定できるようにしよう。
というような見当だろう。
(M++) 前橋氏の電卓に行列ができるようにしてみよう。もちろん,加減乗算はBLASの関数を使う。また,ついでだから,
Ax=b
を
> x=A\b
でできるようにしてみよう。複素行列も扱えるようになったら,固有値問題も解けるようにしてみたい。
> [P D] = eig(A)
で行列Aの固有値(を対角要素に並べた行列)Dと対応する固有ベクトルを並べた行列Pが計算できるようにしたい(これができたら+30点)。
(M+++) 前橋氏の電卓でgcでメモリの確保をしたらどうなるだろう。
(4) ファイルも読み込めるようにするというのは前橋氏の電卓はすでにできる。スクリプトと関数定義を読み込めるようにしてみよう。
(5) オブジェクトが定義でき,演算子多重定義ができるようにするのも面白い。Scilabのtyped listは演算子多重定義できるオブジェクトである。MATLABのクラス定義の仕方も変わっていて面白い(中がみれないので仕様しか参考にならない)。
(6) 絵が書けるようになりたい。gnuplotを呼び出す仕組みにするのは簡単だろう。ただ,これだけでは寂しい。Javaで絵を描くのはいいかもしれない。
学生からは力作が次々と返されてきた。例として以下に5つのレポートを紹介する。
まず,河邊昌彦 君の作品である。これは上記方針から完全に自由な数値計算インタプリタの提案になっていて,素晴らしい。
次は,永田貴彦君の作品である。これは,上記方針をたどっていったときに,かなりがんばるとこうなるという例である。
次に,永山陽平君の作品である。BLASは使っていないが,行列周りを頑張っている。
一から作った例として,斎藤卓也氏の作品を挙げよう。これもなかなかよい。
最後は,益子 理絵 氏の作品である。色々試行錯誤のあとにうまく実装している。行列ができるとよかった。
尚,前橋和弥氏は氏のwebの参照やプログラムの利用を快諾して下さいました。ここに深く感謝の意を表します。ありがとうございました。また,bisonやflexの参考webを作成されている方にも謝意を捧げる。
次いで,現代応用解析Bで出題した課題の概要を示そう。
電卓プログラムに加えて,if分,for文,while文などのプログラミング機能を持たせよ。また,行列の演算はBLASのライブラリを用いること。わり算(バックスラッシュはAx=bの解を与えよ)。
例として斎藤史子氏のレポートを示そう。よく考えらえれている。
実は,学生に出題したのと同時に,私もこの課題に取り組んだ。現在のところ,ユーザがオブジェクトを定義できるようにする機能以外は実装されており,総ステップ数が1万を優に超えながらも快適に動作している。これをSlabと名づけている。Slabをどのように公表するかは未定であるが,研究会などで紹介したいと考えている。
最終変更 2001/8/18
©大石進一 早稲田大学理工学部情報学科
このページのURI はhttp://www.oishi.info.waseda.ac.jp/~oishi/interpreter/interpreter.html