Python求解偏微分方程

閱讀時間約 3 分鐘

1 引言

微分方程是描述一個系統的狀態隨時間和空間演化的最基本的數學工具之一,其在物理、經濟、工程、社會等各方面都有及其重要的應用。 然而,只有很少的微分方程式可以解析求解,尤其對於偏微分方程,能解析求解的種類更是寥寥可數。 更多的微分方程式可以用數值法來求解,只要精確度夠高,就可以滿足科學和工程上的需求。


數值解微分方程的基本想法是先把時間和空間離散化,再將微分化為差分,建立遞推關係,再利用電腦強大的重複運算能力,快速得到任意格點處的值。 Python的Numpy、Scipy工具包可以很好地實現此功能,Matplotlib工具包則可以將求解結果畫為非常直觀的圖形。


接下來,我們先以常微分方程的數值解為例,引入差分的思想,再推廣到偏微分方程。

2 常微分方程的差分求解

一般地,一階常微分方程式可以寫成

raw-image

上述微分方程可以化為差分方程

raw-image


從而我們得到遞推關係

raw-image

有了遞推關係和初始條件以後,就可以利用Python的強大運算功能來求解了


2.1 RC迴路放電問題

對於一個 RC 迴路,我們有

raw-image

其中,I R Q C 分別為電流,電阻,電量和電容,利用 I=dQ/dt並定義

τ=RC,我們得到一個含初始條件的一階常微分方程

raw-image


這個方程式當然可以解析求解,得到

raw-image

另一方面依照差分法,可以得到遞推關係

raw-image


下面我們用Python進行數值求解,並和解析結果做比較。

import numpy as np
import matplotlib.pyplot as plt
rc = 2.0 #設置常數
dt = 0.5 #設置步長
n = 1000 #設置分割段數
t = 0.0 #設置初始時間
q = 1.0 #設置初始電量

qt=[] #用來存放差分得到的q值
qt0=[] #用來存放解析得到的q值
time = [] #用來存放時間值

for i in range(n):
    t = t + dt
    q1 = q - q*dt/rc #qn+1的近似值
    q = q - 0.5*(q1*dt/rc + q*dt/rc) #差分遞推關係
    q0 = np.exp(-t/rc) #解析關係
    qt.append(q) #差分得到的q值列表
    qt0.append(q0) #解析得到的q值列表
    time.append(t) #時間列表

plt.plot(time,qt,'o',label='Euler-Modify') #差分得到的電量隨時間的變化
plt.plot(time,qt0,'r-',label='Analytical') #解析得到的電量隨時間的變化
plt.xlabel('time')
plt.ylabel('charge')
plt.xlim(0,20)
plt.ylim(-0.2,1.0)
plt.legend(loc='upper right')
plt.show()
raw-image

在COLAB跑了一下

差分法得到的結果與解析法得到結果的比較,發現兩者符合得很好

這說明對於這個問題,改進的歐拉法已經可以給出足夠精確的結果。

要注意的是,這個微分方程本身比較簡單,可以解析求解,

而對於複雜得多的微分方程,沒辦法解析求解,

但是上述數值求解差分法仍然是適用的。


