Pythonで数値積分 〜フーリエ級数展開を例に、てかscipy.integrate.quad()かわいいよscipy.integrate.quad()
はいはいまたグラフ描きたいだけのエントリですよ。てか数値積分が簡単に出来ちゃうSciPy(・∀・)イイネ!!
が
from scipy.integrate import quad y, abserr = quad(f, a, b)
で計算できちゃうのです。(y が積分値、abserrは推定誤差の絶対値)
基礎編
→ を期待。
# -*- coding: utf-8 -*- from scipy.integrate import quad y, abserr = quad(lambda x:x*x*x, 0, 2) print "∫_0^2 x^3 dx = %g ± %g" % (y, abserr)
→ ∫_0^2 x^3 dx = 4 ± 4.44089e-14
正解。推定誤差も小さい。
相手はSciPy様なので人間に正解とか言われてもおそらくあれですね。
→ を期待。
# -*- coding: utf-8 -*-
from numpy import sin
from scipy.integrate import quad
y, abserr = quad(sin, 0, pi/3)
print "∫_0^{¥pi/3} sin x dx = %g ± %g" % (y, abserr)→ ∫_0^{\pi/3} sin x dx = 0.5 ± 5.55112e-15
これも正解。
応用編
定積分を使ってて簡単そうなところで(かつグラフが描けそうなところで←ここ重要)、フーリエ級数展開とかしてみる。
の係数の計算に定積分を使うあれです。
# -*- coding: utf-8 -*-
from pylab import *
from scipy.integrate import quad
def fourier(fun, n_max):
a = []
b = []
for n in xrange(0, 1+n_max):
res, err = quad(lambda x:fun(x)*cos(n*x), -pi, pi)
a.append(res/pi)
res, err = quad(lambda x:fun(x)*sin(n*x), -pi, pi)
b.append(res/pi)
def fn(x):
sum = a[0] / 2
for n in xrange(1, 1+n_max):
sum += a[n]*cos(n*x) + b[n]*sin(n*x)
return sum
return fn
def f(x):
x = (x + pi) % (pi * 2) - pi
if x >= 0:
return 1
else:
return 0
x_min = -pi - 0.5
x_max = pi*2 + 0.5
y_min = -0.25
y_max = 1.25
axis([x_min, x_max, y_min, y_max])
f_fn = fourier(f, 10)
xs = linspace(x_min, x_max, 256)
plot(xs, amap(f, xs), 'b:', lw=1)
plot(xs, amap(f_fn, xs), 'r-', lw=1)
show()
いくつか遊んでみた結果をアニメGIFにしてみた。ImageMagickで
$ convert -delay 42 f1_*.png -loop 0 anime_f1.gif
Gistに貼ったソースをここにembedしてみるテスト。(2/27から出来るようになったらしいので)
ライセンスはNYSLでどぞ。





