Scipyのinterpolateはデータの外側へも広げられることを知った.
fminなどを使用していると,引数が意図しない範囲に行って補間が失敗して止まることがあるのだが,未然に防ぐことができる.
scipyのinterpolateは今まで使ったことがなかったが,事前にx, yの2つの数値列を与えておくと補間するための関数を返してくれるという仕様になっている.この関数として返すという仕様がfminなどで使うときの便利さにつながる.
さらに,interpolateはデータの範囲が超えたときにエラーにしない仕様がある.例えば以下のような例である
# -*- coding: utf-8 -*- import numpy as np import scipy as scipy from scipy.optimize import fmin from scipy import interpolate import matplotlib import matplotlib.pyplot as plt x = np.linspace(0, 100, num=1001, endpoint=True); y = np.zeros(x.shape); for i in range(y.shape[0]): if i < 500 and i > 50: y[i] = 1; f4 = scipy.interpolate.interp1d(x, y, 'cubic', fill_value='extrapolate') xi = np.linspace(-100, 200, num=121) plt.plot(x, y, linewidth='3'); plt.plot(xi, f4(xi)) plt.grid(True) plt.savefig('20190727test.png', format='png', dpi=100) plt.show();
さらに数値最小化の追加の例までついかすると例えば以下のようになる.
# -*- coding: utf-8 -*- import numpy as np import scipy as scipy from scipy.optimize import fmin from scipy import interpolate import matplotlib import matplotlib.pyplot as plt x = np.linspace(0, 100, num=1001, endpoint=True); y = (x - 40) ** 2 f2 = scipy.interpolate.interp1d(x, y, 'cubic', fill_value='extrapolate') minimum = scipy.optimize.fmin(f2, 1) xi = np.linspace(-100, 200, num=121) plt.plot(x, y, linewidth='3'); plt.plot(xi, f2(xi)) plt.plot(minimum, f2(minimum), '+') plt.grid(True) plt.savefig('20190727test2.png', format='png', dpi=100) plt.show();
導関数を使わない数値最小化ならこれらでもよいが,微分係数を使って勾配を下に下らせるように最適化を目指すアルゴリズムを使用したい場合には,計算が増えてしまう.そこで,UnivariateSplineというものもある.まず上の置き換えだけなら,
from scipy.interpolate import UnivariateSplie f2 = scipy.interpolate.UnivariateSpline(x, y, s=0, ext=0)
にするだけである.さらにf2.derivatives()なるものが使えるようになる
f2.derivatives(minimum)は[ほぼ0, ほぼ0, 2, ほぼ0]になるはず.順にf2の補間結果,1次微分係数,2次微分係数,...
タグ:Python