替换在嵌套循环中的长度为零

时间:2014-01-12 18:35:49

标签: r for-loop nested-loops

我遇到嵌套循环问题,这是代码:

T=2
dt=0.001
K=floor(T/dt)
t= seq(0,T,dt)

BM<- matrix(0,2000,1000)
for (i in 1:1000){
for (k in 1:K-1){
BM[k+1,i]=BM[k,i]+sqrt(dt)*rnorm(1)
}
}

错误信息是:

Error in BM[k + 1, i] = BM[k, i] + sqrt(dt) * rnorm(1) : 
replacement has length zero

循环有什么问题? 它的目标是模拟布朗运动的1000个样本路径。

2 个答案:

答案 0 :(得分:3)

这是一个完全向量化的方法,它可以提供相同的结果,并且比使用for循环更快

B <-  mat.or.vec(K,1000)  # pre-allocate 
set.seed(1)
B[-1, ] <- matrix(rnorm((K-1)*100),K-1,1000) * sqrt(dt)
B <- apply(B, 2, cumsum)

矢量化函数可以加速您的代码,如下面的基准测试结果所示:

          test elapsed relative
1 vectorized()   2.070    1.000
2   for.loop() 181.768   87.811

矢量化方法比两个嵌套for - 循环快约88倍。基准代码如下所示。

for.loop <- function(){  # this is your approach
  BM<- matrix(0,2000,1000)
  set.seed(1)
  for (i in 1:1000){
    for (k in 1:(K-1)){
      BM[k+1, i]=BM[k,i]+sqrt(dt)*rnorm(1)
    }
  }
  return(BM)
}


vectorized <- function(){  # this is my approach
  B <-  mat.or.vec(K,1000)  # pre-allocate
  set.seed(1)
  B[-1, ] <- matrix(rnorm((K-1)*100),K-1,1000) * sqrt(dt)
  B <- apply(B, 2, cumsum)
}


library("rbenchmark")
benchmark(vectorized(),
          for.loop(),
          replications=10,
          columns=c('test', 'elapsed', 'relative'),
          order = "relative")

比较前5行和5列以检查结果:

> vectorized()[1:5, 1:5]
            [,1]         [,2]         [,3]         [,4]         [,5]
[1,]  0.00000000  0.000000000  0.000000000  0.000000000  0.000000000
[2,] -0.01981021 -0.009865464 -0.008371525  0.015834886  0.001562361
[3,] -0.01400290 -0.037887974 -0.037253019  0.010349073 -0.024924006
[4,] -0.04042779 -0.098675011 -0.073133176  0.018483702 -0.066867547
[5,]  0.01001941 -0.047455576 -0.048955758 -0.001085329 -0.123356698
> for.loop()[1:5, 1:5]
            [,1]         [,2]         [,3]         [,4]         [,5]
[1,]  0.00000000  0.000000000  0.000000000  0.000000000  0.000000000
[2,] -0.01981021 -0.009865464 -0.008371525  0.015834886  0.001562361
[3,] -0.01400290 -0.037887974 -0.037253019  0.010349073 -0.024924006
[4,] -0.04042779 -0.098675011 -0.073133176  0.018483702 -0.066867547
[5,]  0.01001941 -0.047455576 -0.048955758 -0.001085329 -0.123356698

答案 1 :(得分:2)

这是问题所在:

for (k in 1:K-1){

你的优先权已经结束。这将有效:

for (k in 1:(K-1)){

等价(对于K > 0):

for (k in seq(K-1)){

矢量化更好:

for (k in seq(K-1)) {
  BM[k+1,] <- BM[k,]+sqrt(dt)*rnorm(2000)
}