16βを迎えて思うこと

理学部 地球物理学科 助手 [執筆当時の職]
増田 耕一

次の形で出版されたものです。 参考文献として使う場合は、次の出版物のほうをあげてください。


旧システムの1台の端末機に代わって、5台のFM16βが地球物理学教室に配置されてから5か月近くなる。端末責任者をひきうけて、教室内の改造にともなう引っ越しや電源工事をする必要があったのと、それに、地球物理学科での計算機教育はいままでのように放任型でよいのだろうかという疑問もあったので、学生たちの端末(パソコン)の使い方をたびたび見に行った。そこで考えたことを書きしるしておきたい。まず、地球物理と計算機とのかかわりを述べ、次に16βがどのように使われたのかを概観し、それに関連して、プログラム言語およびプログラムのスタイルについて日ごろ感じていることを述べてみたい。なお、グラフィックスのことについてはまだ言いたいことがあるのだが、とりあえずは駒場支所の拡充に期待しておきたい。

(1節では地球物理学科ことに気象研究室の先輩方、2節では地球物理3、4年生のみなさん、3節では中村匡さん、林祥介さん、ロバート ゲラーさん、野本征子さんなどのおかげをこうむっているが、あくまでもわたし個人の、かなり主観的な文章であることをおことわりしておく。)

1. 地球物理学科と計算機

地球物理学は、地球(および惑星、宇宙空間)について、物理的考え方や技術を使って、なるべく法則的に理解しようとする学問である。地球物理学科のメンバーや卒業生が、地球に関する知識以外に何で貢献できるか考えてみると、連続の4次元時空間(島津康男氏の用語によれば「縫い目のない地球」)の中からいかにして意味のある情報を取り出すか、という努力をしている、ということだろう。また、地球システム(そのいろいろな部分系)のいろいろなパラメータへの依存性を調べる場合には、パラメータにともなう次元がふえてくる。と言っても地球物理学者が多次元空間を知覚できる特殊能力を備えているわけではなく、2次元(立体模型とか動画の場合3次元)に射影をいろいろと試みているにすぎないが。

地球科学は野外観測なしにはなりたたないし、また室内でも、地球を構成する物質のサンプルを取って来てその物質的性質を調べたり、またスケールが違ってもなりたつはずの法則を検証するために模型実験をしたりする。それと同時に、地球物理学科は計算機をよく使う学科である。大型計算機センターの利用時間では物理学科と1、2を争っている。物理学科には素粒子研究センターや高エネルギー研究所などの計算機を使う人も多いとはいえ、人数が4倍だから、ひとりあたりでは地球物理のほうがかなり大量に使っていることになる。

計算機を使う研究の手法には、数値シミュレーション、理論計算、データ解析がある(このように明確に分類できるわけではないが)。

固体、液体、気体、プラズマのいずれにしても、その運動は偏微分方程式で表現できることが多い。それを昔からいろいろな近似をして解析学的に解く努力がされてきた。しかし、どの項を省略するかで苦労するよりも、なるべく基本の方程式を忠実に積分してみようではないかという立場もある。微分方程式が時間発展型ならば、ある初期値を与えて時間積分していけば続く時刻の状態が得られる。もちろん、実際には連続時空間を離散化し、表現できない細かいスケールに関してはある近似をおくわけである。離散化は、一般には細かいほどよいが、計算機の能力によって実用的な制限がある。歴史をたどれば。最初の電子計算機ENIACを使った仕事の中に、弾道計算とともに、運動方程式に基づいた天気予報が含まれていた(Charney. Fjortoft and von Neumann, 1950)。それ以来天気予報モデルは常にその時代の計算機の性能の限界に挑戦してきた。また、数値天気予報モデルと実体はほとんど同じだが、実際の大気とは違う初期条件、境界条件を置いて積分することにより、大気というシステムの特性を知ろうとする目的に使うものを大気大循環モデルと呼んでおり、1960年代以来特別に計算機環境のめぐまれた研究所で開発されてきたが、最近では東大でも使えるようになった。気象以外の分野では必ずしも実用が先行したわけではないが、最近では同様に基礎方程式に基づいた大がかりなシミュレーションが行なわれるようになった。このような時間発展型シミュレーションが大型計算機を(CPU時間で見て)いちばん大量に使う種類の仕事である。