28會員
48Content count
人工智能工作經驗跟研究
留言0
查看全部
發表第一個留言支持創作者!
根據泰勒定理,f(x)可以寫成右邊一長串的導數的組合 為了更好理解這個東西我們可以用python實作 首先定義f(x)和定義factorial怎麼算 然後寫泰勒定理 f(x) = f(a) + f'(a)(x-a) ....後面還有一串 注意公式往後面看其實是有規律的 例如從
一個罐頭其中高度為h,底部半徑為r,且 h/r=2 已知 容量V = 1(公升) 找到一組: h(高度) , r(底部半徑) 使得表面積最小 目的: 因表面積最小因此可以讓製造成本降低幫助企業省錢 算式如上 答案我也使用python驗證一下求出數值解 接下來換個角度跟工具
根據泰勒定理,f(x)可以寫成右邊一長串的導數的組合 為了更好理解這個東西我們可以用python實作 首先定義f(x)和定義factorial怎麼算 然後寫泰勒定理 f(x) = f(a) + f'(a)(x-a) ....後面還有一串 注意公式往後面看其實是有規律的 例如從
一個罐頭其中高度為h,底部半徑為r,且 h/r=2 已知 容量V = 1(公升) 找到一組: h(高度) , r(底部半徑) 使得表面積最小 目的: 因表面積最小因此可以讓製造成本降低幫助企業省錢 算式如上 答案我也使用python驗證一下求出數值解 接下來換個角度跟工具
你可能也想看
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
"求和"應該是我們最常用到的基本數學運算了,利用迴圈和切片的技巧,以下的程式碼能分別印出每個人的總分和各科的總分。
Thumbnail
實務工作上,我們很可能會遇到需要對每張工作表的某一固定位置儲存格求和的情況。比如說,E5儲存格存放每個月的業績總額,以下的程式碼可以求得一整年的總營業額。 以下的程式碼則是用更具Python風格、更精簡且更漂亮的列表推導式(List Comprehension)來輕鬆達成同樣的功能。
Thumbnail
我們利用工作表的move_range()方法,可以輕鬆地移動儲存格。其中,rows參數的值表示向下移幾列,cols參數的值表示向右移幾行;當rows參數的值是負數時,則表示向上移幾列;cols參數的值負數時,則表示向上移幾行, 也可以一次移動一整個區塊範圍的儲存格。 利用工作表的freeze_pan
Thumbnail
我們可以利用工作表的append()方法,在工作表的列尾添加資料列。 利用迴圈的技巧,我們可以批次賦予區塊內所有儲存格相同的值。 我們也可以在指定的列(行)之前插入指定數量的空白列(行),從指定的列(行)開始向下(右)刪除指定數量的列(行)。
Thumbnail
其餘讀取整列、整行和所有儲存格等的方法,詳見以下程式碼的註解說明。
Thumbnail
區塊儲存格 假設我們有一張工作表如下,而我們打算讀取C3:D6區塊儲存格的值。 以下的程式碼可以列印出C3:D6區塊儲存格的資料,注意openpyxl預設是採以列為主(row-major)拜訪儲存格。 如果需要以行為主(column-major)的方式印出區塊儲存格的值,可以改用以下的程式碼。 列印
Thumbnail
儲存格的存取和變數的存取一樣直覺與簡單,但是要注意儲存格的值和儲存格物件是兩個不同的東東;其中,儲存格的值是儲存格物件的一個屬性(value)。工作表ws中儲存格A4可以用ws['A4']這樣的方式表示,也可以用ws.cell(row = 4, column = 2)表示,或簡單地用ws.cell(
Thumbnail
學會了工作簿和工作表基本的操作後,讓我們來做一些練習。 1. 新建一個工作簿,並在其內新增12張工作表;將工作表的名稱分別定為1月、2月、3月……12月。 解答: 2. 續上題,批次將工作表的名稱更改為竹科1月、竹科2月、竹科3月……竹科12月。 解答:
Thumbnail
一、命名工作表 二、新增工作表 你可以使用create_sheet()方法來新增一張工作表,並命名新的工作表名稱。 三、複製工作表 你可以使用copy_worksheet()方法來複製一張工作表。 四、列印所有工作表名稱 五、刪除工作表 你可以使用remove()方法來刪除工作表"物件"。 注意:
Thumbnail
一、套件安裝 在使用Python操控Excel前,需要先安裝openpyxl模組。 二、建立工作簿 不需要先建立Excel檔案,就可以開始使用openpyxl;只要引用Workbook類別,就可以開始工作。 一個工作簿被建立起來的時候,至少會含有一張工作表。你可以用active屬性來使用這張工作表。
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
"求和"應該是我們最常用到的基本數學運算了,利用迴圈和切片的技巧,以下的程式碼能分別印出每個人的總分和各科的總分。
Thumbnail
實務工作上,我們很可能會遇到需要對每張工作表的某一固定位置儲存格求和的情況。比如說,E5儲存格存放每個月的業績總額,以下的程式碼可以求得一整年的總營業額。 以下的程式碼則是用更具Python風格、更精簡且更漂亮的列表推導式(List Comprehension)來輕鬆達成同樣的功能。
Thumbnail
我們利用工作表的move_range()方法,可以輕鬆地移動儲存格。其中,rows參數的值表示向下移幾列,cols參數的值表示向右移幾行;當rows參數的值是負數時,則表示向上移幾列;cols參數的值負數時,則表示向上移幾行, 也可以一次移動一整個區塊範圍的儲存格。 利用工作表的freeze_pan
Thumbnail
我們可以利用工作表的append()方法,在工作表的列尾添加資料列。 利用迴圈的技巧,我們可以批次賦予區塊內所有儲存格相同的值。 我們也可以在指定的列(行)之前插入指定數量的空白列(行),從指定的列(行)開始向下(右)刪除指定數量的列(行)。
Thumbnail
其餘讀取整列、整行和所有儲存格等的方法,詳見以下程式碼的註解說明。
Thumbnail
區塊儲存格 假設我們有一張工作表如下,而我們打算讀取C3:D6區塊儲存格的值。 以下的程式碼可以列印出C3:D6區塊儲存格的資料,注意openpyxl預設是採以列為主(row-major)拜訪儲存格。 如果需要以行為主(column-major)的方式印出區塊儲存格的值,可以改用以下的程式碼。 列印
Thumbnail
儲存格的存取和變數的存取一樣直覺與簡單,但是要注意儲存格的值和儲存格物件是兩個不同的東東;其中,儲存格的值是儲存格物件的一個屬性(value)。工作表ws中儲存格A4可以用ws['A4']這樣的方式表示,也可以用ws.cell(row = 4, column = 2)表示,或簡單地用ws.cell(
Thumbnail
學會了工作簿和工作表基本的操作後,讓我們來做一些練習。 1. 新建一個工作簿,並在其內新增12張工作表;將工作表的名稱分別定為1月、2月、3月……12月。 解答: 2. 續上題,批次將工作表的名稱更改為竹科1月、竹科2月、竹科3月……竹科12月。 解答:
Thumbnail
一、命名工作表 二、新增工作表 你可以使用create_sheet()方法來新增一張工作表,並命名新的工作表名稱。 三、複製工作表 你可以使用copy_worksheet()方法來複製一張工作表。 四、列印所有工作表名稱 五、刪除工作表 你可以使用remove()方法來刪除工作表"物件"。 注意:
Thumbnail
一、套件安裝 在使用Python操控Excel前,需要先安裝openpyxl模組。 二、建立工作簿 不需要先建立Excel檔案,就可以開始使用openpyxl;只要引用Workbook類別,就可以開始工作。 一個工作簿被建立起來的時候,至少會含有一張工作表。你可以用active屬性來使用這張工作表。