1. 程式人生 > >Python之高等數學(導數的性質,切線法,二分法)

Python之高等數學(導數的性質,切線法,二分法)

函式的單調性
定理:設函式 y = f (x) 在 [a, b] 上連續,在 (a, b) 內可導 .
如果在 (a, b) 內 f ' (x) ≥ 0, 且等號僅在有限多個點處成立,那麼函式 y=f(x)在 [a,b]上單調增加;

 如果在 (a, b) 內 f ' (x) ≤ 0, 且等號僅在有限多個點處成立,那麼函式 y=f(x)在 [a,b]上單調減少;

# f(x) = 2*x**3 - 9*x**2 + 12*x - 3

def f1(x):
    return 2*x**3 - 9*x**2 + 12*x - 3   # 函式
def f1_1(x):
    return 6*x**2 -18*x + 12

n = np.linspace(-10,10,num = 100)
plt.plot(n,f1(n))
plt.plot(n,f1_1(n))

plt.axvline(0,color = 'gray',linestyle = '--',alpha=0.8)  
plt.axhline(0,color = 'gray',linestyle = '--',alpha=0.8)  
# 輔助線

# 結論:設函式y = f(x)在[a,b]上連續,在(a,b)內可導 → 若函式導數始終大於等於0,該函式單調增加;反之單調減少

曲線的凸凹性
定理:設函式 y = f (x) 在 [a, b] 上連續,在 (a, b) 內具有一階和二階導數,那麼
 如果在 (a, b) 內 f '' (x) > 0, 則函式 y=f(x)在 [a,b]上是凹的;
 如果在 (a, b) 內 f '' (x) < 0, 則函式 y=f(x)在 [a,b]上是凸的;

# 二階導數

def f1_2(x):
    return 12*x - 18

n = np.linspace(-10,10,num = 100)
plt.plot(n,f1(n))
plt.plot(n,f1_1(n))
plt.scatter([1,2],[0,0],color = 'green')
plt.plot(n,f1_2(n))
plt.scatter([1.5],[0],color = 'red')

plt.xlim([-1,3])
plt.ylim([-20,20])
plt.axvline(0,color = 'gray',linestyle = '--',alpha=0.8)  
plt.axhline(0,color = 'gray',linestyle = '--',alpha=0.8)  
# 輔助線

# 結論:設函式y = f(x)在[a,b]上連續,在(a,b)內具有一階和二階導數 → 若函式二階導數始終大於等於0,該函式在[a,b]上是凹函式;反之則是凸函式

二分法
設函式 f(x) 在區間 [a,b]上連續, f(a)*f(b)<0,且方程 f(x)=0在 (a,b)內僅有一個實根 ξ,於是 [a,b]即是這個根的一個
隔離區間。
◼ 取 [a, b] 的中點 ξ1 = a + b2,計算 f(ξ1).
 如果 f(ξ1) = 0, 那麼 ξ = ξ1,計算結束;
 如果 f(ξ1) 與 f(a) 同號,那麼取 a1 = ξ1, b1 = b, 由 f(a1)* f (b1) < 0, 即知 a1 < ξ < b1, 且 b1 - a1 = 12(b - a);
 如果 f(ξ1) 與 f(b) 同號,那麼取 a1 = a, b1 = ξ1, 同理 a1 < ξ < b1, 且 b1 - a1 = 12(b - a);
◼ 總之,當 ξ ≠ ξ1 時,可求得 a1 < ξ < b1,且 b1 - a1 = 12(b - a)
 

# 二分法求解
# 對於函式f(x) = x**3 + 1.1*x**2 + 0.9*x -1.4
# 單調遞增

def f2(x):
    return x**3 + 1.1*x**2 + 0.9*x -1.4
def f2_1(x):
    return 3*x**2 + 2.2*x + 0.9

n = np.linspace(-10,10,num = 100)
plt.plot(n,f2(n))
plt.plot(n,f2_1(n))
plt.axvline(0,color = 'gray',linestyle = '--',alpha=0.8)  
plt.axhline(0,color = 'gray',linestyle = '--',alpha=0.8)  
# 輔助線

print('f(0)和f(1)的值分別為%.2f,%.2f' % (f2(0),f2(1)))
# f(0)=-1.4<0,f(1)=1.6>0,因此f(x)=0在[0,1]內有唯一實根

# 二分法求解

lst = [0,1]
n = 0
while n < 30:
    z = (lst[0]+lst[1])/2
    if f2(z)*f2(0) > 0:   # 即與f(0)同號
        lst[0] = z
    else:
        lst[1] = z    
    print('第%i次迭代的隔離區間為' % (n+1),lst)
    n += 1
第30次迭代的隔離區間為 [0.6706573106348515, 0.670657311566174]

切線法
設函式 f(x) 在區間 [a,b]上具有二階導數連續, f(a)*f(b)<0,且 f’(x)及 f’’(x)在 [a,b]上保持定號 .這樣方程 f(x)=0在
(a,b)內僅有一個實根 ξ,於是 [a,b]即是這個根的一個隔離區間。此時圖形僅以下幾種情況:
考慮用曲線弧的端點的切線來代替曲線弧,從而求出方程實根的近似值。這種方法叫做切線法
以 f(a)<0,f(b)>0,f’(x)>0,f’’(x)>0討論令 x0 = b, 在端點 (x0, f (x0)) 處做切線,切線方程為 y - f (x0) = f ' (x0) (x - x0),
得到與 x軸交點 (x1, 0) = x0 - f (x0)f ' (x0), 0 , 它比 x0 更接近方程的根 ξ;在點 (x1, f (x1)) 處做切線,可得到根的近似值 x2;
 如此繼續,一般地,在點 (xn, f (xn)) 處作切線,得到根的近似值 xn+1 = xn f (xn)f ' (xn)
 

# 切線法求解
# f ''(x) = 6 x + 2 經判斷在區間[0, 1] f '(x)> 0, f ''(x)> 0, 因此f(x) = 0 至多一個實根。

def f2_2(x):
    return 6*x + 2.2

xmin = -0.2
xmax = 1.2
n = np.linspace(xmin,xmax,num = 100)
plt.plot(n,f2(n))
plt.xlim([xmin,xmax])
plt.ylim([f2(xmin),f2(xmax)])
plt.axvline(0,color = 'gray',linestyle = '--',alpha=0.8)  
plt.axvline(1,color = 'gray',linestyle = '--',alpha=0.8)  
plt.axhline(0,color = 'gray',linestyle = '--',alpha=0.8)  
# 輔助線

xn = 1
lst_k = []
for i in range(5):
    def f2_qx(xi):
        # 切線函式
        k = f2_1(xn)
        b = f2(xn) - k*xn
        return k*xi + b
    plt.plot(n,f2_qx(n))
    xn = xn - f2(xn)/f2_1(xn)
    print('第%i次迭代的近似值為'%i, xn)