2014-01-12 59 views
1

长度为零我有一个嵌套循环的问题,下面的代码:更换在嵌套循环

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个布朗运动的样本路径。

+1

你的缺少)在1:(K-1)。尽管如此,我认为你可以做这个没有循环的模拟。 – Fernando

+0

谢谢大家,伙计们!你帮了很多! – user3187955

+0

@ user3187955如果你认为你的问题已经得到解答,你可以[接受答案](http://meta.stackexchange.com/a/5235),你只能接受他们中的一个,但当你有足够的声誉upvoting;) –

回答

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 -loops快约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个COLS比较,以检查结果:

> 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 
+0

嗯,从来没有听说过'mat.or.vec' – rawr

+0

因为大家都是关于基准在这里,'矩阵(0,K,1000)'需要更少的击键 – rawr

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) 
}