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;
}
Exemple #5
0
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_;
}