msfz751

one draw from truncated normal distribution (mu,sigma^2)

Aug 16th, 2017
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
R 1.10 KB | None | 0 0
  1. // ---------------------------------------------  
  2. // Returns one draw from truncated normal distribution (mu,sigma^2) with range
  3. // (bound,+inf) if lb=TRUE and
  4. // (-inf,bound) if lb=FALSE
  5. // from http://athens.src.uchicago.edu/jenni/econ319_2003/lecture.html
  6. // ---------------------------------------------  
  7.  
  8. double truncn(double bound, bool lb, double mu, double sigma){
  9.  
  10.   double c, z, w;
  11.  
  12.   // 1. standardised cut-off c for truncation from below or above
  13.   if(lb == TRUE){
  14.     c = (bound-mu)/sigma;
  15.   } else{
  16.     c = -(bound-mu)/sigma;
  17.   }
  18.  
  19.   // 2. standardised draw using Geweke (1991)
  20.   if(c < 0.45){ // normal rejection sampling
  21.     z = ::Rf_rnorm(0.0,1.0);
  22.     while(z < c){
  23.       z = ::Rf_rnorm(0.0,1.0);
  24.     }
  25.   } else{ // exponential rejection sampling
  26.     z = -log(1-::Rf_runif(0.0,1.0))/c;
  27.     w = ::Rf_runif(0.0,1.0);
  28.     while(w > exp(-0.5*pow(z,2))){
  29.       z = -log(1-::Rf_runif(0.0,1.0))/c;
  30.       w = ::Rf_runif(0.0,1.0);
  31.     }
  32.     z = z+c;
  33.   }
  34.  
  35.   // 3. reverse standardisation
  36.   if(lb == TRUE){
  37.     return mu + sigma*z;
  38.   } else{
  39.     return mu - sigma*z;
  40.   }
  41. }
Advertisement
Add Comment
Please, Sign In to add comment