• 沒有找到結果。

第二十九章

N/A
N/A
Protected

Academic year: 2022

Share "第二十九章"

Copied!
21
0
0

加載中.... (立即查看全文)

全文

(1)

第二十九章

常微分方程式

本 章 重 點

本 章 介 紹 MATLAB 用 於 求 解 常 微 分 方 程 式

(Ordinary Differential Equations,簡稱 ODE)的指

令,這些指令可對一般的 ODE 或 Stiff 的 ODE 進

行數值積分求解。

(2)

29-1 ODE 指令簡介

MATLAB 用於求解常微分方程式的指令可以列表如下:

整理:

指令 方法 說明

ode45 Explicit Runge-Kutta(4, 5)pair of Dormand-Prince Nonstiff Solver

ode23

Explicit Runge-Kutta (2, 3)pair of Bogacki and Shampine

Nonstiff Solver

ode113 Variable order Adams-Bashforth-Moulton PECE solver

Nonstiff Solver ode15s Numerical differentiation formulas(NDFS) Stiff Solver ode23s Modified Rosenbrock formula of order 2 Stiff Solver ode23t Trapezoidal rule with a“free”interpolant Stiff Solver

ode23tb

Implicit Runge-Kutta formula with a backward

differentiation formula of order two Stiff Solver

提 示 :

8 除了 ODE 指令外,您也可使用 Simulink 來求解常微分方程式。

上表列出的指令項目繁多,但最主要可分兩大類,即適用於 Nonstiff 系 統及 Stiff 系統的指令。一般的常微分方程式都是 Nonstiff 系統,所以 可以直接選用 ode45、ode23 或 ode113 來求解。Stiff 系統的特性是它 的速率(即微分值)差異相常大,因此若使用一般的 ode45、ode23 或

(3)

ode113 來求解,可能會使得積分的步長(Step Sizes)變得很小(以降 低積分誤差至可容忍範圍以內),導致計算時間過長。因此,欲解決 此類 Stiff 系統 問題, 只要選 用專門 對付 Stiff 系統 的指令 ,例 如 ode15s、ode23s、ode23t 及 ode 23tb,即可迎刃而解。

29-2 ODE 指令基本用法

在使用 ODE 指令時,我們必須先將要求解的 ODE 表示成一個函式,

此函式的輸入為 t(時間)及 y(狀態變數),輸出則為 dy(狀態變 數的微分值)。若此 ODE 函式(或又稱 ODE 檔案)的檔名為 odefile.m,

則我們呼叫 ODE 指令的格式如下:

[t, y] = solver ('odefile', [t0, t1], y0);

其中 [t0, t1] 是積分的時間區間,y0 代表起始條件(Initial Conditions), solver 是前表所列的 ODE 指令,t 是積分時間向量,y 則是對應的狀態 變數。

以 van der Pol 微分方程為例,其方程式為:

0 ' ) 1 (

'' − − y

2

y + y = y µ

首先我們必須將它化成標準格式,令

y

1

= y

,

y

2

= y '

,則上述微分方程

式可以重寫為:

 

=

=

1 2 2 1 2

