R中定积分的Monte-Carlo方法

gua*_*. S 4 r montecarlo

我开始了一个Msc,我们正在学习R包,但是我在运动时遇到了问题.练习是这样的:

"假设我们想要使用基本的蒙特卡罗方法估计∫x2(在1和0之间确定).基本上,我们在曲线上投掷飞镖并计算落在曲线下方的飞镖数量.该方法的算法包括:

1)初始化:命中= 0

2)for(i in 1:N):生成两个随机数,U1,U2在0和1之间.如果U2 <(U1)^ 2,则命中=命中+ 1结束.

3)面积估计=命中/ N.

使用循环提供R代码以实现此蒙特卡罗算法.你的功能需要多长时间?提供更有效的代码,避免以前的循环.说明通过矢量化代码可以提高效率."

我有这些代码,但我认为我做错了.

montecarlo <- function(N){
  hits=0
  for (i in 1:N){
    U1 <- runif(1, 0, 1)
    U2 <- runif(1, 0, 1)
    if (U2 < (U1)^2){
      hits = hits+1}}
  return(hits/N)
}

montecarlo2 <- function(N){
  hits=0
  U1 <- runif (1:N, 0, 1)
  U2 <- runif (1:N, 0, 1)
  hits= hits+1 [U2<(U1)^2]
  return(hits/N)
}
Run Code Online (Sandbox Code Playgroud)

对于第一种方法,使用循环,我已经获得(例如):

> montecarlo(23)
[1] 0.3478261
> montecarlo(852)
[1] 0.3591549
> montecarlo(8563255)
[1] 0.3332472
Run Code Online (Sandbox Code Playgroud)

你能帮助我吗?非常感谢你:S.

Joz*_*zef 5

其中一种方式:

montecarlo_for <- function(N) {
  hits <- 0
  for (i in 1:N) {
    U1 <- runif(1)
    U2 <- runif(1)
    if (U2 < (U1) ^ 2) hits <- hits + 1
  }
  return(hits / N)
}
Run Code Online (Sandbox Code Playgroud)

矢量化

montecarlo_vec <- function(N) {
  sum(runif(N) < runif(N)^2) / N
}
Run Code Online (Sandbox Code Playgroud)

比较速度,例如使用microbenchmark包:

microbenchmark::microbenchmark(times = 50,
  montecarlo_for(1e5),
  montecarlo_vec(1e5)
)
Run Code Online (Sandbox Code Playgroud)

我的机器上的速度比较表明,矢量化方法大约快了100倍(平均值和中位数时间如下所示):

Unit: milliseconds
expr                  mean       median
montecarlo_for(1e+05) 509.927001 497.238904
montecarlo_vec(1e+05) 5.214527   4.922007
Run Code Online (Sandbox Code Playgroud)

只是为了好玩,如果你想看看算法收敛到结果(1/3)的速度越来越快,样本量越来越大:

plot(sapply(1:1000, montecarlo_vec), type = "line")
Run Code Online (Sandbox Code Playgroud)