Skip to content

Commit b79f304

Browse files
committed
Merge pull request #13 from bashtage/mlfg-64
ENH: Update MLFG to 64 bits
2 parents cebc5df + 985abb4 commit b79f304

File tree

17 files changed

+2172
-2284
lines changed

17 files changed

+2172
-2284
lines changed

README.md

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@ identical sequence of random numbers for a given seed.
3535
## Plans
3636
It is essentially complete. There are a few rough edges that need to be smoothed.
3737

38-
* Document core RNG classes
3938
* Pickling support
40-
* Verify entropy based initialization is missing for some RNGs
41-
* Multiple stream support for MLFG and MRG32K3A
39+
* Verify entropy based initialization for some RNGs
40+
* Stream support for MLFG and MRG32K3A
4241
* Creation of additional streams from a RandomState where supported (i.e.
4342
a `next_stream()` method)
4443

@@ -134,36 +133,36 @@ Performance is promising. Some early numbers:
134133
```
135134
Time to produce 1,000,000 Uniforms
136135
************************************************************
137-
numpy-random-random_sample 11.44 ms
138-
randomstate-mlfg_1279_861-random_sample 7.18 ms
139-
randomstate-mrg32k3a-random_sample 35.70 ms
140-
randomstate-mt19937-random_sample 9.26 ms
141-
randomstate-pcg32-random_sample 6.75 ms
142-
randomstate-pcg64-random_sample 5.79 ms
143-
randomstate-xorshift1024-random_sample 5.73 ms
144-
randomstate-xorshift128-random_sample 5.38 ms
136+
numpy-random-random_sample 13.68 ms
137+
randomstate-mlfg_1279_861-random_sample 6.64 ms
138+
randomstate-mrg32k3a-random_sample 37.87 ms
139+
randomstate-mt19937-random_sample 13.33 ms
140+
randomstate-pcg32-random_sample 10.20 ms
141+
randomstate-pcg64-random_sample 7.83 ms
142+
randomstate-xorshift1024-random_sample 6.20 ms
143+
randomstate-xorshift128-random_sample 5.49 ms
145144
146145
Uniforms per second
147146
************************************************************
148-
numpy-random-random_sample 87.39 million
149-
randomstate-mlfg_1279_861-random_sample 139.27 million
150-
randomstate-mrg32k3a-random_sample 28.01 million
151-
randomstate-mt19937-random_sample 107.94 million
152-
randomstate-pcg32-random_sample 148.16 million
153-
randomstate-pcg64-random_sample 172.63 million
154-
randomstate-xorshift1024-random_sample 174.63 million
155-
randomstate-xorshift128-random_sample 185.83 million
156-
dtype: object
147+
numpy-random-random_sample 73.11 million
148+
randomstate-mlfg_1279_861-random_sample 150.71 million
149+
randomstate-mrg32k3a-random_sample 26.41 million
150+
randomstate-mt19937-random_sample 75.03 million
151+
randomstate-pcg32-random_sample 98.00 million
152+
randomstate-pcg64-random_sample 127.77 million
153+
randomstate-xorshift1024-random_sample 161.39 million
154+
randomstate-xorshift128-random_sample 182.29 million
157155
158156
Speed-up relative to NumPy
159157
************************************************************
160-
randomstate-mlfg_1279_861-random_sample 59.4%
161-
randomstate-mrg32k3a-random_sample -67.9%
162-
randomstate-mt19937-random_sample 23.5%
163-
randomstate-pcg32-random_sample 69.5%
164-
randomstate-pcg64-random_sample 97.5%
165-
randomstate-xorshift1024-random_sample 99.8%
166-
randomstate-xorshift128-random_sample 112.6%
158+
randomstate-mlfg_1279_861-random_sample 106.1%
159+
randomstate-mrg32k3a-random_sample -63.9%
160+
randomstate-mt19937-random_sample 2.6%
161+
randomstate-pcg32-random_sample 34.0%
162+
randomstate-pcg64-random_sample 74.8%
163+
randomstate-xorshift1024-random_sample 120.7%
164+
randomstate-xorshift128-random_sample 149.3%
165+
167166
--------------------------------------------------------------------------------
168167
```
169168

randomstate/__init__.py

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,9 @@
1-
#import randomstate.mlfg_1279_861 as mlfg_1279_861
2-
#import randomstate.mrg32k3a as mrg32k3a
3-
import randomstate.mt19937 as __mt19937
4-
#import randomstate.pcg32 as pcg32
5-
#import randomstate.xorshift1024 as xorshift1024
6-
#import randomstate.xorshift128 as xorshift128
1+
from __future__ import division, absolute_import, print_function
72

