Changeset 738 for trunk/yat/random


Ignore:
Timestamp:
Jan 8, 2007, 12:08:39 AM (17 years ago)
Author:
Jari Häkkinen
Message:

Fixes #8 and #179, addresses #2.

Location:
trunk/yat/random
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/yat/random/random.cc

    r718 r738  
    2424#include "random.h"
    2525#include "yat/statistics/Histogram.h"
     26#include "yat/utility/Exception.h"
    2627
    2728#include <fstream>
    28 #include <iostream>
     29#include <sstream>
    2930
    3031namespace theplu {
     
    3637  RNG::RNG(void)
    3738  {
    38     gsl_rng_env_setup();  // support rng/seed changes through environment vars
    39     rng_ = gsl_rng_alloc(gsl_rng_default);  // Memory is allocated here!
     39      // support rng/seed changes through environment vars
     40    if (!gsl_rng_env_setup())
     41      throw utility::GSL_error("RNG: unknown generator");
     42    if (!(rng_=gsl_rng_alloc(gsl_rng_default)))
     43      throw utility::GSL_error("RNG: failed to allocate memory");
    4044  }
    4145
     
    105109  RNG_state::RNG_state(const RNG* rng)
    106110  {
    107     rng_ = gsl_rng_clone(rng->rng());
     111    if (!(rng_ = gsl_rng_clone(rng->rng())))
     112      throw utility::GSL_error("RNG_state: failed to allocate memory");
    108113  }
    109114 
     
    146151    gen_ = gsl_ran_discrete_preproc( hist.nof_bins(), p );
    147152    delete p;
     153    if (!gen_)
     154      throw utility::GSL_error("DiscreteGeneral: failed to setup generator.");
    148155  }
    149156
     
    163170
    164171
    165   DiscreteUniform::DiscreteUniform(void)
    166     : range_(rng_->max())
    167   {
    168   }
    169 
    170   DiscreteUniform::DiscreteUniform(const u_long n)
     172  DiscreteUniform::DiscreteUniform(u_long n)
    171173    : range_(n)
    172174  {
    173     if (range_>rng_->max())
    174       range_=rng_->max();
     175    if (range_>rng_->max()) {
     176      std::stringstream ss("DiscreteUniform: ");
     177      ss << n << " is too large for RNG " << rng_->name();
     178      throw utility::GSL_error(ss.str());
     179    }
    175180  }
    176181
     
    178183  u_long DiscreteUniform::operator()(void) const
    179184  {
    180     return gsl_rng_uniform_int(rng_->rng(), range_);
    181   }
    182 
    183 
    184   u_long DiscreteUniform::operator()(const u_long n) const
    185   {
    186     return gsl_rng_uniform_int(rng_->rng(), n);
     185    return (range_ ?
     186            gsl_rng_uniform_int(rng_->rng(), range_) : gsl_rng_get(rng_->rng()));
     187  }
     188
     189
     190  u_long DiscreteUniform::operator()(u_long n) const
     191  {
     192    // making sure that n is not larger than the range of the
     193    // underlying RNG
     194    if (n>rng_->max()) {
     195      std::stringstream ss("DiscreteUniform::op(): ");
     196      ss << n << " is too large for RNG " << rng_->name();
     197      throw utility::GSL_error(ss.str());
     198    }
     199    return gsl_rng_uniform_int(rng_->rng(),n);
    187200  }
    188201
  • trunk/yat/random/random.h

    r718 r738  
    4848  ///
    4949  /// There is information about how to change seeding and generators
    50   /// at run time without recompilation using environment
    51   /// variables. RNG of course support seeding at compile time if you
    52   /// don't want to bother about environment variables and GSL.
     50  /// at run time without recompilation using environment variables in
     51  /// the GSL manual (Chapter on random number generators). RNG of
     52  /// course support seeding at compile time if you don't want to
     53  /// bother about environment variables and GSL.
    5354  ///
    5455  /// There are many different rng's available in GSL. Currently only
     
    6566  /// follow the coding style.)
    6667  ///
    67   /// This implementation may be thread safe (according to GSL
    68   /// documentation), but should be checked to be so before trusting
    69   /// thread safety.
     68  /// The current implementation is NOT thread safe since the RNG is
     69  /// implemented as a singleton. However, the underlying GSL rng's
     70  /// support thread safety since each instance of GSL rng's keep
     71  /// track of their own state accordning to GSL documentation.
    7072  ///
    7173  /// @see Design Patterns (the singleton and adapter pattern). GSL
     
    134136    u_long seed_from_devurandom(void);
    135137
    136     ///
    137     /// @brief set the state
    138     ///
    139     /// @return see gsl_rng_memcpy
    140     ///
     138    /**
     139       \brief Set the state to \a state.
     140
     141       \return 0 on success, non-zero otherwise.
     142
     143       \see gsl_rng_memcpy
     144    */
    141145    int set_state(const RNG_state&);
    142146
     
    276280  {
    277281  public:
    278     ///
    279     /// @brief Default constructor.
    280     ///
    281     DiscreteUniform(void);
    282 
    283     ///
    284     /// @brief Constructor.
    285     ///
    286     /// The generator will generate integers from \f$ [0,n-1] \f$. If
    287     /// \a n is larger than the maximum number the random number
    288     /// generator can return, then (currently) \a n is adjusted
    289     /// appropriately.
    290     ///
    291     /// @todo If a too large \a n is given an exception should be
    292     /// thrown, i.e. the behaviour of this class will change. The case
    293     /// when argument is 0 is not treated gracefully (underlying GSL
    294     /// functionality will not return).
    295     ///
    296     DiscreteUniform(const u_long n);
    297 
    298     ///
    299     /// This function returns a random integer from 0 to n-1
    300     /// inclusive. All integers in the range [0,n-1] are equally
    301     /// likely. n is set in constructor.
    302     ///
     282    /**
     283       \brief Constructor.
     284
     285       The generator will generate integers within the range \f$
     286       [0,n-1] \f$. If \a n is zero, then the whole range of the
     287       underlying RNG will be used \f$ [min,max] \f$. Setting \a n to
     288       zero is the preferred way to sample the whole range of the
     289       underlying RNG, i.e. not setting \n to RNG.max.
     290
     291       \throw If \a n is larger than the maximum number the underlying
     292       random number generator can return, then a GSL_error exception
     293       is thrown.
     294    */
     295    DiscreteUniform(u_long n=0);
     296
     297    /**
     298       \brief Get a random number
     299
     300       The returned integer is either in the range [RNG.min,RNG.max]
     301       or [0,n-1] depending on how the random number generator was
     302       created.
     303
     304       \see DiscreteUniform(const u_long n=0)
     305    */
    303306    u_long operator()(void) const;
    304307
    305     ///
    306     /// This function returns a random integer from 0 to n-1
    307     /// inclusive. All integers in the range [0,n-1] are equally
    308     /// likely.
    309     ///
    310     u_long operator()(const u_long n) const;
     308    /**
     309       \brief Get a random integer in the range \f$ [0,n-1] \f$.
     310
     311       All integers in the range [0,n-1] are equally likely. This
     312       function should be avoided for sampling the whole range of the
     313       underlying RNG.
     314
     315       \throw GSL_error if \an is larger than the range of the
     316       underlying generator.
     317    */
     318    u_long operator()(u_long n) const;
    311319
    312320  private:
Note: See TracChangeset for help on using the changeset viewer.