2 1

) 1 ( '

'

y y y y

y y

µ

此種標準格式可用數學式表示成:

(4)

) , ( ' F y t y r r r =

其中

y r

為一向量,代表狀態變數(State Variables)。使用此標準格式 後,並假設

µ

=1,我們的 ODE 檔案(vdp.m)可顯示如下:

>> type vdp1.m

function dy = vdp1(t, y) mu = 1;

dy = [y(2); mu*(1-y(1)^2)*y(2)-y(1)];

一旦有了 ODE 檔案,我們即可選用 ODE 指令來朮解。在

µ

=1 時,

van der Pol 方程式並非 Stiff 系統,因此,我們可選用 ode45 來求解,

最簡單的作法如下:

>> ode45('vdp1', [0 25], [3 3]');

0 5 10 15 20 25

-3 -2 -1 0 1 2 3 4

(5)

其中 [0, 25] 代表積分的時間區間,[3 3] 則代表起始條件(必須以行向 量來表示)。程式執行結束後,MATLAB 只會畫出狀態變數對時間的 圖形,如上圖。若要取得積分所得的狀態變數及對應的時間,可加上 輸出變數,例如:

>> [t, y] = ode45('vdp1', [0 25], [3 3]');

程式執行結束後,我們可以畫出這兩個狀態變數隨時間而變化的情 況,如下:

>> plot(t, y(:,1), t, y(:,2), ':')

>> xlabel('Time t'); ylabel('Solution y(t) and y''(t)');

>> legend('y(t)', 'y''(t)');

0 5 10 15 20 25

-3 -2 -1 0 1 2 3 4

Tim e t

Solution y(t) and y'(t)

y(t) y'(t)

我們也可以畫出

y (t )

y ' t ( )

在 相位平面(Phase Plane )的運動情況:

>> plot(y(:,1), y(:,2), '-o');

>> xlabel('y(t)'); ylabel('y''(t)');

(6)

-3 -2 -1 0 1 2 3 4 -3

-2 -1 0 1 2 3

y(t)

y'(t)

在上例中,當

µ

值越來越大時,van der Pol 方程式就漸漸變成一個 Stiff 的系統,此時若要解此方程式,就必須改用專門對付 Stiff 系統的指 令。

首先,我們將

µ

值改成 1000, ODE 檔案要改寫如下(vdp2.m):

>> type vdp2.m

function dy = vdp2(t, y) mu = 1000;

dy = [y(2); mu*(1-y(1)^2)*y(2)-y(1)];

此時即可選用專門對付 Stiff 系統的 ODE 指令,例如 ode15s,來求解 此系統並作圖顯示,如下:

>> [t, y]= ode15s('vdp2', [0 3000], [2 1]');

>> subplot(2,1,1); plot(t, y(:,1), '-o');

>> xlabel('Time t'); ylabel('y(t)');

>> subplot(2,1,2); plot(t, y(:,2), '-o');

>> xlabel('Time t'); ylabel('y''(t)'); % 注意單引號「'」的重覆使用

(7)

0 500 1000 1500 2000 2500 3000 -4

-2 0 2 4

Tim e t

y(t)

0 500 1000 1500 2000 2500 3000

-2000 -1000 0 1000 2000

由上圖可知,

y ' ( t )

的變化相當劇烈(超過

± 1000

),這就是 Stiff 系 統的特色。在相位平面上的圖形為:

>> subplot(1,1,1);

>> plot(y(:, 1), y(:, 2), '-o');

>> xlabel('y(t)'); ylabel('y''(t)');

y(t)

y'(t)

(8)

-3 -2 -1 0 1 2 3 -1500

-1000 -500 0 500 1000 1500

y(t)

y'(t)

若要產生在某些特定時間點的狀態變數值,則我們呼叫 ODE 指令的 格式可改成:

[t, y] = solver('odefile', [t0, t1, … , tn], y0);

其中 [t0, t1, … , tn] 即是特定時間點所形成的向量。

29-3 ODE 指令的選項

所有的 ODE 指令可以接受第四個輸入變數,代表積分過程用到的各 種選項(Options),此種 ODE 指令的格式為:

[t, y] = solver('odefile', [t0, tn], y0, options);

其中 options 是由 odeset 指令來控制的結構變數,此結構變數即包含了 積分過程用到的各種選項,odeset 的一般格式如下:

二維相位平面圖

(9)

options = odeset('name1', value1, 'name2', value2, … )

此時產生的結構變數 options,其欄位 name1 的值為 value1,欄位 name2 的值為 value2,依此類推。未被設定的欄位,其欄位值即為預設值。

我們也可以只改變一個現存的 options 結構變數中,某個欄位的值,其 格式如下:

new_options = odeset(options, 'name', value);

若要讀出某個欄位的值,可用 odeget,其格式如下:

value = odeget(otpions, 'name');

其中 name 為欄位名稱,value 即為對應的欄位值。

當使用 odeset 指令時,若無任何輸入變數,則 odeset 會顯示所有的欄 位名稱及欄位值,並以大括號代表預設值,例如:

>> odeset

AbsTol: [ positive scalar or vector {1e-6} ] BDF: [ on | {off} ]

Events: [ on | {off} ] InitialStep: [ positive scalar ] Jacobian: [ on | {off} ] JConstant: [ on | {off} ] JPattern: [ on | {off} ]

Mass: [ {none} | M | M(t) | M(t,y) ] MassSingular: [ yes | no | {maybe} ]

MaxOrder: [ 1 | 2 | 3 | 4 | {5} ] MaxStep: [ positive scalar ] NormControl: [ on | {off} ] OutputFcn: [ string ]

OutputSel: [ vector of integers ] Refine: [ positive integer ]

RelTol: [ positive scalar {1e-3} ]

(10)

Stats: [ on | {off} ] Vectorized: [ on | {off} ]

這些欄位名稱及相關說明,可見下表:

整理:由 odeset 產生的 ODE 選項

類別 欄位名稱 資料型態 預設值 說明

RelTol 正純量

10

3 相對誤差容忍度

誤差容忍度之

相關欄位 AbsTo1 正純量或向量

10

6 絕對誤差容忍度

OutPutFcn 字串 ‘odeplot’

輸出函式(若 ODE 指令 無輸出變數,則在數值積 分執行完畢後,MATLAB 會呼叫此輸出函式)

OutputSel 索引向量 全部

ODE 指令之輸出變數的 索引值,以決定那些輸出 變數之元素將被送到輸 出函式

Refine 正整數 1 或

4 (for ode45)

Refine = 2 可產生兩倍數 量的輸出點,Refine = 3 可產生三倍數量的輸出 點,依此類推。

積分輸出之相 關欄性

Stats on 或 off off

Stats = 'on' 產生計算過 程的各種統計資料。

Jacobian 矩陣

之相關欄位 Jconstant on 或 off off

如果 Jacobian 矩陣常 數,則 JConstant = 'on'

(11)

Jacobian on 或 off off

若 F(t, y, ’Jacobian') 傳

y F

,則 Jacobian = 'on'

Jpattern on 或 off off

若 F([ ], [ ], ’JPattern’) 傳

回 y F

,且 y F

是稀疏矩 陣,則 JPattem = 'on'

Vectorized on 或 off off

若 F(t, [y1, y2… ..]) 傳回 [F(t,y1), F(t,y2)… ..],則 Vectorized = 'on'

Max Step 正純量 ODE 指令之積分步長 的

上限 積分步(Step

Sizes)之相關

欄位 Initial Step 正純量 起始步長的建議值

Mass

none,M,

M(t),或 M(t, y) none

表明 ODE 指令案是否會 傳回質量矩陣

質量矩陣之相

關欄位 MassSingu lar

yes,no 或

maybe maybe

表明質量矩陣是否為 Singular

事件發生時間

之相關欄位 Events on 或 off off

若 ODE 檔案並傳回事件 函式及相關資訊,則 Events = 'on' Ode15s 之相

關欄位 MaxOrder 1, 2, 3, 4 或 5 5

積分公式用到的最高次 數

BDF on 或 off off

若使用 BDF(Backward Differentiation

Formula)則 BDF = 'on'

以下對幾個常用到的欄位來進行說明。

(12)

f 在積分誤差容忍度方面,每一次積分所產生的局部誤差 e(i),必須滿 足下列方程式:

≤ (i )

e

max(RelTol*

y (i )

, AbsTol(i))

其中 i 代表第 i 個狀態變數,因此,我們可降低 RelTol 及 AbsTol 來求 得更精確的積分結果。例如:

>> options = odeset('RelTol', 0.0001);

>> ode45('vdp1', [0 25], [3 3]', options);

0 5 10 15 20 25

-3 -2 -1 0 1 2 3 4

在上圖中,由於相對誤差值很小,因此我們得到較細密的點,讀者可 將之與本章第二節的第一個圖比較,即可驗證。

在積分輸出的相關處理方面,我們可以選用一個 OutputFcn,使得當 ODE 指令沒有輸出變數時,此輸出函式 OutputFcn 會被 MATLAB 呼 叫。OutputFcn 的預設值是“odeplot”,其功能為畫出所有的狀態變 數,其它可用的函式還有:

(13)

l odephas2:畫出 2-D 的相位平面(Phase Plane)

l odephas3:畫出 3-D 的相位平面

l odeprint:隨時在指令視窗印出計算結果

以 Lorenz 渾沌方程式(Lorenz Chaotic Equation)為例,其 ODE 檔案 之內容可顯示如下:

>> type lorenz1.m

function dy = lorenz1(t, y)

% LORENZ1: ODE file for Lorenz chaotic equation SIGMA = 10.;

RHO = 28.;

BETA = 8./3.;

A = [ -BETA 0 y(2) 0 -SIGMA SIGMA -y(2) RHO -1 ];

dy = A*y;

以 ode45 進行數值積分之結果可繪圖如下:

>> ode45('lorenz1', [0 10], [20 5 -5]');

0 2 4 6 8 10

-30 -20 -10 0 10 20 30 40 50

三個狀態變數

(14)

若要畫三度空間之相位圖形,可輸入如下:

>> options = odeset('OutputFcn', 'odephas3'); % 使用 odephas3

% 進行繪圖

>> ode45('lorenz1', [0 10], [20 5 -5]', options);

0 10

20 30

40 50

-20 -10 0 10 20 -30 -20 -10 0 10 20 30

提 示 :

8 若要觀看 Lorenz 渾沌方程式隨時間而變的動畫,可在 MATLAB 指令視窗下 直接輸入 lorenz 指令即可。非常值得一看!!

一般而言,假設我們的 OutputFcn 設成“myfunc”:

options = odeset('OutputFcn', 'myfunc')

則在積分開始時,ODE 指令會呼叫 myfunc(tspan, y0, 'init')以讓 myfunc 進行各種初始化動作;在每個積分步驟中,ODE 指令將會持續呼叫

三度空 間的相 位圖形

(15)

status=myfunc(t, y),若 status=1,則停止積分;在積分結束時,ODE 指 令會呼叫 myfunc([ ], [ ], 'done'),以讓 myfunc 進行收尾動作。

OutputSel 可指定要傳送到 OutputFcn 的狀態變數之元素。例如,若只 要傳送第一及第三個 Lorenz 渾沌方程式的狀態戀數至 odeplot,可輸 入如下:

>> options = odeset('OutputSel', [1,3]); % 只畫出第一和第三個

% 狀態變數

>> ode45('lorenz1', [0 10], [20 5 -5]', options);

0 2 4 6 8 10

-30 -20 -10 0 10 20 30 40 50

Refine 欄位可使輸出點由內差法而增加數量,以得到較平滑的輸出曲 線。在下例中,我們利用 Refine 欄位來使 ode23 的輸出點個數增為原 先的三倍:

>> subplot(2,1,1); ode23('vdp1', [0 25], [3 3]');

>> options = odeset('Refine', 3);

>> subplot(2,1,2); ode23('vdp1', [0 25], [3 3]', options);

第一個狀態變數

第三個狀態變數

(16)

0 5 10 15 20 25 -4

-2 0 2 4

0 5 10 15 20 25

-4 -2 0 2 4

當 Stat=on 時,ODE 指令會在執行完畢後顯示計算過程的各種統計數 字,例如:

>> [t, y] = ode45('vdp1', [0 25], [3 3]', odeset('Stat', 'on'));

71 successful steps 10 failed attempts

487 function evaluations 0 partial derivatives 0 LU decompositions

0 solutions of linear systems

相同的統計數字,也可由 ODE 指令的第三個輸出變數傳回,例如:

>> [t, y, s] = ode45('vdp1', [0 25], [3 3]');

>> s s = 71 10

正常 資料點

資料點 增為 3 偣

(17)

487 0 0 0

MaxStep 及 InitialStep 欄位可用來調整最大積分步長(Step Size)及起 始積分步長。但一般而言,您不必去調整這兩個數值,因為 ODE 指 令本身就具有非常先進的步長自動調適功能。特別值得注意的是:

l 若要產生更多輸出點,可直接調整 Refine 欄位值。調整 MaxStep 雖然可以達到同樣效果,但是計算時間可能會大幅增加。

l 如果積分結果不甚準確,請勿先調降 MaxStep,您應先調降 RelTol 及 AbsTol。調降 MaxStep 是最後的步驟。

其它欄位因較少用到,不再贅述,有興趣的讀者,可直接翻閱 MATLAB 有關 ODE 的手冊。

29-4 ODE 檔案的進階用法

在第二節中,我們已知道基本 ODE 檔案的寫法,如 vdp1.m、vdp2.m 及 lorenz1.m 等。在本節中,將更進一步介紹 ODE 檔案的進階用法,以 使 ODE 指令能夠迅速且準確地算出積分結果。

首先,我們可將 tspan(積分時間範圍)、y0(起始值)及 options(ODE 參數)置於 ODE 檔案中,這些變數必須能由 ODE 檔案傳回,其格式 為:

[tspan, y0, options] = odefile([], [], 'init')

其中我們假設 odefile 即是我們的 ODE 檔案。若 odefile 滿足上述要 求,則我們可以直接呼叫 ODE 指令如下:

[t, y] = solver('odefile')

(18)

其中 solver 為前述的任一個 ODE 指令,它可由 odefile 直接得到 tspan、y0 及 options 等積分所需的資訊。

以前述的 van der Pol 為例,若要能夠傳回 tspan、y0 及 options,vdp1.m 須改寫如下(vdp3.m):

>> type vdp3.m

function [output1, output2, output3] = vdp3(t, y, flag) if strcmp(flag, '')

mu = 1;

output1 = [y(2); mu*(1-y(1)^2)*y(2)-y(1)]; % dy/dt elseif strcmp(flag, 'init'),

output1 = [0; 25]; % Time span

output2 = [3; 3]; % Initial conditions output3 = odeset; % ODE options

end

此時我們可以直接呼叫 ODE 指令如下:

>> ode45('vdp3');

0 5 10 15 20 25

-4 -2 0 2 4

0 5 10 15 20 25

-4 -2 0 2 4

(19)

此外,van der Pol 的微分方程式有一個參數

µ

,若希望從外面傳入此

參數的值,我們可將 vdp3.m 改寫如下(vdp4.m):

>> type vdp4.m

function [output1, output2, output3] = vdp4(t, y, flag, mu) if nargin < 4 | isempty(mu),

mu = 1;

end

if strcmp(flag, '')

output1 = [y(2); mu*(1-y(1)^2)*y(2)-y(1)]; % dy/dt elseif strcmp(flag, 'init'),

output1 = [0; 25]; % Time span

output2 = [3; 3]; % Initial conditions output3 = odeset; % ODE options

end

此時

µ

就變成一個選擇性(Optional)的參數,其預設值為 1。在下 例中,我們將

µ

的值從 MATLAB 傳入,並畫出不同

µ

值下的 van der Pol 方程式的狀態變數:

>> subplot(2,1,1); ode45('vdp4', [], [], [], 1); % mu = 1

>> subplot(2,1,2); ode45('vdp4', [], [], [], 3); % mu = 3

(20)

0 5 10 15 20 25 -4

-2 0 2 4

0 5 10 15 20 25

-10 -5 0 5 10

在上圖中,

µ

的值分別是 1 及 3。指令列中用到了許多空矩陣,這些 空矩陣代表「取用預設值」,因此 ode45 會直接從 vdp4.m 取用時間區 間及變數起始值。事實上,您也可以傳入二個或更多的參數,MATLAB 及 ODE 指令對於可傳入的參數個數並無設限。

此 外 , 為 解 決 其 它 較 複 雜 的 ODEs 及 DAEs ( Differential Algebra Equations),ODE 檔案亦可在不同的旗號(Flag)下傳回不同的資訊,

以下是一個完整的列表:

整理:由 odeset 產生的 ODE 選項

旗號 傳回值

(空字串) dy(=F(t,y))

init tspan, yo 及 options

jacobian Jacobian 矩陣 J(t,y) = 2F/2Y jpattern Jacobian sparsity pattern 之矩陣

µ

= 1

µ

= 3

(21)

mass 解 M(t,y)y' = F(t,y) 所須的 質量矩陣 M

events 定義事件發生點的各種資訊

後四者因為不常用到,在此不再贅述。有興趣的讀者可參考 MATLAB 有關 ODE 的手冊。

參考文獻

相關文件

Stability of Runge-Kutta Methods High-Order Runge-Kutta methods Numerical

In words, the Product Rule says that the derivative of a product of two functions is the first function times the.. derivative of the second function plus the second function

(b) with respect to a free-trade area, or an interim agreement leading to the formation of a free-trade area, the duties and other regulations of commerce maintained

受方便學處品第十八 次說釋百字生品第十九 次百字果相應品第二十 次真言百字位成品第二十一 次百字成就持誦品第二十二

“ Numerical studies of hyperbolic IBVP with high-order finite difference operators satisfying a summation by parts rule.”.. “High-order finite difference methods,

締約國同意在環保、保育(包括天然資源)方面共同合作。環境 合作機制(Environmental Cooperation

釋舌相品第六 釋三假品第七 釋勸學品第八 釋集散品第九上 釋集散品第九下 釋行相品第十 釋幻品第十一 釋義品第十二..

三、第二項係參照原優存辦法第二條第二 項規定,明定於九十九年十二月三十