8-
#try:
9-
# import randomstate.pcg64
10-
#except ImportError:
11-
# pass
12-
13-
__all__ = ['standard_normal', 'standard_gamma', 'get_state', 'set_state', 'seed', 'bytes',
14-
'standard_exponential', 'standard_cauchy', 'standard_t', 'rand', 'randn']
15-
16-
__rs = __mt19937.RandomState()
17-
RandomState = __mt19937.RandomState
18-
standard_normal = __rs.standard_normal
19-
standard_gamma = __rs.standard_gamma
20-
standard_exponential = __rs.standard_exponential
21-
standard_cauchy = __rs.standard_cauchy
22-
standard_t = __rs.standard_t
23-
random_sample = __rs.random_sample
24-
get_state = __rs.get_state
25-
set_state = __rs.set_state
26-
seed = __rs.seed
27-
bytes = __rs.bytes
28-
randn = __rs.randn
29-
rand = __rs.rand
3+
from randomstate.mt19937 import *
4+
import randomstate.mlfg_1279_861 as mlfg_1279_861
5+
import randomstate.mrg32k3a as mrg32k3a
6+
import randomstate.pcg32 as pcg32
7+
import randomstate.pcg64 as pcg64
8+
import randomstate.xorshift1024 as xorshift1024
9+
import randomstate.xorshift128 as xorshift128

randomstate/setup-all.py

Lines changed: 0 additions & 130 deletions
This file was deleted.
File renamed without changes.

randomstate/setup-wrappers.py

Lines changed: 0 additions & 40 deletions
This file was deleted.
Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
#ifdef _WIN32
23
#include "../../src/common/stdint.h"
34
#define inline __inline
@@ -9,10 +10,6 @@
910
#include "../../src/common/binomial.h"
1011
#include "../../src/mlfg-1279-861/mlfg-1279-861.h"
1112

12-
#define BITMASK_UPPER 0xffff0000
13-
#define BITMAST_UPPER22 0xfffffc00
14-
#define BITMAST_UPPER21 0xfffff800
15-
1613
typedef struct s_aug_state {
1714
mlfg_state *rng;
1815
binomial_t *binomial;
@@ -25,24 +22,13 @@ typedef struct s_aug_state {
2522

2623
inline uint32_t random_uint32(aug_state* state)
2724
{
28-
// Two are needed since there is only 31 bits in each
29-
#if defined(_WIN32) && !defined(_WIN64)
30-
uint32_t a, b;
31-
a = mlfg_next(state->rng) & BITMASK_UPPER;
32-
b = mlfg_next(state->rng) >> 16;
33-
return a | b;
34-
#else
35-
return (mlfg_next(state->rng) & BITMASK_UPPER) | (mlfg_next(state->rng) >> 16);
36-
#endif
25+
return (uint32_t)(mlfg_next(state->rng) >> 32);
3726
}
3827

3928
inline uint64_t random_uint64(aug_state* state)
4029
{
41-
42-
uint64_t out = ((uint64_t)(mlfg_next(state->rng)) & BITMAST_UPPER22) << 32;
43-
out |= ((uint64_t)(mlfg_next(state->rng)) & BITMAST_UPPER21) << 10;
44-
out |= ((mlfg_next(state->rng)) & BITMAST_UPPER21) >> 11;
45-
// Three are needed since there is only 31 bits in each
30+
uint64_t out = mlfg_next(state->rng) & 0xffffffff00000000ULL;
31+
out |= mlfg_next(state->rng) >> 32;
4632
return out;
4733
}
4834

@@ -60,7 +46,10 @@ inline void entropy_init(aug_state* state)
6046

6147
inline double random_double(aug_state* state)
6248
{
63-
// These differ by 1 bit since there are only 31 bits in each
64-
int32_t a = mlfg_next(state->rng) >> 5, b = mlfg_next(state->rng) >> 6;
49+
uint64_t rn;
50+
int32_t a, b;
51+
rn = mlfg_next(state->rng);
52+
a = rn >> 37;
53+
b = (rn & 0xFFFFFFFFULL) >> 6;
6554
return (a * 67108864.0 + b) / 9007199254740992.0;
66-
}
55+
}

0 commit comments

Comments
 (0)