如上图所示,计算区间[a  b]上f(x)的积分即求曲线与X轴围成红色区域的面积。下面使用蒙特卡洛法计算区间[2  3]上的定积分:∫(x2+4*x*sin(x))dx

 # -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt def f(x):
return x**2 + 4*x*np.sin(x) def intf(x):
return x**3/3.0+4.0*np.sin(x) - 4.0*x*np.cos(x) a = 2;
b = 3; # use N draws
N= 10000 X = np.random.uniform(low=a, high=b, size=N) # N values uniformly drawn from a to b
Y =f(X) # CALCULATE THE f(x) # 蒙特卡洛法计算定积分:面积=宽度*平均高度
Imc= (b-a) * np.sum(Y)/ N; exactval=intf(b)-intf(a) print "Monte Carlo estimation=",Imc, "Exact number=", intf(b)-intf(a) # --How does the accuracy depends on the number of points(samples)? Lets try the same 1-D integral
# The Monte Carlo methods yield approximate answers whose accuracy depends on the number of draws.
Imc=np.zeros(1000)
Na = np.linspace(0,1000,1000) exactval= intf(b)-intf(a) for N in np.arange(0,1000):
X = np.random.uniform(low=a, high=b, size=N) # N values uniformly drawn from a to b
Y =f(X) # CALCULATE THE f(x)
Imc[N]= (b-a) * np.sum(Y)/ N; plt.plot(Na[10:],np.sqrt((Imc[10:]-exactval)**2), alpha=0.7)
plt.plot(Na[10:], 1/np.sqrt(Na[10:]), 'r')
plt.xlabel("N")
plt.ylabel("sqrt((Imc-ExactValue)$^2$)")
plt.show()

>>>

Monte Carlo estimation= 11.8181144118    Exact number= 11.8113589251

从上图可以看出,随着采样点数的增加,计算误差逐渐减小。想要提高模拟结果的精确度有两个途径:其一是增加试验次数N;其二是降低方差σ2. 增加试验次数势必使解题所用计算机的总时间增加,要想以此来达到提高精度之目的显然是不合适的。下面来介绍重要抽样法来减小方差,提高积分计算的精度。

重要性抽样法的特点在于,它不是从给定的过程的概率分布抽样,而是从修改的概率分布抽样,使对模拟结果有重要作用的事件更多出现,从而提高抽样效率,减少花费在对模拟结果无关紧要的事件上的计算时间。比如在区间[a  b]上求g(x)的积分,若采用均匀抽样,在函数值g(x)比较小的区间内产生的抽样点跟函数值较大处区间内产生的抽样点的数目接近,显然抽样效率不高,可以将抽样概率密度函数改为f(x),使f(x)与g(x)的形状相近,就可以保证对积分计算贡献较大的抽样值出现的机会大于贡献小的抽样值,即可以将积分运算改写为:

x是按照概率密度f(x)抽样获得的随机变量,显然在区间[a  b]内应该有:

因此,可容易将积分值I看成是随机变量 Y = g(x)/f(x)的期望,式子中xi是服从概率密度f(x)的采样点

下面的例子采用一个正态分布函数f(x)来近似g(x)=sin(x)*x,并依据正态分布选取采样值计算区间[0  pi]上的积分个∫g(x)dx

 # -*- coding: utf-8 -*-
# Example: Calculate ∫sin(x)xdx # The function has a shape that is similar to Gaussian and therefore
# we choose here a Gaussian as importance sampling distribution. from scipy import stats
from scipy.stats import norm
import numpy as np
import matplotlib.pyplot as plt mu = 2;
sig =.7; f = lambda x: np.sin(x)*x
infun = lambda x: np.sin(x)-x*np.cos(x)
p = lambda x: (1/np.sqrt(2*np.pi*sig**2))*np.exp(-(x-mu)**2/(2.0*sig**2))
normfun = lambda x: norm.cdf(x-mu, scale=sig) plt.figure(figsize=(18,8)) # set the figure size # range of integration
xmax =np.pi
xmin =0 # Number of draws
N =1000 # Just want to plot the function
x=np.linspace(xmin, xmax, 1000)
plt.subplot(1,2,1)
plt.plot(x, f(x), 'b', label=u'Original $x\sin(x)$')
plt.plot(x, p(x), 'r', label=u'Importance Sampling Function: Normal')
plt.xlabel('x')
plt.legend()
# =============================================
# EXACT SOLUTION
# =============================================
Iexact = infun(xmax)-infun(xmin)
print Iexact
# ============================================
# VANILLA MONTE CARLO
# ============================================
Ivmc = np.zeros(1000)
for k in np.arange(0,1000):
x = np.random.uniform(low=xmin, high=xmax, size=N)
Ivmc[k] = (xmax-xmin)*np.mean(f(x)) # ============================================
# IMPORTANCE SAMPLING
# ============================================
# CHOOSE Gaussian so it similar to the original functions # Importance sampling: choose the random points so that
# more points are chosen around the peak, less where the integrand is small.
Iis = np.zeros(1000)
for k in np.arange(0,1000):
# DRAW FROM THE GAUSSIAN: xis~N(mu,sig^2)
xis = mu + sig*np.random.randn(N,1);
xis = xis[ (xis<xmax) & (xis>xmin)] ; # normalization for gaussian from 0..pi
normal = normfun(np.pi)-normfun(0) # 注意:概率密度函数在采样区间[0 pi]上的积分需要等于1
Iis[k] =np.mean(f(xis)/p(xis))*normal # 因此,此处需要乘一个系数即p(x)在[0 pi]上的积分 plt.subplot(1,2,2)
plt.hist(Iis,30, histtype='step', label=u'Importance Sampling');
plt.hist(Ivmc, 30, color='r',histtype='step', label=u'Vanilla MC');
plt.vlines(np.pi, 0, 100, color='g', linestyle='dashed')
plt.legend()
plt.show()

