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

Reply via email to