-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathprovider.py
97 lines (82 loc) · 3.11 KB
/
provider.py
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
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env python3
# −*− coding:utf-8 −*−
import numpy as np
from bitstring import Bits, ConstBitStream
class Provide(object):
'''
A class interpreting a string of random bits in a sophisticated manner,
so as to provide three major categories of random numbers:
1. uniformly drawn random integers,
2. uniformly drawn random decimals,
3. normally distributed complex random numbers.
'''
def __init__(self, source):
'''
Parameters:
source: str
Random-bit source file generated by RANDOM.ORG.
'''
self.source = source
def integer(self, N, M, offset=0):
'''
Provide an array of random integers following uniform distribution.
Parameters:
N: int
Amount of provided integers.
M: int
Upper range (exclusive) of the integers,
Which can only take a value among 0, 1, ..., M-1.
offset: int
Amount of bits at the beginning of the file to be skipped over.
Returns:
result: 1d numpy array
'''
width = int(np.ceil(np.log2(M)))
blob = ConstBitStream(filename=self.source)
result = np.empty(N, dtype="u4") # 32-bit unsigned integer in native endian
blob.pos = offset
for i in range(N):
while True:
number = blob.read(width).uint
if number < M:
result[i] = number
break
return result
def uniform(self, N, offset=0):
'''
Provide an array of random decimals following uniform distribution
in the half-open range [0, 1).
Parameters:
N: int
Amount of provided decimals.
offset: int
Amount of bits at the beginning of the file to be skipped over.
Returns:
result: 1d numpy array
'''
sign = '0' # sign bit denoting positive
exponent = '0' + '1' * 10 # exponent bits denoting 0
prefix = "0b" + sign + exponent # the bit order entails big endian
blob = Bits(filename=self.source, length=52*N, offset=offset)
buf = Bits().join([prefix+mantissa for mantissa in blob.cut(52)])
result = np.frombuffer(buf.bytes, dtype=">f8") - 1 # 64-bit double precision in big endian
return result
def gaussian(self, N, offset=0):
'''
Provide an array of complex random numbers following the
standard complex Gaussian distribution (zero mean, unit variance).
Parameters:
N: int
Amount of provided complex numbers.
offset: int
Amount of bits at the beginning of the file to be skipped over.
Returns:
result: 1d numpy array
'''
decimals = self.uniform(2*N, offset)
result = np.sqrt(-np.log(decimals[::2])) * np.exp(2j*np.pi*decimals[1::2])
return result
if __name__ == "__main__":
provide = Provide("2019-10-24.bin")
integers = provide.integer(100, 6)
print(integers.reshape(10,10))