void librandom::PoissonRandomDev::set_status( const DictionaryDatum& d ) { /* Limits on mu: - mu >= 0 trivial - As shown in comments in ldev(), the maximum absolute value that can be chosen as a candidate is mu + 710 * sqrt(mu). - We thus must require mu + 710 * sqrt(mu) < max(long). - This is equivalent to mu < ( 2 N + a^2 - sqrt(4 N + a^2) ) / 2 where N is the largest representable integer and a = 710. - Numerical evaluation shows that mu < 0.999 N is safe for 32 and 64 bit doubles with a good margin. */ const double MU_MAX = 0.999 * std::numeric_limits< long >::max(); double new_mu = mu_; if ( updateValue< double >( d, "lambda", new_mu ) ) { if ( new_mu < 0 ) throw BadParameterValue( "Poisson RDV: lambda >= 0 required." ); if ( new_mu > MU_MAX ) throw BadParameterValue( String::compose( "Poisson RDV: lambda < %1 required.", MU_MAX ) ); set_lambda( new_mu ); } }
void librandom::GSL_BinomialRandomDev::set_status( const DictionaryDatum& d ) { double p_new = p_; const bool p_updated = updateValue< double >( d, "p", p_new ); long n_new = n_; const bool n_updated = updateValue< long >( d, "n", n_new ); if ( p_new < 0. || 1. < p_new ) throw BadParameterValue( "gsl_binomial RDV: 0 <= p <= 1 required." ); if ( n_new < 1 ) throw BadParameterValue( "gsl_binomial RDV: n >= 1 required." ); // gsl_ran_binomial() returns unsigned int. To be on the safe side, // we limit here to within ints. const long N_MAX = static_cast< long >( 0.9 * std::numeric_limits< int >::max() ); if ( n_new > N_MAX ) throw BadParameterValue( String::compose( "Gsl_binomial RDV: N < %1 required.", static_cast< double >( N_MAX ) ) ); if ( n_updated || p_updated ) set_p_n( p_new, n_new ); }
void librandom::UniformIntRandomDev::set_status( const DictionaryDatum& d ) { long new_nmin = nmin_; long new_nmax = nmax_; updateValue< long >( d, "low", new_nmin ); updateValue< long >( d, "high", new_nmax ); if ( new_nmax < new_nmin ) { throw BadParameterValue( "Uniformint RDV: low <= high required." ); } // The following test is based on // https://www.securecoding.cert.org/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow // The third condition tests that we can add 1 to the difference; by the time we reach // that clause, we know that the first two are false, so that the difference does not overflow. if ( ( new_nmin > 0 && new_nmax < std::numeric_limits< long >::min() + new_nmin ) || ( new_nmin < 0 && new_nmax > std::numeric_limits< long >::max() + new_nmin ) || ( new_nmax - new_nmin > std::numeric_limits< long >::max() - 1 ) ) { throw BadParameterValue( String::compose( "Uniformint RDV: high - low < %1 required.", static_cast< double >( std::numeric_limits< long >::max() ) ) ); } nmin_ = new_nmin; nmax_ = new_nmax; range_ = nmax_ - nmin_ + 1; }
void librandom::UniformIntRandomDev::set_status( const DictionaryDatum& d ) { long new_nmin = nmin_; long new_nmax = nmax_; updateValue< long >( d, "low", new_nmin ); updateValue< long >( d, "high", new_nmax ); if ( new_nmax < new_nmin ) { throw BadParameterValue( "Uniformint RDV: low <= high required." ); } // The following test is based on // https://www.securecoding.cert.org/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow // Rollover cases (integer bounds min, max): // new_nmax = n+, new_nmin = n- // // a) n+ >= n-: // 1) n- >= 0: 0 <= n+ - n- <= max // 2) n- < 0: 0 <= n+ - n- // must confirm that n+ - n- <= max // // b) n+ < n-: // 1) n- <= 0: 0 > n+ - n- >= min // 2) n- > 0: 0 > n+ - n- // must confirm that n+ - n- >= min // // Case b) is eliminated by the first test above. // Case a) is checked by confirming that // n+ <= max + n- // which can not rollover when n- < 0 // // Additionally, we set range = 1 + (n+ - n-) // a1: n+ - n- < max // n+ < max + n- // a2: n+ - n- < max // // so we need to confirm that n+ - n- != max. // See pull request #61 const long max = std::numeric_limits< long >::max(); if ( ( new_nmin < 0 && new_nmax >= max + new_nmin ) || ( new_nmax - new_nmin == max ) ) { throw BadParameterValue( String::compose( "Uniformint RDV: high - low < %1 required.", static_cast< double >( max ) ) ); } nmin_ = new_nmin; nmax_ = new_nmax; range_ = nmax_ - nmin_ + 1; }
void librandom::GammaRandomDev::set_status(const DictionaryDatum& d) { double a_new = a; double b_new = b_; updateValue<double>(d, "order", a_new); updateValue<double>(d, "scale", b_new); if ( a_new <= 0. ) throw BadParameterValue("Gamma RDV: order > 0 required."); if ( b_new <= 0. ) throw BadParameterValue("Gamma RDV: scale > 0 required."); set_order(a_new); b_ = b_new; }
void librandom::UniformIntRandomDev::set_status(const DictionaryDatum& d) { long new_nmin = nmin_; long new_nmax = nmax_; updateValue<long>(d, "low", new_nmin); updateValue<long>(d, "high", new_nmax); if ( new_nmax < new_nmin ) throw BadParameterValue("Uniformint RDV: low <= high required."); if ( new_nmax - new_nmin < 0 ) throw BadParameterValue(String::compose("Uniformint RDV: high - low < %1 required.", static_cast<double>(std::numeric_limits<long>::max()))); nmin_ = new_nmin; nmax_ = new_nmax; range_ = nmax_ - nmin_ + 1; }
void librandom::ExpRandomDev::set_status( const DictionaryDatum& d ) { double new_lambda = lambda_; updateValue< double >( d, "lambda", new_lambda ); if ( new_lambda <= 0. ) throw BadParameterValue( "Exponential RDV: lambda > 0 required." ); lambda_ = new_lambda; }
void librandom::LognormalRandomDev::set_status( const DictionaryDatum& d ) { double new_mu = mu_; double new_sigma = sigma_; updateValue< double >( d, "mu", new_mu ); updateValue< double >( d, "sigma", new_sigma ); if ( new_sigma < 0. ) throw BadParameterValue( "Lognormal RDV: sigma >= 0 required." ); mu_ = new_mu; sigma_ = new_sigma; }
void librandom::UniformRandomDev::set_status( const DictionaryDatum& d ) { double new_low = low_; double new_high = high_; updateValue< double >( d, "low", new_low ); updateValue< double >( d, "high", new_high ); if ( new_high <= new_low ) throw BadParameterValue( "Uniform RDV: low < high required." ); low_ = new_low; high_ = new_high; delta_ = high_ - low_; }