Генерація випадкових зразків з користувацького розподілу


16

Я намагаюся генерувати випадкові вибірки з користувальницького pdf за допомогою R. Мій pdf такий:

fХ(х)=32(1-х2),0х1

Я створив рівномірні зразки, а потім спробував перетворити його на свій власний розподіл. Я зробив це, знайшовши cdf мого розповсюдження ( ) і встановивши його на єдиний зразок ( u ) та вирішивши для x .FX(x)ux

FX(x)=Pr[Xx]=0x32(1y2)dy=32(xx33)

Щоб генерувати випадкову вибірку з наведеним вище розподілом, отримайте рівномірний зразок і вирішіть для x у 3u[0,1]x

32(xx33)=u

Я реалізував це в Rі не отримую очікуваного розповсюдження. Чи може хтось вказати на недолік у моєму розумінні?

nsamples <- 1000;
x <- runif(nsamples);

f <- function(x, u) { 
  return(3/2*(x-x^3/3) - u);
}

z <- c();
for (i in 1:nsamples) {
  # find the root within (0,1) 
  r <- uniroot(f, c(0,1), tol = 0.0001, u = x[i])$root;
  z <- c(z, r);
}

1
Повинно бути помилкою кодування. Я не використовую R, тому я не можу сказати, у чому полягає помилка - але я просто зашифрував ваше рішення (дбаючи про те, щоб взяти середній корінь кубічного многочлена, який завжди лежить між 0 і 1), і Я отримую гарну згоду між зразками та очікуваним розподілом. Чи може бути проблема з вашим кореневим шукачем? Що не так із зразками, які ви отримуєте?
jpillow

Я спробував ваш код (до речі, не дуже ефективний) і отримав очікуване розповсюдження.
Аніко

@jpillow та @Aniko Моя помилка. Коли я використовував, nsamples <- 1e6це був хороший матч.
Ананд

2
@Anand Один із способів полягає в тому, щоб помітити, що , що дозволяє прямий обчислення x у термінах u . x=2sin(арцин(у)/3)ху
whuber

Відповіді:


11

Схоже, ви зрозуміли, що ваш код працює, але @Aniko зазначив, що ви можете покращити його ефективність. Ваш найбільший приріст швидкості, ймовірно, відбудеться від попереднього розподілу пам'яті, zщоб ви не зростали її всередині циклу. Щось подібне z <- rep(NA, nsamples)повинно зробити трюк. Ви можете отримати невеликий приріст швидкості, використовуючи vapply()(який вказує тип повернутої змінної) замість явного циклу ( у сімейства застосувань є велике запитання щодо ТА).

> nsamples <- 1E5
> x <- runif(nsamples)
> f <- function(x, u) 1.5 * (x - (x^3) / 3) - u
> z <- c()
> 
> # original version
> system.time({
+ for (i in 1:nsamples) {
+   # find the root within (0,1) 
+   r <- uniroot(f, c(0,1), tol = 0.0001, u = x[i])$root
+   z <- c(z, r)
+ }
+ })
   user  system elapsed 
  49.88    0.00   50.54 
> 
> # original version with pre-allocation
> z.pre <- rep(NA, nsamples)
> system.time({
+ for (i in 1:nsamples) {
+   # find the root within (0,1) 
+   z.pre[i] <- uniroot(f, c(0,1), tol = 0.0001, u = x[i])$root
+   }
+ })
   user  system elapsed 
   7.55    0.01    7.78 
> 
> 
> 
> # my version with sapply
> my.uniroot <- function(x) uniroot(f, c(0, 1), tol = 0.0001, u = x)$root
> system.time({
+   r <- vapply(x, my.uniroot, numeric(1))
+ })
   user  system elapsed 
   6.61    0.02    6.74 
> 
> # same results
> head(z)
[1] 0.7803198 0.2860108 0.5153724 0.2479611 0.3451658 0.4682738
> head(z.pre)
[1] 0.7803198 0.2860108 0.5153724 0.2479611 0.3451658 0.4682738
> head(r)
[1] 0.7803198 0.2860108 0.5153724 0.2479611 0.3451658 0.4682738

І вам не потрібно ;в кінці кожного рядка (ви перетворюєте MATLAB?).


Дякуємо за детальну відповідь та за вказівку vapply. Я кодую C/C++вже дуже давно, і це є причиною ;скорботи!
Ананд

1
uniroot107
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.