从图中可以看出曲线sin(x)*x的形状和正态分布曲线的形状相近,因此在曲线峰值处的采样点数目会比曲线上位置低的地方要多。精确计算的结果为pi,从上面的右图中可以看出:两种方法均计算定积分1000次,靠近精确值pi=3.1415处的结果最多,离精确值越远数目越少,显然这符合常规。但是采用传统方法(红色直方图)计算出的积分值方的差明显比采用重要抽样法(蓝色直方图)要大。因此,采用重要抽样法计算可以降低方差,提高精度。另外需要注意的是:关于函数f(x)的选择会对计算结果的精度产生影响,当我们选择的函数f(x)与g(x)相差较大时,计算结果的方差也会加大。

参考:

http://iacs-courses.seas.harvard.edu/courses/am207/blog/lecture-3.html

蒙特卡洛法计算定积分—Importance Sampling的更多相关文章

  1. Not All Samples Are Created Equal: Deep Learning with Importance Sampling

    目录 概 主要内容 "代码" Katharopoulos A, Fleuret F. Not All Samples Are Created Equal: Deep Learnin ...

  2. Implemented the “Importance Sampling of Reflections from Hair Fibers”

      Just the indirect specular pass by importance sampling. With all layers. Manually traced by 3D Ham ...

  3. [Bayes] Hist & line: Reject Sampling and Importance Sampling

    吻合度蛮高,但不光滑. > L= > K=/ > x=runif(L) > *x*(-x)^/K)) > hist(x[ind],probability=T, + xla ...

  4. Importance sampling

    用蒙特卡洛求解积分时 (Monte Carlo 随机采样对目标积分函数做近似) importance sampling func p(x) p(x)值大的地方,Monte Carlo多采几次 值小的地 ...

  5. 转 如何理解 重要性采样(importance sampling)

    分类: 我叫学术帖2011-03-25 13:22 3232人阅读 评论(4) 收藏 举报 图形 重要性采样是非常有意 思的一个方法.我们首先需要明确,这个方法是基于采样的,也就是基于所谓的蒙特卡洛法 ...

  6. 小小知识点(二十)利用MATLAB计算定积分

    一重定积分 1. Z = trapz(X,Y,dim) 梯形数值积分,通过已知参数x,y按dim维使用梯形公式进行积分 %举例说明1 clc clear all % int(sin(x),0,pi) ...

  7. C++ 计算定积分、不定积分、蒙特卡洛积分法

    封装成了一个类,头文件和源文件如下: integral.h #pragma once //Microsoft Visual Studio 2015 Enterprise #include <io ...

  8. 随机模拟的基本思想和常用采样方法(sampling)

    转自:http://blog.csdn.net/xianlingmao/article/details/7768833 引入 我们会遇到很多问题无法用分析的方法来求得精确解,例如由于式子特别,真的解不 ...

  9. PRML读书会第十一章 Sampling Methods(MCMC, Markov Chain Monte Carlo,细致平稳条件,Metropolis-Hastings,Gibbs Sampling,Slice Sampling,Hamiltonian MCMC)

    主讲人 网络上的尼采 (新浪微博: @Nietzsche_复杂网络机器学习) 网络上的尼采(813394698) 9:05:00  今天的主要内容:Markov Chain Monte Carlo,M ...

随机推荐

  1. yii2购物车实现

    1.商品列表中点击加入购物车,则跳转到购物车列表,效果如图所示: 视图代码goods/list.php中.代码如下: <?php echo Html::a('加入购物车',['cart','id ...

  2. 三、Java基础---------关于继承、构造函数、静态代码块执行顺序示例讲解

    在上节博客中曾提到过类的继承,这篇文章主要是介绍类的继承.构造函数以及静态代码块的执行顺序. 首先接着分析在黑马基础测试中的一个关于继承的题目,题目描述如下: 声明类Person,包含2个成员变量:n ...

  3. SQL2005中的事务与锁定(一) - 转载

    ----------------------------------------------------------------------- -- Author : HappyFlyStone -- ...

  4. 关于MyEcplise中常见的问题和解决方案

    1.问题:严重   The web application  created a ThreadLocal with key of type  and a value of type  but fail ...

  5. Maven(一)

    Maven学习总结(一)——Maven入门 一.Maven的基本概念 Maven(翻译为"专家","内行")是跨平台的项目管理工具.主要服务于基于Java平台的 ...

  6. Ceph的客户端丢失文件夹的解决办法

    原来的解决办法 更新linux内核,使用linux内核级的mount方式,一段时间后将会在客户端看不到部分长期不使用的文件夹 更正后的解决办法 参考Ceph的客户端安装设置ceph-fuse方式挂载c ...

  7. JS货币数字转换中文

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. ubuntu下配置tomcat

    配置tomcat 1.解压 tar -zxvf apache-tomcat-7.0.53.tar.gz 2.修改/bin/catalina.sh cygwin=falsedarwin=falseos4 ...

  9. DBLINK的session无法关闭,报异常!

    ------解决方法-------------------------------------------------------- --ALTER SESSION alter session clo ...

  10. php中urlencode与rawurlencode的区别有那些呢

    urlencode 函数: 返回字符串,此字符串中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,空格则编码为加号(+).此编码与 WWW 表单 POST 数据的编码 ...