投稿

2月, 2008の投稿を表示しています

正弦曲線を描く

計算結果を可視化するために, Javaを使って数値計算を教えようとする教科書を見かけた. Fortran用の可視化ライブラリはたくさんあるので, Fortranでも計算結果は簡単に可視化できる. アルゴリズムの研究にはJavaでもいいかもしれないが, ゆくゆくは大きな計算をするのならばやはりFortranを使った方がよいと思う.

計算するプログラムと可視化するプログラムは別であることも多く, 言語は同じである必要はない.

ともかく, Fortranから可視化ライブラリを呼んで実際に図を書いてみることにする. PLplotはC (もとはFortran 77) で書かれた可視化ライブラリである. C++, Fortran, Java, Tclなど多数の言語から使える. PLplotを使って, 正弦曲線を描いてみよう.

まずはMacPortsを使ってplplotをインストール.
sudo -d install plplot +g95
正弦曲線を描くプログラムは次の通り.
program p01
use plplot, pi=>pl_pi
implicit none

integer, parameter :: n = 20
integer :: i

real(kind=plflt), dimension(n) :: x, y

do i=1, n
x(i) = -pi + 2*pi*(i-1)/(n-1)
y(i) = sin(x(i))
end do


call plinit()
call plenv(-pi, pi, -1._plflt, 1._plflt, 0, 1)
call pllab("x", "y", "plot 1 y = sin(x)")
call plline(x, y)
call plend()

end program p01

必要なライブラリをpkg-configで取得してコンパイル.

g95 p01.f90 `pkg-config --cflags --libs plplotd-f95`

実行すると, 出力先の選択肢が示される. X Windowに表示するには1を選ぶ.
ほかの番号を選んで, PostScriptやPNG形式で保存することもできる.

最初のプログラム

半径を入力して円の面積を求めるプログラムは次の通り.

program area
implicit none

real, parameter :: pi = 3.14159
real :: r

print *, "Enter radius"
read *, r
print *, "radius=", r, "area=", pi*r**2
end program area

プログラムはprogramで始まり, programで終わる. プログラム名をここではareaとした. implicit noneは全ての変数を陽に宣言することを示している. Fortranでは, 宣言なしに変数を使うこともできるが, バグを防止するため, implicit noneは必ずつけるようにする.

realは実数の宣言. parameterは定数であるという属性. 変数rにキーボードから値を入力してもらい結果を表示する.

入力を促すprint文だけでなく, 確認のため入力された値を表示すると間違えが少なくなる.

大規模なプログラムであれば, namelist入出力を利用したり, コマンドラインツールを作るときは, コマンドライン引数を利用することがよい. 簡単なプログラムでは, print, read, printの組み合わせで対話的なプログラムを作る方が状態がひとつひとつ確認できるので便利である.

Pandoc

メモやウェブページ作成にMarkdownを使ってきたが, より高機能なPandocがあることを知った.

Pandocは, HTMLやTeXと相互変換でき, PDFも作れる.
Haskellという関数言語で書かれているところも面白い.TclでMarkdownを書いてみようかと思っていたが, Pandocほど多機能なものを作るのは大変だ.
「車輪の再発明」に時間をかけるより, 別のことをした方が良さそうだ.Pandocは, MacPortsにもパッケージがあるが, ghc (The Glasgow Haskell Compiler) がうまくコンパイルできないので, まだPandocを試せない.
# iPhone SDKを削除したらghcのコンパイルができました.

MacPortsでg95をインストール

Mac OS Xにも, BSD系OSやLinuxのようにパッケージ管理システムがある. たくさんのパッケージが登録されているのはFinkとMacPortsのふたつである.

FinkはDebianのツールを利用したシステムで, Perlで書かれいる. 8000を超えるパッケージを有し, バイナリも提供されている. OS毎にツリーがあり, さらにstable (安定版) と unstable (開発版) に分かれる. また, バイナリ, ヘッダ, ライブラリとパッケージが分かれている.

