@@ -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