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のデフォルト数式フォント)

関数 $\sin x$ のTaylor展開は, \begin{gather} \sin x = x - \frac{x^3}{3!} + \frac{x^5}{5!} - \cdots \end{gather}

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()
No description has been provided for this image
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')
No description has been provided for this image