Try   HackMD

Recall: Function handle and pseudo code
Recall: Solving linear system

Lecture - fsolve

fsolvematlab 最強大的工具之一 (另一個是反除 /). 它可以解非線性方程. 也就是說, 若我們把要解的問題寫成以下形式:

F(x)=0.
那就能以 fsolve 來解.

其基本指令就是

X = fsolve(FUN,X0)

其中

  • ODEFUN 是個 function handle, 定義了要解的函數
  • X0 是初始猜測
  • X 則是算出來的解

Remark

fsolve 是以迭代法來解, 所以需要一個初始猜測值, 然後找出一個解.

Example

以下這例子想找

sin(x)=0 的解, 一開始先猜
x=2
:

x = fsolve(@(x) sin(x), 2)

如果一開始想多猜幾個一起也是可以的, 比如說初始猜測值我們定

x=0,2,4,6,8, 則 fsolve 就會將這五個初始值所收斂到的解算出來:

x = fsolve(@(x) sin(x), [0 2 4 6 8])

如果我們想知道 fsolve 解問題過程的一些細節也可以設定, 比如說我想知道迭代的情形, 可以要求顯示迭代過程:

x = fsolve(@(x) sin(x), [0 2 4 6 8], optimoptions('fsolve','Display','iter'))

假設我定一個函數, 有兩個 input,

f(x,c)=sin(cx)

% myfun.m function y = myfun(x,c) y = sin(c*x);

但是我想要解當

c=2 時候根, 也就是求
x
使得
f(x,2)=0
, 那可以這樣做:

c = 2; x0 = 1; % 初始猜測值 x = fsolve(@(x) myfun(x,c), x0)

當然, 有可能我就是想解雙變數函數, 也就是我要找

(x,c) 使得
f(x,c)=0
, !!這是不可能的!!

因為有兩個未知數, 不過只有一個方程式, 所以有無限多組解.

所以, 以下這樣的系統才有機會求根:

F(x,y)=[sin(x+y)cos(xy)]

% myfun2.m function F = myfun2(X) % X: 2x1 vector % F: 2x1 vector F(1,1) = sin(X(1)+X(2)); F(2,1) = cos(X(1)-X(2));

那就直接解雙變數:

x0 = [2, 1]; % 初始猜測值 X = fsolve(@myfun2, x0)

Exercise

Recall Assignment in Root finding,

Use fsolve to solve that problem.


Assignment

Recall Assignment in ODE solver

以 finite difference method 解以下的 two-point boundary value problem:

y+yy2=0,y(0)=1,y(8)=0;

我們先將

[0,8] 分成
N+2
個點, 其中
x0=0
,
xN+1=8
,
xk=kΔx,Δx=8N+1,k=0,,N+1,

這樣的話可以將
y=y(x)
同樣分成
N+2
個點,
yk=y(xk),k=0,,N+1,

所以兩個邊界條件
y(0)=1
,
y(8)=0
得到
y0=1
,
yN+1=0
.

接著, 將微分方程以有限差分法離散得到

yk12yk+yk+1(Δx)2+ykyk2=0,k=1,,N

Summary

所以我們希望求出

y1,,yN, 並使他們滿足上列式子. 我們以 fsolve 將它解出來.