<style>
.red {
color: red;
}
.blue{
color:blue;
}
</style>
# 蒙地卡羅方法緣由
<img src="https://hackmd.io/_uploads/ryLLhs-Yh.png" height =400; style="display:block; margin-left: 0;auto; width:100%" />
<figcaption>(戰爭促進了科學的發展,但卻也奪走了無數條生命...)</figcaption>
<br>
1940年代,美國新墨西哥州內的洛斯阿拉莫斯國家實驗室( Los Alamos National Laboratory ) 的科學家們正秘密地進行和核武器相關的研究計畫。當時他們正在研究核武器核心中的中子擴散問題(Neutron Diffussion),儘管他們已經掌握了多數必要的資料(例如中子在和原子核發生碰撞前平均移動距離等...... ),然而該問題其中涉及的計算量過於龐大,無法用 deterministic 的數學方法來解決,然而 John von Neumann, Stanisław Marcin Ulam 和 Nicholas Constantine Metropolis 等人卻讓這件事情有了進展...。
當時擅長研究隨機問題的 Stanisław Marcin,在某次聽聞了物理學家Nicholas Constantine Metropolis 等人的會議報告後,便和同時也在場的 John von Neumann 討論起了如何用"隨機模擬"的方法去解決該問題。
之後 John von Neumann 和 Nicholas Constantine Metropolis 等人更是使用史上第一台電子數位電腦 ENINC,配合該方法,克服了核分裂問題所涉及的龐大計算量,此方法之後更進一步用於製造氫彈的研究中,可以說是"曼哈頓計畫"中最核心的模擬方法之一!!!
但因為這是秘密研究,所以就像特務一樣,必須有個代號來稱呼 :sunglasses:,而 Ulam 的叔叔常常跟親戚借錢去摩納哥的蒙地卡羅賭場賭博(~~想必是常常輸錢,不然怎麼會跟親戚借錢~~)且這個方法又跟機率有關,於是 Nicholas Constantine Metropolis 惡趣味地將其取名為 "蒙地卡羅",這便是"蒙地卡羅方法"的由來。
之後在核武器的計畫結束前,更是有段和這方法有關的小插曲,物理學家費米(Enrico Fermi)在蒙地卡羅方法發明後才參與核武器的相關計畫,然而他加入後表示在十幾年前他已使用類似的方法,所以費米若是在一開始或早點加入,應該會更早完成計算 XDD
時至今日,蒙地卡羅方法已不侷限於核分裂的研究中,該方法廣泛地用於金融工程,機器學習,計算物理等多個領域中,接著就讓我們來體驗一下這神奇的方法吧~~~
# 瘋狂投針的人...
在開始介紹蒙地卡羅方法之前,讓我們再提一個人,那就是十八世紀的法國博物學家布豐。
某天他不知道發生什麼事了,對著平行等距的木地板投了一根長度小於木板寬度的針,接著再去看這根針跟木地板組合出來的平行線有沒有相交,然後他重複了此行為很多次,並去計算針和平行線相交的機率。
<img src="https://hackmd.io/_uploads/HJJj2lXY3.png" height =200; style="display:block; margin:auto; width:60%" />
<figcaption>(假設投了 n 次針,有 h 次與線相交,則會發現當 n 足夠大時, 2Ln/th 趨近於 Pi)</figcaption>
</br>
筆者我覺得這件事本身其實蠻瘋狂的,誰吃飽沒事會一直去投針= =,然後去計算針和木板組出的平行線相交的次數阿 !!! :thinking_face: 。重點是,隨著投著的次數越多次,算出來的機率值竟然和 $\pi$ 有關係,因而求得了 $\pi$ 的近似值,只能說天才和瘋子只有一線之隔 XD

