引用自:
GAMES101-现代计算机图形学入门-闫令琪_哔哩哔哩_bilibili
概率论的介绍
离散随机变量
连续随机变量与概率密度函数(PDF)
因为是连续的,所以它的期望是用积分计算的
从变量与分布与期望,到函数与自变量与分布与期望
这个期望怎么求?
只要是求期望,就是概率*值,然后累加,结束;套上图里的那个EX的公式。
这一段,是为了干啥?计算蒙特卡洛积分的时候会用到的。
蒙特卡洛积分
它是做什么的?计算定积分的结果的。
在积分不好解,只需要一个最后数值结果的时候可以用。
弹幕:
【总结一下,用数值方法去算一个复杂定积分的近似值】
【蒙特卡洛积分:我承认我有赌的成分】
【这看起来和黎曼积分是一回事】
【非均匀采样有 pdf 的时候就不是一回事了】
【所以和黎曼积分不一样的是黎曼积分是从小到大所有的位置的值都加起来 而蒙特卡洛积分是随机采样的值平均?】
【采样本身有概率随机性】
具体的方法:
随便按一个概率密度去采样
应用举例:
按一个均匀的概率密度采样:
还有一些注意事项
在x上积分,就得在x上采样——很直白,但是以后很有用
其它网站的相关内容
为什么是F/P?
在视频里,关于上图里的公式为什么要/p,弹幕进行了激烈的讨论:
【为什么是随机采样,不是均匀采样呢】
【你可以用不同的概率分布采样,均匀还是正态分布都可以】
【这里是样本均值收敛于期望,应该是中心极限而不是大数】
【没搞懂为什么f(x)要除以p(x),除了就得出了啥】
【就是多次求面积,再平均一下】
【为什么fx除以px?算面积不是要乘吗?】
【不是求面积和么,怎么变成除p(x)了】
【这里解释一下MC estimator的除以p(x)的问题, 蒙特卡洛法求积分其实和蒲丰投针有些类似, 通过频率来估算概率,基于大数定律, 这里除以p(x)是为了使得其数学期望等于所求积分】
【乘以(b-a)可以看做除以 1 / (b-a)。 而前面讲过了随随机在曲线上采样因此随机到每个点的概率都是1 / (b-a)。 扩展到更一般的随机情况则有 1 / pdf(x)。】
【根据nvidia的gpu gem3 chapter20:除以pdf是一种加权,因为高pdf区域中的一个样本仅相当于均匀分布中的一小部分样本】
【简单理解就是p越大这里就会有越多这个fx值,那为了公平求平均时就要除以出现次数】
【当某个区间的p变为原来的k倍时,随机变量出现在这个区间的概率也扩大k倍,因此相当于在这个区间内采样次数扩大k倍,求平均就要除以k】
【f(x)/p(x)=f(x)x/p(x)x,因为p(x)x=1,所以有f(x)/p(x)=f(x)x】
【概率密度不平均,在有的地方大,采样的结果除以概率密度,来消除这种不平均的影响】
【就是f(x)的平均值 。然后用概率密度去修正】
【直观但不严谨的说,就是该点满足采样的百分之多少,最后把这些求平均就得到了总体的百分比】
【看不懂的去看ray tracing in one weekend 第三本】
【pdf很小,那么这一样本出现的概率也越小,不加权的话就会导致最后的结果偏向于pdf大的样本而不是正确的估计值】
【并不是经验得出的,从概率论上可以证明,没有理解的可以翻一下概率统计的课本】
【因为要公平对待整个定义域上的数值,所以出现概率越大的值占得权重应该相对较小, 所以是除以】
【f(x)这个pdf 采样通常认为比较困难,所以用另一个容易采样的pdf p(x)做 reweighting,然后通过对p(x)采样对积分进行估计】
【重要性采样】
【设g(x) = f(x) / p(x), 求g(x)的期望就是f(x)在[a, b]上的积分,再用大数定律得到n趋于无穷收敛于期望】
【蒙特卡洛说 你要积分的结果 我给你蒙一个】
【蒙特卡洛积分 你们对那个公式求一下期望就会懂了】
那末,为什么?
按照弹幕的说法求期望试试吧!
参照这个链接:
看懂蒙特卡洛积分(二) 蒙特卡洛估计与重要性采样 - 知乎 (zhihu.com)
写了这些,我是小白,不会数学,所以也不知道写的对不对。
上面那个是倒推的,有顺着推的吗?
这个链接里:(61条消息) 从期望到蒙特卡洛再到抽样(MCMC学习和梳理)_surtol的博客-CSDN博客_蒙特卡洛求期望
引用了一个证明的链接:
蒙特卡洛积分法(一) - 闪之剑圣 - 博客园 (cnblogs.com)
我觉得大概是这样写的:
这个网页,解释的更清楚:
至于,这写的对不对?我是小白……
实际使用
import random
import math
count = 1000
sum = 0.0
pi = 3.14159265
for i in range(count):
p = 1.0 / pi #这里按均匀分布来进行采样,所以PDF是常数函数,区间面积为1,区间宽度为pi,所以PDF恒为1.0/pi
x = random.uniform(0.0, pi)
sum += math.sin(x)/p
sum /= count
print ("蒙特卡洛积分下的数值解:",sum)
print ("牛————莱公式下的解析解:",math.cos(0) - math.cos(pi))
差不多吧……