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.