MacPortsは, FreeBSDのportsを参考にした作られたシステムである. FreeBSDのportsの実体はMakefileだがMacPortsのPortfileはTclスクリプトである. 登録されているパッケージは4500弱程度でFinkよりも少ないが, Finkと異なりバイナリ, ヘッダ, ライブラリを分けていないので, 差はもっと少ない. サポートされているのは現行のOSとその前のバージョンであるが, ツリーは一つである. OSのバージョン依存性は, Portfileの中で吸収されている. variantsという仕組みにより一つのPortfileでいくつかのオプションを提供できる. Tclの簡潔な言語仕様をうまく利用している.

パッケージ数の多いFinkが主に使われてきたが, Appleがサポートし社員も関わっているMacPortsに勢いがある. Finkはバイナリも提供されているので, 初心者には使いやすい反面, 細分化が徹底して完璧主義なのでパッケージの管理は面倒である. MacPortsはコンパイルのお手伝いという気楽な側面がある. うまくいかなくて, 自分で手を動かす場合の敷居が低いように感じられる. この辺りが気に入ってFinkからMacPortsに移行した.

g95自体はバイナリがインストールされているので, Fortranだけに興味があれば,
バイナリをインストールすれば済むが, 数値計算や描画のライブラリを簡単に利用するには,
パッケージ管理システムを導入するとよい.

デフォルトでは, /opt/local以下にMacPortsで導入したものが保存される.

MacPortsでg95をインストールするための手順を示す.
まずMacPortsをインストールする. インストー…

ソースからg95をコンパイルする

g95をソースからコンパイルする方法は, g95のサイトに手順が示されているが要点を下記に記す.

まず, gcc-4.0.3とg95のソースを取得する.
最新のgcc-4.2.xを使うには大規模な改変が必要になる. 当面gcc-4.2系列に移行する予定はないそうである.

gcc-4.0.3を展開し, その中にg95というディレクトリを作る. gcc-4.0.3/g95に移動して,
../configure --enable-languages=c
のあとmakeする. 必要なファイルlibgcc.a, libbackend.aができればよい.

次にg95を展開して,
./configure --prefix=インストール先 --with-gcc-dir=gccのディレクトリ

を実行. インストール先には適切なインストール先, 例えば$HOMEを指定する. gccのディレクトリは上で使ったgcc-4.0.3を指定する. make, make install (インストール先によっては, 管理者権限が必要な場合がある) した後, libf95.a-0.91.tgz (安定版の場合はlibf95.a-0.90.tgz) を展開して, configure, make, make installする. configureのprefixオプションは, 上と同じインストール先を指定する. 適宜, バイナリファイルの名前はプラットフォームに依存したものになるので, 使いやすいようにシンボリックリンクをはる.


Mac OS X 10.5 (Leopard) では, いくつかパッチが必要になるので, パッケージ管理システムMacPortsまたはFinkからインストールすることを勧める.

g95バイナリのインストール

g95を試してみるには, バイナリを利用するのが手っ取り早い. さまざまなプラットフォーム用のバイナリがg95のダウンロードサイトにある.

g95には開発版と安定版とがある. 開発版で日々更新されているcurrent snapshotと2006年8月の安定版 (バージョン0.9) がある. 開発版では, 機能追加に伴ってバグが入ったり修正したりしているので, 通常は安定版を導入するのがよいだろう. Fortran 2003の最新の機能が必要な場合は, 開発版を使ってみるとよい.

まず, Mac OS Xを含むUnix/Linuxの場合について説明する.

バイナリをダウンロードし, 適当な場所に展開すると, g95-installというディレクトリができるので, そこに移動する. binディレクトリにある*-g95 (*はプラットフォームを識別する文字列) という名前の実行ファイルのシンボリックリンクをパスが通っている場所に作る. 例えば, ホームディレクトリの下のbinにパスが通っている場合は,