# 大數法則
由此可見,大至核分裂,小至投針問題,都能看見機率的蹤跡。
實際上,這兩件毫不相干的事情背後都涉及到了下方的"大數法則",也就是蒙地卡羅方法背後的原理:
:::info
$Theorem(Strong\ Law \ of\ Large \ Number)$ :
Let $\{X_n\}$ be a sequence of $iid$ random variable with $E(|X_1|)<\infty$,
then we have
$$\frac{S_n}{n}\overset{a.s.}\to \ E(X_1)\ \ as \ \ n \to \infty, \ where \ S_n=\sum_{i=1}^{n}X_i.$$
:::
我相信知道怎麼證明上述定理的人應該不多(~~例如Truncate手法,但不是數學系的學生不需要讀懂證明~~),白話來說,就是隨著實驗的次數越多,計算出來的平均結果會越接近其期望值,最簡單的例子就是你投一枚公正的硬幣 N 次,當 N 夠大時,硬幣出現正面的次數除以 N 會靠近1/2,
不過拜於近代電腦快速發展所賜,我們現今已可以在個人電腦簡單快速地使用蒙地卡羅方法(~~不需要自己下去投針~~),接下來就讓我們簡單地用 Python 加上此方法來估計 $\int_{0}^{1}x^ndx,n=1,2,3...$吧( 以 $x^2$ 為例 )。
# Toy Example: 估計 x^n 在 [0,1] 上的積分, n =1,2,3, ....(以 x^2 為例)
### Method1 撒豆子
<img src="https://hackmd.io/_uploads/Hk49rjSt3.png" height =300; style="display:block; margin:auto; width:60%" />
</br>
如上圖所示,令 $f(x)=x^2$. $x=1$ 和 $y=0$圍成的區域為 A。想像你跟布豐一樣,準備從一袋裝滿豆子的袋子拿出針來均勻地撒在 [0,1]X[0,1],隨著撒著的豆子數量越多,就像你投擲一枚公正的硬幣一樣,你會發現
<font class='red'>$$落在區域A 的豆子數/所有的豆子數 \approx P(豆子落在區域A的機率)。$$</font>
而 P(豆子落在區域A的機率)可以很直覺的想成 $\frac{Area(A)}{Area([0,1]X[0,1])}= Area(A)$,(或是說$P(A)\equiv\mu(A)$ defines a probability measure on [0,1]x[0,1], where $\mu$ is Lebesgue measure and $A$ is a measurable subset in [0,1]x[0,1].)
因此我們投的豆子數量越多,越能得到 $Area(A)=\int_{0}^{1}x^2dx$ 的近似值.
P.S. Let $\{X_i\}$ be a seq of iid r.v. with unif distribution on $[0,1] \times [0,1]$, $g(x) = 1_{A}(x), x \in[0,1]\times[0,1]$, indicator function of Area A, then by law of large number, $$\frac{\sum_{i=1}^{n}g(X_i)}{n}\overset{a.s.}\to \ E(g(X_1))=P(X_1\in A)=Area(A)\ \ as \ \ n \to \infty. $$
```python=
import random as rd
import matplotlib.pyplot as plt
import numpy as np
# 取得落在 [0,1]x[0,1] 的點 Point (x,y)
def getRandomPoint():
x = rd.random()
y = rd.random()
return (x,y)
# 蒙地卡羅模擬,n:numberOfTrials, k: power of x^k, showPlot:布林值,決定是否要把圖畫出來
def Monte(n, k, showPlot = False):
fig, ax = plt.subplots()
#落在目標區域面積裡的次數
inTheArea = 0
#收集落在區域內的點,For 繪圖用
pointsToDraw = []
# 撒 n 次豆子
for i in range(n):
# 豆子落地於[0,1]x[0,1] 的點
(x,y) = getRandomPoint()
# 檢查是否有撒入目標區域面積內,有的話落在目標區域面積裡的次數++
if(y <= x**k ):
inTheArea += 1
pointsToDraw.append((x,y))
print(f'x^{k} 於 [0,1] 區間面積估計為:', inTheArea/n,', numOfTrials:',n)
if(showPlot):
# 畫出 y= x^k 和 [0,1]X[0,1] 圍成的區域
x = np.linspace(0,1,1000)
y = x**k
ax.plot(x,y, marker='o', markersize=1, color = 'g')
ax.plot(x, 0*x, marker='o', markersize=1, color = 'g')
ax.plot(0*x+1, x, marker='o', markersize=1, color = 'g')
# 將落在區域內的點畫出來
for point in pointsToDraw:
ax.plot(point[0], point[1], marker='o', markersize=0.5, color = 'r')
plt.show()
return inTheArea/n
# 使用蒙地卡羅方法估計 x^2 在 [0,1] 區間的積分
Monte(10000,2,False)
```
若我們將畫圖的 flag 打開(改成 True),則可以得到下面的圖,綠色的線為區域A的邊界,紅點代表落在區域A內的點。

