Skip to content

Commit 0dbba71

Browse files
committed
Study inversion and rejection method
1 parent eac84eb commit 0dbba71

1 file changed

Lines changed: 69 additions & 0 deletions

File tree

R/README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,3 +536,72 @@ Since a RNG normally uses a deterministic algorithm, its randomness property is
536536
- `R` function `ks.test`
537537
- Try: `x = seq(0, 1, length = 10000)`
538538
- The longest runs of head
539+
540+
### Generating Non-uniform Distributions
541+
542+
- Use `R` built-in RNG functions such as `rpois`, `rexp`, `rgama`, `rbinom` etc.
543+
- How to generate nonstandard distributions?
544+
- Inversion method
545+
- Let `F(x)` be the C.D.F of a random variable `X`. Its inverse function (quantile function) is defined `Q(t) = F^{-1}(t) = inf{x: F(x) >= t}`
546+
- In principle if `Q(t)` has a closed form, inversion method is the best way to generate required random numbers
547+
- Distributions: `Exp`, `Cauchy`, `Geometric`, `Pareto`, `Logistic`, `Extreme Value`, `Weibull` etc.
548+
- Normal distribution has no closed form for `Q(t)`
549+
- There are other ways to generate normal sample exactly
550+
- `Box-Muller` normal RNG uses 2 independent uniform `[0, 1]` to generate 2 independent normal; computation is costly (sin, cos, log, sqrt)
551+
- Rejection method
552+
- `R` and `Matlab` use highly refined numerical approximation of `Q(t)`
553+
- Random variables are functions of random variables
554+
- `Z` is normal, then `exp(Z)` is log-normal
555+
- Rejection method
556+
- density of interest: `f(x), a <= x <= b`
557+
- A known function: `M(x) >= f(x), a <= x <= b`
558+
- algorithm: let `m(x) = M(x) / (integral of M over [a, b])`
559+
- step 1: Generate `T` with the density function `m(x)`
560+
- step 2: Generate `U` of `unif[0, 1]`. If `M(T) * U <= f(T)` then `X = T` else go to step 1
561+
562+
```r
563+
rejection_sample <- function(n, f, M, r_m) {
564+
samples <- numeric(n)
565+
count <- 0
566+
567+
while (count < n) {
568+
# Step 1: sample T ~ m(x)
569+
T <- r_m(1)
570+
571+
# Step 2: sample U ~ Uniform(0,1)
572+
U <- runif(1)
573+
574+
# Accept or reject
575+
if (M(T) * U <= f(T)) {
576+
count <- count + 1
577+
samples[count] <- T
578+
}
579+
}
580+
581+
return(samples)
582+
}
583+
```
584+
585+
```r
586+
rejection_sample_vec <- function(n, f, M, r_m, batch_size = 10000) {
587+
samples <- numeric(0)
588+
589+
while (length(samples) < n) {
590+
# Step 1: generate a batch of proposals
591+
T <- r_m(batch_size)
592+
593+
# Step 2: generate uniforms
594+
U <- runif(batch_size)
595+
596+
# Step 3: vectorized acceptance test
597+
accept <- (M(T) * U) <= f(T)
598+
599+
# Keep accepted samples
600+
samples <- c(samples, T[accept])
601+
}
602+
603+
# Trim to exactly n samples
604+
samples[1:n]
605+
}
606+
```
607+

0 commit comments

Comments
 (0)