$ ln -s bin/*-g95 ~/bin/g95

とする.

Windows用には, MinGW版及びCygwin版が配布されている. Cygwinがインストールされていない環境用にCygwinの一部をインストールするものもあるが, 廃止予定とあるので使わない方がよいだろう. MinGW版は, もっともよく使われている版である. MinGWも同時にインストールされ, コマンドプロンプトg95をで利用する. Cygwin版を使う場合は, 前もって最新のCygwinをインストールしておく必要がある. Cygwin版では, bash上でg95を使うことになる. DOSのコマンドに慣れている場合は前者, Unix/Linux環境になじんでいる場合は後者が便利だろう. VMWareのような仮想環境にLinuxやBSD系のOS, Solarisをインストールして, その中で使うのもよいだろう.

gfortranとg95

フリーのFortran 90/95コンパイラには, gfortrang95がある. gfortranは, gcc (GNU compiler collection) に含まれているFortranコンパイラである. かつては, g77が含まれていたがg77はgcc-4.Xではサポートされていない.

g95は, gcc-4.0に基づいたFortranコンパイラである. gfortranは, もともとg95から分離してgccの一部として開発が始まったものである. それぞれ独立して開発が進められた結果, 現在ではソースはかなり異なったものとなっているそうである. g95は「オリジナル」「元祖」でgfortranは「オフィシャル」「本家」だと言える.

二つのコンパイラは開発体制が異なる. g95は, 協力者からのバグ報告を受けながら, 開発を始めたAndy Vaught氏がひとりでソースコードを管理している. gfortranは, 複数の開発者により開発されている.

g95は歴史が長い分, より多くのプログラムのコンパイルが試されていて, 安定していることが特長である. g95のサイトにあるリストには, コンパイルができたことが確認されているプログラムが多数列挙されている. g95は, より多くのFortran 2003の機能を実装している. gcc全部をコンパイルしなくて良いので, g95の構築は早く終わるので, Fortranさえ使えればよいのなら導入が簡単である.

gfortranは, gccに含まれている点が強みである. Fortran 90/95の実装には差があまりないようである. マルチコア, マルチプロセッサを搭載したパソコンやクラスタでOpenMPを使ったプログラムを使いたい場合は, gfortranを使う必要がある.

g95は, gcc-4.2で導入されたGNU版OpenMP GOMPへの対応の予定はないが, Fortran 2008の仕様に含まれることになったco-arrayの実装に取り組んでいるそうである. gfortranはgccとの統合を進めて, 多機能化やパフォーマンスの改善を進めていくのだろう. g95は, Fortranの規格に準拠した, ユーザが使いやすいコンパイラを志向しているようである.

gfortranには勢いがあるようだが, ここでは安定性に…

数値計算にはFortran

半世紀の歴史を持つFortranはCOBOLと並んで, 過去の遺物だと思われている. 大規模な数値計算では, Fortranは現役である. 正確な統計はないが, 地球シミュレータで実行されている大規模な計算のほとんどはFortranで書かれている. Cで書かれているものがいくつかあり, その中には最適化のために一部をFortranで書き直したものがあるそうだ.

パソコンでは, コンパイル不要なスクリプト言語が, さまざまな用途に使われている. パソコンの計算性能が向上し, スクリプト言語でも実用的な計算ができる. しかし, 計算量の大きな問題を解くときは, CやFortranで書いたプログラムの方が圧倒的に速く計算が終了する.

コンパイルは簡単なプログラムならほぼ瞬時に終わるので, プログラムの作成 (修正) と実行のサイクルにおいて, 妨げにはならない. Fortran 77はオブジェクト指向ではないが, サブルーチンは, 十分再利用されてきた. Fortran 90以降はmoduleが導入され, 再利用がしやすくなっている. Fortranは77以前のイメージがつきまとうが, 95, 2003, そして2008と進化を続けている.

スクリプト言語にもさまざまなライブラリへのラッパが提供されていて, 手軽に利用できるようになっているが, CやFortranの資産を利用しているものが多い. それらの資産は, ラッパの作り方の作法を覚えなくても, CやFortranからはそれぞれ直接利用できる. CからFortranのサブルーチンや関数, FortranからCの関数を呼び出すことは, それほど難しくない. CとFortran 77との相互利用の規約はよく知られているし, Fortran 2003ではCとの相互運用性が高められている.

最近ではスクリプト言語での利用も考えて, Cで書かれたライブラリも多い. C99では複素数も使えるようになった. それでは, Cを使うべきだろうか. Cはシステムに近い言語で危険なプログラムが簡単に書ける. また, 配列の機能がFortranに比べて少ない. 基本的な関数を書くにはよいが, 数値計算のプログラムにはFortranが便利である.

JavaはCよりも安全で様々なプラットフォームで動作する. また, 星の数ほどあるフレームワークやライブ…