物理学のための計算機とオープンソース
物理学 > 物理学のための計算機とオープンソース
始めに
[編集]この文書は、理学系の学部を卒業した者が、何らかの仕方で計算機を学ぼうと考えた場合の教科書の役割を果たすものとして書かれるものである。また、計算機そのものに興味は無くとも研究の手段として計算機に関わる必要が出来、それに関する知識を得たいと考える者も想定している。
この文書では、出来る限り計算機科学の原理的な部分も扱っていきたいと考えている。しかし多くの部分はすでに完成しているプログラムやライブラリの使い方だけを示して、その原理にまでは触れないことも多い。これは、現代の物理研究と計算機の関係を如実に表している。例えば、現在でもFortranによる数値計算は物理研究において重要な位置を占めており、近年では高性能な数値計算言語Juliaも普及しつつある。しかし、物理学者で実際にFortranのコンパイラやJuliaの最適化システムを理解している人間は極めて少ない。つまり、こういった場合物理学者はこれらの言語処理系をブラックボックスとして扱い、それによって物理的な結果を得ているのである。
しかし、このことは必ずしも責められるべきことではない。実際的な問題としてコンパイラの理論や言語処理系の実装は計算機科学の専門的な領域であり、その修得には相当な時間と労力が必要となる。更に、それらの理解にはプログラミング言語理論や最適化理論といった基礎知識も必要となるため、その習得には膨大な時間が必要となる。このため、実際に物理研究のために言語処理系の詳細を学ぶのは、現実的ではないといえよう。むしろ、数値計算アルゴリズムの安定性や計算誤差の制御に注力すべきである。
この文書でも、コンパイラや言語処理系の実装詳細自体を扱うことは出来ない。しかし、それに関係する部分で、それほど複雑でない部分は出来る限り扱っていこうと考えている。例えば、現代では多くの数値計算ライブラリやツールがオープンソースで利用可能であり、それらの基本的な設計思想や使用方法を紹介していきたい。また、配列演算や並列計算といった概念は、現代の科学技術計算において頻繁に遭遇する考え方であり、これらは詳しく紹介したいと思う。
計算機との情報伝達手段
[編集]理想的な計算機は、0と1の2種類の信号しか受け取れない機械であり、 これによって2種類以上のことをさせるよう指示を出すことは不可能に思える。 しかし、これは間違いであり、計算機が2通りの事柄しか理解できないとしても これに対して人間が出来ることと同じだけのことをさせることが可能である。
もっとも簡単な例としてモールス信号を考えてみるとよい。 これは、ただ2通りだけの信号を用いて英語のアルファベットを 表現する方法を表わしているが、これを用いることが出来、更に 計算機が多少の英語の文法と単語を知っていたのなら、計算機に 人間に対すると同じだけの指示を与えることが可能になる。
実際には、計算機に文法と単語を教えることも人間がやらなくてはならない 作業であるため、実際の人間が扱う言語よりも単純化された 文法と単語を扱うことが多い。 ここで実際に文法と単語を教える手法はまさしくコンパイラの理論そのものなので やや複雑になるが、簡単な例を取って考えてみることにする。
まず、メモリとCPUだけからなっている理想的な計算機を 考える。ここで、メモリはそれぞれの部分が0と1だけの情報を蓄えることが出来る ものであり、CPUは加算、減算などの処理をすることが出来る電子回路であるとする。
実際にはメモリとCPUの実際の設計は計算機科学というよりも工学部の特に 電気電子系で扱われることが多い内容であり、その詳細には触れることが出来ないが、 直観的にはメモリはただ2つの量子状態からなる電子スピンのようなものを 想像し、CPUに関しては、AND回路やOR回路が標準的な仕方で連なっている ものを想像すればよい。例えば、2進数の1桁の数に対する加算回路を考えてみる。 このとき、2進数の1桁の数は0と1のみであり、これらの足し算の結果の 1桁目を考えてみる。すると、それらの和は
+ 0 1 0 0 1 1 1 0
が得られる。これは回路としてはXOR回路と呼ばれる回路であり、 ある回路によって作ることが出来ることが知られている。 更に、1桁同士の足し算によって2桁の数が作られることに注目して、 2桁めの数値を計算する回路も考えてみる。このとき、2桁めの数値は、
× 0 1 0 0 0 1 0 1
となるが、これは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に対して書いたプログラムと、他のCPUに対して書いたプログラムに全く互換性が無いとすると、それぞれのCPUに対して全く別のプログラムを書くことをしなければならず、このことは非常に大変な作業になると考えられる。
実際にはこの問題は、CPUに対してだけに留まらない。現代ではGPUやNVMeストレージ、ネットワークインターフェースなど、それぞれの機器が個別の命令の体系を持っており、それら自身もある程度それを作るメーカーに信号の受け方を決める権限が任されている。そのため、それらに対しても個別に信号の受け方や送り方を規定せねばならず、それぞれの機器がそれぞれのCPUや他の機器と組み合わせて用いられることを考え合わせると、その組み合わせは非常に多くの数を持つと考えられる。
この問題はいくつかの方法で解決が図られている。しかし、いくつかの場合にこのことは依然として問題になっており、完全な解決が得られたわけではないことに注意しなければならない。1つめの方法として、ハードウェアやCPUが受けつける命令自体を統一してしまうことがあげられる。このことは通常ハードウェアメーカー各社の努力によってなされる。
例えば、組み込みシステムやスーパーコンピュータなど、より多様な仕方で用いられるCPUについては、大きな市場シェアを占めるメーカーが存在せず、それらに対する対応はまちまちであるといえる。関連のハードウェアについてもそれらへの命令の体系はあまり統一されているとはいえない。特に、急激な進歩が続いている分野、例えば、機械学習アクセラレータやデータストレージシステムなどは、それらの命令にメーカーの重要な企業秘密に属する情報が含まれていることがあり、それらの情報を公開することが困難であることがある。そのため、これらの命令が完全に統一されることはあまり期待できないといえる。
2つめの方法としてあげられることは、それぞれの機器の機能のうちで他の機器の機能と共通する部分を抽象化し、それに元々の命令とは別の統一された名前を与え、それらの名前だけを用いてプログラムを作製することである。このことは実際にはコンパイラに関する話題とも密接に関係するのだが、つまり、そのような名前をある文法にしたがって書き並べることで、プログラムをより汎用的な形で書くことが出来るのである。
もちろん書き上げたプログラムを機械語に変換する簡単な方法がないのなら、これは全く無意味な事であるが、幸いにもそのような作業を行なうプログラムが実際に書けることが知られており、また広く流通してもいる。このような抽象化された名前によって作られたプログラムを、あるCPUに向けた機械語プログラムに置き換えるプログラムをコンパイラと呼ぶのである。
しかし、このことはある機器が持つ標準的でない機能はコンパイラを使ってそれを扱うことが難しいことを意味する。そのようなものについては必要な部分だけを機械語で書くか、コンパイラに適切な分岐を用いてそのような機能に対応させることによって、それらに対応しているがいずれにせよ対応がやや場当たり的になることは避けられないといえる。
結局、それぞれの機器の機能に対応する抽象化された名前を作ることが、それぞれの機器の機能を移植性を保った方法で用いるために役立つことが分かった。実際にはこれらの抽象化された名前の体系はまさにOSの機能の一部分を成している。例えば、現代のOSでは、このような抽象化された命令としてファイル操作のAPIを持っている。
これは、例えばストレージデバイスに対する命令を抽象化することを考えてみるとわかりやすい。ストレージデバイスはその中に電気的なしくみで蓄えられている情報を読みだしたり、新しい情報を書きこんだりする機能を持っているが、その仕組みは単にファイルを読み書きするという言葉で抽象化することが出来るのである。もちろんopen、read、writeという言葉は人間にとって直観的に意味が把握でき便利であるが、それ自体はコンパイラにとっては意味があることではなく、もっと分かりづらい名前にしてもよいのである。
実際には、ストレージデバイスが扱える情報を用いて人間にとって分かり易い仕方で情報を蓄えることはそれ自体が興味ある仕事である。例えば、現代の計算機において広く用いられているファイルシステムも計算機に分かる仕方でそれを構成するのは、例えコンパイラを用いたとしても非常に大変な作業である。また、現在では分散ファイルシステムやオブジェクトストレージなど、より柔軟なストレージシステムも実用化されており、これからどのような形態が主流になるかは、今の時点ではよく分からないといえる。このように計算機の機能を用いて、情報を蓄える方法をファイルシステムと呼びこれもOSの理論の重要な一分野となっている。
上では読み書きの命令を持っている機器としてストレージデバイスを挙げたが、実際にはこのような命令を持っている機器はストレージに代表される記憶装置だけにとどまらない。実際にはGPUやネットワークインターフェースもこのような命令を持っているのである。例えば、現代のLinuxシステムではPCIeデバイスドライバーの形で、それぞれのメーカーの機器の命令を抽象化するような統一的なインターフェースが定義されているのである。
また、このようなデバイスドライバーやファイルシステムの実装自体も計算機科学の重要な一分野であり、様々な効率的な実装手法が考案されている。他の分野でもネットワークプロトコルやセキュリティシステムの実装も様々に研究されており、それらの応用も幅広く知られている。また、これらの実装手法については考案した企業により特許が取得されている場合があり、そのような場合はこれらの情報を容易に用いることは出来ず、必ず特許取得者に対して何らかの額のお金を払わなくてはならない。このことは研究への投資を回収し更なる研究を進めることを助けるという観点から当然視されているが、あまりにも特許の内容が簡単な事でありその特許の適用範囲が広大である場合には、その特許を守ること自体が研究の進行を遅らせる働きをしてしまい本来の特許法の意義に反する結果になることが起こることもあり、そのような場合について様々な議論がかわされているようである。
アプリケーション
[編集]ここまででそれぞれの機器の機能を抽象化しある一定の機能を用いる方法を見てきた。おおよそ、現在の計算機システムはここまでに書かれて来たことを基盤として構成されているといえる。
ここからは、そのような標準化された入出力やファイルシステムはすでに与えられたものとして、それらを用いてどのようなことを計算機にさせることができるかを見ていく。このようにすでに入出力やファイルシステムなどのOSの機能が与えられた上でその機能を用いて書かれるソフトウェアを総称してアプリケーションと呼ばれる。ただし、OSの機能を用いて他のソフトウェアに用いられるために書かれるソフトウェアも存在し、これらをライブラリと呼んで区別することがある。
ライブラリは例えば、グラフィックスをより統一的な仕方で表示するために用いられる。GPUも他のデバイスと同様計算機からはメモリマップされたデバイスにしか見えないが、このような装置の特性上、直観的には簡単に見える機能であっても実際に計算機を使ってやらせようと思うと難しく見える機能がある。
例として、GPU上で線を描画することを考える。これは、ピクセルグリッド上の図形を用意し、描画する部分を指定された色で埋めて、描画しない部分を背景色で埋めることで線を引くことが出来る。通常GPU上のフレームバッファに配置されているピクセルデータは何らかの仕方でディスプレイに送り届けられるのであるが、この部分は計算機の側からは見えない仕方で行なわれるハードウェアメーカーの領分の仕事である。
ここでは、単にピクセルグリッド上に描かれた図形がそのままディスプレイ上に表示されると考える。このとき、横向きや縦向きに線を引く場合は、どのピクセルを描画するかは簡単に決まる。しかし、斜めに線を引く場合にはこれは簡単には決まらずアンチエイリアシングなどの手法を用いて見た目を制御する必要がある。このような制御は、グラフィックスを用いる場合には非常に頻繁に用いられるため、このような機能を何らかの標準化された仕方で作製しておくことが望ましい。このような目的で作製されたプログラムをライブラリと呼ぶのである。
ライブラリは大きなプログラムになることが多く、単に利用するだけの立場で計算機に関わるのならまずこれを作製する機会は無いが、もちろんライブラリの機能は知っていた方が望ましい。また、大規模なライブラリになるとそれを設計するだけでも非常に難しい仕事になるため、有能な設計者や技術者を確保するため大金が動くことも珍しくない。
ユーザーインタフェース
[編集]ここからは個々のアプリケーションについて見て行きたいと思う。ただし、あまりにも個々のアプリケーションの機能に特化した説明をしてしまうと、解説に汎用性が無くなるため出来る限り様々なOS上で同じような機能を持つ対応物がある程度に抽象化して話を進めたいと思う。
ここでは、それぞれのアプリケーションがもつインタフェースに注目して話を進める。インターフェースとは個々のアプリケーションとそれを用いるユーザーが意志疎通を行なう方法である。
例えば、読書などについてもインターフェースの考え方を抽象化して適用することが出来る。読書の場合には本が表示する情報を利用者が読み取るという関係になっており、利用者の方から本に対して何かを要求するという関係は存在しない。これに対して、計算機を用いた場合ユーザーからプログラムへの入力に対してはタッチスクリーン、キーボード、音声入力など様々な方式が用いられる。ただし、これは利用者が用いるOSがそれぞれの入力方式に対応する機能を持っているときの話である。現代のOSでは そのような機能は標準で備わっていることが普通なので、ここからはそのような機能が既に得られているとする。
一方、計算機からユーザーに対しても文字を表示したり、音声を出力したり、ハプティックフィードバックを提供したりと様々な方法が考えられる。特に最近では拡張現実(AR)や仮想現実(VR)のような新しいインターフェースも実用化されている。
ここでは特に、利用者から計算機へのインターフェースに注目する。現在では主要なインタフェースは大きく分けてCUIとGUIがあげられる。CUIはCharacter-based User Interfaceの略であり、文字を用いて利用者に情報を送る方式である。この方式は古い方式で今は主流でないと考えられがちであるが、実際にはそうではない。例えば、開発者向けのツールやシステム管理ツールに対してそれぞれにグラフィカルなインターフェースをつけることはやや無駄に思われ、実際それほど行なわれてもいない。また、このような情報はそれぞれのツールに固有のものとなってしまう傾向があり特に変化の速い分野では機能の変化にGUIを追従させる作業の方が間に合わなくなってしまうことが予想される。そのため、より変化の速い分野においては現在もそうであるし、おそらくこれからも文字による情報伝達は主流であり続けるであろう。
次に、GUIは、Graphic-based User Interfaceの略であり、それぞれの情報にアイコンやスクロールバーなどのグラフィカルな要素を表示し、それぞれの情報をより直観的に提示する方法である。この方法は使うときには非常に分かり易く重宝するが、これを実際にプログラムで制作することはやや難しい場合が多い。例えば、プラットフォームによっては標準的な仕方でグラフィックスAPIを利用できるとは限らないし、利用できたとしてもそれに対応するUIフレームワークが存在するとは限らないのである。
しかし、幸いにして現代では多くのクロスプラットフォームUIフレームワークが利用可能である。例えば、Qt、Electron、Flutter などは複数のプラットフォームで動作するアプリケーションを開発できる。また、Webブラウザを利用したWebアプリケーションも、プラットフォームに依存しない開発手法として広く普及している。
このように、GUIは様々な課題を抱えているが、特にエンドユーザー向けのアプリケーションについてはこのような直観的な入力方法は必須であり、各々の開発者やコミュニティが様々な仕方で開発を進めているといえる。
ここからは、特にCUIを中心に用いた手法を進めて行こうと思う。なぜなら、上でも書いた通りGUIを用いた方法は依然として移植性の課題を抱えている場合があり、それぞれのプラットフォームに対して解説を加えるのも大変であるからである。また、計算機の機能を網羅的に扱うという点ではCUIの方がGUIよりも優れているといえる。例えば、通常あるアプリケーションのGUIを作製するためのビルドツールやデバッグツールは、CUIを用いる場合が多い。これは、GUIで用いられるのはあくまでライブラリに代表される抽象化された機能の集合であり、それらを扱うのは通常開発ツールの仕事であり、またそれらのツール自身は通常CUIによる入力を受け取る方が自動化や連携の面で優れているからである。
物理学研究に際して応用上重要なアプリケーション群
[編集]物理学研究に必要な計算機技術に関する一般論
[編集]本章では、物理的な結果を得るために応用できる計算機技術について説明する。物理学の研究は一般に実験系と理論系に分かれており、両者で必要とされる計算機技術にはかなりの違いがある。 理論系において必要な計算機技術の多くは数値計算と代数処理であり、計算機言語としては通常Fortranが使用される。しかし、この分野では計算機科学の詳細な知識は必ずしも必要ない。むしろ、実際に使われるのは数値計算に関する実務的な知識であり、これは工学分野に近い知識であると言える。
一方、計算機を用いた計算手法を汎用的にライブラリ化しようとする場合、どの計算機言語を使用するかや、そのプログラムのメンテナンスを自動化するための技術が重要になる。このように、計算機で仕事を進めるためには「計算機プログラム」という概念が不可欠であり、これは計算機を用いた仕事の特徴的な要素の一つである。
次に、実験系の研究において最も頻繁に行われる作業はデータ処理である。実際、データ収集にも計算機が使われるのが一般的であるが、この手法は使用する機器に依存するため、各機器の仕様により異なる。また、企業が装置を製造する場合、その仕様やプログラムは企業秘密となることがあり、一般的な知識を得ることが難しい現状がある。
一方、実験データを加工する技術は計算機技術の一部として非常に興味深いものであり、コンパイラ理論とも関係が深い。これについては後ほど詳述したい。 理論物理と実験物理の共通の課題として、数値計算の結果を外部プログラムに渡してプロットを作成する手法が挙げられる。この問題には、かなりの計算機知識が必要となるため、ここで少し詳しく解説しておく。
実際に外部プログラムを呼び出す方法は複数あり、以下に代表的な方法を紹介する。最初の2つは、外部プログラム自体の設計に依存するため、その設計に合った方法でないと適用できない。また、最後の方法を説明するには、未紹介のOS機能を導入する必要があるが、これはより汎用的に使用可能な方法である。ただし、OSによってはその機能をサポートしていないことがあり、移植性に欠けるという欠点がある。
第1の方法として、外部プログラムのコードを自分のコード内から直接呼び出す方法がある。つまり、外部プログラムの一部として自分のコードをコンパイルし、同時に実行する方法だ。この方法の欠点は、外部プログラムが大規模なプログラム群である場合、そのコンパイルに非常に時間がかかる点である。しかし、明確に設計されたライブラリの場合、こうした問題は発生しないことが多い。例えば、X11というグラフィックライブラリは、機能自体は非常に大規模であるが、利用者が使用するのはそのごく一部に過ぎない。このように、巨大なライブラリの一部分だけを切り出して利用する手法は、計算機言語ごとに異なり、コンパイラ設計と密接に関係している。ただし、これをC言語だけで修得することは難しく、JavaやPerlなど、異なる言語ごとに異なる手法を理解する必要がある。そのため、ここではその詳細には触れず、抽象的にその方法が存在することを前提に進める。
第2の方法として、プロセス間通信という技術を用いる方法がある。プロセス管理とは、計算機が複数の作業を同時に処理できるようにするための技術であり、家庭用パソコンでは一般的にマルチタスクを実現している。この技術を活用することで、複数のプロセスが並行してデータをやり取りできるようになる。 プロセス間通信では、異なるプロセス間でデータを送受信する方法が用いられる。実際には、同一計算機内のプロセス間だけでなく、異なる計算機で動作しているプロセス間でもデータを送信することが可能である。この手法は、Webサーバーなどで広く使用されており、その中でもソケットという仕組みがよく知られている。ソケットは、プロセス間通信を実現するための規格の一つであり、現在では多くのOSで利用されている。ソケットを用いることで、OSのメモリ上に領域を作成し、二つのプロセス間でデータを送受信するための通信路を開設することができる。この仕組みを利用して、ユーザーが作成したプログラムから外部のプロットソフトにデータを送信することも可能である。
計算機代数
[編集]概説
[編集]理論的な研究手法に役立つ計算機技術の1つとして、計算機代数を 挙げようと思う。計算機代数は実用的にそれらによって得られる結果も面白い ものであることが多いが、その構成自身も非常に興味深いものであることが 多く、ここでは少し詳しく扱う。
計算機によって数式を扱うことは、計算機によって通常の数を扱う場合とは やや異なった性質を帯びる。なぜなら、通常加法や減法のような 数に対する四則演算は、CPU自体がそのような命令を持っていることが普通であり、 そのような手法を利用者はいかなる意味でも書き下すことは無い。 これは計算手法のハードウェア的な実装と呼ばれ、あらゆる意味で最も高速に 結果を得る手法であるといえる。例えば、通常計算機が扱うことが出来ない 文字式を扱うことが出来る計算機を作るとする。このときには、例えば、 xという文字だけを加えたいのなら回路の数を2倍に増やして、それによって 計算を行なうようにすればよい。片方の回路で扱う数をxについて0次の項の 係数として扱い、もう片方の回路で扱う数をxの係数として扱えばよいのである。 このような手法は高速であるが、しかしそのための計算機を作製するほど 汎用性がある機能であるかは疑問である。なぜなら、xの係数とxについて 0次の項の係数を分けて計算することはそれをソフトウェアで行なうことも けっして難しいことではないからである。通常計算機代数と呼ばれる プログラムはそのように特殊なハードウェアを用いる手法ではなく、既存の ハードウェアでソフトウェア的に計算機が扱える数学的な量を増やす手法のことを いうのである。
実際にそのような数学的関係を計算機的に書き下す方法は、 大きく分けて2つに分かれる。歴史的には数式処理は、Lispと呼ばれる計算機言語 と深い関係にあった。Lispについての解説は出来る限り避ける方針で 話を進めたいので、ここでは代わりにC言語を用いて話を進める。 1つめの書き方はCでいうところのvectorの構造を用いて、数式の関係を 書き下す手法である。 例えば、
という式を扱いたいとする。伝統的にはこの式は、
char * exp[10]; exp[0] = "plus"; exp[1] = "x"; exp[2] = "y";
などとして書き下された。これはより直観的な書き方では、
["plus","x","y"]
のように、文字列が順に並べられている情况であると考えられる。 通常数学的な式は、いくつかの数の間の関係を表わす表式であるので、 あるベクトルを作成し、その最初の要素を関係を表わす文字列とし、 以降のベクトルの中味を先頭の文字列が表わす関係によって 関係づけられる量とすることで、数学的な関係が表わされるのである。 より複雑な式として例えば、
のような式は、
["plus", "1" , ["mul", "x","y"]]
のような構造を用いて計算すればよい。ただし、Cの文法では ベクトルの中にベクトルを代入するような仕方は、通常の仕方では 出来ないので、これはあくまで仮想的なデータと考えなくてはいけない。 実際の数式処理では、このようなデータを作成するためにLispという 計算機言語を用いている場合が多い。Lispは、このようなデータを 統一的に管理するためのリストと呼ばれるデータを使用している。 リスト自体はCを用いても書くことが出来るがそれを用いて 様々なデータ型を統一的に扱う手法を得ることはやや難しい作業となる。
2つめの手法はオブジェクト指向の手法を用いる手法がある。 しかし、この手法を用いた数式処理では有力なものがあまり知られていないため、 さしあたりこちらの手法は無視することにする。
データ処理
[編集]概説
[編集]プログラムは通常何らかのデータを他の形に加工するために作製されるため、 データの処理は常に必要となる。もちろんこの分野はアカデミックな研究分野としても 重要と思われるのだが、より実用的な計算機技術においても しばしば問題となっており、それぞれに対して解決法が考察されている。 ここでは、データの扱い方を少し一般的に扱う。
ここでいうデータは、 (1)人間の読める形式になっている。 (2)データとして扱われるものは文字でも数値でもよい。 を満たすものとする。例えば、計算機を用いて計算した数値計算の結果や すこし一般的には学術論文などに用いられる.texファイル、更にXML形式で 保存されたオフィスソフトの文書などもこの中に含まれる。
一般にデータは、何らかの規則に従って並べられた文字列の集合である。数値的な データはそれが1つのものであったら数値と改行をくり返すことで書かれていることが 多い。また、データが何らかの意味で対応づけられている場合には対応のあるデータは スペースやコンマ等で区切られ、そのあとに改行が付けられていることが多い。 例えば、実験が始まってからの時刻とその時刻での測定値を並べて書いている場合が これに当てはまる。これらはいずれもデータを並べる規則の1つとして扱うことが できる。更に、より複雑な例では.texファイルでは (1)命令に対しては最初に を付ける。 (2)引数を取る命令は命令の直後に を付けることによって記述する。 などのいくつかのルールを用いて組版の情報を計算機に伝達しているのである。 .texファイルの場合には計算機は書かれた情報を与えられた命令を用いて理解し、 それを用いて更に別種の命令を作りだすことが成されている。 これは、例えば測定データ等についても、更にデータに対して四則演算等の 加工を行ないそれを出力としたいときには、常に必要となる技工である。 一般的には例えばC言語のコンパイラがCのプログラムを扱うときでも このことは当てはまっており、 (1)用いる変数を宣言する。 (2)文の最後には;をつける。 などのいくつかの規則の元にコンパイラは機械語の命令群を出力しているのである。
ここでは、より簡単な場合として通常の測定データの処理などを扱う。 そのために正規表現の導入を行なう。
正規表現
[編集]w:正規表現とは次の規則で生成される文字列のことである。 (1)用いたい文字を全て導入し、それらを,とする。(nは整数。) (2)それらの任意の並びを文字列と呼ぶ。 (3)更に、ある文字列が任意の回数だけくり返されてできる文字列も 用いてよい文字列とする。 (4)どの文字とも一致するような文字が存在する。
通常正規表現を用いるプログラムではある程度記号ごとの意味が決まっている。 代表的なものとして、 (1)a,b, ...などの通常の文字 (2)1,2, ...などの通常の文字 (3)スペースなどの特殊な文字のうちで正規表現による意味が与えられていないもの (3) *:直前の文字が任意の回数だけくり返されることを表わす。 (4) []:かっこ内に現われる文字のいずれかが現われる。 (5) (): かっこ内に含まれる文字を1つの文字として扱う。 例えば、スペースを用いて区切られた任意の個数の数値 1 2 5 3 6 は、
([1-9] )*
に一致する。ここで、正規表現のパターンに一致した数値を後から使えるように したツールも知られており、その様なものを用いれば、 データを加工することが可能となるのである。 そのようなツールはPerl,Pythonなどが知られているが、 これらについてはプログラミングの手法でより詳しく述べる。
プログラミングの手法
[編集]RCS
[編集]RCS(Revision Control System)は、ソフトウェア開発における初期のバージョン管理システムであり、1970年代後半に登場した。RCSは、主にソースコードの単一ファイルの履歴管理を目的としており、変更内容を追跡するためにファイルごとにバージョン管理を行う。RCSの特徴は、変更履歴を記録し、過去のバージョンに簡単に戻すことができる点であり、主に個々の開発者による作業において重宝された。しかし、プロジェクトが大規模になると、RCSはファイルごとに管理するため、複数人での同時開発に対応するのが難しくなる。このため、より高機能で複数人での協力作業に適したバージョン管理システムが求められ、CVSなどの後続システムが登場した。
CVS
[編集]CVS(Concurrent Versions System)は、RCSの後継として、複数の開発者が同時に作業する環境に対応できるよう設計されたバージョン管理システムである。CVSは、ソースコードのリポジトリを中央に置き、複数の開発者が同時に作業しても、変更を管理し、統合することができる。CVSは、RCSのようにファイル単位でバージョンを管理するのではなく、リポジトリ全体の管理を行うため、大規模なプロジェクトにも適応することができる。さらに、CVSでは、分岐(ブランチ)やマージ(統合)といった機能が追加され、並行して作業する開発者同士の変更を統一する際の柔軟性が向上した。しかし、CVSは分岐やマージ機能において制約が多く、特に複雑な開発フローにおいては使いにくい点があり、後にGitやSubversionといったより強力で柔軟なシステムに取って代わられることとなった。
Subversion
[編集]Subversion(SVN)は、CVSの後継として登場したバージョン管理システムであり、CVSの問題点を改善することを目的として開発された。Subversionは、CVSのような中央集権型の管理システムであり、リポジトリの管理方法やバージョン履歴の追跡において多くの改良が加えられた。特に、分岐やマージの機能が強化され、開発者が複数のラインで並行して作業を行う場合でも、統合が容易である。また、Subversionは、CVSと比較してより直感的で使いやすく、大規模なプロジェクトでも安定した運用が可能となる。しかし、分散型のGitが登場したことで、Subversionは次第に利用される機会が減少し、特に個々の開発者が独立して作業を行う際にはGitの方が優れているとされている。
Git
[編集]Gitは、最も広く使用されている分散型バージョン管理システムであり、ソースコードの管理における標準ツールとなっている。Gitは、分散型であるため、ローカル環境でフル機能を持ち、ネットワーク接続がなくても作業を続けることができる。これにより、開発者は効率的に作業でき、他の開発者と作業を同期する際に変更の競合を簡単に解決できる。また、Gitは分岐とマージに優れた機能を持ち、複雑な開発フローでもスムーズに運用することが可能である。さらに、Gitは分散型のため、中央のサーバーがダウンしても、リポジトリのコピーがローカルに存在するため、作業を継続できる点が大きな利点である。Gitは、特にオープンソースコミュニティにおいて広く使用されており、GitHubなどのホスティングサービスと連携することで、世界中の開発者が協力してプロジェクトを進めることができる。
Fortran
[編集]Fortran(Formula Translation)は、数値計算を中心に開発された高級プログラミング言語であり、特に科学技術計算において重要な役割を果たしてきた。Fortranは、その歴史が長く、1960年代に登場して以来、様々な科学技術計算分野で広く使われている。数値計算に特化した特徴を持ち、高速で効率的な計算を実現するために多くの最適化が施されている。Fortranは、特に数値計算やシミュレーション、データ解析などの分野において、依然として高いパフォーマンスを発揮する。近年では、Fortranの最新バージョンでもオブジェクト指向や並列処理をサポートしており、より高度な計算を行うための新しい機能が追加されている。それでも、Fortranはその特化性ゆえに、他の汎用プログラミング言語とは異なる性質を持つため、特定の用途において強力であるが、他の分野ではあまり使用されないことがある。
Julia
[編集]Juliaは、数値計算に特化した新しい高級プログラミング言語であり、科学技術計算分野で急速に注目を集めている。Juliaは、高速な実行速度を誇り、C言語に匹敵する性能を持ちながらも、PythonやRのような高級言語の使いやすさを提供する。これにより、データ解析や機械学習、シミュレーションなどの分野で非常に有用である。Juliaは、動的型付けとコンパイルの両方をサポートしており、実行時に型推論を行うことで、最適なコードを生成する。また、並列処理やGPUアクセラレーションのサポートも充実しており、大規模な計算を効率的に行うことができる。Juliaは、科学技術計算において非常に優れたパフォーマンスを発揮し、次世代の数値計算言語としての地位を確立しつつある。
CUIの技術
[編集]viエディタ
[編集]shellプログラミング
[編集]最近の話題
[編集]オープンソースによる物理学シミュレーション
[編集]物理学におけるシミュレーションは、複雑な自然現象を理解し予測するための重要なツールとなっている。近年、オープンソースソフトウェアが物理学のシミュレーションにおいても広く利用されるようになり、その柔軟性と共同開発の恩恵が注目されている。例えば、分子動力学シミュレーションには「LAMMPS」や「GROMACS」などのソフトウェアがあり、これらは研究者によって常に改善され、新たな物理現象の探求を支えている。また、一般相対性理論や量子力学を扱うシミュレーションでは、「Einstein Toolkit」や「Quantum Development Kit」といったツールが活用され、広範な計算を可能にしている。オープンソースの特徴は、誰でもソースコードを確認し、修正や改良を加えることができる点であり、これにより、物理学者やエンジニアの共同作業が促進される。
計算物理学におけるGPUの活用
[編集]計算物理学の分野では、計算リソースを効率的に利用するための手段として、グラフィックス処理ユニット(GPU)の利用が増えている。特に、GPUは並列処理に優れ、数百万規模の粒子シミュレーションや大規模な数値計算を高速に実行できる。オープンソースの計算ライブラリやフレームワーク、例えば「CUDA」や「OpenCL」などが、GPUの利点を最大限に引き出すために利用されており、物理学のシミュレーションにおいても計算速度の向上が実現されている。これにより、複雑な物理現象のモデリングや、より精緻な数値解析が可能になり、シミュレーションの精度や解像度が向上している。
量子コンピュータと物理学の融合
[編集]量子コンピュータは、物理学における複雑な問題解決に革命をもたらす可能性を秘めている。量子力学を基盤にした計算機は、従来のコンピュータでは不可能な速度で計算を行えるため、物理学の問題、特に量子力学的な現象や物質の性質に関するシミュレーションにおいて大きな期待を寄せられている。オープンソースの量子コンピュータシミュレーションツール、例えば「Qiskit」や「Cirq」などは、研究者にとってアクセスしやすいリソースとなっており、量子アルゴリズムの実装や最適化に利用されている。これらのツールは、量子コンピュータが商業化される前から物理学の現場で利用され、量子力学の理解を深めるための重要なステップとなっている。
オープンデータと物理学研究の革新
[編集]物理学の進展には、観測データの収集と解析が不可欠であり、近年では多くの物理学的データがオープンデータとして公開されるようになっている。例えば、天文学では「Sloan Digital Sky Survey」や「LSST」などが提供する大規模な観測データがオープンアクセスで提供され、これらのデータを利用して新たな発見が行われている。また、実験物理学においても、CERNの「LHCデータ」など、巨大なデータセットが公開され、世界中の研究者がそれらを分析し、共同で研究を進めている。オープンデータの利用は、物理学における再現性の向上と、異なる視点からの新たな発見を促進するため、非常に重要な役割を果たしている。
科学技術計算におけるJuliaの普及
[編集]Juliaは、科学技術計算や数値解析分野で急速に普及しているプログラミング言語である。その高い性能とシンプルな構文が、特に物理学や工学の研究者から注目されており、既存の計算プラットフォームでのパフォーマンスの限界を超える可能性を持っている。Juliaの最大の特徴は、JIT(Just-In-Time)コンパイルによる高速な計算処理能力であり、これによりCやFortranに匹敵する速度で数値計算を行うことができる。その一方で、動的型付けを採用しているため、PythonやMATLABといった他の高水準言語と同じように直感的に記述できる。
Juliaは、多重ディスパッチという独自の特徴を持っており、関数の引数に基づいて最適な実装を選択することができる。この機能により、数値解析の効率が大幅に向上し、複雑な数値モデルやシミュレーションの実行が容易になった。また、並列処理や分散コンピューティングもサポートしており、スーパーコンピュータやクラウド環境を活用した大規模な計算を効率的に行うことができる。
物理学の分野では、Juliaは特に以下のような用途での利用が広がっている:
- 数値シミュレーション:物理学的なシミュレーションでは、膨大な計算リソースを必要とするケースが多い。Juliaは、分子動力学、流体力学、天体力学などのシミュレーションを効率的に実行するために必要な性能を提供しており、研究者にとって非常に有用なツールとなっている。
- 最適化問題:物理学では、システムの最適化やパラメータ推定などの問題を解決するために最適化手法を多く利用する。JuliaのOptim.jlやJuMP.jlなどのパッケージは、最適化問題の定式化と解決を非常に効率的に行うことができ、研究者にとって強力な支援となっている。
- データ解析と可視化:物理学では観測データの解析とその結果の可視化が重要な作業である。JuliaにはPlots.jlやMakie.jlといった高機能な可視化ライブラリがあり、大規模なデータセットを扱う際にも優れたパフォーマンスを発揮する。
Juliaの普及には、オープンソースコミュニティの支援も大きく関与しており、多くのユーザーや開発者が積極的に新しいパッケージの開発や最適化を行っている。このような活発なコミュニティの存在は、Juliaが物理学や他の科学技術分野での実用性を高める要因となっている。
また、Juliaは他の言語との連携にも優れており、PythonやC、Fortranなどで書かれた既存のライブラリと簡単に連携することができる。これにより、既存の計算リソースを活用しつつ、より高い性能を追求することが可能となる。
そのため、Juliaは今後さらに多くの物理学的問題に対する解決策を提供する言語として、重要な役割を果たすと考えられている。
科学者とエンジニアの共同作業を支えるツール
[編集]物理学の研究では、科学者とエンジニアが協力して新しい技術やモデルを開発する場面が増えている。このような共同作業を支えるために、オープンソースのツールやプラットフォームが役立っている。例えば、共同作業のためのバージョン管理システム「Git」や、プロジェクト管理ツール「GitHub」は、複数の研究者が協力して計算物理学やシミュレーションのプロジェクトを進めるために広く使用されている。また、コンテナ技術を利用した「Docker」や「Singularity」なども、研究環境を再現可能にし、シミュレーションコードを他の研究者と簡単に共有できる仕組みを提供している。これにより、物理学の研究はますます効率的に進行し、より多くの発見が加速することが期待されている。