赞
踩
对于光子学、经济学、视频游戏开发和工程学等许多依赖数值的领域来说,求解复杂积分是必需的。
I
=
∫
a
b
g
(
x
)
d
x
I=\int_a^b g(x) d x
I=∫abg(x)dx
许多有趣的问题都无法通过分析求解积分,因此必须应用替代数值方法来找到适当的估计。 值得注意的是,通过应用数值方法(例如蒙特卡洛积分),我们并不是“求解”积分,而是对积分值进行适当的估计。 对于许多应用来说,这种差异可以忽略不计,但应牢记这种区别,特别是在考虑当前问题所需的准确度时。
“蒙特卡洛方法”的现代变体可以追溯到 20 世纪 40 年代的洛斯阿拉莫斯实验室,该实验室最初开发该方法是为了帮助模拟核裂变过程,特别是模拟裂变材料中中子的平均自由程 。 我们没有确定地解决中子的扩散路径,而是应用了统计采样方法,而且效果非常好。 从那时起,“蒙特卡罗方法”一词根据其应用领域的不同而具有广泛的含义。 然而,蒙特卡罗的所有应用都有一个共同的基本原理,即使用统计采样来解决确定性难以解决的问题。
蒙特卡罗积分器
首先,我们可以使用蒙特卡罗检查积分的期望值。 传统上,函数 g(x) 的期望值可以通过首先乘以其概率密度函数 f(x),然后在所需区域上进行积分来计算:
E
[
g
(
x
)
]
=
∫
a
b
g
(
x
)
f
(
x
)
d
x
E[g(x)]=\int_a^b g(x) f(x) d x
E[g(x)]=∫abg(x)f(x)dx
或者,我们可以通过对积分极限之间的均匀分布重复采样来使用蒙特卡罗近似来获得期望值。
E
[
g
(
x
)
]
=
1
n
∑
i
=
1
n
f
(
x
i
)
E[g(x)]=\frac{1}{n} \sum_{i=1}^n f\left(x_i\right)
E[g(x)]=n1i=1∑nf(xi)
其中,
x
i
∈
[
a
,
b
]
x_i \in[a, b]
xi∈[a,b]。
如前所述, x i x i xi 是从每个唯一 n = 1 , 2 , 3 n=1,2,3 n=1,2,3 等的限制 a a a 和 b b b 之间的均匀分布中采样的值。这种方法对 f ( x ) 进行采样 f(x) 进行采样 f(x)进行采样 函数并使用大数定律来找到收敛的期望值。
乘法因子
1
/
n
1 / n
1/n 有时给出为
1
/
(
n
−
1
)
1 /(n-1)
1/(n−1) 因为
n
n
n 个样本确实有
n
−
1
n-1
n−1 个自由度,但是当
n
n
n 很大时
1
/
n
1 / n
1/n 和
1
/
(
n
−
1
)
1 /(n-1)
1/(n−1) 之间的差异可以忽略不计。给定期望值估计量的形式,扩展到积分的估计很简单。期望值公式乘以积分限制的范围,如下所示。
F
=
(
b
−
a
)
1
n
∑
i
=
1
n
f
(
x
i
)
F=(b-a) \frac{1}{n} \sum_{i=1}^n f\left(x_i\right)
F=(b−a)n1i=1∑nf(xi)
其中,
x
i
∈
[
a
,
b
]
x_i \in[a, b]
xi∈[a,b]。
积分估计使用期望值估计器以及由积分限制确定的矩形宽度来查找积分面积/体积的近似值。我们可以用一个相对简单的例子来测试它,取积分:
∫
1
5
x
4
e
−
x
d
x
\int_1^5 x^4 e^{-x} d x
∫15x4e−xdx
我们可以编写一个简短的 C++ 程序来应用蒙特卡罗积分技术,样本大小为 n = 200。
#include <iostream> #include <cstdlib> #include <cmath> double myFunction(double x); double monteCarloEstimate(double lowBound, double upBound, int iterations); int main() { double lowerBound, upperBound; int iterations; lowerBound = 1; upperBound = 5; iterations = 200; double estimate = monteCarloEstimate(lowerBound, upperBound,iterations); printf("Estimate for %.1f -> %.1f is %.2f, (%i iterations)\n", lowerBound, upperBound, estimate, iterations); return 0; } double myFunction(double x) //Function to integrate { return pow(x,4)*exp(-x); } double monteCarloEstimate(double lowBound, double upBound, int iterations) { double totalSum = 0; double randNum, functionVal; int iter = 0; while (iter<iterations-1) { randNum = lowBound + (float(rand())/RAND_MAX) * (upBound-lowBound); functionVal = myFunction(randNum); totalSum += functionVal; iter++; } double estimate = (upBound-lowBound)*totalSum/iterations; return estimate; }
它应该打印一些接近于:
Estimate for 1.0 -> 5.0 is 13.28, (200 iterations)
我们必须考虑蒙特卡罗积分技术隐含的方差。蒙特卡罗积分方案的方差遵循计算某个随机变量方差的传统过程。如果我们继续前面对函数
g
(
x
)
g(x)
g(x) 求积分的表示法,则
g
(
x
)
g(x)
g(x) 积分期望值的方差可以给出。为了简洁起见,我将跳过蒙特卡罗积分方案固有的标准差关系的推导。如果我们继续采用对函数
g
(
x
)
g(x)
g(x) 进行积分的表示法,并且积分的期望值为
E
[
g
(
x
)
]
E[g(x)]
E[g(x)],则标准差的关系可以给出为:
σ
n
=
V
E
[
g
(
x
)
2
]
−
E
[
g
(
x
)
]
2
n
−
1
\sigma_n=V \sqrt{\frac{E\left[g(x)^2\right]-E[g(x)]^2}{n-1}}
σn=Vn−1E[g(x)2]−E[g(x)]2
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。