numo-random 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2 -2
- data/ext/numo/random/ext.hpp +156 -2
- data/lib/numo/random/generator.rb +72 -0
- data/lib/numo/random/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c0f7c2bfe21c7c499f2d18453607b78ccd48bfea287336a3ce8ca4bee1a30e0
|
4
|
+
data.tar.gz: cef6d2005611cabe21606d3b9e3fe31b82ee9e34e909206c6b0b89b6fc78115d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e42a2ecae4e48173c0f96a8d5170bed05165c378289a3b84c1fdad56bd8dcc392b53596c1d3501ddf151bfdd6b10ae82032b6b6ca4f1f03a38e87e8ff83f418
|
7
|
+
data.tar.gz: 96f8de00675b3762ed859a5a9afef3fa8f2fe8a7d48562a3aae267d78caa963e9ddc6c514a6c14a0121b4ab1d633d370a04b6fd64551a60b46e03f73c94682b9
|
data/CHANGELOG.md
CHANGED
data/ext/numo/random/ext.hpp
CHANGED
@@ -58,6 +58,9 @@ public:
|
|
58
58
|
rb_define_method(rb_cPCG64, "seed=", RUBY_METHOD_FUNC(_numo_random_pcg64_set_seed), 1);
|
59
59
|
rb_define_method(rb_cPCG64, "seed", RUBY_METHOD_FUNC(_numo_random_pcg64_get_seed), 0);
|
60
60
|
rb_define_method(rb_cPCG64, "random", RUBY_METHOD_FUNC(_numo_random_pcg64_random), 0);
|
61
|
+
rb_define_method(rb_cPCG64, "binomial", RUBY_METHOD_FUNC(_numo_random_pcg64_binomial), -1);
|
62
|
+
rb_define_method(rb_cPCG64, "negative_binomial", RUBY_METHOD_FUNC(_numo_random_pcg64_negative_binomial), -1);
|
63
|
+
rb_define_method(rb_cPCG64, "geometric", RUBY_METHOD_FUNC(_numo_random_pcg64_geometric), -1);
|
61
64
|
rb_define_method(rb_cPCG64, "exponential", RUBY_METHOD_FUNC(_numo_random_pcg64_exponential), -1);
|
62
65
|
rb_define_method(rb_cPCG64, "gamma", RUBY_METHOD_FUNC(_numo_random_pcg64_gamma), -1);
|
63
66
|
rb_define_method(rb_cPCG64, "gumbel", RUBY_METHOD_FUNC(_numo_random_pcg64_gumbel), -1);
|
@@ -149,6 +152,157 @@ private:
|
|
149
152
|
}
|
150
153
|
}
|
151
154
|
|
155
|
+
// #binomial
|
156
|
+
|
157
|
+
template<typename T> static void _rand_binomial(VALUE& self, VALUE& x, const long n, const double& p) {
|
158
|
+
pcg64* ptr = get_pcg64(self);
|
159
|
+
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
160
|
+
std::binomial_distribution<T> binomial_dist(n, p);
|
161
|
+
ndfunc_t ndf = { _iter_rand<std::binomial_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
162
|
+
rand_opt_t<std::binomial_distribution<T>> opt = { binomial_dist, ptr };
|
163
|
+
na_ndloop3(&ndf, &opt, 1, x);
|
164
|
+
}
|
165
|
+
|
166
|
+
static VALUE _numo_random_pcg64_binomial(int argc, VALUE* argv, VALUE self) {
|
167
|
+
VALUE x = Qnil;
|
168
|
+
VALUE kw_args = Qnil;
|
169
|
+
ID kw_table[2] = { rb_intern("n"), rb_intern("p") };
|
170
|
+
VALUE kw_values[2] = { Qundef, Qundef };
|
171
|
+
rb_scan_args(argc, argv, "1:", &x, &kw_args);
|
172
|
+
rb_get_kwargs(kw_args, kw_table, 2, 0, kw_values);
|
173
|
+
|
174
|
+
const VALUE klass = rb_obj_class(x);
|
175
|
+
if (klass != numo_cInt8 && klass != numo_cInt16 && klass != numo_cInt32 && klass != numo_cInt64
|
176
|
+
&& klass != numo_cUInt8 && klass != numo_cUInt16 && klass != numo_cUInt32 && klass != numo_cUInt64)
|
177
|
+
rb_raise(rb_eTypeError, "invalid NArray class, it must be integer typed array");
|
178
|
+
|
179
|
+
const long n = NUM2LONG(kw_values[0]);
|
180
|
+
const double p = NUM2DBL(kw_values[1]);
|
181
|
+
if (n < 0) rb_raise(rb_eArgError, "n must be a non-negative value");
|
182
|
+
if (p < 0.0 || p > 1.0) rb_raise(rb_eArgError, "p must be >= 0 and <= 1");
|
183
|
+
|
184
|
+
if (klass == numo_cInt8) {
|
185
|
+
_rand_binomial<int8_t>(self, x, n, p);
|
186
|
+
} else if (klass == numo_cInt16) {
|
187
|
+
_rand_binomial<int16_t>(self, x, n, p);
|
188
|
+
} else if (klass == numo_cInt32) {
|
189
|
+
_rand_binomial<int32_t>(self, x, n, p);
|
190
|
+
} else if (klass == numo_cInt64) {
|
191
|
+
_rand_binomial<int64_t>(self, x, n, p);
|
192
|
+
} else if (klass == numo_cUInt8) {
|
193
|
+
_rand_binomial<uint8_t>(self, x, n, p);
|
194
|
+
} else if (klass == numo_cUInt16) {
|
195
|
+
_rand_binomial<uint16_t>(self, x, n, p);
|
196
|
+
} else if (klass == numo_cUInt32) {
|
197
|
+
_rand_binomial<uint32_t>(self, x, n, p);
|
198
|
+
} else if (klass == numo_cUInt64) {
|
199
|
+
_rand_binomial<uint64_t>(self, x, n, p);
|
200
|
+
}
|
201
|
+
|
202
|
+
RB_GC_GUARD(x);
|
203
|
+
return Qnil;
|
204
|
+
}
|
205
|
+
|
206
|
+
// #negative_binomial
|
207
|
+
|
208
|
+
template<typename T> static void _rand_negative_binomial(VALUE& self, VALUE& x, const long n, const double& p) {
|
209
|
+
pcg64* ptr = get_pcg64(self);
|
210
|
+
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
211
|
+
std::negative_binomial_distribution<T> negative_binomial_dist(n, p);
|
212
|
+
ndfunc_t ndf = { _iter_rand<std::negative_binomial_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
213
|
+
rand_opt_t<std::negative_binomial_distribution<T>> opt = { negative_binomial_dist, ptr };
|
214
|
+
na_ndloop3(&ndf, &opt, 1, x);
|
215
|
+
}
|
216
|
+
|
217
|
+
static VALUE _numo_random_pcg64_negative_binomial(int argc, VALUE* argv, VALUE self) {
|
218
|
+
VALUE x = Qnil;
|
219
|
+
VALUE kw_args = Qnil;
|
220
|
+
ID kw_table[2] = { rb_intern("n"), rb_intern("p") };
|
221
|
+
VALUE kw_values[2] = { Qundef, Qundef };
|
222
|
+
rb_scan_args(argc, argv, "1:", &x, &kw_args);
|
223
|
+
rb_get_kwargs(kw_args, kw_table, 2, 0, kw_values);
|
224
|
+
|
225
|
+
const VALUE klass = rb_obj_class(x);
|
226
|
+
if (klass != numo_cInt8 && klass != numo_cInt16 && klass != numo_cInt32 && klass != numo_cInt64
|
227
|
+
&& klass != numo_cUInt8 && klass != numo_cUInt16 && klass != numo_cUInt32 && klass != numo_cUInt64)
|
228
|
+
rb_raise(rb_eTypeError, "invalid NArray class, it must be integer typed array");
|
229
|
+
|
230
|
+
const long n = NUM2LONG(kw_values[0]);
|
231
|
+
const double p = NUM2DBL(kw_values[1]);
|
232
|
+
if (n < 0) rb_raise(rb_eArgError, "n must be a non-negative value");
|
233
|
+
if (p <= 0.0 || p > 1.0) rb_raise(rb_eArgError, "p must be > 0 and <= 1");
|
234
|
+
|
235
|
+
if (klass == numo_cInt8) {
|
236
|
+
_rand_negative_binomial<int8_t>(self, x, n, p);
|
237
|
+
} else if (klass == numo_cInt16) {
|
238
|
+
_rand_negative_binomial<int16_t>(self, x, n, p);
|
239
|
+
} else if (klass == numo_cInt32) {
|
240
|
+
_rand_negative_binomial<int32_t>(self, x, n, p);
|
241
|
+
} else if (klass == numo_cInt64) {
|
242
|
+
_rand_negative_binomial<int64_t>(self, x, n, p);
|
243
|
+
} else if (klass == numo_cUInt8) {
|
244
|
+
_rand_negative_binomial<uint8_t>(self, x, n, p);
|
245
|
+
} else if (klass == numo_cUInt16) {
|
246
|
+
_rand_negative_binomial<uint16_t>(self, x, n, p);
|
247
|
+
} else if (klass == numo_cUInt32) {
|
248
|
+
_rand_negative_binomial<uint32_t>(self, x, n, p);
|
249
|
+
} else if (klass == numo_cUInt64) {
|
250
|
+
_rand_negative_binomial<uint64_t>(self, x, n, p);
|
251
|
+
}
|
252
|
+
|
253
|
+
RB_GC_GUARD(x);
|
254
|
+
return Qnil;
|
255
|
+
}
|
256
|
+
|
257
|
+
// #geometric
|
258
|
+
|
259
|
+
template<typename T> static void _rand_geometric(VALUE& self, VALUE& x, const double& p) {
|
260
|
+
pcg64* ptr = get_pcg64(self);
|
261
|
+
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
262
|
+
std::geometric_distribution<T> geometric_dist(p);
|
263
|
+
ndfunc_t ndf = { _iter_rand<std::geometric_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
264
|
+
rand_opt_t<std::geometric_distribution<T>> opt = { geometric_dist, ptr };
|
265
|
+
na_ndloop3(&ndf, &opt, 1, x);
|
266
|
+
}
|
267
|
+
|
268
|
+
static VALUE _numo_random_pcg64_geometric(int argc, VALUE* argv, VALUE self) {
|
269
|
+
VALUE x = Qnil;
|
270
|
+
VALUE kw_args = Qnil;
|
271
|
+
ID kw_table[1] = { rb_intern("p") };
|
272
|
+
VALUE kw_values[1] = { Qundef };
|
273
|
+
rb_scan_args(argc, argv, "1:", &x, &kw_args);
|
274
|
+
rb_get_kwargs(kw_args, kw_table, 1, 0, kw_values);
|
275
|
+
|
276
|
+
const VALUE klass = rb_obj_class(x);
|
277
|
+
if (klass != numo_cInt8 && klass != numo_cInt16 && klass != numo_cInt32 && klass != numo_cInt64
|
278
|
+
&& klass != numo_cUInt8 && klass != numo_cUInt16 && klass != numo_cUInt32 && klass != numo_cUInt64)
|
279
|
+
rb_raise(rb_eTypeError, "invalid NArray class, it must be integer typed array");
|
280
|
+
|
281
|
+
const double p = NUM2DBL(kw_values[0]);
|
282
|
+
if (p <= 0.0 || p >= 1.0) rb_raise(rb_eArgError, "p must be > 0 and < 1");
|
283
|
+
|
284
|
+
if (klass == numo_cInt8) {
|
285
|
+
_rand_geometric<int8_t>(self, x, p);
|
286
|
+
} else if (klass == numo_cInt16) {
|
287
|
+
_rand_geometric<int16_t>(self, x, p);
|
288
|
+
} else if (klass == numo_cInt32) {
|
289
|
+
_rand_geometric<int32_t>(self, x, p);
|
290
|
+
} else if (klass == numo_cInt64) {
|
291
|
+
_rand_geometric<int64_t>(self, x, p);
|
292
|
+
} else if (klass == numo_cUInt8) {
|
293
|
+
_rand_geometric<uint8_t>(self, x, p);
|
294
|
+
} else if (klass == numo_cUInt16) {
|
295
|
+
_rand_geometric<uint16_t>(self, x, p);
|
296
|
+
} else if (klass == numo_cUInt32) {
|
297
|
+
_rand_geometric<uint32_t>(self, x, p);
|
298
|
+
} else if (klass == numo_cUInt64) {
|
299
|
+
_rand_geometric<uint64_t>(self, x, p);
|
300
|
+
}
|
301
|
+
|
302
|
+
RB_GC_GUARD(x);
|
303
|
+
return Qnil;
|
304
|
+
}
|
305
|
+
|
152
306
|
// #exponential
|
153
307
|
|
154
308
|
template<typename T> static void _rand_exponential(VALUE& self, VALUE& x, const double& lam) {
|
@@ -272,8 +426,8 @@ private:
|
|
272
426
|
static VALUE _numo_random_pcg64_poisson(int argc, VALUE* argv, VALUE self) {
|
273
427
|
VALUE x = Qnil;
|
274
428
|
VALUE kw_args = Qnil;
|
275
|
-
ID kw_table[
|
276
|
-
VALUE kw_values[
|
429
|
+
ID kw_table[1] = { rb_intern("mean") };
|
430
|
+
VALUE kw_values[1] = { Qundef };
|
277
431
|
rb_scan_args(argc, argv, "1:", &x, &kw_args);
|
278
432
|
rb_get_kwargs(kw_args, kw_table, 0, 1, kw_values);
|
279
433
|
|
@@ -57,6 +57,78 @@ module Numo
|
|
57
57
|
rng.random
|
58
58
|
end
|
59
59
|
|
60
|
+
# Generates array consists of random values according to the Bernoulli distribution.
|
61
|
+
#
|
62
|
+
# @example
|
63
|
+
# require 'numo/random'
|
64
|
+
#
|
65
|
+
# rng = Numo::Random::Generator.new(seed: 42)
|
66
|
+
# x = rng.bernoulli(shape: 1000, p: 0.4)
|
67
|
+
#
|
68
|
+
# @param shape [Integer | Array<Integer>] size of random array.
|
69
|
+
# @param p [Float] probability of success.
|
70
|
+
# @param dtype [Symbol] data type of random array.
|
71
|
+
# @return [Numo::IntX | Numo::UIntX]
|
72
|
+
def bernoulli(shape:, p:, dtype: :int32)
|
73
|
+
binomial(shape: shape, n: 1, p: p, dtype: dtype)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Generates array consists of random values according to a binomial distribution.
|
77
|
+
#
|
78
|
+
# @example
|
79
|
+
# require 'numo/random'
|
80
|
+
#
|
81
|
+
# rng = Numo::Random::Generator.new(seed: 42)
|
82
|
+
# x = rng.binomial(shape: 1000, n: 10, p: 0.4)
|
83
|
+
#
|
84
|
+
# @param shape [Integer | Array<Integer>] size of random array.
|
85
|
+
# @param n [Integer] number of trials.
|
86
|
+
# @param p [Float] probability of success.
|
87
|
+
# @param dtype [Symbol] data type of random array.
|
88
|
+
# @return [Numo::IntX | Numo::UIntX]
|
89
|
+
def binomial(shape:, n:, p:, dtype: :int32)
|
90
|
+
x = klass(dtype).new(shape)
|
91
|
+
rng.binomial(x, n: n, p: p)
|
92
|
+
x
|
93
|
+
end
|
94
|
+
|
95
|
+
# Generates array consists of random values according to a negative binomial distribution.
|
96
|
+
#
|
97
|
+
# @example
|
98
|
+
# require 'numo/random'
|
99
|
+
#
|
100
|
+
# rng = Numo::Random::Generator.new(seed: 42)
|
101
|
+
# x = rng.negative_binomial(shape: 1000, n: 10, p: 0.4)
|
102
|
+
#
|
103
|
+
# @param shape [Integer | Array<Integer>] size of random array.
|
104
|
+
# @param n [Integer] number of trials.
|
105
|
+
# @param p [Float] probability of success.
|
106
|
+
# @param dtype [Symbol] data type of random array.
|
107
|
+
# @return [Numo::IntX | Numo::UIntX]
|
108
|
+
def negative_binomial(shape:, n:, p:, dtype: :int32)
|
109
|
+
x = klass(dtype).new(shape)
|
110
|
+
rng.negative_binomial(x, n: n, p: p)
|
111
|
+
x
|
112
|
+
end
|
113
|
+
|
114
|
+
# Generates array consists of random values according to a geometric distribution.
|
115
|
+
#
|
116
|
+
# @example
|
117
|
+
# require 'numo/random'
|
118
|
+
#
|
119
|
+
# rng = Numo::Random::Generator.new(seed: 42)
|
120
|
+
# x = rng.geometric(shape: 1000, p: 0.4)
|
121
|
+
#
|
122
|
+
# @param shape [Integer | Array<Integer>] size of random array.
|
123
|
+
# @param p [Float] probability of success on each trial.
|
124
|
+
# @param dtype [Symbol] data type of random array.
|
125
|
+
# @return [Numo::IntX | Numo::UIntX]
|
126
|
+
def geometric(shape:, p:, dtype: :int32)
|
127
|
+
x = klass(dtype).new(shape)
|
128
|
+
rng.geometric(x, p: p)
|
129
|
+
x
|
130
|
+
end
|
131
|
+
|
60
132
|
# Generates array consists of random values with an exponential distribution.
|
61
133
|
#
|
62
134
|
# @example
|
data/lib/numo/random/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: numo-random
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- yoshoku
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-11-
|
11
|
+
date: 2022-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: numo-narray
|