幫別人做設計圖的網(wǎng)站渠道推廣策略
🎯要點
🎯平流擴散簡單離散微分算子 | 🎯相場模擬:簡單旋節(jié)線分解、枝晶凝固的 | 🎯求解二維波動方程,離散化時間導數(shù)
🎯英偉達 A100 人工智能核性能評估模型 | 🎯熱漲落流體動力學求解及算法
📜有限差分法 | 本文 - 用例
📜Python和Julia河流湖泊沿海水域特征數(shù)值算法模型
📜Python和C++數(shù)學物理計算分形熱力學靜電學和波動方程
📜Python物理學有限差分微分求解器和動畫波形傳播
📜Python數(shù)值和符號算法計算及3D視圖物理數(shù)學波形方程
📜Python氮氧甲烷乙烷乙烯丙烯氣體和固體熱力學模型計算
📜Python射頻電磁腫瘤熱療數(shù)學模型和電磁爆炸性變化統(tǒng)計推理模型
🍇Python有限差分逼近余弦導數(shù)
函數(shù) f ( x ) f(x) f(x)在 x = a x=a x=a點的導數(shù) f ′ ( x ) f^{\prime}(x) f′(x)定義為:
f ′ ( a ) = lim ? x → a f ( x ) ? f ( a ) x ? a f^{\prime}(a)=\lim _{x \rightarrow a} \frac{f(x)-f(a)}{x-a} f′(a)=x→alim?x?af(x)?f(a)?
x = a x=a x=a 處的導數(shù)就是此時的斜率。在該斜率的有限差分近似中,我們可以使用點 x = a x=a x=a 附近的函數(shù)值來實現(xiàn)目標。不同的應用中使用了多種有限差分公式,下面介紹其中的三種,其中導數(shù)是使用兩點的值計算的。
前向差分是使用連接 ( x j , f ( x j ) ) \left(x_j, f\left(x_j\right)\right) (xj?,f(xj?)) 和 ( x j + 1 , f ( x j + 1 ) ) \left(x_{j+1}, f\left(x_{j+1}\right)\right) (xj+1?,f(xj+1?))?的線來估計 x j x_j xj? 處函數(shù)的斜率:
f ′ ( x j ) = f ( x j + 1 ) ? f ( x j ) x j + 1 ? x j f^{\prime}\left(x_j\right)=\frac{f\left(x_{j+1}\right)-f\left(x_j\right)}{x_{j+1}-x_j} f′(xj?)=xj+1??xj?f(xj+1?)?f(xj?)?
后向差分是使用連接 ( x j ? 1 , f ( x j ? 1 ) ) \left(x_{j-1}, f\left(x_{j-1}\right)\right) (xj?1?,f(xj?1?)) 和 ( x j , f ( x j ) ) \left(x_j, f\left(x_j\right)\right) (xj?,f(xj?)) 的線來估計 x j x_j xj? 處函數(shù)的斜率:
f ′ ( x j ) = f ( x j ) ? f ( x j ? 1 ) x j ? x j ? 1 f^{\prime}\left(x_j\right)=\frac{f\left(x_j\right)-f\left(x_{j-1}\right)}{x_j-x_{j-1}} f′(xj?)=xj??xj?1?f(xj?)?f(xj?1?)?
中間差分是使用連接 ( x j ? 1 , f ( x j ? 1 ) ) \left(x_{j-1}, f\left(x_{j-1}\right)\right) (xj?1?,f(xj?1?)) 和 ( x j + 1 , f ( x j + 1 ) ) \left(x_{j+1}, f\left(x_{j+1}\right)\right) (xj+1?,f(xj+1?)) 的線來估計 x j x_j xj? 處函數(shù)的斜率:
f ′ ( x j ) = f ( x j + 1 ) ? f ( x j ? 1 ) x j + 1 ? x j ? 1 f^{\prime}\left(x_j\right)=\frac{f\left(x_{j+1}\right)-f\left(x_{j-1}\right)}{x_{j+1}-x_{j-1}} f′(xj?)=xj+1??xj?1?f(xj+1?)?f(xj?1?)?
為了導出 f f f 導數(shù)的近似值 ,我們回到泰勒級數(shù)。對于任意函數(shù) f ( x ) f(x) f(x),對于任意函數(shù) f ( x ) f(x) f(x) , f f f 圍繞 a = x j a=x_j a=xj? 的泰勒級數(shù)是 f ( x ) = f ( x j ) ( x ? x j ) 0 0 ! + f ′ ( x j ) ( x ? x j ) 1 1 ! + f ′ ′ ( x j ) ( x ? x j ) 2 2 ! + f ′ ′ ′ ( x j ) ( x ? x j ) 3 3 ! + ? f(x)=\frac{f\left(x_j\right)\left(x-x_j\right)^0}{0!}+\frac{f^{\prime}\left(x_j\right)\left(x-x_j\right)^1}{1!}+\frac{f^{\prime \prime}\left(x_j\right)\left(x-x_j\right)^2}{2!}+\frac{f^{\prime \prime \prime}\left(x_j\right)\left(x-x_j\right)^3}{3!}+\cdots f(x)=0!f(xj?)(x?xj?)0?+1!f′(xj?)(x?xj?)1?+2!f′′(xj?)(x?xj?)2?+3!f′′′(xj?)(x?xj?)3?+?
如果 x x x 位于間距為 h h h 的點網(wǎng)格上,我們可以計算 x = x j + 1 x=x_{j+1} x=xj+1? 處的泰勒級數(shù)以獲得
f ( x j + 1 ) = f ( x j ) ( x j + 1 ? x j ) 0 0 ! + f ′ ( x j ) ( x j + 1 ? x j ) 1 1 ! + f ′ ′ ( x j ) ( x j + 1 ? x j ) 2 2 ! + f ′ ′ ′ ( x j ) ( x j + 1 ? x j ) 3 3 ! + ? f\left(x_{j+1}\right)=\frac{f\left(x_j\right)\left(x_{j+1}-x_j\right)^0}{0!}+\frac{f^{\prime}\left(x_j\right)\left(x_{j+1}-x_j\right)^1}{1!}+\frac{f^{\prime \prime}\left(x_j\right)\left(x_{j+1}-x_j\right)^2}{2!}+\frac{f^{\prime \prime \prime}\left(x_j\right)\left(x_{j+1}-x_j\right)^3}{3!}+\cdots f(xj+1?)=0!f(xj?)(xj+1??xj?)0?+1!f′(xj?)(xj+1??xj?)1?+2!f′′(xj?)(xj+1??xj?)2?+3!f′′′(xj?)(xj+1??xj?)3?+?
代入 h = x j + 1 ? x j h=x_{j+1}-x_j h=xj+1??xj? 并求解 f ′ ( x j ) f^{\prime}\left(x_j\right) f′(xj?) 得出方程
f ′ ( x j ) = f ( x j + 1 ) ? f ( x j ) h + ( ? f ′ ′ ( x j ) h 2 ! ? f ′ ′ ′ ( x j ) h 2 3 ! ? ? ) f^{\prime}\left(x_j\right)=\frac{f\left(x_{j+1}\right)-f\left(x_j\right)}{h}+\left(-\frac{f^{\prime \prime}\left(x_j\right) h}{2!}-\frac{f^{\prime \prime \prime}\left(x_j\right) h^2}{3!}-\cdots\right) f′(xj?)=hf(xj+1?)?f(xj?)?+(?2!f′′(xj?)h??3!f′′′(xj?)h2???)
括號中的項 ? f ′ ′ ( x j ) h 2 ! ? f ′ ′ ′ ( x j ) h 2 3 ! ? ? -\frac{f^{\prime \prime}\left(x_j\right) h}{2!}-\frac{f^{\prime \prime \prime}\left( x_j\right) h^2}{3!}-\cdots ?2!f′′(xj?)h??3!f′′′(xj?)h2??? 被稱為 h h h 的高階項。高階項可以重寫為
? f ′ ′ ( x j ) h 2 ! ? f ′ ′ ′ ( x j ) h 2 3 ! ? ? = h ( α + ? ( h ) ) -\frac{f^{\prime \prime}\left(x_j\right) h}{2!}-\frac{f^{\prime \prime \prime}\left(x_j\right) h^2}{3!}-\cdots=h(\alpha+\epsilon(h)) ?2!f′′(xj?)h??3!f′′′(xj?)h2???=h(α+?(h))
其中 α \alpha α 是某個常數(shù), ? ( h ) \epsilon(h) ?(h) 是 h h h 的函數(shù),當 h h h 變?yōu)?0 時,該函數(shù)也變?yōu)?0。你可以用一些代數(shù)來驗證這是真的。我們使用縮寫“ O ( h ) O(h) O(h)”來表示 h ( α + ? ( h ) ) h(\alpha+\epsilon(h)) h(α+?(h)),并且一般來說,我們使用縮寫“ O ( h p ) O\left(h^p\right) O(hp)”來表示 h p ( α + ? ( h ) ) h^p(\alpha+\epsilon(h)) hp(α+?(h))
將 O ( h ) O(h) O(h) 代入前面的方程得出
f ′ ( x j ) = f ( x j + 1 ) ? f ( x j ) h + O ( h ) f^{\prime}\left(x_j\right)=\frac{f\left(x_{j+1}\right)-f\left(x_j\right)}{h}+O(h) f′(xj?)=hf(xj+1?)?f(xj?)?+O(h)
這給出了近似導數(shù)的前向差分公式為
f ′ ( x j ) ≈ f ( x j + 1 ) ? f ( x j ) h f^{\prime}\left(x_j\right) \approx \frac{f\left(x_{j+1}\right)-f\left(x_j\right)}{h} f′(xj?)≈hf(xj+1?)?f(xj?)?
我們說這個公式是 O ( h ) O(h) O(h)。
💦示例:余弦函數(shù) f ( x ) = cos ? ( x ) f(x)=\cos (x) f(x)=cos(x)。我們知道 cos ? ( x ) \cos(x) cos(x)的導數(shù)是 ? sin ? ( x ) -\sin(x) ?sin(x)?。盡管在實踐中我們可能不知道我們求導的基礎函數(shù),但我們使用簡單的例子來說明上述數(shù)值微分方法及其準確性。以下代碼以數(shù)值方式計算導數(shù)。
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('seaborn-poster')
%matplotlib inline
h = 0.1
x = np.arange(0, 2*np.pi, h)
y = np.cos(x) forward_diff = np.diff(y)/h
x_diff = x[:-1:]
exact_solution = -np.sin(x_diff) plt.figure(figsize = (12, 8))
plt.plot(x_diff, forward_diff, '--', \label = 'Finite difference approximation')
plt.plot(x_diff, exact_solution, \label = 'Exact solution')
plt.legend()
plt.show()max_error = max(abs(exact_solution - forward_diff))
print(max_error)
0.049984407218554114
如上圖所示,兩條曲線之間存在微小的偏移,這是由于數(shù)值導數(shù)求值時的數(shù)值誤差造成的。兩個數(shù)值結果之間的最大誤差約為 0.05,并且預計會隨著步長的增大而減小。
💦示例:以下代碼使用遞減步長 h h h 的前向差分公式計算 f ( x ) = cos ? ( x ) f(x)=\cos (x) f(x)=cos(x) 的數(shù)值導數(shù)。然后,它繪制近似導數(shù)和真實導數(shù)之間的最大誤差與 h h h 的關系,如生成的圖形所示。
h = 1
iterations = 20
step_size = []
max_error = [] for i in range(iterations):h /= 2 step_size.append(h) x = np.arange(0, 2 * np.pi, h) y = np.cos(x) forward_diff = np.diff(y)/h x_diff = x[:-1] exact_solution = -np.sin(x_diff) max_error.append(\max(abs(exact_solution - forward_diff)))
plt.figure(figsize = (12, 8))
plt.loglog(step_size, max_error, 'v')
plt.show()
雙對數(shù)空間中直線的斜率為 1 ;因此,誤差與 h 1 h^1 h1成正比,這意味著,正如預期的那樣,前向差分公式為 O ( h ) O(h) O(h)。