Mathematica

  • Uploaded by: Chung-Yuan Dye
  • 0
  • 0
  • May 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Mathematica as PDF for free.

More details

  • Words: 4,704
  • Pages: 45
Mathematica 戴忠淵 [email protected] http://chungyuandye.blogspot.com

July 30, 2009

Contents

1

2

微積分的基本操作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1

1.1

極限 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1

1.2

微分 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2

1.3

全微分 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5

1.4

積分 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6

1.5

級數 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

18

非線性最佳化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 2.1

2.2

方程式求解 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

23

2.1.1 Solve . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

23

2.1.2 FindRoot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

26

非線性最佳化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

34

2.2.1 無限制條件下最佳化求解 . . . . . . . . . . . . . . . . . . . . . . . . . . . .

36

第1章 微積分的基本操作

1.1 極限 Mathematica計算極限的指令為Limit[f, x]。該指令的用法有以下幾種 1. Limit[f, x->a]:計算函數f在x → a的極限值 2. Limit[f, x->a, Direction -> 1]:計算函數f在x → a的右極限值 3. Limit[f, x->a, Direction ->-1]:計算函數f在x → a的左極限值

範例 1-1. sin(x) x→0 x

計算 lim

In[1]: Limit[Sin[x]/x, x -> 0] Out[1]: 1

計算 lim + x→−2

|x + 2| x+2

In[2]: Limit[Abs[x + 2]/(x + 2), x -> -2, Direction -> 1] Out[2]: −1

計算 lim − x→−2

|x + 2| x+2

In[3]: Limit[Abs[x + 2]/(x + 2), x -> -2, Direction -> -1] Out[3]: 1

1.2 微分

計算 lim

x→−2

2

|x + 2| x+2

In[4]: Limit[Abs[x + 2]/(x + 2), x -> -2] Out[4]: 1

在上式中很明顯發現Mathematica在計算極限值時,並不會考慮到極限的存在性。所以在函數極限發 散或不存在時,使用Limit指令必須更為小心。

1.2 微分 在Mathematica中計算函數的微分或積分是非常方便的,其指令為D[f,x],表示函數f對x做或偏微 分。該指令的用法有以下幾種: 1. D[f, x]:函數f對x微分,

∂f ∂x

2. D[f, x1 , x2 , . . . , xn ]: 函數f對x1 , x2 , . . . 偏微分, 3. D[f,{x,n}]:函數f對x做n次微分,

∂n f ∂xn

