/
sample.py
239 lines (182 loc) · 7.85 KB
/
sample.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
import six
from cupy import core
from cupy.creation import basic
from cupy.random import distributions
from cupy.random import generator
def rand(*size, **kwarg):
"""Returns an array of uniform random values over the interval ``[0, 1)``.
Each element of the array is uniformly distributed on the half-open
interval ``[0, 1)``. All elements are identically and independently
distributed (i.i.d.).
Args:
size (ints): The shape of the array.
dtype: Data type specifier. Only :class:`numpy.float32` and
:class:`numpy.float64` types are allowed. The default is
:class:`numpy.float64`.
Returns:
cupy.ndarray: A random array.
.. seealso:: :func:`numpy.random.rand`
.. admonition:: Example
.. code-block:: python
>>> cupy.random.rand(3, 2)
array([[0.86476479, 0.05633727], # random
[0.27283185, 0.38255354], # random
[0.16592278, 0.75150313]]) # random
>>> cupy.random.rand(3, 2, dtype=cupy.float32)
array([[0.9672306 , 0.9590486 ], # random
[0.6851264 , 0.70457625], # random
[0.22382522, 0.36055237]], dtype=float32) # random
"""
dtype = kwarg.pop('dtype', float)
if kwarg:
raise TypeError('rand() got unexpected keyword arguments %s'
% ', '.join(kwarg.keys()))
return random_sample(size=size, dtype=dtype)
def randn(*size, **kwarg):
"""Returns an array of standard normal random values.
Each element of the array is normally distributed with zero mean and unit
variance. All elements are identically and independently distributed
(i.i.d.).
Args:
size (ints): The shape of the array.
dtype: Data type specifier. Only :class:`numpy.float32` and
:class:`numpy.float64` types are allowed.
The default is :class:`numpy.float64`.
Returns:
cupy.ndarray: An array of standard normal random values.
.. seealso:: :func:`numpy.random.randn`
.. admonition:: Example
.. code-block:: python
>>> cupy.random.randn(3, 2)
array([[0.41193321, 1.59579542], # random
[0.47904589, 0.18566376], # random
[0.59748424, 2.32602829]]) # random
>>> cupy.random.randn(3, 2, dtype=cupy.float32)
array([[ 0.1373886 , 2.403238 ], # random
[ 0.84020025, 1.5089266 ], # random
[-1.2268474 , -0.48219103]], dtype=float32) # random
"""
dtype = kwarg.pop('dtype', float)
if kwarg:
raise TypeError('randn() got unexpected keyword arguments %s'
% ', '.join(kwarg.keys()))
return distributions.normal(size=size, dtype=dtype)
def randint(low, high=None, size=None, dtype='l'):
"""Returns a scalar or an array of integer values over ``[low, high)``.
Each element of returned values are independently sampled from
uniform distribution over left-close and right-open interval
``[low, high)``.
Args:
low (int): If ``high`` is not ``None``,
it is the lower bound of the interval.
Otherwise, it is the **upper** bound of the interval
and lower bound of the interval is set to ``0``.
high (int): Upper bound of the interval.
size (None or int or tuple of ints): The shape of returned value.
dtype: Data type specifier.
Returns:
int or cupy.ndarray of ints: If size is ``None``,
it is single integer sampled.
If size is integer, it is the 1D-array of length ``size`` element.
Otherwise, it is the array whose shape specified by ``size``.
"""
rs = generator.get_random_state()
return rs.randint(low, high, size, dtype)
def random_integers(low, high=None, size=None):
"""Return a scalar or an array of integer values over ``[low, high]``
Each element of returned values are independently sampled from
uniform distribution over closed interval ``[low, high]``.
Args:
low (int): If ``high`` is not ``None``,
it is the lower bound of the interval.
Otherwise, it is the **upper** bound of the interval
and the lower bound is set to ``1``.
high (int): Upper bound of the interval.
size (None or int or tuple of ints): The shape of returned value.
Returns:
int or cupy.ndarray of ints: If size is ``None``,
it is single integer sampled.
If size is integer, it is the 1D-array of length ``size`` element.
Otherwise, it is the array whose shape specified by ``size``.
"""
if high is None:
high = low
low = 1
return randint(low, high + 1, size)
def random_sample(size=None, dtype=float):
"""Returns an array of random values over the interval ``[0, 1)``.
This is a variant of :func:`cupy.random.rand`.
Args:
size (int or tuple of ints): The shape of the array.
dtype: Data type specifier. Only :class:`numpy.float32` and
:class:`numpy.float64` types are allowed.
Returns:
cupy.ndarray: An array of uniformly distributed random values.
.. seealso:: :func:`numpy.random.random_sample`
"""
rs = generator.get_random_state()
return rs.random_sample(size=size, dtype=dtype)
def choice(a, size=None, replace=True, p=None):
"""Returns an array of random values from a given 1-D array.
Each element of the returned array is independently sampled
from ``a`` according to ``p`` or uniformly.
.. note::
Currently ``p`` is not supported when ``replace=False``.
Args:
a (1-D array-like or int):
If an array-like,
a random sample is generated from its elements.
If an int, the random sample is generated as if ``a`` was
``cupy.arange(n)``
size (int or tuple of ints): The shape of the array.
replace (boolean): Whether the sample is with or without replacement.
p (1-D array-like):
The probabilities associated with each entry in ``a``.
If not given the sample assumes a uniform distribution over all
entries in ``a``.
Returns:
cupy.ndarray: An array of ``a`` values distributed according to
``p`` or uniformly.
.. seealso:: :func:`numpy.random.choice`
"""
rs = generator.get_random_state()
return rs.choice(a, size, replace, p)
def multinomial(n, pvals, size=None):
"""Returns an array from multinomial distribution.
Args:
n (int): Number of trials.
pvals (cupy.ndarray): Probabilities of each of the ``p`` different
outcomes. The sum of these values must be 1.
size (int or tuple of ints or None): Shape of a sample in each trial.
For example when ``size`` is ``(a, b)``, shape of returned value is
``(a, b, p)`` where ``p`` is ``len(pvals)``.
If ``size`` is ``None``, it is treated as ``()``. So, shape of
returned value is ``(p,)``.
Returns:
cupy.ndarray: An array drawn from multinomial distribution.
.. note::
It does not support ``sum(pvals) < 1`` case.
.. seealso:: :func:`numpy.random.multinomial`
"""
if size is None:
m = 1
size = ()
elif isinstance(size, six.integer_types):
m = size
size = (size,)
else:
size = tuple(size)
m = 1
for x in size:
m *= x
p = len(pvals)
shape = size + (p,)
# atomicAdd only supports int32
ys = basic.zeros(shape, 'i')
if ys.size > 0:
xs = choice(p, p=pvals, size=n * m)
core.ElementwiseKernel(
'int64 x, int32 p, int32 n', 'raw int32 ys',
'atomicAdd(&ys[i / n * p + x], 1)',
'cupy_random_multinomial')(xs, p, n, ys)
return ys.astype('l')