物理学 > 物理学のための計算機とオープンソース	
----
この文書は、理学系の学部を卒業した者が、何らかの仕方で計算機を学ぼうと
考えた場合の教科書の役割を果たすものとして書かれるものである。
また、計算機そのものに興味は無くとも研究の手段として計算機に関わる
必要が出来、それに関する知識を得たいと考える者も想定している。
この文書では、出来る限り計算機科学の原理的な部分も扱っていきたいと考えて
いる。しかし多くの部分はすでに完成しているプログラムの使い方だけを示して、
その原理にまでは触れないことも多い。これは、ひとえに現在の物理研究と
計算機の関係を表わしてもいる。例えば、現在ではFortranによる数値計算は
物理研究に欠かせないものとなっている。しかし、物理学者で実際にFortranの
コンパイラを書ける人間はほとんどいないのである。つまり、こういった場合
物理学者はコンパイラをブラックボックスとして扱い、それによって物理的な
結果を得ているのである。
しかし、このことは必ずしも責められるべきことではない。実際的な問題として
コンパイラの理論は計算機科学の学部講義に含まれるものであり、その修得には
すくなくとも2単位分の時間がかかる。更に、その講義自身もそれ以前の
学部の講義の内容に依存しているため、その修得には相当の時間がかかることになる。
このため、実際に物理研究のためにコンパイルの理論を学ぶのは、
あまり現実的ではないといえよう。むしろ、計算誤差の拡大を防ぐ方法に注力すべきである。
この文書でも、コンパイラの理論自体を扱うことは出来ない。しかし、
それに関係する部分で、それほど複雑でない部分は出来る限り扱っていこうと
考えている。例えば、Web上にはすでに多くのコンパイラが出回っており、
それらの原理や設計の思想を出来る限り紹介して行きたい。
また、コンパイラの中でも構文解析と呼ばれる部分は、計算機を扱う上で
いろいろな部分で出会う考え方であり、これは詳しく紹介したいと思う。
理想的な計算機は、0と1の2種類の信号しか受け取れない機械であり、
これによって2種類以上のことをさせるよう指示を出すことは不可能に思える。
しかし、これは間違いであり、計算機が2通りの事柄しか理解できないとしても
これに対して人間が出来ることと同じだけのことをさせることが可能である。
もっとも簡単な例としてモールス信号を考えてみるとよい。
これは、ただ2通りだけの信号を用いて英語のアルファベットを
表現する方法を表わしているが、これを用いることが出来、更に
計算機が多少の英語の文法と単語を知っていたのなら、計算機に
人間に対すると同じだけの指示を与えることが可能になる。
実際には、計算機に文法と単語を教えることも人間がやらなくてはならない
作業であるため、実際の人間が扱う言語よりも単純化された
文法と単語を扱うことが多い。
ここで実際に文法と単語を教える手法はまさしくコンパイラの理論そのものなので
やや複雑になるが、簡単な例を取って考えてみることにする。
まず、メモリとCPUだけからなっている理想的な計算機を
考える。ここで、メモリはそれぞれの部分が0と1だけの情報を蓄えることが出来る
ものであり、CPUは加算、減算などの処理をすることが出来る電子回路であるとする。
実際にはメモリとCPUの実際の設計は計算機科学というよりも工学部の特に
電気電子系で扱われることが多い内容であり、その詳細には触れることが出来ないが、
直観的にはメモリはただ2つの量子状態からなる電子スピンのようなものを
想像し、CPUに関しては、AND回路やOR回路が標準的な仕方で連なっている
ものを想像すればよい。例えば、2進数の1桁の数に対する加算回路を考えてみる。
このとき、2進数の1桁の数は0と1のみであり、これらの足し算の結果の
1桁目を考えてみる。すると、それらの和は
が得られる。これは回路としてはXOR回路と呼ばれる回路であり、
ある回路によって作ることが出来ることが知られている。
更に、1桁同士の足し算によって2桁の数が作られることに注目して、
2桁めの数値を計算する回路も考えてみる。このとき、2桁めの数値は、
となるが、これはAND回路に等しい。結局、AND回路とXOR回路を組み合わせることで、
2進数の加法を行なう回路が作れたわけである。このように、CPUは
計算を行なう回路を集積したものであり、どちらかといえば計算機というより
電気系の学課の題材といえるだろう。
また、多くの実際に使われているCPUの詳細は全くの企業秘密であり、
それらを自由に扱うことは出来ない。
一般にCPUに対してモールス信号的な2進数で表現された命令や足し算等に必要な
数値を与える部分を理想化したものをレジスタと呼ぶ。物理的には、CPUに
対して外部から電気信号を送るための端子である。レジスタは通常
複数あり、命令を受けるレジスタと、データを受け取るレジスタは別になっている。
さて、ここまでで計算機に命令と命令を実行するのに必要なデータを与える
手段が分かった。理想的にはここからの話で、CPUへの命令は全てモールス信号的な
2進数の信号で行なわれており、2進数表記での命令を作ることを人間の側が
行なっているとしてもよい。しかし、それはあくまでも実用的に役立つ
文書を作るという本来のこの文書の目標に反している。例えば、
文書の執筆を行なうという大事業を2進数で書くことはほぼ不可能である。
ASCIIコードも全て手作業で2進数に直さなくてはならないし、
漢字が加わると更にその作業は難度を増す。
そのため、計算機に効果的な仕方で指示を与えるには、何らかの仕方で
既存の計算機への情報伝達を扱う道具を使う方法を修得しなければならない。
しかし、それらの道具自体も最終的にはそのような2進数の集まりであり、
それら自身もおそらく既存の資産を用いて作られたことは重要であると
いえるだろう。
ここまででCPUに命令を与える方法について考察して来た。
もちろんCPUに与える命令自体はCPUを作るメーカーに任せられており、
それについては個々のCPUメーカーの作る文書を読むしかその内容を知る
方法は無い。しかし、実際にはそれでは問題が生じて来る。
あるソフトウェアをあるCPU向けに書いたとする。このとき、このソフトは
あるそのCPUが理解できる命令の集まりとなっている。
このソフトを、他のCPUに対しても使いたいと思ったとしよう。
このとき、CPUごとに体系に異なった命令が用いられていたとすると、
ある命令の集まりは別のCPUに対してはなんら意味のある活動を
起こさせることが出来ない。このことを、得られた命令に移植性がないという。
このことは、そもそもCPUごとの命令に定まった意味が無く、信号ごとの意味の
当てはめ方が任意であったことを考えると、全く当然のことと言えるのだが、
それでも、1つのCPUに対して書いた2進数プログラムと、他のCPUに対して書いた
2進数プログラムに全く互換性が無いとすると、それぞれのCPUに対して
全く別のプログラムを書くことをしなければならず、このことは非常に大変な
作業になると考えられる。
実際にはこの問題は、CPUに対してだけに留まらない。昨今ではそれぞれの
機器、例えばハードディスクやサウンドカードなどが挙げられるが、
それぞれが個別の命令の体系を持っており、それら自身もある程度それを
作るメーカーに信号の受け方を決める権限が任されている。
そのため、それらに対しても個別に信号の受け方や送り方を規定せねばならず、
それぞれの機器がそれぞれのCPUや他の機器と組み合わせて用いられることを
考え合わせると、その組み合わせは非常に多くの数を持つと考えられる。
この問題はいくつかの方法で解決が図られている。しかし、
いくつかの場合にこのことは依然として問題になっており、完全な
解決が得られたわけではないことに注意しなければならない。
1つめの方法として、ハードウェアやCPUが受けつける命令自体を
統一してしまうことがあげられる。このことは通常ハードウェアメーカー各社の
努力によってなされる。
例えば、家庭用パソコンでない
より多様な仕方で用いられるCPUのについては、大きな市場シェアを
占めるメーカーが存在せず、それらに対する対応はまちまちであるといえる。
関連のハードウェアについてもそれらへの命令の体系はあまり統一されているとは
いえない。特に、急激な進歩が続いている分野、例えば、ハードディスクや
グラフィックボードなどは、それらの命令にメーカーの重要な企業秘密に属する
情報が含まれていることがあり、それらの情報を公開することが
困難であることがある。そのため、これらの命令が完全に統一されることは
あまり期待できないといえる。
2つめの方法としてあげられることは、それぞれの機器の機能のうちで
他の機器の機能と共通する部分を抽象化し、それに元々の命令とは
別の統一された名前を与え、それらの名前だけを用いてプログラムを作製する
ことである。このことは実際にはコンパイラに関する話題とも密接に関係する
のだが、つまり、そのような名前をある文法にしたがって書き並べることで、
プログラムをより汎用的な形で書くことが出来るのである。
もちろん書き上げたプログラムを2進数のプログラムに変換する簡単な方法が
ないのなら、これは全く無意味な事であるが、
幸いにもそのような作業を行なうプログラムが実際に書けることが
知られており、また広く流通してもいる。このような抽象化された
名前によって作られたプログラムを、あるCPUに向けた2進数プログラムに置き換える
プログラムをコンパイラと呼ぶのである。
しかし、このことはある機器が持つ標準的でない機能はコンパイラを使って
それを扱うことが難しいことを意味する。そのようなものについては
必要な部分だけを2進数で書くか、コンパイラに適切な分岐を用いて
そのような機能に対応させることによって、それらに対応しているが
いずれにせよ対応がやや場当たり的になることは避けられないといえる。
結局、それぞれの機器の機能に対応する抽象化された名前を
作ることが、それぞれの機器の機能を移植性を保った方法で
用いるために役立つことが分かった。実際にはこれらの抽象化された名前の体系は
まさにOSの機能の一部分を成している。例えば、OSの1つであるLinuxでは、
このような抽象化された命令としてread()とwrite()を持っている。
これは、例えばハードディスクに対する命令を抽象化することを
考えてみるとわかりやすい。ハードディスクはその中に磁気的なしくみで
蓄えられている情報を読みだしたり、新しい情報を書きこんだり
する機能を持っているが、その仕組みは単に情報をreadする、または
writeするという言葉で抽象化することが出来るのである。
もちろんreadやwriteという言葉は人間にとって直観的に意味が把握でき
便利であるが、それ自体はコンパイラに取っては意味があることではなく、
もっと分かりづらい名前にしてもよいのである。例えば、readは英語であるが、
これを日本語にしたり、別の言語にしたり、何の意味も持たない文字の羅列と
してもよい。ただ、コンパイラとそれを用いる人間の間に共通の情報であれば
それで用は足りているのである。
実際には、ハードディスクが扱える0と1の情報を用いて人間にとって
分かり易い仕方で情報を蓄えることはそれ自体が興味ある仕事である。
例えば、昨今どのような計算機においても用いられているツリー状の
ディレクトリ構造も計算機に分かる仕方でそれを構成するのは、例え
コンパイラを用いたとしても非常に大変な作業である。また、現在では
ツリー状の構造を超えたより直観的なディレクトリ構造も模索されており、
これ以降どのようなファイル構造が主流になるかは、今の時点では
よく分からないといえる。このように計算機の機能を用いて、
情報を蓄える方法をファイルシステムと呼びこれもOSの理論の重要な
一分野となっている。また、この部分は実際のOSメーカーの力も強く
アカデミックな研究とメーカーとの距離が近い分野であるといえよう。
上ではread(),write()の命令を持っている機器としてハードディスクを
挙げたが、実際にはこのような命令を持っている機器はハードディスクに代表される
記憶装置だけにとどまらない。実際にはグラフィックカードやサウンドカードも
このような命令を持っているのである。例えば、Linuxの重要なサウンドカード
を扱う命令群にalsa
があげられるが、そのコードの中には各々のメーカーのディレクトリがあり
それぞれのメーカーの機器の命令を抽象化するようなread命令とwrite命令が
定義されているのである。しかし、サウンドカードについて何をreadしたりwrite
したりするのであろうか?これは、readよりもwriteの方が分かり易いため
そちらの方を扱う。理想化されたサウンドカードは1つの
ディジタルアナログコンバーターに帰着される。
ディジタルアナログコンバーターはデジタル信号とアナログ信号を
変換するものであり、その逆にアナログ信号とデジタル信号を
変換する機器も知られている。このような機器は、加速器実験でも
加速器の実験機器が送ってくる信号を計算機が理解できる信号に変換するため
よく用いられるものである。
ここでいうwrite命令はサウンドカード上のディジタルアナログコンバーターに
ある定まった形式のデータを送り込む命令である。このデータは
サウンドカードによって音楽を表わすデータと解釈され、それが本物の
音楽であるなら音楽を鳴らし、全く関係の無い文字などの羅列なら、
ノイズを鳴らすのである。このような音楽は通常圧縮された形式で
計算機上に蓄えられ、もともとどのような形で蓄えられていたものなのか
知るのは困難だが、各々の形式のデータを扱う音楽プレーヤーそれぞれの
仕方で圧縮されたデータを元のデータに変換しそれを用いて音楽を
鳴らしているのである。このことは、例え音楽を鳴らすような複雑な操作が
行なわれるにしても、計算機の側からはその機器は
通常の記憶装置の一種にしか見えないというやや非直観的な側面を持っている。
また、ここでいう音楽の圧縮自体も計算機科学の重要な一分野であり、
様々な効果的な圧縮手法が考案されている。他の分野でも映像や動画の
圧縮手法も様々に研究されており、それらの応用も幅広く知られている。
また、これらの圧縮手法については考案したメーカーの人間により
特許が取得されている場合があり、そのような場合はこれらの情報を
容易に用いることは出来ず、必ず特許取得者に対して何らかの額のお金を
払わなくてはならない。このことは研究への投資を回収し更なる研究を進めることを助けるという
観点から当然視されているが、あまりにも特許の内容が簡単な事であり
その特許の適用範囲が広大である場合には、その特許を守ること自体が
研究の進行を遅らせる働きをしてしまい本来の特許法の意義に反する結果に
なることが起こることもあり、そのような場合について様々な議論が
かわされているようである。
ここまででそれぞれの機器の機能を抽象化しある一定の機能を用いる方法を
見てきた。おおよそ、現在用いられている家庭用パソコンはここまでに
書かれて来たことを用いて構成されているといえる。
ここからは、そのような標準化された入出力やファイルシステムはすでに
与えられたものとして、それらを用いてどのようなことを計算機にさせることが
できるかを見ていく。このようにすでに入出力やファイルシステムなどの
OSの機能が与えられた上でその機能を用いて書かれるソフトウェアを総称して
アプリケーションと呼ばれる。ただし、OSの機能を用いて他のソフトウェアに
用いられるために書かれるソフトウェアも存在し、これらをライブラリと呼んで
区別することがある。ライブラリは例えば、グラフィックをより統一的な
仕方で表示するために用いられる。グラフィックカードもサウンドカードと同様
計算機からは記憶装置にしか見えない機器の一種であるが、
このような装置の特性上、直観的には簡単に見える機能であっても実際に
計算機を使ってやらせようと思うと難しく見える機能がある。
例として、グラフィックカード上に線を引くことを考える。これは、
碁盤の目上の図形を用意し、塗りつぶす部分を1で埋めて、塗りつぶさない部分を
0で埋めることで線を引くことが出来る。通常グラフィックカード上に配置されている
メモリ上の図形は何らかの仕方でグラフィックを表示するディスプレイに送り届け
られるのであるが、この部分は計算機の側からは見えない仕方で行なわれる
ハードウェアメーカーの領分の仕事である。
ここでは、単に碁盤の目上に描かれた図形がそのままディスプレイ上に表示されると
考える。このとき、横向きや縦向きに線を引く場合は、どの点を1にしてどの点を
0にするかは簡単に決まる。しかし、斜めに線を引く場合にはこれは簡単には決まらず
どのような見え方をさせたいかによって制御する必要がある。このような
制御は、グラフィックを用いる場合には非常に頻繁に用いられるため、
このような機能を何らかの標準化された仕方で作製しておくことが望ましい。
このような目的で作製されたプログラムをライブラリと呼ぶのである。
ライブラリは大きなプログラムになることが多く、単に利用するだけの立場で
計算機に関わるのならまずこれを作製する機会は無いが、
もちろんライブラリの機能は知っていた方が望ましい。
また、大きなライブラリになるとそれを設計するだけでも非常に難しい仕事に
なるため、有能な設計者や技術者を確保するため大金が動くことも珍しくない。
ここからは個々のアプリケーションについて見て行きたいと思う。
ただし、あまりにも個々のアプリケーションの機能に特化した
説明をしてしまうと、解説に汎用性が無くなるため出来る限り
様々なOS上で同じような機能を持つ対応物がある程度に抽象化して
話を進めたいと思う。
ここでは、それぞれのアプリケーションがもつインタフェースに
注目して話を進める。
インターフェースとは個々のアプリケーションとそれを用いるユーザーが
意志疎通を行なう方法である。
例えば、読書などについてもインターフェースの考え方を抽象化して適用する
ことが出来る。読書の場合には本が表示する情報を利用者が読み取る
という関係になっており、利用者の方から本に対して何かを要求するという
関係は存在しない。これに対して、計算機を用いた場合ユーザーから
プログラムへの入力に対してはマウス、キーボードなど様々な機器が
用いられる。ただし、これは利用者が用いるOSがそれぞれの機器に対応する
命令のセットを所持しているときの話である。通常の家庭用パソコンでは
そのような事は既に設定されていることが普通なので、
ここからはそのような機能が既に得られているとする。
一方、計算機からユーザーに対しても文字を表示したり音楽を鳴らしたりと
様々な方法が考えられる。ただし、特に音楽や動画については現時点では
OSごとに移植性が無い場合も多く、今後の発展が期待されるところである。
ここでは特に、利用者から計算機のインターフェースに注目する。
現在では主要なインタフェースは大きく分けてCUIとGUIがあげられる。
CUIはCharacter-based User Interfaceの略であり、文字を用いて
利用者に情報を送る方式である。この方式は古い方式で今は主流でないと
考えられがちであるが、実際にはそうではない。例えば、技術者だけが
用いるハードウェアの命令のセットに対してそれぞれにグラフィックをつけることは
やや無駄に思われ、実際それほど行なわれてもいない。また、このような情報は
それぞれの機器に固有のものとなってしまう傾向があり特に変化の速い分野では
機器の方の変化にグラフィックをつける作業の方が間に合わなくなってしまう
ことが予想される。そのため、より変化の速い分野においては現在もそうであるし、
おそらくこれからも文字による情報伝達は主流であり続けるであろう。
次に、GUIは、Graphic-based User Interfaceの略であり、それぞれの情報に
アイコンやスクロールバーなどのグラフィックを表示し、それぞれの情報を
より直観的に提示する方法である。この方法は使うときには
非常に分かり易く重宝するが、これを実際にプログラムで制作することは
やや難しい場合が多い。例えば、OSによっては標準的な仕方でグラフィックカードを
動かせるとは限らないし、動かせたとしてもそれに対応するライブラリが存在するとは
限らないのである。ライブラリが無いときにはそれを自力で作製するしか無いが
それには通常多くの人手や予算がかかり、実際にそれを行なうのは困難であることが
多いのである。しかし、幸いにしてそのようなライブラリ等の問題を
全て乗り越えた計算機も家庭用パソコンを中心として多く存在する。例えば、
現在のWindowsや、Mac OS XやLinuxは通常グラフィカルな表示を持っており、
そのような問題を解決しているといえる。ただし、更に問題なのは
それらのOSはそれぞれ異なったグラフィック表示ライブラリを用いており、
その間には互換性がないということである。それぞれのグラフィックライブラリは
製造元も発生の歴史的経緯も異なっているため、これらに互換性が無いのは
当然であるが、昨今ではLinuxが用いているものを中心に
グラフィックライブラリを様々なOSに移植する計画が進んでいる。
Mac OS Xに対するXdarwinと呼ばれるプロジェクトはこの一種である。
ただし、実際には移植はただ一度だけではすまず、ライブラリが新機能を
加えるたびに、何度もそのような作業を繰り返す必要があり
どのような仕方でこのプロジェクトが進行していくかは今の時点では分からない。
このように、GUIは様々な問題をかかえているが、特に初心者向けの
アプリケーションについてはこのような直観的な入力方法は必須であり、
各々のメンバーが様々な仕方で開発を進めているといえる。
ここからは、特にCUIを中心に用いた手法を進めて行こうと思う。
なぜなら、上でも書いた通りGUIを用いた方法は移植性が無い場合が多く
それぞれのOSに対して解説を加えるのも大変であるからである。
また、計算機の機能を全て使うという点ではCUIの方がGUIよりも優れているといえる。
例えば、通常あるアプリケーションのGUIを作製するためには、 CUIを用いる場合が
多い。これは、GUIで用いられるのはあくまでライブラリに代表される
抽象化された名前の集合であり、それらを扱うのは通常コンパイラの仕事であり、
またコンパイラ自身は通常CUIによる入力を受け取る方が普通だからである。
また、CUIを用いたプログラムは移植性に長けている場合が多く、
様々なOSで実行できる場合が多いことも理由の1つとしてあげられる。
ここからは本題である物理的な結果を得るために応用できる
ソフトを説明して行く。一般に物理の研究は実験系と理論系に分かれており、
両者に取って必要となる計算機技術はかなり異なっている。
理論の側にとって理論研究に必要な計算機技術のうち多くは数値計算と
代数処理である。また、 数値計算を行なうときには計算機言語としては通常Fortranを
用いることになる。しかし、このときには計算機科学に属する詳しい知識は
実はあまり必要でない。どちらかといえば、このときに必要の知識はより実用的な
数値計算の知識であり、どちらかといえば工学に属する分野の知識であるといえる。
一方、計算機で用いる計算手法をより汎用性のある仕方でライブラリにしようとする
ときには、どの計算機言語を用いるかの選択や、その選択した言語で書かれた
プログラムのメンテナンスなどのいくらかを自動化するために、計算機を用いた
手法が重要になる。このように、計算機で仕事をするための計算機プログラムという
概念が存在することは、計算機以外の仕事と比べて計算機を用いた仕事の
著しい特徴と呼ばれるものであると思う。
次に実験的な研究を行なうときについては、最も頻繁に行なわれる仕事は
データ処理である。実際にはデータの収集にも計算機が用いられるのが
普通であるが、このような手法はデータを収集する機器ごとに変わって来ており、
更に、そのうちにいくらかは企業に装置の作成を依頼した場合には企業秘密であり
それ以上に詳しく知ることが許されないものでもあり、あまり一般的な事は
知ることが出来ないのが現状である。一方、実験で得たデータを
加工する技術は計算機技術の一種としても非常に面白いものであり、
またコンパイラの理論との関連にも興味深いものがあるため、追って
詳しく述べたいと思う。
また、理論物理と実験物理の共通の話題として、
数値計算で得た結果を直接外部のプログラムを呼び出してプロットを
作成する手法が問題になる場合がある。
しかし、このことについては割合深い計算機の知識が必要であるため、
ここですこし詳しく述べておこうと思う。
実際には外部プログラムを呼び出す方法はいくつかに分かれる。
ここでは3つの方法をあげるが、
そのうちの最初の2つは外部プログラム自身の設計によってそのような方法が
実際に適用できるかどうかが変化するため、実際にそのような設計になっていない場合
その方法を実行することが非常に困難になる。
また、最後の2つを説明するには、今までに紹介していないOSの機能の1つを
導入する必要がある。ただし、最後の1つはより汎用的に用いることが出来る
方法である。
ただし、OSの種類によってはそのような機能をサポートしていないことがあり、
やや移植性に欠けるという欠点がある。
まず第1に、外部プログラムのコードを自分が作成したコードの中から直接
呼び出す方法がある。つまり、自分が作成したコードが外部プログラムの
一部であるかのようにして、外部プログラムと同時にコンパイルを行なうのである。
この方法の欠点は、外部プログラム自身が大きいプログラムの集合であったとき、
それをコンパイルする事自体にかなりの時間がかかる点である。このような
欠点は、しかしより明快な形で設計されたライブラリについては現われることは無い。
例えば、X11というグラフィックを扱うライブラリがあるが、それらを扱う
コードの全体は圧縮してもなお数10Mbにいたる巨大なものであるが、
実際に利用者がそれらの機能を用いるときには、そのライブラリが提供する機能の
ほんの一部を用いることが普通である。このように、巨大なライブラリのうちの
ただ一部を切り出してくる手法は計算機言語ごとに様々であり、言語の設計という
1つの分野を成している。この分野はコンパイラ設計と極めて近い関係に
あるが、ただ設計だけを考えてコンパイラを作成しない場合も考えられるので、
それらの分野は一応分けて考えておいた方がよいものと思われる。
このようなコードの一部分だけを再利用する方法は、巨大なライブラリの多くが
Cによって書かれているため、Cによる方法だけを修得すればよいように思える。
しかし、Java,Perlなどそれぞれの言語が無視できない
異なった手法を提示しているためここではこれ以上深く扱わず、抽象的に
そのようなことがなられたものと仮定するにとどめておく。
いずれにしても始めからいくらかの機能だけを取りだして用いることを考えて
設計された場合を除いて、そのプログラムの全体をコンパイルしなければならない
手法は、あまり現実的な方法とはなり得ないと思われる。
第2の方法として、プロセス間通信と呼ばれる計算機技術を用いる方法がある。
ここで、OSの機能の1つであるプロセス管理について簡単に説明する。
幸いにもプロセスという考えかたは割合直観的に把握し易く、
おおよその考えを述べるだけでよいものと思われる。
計算機は何らかの意味を持った命令を連続的に計算機の命令を受けつける
レジスタに受けつけることで、命令を実行している。このとき、通常の計算機は
一度に1つの命令しか実行できない。しかし、実用的な家庭用パソコンでは
例えばテレビを見ながらワープロを使うなど計算機に同時に複数の作業を
させたいことが往々にしてある。このような情况を管理するため、
プロセス管理という考え方が生まれたのである。実際には計算機が1通りの
仕事をするだけなら、このようなプロセス管理の考え方は必要がない。
例えば、巨大な数値計算を専門に行なう計算機に取っては、常にただ1つの命令を
扱えば十分であり、それ以上に複雑な処理を行なうことはCPUに不必要な
負担をかけることになる。そのため、プロセス管理の手法は計算機の用途によって
使いわけることが必要となる。実際の現代的な家庭用パソコンでは
常にいくつかの仕事を並行して行なう形態が取られている。
このような手法をマルチタスクと呼ぶ。このように複数の仕事を同時に
行なうことはやや計算機科学の世界に深入りしすぎていると思われるので、
省略することにし、ここでは元の題材であるプロセス間通信に戻る。
プロセス間通信とは複数のプロセスの間でデータの電送を行なう手法の
ことである。これは、実際にはある計算機で動いている2つのプロセスの
間だけでなく、他の計算機で動いているプロセスに対してもお互いの間で規格が
統一されていればデータを送ることが出来る。例えば、Webサーバーなどは
この仕組みを用いて作成されている。
このような仕組みは伝統的に複数知られており、どの仕組みを用いるかは
プログラムの設計上重要となるものと思われるが、実際にはそのような仕組みを
採用しているプログラム自体が少ないため、あまりどの仕組みが重要なのかは
触れないことにする。ここでは、様々なサーバーの仕組みの基礎を成す
ソケットについて説明する。ソケットは、プロセス間通信の規格の1つであり
現在では数多くのOSにおいて使用可能となっている。
ソケットの仕組みは、OSのメモリ上にある領域を作成しておき、
その地点で2つのプロセスから来る信号を待ち受けることにある。
ここで、2つの信号がうまくであったならその2つの信号を発した
プロセス間にデータを送受信するトンネルを開いて、各々の間で
データを送受信可能にするのである。
このような仕組みを用いて、プロットのソフトに利用者が作成したプログラムによる
データを送信することも出来そうに思える。しかし、実際にはそのような
機能を付け加えることは割合手間がかかるため、そのような機能をそなえた
外部プログラムはあまり知られていない。例外的にOpenOffice.org
と呼ばれる
オフィスソフトは、利用者が作成したプログラムとソケットを用いて更新することで、
作成中の文書の編集を行なうことが出来る仕組みを用いている。しかし、
このような機能が実際に使われるのかどうかは今の時点ではよく分からない。
第3の機能として紹介するのが、プロセス生成の手法である。
ここでは、プロセス自体を利用者のプログラムの中で生成してそれを用いて
プロットを作成する方法を紹介する。プロセスを作成する方法は、
OSによって異なっているためこの手法に移植性があるかどうかは疑問だが、
この手法が使えるOSを用いている場合はもっとも手軽な方法である。
ここで、プロセスを生成する方法を見るために、プロセス管理の手法を
少し深く見て行くことにする。
通常、OSは複数のプロセスを管理するためにプロセステーブル
と呼ばれる表を持っている。プロセス生成を行なうためには、
そのプロセステーブルに1つのプロセスを加える方法をOS側が提供している
必要がある。このような方法は実際Unixの周辺では実際提供されており、
命令の名前をfork()という。この命令はLinuxで提供されている他、
おそらくMac OS Xでも提供されているものと思われる。このように
自分がのコードが計算した値を何らかのファイルに書き出しておいて、
次に外部プログラムを行なうプロセスを立ち上げるようにしておけば、
自動的にプロットがなされたように見えるであろう。
理論的な研究手法に役立つ計算機技術の1つとして、計算機代数を
挙げようと思う。計算機代数は実用的にそれらによって得られる結果も面白い
ものであることが多いが、その構成自身も非常に興味深いものであることが
多く、ここでは少し詳しく扱う。
計算機によって数式を扱うことは、計算機によって通常の数を扱う場合とは
やや異なった性質を帯びる。なぜなら、通常加法や減法のような
数に対する四則演算は、CPU自体がそのような命令を持っていることが普通であり、
そのような手法を利用者はいかなる意味でも書き下すことは無い。
これは計算手法のハードウェア的な実装と呼ばれ、あらゆる意味で最も高速に
結果を得る手法であるといえる。例えば、通常計算機が扱うことが出来ない
文字式を扱うことが出来る計算機を作るとする。このときには、例えば、
xという文字だけを加えたいのなら回路の数を2倍に増やして、それによって
計算を行なうようにすればよい。片方の回路で扱う数をxについて0次の項の
係数として扱い、もう片方の回路で扱う数をxの係数として扱えばよいのである。
このような手法は高速であるが、しかしそのための計算機を作製するほど
汎用性がある機能であるかは疑問である。なぜなら、xの係数とxについて
0次の項の係数を分けて計算することはそれをソフトウェアで行なうことも
けっして難しいことではないからである。通常計算機代数と呼ばれる
プログラムはそのように特殊なハードウェアを用いる手法ではなく、既存の
ハードウェアでソフトウェア的に計算機が扱える数学的な量を増やす手法のことを
いうのである。
実際にそのような数学的関係を計算機的に書き下す方法は、
大きく分けて2つに分かれる。歴史的には数式処理は、Lispと呼ばれる計算機言語
と深い関係にあった。Lispについての解説は出来る限り避ける方針で
話を進めたいので、ここでは代わりにC言語を用いて話を進める。
1つめの書き方はCでいうところのvectorの構造を用いて、数式の関係を
書き下す手法である。
例えば、
x + y 
という式を扱いたいとする。伝統的にはこの式は、
 
 char *  exp[10];
 exp[0] = "plus";
 exp[1] = "x";
 exp[2] = "y";
