gnuplot を使って描いた。
|
|
euler.dat を作るには、 https://m-katsurada.sakura.ne.jp/labo/text/num-ode/node27.htmlにある reidai5-2.c が使える。
% cc reidai5-2.c % ./a.out > euler.data 10 1280 2 % |
参考までそれを Python, Julia に書き換えたものを載せておく。
euler-error.py |
# euler-error.py ---dx/dt=x (0<t<1), x(0)=1 を Euler 法で解く import math # 微分方程式 x'=f(t,x) の右辺の関数 f の定義 def f(t,x): return x a=0.0; b=1.0 e=math.exp(1.0) x0=1.0 str=input("N0,N1,r=") s=str.split() N0=int(s[0]) N1=int(s[1]) r=int(s[2]) print('#') n=N0 while n <= N1: h=(b-a)/n # 開始時刻と初期値のセット t=a x=x0 for i in range(0,n): x += h * f(t,x) t += h print('%4d %e' % (n,abs(e-x))) # C言語の printf("%4d %e\n", n, fabs(e-x))相当 n *= r |
euler-error.jl |
# euler-error.jl --- dx/dt=x (0<t<1), x(0)=1 を Euler 法で解く # euler-error.c の真似 using Printf function f(t,x) x end function compute_euler_error(N0, N1, r) a=0.0; b=1.0; e=exp(1.0); x0=1.0; n=N0; while (n <= N1) h=(b-a)/n; t=a; x=x0; for i=0:n x += h * f(t, x); t += h; end @printf("%4d %e\n", n, abs(e-x)) n *= r; end end # julia euler-error.jl と実行した場合に実行する。 if abspath(PROGRAM_FILE) == @__FILE__ s=split(Base.prompt("# FIRSTN,LASTN,r=")) N0=parse(Int64,s[1]); N1=parse(Int64,s[2]); r=parse(Int64,s[3]); println("#") compute_euler_error(N0,N1,r) end |
euler-error.py を実行する |
% python euler-error.py > euler.data 10 1280 2 % cat euler.data # FIRSTN,LASTN,r=: # 10 1.348349e-01 20 6.768076e-02 40 3.390861e-02 80 1.697167e-02 160 8.490220e-03 320 4.246211e-03 640 2.123381e-03 1280 1.061760e-03 % |
euler-error.jl を実行する |
% julia euler-error.jl > euler.data |
runge-kutta.dat を作るプログラムは公開していないが、 reidai5-2.c を書き換えれば良い。Runge-Kutta法のコードは、 https://m-katsurada.sakura.ne.jp/labo/text/num-ode/node28.htmlが参考になる (分かってしまえば簡単, ほぼ該当部分のコピペで済む)。
gnuplot で描く |
set logscale xy plot "euler.data" with lp replot "runge-kutta.data" with lp(lp の l は L の小文字。 lp は linespoints の略。) |
gnuplot で描く (続き) |
set term pdf set output "compare_data.pdf" replot |
補足1 ここでは標準出力のリダイレクション (コマンド > ファイル名) を使って、 データ・ファイル euler.data を作成したが、 Cのプログラムの中で fopen(), fprintf(), flose() などの関数を使って直接ファイルを作成することも出来る (その方がずっと融通が効く)。 「常微分方程式の初期値問題を解くプログラムの書き方 2.3.1 Euler法のCプログラム例」 の問2を参考にすると良い(解答プログラム付き)。
補足2 Cのプログラムから直接 gnuplot を起動して、 データを渡してグラフを描くことも出来る。