2013-03-01 6 views
1

Следующий код R дает мне только половину нормального распределения; что я должен изменить на код, чтобы получить вторую половину?Сгенерировать вторую половину нормального распределения, используя метод приемки-отклонения

halfnormal <- function(n){ 
    vector <- rep(0,n) 
    for(i in 1:n){ 
     uni_random <- runif(2) 
     y <- -log(uni_random) 
     while(y[2] < (y[1]-1)^2/2){ 
      uni_random <- runif(2) 
      y <- -log(uni_random) 
     } 
     vector[i] <- y[1] 
    } 
    vector 
} 

output <- halfnormal(1000) 
hist(output) 
+0

Почему вы не используете функцию rnorm? –

+1

попробуйте 'hist (rnorm (1000))' –

ответ

7

Если вы настаиваете на использование этого кода для генерации стандартного нормального (не рекомендуются, так как rnorm будет быть намного быстрее и точнее), просто точечный продукт, что весь вектор вектор равной длины, состоящий из случайных значений (-1, +1).

Кстати, полунормальное явление также известно как Chi distribution (с 1 степенью свободы).

+0

+1 для более быстрого способа сделать то же, что и в моем коде. –

+0

Я использовал точечный продукт, но получил только номер. Мой код «vector% *% runif (n, min = -1, max = 1)». Как я могу это исправить? Благодарю. –

+0

Нет, вы не хотите генерировать из равномерного распределения, вы хотите генерировать случайные биты. Используйте 'rbinom' с n = 1 и p = 0.5 или выполните' runif() <0.5'. Затем замените все вхождения '0' на' -1'. –

1

Это похоже на алгоритм Зиггурата с модификацией Марсалья, но это немного отличается? Если вы не хотите использовать любые гарантируемые к работе генераторов случайных чисел в R, возможно, это работает:

halfnormal <- function(n){ 
     vector <- rep(0,n) 
     for(i in 1:n){ 
      uni_random <- runif(2) 
      y <- -log(uni_random) 
      while(y[2] < (y[1]-1)^2/2){ 
       uni_random <- runif(2) 
       y <- -log(uni_random) 
      } 
      vector[i] <- sample(c(-1,1),size=1)*y[1] #randomly select the tail 
     } 
     vector 
    } 

    output <- halfnormal(1000) 
    hist(output)