しかし、基礎方程式を積分すればこうなりますと言っても、わかった気がしない。どんなメカニズムがきいているのか考えるためには、また解析学的理論計算が必要になることもある。方程式を扱うだけなら紙とえんぴつ、または黒板とチョークですむかというと、たいていの場合、だれだれの特殊関数で書けるとか、こういう級数で書けるとかいう形になって、得られた解を目でみるためにはある程度の数値計算をしなければならないことが多い。このように理論計算も、けっして無視できない割合を占める。

一方、観測データも、自動測器が普及してきたこと、国際的なデータ交換が活発になってきたことなどにともなって、膨大な量になってきた。かりに全部を数値で印刷するだけの紙があったとしても、とても目を通せるものではない。普通は何か処理をした統計量を求めたいのだが、時にとんでもない値(通信の誤りなど)がはいっていることもあるので、データを図としてながめてみることも必要である。図にしてみると、新しい発見が生まれることもある。ことに衛星に積んだ走査型センサーによるデータは、画像データの典型的なものだが、地球物理では画像のパタンを認識しようとする場合より、センサーがとらえた物理量(放射輝度)を使うことが多い。

実は、大量のデータ処理は、シミュレーションの結果を見るときにも現われる。実験の初めから見るべき量がしぼられている場合もあるが、いくつもの量の時間発展を組み合わせてみないと解釈できない現象もある。このような場合、いわばシミュレートされた地球上で観測を行なってデータをためておき、あとで操作して解釈をすることになる。こういうわけで、人間時間でみれば、データ解析がいちばん時間を食っていると言えるだろう。

この3つのいずれにしても、地球物理学科で行なわれている計算はほとんどが数値計算と図形作成である。そして、少なくともこれまでは、圧倒的に多くの計算がFortranを使って行なわれてきた。実験や観測をする人もデータ処理の必要が生じるので、地球物理はFortranなしではやっていけないような状況にある。(全員がFortranというわけではなく、Vax育ちの人はCが使いやすいと言う。まあFortranもCも手順立て言語という点では同類ではあるが。) 計算速度の面で、メーカーが最大の努力をするのがFortranであるという背景もある。こういうふんいきは学生にも伝わっていて、数学科開講の「計算機演習」でFortranのプログラミング教育をしてくれるという情報が伝わるとみんな履修しようとするが、そこでLispの課題が出たりするとやる気を失ってしまう。

ではLispのような関数型(作用型)言語は役にたたないのかといえば、そんなことはないと思う。もはやデータを図にするだけではあたりまえであり、その先の認識論が問題なのだから、それを補助する人工知能がほしいところに来ているからである。ただしこう使えばいいという提案ができる人がこのまわりには見あたらない。

2. 端末機はいかに使われたか

1986年9月、教育用計算機センターが休業することになって、予告されてはいたものの、地球物理学科4年生は困った。学期末(10月中旬)をひかえて、演習の計算のプログラムがようやく動きはじめ、これから本格的計算に取りかかろうというところだったのである。10月に16βが設置されたとき、おおぜいの学生が飛びついたことは言うまでもない。それから冬学期の聞を通じて、16βは(休日も含めて)使われない日のないほどのにぎわいを見せた。具体的に内容をあげてみよう。なお、カリキュラムは1987年度には少し変わることになっている。

<夏学期>

気象海洋演習1 (4年)。この科目では地球物理学でよく使われる時間発展型の偏微分方程式の数値的な解き方を学ぶ。この科目ではいくつかの計算問題が出された。たとえば、海岸に向かって少しずつ浅くなる海を津波が伝わってきたらどうなるか(鉛直に積分した運動方程式に基づく1次元問題)とか、海流が、黒潮に見られるように海の西側で強くなることを初歩的に説明せよ(渦度方程式に基づく2次元問題)などである。