などとして書き下された。これはより直観的な書き方では、
 
 ["plus","x","y"]
のように、文字列が順に並べられている情况であると考えられる。
通常数学的な式は、いくつかの数の間の関係を表わす表式であるので、
あるベクトルを作成し、その最初の要素を関係を表わす文字列とし、
以降のベクトルの中味を先頭の文字列が表わす関係によって
関係づけられる量とすることで、数学的な関係が表わされるのである。
より複雑な式として例えば、
1 + x y
のような式は、
 ["plus", "1" , ["mul", "x","y"]]
のような構造を用いて計算すればよい。ただし、Cの文法では
ベクトルの中にベクトルを代入するような仕方は、通常の仕方では
出来ないので、これはあくまで仮想的なデータと考えなくてはいけない。
実際の数式処理では、このようなデータを作成するためにLispという
計算機言語を用いている場合が多い。Lispは、このようなデータを
統一的に管理するためのリストと呼ばれるデータを使用している。
リスト自体はCを用いても書くことが出来るがそれを用いて
様々なデータ型を統一的に扱う手法を得ることはやや難しい作業となる。
2つめの手法はオブジェクト指向の手法を用いる手法がある。
しかし、この手法を用いた数式処理では有力なものがあまり知られていないため、
さしあたりこちらの手法は無視することにする。
プログラムは通常何らかのデータを他の形に加工するために作製されるため、
データの処理は常に必要となる。もちろんこの分野はアカデミックな研究分野としても
重要と思われるのだが、より実用的な計算機技術においても
しばしば問題となっており、それぞれに対して解決法が考察されている。
ここでは、データの扱い方を少し一般的に扱う。
ここでいうデータは、
(1)人間の読める形式になっている。
(2)データとして扱われるものは文字でも数値でもよい。
を満たすものとする。例えば、計算機を用いて計算した数値計算の結果や
すこし一般的には学術論文などに用いられる.texファイル、更にXML形式で
保存されたオフィスソフトの文書などもこの中に含まれる。
一般にデータは、何らかの規則に従って並べられた文字列の集合である。数値的な
データはそれが1つのものであったら数値と改行をくり返すことで書かれていることが
多い。また、データが何らかの意味で対応づけられている場合には対応のあるデータは
スペースやコンマ等で区切られ、そのあとに改行が付けられていることが多い。
例えば、実験が始まってからの時刻とその時刻での測定値を並べて書いている場合が
これに当てはまる。これらはいずれもデータを並べる規則の1つとして扱うことが
できる。更に、より複雑な例では.texファイルでは
(1)命令に対しては最初に\backslash を付ける。
(2)引数を取る命令は命令の直後に\{ \} を付けることによって記述する。
などのいくつかのルールを用いて組版の情報を計算機に伝達しているのである。
.texファイルの場合には計算機は書かれた情報を与えられた命令を用いて理解し、
それを用いて更に別種の命令を作りだすことが成されている。
これは、例えば測定データ等についても、更にデータに対して四則演算等の
加工を行ないそれを出力としたいときには、常に必要となる技工である。
一般的には例えばC言語のコンパイラがCのプログラムを扱うときでも
このことは当てはまっており、
(1)用いる変数を宣言する。
(2)文の最後には;をつける。
などのいくつかの規則の元にコンパイラは機械語の命令群を出力しているのである。
ここでは、より簡単な場合として通常の測定データの処理などを扱う。
そのために正規表現の導入を行なう。
正規表現とは次の規則で生成される文字列のことである。
(1)用いたい文字を全て導入し、それらをa _1,a _nとする。（nは整数。）
(2)それらの任意の並びを文字列と呼ぶ。
(3)更に、ある文字列が任意の回数だけくり返されてできる文字列も
用いてよい文字列とする。
(4)どの文字とも一致するような文字が存在する。
通常正規表現を用いるプログラムではある程度記号ごとの意味が決まっている。
代表的なものとして、
(1)a,b, ...などの通常の文字
(2)1,2, ...などの通常の文字
(3)スペースなどの特殊な文字のうちで正規表現による意味が与えられていないもの
(3) *:直前の文字が任意の回数だけくり返されることを表わす。
(4) []:かっこ内に現われる文字のいずれかが現われる。
(5) (): かっこ内に含まれる文字を1つの文字として扱う。
例えば、スペースを用いて区切られた任意の個数の数値
1 2 5 3 6
は、
 
 ([1-9] )*
に一致する。ここで、正規表現のパターンに一致した数値を後から使えるように
したツールも知られており、その様なものを用いれば、
データを加工することが可能となるのである。
そのようなツールはPerl,Pythonなどが知られているが、
これらについてはプログラミングの手法でより詳しく述べる。