--- title: 數學軟體實作 - ODE solver tags: 2020 Fall - 數學軟體實作 GA: G-77TT93X4N1 --- Recall: [Function handle and pseudo code](https://hackmd.io/@teshenglin/ms_pseudo) # Lecture - ODE solver ## Basic Matlab ODE solvers `Matlab` 解常微分方程的指令中, 最常用的有以下兩個: * `ode45`: 解 non-stiff 微分方程 * `ode15s`: 解 stiff 微分方程 其基本指令就是 ``` [TOUT,YOUT] = ode45(ODEFUN,TSPAN,Y0) ``` 其中 * `ODEFUN` 是個 function handle, 定義了要解的 ODE * `TSPAN` = [T_0 T_FINAL], 定義另要解的時間範圍 * `Y0` 是初始值 也就是說, 這是在解**一階常微分方程的初始值問題**. <!-- 舉例來說, 要解 $$ \frac{dy}{dt} = 2t, \quad y(0)= 0, \quad t\in[0 5] $$ 我們可以定義 function handle 為 ```matlab= [t,y] = ode45(@(t,y) 2*t, [0 5], 0); % 解 y' = 2*t plot(t,y, 'o-'); % 畫出解來 ``` --> --- ### ODEFUN 要解一階常微分方程的初始值問題, 我們將方程寫成 $$ \frac{dY}{dt} = F(t, Y), $$ 其中 $Y=Y(t)$. 若 $Y$ 是個向量那就是個一階常微分方程系統. 接著我們將它寫成 `matlab` 函數: ``` dydt = myODE(t, Y) % Input: t - time, scalar % Y - nx1 vector % Output: dydt: nx1 vector dydt = F(t, Y) ``` 定義出這個函數之後, 就可以把它以 `@` 做成 function handle 輸入至 `ode45` 來解了. --- #### van der Pol equation: 舉例來說, 我們想要解這個二階常微分方程的初始值問題: $$ y'' - \mu(1-y^2)y' + y = 0, \, y(0)=2, \, y'(0)=0, $$ 其中 $y=y(t)$, $\mu$ 是個常數. 我們引進 $y_1=y$, $y_2=y'$, 則可以將上式改寫成兩個一階的常微分方程 $$ y_1' =y_2, \\ y_2' = \mu(1-y_1^2)y_2 - y_1, $$ 其初始值為 $y_1(0)=2$, $y_2(0)=0$. 上面這個微分方程寫成函數就是以下這個樣子. (這是 `matlab` 內建的程式, 不需要另外存可以直接用, 其中 $\mu=1$) ```matlab= function dydt = vdp1(t,y) %VDP1 Evaluate the van der Pol ODEs for mu = 1 % dydt = [y(2); (1-y(1)^2)*y(2)-y(1)]; ``` 好了之後我想要以 `ode45` 來解, $t\in[0, 20]$. 這樣我需要在 `matlab` 的 command window 輸入 ```matlab= [t,y]=ode45(@vdp1,[0 20],[2 0]'); % 解上列 van der pol ODEs plot(t,y(:,1)); % 畫出解來 ``` --- #### Remark: 1. 若我們直接在 command window 輸入 ```matlab= ode45(@vdp1,[0 20],[2 0]') ``` 會直接將 $y_1$ 以及 $y_2$ 畫出來, 不過沒有 output. 3. 若要畫在 phase plane (y(t), y'(t)) 上, 可以這樣做 ```matlab= [t,y]=ode45(@vdp1,[0 20],[2 0]'); plot(y(:,1), y(:,2)) ``` --- #### Exercise 解以下的 Lorenz system $$ \frac{dy_1}{dt} = \sigma(y_2 - y_1)\\ \frac{dy_2}{dt} = y_1(\rho-y_3) - y_2\\ \frac{dy_3}{dt} = y_1y_2 - \beta y_3, $$ 其中 $\rho = 28$, $\sigma = 10$, $\beta = 8/3$. 系統初始條件為 $(y_1(0), y_2(0), y_3(0)) = (0, 1, 0)$. 並以如下指令畫出其在三維的 phase plane ```matlab= plot3(y(:,1), y(:,2), y(:,3)) ``` --- ## Two point boundary value problems `ode45` 只能解常微分方程初始值問題, 因此, 若我們要解的問題是邊界值問題, 那就需要用其他方式來做. 比如說我們要解以下 Fisher-KPP equation $$ y'' + y - y^2=0, \quad y(0)=1, \quad y(8)=0; $$ 跟之前一樣我們引進 $y_1=y$, $y_2=y'$, 則可以將上式改寫成兩個一階的常微分方程 $$ y_1' =y_2, \\ y_2' = -y_1 + y_1^2, $$ 然後我們知道 $y_1(0)=1$. ### Shooting method 假設我們令 $y_2(0)=\alpha$, 比如說 $\alpha=1$, 那這樣我們在 $t=0$ 就有兩個初始值, 就可以以 `ode45` 來解這問題, 得到 $y_1(t)$, $y_2(t)$. 然後我們可以算 $y_1(8)$ 是多少, 假設 $y_1(8)=\beta$. 也就是說, 給定 $\alpha$, 我們就可以算出一個 $\beta=y_1(8)$. 因此我們可以將這想成是一個函數, $f(\alpha)=\beta$. 而原問題是要找 $y(8)=0$, 也就是 $y_1(8)=0$, 也就是 $\beta=0$. \ 也就是說, 我們要找 $\alpha$, 使得 $\beta=0$. \ 也就是說, 這是個求根問題, 我們要找 $\alpha$, 使得 $f(\alpha)=0$. #### Assignment 以 shooting method 解以下的 two-point boundary value problem: $$ y'' + y - y^2=0, \quad y(0)=1, \quad y(8)=0; $$