對於手工計算來說,積分計算是非常困難的,對於一些簡單的函數,我們可以直接通過已知的積分公式來求解,但在更多的情況下,原函數並沒有簡單的表達式,因此確定積分的反函數變得非常困難。 另外,相對於微分運算來說,積分運算則具有更多的多樣性,包括不同的積分方法(如換元積分法、分部積分法等)和積分技巧,需要根據 ...
對於手工計算來說,積分計算是非常困難的,對於一些簡單的函數,我們可以直接通過已知的積分公式來求解,但在更多的情況下,原函數並沒有簡單的表達式,因此確定積分的反函數變得非常困難。
另外,相對於微分運算來說,積分運算則具有更多的多樣性,包括不同的積分方法(如換元積分法、分部積分法等)和積分技巧,需要根據具體的函數形式選擇合適的方法,這增加了積分運算的複雜性。
而微分運算有一條基本的規則,即導數運算具有線性性質,可以通過求導法則來簡化計算。
Scipy
庫的積分子模塊為我們提供了便捷的積分和微分方程計算介面。
利用Scipy
,進行數學或科學研究時,可以把更多的時間花在原理和推導上,計算過程交由Scipy
去處理。
1. 主要功能
Scipy
的積分模塊主要用於進行數學方程的求解和過程式控制制。
該模塊提供了一組函數,可以用於求解一元和多元函數的導數、積分、二階導數和偏導數等。
此外,該模塊還提供了一些用於過程式控制制和優化的函數。
此模塊的函數主要分為以下幾類:
- 針對函數對象的積分
- 針對固定樣本的積分
- 常微分方程
總之,scipy.integrate
模塊提供了豐富的函數和演算法,用於解決各種數學問題和過程式控制制問題。
下麵通過一些示例來瞭解其使用方法。
2. 積分運算
2.1. 一重積分
比如計算曲線 \(y = e^{-x}\)在 \(-0.75 \leqslant x \leqslant 0.5\)範圍內的面積。
也就是計算積分:\(\int_{-0.75}^{0.5}e^{-x}dx\)
from scipy.integrate import quad
y = lambda x: np.exp(-x)
integral, integral_err = quad(y, -0.75, 0.5)
print("面積為:{}".format(integral))
# 運行結果
面積為:1.5104693569000414
2.2. 二重積分
所謂二重積分,就是積分變數有兩個,依次在兩個變數上積分得出最終的結果。
比如,對於函數:\(z = x^2 + y^2\),相當於如下的三維曲面。
計算上面的曲面在 \(-2 \leqslant x \leqslant 2\)且 \(-1 \leqslant y \leqslant 1\)情況下,與XY平面所包圍的體積。
即:\(\int_{-2}^2\int_{-1}^1(x^2+y^2)dydx\)
from scipy.integrate import dblquad
integrand = lambda y, x: x**2 + y**2
integral, integral_error = dblquad(integrand, -2, 2, -1, 1)
print("體積為:{}".format(integral))
# 運行結果
體積為:13.333333333333334
這個示例中的曲面在X平面和Y平面上是對稱的,計算二重積分時,先積分x
,還是先積分y
,結果是一樣的。
也就是:\(\int_{-2}^2\int_{-1}^1(x^2+y^2)dydx = \int_{-2}^2\int_{-1}^1(x^2+y^2)dxdy\)
其他的曲面不一定是對稱的,所以二重積分時一定要註意積分的順序。
3. 常微分方程求解
常微分方程是一類以未知函數和其導數為主要研究對象的數學方程,適合描述不斷變化的場景。
3.1. 一元常微分方程
比如計算物體速度的時候,如果加速度恆定,根據牛頓運動定律,很容易就能計算出速度和時間的關係。
但是若加速度也會不斷變化的話,如何確定速度和時間的關係呢?
比如假設加速度隨速度和時間變化的關係是: \(a = v+3t\)
因為加速度也可以表示為:\(a = \frac{dv}{dt}\),也就是速度對時間的微分,即:\(a = v'\)。
這樣,就得到:\(a = \frac{dv}{dt} = v' = v+3t\),其中,\(v' = v+3t\)就是一個常微分方程。
假設時間t為0
時,速度v也為0
,則得到:\(v'-v-3t=0, v(0)=0\)
下麵利用Scipy
來求解這個一元常微分方程。
from scipy.integrate import odeint
# v是速度,t是時間
def dvdt(v, t):
return v + 3*t
v0 = 0
t = np.linspace(0, 1, 100)
# 結果res是 N行1列的二維數組(因為是一元方程)
res = odeint(dvdt, v0, t)
# 轉置之後第一行就是各個時間點的速度
res_v = res.T[0]
# 繪製速度和時間的關係
plt.plot(t, res_v)
plt.show()
圖中曲線的斜率就是加速度,可以看出加速度是隨時間不斷變大的。
3.2. 二元常微分方程組
對於二元常微分方程組,同樣也可以用 scipy
來求解。
比如如下方程組:
\(\begin{align*}
& y_1' = y_1 + y_2^2 - 5x \quad & y_1(0)=0\\
& y_2' = 2y_1 + y_2^3 + sin(x) \quad & y_2(0)=0
\end{align*}\)
求解方法:
from scipy.integrate import odeint
# 創建方程組
def dSdx(S, x):
y1, y2 = S
return [
y1 + y2**2 - 5 * x,
2 * y1 + y2**3 + np.sin(x),
]
# 方程組初始值
y1_0 = 0
y2_0 = 0
S_0 = (y1_0, y2_0)
x = np.linspace(0, 1, 100)
sol = odeint(dSdx, S_0, x)
y1_sol = sol.T[0]
y2_sol = sol.T[1]
# 分別繪製y1,y2和x的關係
plt.plot(x, y1_sol, label="y1")
plt.plot(x, y2_sol, label="y2")
plt.legend()
plt.show()
4. 總結
積分和常微分方程算是應用非常廣,但手工計算非常麻煩的兩種數學工具,
在學校學習高等數學的時候應該沒少吃過這兩種計算的苦。
有了Scipy
的幫助,則可以擺脫這類複雜計算帶來的痛苦,讓我們可以專註於創建解決問題的方程。