∂n f ∂x1 ∂x2 · · · ∂xn {

} ∂f ∂f ∂f 4. D[f, {{x1 , x2 , . . . ,xn }]: 函數f分別對x1 , x2 , . . . 偏微分, , ,..., ,即傳回函 ∂x1 ∂x2 ∂xn 數f的梯度。必須注意的是此處所傳回的為一陣列 對於單變數函數的微分,Mathematica有個方便的技巧,就是直接以f’[x]表示即可;同理,f”[x]則表 示函數f(x)的二階導數,以此類推。 範例 1-2.

定義函數f(x) = xex

2

In[1]: f[x_]:=x*Exp[x^2] Out[1]:

傳回一階、二階和三階導數 In[2]: {f’[x],f’’[x],f’’’[x]} { 2 } 2 2 2 2 2 2 Out[2]: ex + 2ex x2 , 6ex x + 4ex x3 , 6ex + 24ex x2 + 8ex x4

CHAPTER 1. 微積分的基本操作

3

傳回f(x)在x = 0的5階泰勒展開式 In[3]: Plus@@Table[(D[f[x],{x,n}]/.x->0)/n!*x^n,{n,0,5}] 1 1 1 1 (5) f (0)x5 + f(4) (0)x4 + f(3) (0)x3 + x2 f ′′ (0) + xf ′ (0) + f(0) Out[3]: 120 24 6 2 2

若將函數f(x) = xex 帶入上式,可得f(x)在x = 0的5階泰勒展開式 In[4]: Plus@@Table[(D[f[x],{x,n}]/.x->0)/n!*x^n,{n,0,5}] x5 Out[4]: + x3 + x 2

以上為Mathematica對單變數函數微分的方式,多變數函數微分在Mathematica中也是非常簡單,僅 需要注意微分的順序即可。

範例 1-3. f(x, y) = xyexy

定義函數f(x, y) = xyexy In[1]: f[x_,y_]:=x*y*Exp[x*y] Out[1]:

函數f(x, y)對x做偏導數,即求

∂f ∂x

In[2]: D[f[x,y],x] Out[2]: exy xy2 + exy y

函數f(x, y)對x做二階偏微分,

∂2 f ∂x2

In[3]: D[f[x,y],x,x] Out[3]: exy xy3 + 2exy y2

以下指令同樣也是對x做二階偏微分 In[4]: D[f[x,y],{x,2}] Out[4]: exy xy3 + 2exy y2

1.2 微分

4

函數f(x, y)分別對x, y偏微分,傳回梯度 In[5]: D[f[x,y],{{x,y}}] { } Out[5]: exy xy2 + exy y, exy yx2 + exy x

上式結果分別再對x, y做偏微分即傳回海賽矩陣(Hessian Matrix),並以矩陣方式表示 In[6]: D[%, {{x, y}}] // MatrixForm   xy 3 xy 2 xy 2 2 xy xy e x y + 3e xy + e  e xy + 2e y  Out[6]:   exy x2 y2 + 3exy xy + exy exy yx3 + 2exy x2

運用函數D[f,{x1 , n}]和D[f, {{x1 ,x2 ,. . . ,xn }}]的概念,我們可以把程式寫得更簡潔 In[7]: D[f[x,y],{{x,y},2}]//MatrixForm   xy 3 xy 2 xy 2 2 xy xy Out[7]: e x y + 3e xy + e  e xy + 2e y    xy 2 2 xy xy xy 3 xy 2 e x y + 3e xy + e e yx + 2e x

產生f(x, y)的多變數麥克勞尼展開式前3階各項元素 In[8]: Table[Binomial[n,i]*(D[f[x,y],{x,i},{y,n-i}]/.{x->0,y->0})* x^i*y^(n-i)/n!,{n,0,3},{i,0,n}]//TableForm Out[8]: f(0, 0) yf(0,1) (0, 0) 1 2 (0,2) y f (0, 0) 2 1 3 (0,3) y f (0, 0) 6

xf(1,0) (0, 0) xyf(1,1) (0, 0) 1 2 (1,2) xy f (0, 0) 2

1 2 (2,0) x f (0, 0) 2 1 2 (2,1) x yf (0, 0) 2

1 3 (3,0) x f (0, 0) 6

將上式所有元素相加即為f(x, y)在(x, y) = (0, 0)的3階泰勒展開式 In[9]: Plus@@(%//Flatten) 1 1 Out[9]: f[0, 0] + yf(0,1) [0, 0] + y2 f(0,2) [0, 0] + y3 f(0,3) [0, 0] + xf(1,0) [0, 0] 2 6 1 2 (1,2) 1 2 (2,0) 1 1 (1,1) +xyf [0, 0] + xy f [0, 0] + x f [0, 0] + x2 yf(2,1) [0, 0] + x3 f(3,0) [0, 0] 2 2 2 6

CHAPTER 1. 微積分的基本操作

5

1.3 全微分 在上一小節中,我們介紹如何用Mathematica來求解y′ ,然而並非所有的y都可以表示成x的封閉解 dy (close-form)。當y無法表示成x的封閉解時,要求解 則必須倚賴隱函數微分。Mathematica中要進 dx 行隱含數微分則必須借助Dt這個全微分指令。全微分指令的用法有以下幾種: 1. Dt[f, x]:函數f對x做全微分 2. Dt[f]: 函數f對做全微分 3. Dt[f,{x,n}]:函數f對x做n階全微分 4. Dt[f, {{x1 , x2 , . . . ,xn }]: 函數f分別對x1 , x2 , . . . 做全微分

範例 1-4. 函數f(x, y) = 4x2 + 2xy − xy3

定義函數f(x, y) In[1]: f[x_, y_] := 4x^2 + 2x*y - x*y^3 Out[1]:

函數f(x, y)對x做全微分 In[2]: Dt[f[x,y],x] Out[2]: 8x + 2y − y3 + 2xDt[y, x] − 3xy2 Dt[y, x]

上式中Dt[y, x]即為

dy dy ,接下來我們用指令Solve來求解 dx dx

In[3]: Solve[%==0,Dt[y,x]] {{ }} 8x + 2y − y3 Out[3]: Dt[y, x] → x (−2 + 3y2 )

函數f(x, y)做全微分 In[4]: Dt[f[x,y]] Out[4]: 8xDt[x] + 2yDt[x] − y3 Dt[x] + 2xDt[y] − 3xy2 Dt[y]

1.4 積分

6

上式中Dt[x]和Dt[y]分別表示dx和dy,移項後也可傳回與Dt[y, x]相同之結果 In[5]: Solve[% == 0, Dt[y]] {{ }} 8xDt[x] + 2yDt[x] − y3 Dt[x] Out[5]: Dt[y] → x (−2 + 3y2 )

1.4 積分 在Mathematica中計算函數的積分指令為Integrate,該指令的用法有以下幾種: ∫ 1. Integrate[f, x]: 傳回函數f的不定積分,即 f(x)dx 2. Integrate[f, {x, a, b}]: 傳回函數f在區間(a, b)間的定積分值 3. Integrate[f, {x1 , a, b}, {x2 , c, d}, . . . ] 傳回函數f在區間(a, b) × (c, d) × · · · 的定積分值。要 注意的是x1 為最外面的積分變數,x2 為倒數第二個的積分變數,即 ∫ ∫b ∫d · · · f(x1 , x2 , . . . , xn )dxn · · · dx2 dx1 a

∫ 範例 1-5. 計算

計算

c

1 dx xp

1 的不定積分 xp

In[1]: Integrate[1/x^p,x] x1−p Out[1]: 1−p

由於當p > 1時積分會發散,所以Mathematica會給於提示 In[2]: Integrate[1/x^p, {x,0,1}] [ ] [ ] 1 Out[2]: If Re(p) < 1, , Integrate x−p , {x, 0, 1}, Assumptions → Re(p) > 1 1−p

如果要避免發生錯誤,可以在指令後面加上一個假設參數,Assumptions->{0{0
CHAPTER 1. 微積分的基本操作

7

另外一個方式為設定參數GenerateConditions為False,要求Mathematica不產生條件判斷式 In[4]: Integrate[1/x^p, {x,0,1}, GenerateConditions->True] 1 Out[4]: 1−p

若希望Mathematica在未來的計算過程中都不要自動產生判斷式,我們可以藉由改變Integrate函數的 屬性來達成。

要求Mathematica在未來所有的計算過程都不產生條件判斷式 In[6]: SetOptions[Integrate,GenerateConditions->False]

∫∫ 範例 1-6.

(x2 − y)dydx,其中Ω = {(x, y)| − x2 6 y 6 x2 , −1 6 x 6 1}



繪出Ω的範圍 In[1]: RegionPlot[y<=x^2&&y>=-x^2,{x,-1,1},{y,-1,1}] Out[1]: 1.0

0.5

0.0

-0.5

-1.0 -1.0

-0.5

0.0

0.5

1.0

∫ 1 ∫ x2 我們可以把積分寫為 x 2 − yd yd x −1 −x2

In[2]: Integrate[x^2-y,{x,-1,1},{y,-x^2,x^2}] 4 Out[2]: 5

1.4 積分

8

我們也可以配合布爾函數來計算積分值 In[3]: Integrate[(x^2-y)*Boole[-x^2<=y&&y<=x^2&&-1<=x&&x<=1], {y,-1,1},{x,-1,1}] 4 Out[3]: 5

此處的Boole為一指標函數,若(x, y)在Ω內則傳回1,否則傳為0,即   1, (x, y) ∈ Ω Boole[-x^2<=y&&y<=x^2&&-1<=x&&x<=1] =  0, (x, y) ∈ /Ω 因此,當積分範圍複雜時,搭配布爾函數則可不考慮積分順序。

範例 1-7. 求由f(x) = x3 − 3x及g(x) = 3x所夾之區域面積。

定義函數f(x)及g(x) In[1]: f[x_]:=x^3-x;g[x_]:=3x; Out[1]:

定義函數f(x)及g(x)並繪出f(x)及g(x)夾之區域 In[2]: f[x_]:=x^3-x;g[x_]:=3x; In[3]: Show[Graphics[Plot[{x^3-x,3x},{x,-2.5,2.5}]], Graphics[Plot[{x^3-x,3x},{x,-2,2},Filling->{1->{2}}]], PlotRange->All] Out[3]: 10

5

-2

1

-1 -5

-10

2

CHAPTER 1. 微積分的基本操作

9

使用布爾函數計算面積 In[4]: Integrate[Boole[-2<x<=2]*Abs[f[x]-g[x]],{x,-2,2}] Out[4]: 8

若不使用布爾函數,本範例積分範圍必須拆成兩部分計算 In[5]: Integrate[f[x]-g[x],{x,-2,0}]+Integrate[g[x]-f[x],{x,0,2}] Out[5]: 8

∫∫ 範例 1-8.

24xydydx,其中Ω = {(x, y)|0 6 x 6 1, 0 6 y 6 1, 1 6 x + y 6 1.5}



首先畫出函數f(x, y) = 24xy在Ω的3D立體圖 In[1]: Plot3D[24*x*y,{x,0,1},{y,0,1},Filling->Bottom, RegionFunction->Function[{x,y},x>=0&&x<=1&&y>=0&&y<=1&&x+y>=1&&x+y<=1.5]] Out[1]:

10

1.0

5 0 0.0

0.5

0.5

1.0 0.0

配合布爾函數來計算積分值 In[2]: Integrate[24*x*y*Boole[x>=0&&x<=1&&y>=0&&y<=1&&x+y>=1&&x+y<=1.5], {x,0,1},{y,0,1}] Out[2]: 2.9375

1.4 積分

10

若不使用布爾函數,本範例積分範圍必須拆成兩部分計算 In[3]: Integrate[24*x*y,{x,0,0.5},{y,1-x,1}]+ Integrate[24*x*y,{x,0.5,1},{y,1-x,1.5-x}] Out[3]: 2.9375

範例 1-9. 假設f(x, y) = xyex

2 +y2

定義函數f(x, y) In[1]: f[x_,y_]:=x*y*Exp[x^2+y^2] Out[1]:

∫ 2 2 f(x, y)對x做積分,即求 xyex +y dx In[2]: Integrate[f[x,y],x] 1 2 2 Out[2]: ex +y y 2

∫b 2 2 f(x, y)對x做積分,其中x ∈ (a, b),即求 xyex +y dx a

In[3]: Integrate[f[x,y],{x,a,b}] ) 1 2( 2 2 Out[3]: ey −ea + eb y 2

∫b ∫d 2 2 f(x, y)對x做積分,其中x ∈ (a, b)及y ∈ (c, d),即求 xyex +y dydx a

c

In[4]: Integrate[f[x,y],{x,a,b},{y,c,d}] )( 2 ) 1 ( a2 2 2 Out[4]: e − eb ec − ed 4 x2 1 當然並不是所有的函數都是可積,例如標準常態分配的機率密度函數,f(z) = √ e− 2 , −∞ < 2π z < ∞就無法求得其不定積分。此時,Mathematica也就無能為力。所以在求解此類問題時就必須借助數

值積分。數值積分是解決定積分的另一種有效的方法,它可以求出一個近似解。特別是對於用Integrate指 令無法求出的定積分,數值積分更是可以發揮巨大作用。

CHAPTER 1. 微積分的基本操作

11

數值積分與傳統定積分基本概念是一樣的,但是傳統定積分使用對應的積分公式,對於一般人來說不 容易推導高複雜度的非線性函數定積分公式,藉由電腦或計算機來快速計算積分值。數值積分的概念源自 於黎曼積分,將積分範圍在一個極小的區域內分割成[x1 , x2 , x3 , . . . , xn ],然後使用電腦或電子計算機程 式進行累加積分值。 z2 1 範例 1-10. 假設f(z) = √ e− 2 ,求解f(z)在區間−∞ < z < 1.96之積分值 2π

定義函數 In[1]: f[z_]:=1/Sqrt[2Pi]*Exp[-z^2/2]; Out[1]:

在−5與1.96間隨機選取49個點,即將區間劃分成50個子區間 In[2]: pts=RandomReal[{-5,1.96},49]//Sort; Out[2]:

將50的個矩形繪出,可以發現此圖形面積近似原來函數面積 In[3]: Show[Graphics[Table[{RGBColor[i/50,0,0],AspectRatio->0.65, Rectangle[{pts[[i]],0},{pts[[i+1]],f[pts[[i+1]]]}]},{i,1,48}]], Plot[f[x],{x,-5,5},PlotStyle->Thickness[0.015]]] Out[3]:

在數值分析上,常用的數值積分的方法有梯形法則和辛普森法則,這兩種方法都屬於牛頓-寇次公式。 牛頓-寇次公式的原理是 以n + 1點進行插值,求得對應函數f(x)的Lagrange多項式來近似原來的函 數,再進行定積分。所以,當n = 1時,即為梯形法則;n = 2時,為辛普森法則;n = 3時,為辛普 森3/8法則;n = 4時,為保爾法則。在Mathematica中,以n個點建構n − 1次方的Lagrange多項式指令

1.4 積分

為InterpolatingPolynomial,該指令用法為: InterpolatingPolynomial[{{x1 ,f(x1 )},{x2 ,f(x2 )},. . . ,{xn ,f(xn )}},x] 範例 1-11. 承上例,計算f(z)在區間−∞ < z < 1.96之積分值

建立牛頓-寇次公式 In[1]: NC[n_]:=NC[n]=Block[{temp=n,x,h,a,b,f,i}, x[0]=a;x[temp]=b;x[i]=a+i*h;h=(b-a)/temp; Integrate[InterpolatingPolynomial[Table[{x[i],f[x[i]]}, {i,0,temp}],t],{t,a,b}]] Out[1]:

輸出牛頓-寇次公式的前五近似公式 In[2]: TableForm[NC/@Range[5]] Out[2]:

1 − (a − b)(f [a] + f [b]) 2 ( [ ]) 1 a+b − (a − b) f [a] + f [b] + 4f 6 ( ( [2 ] [ ])) 1 1 1 − (a − b) f [a] + f [b] + 3 f (2a + b) + f (a + 2b) 8 3[ ( (3 ( ) ] [ ])) 1 a+b 1 1 − (a − b) 7f [a] + 7f [b] + 4 3f + 8f (3a + b) + 8f (a + 3b) 90 2 4 4

將−5與1.96均分成1000等分 In[3]: pts=Table[-5+(1.96+5)/1000*i,{i,0,1000}]; Out[3]:

以梯形法則計算面積 In[4]: Sum[(a=pts[[i]];b=pts[[i+1]];NC[1]),{i,1,1000,1}] Out[4]: 0.975001

以辛普森法則計算面積 In[5]: Sum[(a=pts[[i]];b=pts[[i+2]];NC[2]),{i,1,999,2}] Out[5]: 0.975002

12

CHAPTER 1. 微積分的基本操作

13

分別以梯形法則、辛普森法則及保爾法則計算面積 In[6]: Sum[(a=pts[[i]];b=pts[[i+#]];NC[#]),{i,1,1001-#,#}]&/@{1,2,4} Out[6]: {0.975001, 0.975002, 0.975002}

上述三種計算法則即為牛頓-寇次公式的1,2,4次方近似式,由上式可發現並非次方越高,近似效果越 好。牛頓-寇次公式對於次數較高的多項式而有很大誤差,此即為龍格現象。

分別將−5與1.96均分成10, 20, . . . ,1000等分在以梯形法計算面積。由輸出圖形發以發現分割越 多,越趨近0.975 In[7]: ListPlot[(pts=Table[-5+(1.96+5)/#*i,{i,0,#}]; Sum[(a=pts[[i]];b=pts[[i+1]];-(1/2)(a-b)(f[a]+f[b])),{i,1,#,1}])& /@Table[10*i,{i,1,100}]] Out[7]: 0.975000 0.974995 0.974990 0.974985 0.974980 0.974975 20

40

60

80

100

上述的計算方式,雖然可以達到近似的效果,但效率並不高。為了提高收斂速度,減少計算次數,數 學家也開始尋求其他方法。我們在此介紹一個較常用的計算方式,Romberg積分法 。Romberg積分法是 在以牛頓-寇次公式為基礎所構造出的一種加速計算積分的方法,它在不增加計算次數的前提下提高了準 確度。有關Romberg演算法的計算公式如下:  1   R (0, 0) = (b − a) (f (a) + f (b))   2   ) 2n−1 (  b−a ∑ b−a 1 f a + (2k − 1) n R(n, 0) = R (n − 1, 0) + n  2 2 2   k=1   1   R (n, m) = R (n, m − 1) + [R (n, m − 1) − R (n − 1, m − 1)] 4m − 1 根據Romberg演算法,我們可以將上述公式以迴圈的方式撰寫程式如下:

1.4 積分

14

∫ 1.96 x2 1 √ e− 2 d x 利用Romberg演算法求解 2π −5 In[8]: Clear[R,n,m];f[x_]:=1/Sqrt[2Pi]*Exp[-x^2/2];a=-5;b=1.96;n=1;error=100; R[0,0]=((b-a)/2*(f[a]+f[b]))//N; While[error>10^-10, For[m=1,m<=n, R[n,0]=(R[n-1,0]/2+(b-a)/2^n*Sum[f[a+(2k-1)*(b-a)/2^n], {k,1,2^(n-1)}])//N; R[n,m]=(R[n,m-1]+(b-a)/(4^m-1)*(R[n,m-1]-R[n-1,m-1]))//N; error=Abs[R[n,m]-R[n,m-1]]; m++]; n++]; Out[8]: 0.975001

將計算過程列出 In[8]: Table[R[n,m],{n,0,5},{m,0,5}]//TableForm Out[8]: 0.20338 0.539003 0.950481 0.967869 0.973201 0.974551

0.650877 1.08764 1.11676 0.973665 0.966066 0.963674 0.974978 0.975065 0.975208 0.975001 0.975002 0.975001

0.975253 0.975 0.975

當然Mathematica中作數值積分不需要自己撰寫程式,Mathematica有自己的數值積分指令。 在Mathematica中數值積分的指令為NIntegrate,該指令組合了N以及Integrate的用途,該指令的用法有 以下幾種: 1. NIntegrate[f, {x, a, b}]: 傳回函數f的數值積分 2. NIntegrate[f, {x1 , a, b}, {x2 , c, d}, . . . ] 傳回函數f在區間(a, b) × (c, d) × · · · 的定積分值。要 注意的是x1 為最外面的積分變數,x2 為倒數第二個的積分變數

z2 1 範例 1-12. 假設f(z) = √ e− 2 ,求解f(z)在區間−∞ < z < 1.96之積分值,即求 2π

∫ 1.96 −∞

z2 1 √ e − 2 dz 2π

CHAPTER 1. 微積分的基本操作

15

繪出常態分配在−∞ < z < 1.96的圖形 In[1]: p1=Plot[1/(2*Pi)^0.5*Exp[-z^2/2],{z,-5,5},RegionFunction->(#<=1.96&), Filling->Bottom,PlotStyle->Thickness[0.01]]; p2=Plot[1/(2*Pi)^0.5*Exp[-z^2/2],{z,-5,5}, PlotStyle->Thickness[0.01],Filling->y]; Show[p1,p2] Out[1]:

0.4

0.3

0.2

0.1

-4

-2

2

4

以Integrate計算不定積分值 In[1]: Integrate[1/(2*Pi)^0.5*Exp[-z^2/2],z] [ ] z Out[1]: 0.5Erf √ 2

上式中Erf(x)為誤差函數, 2 Erf(x) = √ π

∫x

2

e−t dt 0

由於函數f(z)不可積,所以Mathematica並沒有真正傳回不定積分。若在上式中將x以數值取代,則可傳 回其近似值。

以Integrate計算不定積分值 ,在統計學上此數表示為Z0.05 In[2]: Integrate[1/(2*Pi)^0.5*Exp[-z^2/2],{z,-Infinity,1.96}] Out[2]: 0.975002

1.4 積分

16

我們也可以用NIntegrate來求解相同的問題。要注意的是Nintegrate指令中的積分範圍參數必須為一 數值,否則會無法運算並出現錯誤訊息。

以NIntegrate計算,由於x並沒有指定特定數值,所以無法計算 In[3]: NIntegrate[1/(2*Pi)^0.5*Exp[-z^2/2],{z, -Infinity, x}] NIntegrate::nintp : Encountered the non-number x at z = z. More. . . [ ] z2 e− 2 Out[3]: Nintegrate , {z, −∞, x} (2π)0.5

將x以1.96取代則可求得積分值為0.975002 In[4]: NIntegrate[1/(2*Pi)^0.5*Exp[-z^2/2],{z, -Infinity, 1.96}] Out[4]: 0.975002

若在模式建立的過程中需要將NIntegrate中將積分參數以符號表示,則必須以函數方式表示。否 則,Mathematica會在後續的計算中以Integrate來取代NIntegrate。

定義函數Φ(x),其中?Number表示指定x為數值型態的變數 In[5]: Φ[x_?NumberQ]:=NIntegrate[1/(2*Pi)^0.5*Exp[-z^2/2], {z,-Infinity,x}]; Out[6]:

計算Φ(z), z = −3, −2, . . . , 3, 的常態機率值 In[6]: Table["P(Z<"<>ToString[i]<>")="<>ToString[Φ[i]], {i,-3,3,1}]//TableForm Out[6]: P(Z < −3) = 0.0013499 P(Z < −2) = 0.0227501 P(Z < −1) = 0.158655 P(Z < 0) = 0.5 P(Z < 1) = 0.841345 P(Z < 2) = 0.97725 P(Z < 3) = 0.99865

CHAPTER 1. 微積分的基本操作

17

利用Φ(x)產生1000個標準常態分配的隨機變數 In[7]: Table[x/.FindRoot[Φ[x]==Random[],{x,1}],{1000}]; Out[8]:

引入直方圖套件,並將上式得到的隨機變數以直方圖繪出 In[9]: Needs["Histograms`"];Histogram[%] Out[9]: 80

60

40

20

-3

-2

0

-1

1

2

此處所使用的FindRoot為方程式求根的指令,使用方式留待後面章節說明。

範例 1-13. 假設f(x, y) = e−

x2 +y2 2

,求解f(x, y)在區間0 < x < y < 1之雙重積分值,即求 ∫1 ∫y e− 0

0

x2 +y2 2

d xd y

以Integrate計算雙重積分值 In[1]: Integrate[Exp[-(x^2+y^2)/2],{y,0,1},{x,0,y}] [ ]2 1 1 √ Out[1]: πErf 4 2

將上式以數值方式輸出 In[2]: %//N Out[2]: 0.366047

1.5 級數

18

以NIntegrate計算雙重積分值 In[3]: NIntegrate[Exp[-(x^2+y^2)/2],{y,0,1},{x,0,y}] Out[3]: 0.366047

搭配布爾函數,就可以不必理會積分順序 In[4]: NIntegrate[Exp[-(x^2+y^2)/2]*Boole[0<=x&&x<=y&&y<=1],{y,0,1},{x,0,1}] Out[4]: 0.366047

1.5 級數 在Mathematica中計算函數的泰勒級數指令為Series[f,{x, a, n}],表示函數f在x = a的n階的泰勒 展開式。同時,Series也可處理多變數函數的泰勒展開式。當a = 0時,泰勒級數也稱為麥克勞林級數。 該指令的用法有: 1. Series[f,{x, a, n}]:函數f在x = a的n階泰勒展開式,所傳回的運算式中O (xn )稱為第n項餘 式。 2. Series[f,{x1 , a1 , n1 }, {x2 , a2 , n2 }]: 函 數f先 對x1 在x1 = a1 做n1 階 展 開 後 再 對x2 在 x2 = a2 展開n2 階的泰勒展開式。 與級數較相關的指令有SeriesCoefficient與CoefficientList,其用法簡單介紹如下: 1. SeriesCoefficient[f[x],n]:傳回多項式函數f(x)中xn 項的係數。 2. CoefficientList[f[x],x]:傳回多項式函數f(x)中的係數。

CHAPTER 1. 微積分的基本操作

19

範例 1-14.

計算f(x)在x = a的5階泰勒展開式 In[1]: Series[f[x], {x, a, 5}] 1 1 1 1 (5) Out[1]: f(a) + f ′ (a)(x − a) + f ′′ (a)(x − a)2 + f(3) (a)(x − a)3 + f(4) (a)(x − a)4 + f (a)(x − a)5 + 2 6 24 120 ) ( O (x − a)6

計算f(x) = Sin(x)在x = 0的5階泰勒展開式 In[2]: Series[Sin[x],{x, 0, 10}] ( ) x3 x5 x7 x9 Out[2]: x − + − + + O x11 6 120 5040 362880

將上式中的第5項餘式省略 In[3]: Normal[%] x3 x5 x7 x9 Out[3]: x − + − + 6 120 5040 362880

將Sin(x)及上式同時繪出 In[4]: Plot[{Sin[x],%},{x,0,2Pi}] Out[4]: 3

2

1

1

2

3

4

5

6

-1

分別將Sin(x)在x = 0的5階泰勒展開式中的各項係數取出 In[5]: Table[SeriesCoefficient[%3, k], {k, 1, 10}] } { 1 1 1 1 , 0, − , 0, ,0 Out[5]: 1, 0, − , 0, 6 120 5040 362880

1.5 級數

20

覺得以Table方式取出太麻煩,用CoefficientList更方便 In[6]: CoefficientList[%3,x] { } 1 1 1 1 Out[6]: 1, 0, − , 0, , 0, − , 0, ,0 6 120 5040 362880

在泰勒展開式中我們是以多項式函數來逼近原式。因此,隨著n的增加,泰勒展開式就可以更逼近原 式。 在以下範例我們將以不同的n來近似Sin(x)做說明。 範例 1-15.

分別產生Sin(x)的2, 4, 6, 8, 10, . . . , 20階泰勒展開式 In[1]: y=Table[Normal[Series[Sin[x],{x,0,i}]],{i,2,20,2}]; Out[1]:

將上式產生的各展開式與Sin(x)同時繪出 In[2]: Plot[Evaluate[{y,Sin[x]}], {x, 0, 2Pi},PlotRange->{-1.5,1.5}, PlotStyle->Table[Hue[k], {k, 0, 1, 0.05}], Ticks->{Flatten[Table[{i},{i,0,2Pi,Pi/4}]],Automatic}] Out[2]:

1.5 1.0 0.5

Π

Π



4

2

4

Π







4

2

4



-0.5

-1.0

-1.5

由上圖可以發現,當n = 20時,泰勒展開式與Sin(x)在x ∈ (0, 2π)之間幾乎無差別。以上我們所探 討的是單變數下Mathematica中計算級數的方法;接下來我們介紹函數Series在多變數的情況下的應用。

CHAPTER 1. 微積分的基本操作

21

範例 1-16.

先將f(x, y) = Sin(x + y)以x = 0求3階泰勒展開式,接著在以y = 0展開3階泰勒展開式 In[1]: Series[Sin[x+y],{x,0,3},{y,0,3}] ( ) ( ) ( ) ( 4) ( 4) ( 4) y3 y2 y y3 2 Out[1]: y − +O y +x 1− +O y +x − + +O y 2 2 12 (6 ) 2 ( ) ( ) 1 y + O y4 + O x4 +x3 − + 6 12

我們必須注意上式並非f(x, y)以(x, y) = (0, 0)展開的泰勒展開式。而是先將f(x, y)以x = 0求3階展 開式,之後再對x次方項的係數y求3階的泰勒展開式,說明如下:

先將f(x, y) = Sin(x + y)以x = 0求3階泰勒展開式 In[2]: Series[Sin[x+y],{x,0,3}}] ( ) 1 1 Out[2]: sin(y) + x cos(y) − x2 sin(y) − x3 cos(y) + O x4 2 6

將上式的係數項取出 In[3]: mycoff=CoefficientList[Series[Sin[x+y],{x,0,3}],x] { } sin(y) cos(y) Out[3]: sin(y), cos(y), − ,− 2 6

分別將各係數項對y取3階泰勒展開式 In[4]: Series[mycoff[[#]],{y,0,3}]&/@{1,2,3,4} { } ( ) ( ) y y3 ( ) 1 y2 ( ) y3 y2 Out[4]: y − + O y4 , 1 − + O y4 , − + + O y4 , − + + O y4 6 2 2 12 6 12

我們在此可以發現,將%4的結果代回%2中可得到與%1相同的結果。所以,Mathematica中函 數Series在多變數中所求得的展開式並非泰勒展開式。若要求得Sin(x + y)之3階泰勒展開式語法可參考 範例3,語法如下:

建立一個以(x, y) = (a, b)展開n階泰勒展開式的公式 In[5]: mytaylor[a_,b_,k_]:=Plus@@(Table[Binomial[n,i]* (D[Sin[x+y],{x,i},{y,n-i}]/.{x->a,y->b})*(x-a)^i*(y-b)^(n-i)/n!, {n,0,k},{i,0,n}]//Flatten); Out[5]:

1.5 級數

傳回(x, y) = (0, 0)展開3階泰勒展開式 In[6]: mytaylor[0,0,3] x3 x2 y xy2 y3 Out[6]: − − − +x− +y 6 2 2 6

22

第2章 非線性最佳化

2.1 方程式求解 在Mathematica中求解方程式根的方式有很多。當方程式具有封閉解時,我們可以用Solve這個指令 來求解。要是函數的解無函數形式,只能藉助數值方法求其數值解,這類問題所得是精確的數值解。在此 分別將Mathematica求解方程式和聯立方程組的指令介紹如下。

2.1.1 Solve 在Mathematica中函數求解方程式或聯立方程組最基本的方法就是使用指令Solve,Solve的使用方法 有以下幾種:

1. Solve[lhs == rhs, x]:以x為變數求解方程式lhs == rhs 2. Solve[{eqn1, eqn2, . . . }, {x1 ,x2 . . . }]:以x1 , x2 , . . . 為變數求解聯立方程組

範例 2-1. 求解ax2 + bx + c = 0

以Solve求解 In[1]: Solve[a*x^2+b*x+c==0,x] {{ } { }} √ √ −b − b2 − 4ac −b + b2 − 4ac Out[1]: x→ , x→ 2a 2a

2.1 方程式求解

24

求解6x2 + 13x + 5 = 0 In[2]: Solve[#1*x^2+#2*x+#3==0,x]&@@{6,13,5} {{ } { }} 5 1 Out[2]: x→− , x→− 3 2

範例 2-2. 求解x使得x5 − 4x + 2 = 0

繪出函數圖,由圖形可知方程式有三組實數解 In[1]: Plot[x^5-4*x+2,{x,-2,2}] Out[1]: 10

5

-2

1

-1

2

-5

以Solve求解,由於並無解析解,因此Mathematica在此以Root表示之 In[2]: Solve[x^5-4*x+2==0,x] Out[2]:

{{

[ ]} { [ ]} x → Root 2 − 4#1 + #15 &, 1 , x → Root 2 − 4#1 + #15 &, 2 , { [ ]} { [ ]} x → Root 2 − 4#1 + #15 &, 3 , x → Root 2 − 4#1 + #15 &, 4 , { [ ]}} x → Root 2 − 4#1 + #15 &, 5

若要求得數值解,可以搭配N要求輸出數值解 In[3]: sol=x/.Solve[x^5-4*x+2==0,x]//N Out[3]: {−1.51851, 0.508499, 1.2436, −0.116792 − 1.43845i, −0.116792 + 1.43845i}

在Mathematica中Root指令為傳回多項式f(x) = 0的第k個根,其用法為Root[f,k]。所以要傳回%1的 第二個根有以下兩種方式。

CHAPTER 2. 非線性最佳化

25

以Solve方式傳回第2個根 In[4]: Solve[x^5-4*x+2==0,x][[2]]//N Out[4]: {x → 0.508499}

以Root方式傳回x5 − 4x + 2 = 0所有根 In[5]: (Root[x^5-4*x+2,x,#]//N)&/@{1,2,3,4,5} Out[5]: {−1.51851, 0.508499, 1.2436, −0.116792 − 1.43845i, −0.116792 + 1.43845i}

以Cases傳回實數根 In[6]: Cases[sol,_Real] Out[6]: {−1.51851, 0.508499, 1.2436}

以Select傳回實數根 In[7]: Select[sol,#∈Reals&] Out[7]: {−1.51851, 0.508499, 1.2436}

繪出函數與x軸交點圖形 In[8]: Plot[x^5-4x+2,{x,-2,2},Epilog->{Red,PointSize[Large], Point[{#,0}]&/@Cases[sol,_Real]}] Out[8]: 10

5

-2

1

-1

-5

2

2.1 方程式求解

26

  x 2 + y2 = 1 範例 2-3. 解聯立方程組  |x| + |y| = 1

以Solve求解,可得四組解依序為 In[1]: sol={x,y}/.Solve[{Abs[x]+Abs[y]==1,x^2+y^2==1},{x,y}] Out[1]: {{−1, 0}, {0, −1}, {0, 1}, {1, 0}}

以Select傳回x > 0及y > 0的解 In[2]: Select[sol,#[[1]]>=0&&#[[2]]>=0&] Out[2]: {{0, 1}, {1, 0}}

繪出聯立方程組交點 In[3]: ContourPlot[{Abs[x]+Abs[y]==1,x^2+y^2==1},{x,-1,1},{y,-1,1}, Epilog->{Red,PointSize[Large],Point[sol]}] Out[3]: 1.0

0.5

0.0

-0.5

-1.0 -1.0

-0.5

0.0

0.5

1.0

2.1.2 FindRoot 在Mathematica中函數求數值解的指令為FindRoot,該指令的用法有以下幾種: 1. FindRoot[lhs == rhs, {x, a}]:以x = a為起始值尋找左右兩方程式交點的數值解。

CHAPTER 2. 非線性最佳化

27

2. FindRoot[f, {x, a}]:以x = a為起始值尋找方程式f的數值解。必須注意的是,該指令預設為求 解f = 0,若要求解其他數值可以f == c定義。 3. FindRoot[{f1 , f2 , . . . }, {{x, a1 }, {y, a2 }, . . . }]:以(x, y, . . . )為起始值尋找聯立方程 組(f1 , f2 , . . . )的數值解。 FindRoot指令中預設以Newton Method做為預設的搜尋方法,假設聯立方程組 fi (X) = 0, i = 1, 2, . . . , m 在給定Xk 時,由泰勒展開式可知 ( ) ( )( ) fi (X) ≈ fi Xk + ∇fi Xk X − Xk , i = 1, 2, . . . , m 由於fi (X) = 0, i = 1, 2, . . . , m,故可知 ( ) ( )( ) fi Xk + ∇fi Xk X − Xk = 0 經移項整理後,可求得

[ ( )]−1 ( k ) X = Xk − ∇fi Xk fi X

所以可求得單變量與多變數Newton Metom的迭代計算過程間遞迴關係式如下: xk+1 = xk − 及

f(xk ) f ′ (xk )

[ ( )]−1 ( k ) Xk+1 = Xk − ∇fi Xk fi X

[ ( )] 其中 ∇fi Xk 為Jacobian。為避免迭代過程發散,建議在求解之前先繪製函數圖形以利設定起始值; 起始值可以單點設定,也可以一個區間,(x, min, max),作為其設定值。 範例 2-4. 求ex − x2 = 0

定義函數 In[1]: f[x_]:=Exp[x]-x^2; Out[1]:

2.1 方程式求解

28

繪製圖形以方便設定起始值 In[2]: Plot[f[x], {x, -2, 2}]; Out[2]: 3 2 1

-2

-1

1

2

-1 -2 -3 -4

以While自行編寫程式 In[2]: init=2;x=init; err=10;sol={}; While[err>10^(-6),x=N[x-f[x]/f’[x]];err=Abs[f[x]];AppendTo[sol,x]]; sol Out[2]: {2.21298,1.31291,-0.513828,-0.71937,-0.703567,-0.703467}

上式所使用的While為一般程式所使用的控制流程,在使用方式與一般程式無太大差別,但上式程式 的寫法無法發揮Mathematica真正的功能。上式中我們可以發現x=N[x-f[x]/f’[x]]為一個遞迴函數, 因此,我們在這邊可以NestList來將程式寫得更簡潔。

以NestList傳回逐次迭代值 In[2]: NestList[N[#-f[#]/f’[#]]&,2,6] Out[2]: {3,2.21298,1.31291,-0.513828,-0.71937,-0.703567,-0.703467}

若想直接求得方程式ex − x2 = 0的根,那我們亦可以NestWhile來求得 In[3]: init=2;f[x_]:=Exp[x]-x^2;g[x_]:=N[x-f[x]/f’[x]]; NestWile[g,init,Unequal,All] Out[3]: -0.703467

CHAPTER 2. 非線性最佳化

29

根據Newton Method前六次迭代的傳回數值繪製收斂過程 In[3]: myplot=Plot[{f’[#]*(x-#)+f[#],f[x]},{x,-3,5},PlotRange->{-5,15}, PlotStyle->{Thickness[0.003],Thickness[0.01]}, Epilog->{PointSize[0.02],Black,Point[{#,N[f[#]]}], Red,Point[{#,0}]}]&/@NestList[N[#-f[#]/f’[#]]&,3,5];

將myplot所得到的六個圖形以GraphicsGrid繪製成2 × 3的矩陣圖 In[4]: GraphicsGrid[{myplot[[{1, 2, 3}]], myplot[[{4, 5, 6}]]}] Out[4]: 15

15

15

10

10

10

5

5

5

2

-2

4

2

-2

4

-2

-5

-5

-5

15

15

15

10

10

10

5

5

5

2

-2

4

-5

2

-2 -5

4

-2

2

4

2

4

-5

利用FindRoot進行求解 In[4]: FindRoot[f[x],{x,3}] Out[4]: {x → −0.703467}

在使用函數FindRoot時,我們也可藉由指定參數EvaluationMonitor來要求將收斂過程輸出至指定字 串。

定義一個sol的一維陣列,並利用AppendTo這個指令將迭代過程加入sol中。 In[5]: sol={};FindRoot[f[x],{x,2},EvaluationMonitor:>AppendTo[sol, x]];sol Out[5]: {3.,2.21298,1.31291,-0.51383,-0.71937,-0.70357,-0.70347,-0.70347}

2.1 方程式求解

30

Mathematica也有提供一個繪製FindRoot迭代步驟圖的指令FindRootPlot。FindRootPlot所傳回資 料陣列包含三個元素,依序為收斂值,求解資訊 ,收斂步驟圖。

引入最佳化套件繪製求解步驟圖 In[6]: <
傳回收斂步驟圖 In[7]: FindRootPlot[f[x], {x, 3}, PlotStyle->{Thickness[.01],RGBColor[0.4,0,0.4]}][[3]] Out[7]: 10

8

6

4

2

-0.5

0.5

1.0

1.5

2.0

2.5

3.0

由圖形可知,收斂過程為x0 = 3 ⇒ x1 = 2.21298 ⇒ · · · ⇒ x7 = −0.703467

傳回求解資訊 In[9]: FindRootPlot[f[x], {x, 2}, PlotStyle->{Thickness[.01],RGBColor[0.4,0,0.4]}][[{1,2}]] Out[9]: {{x → −0.703467}, {Steps → 8, Residual → 8, Jacobian → 7}}

由輸出資料可知經由8次迭代計算後,x = −0.703467

CHAPTER 2. 非線性最佳化

31

範例 2-5. 求解聯立方程組   x2 + y2 = 1  y − xex = 0

首先定義函數f(x, y)和g(x, y) In[1]: f[x_,y_]:=x^2+y^2-1;g[x_,y_]:=y-x*Exp[x]; Out[1]: 由圖形可了解交點有兩處 In[2]: ContourPlot[{f[x,y],g[x,y]},{x,-1.5,1.5},{y,-1.5,1.5}] Out[2]: 1.5

1.0

0.5

0.0

-0.5

-1.0

-1.5 -1.5

-1.0

-0.5

0.0

0.5

1.0

1.5

首先計算Jacobian In[3]: J=D[{f[x,y],g[x,y]},{{x,y}}] Out[3]: {{2x, 2y}, {−ex − ex x, 1}}

[ ( )]−1 ( k ) 定義 ∇fi Xk fi X ,其中"."在Mathematica中為矩陣相乘符號 In[4]: delta[x_,y_]=Inverse[J].{f[x,y],g[x,y]} { ( ( )) } −1 + x2 + 2ex xy − y2 2xy + ex −1 + y2 + x −1 + (−1 + x)x + y2 , Out[4]: 2 (x + ex (1 + x)y) 2 (x + ex (1 + x)y)

2.1 方程式求解

32

分別以(1, 0.5)和(−1, 0.5)為起始值利用NestWhile傳回數值解 In[5]: NestWhile[N[#-Apply[delta,#]]&,#,Unequal,All]&/@{{1,0.5},{-1,0.5}} Out[5]: {{0.513489,0.858096},{-0.930244,-0.366942}}

上式所求得的解之所以有差異,主要原因為起始值所導致。

繪出最佳解 In[6]: ContourPlot[{f[x,y],g[x,y]},{x,-1.5,1.5},{y,-1.5,1.5}, Epilog->{Red,PointSize[Large], Point[{x,y}/.FindRoot[{f[x,y],g[x,y]},{x,#},{y,#}]&/@{1,-1}]}] Out[6]: 1.5

1.0

0.5

0.0

-0.5

-1.0

-1.5 -1.5

-1.0

-0.5

0.0

0.5

1.0

1.5

定義一個sol的二維陣列,並利用AppendTo將以(1, 0.5)為起始值的迭代過程加入sol中。 In[7]: sol={};FindRoot[{f[x,y],g[x,y]},{x,1},{y,0.5}, EvaluationMonitor:>AppendTo[sol,{Length[sol],x,y}]];sol//TableForm Out[7]: 0 1 2 3 4 5 6 7

0.1 0.5 0.897833 1.080430 0.291842 0.639567 0.586557 0.900495 0.518046 0.859091 0.513507 0.858098 0.513489 0.858096 0.513489 0.858096

CHAPTER 2. 非線性最佳化

33

分別以(1, 0.5)和(−1, 0.5)為起始值利用FindRoot求解聯立方程組 In[8]: FindRoot[{f[x,y],g[x,y]},{x,#[[1]]},{y,#[[2]]}]&/@{{1,0.5},{-1,0.5}} Out[8]: {{x → 0.513489, y → 0.858096}, {x → −0.930244, y → −0.366942}}

引入最佳化套件繪製求解步驟圖 In[9]: <
繪製求解的步驟圖 In[10]: FindRootPlot[{f[x,y],g[x,y]},{{x,1},{y,0.5}}][[3]] Out[10]: 0.9

0.8

0.7

0.6

0.5 0.6

0.7

0.8

0.9

1

傳回求解資訊,由輸出資料可知經由7次迭代計算後,(x, y) = (0.513489, 0.858096) In[11]: FindRootPlot[{f[x,y],g[x,y]},{{x,1},{y,0.5}}][[{1,2}]] Out[11]: {{x->0.513489,y->0.858096},{Steps->7,Residual->7,Jacobian>6}}

2.2 非線性最佳化

34

2.2 非線性最佳化 在微積分中,我們知道目標函數f (X)若存在極值,則極值必發生在∇f (X) = 0或不存在的點。 當∇f (X) = 0有解析解,我們可以用Solve來求得臨界點;反之,若∇f (X) = 0只有數值解,則可 用FindRoot來解聯立方程組以求得臨界點。 範例 2-6. min f(x1 , x2 ) = 100(x2 − x21 )2 + (1 − x1 )2 x1 ,x2

定義函數f(x1 , x2 ) In[1]: f[x1_,x2_]:=100*(x2-x1^2)^2+(1-x1)^2

繪出函數3D立體圖 In[2]: Plot3D[f[x1,x2],{x1,-2,2},{x2,-2,2} Out[2]:

2000 1500

2

1000 1

500 0 -2

0 -1 0

-1 1 2 -2

計算梯度 In[3]: g=D[f[x1,x2],{{x1,x2}}] { ( ) ( )} Out[3]: −2(1 − x1) − 400x1 −x12 + x2 , 200 −x12 + x2

計算臨界點 In[4]: {x1,x2}/.FindRoot[D[f[x1,x2],{{x1,x2}}],{x1,1},{x2,1}] Out[4]: {1., 1.}

CHAPTER 2. 非線性最佳化

35

計算海賽矩陣 In[5]: h=D[f[x1,x2],{{x1,x2}},{{x1,x2}}] {{ ( ) } } Out[5]: 2 + 800x12 − 400 −x12 + x2 , −400x1 , {−400x1, 200}

計算海賽矩陣各階行列值 In[6]: Det[h[[Table[i,{i,1,#}],Table[i,{i,1,#}]]]]&/@{1,2}/. FindRoot[D[f[x1,x2],{{x1,x2}}],{x1,1},{x2,1}] Out[6]: {802., 400.}

上式中應用到Map這個映射指令,在此也可利用Table達到相同的目的 In[7]: Table[Det[h[[Table[i,{i,1,k}],Table[i,{i,1,k}]]]],{k,2}]/. FindRoot[D[f[x1,x2],{{x1,x2}}],{x1,1},{x2,1}] Out[7]: {802., 400.}

由上式傳回之海賽矩陣行列值可知f(x1 , x2 )在{x1, x2} = {1., 1.} 有極小值,極小值可計算如下: In[8]: f[x1,x2]/.FindRoot[D[f[x1,x2],{{x1,x2}}],{x1,1},{x2,1}] Out[8]: 0.

範例 2-7.

min 2x1 x2 x3 − 4x1 x3 − 2x2 x3 + x21 + x22 + x23 − 2x1 − 4x2 + 4x3

x1 ,x2 ,x3

定義函數f(x1 , x2 , x3 ) In[1]: f[x1_,x2_,x3_]:=2x1*x2*x3-4x1*x3-2x2*x3+x1^2+x2^2+x3^2-2x1-4x2+4x3;

由於臨界點有五個,若採用FindRoot無法將此五組臨界點一次求出,在此可採用Solve In[1]: {x1,x2,x3}/.Solve[D[f[x1,x2,x3],{{x1,x2,x3}}]==0,{x1,x2,x3}] Out[1]: {{0, 1, −1}, {0, 3, 1}, {1, 2, 0}, {2, 1, 1}, {2, 3, −1}}

2.2 非線性最佳化

36

計算海賽矩陣 In[2]: h=D[f[x1,x2,x3],{{x1,x2,x3}},{{x1,x2,x3}}]/. Solve[D[f[x1,x2,x3],{{x1,x2,x3}}]==0,{x1,x2,x3}];

計算海賽矩陣各階行列值。由海賽矩陣可知,上述解只有第三組為極小值,其餘皆為鞍點。 In[2]: Table[Det[h[[m,Table[i,{i,1,#}],Table[i,{i,1,#}]]]]&/@{1,2,3},{m,1,5}] //TableForm Out[2]: 2 2 2 2 2

0 0 4 0 0

−32 −32 8 −32 −32

計算極小值 In[3]: f[x1, x2, x3]/.Solve[D[f[x1,x2,x3],{{x1,x2,x3}}]==0,{x1,x2,x3}][[3]] Out[3]: −5

2.2.1 無限制條件下最佳化求解 然而當目標函數是包含多變數時,求解聯立方程組∇f (X) = 0就更為複雜。所以我們需要一些有效率 的演算法來幫助求解。假設函數f (X),由泰勒展開式可知 1 f (X + △X) ≈ f (X) + (∇f (X))⊤ △X + △X⊤ H △ X 2 欲求f (X)極值,必要條件為 ∂f (X + △X) ≈ ∇f (X) +H △ X = 0 ∂△X 由於△X = Xk+1 − Xk ,Xk 為第k階段的迭代值 ( ) Xk+1 − Xk = △X = −H−1 ∇f Xk 所以第k + 1階段的迭代值為

( ) Xk+1 = Xk − 1 × H−1 ∇f Xk

CHAPTER 2. 非線性最佳化

37

以上的搜尋方式稱為牛頓法(Newton’s Method)。在這個推導中步長1,但實際演算法進行時容易造 成發散。為避免發生上述情況,我們以α取代1並求得使得f (X)有極大或極小的α值作為下一階段的迭代 值,即

( ) Xk+1 = Xk −αH−1 ∇f Xk

這種作法稱為修正牛頓法(Modified Newton’s Method)。 Mathematica提 供 了 一 些 求 解 最 佳 化 問 題 的 指 令 , 例 如FindMinimum、FindMaximum 、Minimize、Maximize、Minimize和 NMaximize來求解有限制情況和無限制情況下的極大極小化問 題。以上指令使用方式介紹如下: 1. FindMinimum[f(x),{x,x0 }]:以x = x0 為起始值求解函數f(x)的區域極小值 2. FindMinimum[f(x1 , x2 , . . . ),{x1 ,x10 },{x1 ,x10 },

. . . ]: 以(x10 , x20 , . . . )為 起 始 值 求 解

f(x1 , x2 , . . . )的區域極小值 3. FindMinimum[{f(x), 限制式},x]:求解f(x)在限制下的區域極小值,其中限制式可以是等式、不等 式以及邏輯條件 4. FindMinimum[{f(x1 , x2 , . . . ), 限制式},{x1 ,x1 , . . . }]:求解f(x1 , x2 , . . . )在限制下的區域極小值, 其中限制式可以是等式、不等式以及邏輯條件 5. Minimize[f(x1 , x2 , . . . ),{x1 ,x1 , . . . }]:求解f(x1 , x2 , . . . )的全域極小值 6. Minimize[{f(x1 , x2 , . . . ), 限制式},{x1 ,x1 , . . . }]:求解f(x1 , x2 , . . . )在限制下的全域極小值,其中 限制式可以是等式、不等式以及邏輯條件 7. NMinimize[f(x1 , x2 , . . . ),{x1 ,x1 , . . . }]:求解f(x1 , x2 , . . . )的全域極小值 8. NMinimize[{f(x1 , x2 , . . . ), 限制式},{x1 ,x1 , . . . }]:求解f(x1 , x2 , . . . )在限制下的全域極小值,其 中限制式可以是等式、不等式以及邏輯條件 9. NMinimize[f(x1 , x2 , . . . ),{x1 ,x1 , . . . }]:求解f(x1 , x2 , . . . )的全域極小值 10. NMinimize[{f(x1 , x2 , . . . ), 限制式},{x1 ,x1 , . . . }]:求解f(x1 , x2 , . . . )在限制下的全域極小值,其 中限制式可以是等式、不等式以及邏輯條件

2.2 非線性最佳化

38

Mathematica在進行FindMinimum時,可以指定以下幾種搜尋方式進行求解:Newton, QuasiNewton, LevenbergMarquardt, ConjugateGradient 及 PrincipalAxis。一般Mathematica以準牛頓法(QuasiNewton Method)進行迭代求解,所以收斂的速度較牛頓法為慢。然而牛頓法需要計算海賽矩陣的 反矩陣,如果海賽矩陣是奇異矩陣(singular matrix)或狀況不佳的矩陣(ill-conditioned matrix), 求反矩陣時會產生數值問題,應用上應該加以注意。若不指定迭代方式,當目標函數含有平方和 時,Mathematica則改以LevenbergMarquardt法進行迭代程序。當變數的起始值給定兩個時,則改以使 用主軸法。在這邊必須提醒的是,FindMinimum所求得的是區域極值,並不保證為全域極值。 若 以Minimize進 行 求 解 , 則 必 須 是 有 解 析 解 的 前 提 下 才 可 使 用 , 否 則 必 須 改 以NMinimize求 解。若以NMinimize進行求解,則可以指定以下幾種搜尋方式:NelderMead, DifferentialEvolution, SimulatedAnnealing, RandomSearch。在這邊必須提醒的是,Minimize或NMinimize所求得的通常是全 域極值,但並不保證一定是全域極值。 範例 2-8. min f(x) = 3x4 − 28x3 + 84x2 − 96x + 42 x

定義函數f(x) In[1]: f[x_]:=3x^4-28x^3+84x^2-96x+42

計算臨界點並繪出函數圖,由圖形可知函數f(x)的最小值為f(4) In[2]: Plot[f[x],{x,0,5},Epilog->{Red,PointSize[Large], Map[Point,{x,f[x]}/.Solve[f’[x]==0,x]]}] Out[2]: 40 30 20 10

1

2

3

4

5

-10 -20

使用FindMinimum以不同的起始值{0.5,1.5,3}求解 In[4]: FindMinimum[f[x],{x,#}][[1]]&/@{0.5,1.5,3} Out[4]: {5., 5., −22.}

CHAPTER 2. 非線性最佳化

39

由上式輸出可發現當起始值為0.5或1時,都只求得區域極值。

以NMinimize求解也只求得區域極小值 In[5]: NMinimize[f[x],x] Out[5]: {5., {x → 1.}}

以Minimize求解即可求得全域極值 In[6]: Minimize[f[x],x] Out[6]: {−22, {x → 4}}

範例 2-9. min f(x1 , x2 ) = 100(x2 − x21 )2 + (1 − x1 )2 x1 ,x2

定義函數f(x1 , x2 ) In[1]: f[x1_,x2_]:=100*(x2-x1^2)^2+(1-x1)^2 Out[1]:

計算梯度及海賽矩陣 In[2]: g=D[f[x1,x2],{{x1,x2}}];h=D[f[x1,x2],{{x1,x2},2}]; Out[2]:

以(0, 0)為起始值,利用修正牛頓法進行求解 In[3]: delta[x1_,x2_]=Inverse[h].g; sol=NestList[(#-a*delta@@#)/.FindRoot[D[f@@(#-a*delta@@#),a], {a,0},AccuracyGoal->6]&,{0,0},8];sol//TableForm Out[3]:

0 0.161262 0.367189 0.630157 0.807286 0.976581 0.997991 1.00003 1.

0 0 0.106009 0.380126 0.639082 0.951533 0.996209 1.00006 1.

2.2 非線性最佳化

40

利用上式所得資料繪出修正牛頓法求解的步驟圖 In[4]: ContourPlot[f[x1,x2],{x1,0,1},{x2,0,1},Epilog->{Green,Line[sol], Red,PointSize[Large],Point[sol]}] Out[4]: 1.0

0.8

0.6

0.4

0.2

0.0 0.0

0.2

0.4

0.6

0.8

1.0

以(0, 0)為起始值利用FindMinimum求解 In[5]: FindMinimum[f[x1,x2],{x1,0},{x2,0}] Out[5]: {0., {x1 → 1., x2 → 1.}}

FindMinimum使用各種方式進行求解,並傳回迭代次數 In[6]: (Clear[x1,x2];sol={};FindMinimum[f[x1,x2],{x1,0},{x2,0},Method->#, EvaluationMonitor:>AppendTo[sol,{Length[sol],x1,x2}]];Length[sol])& /@{Gradient,ConjugateGradient,InteriorPoint,QuasiNewton,Newton, LevenbergMarquardt,PrincipalAxis} Out[6]: {149, 57, 20, 30, 17, 15, 335}

引入最佳化套件繪製求解步驟圖 In[7]: <
CHAPTER 2. 非線性最佳化

41

由於目標函數包含平方和,故FindMinimum以LevenbergMarquardt法進行求解。由輸出資料可知 經由12次迭代計算後,(x∗ , y∗ ) = (1, 1) In[8]: FindMinimumPlot[f[x1,x2],{{x1,0},{x2,0}}][[{1,2}]] Out[8]: {{0., {x1 → 1., x2 → 1.}}, {Steps → 12, Function → 15}}

繪製求解的步驟圖 In[9]: FindMinimumPlot[f[x1,x2],{{x1,0},{x2,0}}][[3]] Out[9]: 1.0

0.8

0.6

0.4

0.2

0.0 0.0

0.2

0.4

0.6

0.8

1.0

由於在本範例中具有解析解,所以Minimize可順利求解 In[10]: Minimize[f[x1,x2],{x1,x2}] Out[10]: {0, {x1 → 1, x2 → 1}}

NMinimize使用各種方式進行求解,並傳回迭代次數 In[11]: (Clear[x1,x2];sol={};NMinimize[f[x1,x2],{x1,x2},Method->#, EvaluationMonitor:>AppendTo[sol,{Length[sol],x1,x2}]];Length[sol])& /@{NelderMead,DifferentialEvolution,SimulatedAnnealing,RandomSearch} Out[11]: {129, 2032, 264, 86}

2.2 非線性最佳化

42

( ) dp ∫ ∞ dK y 範例 2-10. T CU(y, R) = +h R+ −µ + (x − R)f(x)dx y 2 y R

定義成本函數 In[1]: TCU[y_,R_]:=d*K/y+h*(R+y/2-mu) +d*p/y*Integrate[(-R+x)*f[x],{x,R,Infinity}]; Out[1]:

定義常態分配 In[2]: dist=NormalDistribution[mu,sigma]; Out[2]:

定義常態分配機率密度函數 In[3]: f[x_]:=PDF[dist,x]; Out[3]:

定義各參數值 In[4]: {d,K,h,p,mu,sigma}={1000,100,2,10,50,2}; Out[4]:

以NMinimize求解,可求得期望成本最小值為640.304 In[5]: NMinimize[TCU[y,R], {y,R}] Out[5]: {640.304, {y → 317.098, R → 53.0534}}

最後,我們為參數d, K, h及p進行敏感性分析。敏感性分析的方式為針對每個參數進行-50%, -25%, 25%及50%的變動以觀察各參數對期望成本的影響。

建立敏感性分析所需參數資料 In[6]: w=Range[0.5,1.5,0.25];para={1000,100,2,10}; sen=Flatten[Table[para/.para[[i]]->para[[i]]*w[[j]],{i,3},{j,5}],1]; Out[6]:

CHAPTER 2. 非線性最佳化

43

傳回敏感性分析資料,並將資料資定給sendata In[7]: sendata=Block[{d=#[[1]],K=#[[2]],h=#[[3]],p=#[[4]],ans}, ans=NMinimize[{TCU[y,R],y>0&&R>0},{y,R}]; {ans[[1]],y/.ans[[2]],R/.ans[[2]]}]&/@sen; Out[7]:

建立各參數敏感性分析表格 In[8]: myexample[x_?IntegerQ]:=TableForm[Partition[data,5][[x]], TableHeadings->{If[#==3,ToString[0],ToString[(#-1)*25-50]<>"%"]&/@ Range[5],{"TCU","y","R"}}] Out[8]:

傳回d的敏感性分析 In[9]: myexample[1] Out[9]: -50% -25% 0 25% 50%

TCU y R 454.439 224.536 52.6838 555.317 274.755 52.9038 640.304 317.098 53.0534 715.147 354.407 53.1661 782.792 388.139 53.2562

Related Documents

Mathematica
May 2020 9
Mathematica
October 2019 15
Regression With Mathematica
December 2019 14

More Documents from ""

Mosiah 28
April 2020 24
April 2020 12
Alma 6
April 2020 27
April 2020 5
Alma 13
April 2020 12
May 2020 13