Вот еще один подход. Обычно ваш код должен быть быстрее, если вы уменьшите количество раз, когда вам нужно делать что-то итеративно. В частности, все ваши вызовы runif(1,0,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)
http://i39.tinypic.com/20qhlac.jpg
Присваивание 'x' (' х [я] <- z1') не должен работать ни при каких обстоятельствах, будь то Win7 или OS X. Пожалуйста, уточните свой вопрос относительно проблемы. –
Потому что, если они не инициализированы, их не существует. И если они не существуют, вы не можете присвоить им значение. Это работает на win7? Я сомневаюсь, что это ... –
да, клянусь, этот код работает на win7 без ошибок .... – jeffrey