Taylor 展開¶
In [1]:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
- numpy: 数値計算ライブラリ.配列操作や数学関数(例:三角関数、統計量など)を高速に行える.
- matplotlib.pyplot: グラフ描画ライブラリ.plt.plot() や plt.show() などを使って図を描ける.
- pandas: 表形式データの操作に特化したライブラリ.DataFrame や Series を使ってExcelのような操作ができる.
In [2]:
import scienceplots # v2.0.0以降では,これを必ず先に書く必要がある.
plt.style.use(['science', 'notebook']) # 論文フォーマットでノートブックにも見やすいスタイル.
#plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['font.family'] = 'serif' # LaTeX風のフォント
plt.rcParams['mathtext.fontset'] = 'cm' # Computer Modern(TeXのデフォルト数式フォント)
関数 sinx のTaylor展開は, sinx=x−x33!+x55!−⋯
In [3]:
def my_sin(x): # Taylor展開によるsinの計算
eps = 1.0e-6 # 収束の閾値
er = eps # 初期誤差
m2 = 1 # 初期の項番号
s = x # 初項 (sin(x) のTaylor展開の1項目)
t = s
while er >= eps:
m1 = m2+1
m2 = m1+1
t = -t*(x*x/m1/m2)
s = s+t
er = np.abs(t)
n_ = m1/2 # 何項目まで使ったか記録
return s,n_
In [4]:
nx = 181
q = 180.0/np.pi
dx = 1.0/q
print(f"{'no.':>3s} {'x[deg]':>7s} {'my_sin':>7s}"\
f"{'sin(x)':>7s} {'error':>13s} {'N':>2s}")
for i in range(0,nx,10):
x = i*dx
y, n_ = my_sin(x)
print(f"{i+1:3d} {x*q:7.3f} {y:7.3f}"\
f"{np.sin(x):7.3f} {y-np.sin(x):13.10f} {n_:2.0f}")
no. x[deg] my_sin sin(x) error N 1 0.000 0.000 0.000 0.0000000000 1 11 10.000 0.174 0.174 -0.0000000000 3 21 20.000 0.342 0.342 -0.0000000002 3 31 30.000 0.500 0.500 0.0000000000 4 41 40.000 0.643 0.643 0.0000000005 4 51 50.000 0.766 0.766 0.0000000056 4 61 60.000 0.866 0.866 -0.0000000003 5 71 70.000 0.940 0.940 -0.0000000022 5 81 80.000 0.985 0.985 -0.0000000122 5 91 90.000 1.000 1.000 0.0000000007 6 101 100.000 0.985 0.985 0.0000000032 6 111 110.000 0.940 0.940 0.0000000134 6 121 120.000 0.866 0.866 -0.0000000008 7 131 130.000 0.766 0.766 -0.0000000031 7 141 140.000 0.643 0.643 -0.0000000109 7 151 150.000 0.500 0.500 0.0000000007 8 161 160.000 0.342 0.342 0.0000000024 8 171 170.000 0.174 0.174 0.0000000076 8 181 180.000 0.000 0.000 0.0000000224 8
In [5]:
xx_deg = np.linspace(0.0, 180.0, nx)
xx = xx_deg/q
yy = np.empty(0)
nn_ = np.empty(0,dtype=int)
for i in range(nx):
y, n_ = my_sin(xx[i])
yy = np.append(yy,y)
nn_ = np.append(nn_, n_)
pd.DataFrame({
'$x$':xx_deg,
'my_sin$(x)$':yy,
'$\sin(x)$':np.sin(xx),
'error':yy-np.sin(xx),
'$N$':nn_,
})
Out[5]:
x | my_sin(x) | sin(x) | error | N | |
---|---|---|---|---|---|
0 | 0.0 | 0.000000e+00 | 0.000000e+00 | 0.000000e+00 | 1.0 |
1 | 1.0 | 1.745241e-02 | 1.745241e-02 | -1.349592e-11 | 1.0 |
2 | 2.0 | 3.489950e-02 | 3.489950e-02 | 1.253164e-14 | 2.0 |
3 | 3.0 | 5.233596e-02 | 5.233596e-02 | 2.140649e-13 | 2.0 |
4 | 4.0 | 6.975647e-02 | 6.975647e-02 | 1.603620e-12 | 2.0 |
... | ... | ... | ... | ... | ... |
176 | 176.0 | 6.975649e-02 | 6.975647e-02 | 1.464303e-08 | 8.0 |
177 | 177.0 | 5.233597e-02 | 5.233596e-02 | 1.630320e-08 | 8.0 |
178 | 178.0 | 3.489951e-02 | 3.489950e-02 | 1.814056e-08 | 8.0 |
179 | 179.0 | 1.745243e-02 | 1.745241e-02 | 2.017286e-08 | 8.0 |
180 | 180.0 | 2.241951e-08 | 1.224647e-16 | 2.241951e-08 | 8.0 |
181 rows × 5 columns
In [6]:
fig = plt.figure() # グラフ領域の作成
xx2 = np.linspace(0.0, 360.0/q, 181)
plt.plot(xx2,np.sin(xx2),color='tab:green', label='sin')
plt.xlabel('$x$')
plt.ylabel(r'$\sin(x)$')
nx = 10
xx = np.linspace(0.0, 180.0/q, nx)
yy = np.empty(nx)
yy[:] = [my_sin(xx[i])[0] for i in range(nx)]
plt.plot(xx,yy,'o',color='tab:orange', label='my_sin')
plt.legend(ncol=1, loc='upper right', fancybox=False, frameon = True)
fig.savefig('p2_ex01_1.pdf')
plt.show()
In [7]:
def my_sin2(x,n): # Taylor展開によるsinの計算(展開項数n)
m2 =1
s = x
t = s
for i in range(n):
m1 = m2+1
m2 = m1+1
t = -t*(x*x/m1/m2)
s = s+t
return s
In [8]:
q = 180.0/np.pi
nx = 24 # 計算点数
n = 12 # 展開項数
print(f"{'No.':>3s} {'x[deg]':>7s} {'my_sin':>7s}"\
f"{'sin(x)':>7s} {'error':>12s} {'N':>3s}")
dx = 15.0/q
for i in range(nx):
x = i*dx
y = my_sin2(x,n)
print(f"{i+1:3.0f} {x*q:7.2f} {y:7.3f}"\
f"{np.sin(x):7.3f} {y-np.sin(x):12.8f} {n:3.0f}")
No. x[deg] my_sin sin(x) error N 1 0.00 0.000 0.000 0.00000000 12 2 15.00 0.259 0.259 -0.00000000 12 3 30.00 0.500 0.500 0.00000000 12 4 45.00 0.707 0.707 0.00000000 12 5 60.00 0.866 0.866 -0.00000000 12 6 75.00 0.966 0.966 -0.00000000 12 7 90.00 1.000 1.000 0.00000000 12 8 105.00 0.966 0.966 -0.00000000 12 9 120.00 0.866 0.866 0.00000000 12 10 135.00 0.707 0.707 0.00000000 12 11 150.00 0.500 0.500 0.00000000 12 12 165.00 0.259 0.259 0.00000000 12 13 180.00 0.000 0.000 0.00000000 12 14 195.00 -0.259 -0.259 0.00000000 12 15 210.00 -0.500 -0.500 0.00000000 12 16 225.00 -0.707 -0.707 0.00000000 12 17 240.00 -0.866 -0.866 0.00000000 12 18 255.00 -0.966 -0.966 0.00000000 12 19 270.00 -1.000 -1.000 0.00000000 12 20 285.00 -0.966 -0.966 0.00000000 12 21 300.00 -0.866 -0.866 0.00000000 12 22 315.00 -0.707 -0.707 0.00000001 12 23 330.00 -0.500 -0.500 0.00000003 12 24 345.00 -0.259 -0.259 0.00000010 12
In [9]:
xx2_deg = np.linspace(0.0, 345.0, nx)
xx2 = xx2_deg/q
yy2 = my_sin2(xx2,n)
#pd.options.display.float_format = '{:.5f}'.format
df = pd.DataFrame({
'$x$':xx2*q,
'my_sin2(x)':yy2,
'$\sin(x)$':np.sin(xx2),
'error':yy2-np.sin(xx2),
})
#df.style.background_gradient(cmap='coolwarm')
#df.style.format({"x":"{:.1f}","my_sin2(x)": "{:.4f}", "sin(x)": "{:.4f}", "error": "{:.13f}"},)
def set_background_gradient(style):
return style.background_gradient(cmap='coolwarm')
def set_format(style):
return style.format({"$x$":"{:.1f}","my_sin2(x)": "{:.4f}", "$\sin(x)$": "{:.4f}", "error": "{:.13f}"},)
df.style.pipe(set_background_gradient).pipe(set_format)
Out[9]:
x | my_sin2(x) | sin(x) | error | |
---|---|---|---|---|
0 | 0.0 | 0.0000 | 0.0000 | 0.0000000000000 |
1 | 15.0 | 0.2588 | 0.2588 | -0.0000000000000 |
2 | 30.0 | 0.5000 | 0.5000 | 0.0000000000000 |
3 | 45.0 | 0.7071 | 0.7071 | 0.0000000000000 |
4 | 60.0 | 0.8660 | 0.8660 | -0.0000000000000 |
5 | 75.0 | 0.9659 | 0.9659 | -0.0000000000000 |
6 | 90.0 | 1.0000 | 1.0000 | 0.0000000000000 |
7 | 105.0 | 0.9659 | 0.9659 | -0.0000000000000 |
8 | 120.0 | 0.8660 | 0.8660 | 0.0000000000000 |
9 | 135.0 | 0.7071 | 0.7071 | 0.0000000000000 |
10 | 150.0 | 0.5000 | 0.5000 | -0.0000000000000 |
11 | 165.0 | 0.2588 | 0.2588 | 0.0000000000000 |
12 | 180.0 | 0.0000 | 0.0000 | 0.0000000000000 |
13 | 195.0 | -0.2588 | -0.2588 | 0.0000000000000 |
14 | 210.0 | -0.5000 | -0.5000 | 0.0000000000002 |
15 | 225.0 | -0.7071 | -0.7071 | 0.0000000000010 |
16 | 240.0 | -0.8660 | -0.8660 | 0.0000000000056 |
17 | 255.0 | -0.9659 | -0.9659 | 0.0000000000288 |
18 | 270.0 | -1.0000 | -1.0000 | 0.0000000001345 |
19 | 285.0 | -0.9659 | -0.9659 | 0.0000000005773 |
20 | 300.0 | -0.8660 | -0.8660 | 0.0000000022988 |
21 | 315.0 | -0.7071 | -0.7071 | 0.0000000085536 |
22 | 330.0 | -0.5000 | -0.5000 | 0.0000000299300 |
23 | 345.0 | -0.2588 | -0.2588 | 0.0000000990257 |
In [10]:
n = 6
xx2 = np.linspace(0.0, 360.0/q, 91)
fig = plt.figure() # グラフ領域の作成
plt.plot(xx2, np.sin(xx2), label='$\sin(x)$', color='green')
plt.plot(xx2, my_sin2(xx2, n), '.', label=f'$n={n}$')
plt.plot(xx2, my_sin2(xx2, n+1), '.', label=f'$n={n+1}$')
plt.plot(xx2, my_sin2(xx2, n+2), '.', label=f'$n={n+2}$')
plt.plot(xx, yy, 'o', label='my_sin2')
plt.legend(ncol=1, loc='lower left', fancybox=False, frameon = True)
fig.savefig('p2_ex01_2.pdf')