summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--rngtest.c81
-rw-r--r--stc/crandom.h78
2 files changed, 21 insertions, 138 deletions
diff --git a/rngtest.c b/rngtest.c
index 8987ff5d..b24caaa9 100644
--- a/rngtest.c
+++ b/rngtest.c
@@ -7,73 +7,6 @@
#endif
-
-/* Period parameters */
-#define N 624
-#define M 397
-#define MATRIX_A 0x9908b0dfUL /* constant vector a */
-#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
-#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
-
-static unsigned long mt[N]; /* the array for the state vector */
-static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
-
-/* initializes mt[N] with a seed */
-void init_genrand(unsigned long s)
-{
- mt[0]= s & 0xffffffffUL;
- for (mti=1; mti<N; mti++) {
- mt[mti] =
- (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
- /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
- /* In the previous versions, MSBs of the seed affect */
- /* only MSBs of the array mt[]. */
- /* 2002/01/09 modified by Makoto Matsumoto */
- mt[mti] &= 0xffffffffUL;
- /* for >32 bit machines */
- }
-}
-
-/* generates a random number on [0,0xffffffff]-interval */
-unsigned long genrand_int32(void)
-{
- unsigned long y;
- static unsigned long mag01[2]={0x0UL, MATRIX_A};
- /* mag01[x] = x * MATRIX_A for x=0,1 */
-
- if (mti >= N) { /* generate N words at one time */
- int kk;
-
- if (mti == N+1) /* if init_genrand() has not been called, */
- init_genrand(5489UL); /* a default initial seed is used */
-
- for (kk=0;kk<N-M;kk++) {
- y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
- mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
- }
- for (;kk<N-1;kk++) {
- y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
- mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
- }
- y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
- mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
-
- mti = 0;
- }
-
- y = mt[mti++];
-
- /* Tempering */
- y ^= (y >> 11);
- y ^= (y << 7) & 0x9d2c5680UL;
- y ^= (y << 15) & 0xefc60000UL;
- y ^= (y >> 18);
-
- return y;
-}
-
-
-
#define NN 1000000000
int main(void)
@@ -82,15 +15,6 @@ int main(void)
uint64_t v;
printf("start\n");
- before = clock(); \
- v = 0;
- for (size_t i=0; i<NN; i++) {
- v += genrand_int32();
- }
- difference = clock() - before;
- printf("refmt: %.02f, %llu\n", (float) difference / CLOCKS_PER_SEC, v);
-
-
mt19937_t state = mt19937_default();
before = clock(); \
@@ -99,7 +23,7 @@ int main(void)
v += mt19937_rand(&state);
}
difference = clock() - before;
- printf("mymt : %.02f, %llu\n", (float) difference / CLOCKS_PER_SEC, v);
+ printf("my-mt: %.02f, %llu\n", (float) difference / CLOCKS_PER_SEC, v);
#ifdef __cplusplus
std::mt19937 mt_rand;
@@ -131,7 +55,7 @@ int main(void)
difference = clock() - before;
printf("sfc64: %.02f, %llu\n", (float) difference / CLOCKS_PER_SEC, v);
-
+/*
before = clock(); \
v = 0;
for (size_t i=0; i<NN; i++) {
@@ -139,4 +63,5 @@ int main(void)
}
difference = clock() - before;
printf("rand : %.02f, %llu\n", (float) difference / CLOCKS_PER_SEC, v);
+*/
} \ No newline at end of file
diff --git a/stc/crandom.h b/stc/crandom.h
index 064c86eb..2bf88028 100644
--- a/stc/crandom.h
+++ b/stc/crandom.h
@@ -1,75 +1,32 @@
#ifndef CRANDOM__H__
#define CRANDOM__H__
-/*
- Mersenne Twister random number generator MT19937, 32 bit.
- A C-program for MT19937, with initialization improved 2002/1/26.
- Coded by Takuji Nishimura and Makoto Matsumoto.
- Optimized by Tyge Løvset.
-
- Before using, initialize the state by using mt19937_init(),
- mt19937_seed() or mt19937_default().
-
- Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. The names of its contributors may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Any feedback is very welcome.
- http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
- email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
-*/
#include <stdint.h>
-enum { /* period parameters */
+/*
+ * Mersenne Twister random number generator MT19937, 32 bit.
+ */
+
+enum {
mt19937_N = 624,
mt19937_M = 397,
};
typedef struct mt19937 {
- uint_fast32_t idx;
- uint_fast32_t arr[mt19937_N]; /* the array for the state vector */
+ uint32_t idx;
+ uint32_t arr[mt19937_N];
} mt19937_t;
/* initializes state with a seed */
-static inline void mt19937_init(mt19937_t *state, uint_fast32_t seed) {
+static inline void mt19937_init(mt19937_t *state, uint32_t seed) {
state->idx = mt19937_N;
state->arr[0] = seed;
for (int i = 1; i < mt19937_N; ++i) {
seed = state->arr[i] = 1812433253 * (seed ^ (seed >> 30)) + i;
- /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
- /* In the previous versions, MSBs of the seed affect */
- /* only MSBs of the array arr[]. */
- /* 2002/01/09 modified by Makoto Matsumoto */
}
}
/* creates a new state from a seed */
-static inline mt19937_t mt19937_seed(uint_fast32_t seed) {
+static inline mt19937_t mt19937_seed(uint32_t seed) {
mt19937_t state;
mt19937_init(&state, seed);
return state;
@@ -82,10 +39,10 @@ static inline mt19937_t mt19937_default(void) {
}
/* generates a random number on [0, 0xffffffff]-interval */
-static inline uint_fast32_t mt19937_rand(mt19937_t *state) {
+static inline uint32_t mt19937_rand(mt19937_t *state) {
enum {N = mt19937_N, M = mt19937_M};
- uint_fast32_t y, *arr = state->arr;
+ uint32_t y, *arr = state->arr;
if (state->idx >= N) { /* generate N words at one time */
int k = 0;
for (; k < N-M; ++k) {
@@ -110,7 +67,9 @@ static inline uint_fast32_t mt19937_rand(mt19937_t *state) {
return y;
}
-/* xoroshiro128** and xoshiro128** with splitmix64 seed initialization */
+/*
+ * xoroshiro128** with splitmix64 seed initialization
+ */
static inline uint64_t splitmix64(uint64_t *state) {
uint64_t z = (*state += 0x9e3779b97f4a7c15);
@@ -123,8 +82,6 @@ static inline uint64_t c_rotl(uint64_t x, int s) {
return (x << s) | (x >> (64 - s));
}
-/* xoroshiro128** */
-
typedef struct xoroshiro128ss {
uint64_t s[2];
} xoroshiro128ss_t;
@@ -146,13 +103,14 @@ static inline uint64_t xoroshiro128ss_rand(xoroshiro128ss_t *state) {
return result;
}
-/* http://pracrand.sourceforge.net */
+/*
+ * sfc64: http://pracrand.sourceforge.net
+ */
typedef struct sfc64 {
uint64_t s[3], counter;
} sfc64_t;
-
static inline uint64_t sfc64_rand(sfc64_t* state) {
enum {LROT = 24, RSHIFT = 11, LSHIFT = 3};
uint64_t *s = state->s;
@@ -160,7 +118,7 @@ static inline uint64_t sfc64_rand(sfc64_t* state) {
uint64_t result = s[0] + s[1] + ++state->counter;
s[0] = s[1] ^ (s[1] >> RSHIFT);
s[1] = s[2] + (s[2] << LSHIFT);
- s[2] = ((s[2] << LROT) | (s[2] >> (64-LROT))) + result;
+ s[2] = c_rotl(s[2], LROT) + result;
return result;
}