-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrandkit.pyx
87 lines (65 loc) · 1.8 KB
/
randkit.pyx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# -*- python -*-
#cython: cdivision=False
cimport cython
cdef extern from "randomkit.h":
ctypedef struct rk_state:
unsigned long key[624]
int pos
int has_gauss
double gauss
ctypedef enum rk_error:
RK_NOERR = 0
RK_ENODEV = 1
RK_ERR_MAX = 2
rk_error rk_randomseed(rk_state *state)
unsigned long rk_random(rk_state *state)
double rk_double(rk_state *state)
cdef class Uniform:
cdef rk_state internal_state
cdef double loc
cdef double scale
def __init__(self, double loc=0, double scale=1):
cdef rk_error errcode = rk_randomseed(cython.address(self.internal_state))
self.loc = loc
self.scale = scale
cdef double get(self):
return self.loc + self.scale * rk_double(cython.address(self.internal_state))
def __call__(self):
return self.get()
# -- Example usage --
import time
import numpy as np
d = 6
cdef unsigned int N = 10**d
u = Uniform()
cdef int i
print 'Experiment: taking 1e%d samples\n' % d
print "Taking single samples in a for loop:"
tic = time.time()
for i in range(N):
np.random.uniform()
t0 = time.time() - tic
print 'numpy: %.2f' % t0
tic = time.time()
for i in range(N):
u()
t1 = time.time() - tic
print 'randkit: %.2f (speedup %.2f)\n' % (t1, t0/t1)
print "Taking all samples in a single call:"
tic = time.time()
np.random.uniform(size=N)
t0 = time.time() - tic
print 'numpy with internal loop: %.2f' % t0
cdef class ExampleSampler(Uniform):
cdef unsigned int N
def __init__(self, N):
self.N = N
def take(self):
cdef unsigned int i
for i in range(self.N):
self.get()
e = ExampleSampler(N)
tic = time.time()
e.take()
t1 = time.time() - tic
print 'randkit with internal loop: %.2f (speedup %.2f)' % (t1, t0/t1)