void drnorm(RngEngine* rng, double* buffer, BlasInt* n, BlasInt* isAligned, RngErrorType* info) { UNUSED(isAligned); if (*n > 0) { #if defined(USE_RNG_BOX_MULLER) for (BlasInt iter = 0; iter < *n; iter += 2) { double x = 2.0 * M_PI * sfmt_genrand_real2(&(rng->m_sfmt)); double z = sqrt(-log(sfmt_genrand_real2(&(rng->m_sfmt)))); double c = cos(x); buffer[iter] = z * c; if (iter + 1 < *n) { double s = sin(x); buffer[iter + 1] = z * s; } } #elif defined(USE_RNG_MARSAGLIA) for (BlasInt iter = 0; iter < *n; ++iter) { double x, y, r; do { x = 2.0 * sfmt_genrand_real2(&(rng->m_sfmt)) - 1.0; y = 2.0 * sfmt_genrand_real2(&(rng->m_sfmt)) - 1.0; r = x * x + y * y; } while (r >= 1 || r == 0); buffer[iter] = x * sqrt(- 2.0 * log(r) / r); } #endif } *info = 0; }
void drunif(RngEngine* rng, double* buffer, BlasInt* n, BlasInt* isAligned, RngErrorType* info) { UNUSED(isAligned); if (*n > 0) { for (BlasInt iter = 0; iter < *n; ++iter) { buffer[iter] = sfmt_genrand_real2(&(rng->m_sfmt)); } } *info = 0; }
int main( int argc, char* argv[] ) { // Time coutning stuff timespec deb, fin, res; clock_t start; double exec; double elapsed; clock_getres(CLOCK_REALTIME, &res); // Create a reference generator sfmt_t an_sfmt; sfmt_t* ref = &an_sfmt; sfmt_init_gen_rand( ref, 25 ); // Create a wrapped generator ae_jumping_mt* my_jumping_mt = new ae_jumping_mt( 25 ); // Generate a few numbers and check printf( "******************** Reals in [0, 1)\n" ); for ( int i = 0 ; i < 5 ; i++ ) { printf( "%f\t\t%f\n", sfmt_genrand_real2( ref ), my_jumping_mt->random() ); } printf( "******************** Integers in [0, 100)\n" ); for ( int i = 0 ; i < 5 ; i++ ) { printf( "%"PRId32"\t\t", (int32_t)( 100.0 * (((double)sfmt_genrand_uint32( ref )) / MT_RAND_MAX_PLUS_1) ) ); printf( "%"PRId32"\n", my_jumping_mt->random( 100 ) ); } // Jump ahead manually start = clock(); clock_gettime(CLOCK_REALTIME, &deb); for ( uint64_t i = 0 ; i < 2000000 ; i++ ) { sfmt_genrand_real2( ref ); } clock_gettime(CLOCK_REALTIME, &fin); elapsed = clock() - start; elapsed = elapsed * 1000 / CLOCKS_PER_SEC; exec = (double) ((fin.tv_nsec - deb.tv_nsec) / 1000); printf( " %u:%u %lu:%lu %lu:%lu exec %f microsecond\n", res.tv_sec, res.tv_nsec, deb.tv_sec, deb.tv_nsec, fin.tv_nsec, fin.tv_sec, exec); printf( "%f ms\n", elapsed ); // Jump ahead with polynomial method start = clock(); clock_gettime(CLOCK_REALTIME, &deb); my_jumping_mt->jump(); clock_gettime(CLOCK_REALTIME, &fin); elapsed = clock() - start; elapsed = elapsed * 1000 / CLOCKS_PER_SEC; exec = (double) ((fin.tv_nsec - deb.tv_nsec) / 1000); printf(" %u:%u %lu:%lu %lu:%lu exec %f microsecond\n", res.tv_sec, res.tv_nsec, deb.tv_sec, deb.tv_nsec, fin.tv_nsec, fin.tv_sec, exec); printf( "%f ms\n", elapsed ); // Generate a few numbers and check printf( "******************** Reals in [0, 1)\n" ); for ( int i = 0 ; i < 20 ; i++ ) { printf( "%f\t\t%f\n", sfmt_genrand_real2( ref ), my_jumping_mt->random() ); } printf( "******************** Integers in [0, 100)\n" ); for ( int i = 0 ; i < 20 ; i++ ) { printf( "%"PRId32"\t\t", (int32_t)( 100.0 * (((double)sfmt_genrand_uint32( ref )) / MT_RAND_MAX_PLUS_1) ) ); printf( "%"PRId32"\n", my_jumping_mt->random( 100 ) ); } //~ gzFile* myFile = (gzFile*) gzopen( "prng.ae", "w" ); //~ my_jumping_mt->save( myFile ); //~ gzclose( myFile ); //~ // Generate a few numbers and check //~ printf( "******************** Reals in [0, 1)\n" ); //~ for ( int i = 0 ; i < 20 ; i++ ) //~ { //~ printf( "%f\n", my_jumping_mt->random() ); //~ } //~ printf( "******************** Integers in [0, 100)\n" ); //~ for ( int i = 0 ; i < 20 ; i++ ) //~ { //~ printf( "%"PRId32"\n", my_jumping_mt->random( 100 ) ); //~ } //~ gzFile* myOtherFile = (gzFile*) gzopen( "prng.ae", "r" ); //~ ae_jumping_mt* my_other_jumping_mt = new ae_jumping_mt( myOtherFile ); //~ gzclose( myOtherFile ); //~ // Generate a few numbers and check //~ printf( "******************** Reals in [0, 1)\n" ); //~ for ( int i = 0 ; i < 20 ; i++ ) //~ { //~ printf( "%f\n", my_other_jumping_mt->random() ); //~ } //~ printf( "******************** Integers in [0, 100)\n" ); //~ for ( int i = 0 ; i < 20 ; i++ ) //~ { //~ printf( "%"PRId32"\n", my_other_jumping_mt->random( 100 ) ); //~ } }
double wrap_genrand_real2(sfmt_t* sfmt) { return sfmt_genrand_real2(sfmt); }