AUTO
AUTO
AUTO という、分岐分析のソフトウェアを西浦研でextensive に使っている。要は,特定の解からじわじわパラメータをずらしていって、解の性質が不連続に変わるところを見つけてプロットする,というものだが,UNIX で普通に走るらしいので,iBookに入れてみることにする。
まずソースコードを展開して、下におりていってmake をかけると、GUI関係の関数がない,ということでエラーが大量に出て止まる。
マニュアルを見ると,Makefile を変えればいいらしいが,それよりテキストベースで充分なので
make cmd
をかけてみる。すると今度はf77コマンドがない,というエラーが出る。Fortran のコンパイラは持っていたはずなので、該当するファイルの入っているディレクトリを探し出して,Makefile の中のコンパイラの指定を “gfortran” に変える。
すると今度は,古い命令,ということでいくつかエラーが出る。Fortran95ってFortran77 の上位互換ではないのか?gfortran の説明を見てみると,gnu では g77 というコンパイラを別に配っているらしい。fink で取ってこよう。
finkを使ってg77を取ってきている間に説明書を読む。guiは着いて入るが,なくてもよいらしい。その場合は”make cmd ”でいけるそうな。g77でコンパイルをかけてみたら,普通に通った。
ついでにguiもなんとかしたいと思ってmake をかけてみると,たくさんエラーが出て止まる。まず、古いインクルードファイルを使っている,というエラーに関しては、単に新しいヘッダファイルに入れ替えたら消えた。その他のエラーに関してチェックしてみると,
In file included from auto97.c:5: ../include/GuiFuncs.h:317: error: ISO C requires a named argument before `...'
該当部分を見てみたら
extern void Wprintf(...);
となっていたので、…を取ってみると,多少コンパイルが進んだ。いっぱいエラーが出ていたように見えたが,大半がWarning だった。さらに
auto97.c:12871: error: parse error before "va_dcl"
というのがあったので見てみたら,何の脈絡もなくva_dclという文字列が入っていたので,削ってみた。さらに
auto97.c:2281: error: too few arguments to function `DeletePrimarySelection'
というのがあったので,該当部分を見て
DeletePrimarySelection(cb->event->xbutton.time);
に変更。さらに
auto97.c:12879: error: `va_start' undeclared (first use in this function)
の部分を見て
va_start(args);
この定義をしているのがstdarg.hなので、includeしてみるが,変わらない。
そうこうしているうちに、autoの新しいバージョンが出ていることに気づく。ばかばかしいのでそちらに変えてみる。configure>makeでできる、とのことだったので、とりあえずかけてみる。
まずmalloc.hがないというおなじみのエラー。stdlib.hに変えたら通る。というか全部通ってしまって拍子抜けをする。デモを走らせてみたら,テキストベースは走るが,結果を表示する@pというコマンドがうまく走らない。具体的には,黒い画面が出てきて,四角い豆腐がいくつも出てくるだけで何も起こらない。何だ?
と思っていたが,上山さんのホームページを見て,tektronix 端末の上で何か打ち込んでみたら,出た!
Apple X11 上で
xterm -t
とやるだけでもバケバケのウインドウが出てくるから,どうやらX11側の問題らしい。tektronic が使うフォントが指定されていないのではないか?
.xinitrc に何かつけてみようかと思ったが,ファイルが存在するだけでX11アプリが立ち上がらなくなってしまう。何じゃこりゃ。検索をかけてみたら
http://www.bjlug.org/ml-archive/jan05/msg00016.html
というのを発見。しかしこいつをコピペしてもやっぱり終わる。さらにいろいろ探すと,Appleのfaqページで、.xinitrc にあたるものは
/etc/X11/xinit
にあることを発見。その頭に
userresources=$HOME/.Xresources
最後に
exec quartz-wm
と書いてあるから,これをまねて..xinitrcを作ってみる。
これはともかく、xtermでフォントを指定するにはどうしたらいいのか?探していたら以下の記事を発見。
http://www.linux.or.jp/JF/JFdocs/XWindow-User-HOWTO-7.html
そうか。その他、昔の人の書いたtektronix の話のページなどを参考にして
xterm -t %480x360 -fg white -bg cadetblue -xrm "*tek4014.fontLarge:6x13"
等と打ってみるが,変わらない。そのうち、Appleのディスカッションボードで5月頃に全く同じ問題に突き当たって投稿している人を発見。ageておく。また、Appleのバグリポートも送っておく。ちょっと思いついてWindow Manager を変えてみたが,そういう問題でもないようだ。元に戻す。その他、他のターミナルではどうか?とも思ったが,ktermではTektronix のサポートは終わっているらしい(コンパイル時にオプションをつけないといけない)。
今後の方針としては 1. X11.app のソースがあったらいじってみる 2. kterm をコンパイルしてみる 3. X11 のオプションをいじる
といったところか。それ以前に分岐分析は何かについてきちんと把握しないと…
何をしたいか?例題>上田さんの仕事の理解 FitzHugh-Nagumo でのパターン形成の理解:パラメータを振った場合,sutureを残す場合と消える場合がどのように異なるか???
…G5 にインストールしたら,なんと普通に動いた。何が違うのかチェックしてみたら,X11.appが前のバージョンだった。はて、と思い,X11のアプリを移して試してみたが,こちらはだめ。XFRee86 4.3.0を使っているか4.4.0を使っているかの違いらしい。finkで何とかならんかと思ってみたら,こちらは4.5.0まで出ているらしい。
今日,fink でxfree86 4.5.0 を入れてみたが,結果は変わらず。困ったものだ。
次善の策として,kterm をコンパイルしてみる。やたらとエラーが出るので何かと思ったら,X11SDKが入っていなかった。Tiger DVD からはなぜかインストールできないので,ADCから落としてきて使う。 kterm.h の頭の部分の
#define KTERM_NOTEK /* disables Tektronix emulation */
の部分を
#undef KTERM_NOTEK /* disables Tektronix emulation */
に変えたら,warning は山ほど出るがコンパイラは通る。それから@pの中身をmiで開いて、xtermを開いている部分を
kterm -t -e $AUTO_DIR/bin/plaut &
としてやったら,見事に出るようになった!!!
とりあえず上山さんのホームページを参考にして簡単な関数に関してAUTO を走らせてみる。
という常微分方程式を考え,パラメータlambda が−2から2まで変化するときの解を追跡する。最初の解は(lambda, u)= (-1,1)とする。
どうやらFortran から C に変えたらしく,そのままでは使えない。まず、関数定義の部分はab.cというファイルを使う。
{ #include "auto_f2c.h" /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ab : The A --> B reaction */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ int func (integer ndim, const doublereal *u, const integer *icp, const doublereal *par, integer ijac, doublereal *f, doublereal *dfdu, doublereal *dfdp) { doublereal e, u1, u2; /* Evaluates the algebraic equations or ODE right hand side */ /* Input arguments : */ /* ndim : Dimension of the ODE system */ /* u : State variables */ /* icp : Array indicating the free parameter(s) */ /* par : Equation parameters */ /* Values to be returned : */ /* f : ODE right hand side values */ /* Normally unused Jacobian arguments : IJAC, DFDU, DFDP (see manual) */ u1 = u[0]; f[0] = par[0] + u[0]*u[0]; return 0; } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ int stpnt (integer ndim, doublereal t, doublereal *u, doublereal *par) { /* Input arguments : */ /* ndim : Dimension of the ODE system */ /* Values to be returned : */ /* u : A starting solution vector */ /* par : The corresponding equation-parameter values */ /* Initialize the equation parameters */ par[0] = (doublereal)-1.0; /* Initialize the solution */ u[0] = (doublereal)1.0; return 0; } /* The following subroutines are not used here, */ /* but they must be supplied as dummy routines */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ int bcnd (integer ndim, const doublereal *par, const integer *icp, integer nbc, const doublereal *u0, const doublereal *u1, integer ijac, doublereal *fb, doublereal *dbc) { return 0; } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ int icnd (integer ndim, const doublereal *par, const integer *icp, integer nint, const doublereal *u, const doublereal *uold, const doublereal *udot, const doublereal *upold, integer ijac, doublereal *fi, doublereal *dint) { return 0; } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ int fopt (integer ndim, const doublereal *u, const integer *icp, const doublereal *par, integer ijac, doublereal *fs, doublereal *dfdu, doublereal *dfdp) { return 0; } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ int pvls (integer ndim, const doublereal *u, doublereal *par) { return 0; } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ }
次に,パラメータ定義のファイルはc.abというファイルを使う。(名前をどういう基準で選んでいるかは謎。)
1 1 0 1 NDIM,IPS,IRS,ILP 1 0 NICP,(ICP(I),I=1 NICP) 50 4 3 1 1 0 0 0 NTST,NCOL,IAD,ISP,ISW,IPLT,NBC,NINT 100 -2.0 2.0 0.0 100.0 NMX,RL0,RL1,A0,A1 100 10 2 8 5 3 0 NPR,MXBF,IID,ITMX,ITNW,NWTN,JAC 1e-06 1e-06 0.0001 EPSL,EPSU,EPSS 0.01 0.005 0.05 1 DS,DSMIN,DSMAX,IADS 0 NTHL,(/,I,THL(I)),I=1,NTHL) 0 NTHU,(/,I,THU(I)),I=1,NTHU) 0 NUZR,(/,I,PAR(I)),I=1,NUZR)
これで走らせた結果が以下の通り。
二次関数だから,安定解と不安定解の枝があって,lambda=0で消える,と。もう一つ分岐でよく出てくるpitchfork 型の分岐
も試してみる。こちらのab.c は以下の通り。
{ #include "auto_f2c.h" /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ab : The A --> B reaction */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ int func (integer ndim, const doublereal *u, const integer *icp, const doublereal *par, integer ijac, doublereal *f, doublereal *dfdu, doublereal *dfdp) { doublereal e, u1, u2; /* Evaluates the algebraic equations or ODE right hand side */ /* Input arguments : */ /* ndim : Dimension of the ODE system */ /* u : State variables */ /* icp : Array indicating the free parameter(s) */ /* par : Equation parameters */ /* Values to be returned : */ /* f : ODE right hand side values */ /* Normally unused Jacobian arguments : IJAC, DFDU, DFDP (see manual) */ u1 = u[0]; f[0] = par[0]*u[0] - u[0]*u[0]*u[0]; return 0; } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ int stpnt (integer ndim, doublereal t, doublereal *u, doublereal *par) { /* Input arguments : */ /* ndim : Dimension of the ODE system */ /* Values to be returned : */ /* u : A starting solution vector */ /* par : The corresponding equation-parameter values */ /* Initialize the equation parameters */ par[0] = (doublereal)-1.0; /* Initialize the solution */ u[0] = (doublereal)-0.0; return 0; } /* The following subroutines are not used here, */ /* but they must be supplied as dummy routines */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ int bcnd (integer ndim, const doublereal *par, const integer *icp, integer nbc, const doublereal *u0, const doublereal *u1, integer ijac, doublereal *fb, doublereal *dbc) { return 0; } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ int icnd (integer ndim, const doublereal *par, const integer *icp, integer nint, const doublereal *u, const doublereal *uold, const doublereal *udot, const doublereal *upold, integer ijac, doublereal *fi, doublereal *dint) { return 0; } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ int fopt (integer ndim, const doublereal *u, const integer *icp, const doublereal *par, integer ijac, doublereal *fs, doublereal *dfdu, doublereal *dfdp) { return 0; } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ int pvls (integer ndim, const doublereal *u, doublereal *par) { return 0; } /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ }
で、結果はこれ。

なるほど,うまいこと動いてくれているようだ。イントロを見ると1次元の反応拡散ぐらいは解いてくれるらしい。最初の定常解の定義とか面倒くさそうだけど、どうするんだろう?空間に関しても周期解ということにしてしまうのか?