地球物理学演習1 (4年)。この科目はおおぜいの教官がそれぞれ出した課題に応じて学生がグループに分かれて演習を行なう。計算中心のものもあれば、室内実験や野外観測もある。

物理学実験1 (3年)。この科目には「計算機」の課題が含まれており、2次方程式、行列の計賞、ルンゲクッタ法、文字によるグラフ表示などを実習した。また「放射線」の課題では、エネルギースペクトルのデータに、核種に対応するピークを最小2乗法であてはめた。これらの計算はセンターのMELCOMで行なわれた。

固体地球物理学1 (3年)。レポート課題として、地下の成層構造を仮定して地震波の伝わり方を示せというもの、逆に地震波のデータから成層構造を推定せよというものがあった。従来なら手計算(または電卓)と方眼紙でやるところだが、今回は16βが活用された。

数値計算2 (情報科学科開講)。連立1次方程式の解法と行列の固有値の計算の課題が出された。

<冬学期>

地球物理学演習2 (4年)。前期と同様にグループ演習である。
気象海洋演習2 (4年)。これも冬学期はグループ演習となる。

固体地球物理学演習 (3年)。学期中は、弾性波動(地震波)の反射係数の計算などの課題に16βが使われた。学期末レポートのための計算は2月末現在まだ始まっていないようである。

地球流体力学 (3年)。中間で、「カオス」、「フラクタル」、「ソリトン」について説明せよ、という課題が出たので、図を作るためなどに計算機を使う人もあった。

<そのほか>

ここでは旧システムのMelcomやMulti16、新システムのMSPを利用したものも含めたので、かならずしも全部が16βを使っていたわけではないが、端末室がよく利用されていたことはわかっていただけよう。これは一つには、使用時間あたりの課金がかからなかったため(端末を置いていることにともなう学科からの負担はあったが)、時間の制限なく使えたという理由もある。連続時空間を表現するのには原則として細かく離散化するほどよいので、時間をかければそれだけよい結果が出る。したがって徹夜でプログラムを動かす学生が出てくるのも(そういう生活リズムを奨励したつもりはないが)当然である。徹夜といっても、だんだん要領がよくなってくると、計算のステップが進むごとに結果をディスクにしまって、あとで早回しでながめていた。また、発表会が近づくと、対話型を生かして発表用の図を何度も作り直している学生をよく見た。内容の理解の点で昔の学生よりも進歩しているかどうかはよくわからないが、少なくとも図示に関してはうまくなってきたと思う。(なお、パソコン用のドットプリンタがなかなか性能がよく、画面のハードコピーが、印刷原図にはちょっと不足だが、レポートにつけたり、ゼロックスコピーでオーバーヘッドプロジェクター用シートを作るのに十分な質である。)

2月24日にシステムが入れかえられて、パソコンとしての利用にも1分2円の課金がされるようになった。こうなると時間にまかせて走らせておくという使い方はできなくなり、端末室はすいてきた。確かに一部の利用者は複数のパソコンを占領するなど度を越した使い方をしていたので、何か歯止めがあるべきだった。(長時聞かかる計算はホストを使うべきである。) しかし、端末室がすいてしまったのは、1分2円という課金ではすぐ限度額を越してしまうのではないかと気になるからである。むだ使いは困るが、臆病になってほしくはない。ときには与えられた課題以外にも、自分で問題を考えて解いたりしてみてほしい。そのためには学科としてもっと金銭の負担をしなければならないのだろうか。この5か月、ホストの計算機の利用は以前より減っているが、それはFACOMでの図形出力の方法がわからないなど、新しいシステムに慣れないせいが大きく、じきにもとにもどると思われる。したがって、学生の計算機利用は、パソコンとして使う分だけ正味で増えるとみてよいと思う。この5か月の勢いで、16βが1日4時間(あるいは2日に1日8時間)使われるとすると、1台あたり年に17万円、5台で85万円の予算追加をしなければならない。なかなかつらいところである。1分2円がセンターの財政上動かせない額でなければ、もう少しまけていただけないものかと思う。

