関数の零点
モジュールのインポート
import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt
from scipy.signal import find_peaks # ピーク値を探す
import scienceplots
#Warning : As of version 2.0.0, you need to add import scienceplots before setting the style (plt.style.use('science')).
plt.style.use(['science', 'notebook'])
関数の計算
def calf(func, x0, dx, nx): # 与えられた関数計算,出力
print(f"{'x':>8s} {'f(x)':>15s}")
for i in range(nx):
x = x0 + dx*i
y = func(x)
print(f"{x:>8.3f} {y:>15.11f}")
return
関数の零点:$f_1(x) = -(x+1.5)x(x-1.5) =0$
関数を$y = -(x+1.5)x(x-1.5)$とすると,
def func4a(x):
y = -(x+1.5)*x*(x-1.5)
return y
eps = 1.0e-15
# f1(x)=0
x1, x2 = 0.1, 4.0
print("f(x)=-(x+1.5)*x*(x-1.5)")
calf(func4a, 0.0, 0.2, 21)
f(x)=-(x+1.5)*x*(x-1.5)
x f(x)
0.000 0.00000000000
0.200 0.44200000000
0.400 0.83600000000
0.600 1.13400000000
0.800 1.28800000000
1.000 1.25000000000
1.200 0.97200000000
1.400 0.40600000000
1.600 -0.49600000000
1.800 -1.78200000000
2.000 -3.50000000000
2.200 -5.69800000000
2.400 -8.42400000000
2.600 -11.72600000000
2.800 -15.65200000000
3.000 -20.25000000000
3.200 -25.56800000000
3.400 -31.65400000000
3.600 -38.55600000000
3.800 -46.32200000000
4.000 -55.00000000000
フリーフォーマットでは,
xx = np.linspace(-2.0, 2.0, 51)
yy = func4a(xx)
xx,yy
(array([-2. , -1.92, -1.84, -1.76, -1.68, -1.6 , -1.52, -1.44, -1.36,
-1.28, -1.2 , -1.12, -1.04, -0.96, -0.88, -0.8 , -0.72, -0.64,
-0.56, -0.48, -0.4 , -0.32, -0.24, -0.16, -0.08, 0. , 0.08,
0.16, 0.24, 0.32, 0.4 , 0.48, 0.56, 0.64, 0.72, 0.8 ,
0.88, 0.96, 1.04, 1.12, 1.2 , 1.28, 1.36, 1.44, 1.52,
1.6 , 1.68, 1.76, 1.84, 1.92, 2. ]),
array([ 3.5 , 2.757888, 2.089504, 1.491776, 0.961632, 0.496 ,
0.091808, -0.254016, -0.544544, -0.782848, -0.972 , -1.115072,
-1.215136, -1.275264, -1.298528, -1.288 , -1.246752, -1.177856,
-1.084384, -0.969408, -0.836 , -0.687232, -0.526176, -0.355904,
-0.179488, 0. , 0.179488, 0.355904, 0.526176, 0.687232,
0.836 , 0.969408, 1.084384, 1.177856, 1.246752, 1.288 ,
1.298528, 1.275264, 1.215136, 1.115072, 0.972 , 0.782848,
0.544544, 0.254016, -0.091808, -0.496 , -0.961632, -1.491776,
-2.089504, -2.757888, -3.5 ]))
ピーク値は,
locs, _ = find_peaks(yy) # ピーク値
xx[locs],yy[locs]
(array([0.88]), array([1.298528]))
関数の概形をプロットすると,
fig = plt.figure() # グラフ領域の作成
plt.plot(xx,yy)
plt.plot([-10,10],[0,0],'--',color='gray',alpha=0.5)
plt.plot(xx[locs],yy[locs],'o')
plt.xlim(-2.0, 2.0)
#plt.ylim(-4.0, 4.0)
plt.xlabel(r"$x$")
plt.ylabel(r"$f(x)$")
fig.savefig('p2_ex04_1.pdf')
二分法
def bisect(func, eps, x01, x02): # 二分法
x1 = x01
x2 = x02
y = func(x1)
while np.abs(x2-x1)>eps:
xm = (x1+x2)*0.5
if y*func(xm)>0.0:
x1 = xm
else:
x2 = xm
return xm
区間$[1,4]$での関数の零点を二分法より求めると,
x1, x2 = 0.1, 4.0
xzero = bisect(func4a, eps, x1, x2)
print ('zero of function: ',xzero)
zero of function: 1.4999999999999991
Scipyの二分法より求めると,
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.bisect.html#scipy.optimize.bisect
xzero2 = optimize.bisect(func4a, x1, x2)
print ('optimize.bisect : ',xzero2)
optimize.bisect : 1.4999999999991358
Scipyのブレント法より求めると,
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.brentq.html
xzero3 = optimize.brentq(func4a, x1, x2)
print ('optimize.brentq : ',xzero3,"\n")
optimize.brentq : 1.5
関数の零点:$f_2(x) = \frac{\sin x}{x} + \cos x = 0$
def func4b(x):
u = x==0
t = np.where(u, 1.0, np.sin(x)/x)
y = t + np.cos(x)
return y
def func4c(x):
y = np.sinc(x/np.pi) + np.cos(x)
return y
関数の値は,
print("f(x)=sin(x)/x + cos(x)")
calf(func4b, -2.0, 0.2, 21)
f(x)=sin(x)/x + cos(x)
x f(x)
-2.000 0.03850187687
-1.800 0.31382436691
-1.600 0.59553397960
-1.400 0.87385980718
-1.200 1.13905699278
-1.000 1.38177329068
-0.800 1.59340182297
-0.600 1.76640640390
-0.400 1.89460684977
-0.200 1.97341323182
0.000 2.00000000000
0.200 1.97341323182
0.400 1.89460684977
0.600 1.76640640390
0.800 1.59340182297
1.000 1.38177329068
1.200 1.13905699278
1.400 0.87385980718
1.600 0.59553397960
1.800 0.31382436691
2.000 0.03850187687
プロットすると,
xx2 = np.linspace(-4.0, 4.0, 81)
yy2 = func4c(xx2)
fig = plt.figure() # グラフ領域の作成
plt.plot(xx2,yy2)
fig.savefig('p2_ex04_2.pdf')
関数の零点は,
x1, x2 = 0.1, 3.0
xzero = bisect(func4b, eps, x1, x2)
print ('zero of function: ',xzero)
xzero2 = optimize.bisect(func4b, x1, x2)
print ('optimize.bisect : ',xzero2)
xzero3 = optimize.brentq(func4b, x1, x2)
print ('optimize.brentq : ',xzero3)
zero of function: 2.028757838110434
optimize.bisect : 2.028757838110187
optimize.brentq : 2.0287578381103835
前のページに戻る
「目次」のページに戻る