Changeset 2802


Ignore:
Timestamp:
Jul 29, 2012, 12:13:39 PM (11 years ago)
Author:
Peter
Message:

adding documentation and tests. Remove private member count_ (not needed). closes #568

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/test/rng-mt.cc

    r2769 r2802  
    3131#include <vector>
    3232
     33using namespace theplu::yat;
    3334using namespace theplu::yat::random;
    3435
     
    5152};
    5253
     54void test1(test::Suite& suite);
     55void test2(test::Suite& suite);
     56void test3(test::Suite& suite);
    5357
    5458int main(int argc, char* argv[])
    5559{
    5660  theplu::yat::test::Suite suite(argc, argv);
    57   int nof_cpu = boost::thread::hardware_concurrency();
    58   suite.out() << "Number of processors: " << nof_cpu << "\n";
     61  test1(suite);
     62  test2(suite);
     63  test3(suite);
    5964
     65  return suite.return_value();
     66}
     67
     68
     69void test1(test::Suite& suite)
     70{
     71  suite.out() << "test1\n";
    6072  boost::thread_group threads;
    6173
     
    7587  suite.out() << "\n";
    7688
    77   return suite.return_value();
     89  if (x==y) {
     90    suite.add(false);
     91    suite.err() << "x and y are equal\n";
     92  }
     93
    7894}
     95
     96
     97void test2(test::Suite& suite)
     98{
     99  suite.out() << "test2\n";
     100  // test that we get same number with same seed
     101  RNG::instance()->seed(0);
     102  std::vector<int> x(10);
     103  Visitor visitor1(x);
     104  boost::thread_group threads;
     105  threads.create_thread(visitor1);
     106  threads.join_all();
     107  std::vector<int> y(x);
     108  RNG::instance()->seed(0);
     109  threads.create_thread(visitor1);
     110  threads.join_all();
     111  suite.out() << "x: ";
     112  std::copy(x.begin(), x.end(), std::ostream_iterator<int>(suite.out(), " "));
     113  suite.out() << "\ny: ";
     114  std::copy(y.begin(), y.end(), std::ostream_iterator<int>(suite.out(), " "));
     115  suite.out() << "\n";
     116  if (x!=y) {
     117    suite.add(false);
     118    suite.err() << "x not equal to y\n";
     119  }
     120  else {
     121    suite.out() << "ok\n";
     122  }
     123}
     124
     125
     126void test3(test::Suite& suite)
     127{
     128  suite.out() << "test3\n";
     129  // test that we get different numbers in thread in which we seed RNG
     130  // and subsequent thread
     131  RNG::instance()->seed(1);
     132  std::vector<int> x(10);
     133  Visitor visitor(x);
     134  visitor();
     135
     136  std::vector<int> y(x);
     137  Visitor visitor1(y);
     138  boost::thread_group threads;
     139  threads.create_thread(visitor1);
     140  threads.join_all();
     141
     142  suite.out() << "x: ";
     143  std::copy(x.begin(), x.end(), std::ostream_iterator<int>(suite.out(), " "));
     144  suite.out() << "\ny: ";
     145  std::copy(y.begin(), y.end(), std::ostream_iterator<int>(suite.out(), " "));
     146  suite.out() << "\n";
     147
     148  if (x==y) {
     149    suite.add(false);
     150    suite.err() << "x equal to y\n";
     151  }
     152  else {
     153    suite.out() << "ok\n";
     154  }
     155}
  • trunk/yat/random/random.cc

    r2800 r2802  
    4343      throw utility::GSL_error("RNG::RNG unknown generator");
    4444    seed_ = gsl_rng_default_seed;
    45     count_ = 0;
     45    // let's allocate already here, just to behave as yat 0.8
     46    rng_alloc();
    4647  }
    4748
     
    9293    if (!rng)
    9394      throw utility::GSL_error("RNG failed to allocate memory");
    94     ++count_;
    95     // we init/seed subsequent generators with seed_+count_ to achieve two
    96     // things: 1) seed_ imlies that changing seed_ via seed(1),
    97     // seed_from_devurandom(), or environment will effect all
    98     // generators allocated subsequently. 2) Adding count_ implies
    99     // different generators are different.
    100     if (count_>1)
    101       gsl_rng_set(rng, seed_+count_);
     95    gsl_rng_set(rng, seed_);
     96    // bump seed to avoid subsequent gsl_rng to be identical
     97    ++seed_;
    10298    // rng_ owns rng and takes care of deallocation
    10399    rng_.reset(rng);
     
    107103  void RNG::seed(unsigned long s) const
    108104  {
    109     seed_ = s;
    110     count_ = 0;
    111105    gsl_rng_set(rng(),s);
     106    seed_ = s+1;
    112107  }
    113108
  • trunk/yat/random/random.h

    r2800 r2802  
    4848  ///
    4949  /// The RNG class is wrapper to the GSL random number generator
    50   /// (rng). This class provides a single global instance of the rng,
    51   /// and makes sure there is only one point of access to the
    52   /// generator.
     50  /// (rng). In yat 0.8 (or older) this class provided a single global
     51  /// instance of the rng, and made sure there was only one point of
     52  /// access to the generator. Since version 0.9 this class provides
     53  /// one rng per thread in order to avoid collisions in multi-thread
     54  /// applications.
     55  ///
     56  /// There are many different rng's available in GSL. RNG uses the
     57  /// default generator, unless the global variable \c gsl_rng_default
     58  /// has been modified (see <a
     59  /// href=\gsl_url/Random-number-environment-variables.html>GSL
     60  /// Manual</a>). Note, \c gsl_rng_default should be changed before
     61  /// RNG creates its generator and safest way to achieve this is to
     62  /// modify \c gsl_rng_default prior calling instance() the first
     63  /// time.
    5364  ///
    5465  /// There is information about how to change seeding and generators
    5566  /// at run time without recompilation using environment variables in
    56   /// the GSL manual (Chapter on random number generators). RNG of
    57   /// course support seeding at compile time if you don't want to
    58   /// bother about environment variables and GSL.
    59   ///
    60   /// There are many different rng's available in GSL. Currently only
    61   /// the default generator is implemented and no other one is
    62   /// choosable through the class interface. This means that you have
    63   /// to fall back to the use of environment variables as described in
    64   /// the GSL documentation, or be bold and request support for other
    65   /// rng's through the class interface.
    66   ///
    67   /// Not all GSL functionality is implemented, we'll add
    68   /// functionality when needed and may do it when requested. Better
    69   /// yet, supply us with code and we will probably add it to the code
    70   /// (BUT remember to implement reasonable tests for your code and
    71   /// follow the coding style.)
    72   ///
    73   /// The current implementation is NOT thread safe since the RNG is
    74   /// implemented as a singleton. However, the underlying GSL rng's
    75   /// support thread safety since each instance of GSL rng's keep
    76   /// track of their own state accordning to GSL documentation.
    77   ///
    78   /// @see Design Patterns (the singleton and adapter pattern). GSL
    79   /// documentation.
     67  /// the <a
     68  /// href=\gsl_url/Random-number-environment-variables.html>GSL
     69  /// Manual</a>. RNG supports seeding at compile time if you don't
     70  /// want to bother about environment variables and GSL.
     71  ///
     72  /// The class provides one generator per thread. The first generator
     73  /// created is seeded with \c gsl_rng_default_seed and subsequent
     74  /// generators are seeded with \c gsl_rng_default_seed + 1, \c
     75  /// gsl_rng_default_seed + 2 etc, unless the seed has been modified
     76  /// with seed() or seed_from_devurandom().
     77  ///
     78  /// @see Design Patterns (the singleton and adapter pattern). <a
     79  /// href=\gsl_url/Random-Number-Generation.html>GSL documentation</a>.
    8080  ///
    8181  class RNG
     
    8484
    8585    ///
    86     /// @brief Get an instance of the random number generator.
    87     ///
    88     /// Get an instance of the random number generator. If the random
    89     /// number generator is not already created, the call will create
    90     /// a new generator and use the default seed. The seed must be
     86    /// @brief Get an instance of the Random Number Generator.
     87    ///
     88    /// Get an instance of RNG. If a random number generator is not
     89    /// already created for current thread, the call will create a new
     90    /// generator of type \c gsl_rng_default. If it is the first
     91    /// generator created it will be seeded with \c
     92    /// gsl_rng_default_seed; otherwise created generator will be
     93    /// seeded with \c seed + \c n, where \c seed is the latest seed
     94    /// set (with seed() or seed_from_devurandom()) The seed may be
    9195    /// changed with the seed or seed_from_devurandom member
    9296    /// functions.
     
    115119    std::string name(void) const;
    116120
     121    ///
     122    /// Access underlying GSL random number generator speicific to
     123    /// current thread. Behaviour of returned generator is undefined
     124    /// outside current thread.
    117125    ///
    118126    /// @return const pointer to underlying GSL random generator.
     
    127135    /// documentation).
    128136    ///
     137    /// This function will also effect generators created subsequently
     138    /// in other threads. The seed \a s is saved and subsequent
     139    /// generators will be created with seed \c s + 1, \c s + 2, etc.
     140    ///
    129141    /// @see seed_from_devurandom
    130142    ///
     
    134146    /// @brief Seed the rng using the /dev/urandom device.
    135147    ///
     148    /// This function will also effect generators in other threads
     149    /// created subsequntly (see seed()).
     150    ///
    136151    /// @return The seed acquired from /dev/urandom.
    137152    ///
     
    142157
    143158       \return 0 on success, non-zero otherwise.
     159
     160       \note this function only effects the RNG in current thread
    144161
    145162       \see gsl_rng_memcpy
     
    172189    // gsl_rng is allocated if necessary.
    173190    mutable boost::thread_specific_ptr<gsl_rng> rng_;
    174     // count_ indicates how many gsl_rng that has been allocated after
    175     // seed_ changed.
    176     mutable unsigned int count_;
    177     mutable unsigned long seed_; // need to be mutable since seed() is const:(
     191    mutable unsigned long seed_;
    178192  };
    179193
Note: See TracChangeset for help on using the changeset viewer.