もう一つ気がついたことは、ほとんどの人がBasicを使っていることである。最初に機械が設置されたときFortranやPascalがいっしょに支給きれなかったこと、電源を入れればBasicが動き出す機械になじんでいる人がかなりいたこと、などの背景もある。しかし、学生はみな旧システムでFortranを経験していたのだから、最大の原因は、Fortranで図をかく方法が提供されなかったことにある。計算結果を図に示すことは、時には計算自体より重要である。あとで論じるように、Basicは長いプログラムを書いたり、プログラムを再利用するのには適さない。きれいな図を作るためにはBasicを使わなければならないというのは嘆かわしいことである。ぜひほかの言語でも図が作れるようにしていただきたい。ProFortranのカタログをみるとグラフィックパッケージ(国際標準GKS準拠のもの)も別の商品として提供されているので、これを導入することも一つの案である。また、OPRというレーザービームプリンタが設置されているが、図形を出せないともったいない。一般のドットパタンを出力するサブルーチンさえあれば図形出力のプログラムを書くことはできるのだが。

3. プログラム言語をめぐって

プログラム言語の専門家ならば常識かもしれないが、多くの利用者を見ていると以下のようなコメントをしておく価値はありそうな気がする。ただし、わたしの知識は手順立て言語(木村泉、米沢明憲、1982、「算法表現論」(岩波)の用語では「命令型言語」)に隈られることをおことわりしておく。

プログラミングの方法論として、「構造化」、「モジュール化」、「データ抽象」などと呼ばれる一連の主張がある。これにはいろいろなレベルの問題を含んでいるが、次のように分けられると思う。

このうちわたしは特に(ア)と(ウ)にこだわる。それは、わたしがRatfor育ち(注)だからである。いわば1970年代型の構造化主義者であり、最近のプログラミング理論からみれば古くさいかもしれないが。

むかし、記憶装置がとても貴重だったころに、フォン ノイマンが考えた計算機のモデルでは、制御装置がプログラムを原則として順に読んで実行していくが、読んだ命令によっては飛び越したり、後もどりしたりする。いまでも、多くの計算機の機械命令はそのように設計されている。計算機を人間のことばに近づけた偉大な発明であるFortranやBasicも、プログラムの中を飛び回るgoto文を欠かせないものとして含んでいた。

しかし、1970年代になると、フォン ノイマン型の計算機のプログラムは、三つの基本的制御構造の入れ子型(再帰的)組み合わせで書けるという「構造化定理」が提唱された。基本的制御構造とは、順次処理、条件別処理、繰り返しである。命令型言語では、順次処理は単に文を順に並べて書くことで表現されるから、あとの二つの構造を表わす文があればいいことになる。これが上記の(ア)の話である。ここではサブルーチンのことはどこかへ行ってしまっている。おそらく、プログラムの長さを別にすれば、サブルーチンを呼び出す位置に展開してしまうことで論理的に同等なプログラムが書けるということから、基本構造には入れなかったのだろう。

もちろん、実際に構造のわかりやすいプログラムを書くためには、条件別処理や繰り返しの構文を使うこととともに、仕事をうまくサブルーチンに分けること(ウ)もたいせつである。サブルーチンは、うまく設計されていれば、ほかの仕事のために再利用できる。「構造化」というときはここまで含むのが普通だろう。

さらに、関連したデータを表わす数値や文字列をひとまとめにして、構造を持った一つの変数として処理できるとプログラムの見通しがよくなることが多い(イ)。PascalやC、あるいは最近設計されたほとんどの言語にはこのような複合型がある。さらに、ある種のプログラムで必要になるデータの秘密保護のためや、どんなプログラムでも大きくなってくると起こりがちの「気がつかないうちにどこかの変数を書き換えてしまう」ことを防ぐために、大事なデータを表わす変数は特定の手続きからでないと読み書きできないようにしよう、という考え方(エ)が出てきた(先にあげた木村、米沢の本の序論を参照)。

このようないくつかの「構造化」の立場から、手近で使えるいくつかの言語を考えてみたい。

