ニュートン法の可視化
ニュートン法によって近似値を求める様子を可視化した.
用いる関数は,f(x) = x^2 -4x + 3.
この関数について,f(x) = 0となるxを求める.


gifの作成には,Pythonとmatplotlib.animationを使用した.
コードを以下に載せる.
# Jupyter上でアニメーションを再生
%matplotlib nbagg
import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np
# xの初期値
curr_x = 4.0
# 変化量がthreshold以下になったら停止
threshold = 5.0e-2
# 変化量
change = 100
# 試行回数
count = 0
print('x{0}:{1}'.format(count, curr_x))
# gifアニメのための画像オブジェクト置き場
artists = []
fig = plt.figure()
# 2次関数とy=0の描画
# xの値の配列
x = np.arange(-0.5, 4.5, 0.05)
# 2次関数
y = x ** 2 - x * 4 + 3
# y=0用の配列
z = x * 0
# 関数の描画
plt.plot(x,y)
# y=0の直線を描画
plt.plot(x,z,'k')
# 軸の調整
plt.ylim(min(y)-1, max(y)+1)
while (threshold < change):
count += 1
# 傾き
grad = 2 * curr_x - 4
# f(curr_x)
f_a = curr_x ** 2 - curr_x * 4 + 3
# 現在のxをプロット
im = plt.plot(curr_x,0, 'bo')
# 現在の描画内容をアニメーションのフレームに追加(点のみ)
artists.append(im)
# 点線の描画
start_y = min(f_a, 0)
end_y = max(f_a, 0)
line_x = np.full(20, curr_x)
line_y = np.linspace(start_y, end_y, 20)
im2 = plt.plot(line_x, line_y, 'k', linestyle = ":")
# 点線と初期点の描画
im2.extend(im)
# 描画内容をアニメーションのフレームに追加
artists.append(im2)
#接線の描画
tan_y = f_a + grad * (x - curr_x) #接線描画用y座標
im3 = plt.plot(x, tan_y, 'r-')
# 接線と点線と初期値の描画
im3.extend(im2)
# 現在の描画内容をアニメーションのフレームに追加
artists.append(im3)
# 更新後の点を求める
change = abs(f_a / grad)
curr_x = curr_x - f_a / grad
print('x{0}:{1}'.format(count, curr_x))
# 更新後の点を描画
im4 = plt.plot(curr_x, 0, 'bo')
# 更新後の点と接線と点線と初期値の描画
im4.extend(im3)
# 現在の描画内容をアニメーションのフレームに追加
artists.append(im4)
anime = animation.ArtistAnimation(fig,artists,1000,2000)
plt.show()
anime.save('x1-43_shoki4.gif', writer="pillow")
可視化の必要がなければ,scipyのnewton関数を利用するのが簡単である.
from scipy.optimize import newton
# 関数の定義
def my_func(x):
return (x**2 - 4*x + 3)
# newton(関数, 初期値)で,f(x)=0となるxの近似値を計算
print(newton(my_func, 4))