############################################################################################################# # # Example 1.2 (page 20) – Figure 1.1 (page 21) – Routines to sample from # # (a) N(0,1) - central limit theorem applied to averages of uniforms # (b) N(0,1) - probability integral transform # (c) N(0,1) - Box-Muller algorithm # (d) N(0,1) - Modified Box-Muller algorithm # (e) Poisson # (f) Gamma(a,1) with a < 1 # (g) Gamma(a,1) with a > 1 # (h) Beta(a,b) with a,b<1 # (i) Student’s t # ############################################################################################################# # # Author : Hedibert Freitas Lopes # Graduate School of Business # University of Chicago # 5807 South Woodlawn Avenue # Chicago, Illinois, 60637 # Email : hlopes@ChicagoGSB.edu # ############################################################################################################# set.seed(826486) par(mfrow=c(3,3)) ########################################################### # Generating N(0,1) by applying the Central Limit Theorem # for the limit of a sequence of U(0,1) draws. ########################################################### n = 20 M = 10000 u = matrix(runif(M*n),M,n) mu = apply(u,1,mean) x = (mu-0.5)/sqrt(1/(12*n)) y = seq(-5,5,length=50) hist(x,prob=T,main="(a)",breaks=y,ylab="",xlab="") lines(y,dnorm(y),col=1) ######################################################## # Generating N(0,1) by using the inverse transformation ######################################################## xnum = rep(0,5) xden = rep(0,5) xnum[1] = -0.322232431088 xnum[2] = -1.000000000000 xnum[3] = -0.342242088547 xnum[4] = -0.020423121025 xnum[5] = -0.000045364221 xden[1] = 0.099348462606 xden[2] = 0.588581570495 xden[3] = 0.531103462366 xden[4] = 0.103537752850 xden[5] = 0.003856070063 polinom = function(a,x){ polin = a[5] for (i in 4:1) polin = a[i] + polin*x return(polin) } invnorm = function(p){ if (p <= 0.5){ sign = -1.0 z = p y = sqrt(-2.0*log(z)) out1 = polinom(xnum,y) out2 = polinom(xden,y) invnor = y + out1/out2 invnor = sign*invnor } else{ sign = 1.0 z = 1.0 - p y = sqrt(-2.0*log(z)) out1 = polinom(xnum,y) out2 = polinom(xden,y) invnor = y + out1/out2 invnor = sign*invnor } } # Testing the generator # --------------------- M = 10000 u = runif(M) x = rep(0,M) for (i in 1:M) x[i] = invnorm(u[i]) y = seq(-5,5,length=50) hist(x,prob=T,main="(b)",breaks=y,ylab="",xlab="") lines(y,dnorm(y),col=1) ####################################################### # Generating N(0,1) by applying the Box-Muller result ####################################################### M = 10000 x = matrix(0,M/2,2) for (i in 1:(M/2)){ u = runif(2) x[i,1] = sqrt(-2*log(u[1]))*cos(2*pi*u[2]) x[i,2] = sqrt(-2*log(u[1]))*sin(2*pi*u[2]) } x = c(x[,1],x[,2]) y = seq(-5,5,length=50) hist(x,prob=T,main="(c)",breaks=y,ylab="",xlab="") lines(y,dnorm(y),col=1) ############################################################ # Generating N(0,1) by using the polar rejection algorithm # Gentle, J.E. (1998) page 89 ############################################################ rnorm.polar = function(M){ x = NULL n = 0 repeat{ v = -1+2*runif(2) r2 = sum(v^2) if (r2<=1){ x = c(x,v[1]*sqrt(-2*log(r2)/r2)) n = n+1 } if (n==M) break } return(x) } # Testing rnorm.polar # ------------------- M = 10000 X = rnorm.polar(M) y = seq(-5,5,length=50) x = seq(min(X),max(X),length=1000) hist(X,prob=T,col=0,main="(d)",breaks=y,ylab="",xlab="") lines(x,dnorm(x)) ####################################### # Generating Poisson(mu) variates # ####################################### rpois1 = function(M,mu){ x = NULL for (i in 1:M){ P = 1 N = 0 C = exp(-mu) repeat{ U = runif(1) P = P*U N = N+1 if (P(exp(1)/(alpha+exp(1)))){ X = -log((alpha+exp(1))*(1-U[1])/(alpha*exp(1))) accept = ifelse(U[2]2.5){ U[1] = U[2]+c5*(1-1.86*U[1]) } if ((U[1]>0)&(U[1]<1)){ break } } W = c2*U[2]/U[1] if (((c3*U[1]+W+1/W)