Basicはひと目で見渡せる長さ(画面だけなら20行、プリンタを使って100行)のプログラムを書くのには確かに便利な言語である。しかし、それを越えると、自分で書いたプログラムさえ、見通しが悪い。それは、Basicがプログラムの構造化(どの意味でも)に適さない言語だからだろう。

Basicは、第ーに、変数が全域的であり、サブルーチンの引き数とか、局所変数といったものが設定できない(ウ)。変数の値をどこかで変えると、その影響のおよぶ可能性はプログラム全体にわたる。第二に、制御構造を表わす構文が足りない(ア)。条件別処理に関しては、16βのBasicを含むMicrosoft系のBasicでは、せっかくif - then - else構文を導入したが、それが1行のなかで閉じなくてはいけないというおかしな制限があるので、goto文がほしくなる。(一方繰り返しについてwhile-wend構文があるのでgoto はいらない。) いったんgoto文を認めると、原理的にはプログラムのどこにでも飛び込めることになり、プログラムは実際に動かして(または人間コンビュータとなってシミュレートして)みないと流れがつかめないものになってしまう。Basicでも、まずアルゴリズムを基本的制御構造に分解し、goto文の使い方を一定させて行儀よく書けば、まあまあ読めるプログラムはできる。しかし、たとえばPascalで書いたプログラムの読みやすさにはおよばない。

Pascalは「構造化」の(ア)、(イ)の思想の具体化として出てきたものと言える。(ア)に関しては、文をグループにまとめて、論理的に一つの文とみなすbegin .. end(注)、条件別処理のためのif .. then .. elseやcase文、繰り返しのためのwhile文やrepeat文をもっている。(イ)に関しては、変数の複合型や部分範囲型を定義できる。(ウ)については、プログラムを「手続き」に分解して書くことを奨励しているものの、手続きに引き数として渡されたもののほかに、主プログラムの変数を全域的変数として使えることなどは、モジュール化が徹底していないといえよう。また、基本的にプログラム全体を1回でコンパイルすることを想定して言語が設計されている。実際にはそれでは困るので分割コンパイルの方法が処理系ごとに考えられているが、非常に処理系に依存する。Fortranから見て不便に思うのは、引き数として配列を渡すとき寸法が一致していなければならず、整合寸法というものがないことである。

Pascalはきゅうくつな言語だと思う。しかしそれで仕事ができる限りでは、きゅうくつなところは、プログラムのチェックが徹底してできるという長所にもなっている。配列の添え字になる変数は部分範囲型で定義すれば、添え字になる前に、値を計算したところで範囲のエラーが点検できる(よい処理系ならば)。変数を必ず宣言しなければいけないのも、書きまちがいを防ぐ効果がある。

Turbo Pascalというパソコン用の処理系を少し使ってみての印象だが、Pascalは100行から1000行ぐらいのアログラムを書くのに適した言語だと思う。あまり短いプログラムではいちいち宣言をするのはめんどうである。(先に実行文を書いておくと見つくろいで宣言文をつけてくれる処理系なら便利なのだが。) いっぽう、1000行をこえるプログラムは一度に書くものではないし、他人の作ったものを結合して使う必要も生じるのが普通であり、Pascalの設計者の考えた以上のモジュール化(ウ)、(エ)が必要になってくるからである。

では10000行の桁のプログラムを書くのにはどんな言語がよいか。残念ながら、処理系まで含めた意味でよい言語は見当たらない。Pascalの作者が(ウ)、(エ)の思想をとり入れて作ったModula-2、USA国防省きもいりのAda、あるいは次の世代のFortranならばもしかしたら便利になるかもしれないが。

(ただし、1984年現在のFortran 8X規格案というのを見せてもらったが、これはAdaなみのデータ抽象を可能にするとともに、いままでのFortranの表現も有効にしようという欲張ったもので、とても標準の名に値しないごたごたしたものになっていた。)

特によい言語がなければ、いままでの歴史を引きつぐことになる。そのうえ、数値計算を速くするベクトルプロセッサ用のコンパイラをFortranしか用意してくれないメーカーがあったりするので、大型の数値計算をする人はどうしてもFortranから離れられないのが現状である。