#### 執行結果

### Method2 大數法則 (Law of Large Number)
令 $g(x) = x^2$, $X_i, i=1,2,3,...$ 為獨立同分布的變數且 $X_1\sim U(0,1),$ uniform distribution on [0,1],則我們會有$E(|g(X_1)|) = E(g(X_1))<E(1)=1<\infty.$
於是根據大數法則,我們知道
$$\frac{\sum_{i=1}^{n}g(X_i)}{n}\overset{a.s.}\to \ E(g(X_1))=\int_{0}^{1}x^2dx \ \ as \ \ n \to \infty. $$
``` python
import random as rd
# 取得落在 [0,1] 區間的隨機點 x
def get_Random_X():
return rd.random()
# 蒙地卡羅模擬,n:numberOfTrials, k: power of x^k
def Monte(n,k):
sumOf_xWithPowerK = 0
for i in range(n):
x = get_Random_X()
sumOf_xWithPowerK += x**k
print(f'x^{k} 於 [0,1] 區間面積估計為:', sumOf_xWithPowerK/n,', numOfTrials:',n)
return sumOf_xWithPowerK/n
# 執行蒙地卡羅方法
Monte(10000,2)
```
#### 執行結果

可以發現上述兩種方法估計的東西些微不同,一個方法是去算落在區域內的個數,另外一個是去算有點類似黎曼合的Sum,但是都對 $\displaystyle\int_{0}^1x^2dx = 1/3$ 做了近似的估計。
# Observation...
1. 將方法 1 撒豆子落在區域 A 的判別方式 ($y<x^2$) 換成 ($x^2+y^2\leq1$),則可以求得 $\displaystyle\frac{\pi}{4}$ 的近似值。同理,可以簡單地用類似的方式求橢圓$\displaystyle\frac{x^2}{a^2}+\frac{y^2}{b^2}=1$的面積,三維單位球的體積等...。
2. 上述的範例用的隨機變數是 Unif distribution,實際上從大數法則定理的敘述可以發現蒙地卡羅方法選用的random variable 不一定要 Unif distribution,
3. 用蒙地卡羅計算高維度的積分概念和上述一維的計算是類似的,例如給定獨立同分布的Random Vector $\{X_n\}$,且 $X_1$ 的 pdf 是 $\phi(x),g(x):\mathbb{R}^n \to\mathbb{R}$ 是 measurable 且 $E(g(X_1)) =\displaystyle\int_{\mathbb{R}^n}g(x)\phi(x)\ dx<\infty,$則根據大數法則,$$\frac{\sum_{i=1}^{n}g(X_i)}{n}\overset{a.s.}\to \ E(g(X_1))\ \ as \ \ n \to \infty. $$
可以發現今天若是期望值的計算是若是非常複雜的,或是說 n 是個非常大的數字,例如氣體的分子數,則可以用蒙地卡羅方法去進行估計 :))
# 參考資料
1. https://foundation.nmns.edu.tw/writing/past.php?v=1&id=192
2. https://en.wikipedia.org/wiki/Monte_Carlo_method
3. https://sites.google.com/a/g2.nctu.edu.tw/unimath/2021-02/%E6%A9%9F%E7%8E%87%E9%97%9C%E6%96%BC%E5%B8%83%E8%B1%90%E6%8A%95%E9%87%9D-%E7%82%BA%E4%BB%80%E9%BA%BC%E5%8F%B2%E4%B8%8A%E5%AF%A6%E9%A9%97%E6%9C%80%E7%B2%BE%E6%BA%96%E7%9A%84%E6%95%B8%E5%AD%B8%E5%AE%B6%E6%8B%89%E6%92%92%E9%87%8C%E5%B0%BC%E8%A2%AB%E6%87%B7%E7%96%91%E4%BD%9C%E5%BC%8A%E5%91%A2
4. https://www.value-at-risk.net/generalizing-the-crude-monte-carlo-estimator/4