#!/usr/bin/env python # coding: utf-8 # # Table of Contents #

0.1  補間法
0.1.1  ラグランジュ補間
0.1.2  逆行列から
0.2  対数関数のニュートンの差分商補間(2014期末試験,25点)
0.2.1  差分商補間の表中の開いている箇所[ XXX ]を埋めよ.
0.2.2  ニュートンの二次多項式
0.2.3  ニュートンの三次多項式の値を求めよ.
0.2.4  補足
0.3  数値積分(I)
# ## 補間法 # 次の4点 # ```maple # x y # 0 1 # 1 2 # 2 3 # 3 1 # ``` # を通る多項式を(a)ラグランジュ補間, (b) 逆行列で求めよ. # ### ラグランジュ補間 # In[4]: import numpy as np from scipy import interpolate import matplotlib.pyplot as plt # もとの点 x = np.array([0,1,2,3]) y = np.array([1,2,3,1]) for i in range(0,4): plt.plot(x[i],y[i],'o',color='r') # Lagrange補間 f = interpolate.lagrange(x,y) print(f) x = np.linspace(0,3, 100) y = f(x) plt.plot(x, y, color = 'b') plt.grid() plt.show() # ### 逆行列から # In[19]: from pprint import pprint x = np.array([0,1,2,3]) y = np.array([1,2,3,1]) n = 4 A = np.zeros((n,n)) b = np.zeros(n) for i in range(0,n): for j in range(0,n): A[i,j] += x[i]**j b[i] = y[i] pprint(A) pprint(b) # In[18]: import scipy.linalg as linalg # SciPy Linear Algebra Library inv_A = linalg.inv(A) pprint(inv_A) np.dot(inv_A,b) # ## 対数関数のニュートンの差分商補間(2014期末試験,25点) # # 2を底とする対数関数(Mapleでは$\log[2](x)$)の$F(9.2)=2.219203$をニュートンの差分商補間を用いて求める.ニュートンの内挿公式は, # # $$ # \begin{array}{rc} # F (x )&=F (x _{0})+ # (x -x _{0})f _{1}\lfloor x_0,x_1\rfloor+ # (x -x _{0})(x -x _{1}) # f _{2}\lfloor x_0,x_1,x_2\rfloor + \\ # & \cdots + \prod_{i=0}^{n-1} (x-x_i) \, # f_n \lfloor x_0,x_1,\cdots,x_n \rfloor # \end{array} # $$ # である.ここで$f_i \lfloor\, \rfloor$ は次のような関数を意味していて, # $$ # \begin{array}{rc} # f _{1}\lfloor x_0,x_1\rfloor &=& \frac{y_1-y_0}{x_1-x_0} \\ # f _{2}\lfloor x_0,x_1,x_2\rfloor &=& \frac{f _{1}\lfloor x_1,x_2\rfloor- # f _{1}\lfloor x_0,x_1\rfloor}{x_2-x_0} \\ # \vdots & \\ # f _{n}\lfloor x_0,x_1,\cdots,x_n\rfloor &=& \frac{f_{n-1}\lfloor x_1,x_2\cdots,x_{n}\rfloor- # f _{n-1}\lfloor x_0,x_1,\cdots,x_{n-1}\rfloor}{x_n-x_0} # \end{array} # $$ # 差分商と呼ばれる.$x_k=8.0,9.0,10.0,11.0$をそれぞれ選ぶと,差分商補間のそれぞれの項は以下の通りとなる. # # $$ # \begin{array}{ccl|lll} # \hline # k & x_k & y_k=F_0( x_k) &f_1\lfloor x_k,x_{k+1}\rfloor & f_2\lfloor x_k,x_{k+1},x_{k+2}\rfloor & f_3\lfloor x_k,x_{k+1},x_{k+2},x_{k+3}\rfloor \\ # \hline # 0 & 8.0 & 2.079442 & & &\\ # & & & 0.117783 & &\\ # 1 & 9.0 & 2.197225 & & [ XXX ] &\\ # & & & 0.105360 & & 0.0003955000 \\ # 2 & 10.0 & 2.302585 & & -0.0050250 &\\ # & & & 0.095310 & &\\ # 3 & 11.0 & 2.397895 & & &\\ # \hline # \end{array} # $$ # それぞれの項は,例えば, # # $$ # f_2\lfloor x_1,x_2,x_3 \rfloor =\frac{0.095310-0.105360}{11.0-9.0}=-0.0050250 # $$ # で求められる.ニュートンの差分商の一次多項式の値はx=9.2で # # $$ # F(x)=F_0(8.0)+(x-x_0)f_1\lfloor x_0,x_1\rfloor =2.079442+0.117783(9.2-8.0)=2.220782 # $$ # となる. # # ### 差分商補間の表中の開いている箇所[ XXX ]を埋めよ. # ### ニュートンの二次多項式 # # $$ # F (x )=F (x _{0})+(x -x _{0})f _{1}\lfloor x_0,x_1\rfloor+(x -x _{0})(x -x _{1}) # f _{2}\lfloor x_0,x_1,x_2\rfloor # $$ # の値を求めよ. # ### ニュートンの三次多項式の値を求めよ. # ただし,ここでは有効数字7桁程度はとるように.(E.クライツィグ著「数値解析」(培風館,2003), p.31, 例4改) # In[49]: np.log(9.2) # In[40]: x_3 = 11 x_1 = 9 f1_23 = 0.095310 f1_12 = 0.105360 f2_123 = (f1_32-f1_21)/(x_3-x_1) print(f2_123) f1_01 = 0.117783 x_0 = 8 x_2 = 10 f2_012 = (f1_12-f1_01)/(x_2-x_0) print((0.105360-0.117783)/(10-8)) # In[41]: x = 9.2 F_0 = 2.079442 F_0 + (x-x_0)*(f1_01)+(x-x_0)*(x-x_1)*f2_012 # In[44]: f3_0123 = 0.0003955000 F_0 + (x-x_0)*(f1_01)+(x-x_0)*(x-x_1)*f2_012+(x-x_0)*(x-x_1)*(x-x_2)*f3_0123 # ### 補足 # # テキストに紹介したコードによって求められるNewton差分商補間の様子を以下に示しておく. # In[2]: # https://stackoverflow.com/questions/14823891/newton-s-interpolating-polynomial-python # by Khalil Al Hooti (stackoverflow) def _poly_newton_coefficient(x,y): """ x: list or np array contanining x data points y: list or np array contanining y data points """ m = len(x) x = np.copy(x) a = np.copy(y) for k in range(1,m): a[k:m] = (a[k:m] - a[k-1])/(x[k:m] - x[k-1]) return a def newton_polynomial(x_data, y_data, x): """ x_data: data points at x y_data: data points at y x: evaluation point(s) """ a = _poly_newton_coefficient(x_data, y_data) n = len(x_data) - 1 # Degree of polynomial p = a[n] for k in range(1,n+1): p = a[n-k] + (x -x_data[n-k])*p return p # In[5]: import numpy as np from scipy import interpolate import matplotlib.pyplot as plt x = [-1, 0, 1] y = [4., -2., -1.2] for i in range(0,3): plt.plot(x[i],y[i],'o',color='r') print(_poly_newton_coefficient(x,y)) xx = np.linspace(-1,4, 100) yy = newton_polynomial(x, y, xx) plt.plot(xx, yy, color = 'b') plt.grid() plt.show() # In[6]: x = [-1, 0, 1] y = [4., -2., -1.2] for i in range(0,3): plt.plot(x[i],y[i],'o',color='r') print(_poly_newton_coefficient(x,y)) xx = np.linspace(-1,4, 100) yy = newton_polynomial(x, y, xx) plt.plot(xx, yy, color = 'b') plt.grid() plt.show() # ## 数値積分(I) # 次の関数 # # $$ # f(x) = \frac{4}{1+x^2} # $$ # を$x = 0..1$で数値積分する. # 1. $N$を2,4,8,…256ととり,$N$個の等間隔な区間にわけて中点法で求めよ.(15) # 1. 小数点以下10桁まで求めた値3.141592654との差をdXとする.dXと分割数Nとを両対数プロット(loglogplot)して比較せよ(10) # (2008年度期末試験) # In[14]: import numpy as np def func(x): return 4.0/(1.0+x**2) def mid(N): x0, xn = 0.0, 1.0 h = (xn-x0)/N S = 0.0 for i in range(0, N): xi = x0 + (i+0.5)*h dS = h * func(xi) S = S + dS return S def trape(N): x0, xn = 0.0, 1.0 h = (xn-x0)/N S = func(x0)/2.0 for i in range(1, N): xi = x0 + i*h dS = func(xi) S = S + dS S = S + func(xn)/2.0 return h*S x, y = [], [] for i in range(1,8): x.append(2**i) y.append(abs(mid(2**i)-np.pi)) x2, y2 = [], [] for i in range(1,8): x2.append(2**i) y2.append(abs(trape(2**i)-np.pi)) # In[15]: import matplotlib.pyplot as plt plt.plot(x, y, color = 'r') plt.plot(x2, y2, color = 'b') plt.yscale('log') plt.grid() plt.show() # In[16]: plt.plot(x, y, color = 'r') plt.plot(x2, y2, color = 'b') plt.yscale('log') plt.xscale('log') plt.grid() plt.show() # In[ ]: