【问题标题】:Making a more efficient monte carlo simulation制作更高效的蒙特卡罗模拟
【发布时间】:2012-11-06 22:53:45
【问题描述】:

所以,我编写了这段代码,它可以有效地估计定义为 h(x) 的函数曲线下的面积。我的问题是我需要能够将面积估计到小数点后 6 位以内,但是我在 estimateN 中定义的算法似乎对我的机器来说太重了。本质上问题是我怎样才能使下面的代码更有效率?有没有办法摆脱这个循环?

h = function(x) {
    return(1+(x^9)+(x^3))
}
estimateN = function(n) {
    count = 0
    k = 1
    xpoints = runif(n, 0, 1)
    ypoints = runif(n, 0, 3)
    while(k <= n){
    if(ypoints[k]<=h(xpoints[k]))
        count = count+1
    k = k+1
    }
    #because of the range that im using for y
    return(3*(count/n))
}
#uses the fact that err<=1/sqrt(n) to determine size of dataset
estimate_to = function(i) {
    n = (10^i)^2
    print(paste(n, " repetitions: ", estimateN(n)))
}

estimate_to(6)

【问题讨论】:

  • estimate_to(6) 可能有点过于贪婪:您当前的算法可能会使 R 在尝试分配长度为 1e12 的数字向量时耗尽内存。
  • 如果你真的需要 1e12 模拟,你必须重写你的算法,以便在计算时间和内存使用之间找到一个折衷方案。
  • 使蒙特卡洛积分(更多)更有效(即在更少的迭代中获得相同的精度)的最佳方法是使用重要性抽样,例如 Metropolis Monte Carlo。在您的情况下,x 更接近1.0 的点比更接近0.0 的点对积分值的贡献更大。

标签: performance r statistics simulation


【解决方案1】:

替换此代码:

count = 0
k = 1
while(k <= n){
if(ypoints[k]<=h(xpoints[k]))
    count = count+1
k = k+1
}

用这一行:

count <- sum(ypoints <= h(xpoints))

【讨论】:

  • 我认为这很好地概括了矢量化的力量。
【解决方案2】:

如果您真正追求的是效率,integrate 在这个问题上的速度要快几个数量级(更不用说内存效率更高了)。

integrate(h, 0, 1)

# 1.35 with absolute error < 1.5e-14

microbenchmark(integrate(h, 0, 1), estimate_to(3), times=10)

# Unit: microseconds
#                expr        min         lq     median         uq        max neval
#  integrate(h, 0, 1)     14.456     17.769     42.918     54.514     83.125    10
#      estimate_to(3) 151980.781 159830.956 162290.668 167197.742 174881.066    10

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 2013-01-02
    相关资源
    最近更新 更多