修正オイラー法

テイラー展開を用いると誤差を小さくすることができる。詳しくは次のサイトで。

http://www.geocities.jp/supermisosan/syuseieulerprogram.html
修正オイラー法

def euler(x0, y0, dx, endx):
	x = x0
	y = y0
	res = [[x, y]]
	while x <= endx:
		s1 = f(x, y)
		s2 = f(x + dx/2, y + dx*s1/2)
		x += dx
		y += (s1 + s2) * dx / 2
		res.append([x, y])
	return res

def f(x, y):
	return (x**2 +x + 1) - (2*x + 1)*y + y**2

def output(filename, ans):
	f = open(filename, 'w')
	for i in ans:
		f.write('%f %f\n' % (i[0], i[1]))
	f.close()

def main():
	x0 = 0.0    #初期値
	y0 = 0.5
	dx = 0.1    #刻み幅
	endx = 2.0    #終了地点
	filename = 'data.txt'
	ans = euler(x0, y0, dx, endx)
	output(filename, ans)

if __name__ == '__main__':
	main()


data.txtの中身はこちら

0.000000 0.500000
0.100000 0.575008
0.200000 0.650109
0.300000 0.725428
0.400000 0.801082
0.500000 0.877187
0.600000 0.953846
0.700000 1.031156
0.800000 1.109200
0.900000 1.188050
1.000000 1.267765
1.100000 1.348390
1.200000 1.429960
1.300000 1.512496
1.400000 1.596006
1.500000 1.680489
1.600000 1.765937
1.700000 1.852331
1.800000 1.939644
1.900000 2.027848
2.000000 2.116907


ちなみにこれは2次のルンゲ・クッタ法とも呼ばれる。

今回も某教科書に載ってた例を使った。結果はほぼ同じになったので大丈夫なはず。
精度が1のオイラー法との比較をやろうとはしたもののうまいグラフが作れなかったので省略。もっと細かいデータを作れば差がわかりやすくなるのかもしれない。


だんだん適当になってる気がするけど気にしない…