In perl.git, the branch smoke-me/tinymt32 has been updated <http://perl5.git.perl.org/perl.git/commitdiff/02ac7f45ca34f23f6f15ab279233609fd093ba6d?hp=788b2882d693368c817aed0d6ef7992f1f513d5a>
- Log ----------------------------------------------------------------- commit 02ac7f45ca34f23f6f15ab279233609fd093ba6d Author: Yves Orton <demer...@gmail.com> Date: Sun Dec 16 20:31:22 2012 +0100 Enable use of WellRNG512a M perl.h commit 4c81a87c5f8179cc3f84dff4ba0cbfc64b751f14 Author: Yves Orton <demer...@gmail.com> Date: Sun Dec 16 20:30:47 2012 +0100 cleanup tinymt32_ embed.fnc definitions M embed.fnc commit 35d4da9755e789500dbafd0abf67fde9420899d5 Author: Yves Orton <demer...@gmail.com> Date: Sun Dec 16 20:25:29 2012 +0100 Add support for WellRNG 512a This is a "new" random number generator. Derived from code published at: http://www.iro.umontreal.ca/~simardr/rng/WELL512a.c See also: http://www.iro.umontreal.ca/~panneton/WELLRNG.html http://www.iro.umontreal.ca/~panneton/well/WELL512a.c lfsr04.pdf: F. Panneton, P. L'Ecuyer and M. Matsumoto, "Improved Long-Period Generators Based on Linear Recurrences Modulo 2" http://www.iro.umontreal.ca/~lecuyer/myftp/papers/lfsr04.pdf <QUOTE> In this paper, we propose new generators, with better equidistribution and âbit-mixingâ properties for equivalent period length and speed. Approximately half of the coefficients of the characteristic polynomial of these generators are nonzero. The state of our new generators evolves in a more chaotic way than for the Mersenne twister. </QUOTE> Many thanks to Pierre L'Ecuyer for GPL'ing the code so that it could be used in this project. M embed.fnc M embed.h M proto.h M util.c M util.h commit f274a208f6184f953a2912fc531e07651ee68a7a Author: Yves Orton <demer...@gmail.com> Date: Sun Dec 16 20:22:02 2012 +0100 use PL_RANDOM_STATE_TYPE instead of TINYMT32 to control special cases We might support more built in RNG implementations. M intrpvar.h M util.c commit 1912306c75ee44ae411fac97f9ce5c489c263461 Author: Yves Orton <demer...@gmail.com> Date: Sun Dec 16 20:20:45 2012 +0100 Add comment M util.h ----------------------------------------------------------------------- Summary of changes: embed.fnc | 16 +++++++++----- embed.h | 4 +++ intrpvar.h | 4 +- perl.h | 2 +- proto.h | 4 +++ util.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- util.h | 43 ++++++++++++++++++++++++++++++++++++++++- 7 files changed, 122 insertions(+), 12 deletions(-) diff --git a/embed.fnc b/embed.fnc index 1a5746a..7879be0 100644 --- a/embed.fnc +++ b/embed.fnc @@ -1524,12 +1524,16 @@ p |I32 |wait4pid |Pid_t pid|NN int* statusp|int flags : Used in locale.c and perl.c p |U32 |parse_unicode_opts|NN const char **popt #ifdef TINYMT32 -Ap |float |tinymt32_generate_float -Ap |double |tinymt32_generate_double -Ap |U32 |tinymt32_generate_U32 -Ap |U32 |tinymt32_temper -Ap |void |tinymt32_next_state -Ap |void |tinymt32_init |U32 seed +Ap |float |tinymt32_generate_float +Ap |double |tinymt32_generate_double +Ap |U32 |tinymt32_generate_U32 +Ap |U32 |tinymt32_temper +Ap |void |tinymt32_next_state +Ap |void |tinymt32_init |U32 seed +#endif +#ifdef WELLRNG512A +Ap |double |wellrng512a_generate_double +Ap |void |wellrng512a_init |U32 seed #endif Ap |U32 |seed : Only used in perl.c diff --git a/embed.h b/embed.h index 36c5ee5..af205d3 100644 --- a/embed.h +++ b/embed.h @@ -856,6 +856,10 @@ #define PerlIO_unread(a,b,c) Perl_PerlIO_unread(aTHX_ a,b,c) #define PerlIO_write(a,b,c) Perl_PerlIO_write(aTHX_ a,b,c) #endif +#if defined(WELLRNG512A) +#define wellrng512a_generate_double() Perl_wellrng512a_generate_double(aTHX) +#define wellrng512a_init(a) Perl_wellrng512a_init(aTHX_ a) +#endif #if defined(WIN32) || defined(__SYMBIAN32__) || defined(VMS) #define do_aspawn(a,b,c) Perl_do_aspawn(aTHX_ a,b,c) #define do_spawn(a) Perl_do_spawn(aTHX_ a) diff --git a/intrpvar.h b/intrpvar.h index 6fd27f6..3cabffb 100644 --- a/intrpvar.h +++ b/intrpvar.h @@ -800,8 +800,8 @@ PERLVARI(I, xmlfp, PerlIO *, NULL) PERLVARI(I, sv_serial, U32, 0) /* SV serial number, used in sv.c */ #endif -#ifdef TINYMT32 -PERLVAR(I, random_state, tinymt32_t) +#ifdef PL_RANDOM_STATE_TYPE +PERLVAR(I, random_state, PL_RANDOM_STATE_TYPE) #endif /* If you are adding a U8 or U16, check to see if there are 'Space' comments diff --git a/perl.h b/perl.h index 09b359b..bfa2ad1 100644 --- a/perl.h +++ b/perl.h @@ -11,7 +11,7 @@ #ifndef H_PERL #define H_PERL 1 -#define TINYMT32 +#define WELLRNG512A #ifdef PERL_FOR_X2P /* diff --git a/proto.h b/proto.h index 51d706a..358c035 100644 --- a/proto.h +++ b/proto.h @@ -7786,6 +7786,10 @@ PERL_CALLCONV SSize_t Perl_PerlIO_write(pTHX_ PerlIO *f, const void *vbuf, Size_ assert(vbuf) #endif +#if defined(WELLRNG512A) +PERL_CALLCONV double Perl_wellrng512a_generate_double(pTHX); +PERL_CALLCONV void Perl_wellrng512a_init(pTHX_ U32 seed); +#endif #if defined(WIN32) PERL_CALLCONV_NO_RET void win32_croak_not_implemented(const char * fname) __attribute__noreturn__ diff --git a/util.c b/util.c index 3c67e4b..31d9c1e 100644 --- a/util.c +++ b/util.c @@ -5690,6 +5690,65 @@ Perl_tinymt32_init(pTHX_ U32 seed) Perl_tinymt32_next_state(aTHX); } } +#elif defined(WELLRNG512A) +/* This is WellRNG512a obtained from + * + * http://www.iro.umontreal.ca/~simardr/rng/WELL512a.c + * + * See also: + * + * http://www.iro.umontreal.ca/~panneton/WELLRNG.html + * http://www.iro.umontreal.ca/~panneton/well/WELL512a.c + * + * lfsr04.pdf: F. Panneton, P. L'Ecuyer and M. Matsumoto, "Improved Long-Period Generators Based on Linear Recurrences Modulo 2" + * http://www.iro.umontreal.ca/~lecuyer/myftp/papers/lfsr04.pdf + * + * <QUOTE> + * In this paper, we propose new generators, with better equidistribution and âbit-mixingâ + * properties for equivalent period length and speed. Approximately half of the coefficients + * of the characteristic polynomial of these generators are nonzero. The state of our new + * generators evolves in a more chaotic way than for the Mersenne twister. + * </QUOTE> + */ +/* ***************************************************************************** */ +/* Copyright: Francois Panneton and Pierre L'Ecuyer, University of Montreal */ +/* Makoto Matsumoto, Hiroshima University */ +/* Notice: This code can be used freely for personal, academic, */ +/* or non-commercial purposes. For commercial purposes, */ +/* please contact P. L'Ecuyer at: lecu...@iro.umontreal.ca */ +/* */ +/* This code can also be used under the terms of the GNU General Public */ +/* License as published by the Free Software Foundation, either version 3 */ +/* of the License, or any later version. See the GPL licence at URL */ +/* http://www.gnu.org/licenses */ +/* ***************************************************************************** */ +/* Changes made to conform to Perl internals expectations by Yves Orton. */ +/* Many thanks to the authors for the GPL release of the code */ +/* ***************************************************************************** */ + +void +Perl_wellrng512a_init(pTHX_ U32 seed) { + int j; + PL_random_state.state_i = 0; + PL_random_state.STATE[0] = seed; + for (j = 1; j < WELLRNG_R; j++) { + U32 l = PL_random_state.STATE[ j - 1 ]; + PL_random_state.STATE[j] = ( 1812433253l * ( l ^ ( l >> 30 ) ) + j ); + } +} + +double +Perl_wellrng512a_generate_double(pTHX){ + U32 z0 = WELLRNG_VRm1; + U32 z1 = WELLRNG_MAT0NEG(-16, WELLRNG_V0) ^ WELLRNG_MAT0NEG(-15, WELLRNG_VM1); + U32 z2 = WELLRNG_MAT0POS( 11, WELLRNG_VM2); + WELLRNG_newV1 = z1 ^ z2; + WELLRNG_newV0 = WELLRNG_MAT0NEG(-2, z0) ^ WELLRNG_MAT0NEG(-18, z1) + ^ WELLRNG_MAT3NEG(-28, z2) ^ WELLRNG_MAT4NEG(-5, 0xda442d24U, WELLRNG_newV1); + PL_random_state.state_i = (PL_random_state.state_i + 15) & 0x0000000fU; + return ((double) PL_random_state.STATE[PL_random_state.state_i]) * WELLRNG_FACT; +} + #endif #ifdef VMS @@ -5711,7 +5770,7 @@ Perl_seed(pTHX) * value from (tv_sec * SEED_C1 + tv_usec). The multipliers should * probably be bigger too. */ -#if defined(TINYMT32) || (RANDBITS > 16) +#if defined(PL_RANDOM_STATE_TYPE) || (RANDBITS > 16) # define SEED_C1 1000003 # define SEED_C4 73819 #else diff --git a/util.h b/util.h index 365b694..27170f8 100644 --- a/util.h +++ b/util.h @@ -76,14 +76,53 @@ struct TINYMT32_T { typedef struct TINYMT32_T tinymt32_t; #define PL_RANDOM_STATE_TYPE tinymt32_t - #define _SEED_RAND(x) tinymt32_init((U32)x) #define RAND01() tinymt32_generate_double() -#else /* dont use tinymt32 */ +#elif defined(WELLRNG512A) + +#define WELLRNG_W 32 +#define WELLRNG_R 16 +#define WELLRNG_P 0 +#define WELLRNG_M1 13 +#define WELLRNG_M2 9 +#define WELLRNG_M3 5 + +#define WELLRNG_K1 15 +#define WELLRNG_K2 14 + +#define WELLRNG_MAT0POS(t,v) ( v ^ ( v >> t ) ) +#define WELLRNG_MAT0NEG(t,v) ( v ^ ( v << ( -(t) ) ) ) +#define WELLRNG_MAT3NEG(t,v) ( v << ( -(t) ) ) +#define WELLRNG_MAT4NEG(t,b,v) ( v ^ ( ( v << ( -(t) ) ) & b ) ) + +#define WELLRNG_V0 PL_random_state.STATE[ PL_random_state.state_i ] +#define WELLRNG_VM1 PL_random_state.STATE[(PL_random_state.state_i + WELLRNG_M1) & 0x0000000fU ] +#define WELLRNG_VM2 PL_random_state.STATE[(PL_random_state.state_i + WELLRNG_M2) & 0x0000000fU ] +#define WELLRNG_VM3 PL_random_state.STATE[(PL_random_state.state_i + WELLRNG_M3) & 0x0000000fU ] +#define WELLRNG_VRm1 PL_random_state.STATE[(PL_random_state.state_i + WELLRNG_K1) & 0x0000000fU ] +#define WELLRNG_VRm2 PL_random_state.STATE[(PL_random_state.state_i + WELLRNG_K2) & 0x0000000fU ] +#define WELLRNG_newV0 PL_random_state.STATE[(PL_random_state.state_i + WELLRNG_K1) & 0x0000000fU ] +#define WELLRNG_newV1 PL_random_state.STATE[ PL_random_state.state_i ] +#define WELLRNG_newVRm1 PL_random_state.STATE[(PL_random_state.state_i + WELLRNG_K2) & 0x0000000fU ] + +#define WELLRNG_FACT 2.32830643653869628906e-10 + +struct WELLRNG512A_T { + U32 state_i; + U32 STATE[WELLRNG_R]; +}; +typedef struct WELLRNG512A_T wellring512a_t; + +#define PL_RANDOM_STATE_TYPE wellring512a_t +#define _SEED_RAND(x) wellrng512a_init((U32)x) +#define RAND01() wellrng512a_generate_double() + +#else /* dont use tinymt32 or wellrng512a */ #define _SEED_RAND(x) (void)seedDrand01((Rand_seed_t)x) #define RAND01() Drand01() +/* PL_RANDOM_STATE_TYPE not defined here as it is not used in this configuration */ #endif -- Perl5 Master Repository