Fortranは、構造化のための機能はあまり発達していない。まず(ア)の意味では、条件別処理のための if - then - else構文は77標準でとりいれられたが、繰り返しについては、回数が決まっている場合のdo文しかなく、不定回数の繰り返しはgoto文で構成するしかない。もともと自由であるgoto文を、ループを作ることとそこから脱出することだけに限って使うことによって、なんとか見通しのよいプログラムが書けるようになる。(ただしFACOM MSPのFortran 77には、標準外だが、do while文がある。)

(イ)に関しては、配列の処理はわりあい便利だが、それ以外のデータ構造を表現する力はFortran自体にはない。したがって、(エ)のデータ抽象には遠い。Commonブロックを使い、それを操作するルーチンを限ることによって、データと操作を組にしたモジュール化のまねごとぐらいはできる。Fortranの標準では、上位のルーチンで宣言されていないcommon変数は使い終わると不確定になることになっているが、実際のほとんどの処理系では保存されるので、一種のデータ隠蔽ができる。

(ウ)については、Fortranは非常に分割コンパイルむきにできている。それはよいのだが、複数のルーチンにまたがったチェックをするのがむずかしい。Fortranを使っていて必ずといっていいほど起こるエラーは、配列をはみだしてプログラムを壊してしまうことと、未定義の変数を使って不確定な計算をしてしまうことである。いずれも一つのルーチンの中ならすぐチェックできるのだが、ほかのルーチンから渡された変数が相手側でどうなっているのか、処理系にもわからない。

わたしの属する研究室では、大気大循環モデルという10000行程度のFortranプログラムを大型計算機センターで動かしている。その書き直しを進めるにあたって、ある不毛な論争が起こった。サブルーチンに情報を引き渡すのに、引き数を使うべきか、common変数を使うべきかということである。不毛と言うのは、Fortranの欠陥からきているからである。もとになったプログラムでは、かなり多くcommonをつかっていた。このプログラムに手を入れようとして、ある変教がどこで定義され、どこで使われているのか探すのがたいへんだった。変数のトレースという点で、引き数のほうがやや確実である。そこで現在の版では徹底して引き数で渡すようにしてある。しかし引き数リストは1次元にならんでいて、commonプロックのような構造をもたせることができない。数が多くなるにつれて、一つずれたものに対応させてしまうといったまちがいの可能性が多くなってくる。

この問題の解決には、変数のグループを引き数としてわたせるようにするといった言語設計上の改善もさることながら、変数の定義、参照関係を複数のルーチンにわたっでトレースするユーティリティーの整備を望みたい。現在でも実際に走らせながらトレースするデバッガといったものはあるが、できればリンクまでした段階で静的に参照関係の矛盾がないか点検するものがほしいのである。

Cはまだ使ったことがないのでよくわからないが、(ア)の意味での構造化構文があり、(イ)についてはデータの型定義ができ、(ウ)については分割コンパイルがしやすいなど、いろいろ配慮された言語ではある。しかし、ポインタが非常に強力である結果、変数でない記憶領域をアクセスしてプログラムを壊してしまう可能性はFortranよりむしろ多いのではないかと思う。(これに対してPascalのポインタは特別な領域にとられた変数しかさすことができない。) Cは行儀のよいプログラムもかけるが、危険なこともできる言語だと言えそうである。なお、ミスタイプの多いわたしとしては、一文字まちがったら別の意味の「正しいプログラム」になってしまうことが多いという点でもCはこわい。

一般に融通のきくことと安全性とはうらはらの関係なのかもしれないが、行儀のよいプログラムがあまり苦労しないで書けて、個別の計算機の能力を生かすこともでき、実行のときの誤りのチェックもていねいにしてくれるような言語と処理系は作れないものだろうか。それが夢だというのならば、プログラム相談員は失業しないですむが、計算機による科学の発展ものろのろとしたものでしかありえないだろう。


(HTML版) 2017-06-25; 2017-10-08
増田 耕一 (MASUDA Kooiti)
[増田が書いた評論の目次へ] [コンピュータ利用関係の教材目次へ]