Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index


Thanks for the additional insight.  Well, I can see two possibilities:

1) Use boost's generator for Windows platform-only, while we keep
the glibc's version for Linux.  I wonder what the situation is on
Mac...

2) Use boost's generator for all platforms.

If there are no issues with using boost then I'd suggest 2) and use
boost's implementation of Mersenne Twister (boost::mt19937) as default
for all.

 http://en.wikipedia.org/wiki/Mersenne_twister

I've attached a simple example on how the boost generator works. It
also turns out to be slightly faster than rand().

What is your opinion on implementing generators for other
distributions like normal and all the ones listed under statistics
(which calculate densities but don't generate)? With boost this is
simple so just a matter of extending the UNO interface.

Cheers, Tino
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <boost/random.hpp>
#include <sys/time.h>

// timer
double stoptime(void) {
   struct timeval t;
   gettimeofday(&t,NULL);
   return (double) t.tv_sec + t.tv_usec/1000000.0;
}

// glibc's rand, uniform [0,1]
double grand01() {
   return (1.0/(RAND_MAX+1.0)) * rand();
}

// boost rand, uniform [0,1]
double brand01() {
   static boost::mt19937 rng(time(0));
   static boost::uniform_01<boost::mt19937> rnd01(rng);
   return rnd01();
}

// boost rand, normal N(0,1)
double brand_normal() {
   static boost::mt19937 rng(time(0));
   static boost::variate_generator<boost::mt19937,
                     boost::normal_distribution<> >
                     rnd_normal(rng, boost::normal_distribution<>());
   return rnd_normal();
}



// ======================================================================
//         Name:  main
//  Description:  main function, executed at runtime
// ======================================================================
int main(int argc, char** argv) {

   const int n=10000000;
   double   sum;
   double   t;

   srand(time(0));          // initialise glibc's rand()

   printf("glibc rand uniform: "); fflush(stdout);
   sum=0.0;
   t=stoptime();
   for(int i=0; i<n; i++){
      sum+=grand01();
   }
   printf("avg=%f (%.3fs)\n",sum/n,stoptime()-t); fflush(stdout);

   printf("boost rand uniform: "); fflush(stdout);
   sum=0.0;
   t=stoptime();
   for(int i=0; i<n; i++){
      sum+=brand01();
   }
   printf("avg=%f (%.3fs)\n",sum/n,stoptime()-t); fflush(stdout);

   printf("boost rand normal:  "); fflush(stdout);
   sum=0.0;
   t=stoptime();
   for(int i=0; i<n; i++){
      sum+=brand_normal();
   }
   printf("avg=%f (%.3fs)\n",sum/n,stoptime()-t); fflush(stdout);

   return EXIT_SUCCESS;
}



Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.