0

i have problems to perform my R-Code in OSX. That's my code:

i <- 1
while (i <= 20000) {
  repeat{
    z1=((runif(1,0,1)*2)-1)
    z2=((runif(1,0,1)*2)-1)
    h=z1**2+z2**2
    if((h > 0) && (h <= 1)){break}
   }
  x[i] <- z1
  y[i] <- z2
  q[i] <- h

  i <- i + 1
} 

j <- 1
while (j <= 20000) {
  h=sqrt((-2*ln(q[j]))/q[j])
  p[j] <- h
  j <- j + 1
}

a=x*p
b=y*p
points(a,b, pch=c(20,20),col=c("dark green","red"),cex=0.6)

When I initialize x,y,q,p and use the log, it works.

But why are there those errors, but why?

error in x[i] <- z1: object 'x' not fund
error: no function for "ln" fund
error: object 'x' not fund
error: object 'y' not fund
4

3 に答える 3

4

ここに別のアプローチがあります。繰り返し実行する必要がある回数を減らすと、通常、コードは高速になります。具体的には、すべてのrunif(1,0,1)呼び出しを 1 つの大きな値のベクトルに置き換えてからrunif()、それに基づいてベクトルをサブセット化できます。

@Mark Miller の関数を出発点として使用し、次の変更を加えました。オーバーサンプラーが前の乱数のセットから適切な値を保持し、n到達するまでのみ埋められた場合、これはさらに改善される可能性がありますが、これは関係なくかなり高速です。速度比較のために、私は彼のコードを逐語的に取り、それをfun2 <- function() {...}

fun1 <- function(n, oversample = 1.50){
  #oversample
  over <- ceiling(n * oversample)
  goodvars <- NA
  while (length(goodvars) < n){
    z1 <- runif(over,-1,1)
    z2 <- runif(over,-1,1)
    h <- z1^2 + z2^2  
    goodvars <- which(h > 0 & h < 1)
  }
  goodvars <- goodvars[1:n]
  x <- z1[goodvars]
  y <- z2[goodvars]
  q <- h[goodvars]
  p <- sqrt((-2 * log(q)) / q)
  a <- x * p
  b <- y * p
  return(cbind(a,b))
 }

##Mark's code put into a function
fun2 <- function() {
  i <- 1

  x <- rep(NA, 20)
  y <- rep(NA, 20)
  q <- rep(NA, 20)
  p <- rep(NA, 20)

  while (i <= 20) {

    repeat{
      z1=((runif(1,0,1)*2)-1)
      z2=((runif(1,0,1)*2)-1)
      h=z1**2+z2**2
      if((h > 0) & (h <= 1)){break}
    }
    x[i] <- z1
    y[i] <- z2
    q[i] <- h

    i <- i + 1
  } 

  j <- 1
  while (j <= 20) {

    h=sqrt((-2*log(q[j]))/q[j])

    p[j] <- h

    j <- j + 1
  }

  a=x*p
  b=y*p
}

#Do some speed checking with rbenchmark. Also checkout compiler package for some free speed
library(compiler)
library(rbenchmark)
#Compile functions to see improvements
cfun1 <- cmpfun(fun1)
cfun2 <- cmpfun(fun2)
#run benchmark tests
benchmark(fun1(n = 20), fun2(), cfun1(n = 20), cfun2(),
          replications = 1000,
          columns=c("test", "elapsed", "relative"),
          order = "elapsed")

そして結果

           test elapsed  relative
3 cfun1(n = 20)   0.042  1.000000
1  fun1(n = 20)   0.055  1.309524
4       cfun2()   0.407  9.690476
2        fun2()   0.882 21.000000

新しい R セッションから始めて、上記のコードをコピーして貼り付けてもエラーは返されません。次に例を示します。

test <- fun1(n = 1000)
plot(test)

ここに画像の説明を入力

ここに画像の説明を入力

于 2012-04-14T12:29:41.893 に答える
2

Windows では、空の新しいワークスペースから開始することはできません。' x' オブジェクトは既に存在している必要があります。存在しないと、そこでもエラーが発生します。ls()Windows と OSX で実行し、「 」があるかどうかを確認しますx。OSXではなくWindowsに1つあることにお金をかけます。

于 2012-04-14T09:46:18.893 に答える
2

これはあなたが望むことをしますか?私:

  1. x、y、q、および p を格納するベクトルを追加しました。
  2. ln を log に変更
  3. plot(a,b) ステートメントを追加しました。
  4. デバッグ目的で 20000 を 20 に変更しました。

私はMacを持っていません。

i <- 1

x <- rep(NA, 20)
y <- rep(NA, 20)
q <- rep(NA, 20)
p <- rep(NA, 20)

while (i <= 20) {

repeat{
    z1=((runif(1,0,1)*2)-1)
    z2=((runif(1,0,1)*2)-1)
    h=z1**2+z2**2
if((h > 0) & (h <= 1)){break}
 }
x[i] <- z1
y[i] <- z2
q[i] <- h

i <- i + 1
} 

j <- 1
while (j <= 20) {

h=sqrt((-2*log(q[j]))/q[j])

p[j] <- h

j <- j + 1
}

a=x*p
b=y*p
plot(a,b)
points(a,b, pch=c(20,20),col=c("dark green","red"),cex=0.6)
于 2012-04-14T08:42:48.383 に答える