13 #if !defined(RANDOMLIB_MPFRNORMALR_HPP) 
   14 #define RANDOMLIB_MPFRNORMALR_HPP 1 
   20 #define HAVE_MPFR (MPFR_VERSION_MAJOR >= 3) 
   22 #if HAVE_MPFR || defined(DOXYGEN) 
   48     static const long chunk_ = 32;
 
   49     static const unsigned long m = 3684067834; 
 
   58       mpfr_init2(_eps, chunk_);
 
   59       mpfr_init2(_u, chunk_);
 
   60       mpfr_init2(_v, chunk_);
 
   61       mpfr_init2(_up, chunk_);
 
   62       mpfr_init2(_vp, chunk_);
 
   63       mpfr_init2(_vx, chunk_);
 
   64       mpfr_init2(_x1, chunk_);
 
   65       mpfr_init2(_x2, chunk_);
 
   91     int operator()(mpfr_t val, gmp_randstate_t r, mpfr_rnd_t round)
 const {
 
  101         scale = std::pow(2.0, -chunk_); 
 
  104         mpz_urandomb(_vi, r, chunk_);
 
  105         if (mpz_cmp_ui(_vi, m) >= 0) 
continue; 
 
  106         double vf = (mpz_get_ui(_vi) + 0.5) * scale;
 
  107         mpz_urandomb(_ui, r, chunk_);
 
  108         double uf = (mpz_get_ui(_ui) + 0.5) * scale;
 
  112           Q = x*x + y * (a*y - b*x);
 
  113         if (Q >= r2) 
continue;    
 
  114         mpfr_set_ui_2exp(_eps, 1u, -chunk_, MPFR_RNDN);
 
  115         mpfr_prec_t prec = chunk_;
 
  116         mpfr_set_prec(_u, prec);
 
  117         mpfr_set_prec(_v, prec);
 
  119         mpfr_set_z_2exp(_u, _ui, -prec, MPFR_RNDN);
 
  120         mpfr_set_z_2exp(_v, _vi, -prec, MPFR_RNDN);
 
  121         mpfr_set_prec(_up, prec);
 
  122         mpfr_set_prec(_vp, prec);
 
  124         mpfr_add(_up, _u, _eps, MPFR_RNDN);
 
  125         mpfr_add(_vp, _v, _eps, MPFR_RNDN);
 
  128         mpfr_prec_t prec_guard = 3 + chunk_ -
 
  129           (std::max)(mpz_sizeinbase(_ui, 2), mpz_sizeinbase(_vi, 2));
 
  139               reject = Reject(_u, _vp, prec, MPFR_RNDU);
 
  141               reject = Reject(_up, _vp, prec, MPFR_RNDU);
 
  143               mpfr_set_prec(_vx, prec);
 
  144               mpfr_add(_vx, _vp, _eps, MPFR_RNDN);
 
  145               reject = Reject(_u, _vx, prec, MPFR_RNDU); 
 
  147             if (reject < 0) 
break; 
 
  151               reject = Reject(_up, _v, prec, MPFR_RNDD);
 
  153               reject = Reject(_u, _v, prec, MPFR_RNDD);
 
  155               mpfr_sub(_vx, _v, _eps, MPFR_RNDN);
 
  156               reject = Reject(_u, _vx, prec, MPFR_RNDD); 
 
  158             if (reject > 0) 
break; 
 
  160             prec = Refine(r, prec);  
 
  162           if (reject > 0) 
continue; 
 
  165         mpfr_prec_t prec0 = mpfr_get_prec (val);
 
  167         if (prec < prec0 + prec_guard)
 
  168           prec = Refine(r, prec,
 
  169                         (prec0 + prec_guard - prec + chunk_ - 1) / chunk_);
 
  170         mpfr_set_prec(_x1, prec0);
 
  171         mpfr_set_prec(_x2, prec0);
 
  175             f1 = mpfr_div(_x1, _v, _up, round),   
 
  176             f2 = mpfr_div(_x2, _vp, _u, round);   
 
  177           if (f1 == f2 && mpfr_equal_p(_x1, _x2)) {
 
  181           prec = Refine(r, prec);
 
  183         mpz_urandomb(_ui, r, 1);
 
  184         if (mpz_tstbit(_ui, 0)) {
 
  186           mpfr_neg(val, _x1, MPFR_RNDN);
 
  188           mpfr_set(val, _x1, MPFR_RNDN);
 
  198     mpfr_prec_t Refine(gmp_randstate_t r, mpfr_prec_t prec, 
long num = 1)
 
  200       if (num <= 0) 
return prec;
 
  202       prec += num * chunk_;
 
  203       mpfr_div_2ui(_eps, _eps, num * chunk_, MPFR_RNDN);
 
  205       mpz_urandomb(_ui, r, num * chunk_);
 
  206       mpfr_set_prec(_up, prec);
 
  207       mpfr_set_z_2exp(_up, _ui, -prec, MPFR_RNDN);
 
  208       mpfr_set_prec(_vx, prec);
 
  209       mpfr_add(_vx, _u, _up, MPFR_RNDN);
 
  211       mpfr_add(_up, _u, _eps, MPFR_RNDN);
 
  213       mpz_urandomb(_vi, r, num * chunk_);
 
  214       mpfr_set_prec(_vp, prec);
 
  215       mpfr_set_z_2exp(_vp, _vi, -prec, MPFR_RNDN);
 
  216       mpfr_set_prec(_vx, prec);
 
  217       mpfr_add(_vx, _v, _vp, MPFR_RNDN);
 
  219       mpfr_add(_vp, _v, _eps, MPFR_RNDN);
 
  224     int Reject(mpfr_t u, mpfr_t v, mpfr_prec_t prec, mpfr_rnd_t round)
 const {
 
  226       mpfr_set_prec(_x1, prec);
 
  228       mpfr_log(_x1, u, round);
 
  229       mpfr_mul(_x1, _x1, u, round); 
 
  230       mpfr_mul(_x1, _x1, u, round); 
 
  231       mpfr_mul_2ui(_x1, _x1, 2u, round); 
 
  233       mpfr_set_prec(_x2, prec);
 
  234       mpfr_mul(_x2, v, v, round);        
 
  236       mpfr_add(_x1, _x1, _x2, round);    
 
  238       return mpfr_sgn(_x1);
 
  255 #endif  // RANDOMLIB_MPFRNORMALR_HPP 
int operator()(mpfr_t val, gmp_randstate_t r, mpfr_rnd_t round) const 
The normal distribution for MPFR (ratio method).