numo-random 0.2.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 +6 -4
- data/ext/numo/random/{randomext.cpp → ext.cpp} +2 -2
- data/ext/numo/random/{randomext.hpp → ext.hpp} +357 -3
- data/ext/numo/random/extconf.rb +1 -1
- data/lib/numo/random/generator.rb +166 -1
- data/lib/numo/random/version.rb +1 -1
- data/lib/numo/random.rb +1 -1
- metadata +4 -4
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
@@ -1,9 +1,11 @@
|
|
1
|
-
## [
|
2
|
-
-
|
3
|
-
- Poisson distribution.
|
1
|
+
## [0.4.0]
|
2
|
+
- Add method for random number generation with bernoulli distribution: bernoulli, binomial, negative_binomial, and geometric.
|
4
3
|
|
5
|
-
## [0.
|
4
|
+
## [0.3.0]
|
5
|
+
- Change native extension filename.
|
6
|
+
- Add methods for random number generation with poisson distributions: poisson, exponential, gamma, gumbel, and weibull.
|
6
7
|
|
8
|
+
## [0.2.0]
|
7
9
|
- Add discrete method.
|
8
10
|
|
9
11
|
### Breaking Changes
|
@@ -16,9 +16,9 @@
|
|
16
16
|
* limitations under the License.
|
17
17
|
*/
|
18
18
|
|
19
|
-
#include "
|
19
|
+
#include "ext.hpp"
|
20
20
|
|
21
|
-
extern "C" void
|
21
|
+
extern "C" void Init_ext(void) {
|
22
22
|
rb_require("numo/narray");
|
23
23
|
|
24
24
|
VALUE rb_mNumoRandom = rb_define_module_under(mNumo, "Random");
|
@@ -16,8 +16,8 @@
|
|
16
16
|
* limitations under the License.
|
17
17
|
*/
|
18
18
|
|
19
|
-
#ifndef
|
20
|
-
#define
|
19
|
+
#ifndef NUMO_RANDOM_EXT_HPP
|
20
|
+
#define NUMO_RANDOM_EXT_HPP 1
|
21
21
|
|
22
22
|
#include <ruby.h>
|
23
23
|
|
@@ -58,6 +58,14 @@ 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);
|
64
|
+
rb_define_method(rb_cPCG64, "exponential", RUBY_METHOD_FUNC(_numo_random_pcg64_exponential), -1);
|
65
|
+
rb_define_method(rb_cPCG64, "gamma", RUBY_METHOD_FUNC(_numo_random_pcg64_gamma), -1);
|
66
|
+
rb_define_method(rb_cPCG64, "gumbel", RUBY_METHOD_FUNC(_numo_random_pcg64_gumbel), -1);
|
67
|
+
rb_define_method(rb_cPCG64, "poisson", RUBY_METHOD_FUNC(_numo_random_pcg64_poisson), -1);
|
68
|
+
rb_define_method(rb_cPCG64, "weibull", RUBY_METHOD_FUNC(_numo_random_pcg64_weibull), -1);
|
61
69
|
rb_define_method(rb_cPCG64, "discrete", RUBY_METHOD_FUNC(_numo_random_pcg64_discrete), -1);
|
62
70
|
rb_define_method(rb_cPCG64, "uniform", RUBY_METHOD_FUNC(_numo_random_pcg64_uniform), -1);
|
63
71
|
rb_define_method(rb_cPCG64, "cauchy", RUBY_METHOD_FUNC(_numo_random_pcg64_cauchy), -1);
|
@@ -144,6 +152,352 @@ private:
|
|
144
152
|
}
|
145
153
|
}
|
146
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
|
+
|
306
|
+
// #exponential
|
307
|
+
|
308
|
+
template<typename T> static void _rand_exponential(VALUE& self, VALUE& x, const double& lam) {
|
309
|
+
pcg64* ptr = get_pcg64(self);
|
310
|
+
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
311
|
+
std::exponential_distribution<T> exponential_dist(lam);
|
312
|
+
ndfunc_t ndf = { _iter_rand<std::exponential_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
313
|
+
rand_opt_t<std::exponential_distribution<T>> opt = { exponential_dist, ptr };
|
314
|
+
na_ndloop3(&ndf, &opt, 1, x);
|
315
|
+
}
|
316
|
+
|
317
|
+
static VALUE _numo_random_pcg64_exponential(int argc, VALUE* argv, VALUE self) {
|
318
|
+
VALUE x = Qnil;
|
319
|
+
VALUE kw_args = Qnil;
|
320
|
+
ID kw_table[1] = { rb_intern("scale") };
|
321
|
+
VALUE kw_values[1] = { Qundef };
|
322
|
+
rb_scan_args(argc, argv, "1:", &x, &kw_args);
|
323
|
+
rb_get_kwargs(kw_args, kw_table, 0, 1, kw_values);
|
324
|
+
|
325
|
+
const VALUE klass = rb_obj_class(x);
|
326
|
+
if (klass != numo_cSFloat && klass != numo_cDFloat) rb_raise(rb_eTypeError, "invalid NArray class, it must be DFloat or SFloat");
|
327
|
+
|
328
|
+
const double scale = kw_values[0] == Qundef ? 1.0 : NUM2DBL(kw_values[0]);
|
329
|
+
if (scale <= 0) rb_raise(rb_eArgError, "scale must be > 0");
|
330
|
+
|
331
|
+
const double lam = 1.0 / scale;
|
332
|
+
if (klass == numo_cSFloat) {
|
333
|
+
_rand_exponential<float>(self, x, lam);
|
334
|
+
} else {
|
335
|
+
_rand_exponential<double>(self, x, lam);
|
336
|
+
}
|
337
|
+
|
338
|
+
RB_GC_GUARD(x);
|
339
|
+
return Qnil;
|
340
|
+
}
|
341
|
+
|
342
|
+
// #gamma
|
343
|
+
|
344
|
+
template<typename T> static void _rand_gamma(VALUE& self, VALUE& x, const double& k, const double&scale) {
|
345
|
+
pcg64* ptr = get_pcg64(self);
|
346
|
+
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
347
|
+
std::gamma_distribution<T> gamma_dist(k, scale);
|
348
|
+
ndfunc_t ndf = { _iter_rand<std::gamma_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
349
|
+
rand_opt_t<std::gamma_distribution<T>> opt = { gamma_dist, ptr };
|
350
|
+
na_ndloop3(&ndf, &opt, 1, x);
|
351
|
+
}
|
352
|
+
|
353
|
+
static VALUE _numo_random_pcg64_gamma(int argc, VALUE* argv, VALUE self) {
|
354
|
+
VALUE x = Qnil;
|
355
|
+
VALUE kw_args = Qnil;
|
356
|
+
ID kw_table[2] = { rb_intern("k"), rb_intern("scale") };
|
357
|
+
VALUE kw_values[2] = { Qundef, Qundef };
|
358
|
+
rb_scan_args(argc, argv, "1:", &x, &kw_args);
|
359
|
+
rb_get_kwargs(kw_args, kw_table, 1, 1, kw_values);
|
360
|
+
|
361
|
+
const VALUE klass = rb_obj_class(x);
|
362
|
+
if (klass != numo_cSFloat && klass != numo_cDFloat) rb_raise(rb_eTypeError, "invalid NArray class, it must be DFloat or SFloat");
|
363
|
+
|
364
|
+
const double k = NUM2DBL(kw_values[0]);
|
365
|
+
if (k <= 0) rb_raise(rb_eArgError, "k must be > 0");
|
366
|
+
const double scale = kw_values[1] == Qundef ? 1.0 : NUM2DBL(kw_values[1]);
|
367
|
+
if (scale <= 0) rb_raise(rb_eArgError, "scale must be > 0");
|
368
|
+
|
369
|
+
if (klass == numo_cSFloat) {
|
370
|
+
_rand_gamma<float>(self, x, k, scale);
|
371
|
+
} else {
|
372
|
+
_rand_gamma<double>(self, x, k, scale);
|
373
|
+
}
|
374
|
+
|
375
|
+
RB_GC_GUARD(x);
|
376
|
+
return Qnil;
|
377
|
+
}
|
378
|
+
|
379
|
+
// #gumbel
|
380
|
+
|
381
|
+
template<typename T> static void _rand_gumbel(VALUE& self, VALUE& x, const double& loc, const double&scale) {
|
382
|
+
pcg64* ptr = get_pcg64(self);
|
383
|
+
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
384
|
+
std::extreme_value_distribution<T> extreme_value_dist(loc, scale);
|
385
|
+
ndfunc_t ndf = { _iter_rand<std::extreme_value_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
386
|
+
rand_opt_t<std::extreme_value_distribution<T>> opt = { extreme_value_dist, ptr };
|
387
|
+
na_ndloop3(&ndf, &opt, 1, x);
|
388
|
+
}
|
389
|
+
|
390
|
+
static VALUE _numo_random_pcg64_gumbel(int argc, VALUE* argv, VALUE self) {
|
391
|
+
VALUE x = Qnil;
|
392
|
+
VALUE kw_args = Qnil;
|
393
|
+
ID kw_table[2] = { rb_intern("loc"), rb_intern("scale") };
|
394
|
+
VALUE kw_values[2] = { Qundef, Qundef };
|
395
|
+
rb_scan_args(argc, argv, "1:", &x, &kw_args);
|
396
|
+
rb_get_kwargs(kw_args, kw_table, 0, 2, kw_values);
|
397
|
+
|
398
|
+
const VALUE klass = rb_obj_class(x);
|
399
|
+
if (klass != numo_cSFloat && klass != numo_cDFloat) rb_raise(rb_eTypeError, "invalid NArray class, it must be DFloat or SFloat");
|
400
|
+
|
401
|
+
const double loc = kw_values[0] == Qundef ? 0.0 : NUM2DBL(kw_values[0]);
|
402
|
+
const double scale = kw_values[1] == Qundef ? 1.0 : NUM2DBL(kw_values[1]);
|
403
|
+
if (scale <= 0) rb_raise(rb_eArgError, "scale must be > 0");
|
404
|
+
|
405
|
+
if (klass == numo_cSFloat) {
|
406
|
+
_rand_gumbel<float>(self, x, loc, scale);
|
407
|
+
} else {
|
408
|
+
_rand_gumbel<double>(self, x, loc, scale);
|
409
|
+
}
|
410
|
+
|
411
|
+
RB_GC_GUARD(x);
|
412
|
+
return Qnil;
|
413
|
+
}
|
414
|
+
|
415
|
+
// #poisson
|
416
|
+
|
417
|
+
template<typename T> static void _rand_poisson(VALUE& self, VALUE& x, const double& mean) {
|
418
|
+
pcg64* ptr = get_pcg64(self);
|
419
|
+
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
420
|
+
std::poisson_distribution<T> poisson_dist(mean);
|
421
|
+
ndfunc_t ndf = { _iter_rand<std::poisson_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
422
|
+
rand_opt_t<std::poisson_distribution<T>> opt = { poisson_dist, ptr };
|
423
|
+
na_ndloop3(&ndf, &opt, 1, x);
|
424
|
+
}
|
425
|
+
|
426
|
+
static VALUE _numo_random_pcg64_poisson(int argc, VALUE* argv, VALUE self) {
|
427
|
+
VALUE x = Qnil;
|
428
|
+
VALUE kw_args = Qnil;
|
429
|
+
ID kw_table[1] = { rb_intern("mean") };
|
430
|
+
VALUE kw_values[1] = { Qundef };
|
431
|
+
rb_scan_args(argc, argv, "1:", &x, &kw_args);
|
432
|
+
rb_get_kwargs(kw_args, kw_table, 0, 1, kw_values);
|
433
|
+
|
434
|
+
const VALUE klass = rb_obj_class(x);
|
435
|
+
if (klass != numo_cInt8 && klass != numo_cInt16 && klass != numo_cInt32 && klass != numo_cInt64
|
436
|
+
&& klass != numo_cUInt8 && klass != numo_cUInt16 && klass != numo_cUInt32 && klass != numo_cUInt64)
|
437
|
+
rb_raise(rb_eTypeError, "invalid NArray class, it must be integer typed array");
|
438
|
+
|
439
|
+
const double mean = kw_values[0] == Qundef ? 0.0 : NUM2DBL(kw_values[0]);
|
440
|
+
if (mean <= 0.0) rb_raise(rb_eArgError, "mean must be > 0");
|
441
|
+
|
442
|
+
if (klass == numo_cInt8) {
|
443
|
+
_rand_poisson<int8_t>(self, x, mean);
|
444
|
+
} else if (klass == numo_cInt16) {
|
445
|
+
_rand_poisson<int16_t>(self, x, mean);
|
446
|
+
} else if (klass == numo_cInt32) {
|
447
|
+
_rand_poisson<int32_t>(self, x, mean);
|
448
|
+
} else if (klass == numo_cInt64) {
|
449
|
+
_rand_poisson<int64_t>(self, x, mean);
|
450
|
+
} else if (klass == numo_cUInt8) {
|
451
|
+
_rand_poisson<uint8_t>(self, x, mean);
|
452
|
+
} else if (klass == numo_cUInt16) {
|
453
|
+
_rand_poisson<uint16_t>(self, x, mean);
|
454
|
+
} else if (klass == numo_cUInt32) {
|
455
|
+
_rand_poisson<uint32_t>(self, x, mean);
|
456
|
+
} else if (klass == numo_cUInt64) {
|
457
|
+
_rand_poisson<uint64_t>(self, x, mean);
|
458
|
+
}
|
459
|
+
|
460
|
+
RB_GC_GUARD(x);
|
461
|
+
return Qnil;
|
462
|
+
}
|
463
|
+
|
464
|
+
// #weibull
|
465
|
+
|
466
|
+
template<typename T> static void _rand_weibull(VALUE& self, VALUE& x, const double& k, const double&scale) {
|
467
|
+
pcg64* ptr = get_pcg64(self);
|
468
|
+
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
469
|
+
std::weibull_distribution<T> weibull_dist(k, scale);
|
470
|
+
ndfunc_t ndf = { _iter_rand<std::weibull_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
471
|
+
rand_opt_t<std::weibull_distribution<T>> opt = { weibull_dist, ptr };
|
472
|
+
na_ndloop3(&ndf, &opt, 1, x);
|
473
|
+
}
|
474
|
+
|
475
|
+
static VALUE _numo_random_pcg64_weibull(int argc, VALUE* argv, VALUE self) {
|
476
|
+
VALUE x = Qnil;
|
477
|
+
VALUE kw_args = Qnil;
|
478
|
+
ID kw_table[2] = { rb_intern("k"), rb_intern("scale") };
|
479
|
+
VALUE kw_values[2] = { Qundef, Qundef };
|
480
|
+
rb_scan_args(argc, argv, "1:", &x, &kw_args);
|
481
|
+
rb_get_kwargs(kw_args, kw_table, 1, 1, kw_values);
|
482
|
+
|
483
|
+
const VALUE klass = rb_obj_class(x);
|
484
|
+
if (klass != numo_cSFloat && klass != numo_cDFloat) rb_raise(rb_eTypeError, "invalid NArray class, it must be DFloat or SFloat");
|
485
|
+
|
486
|
+
const double k = NUM2DBL(kw_values[0]);
|
487
|
+
if (k <= 0) rb_raise(rb_eArgError, "k must be > 0");
|
488
|
+
const double scale = kw_values[1] == Qundef ? 1.0 : NUM2DBL(kw_values[1]);
|
489
|
+
if (scale <= 0) rb_raise(rb_eArgError, "scale must be > 0");
|
490
|
+
|
491
|
+
if (klass == numo_cSFloat) {
|
492
|
+
_rand_weibull<float>(self, x, k, scale);
|
493
|
+
} else {
|
494
|
+
_rand_weibull<double>(self, x, k, scale);
|
495
|
+
}
|
496
|
+
|
497
|
+
RB_GC_GUARD(x);
|
498
|
+
return Qnil;
|
499
|
+
}
|
500
|
+
|
147
501
|
// #discrete
|
148
502
|
|
149
503
|
template<typename T, typename P> static void _rand_discrete(VALUE& self, VALUE& x, const std::vector<P>& weight) {
|
@@ -491,4 +845,4 @@ const rb_data_type_t RbNumoRandomPCG64::pcg64_type = {
|
|
491
845
|
RUBY_TYPED_FREE_IMMEDIATELY
|
492
846
|
};
|
493
847
|
|
494
|
-
#endif /*
|
848
|
+
#endif /* NUMO_RANDOM_EXT_HPP */
|
data/ext/numo/random/extconf.rb
CHANGED
@@ -16,7 +16,7 @@ module Numo
|
|
16
16
|
# # Numo::DFloat#shape=[2,5]
|
17
17
|
# # [[1.90546, -0.543299, 0.673332, 0.759583, -0.40945],
|
18
18
|
# # [0.334635, -0.0558342, 1.28115, 1.93644, -0.0689543]]
|
19
|
-
class Generator
|
19
|
+
class Generator # rubocop:disable Metrics/ClassLength
|
20
20
|
# Returns random number generation algorithm.
|
21
21
|
# @return [String]
|
22
22
|
attr_accessor :algorithm
|
@@ -57,6 +57,171 @@ 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
|
+
|
132
|
+
# Generates array consists of random values with an exponential distribution.
|
133
|
+
#
|
134
|
+
# @example
|
135
|
+
# require 'numo/random'
|
136
|
+
#
|
137
|
+
# rng = Numo::Random::Generator.new
|
138
|
+
# x = rng.exponential(shape: 100, scale: 2)
|
139
|
+
#
|
140
|
+
# @param shape [Integer | Array<Integer>] size of random array.
|
141
|
+
# @param scale [Float] scale parameter, lambda = 1.fdiv(scale).
|
142
|
+
# @param dtype [Symbol] data type of random array.
|
143
|
+
# @return [Numo::DFloat | Numo::SFloat]
|
144
|
+
def exponential(shape:, scale: 1.0, dtype: :float64)
|
145
|
+
x = klass(dtype).new(shape)
|
146
|
+
rng.exponential(x, scale: scale)
|
147
|
+
x
|
148
|
+
end
|
149
|
+
|
150
|
+
# Generates array consists of random values with a gamma distribution.
|
151
|
+
#
|
152
|
+
# @example
|
153
|
+
# require 'numo/random'
|
154
|
+
#
|
155
|
+
# rng = Numo::Random::Generator.new
|
156
|
+
# x = rng.gamma(shape: 100, k: 9, scale: 0.5)
|
157
|
+
#
|
158
|
+
# @param shape [Integer | Array<Integer>] size of random array.
|
159
|
+
# @param k [Float] shape parameter.
|
160
|
+
# @param scale [Float] scale parameter.
|
161
|
+
# @param dtype [Symbol] data type of random array.
|
162
|
+
# @return [Numo::DFloat | Numo::SFloat]
|
163
|
+
def gamma(shape:, k:, scale: 1.0, dtype: :float64)
|
164
|
+
x = klass(dtype).new(shape)
|
165
|
+
rng.gamma(x, k: k, scale: scale)
|
166
|
+
x
|
167
|
+
end
|
168
|
+
|
169
|
+
# Generates array consists of random values according to the Gumbel distribution.
|
170
|
+
#
|
171
|
+
# @example
|
172
|
+
# require 'numo/random'
|
173
|
+
#
|
174
|
+
# rng = Numo::Random::Generator.new
|
175
|
+
# x = rng.gumbel(shape: 100, loc: 0.0, scale: 1.0)
|
176
|
+
#
|
177
|
+
# @param shape [Integer | Array<Integer>] size of random array.
|
178
|
+
# @param loc [Float] location parameter.
|
179
|
+
# @param scale [Float] scale parameter.
|
180
|
+
# @param dtype [Symbol] data type of random array.
|
181
|
+
# @return [Numo::DFloat | Numo::SFloat]
|
182
|
+
def gumbel(shape:, loc: 0.0, scale: 1.0, dtype: :float64)
|
183
|
+
x = klass(dtype).new(shape)
|
184
|
+
rng.gumbel(x, loc: loc, scale: scale)
|
185
|
+
x
|
186
|
+
end
|
187
|
+
|
188
|
+
# Generates array consists of random values according to the Poisson distribution.
|
189
|
+
#
|
190
|
+
# @example
|
191
|
+
# require 'numo/random'
|
192
|
+
#
|
193
|
+
# rng = Numo::Random::Generator.new(seed: 42)
|
194
|
+
# x = rng.poisson(shape: 1000, mean: 4)
|
195
|
+
#
|
196
|
+
# @param shape [Integer | Array<Integer>] size of random array.
|
197
|
+
# @param mean [Float] mean of poisson distribution.
|
198
|
+
# @param dtype [Symbol] data type of random array.
|
199
|
+
# @return [Numo::IntX | Numo::UIntX]
|
200
|
+
def poisson(shape:, mean: 1.0, dtype: :int32)
|
201
|
+
x = klass(dtype).new(shape)
|
202
|
+
rng.poisson(x, mean: mean)
|
203
|
+
x
|
204
|
+
end
|
205
|
+
|
206
|
+
# Generates array consists of random values with the Weibull distribution.
|
207
|
+
#
|
208
|
+
# @example
|
209
|
+
# require 'numo/random'
|
210
|
+
#
|
211
|
+
# rng = Numo::Random::Generator.new
|
212
|
+
# x = rng.weibull(shape: 100, k: 5, scale: 2)
|
213
|
+
#
|
214
|
+
# @param shape [Integer | Array<Integer>] size of random array.
|
215
|
+
# @param k [Float] shape parameter.
|
216
|
+
# @param scale [Float] scale parameter.
|
217
|
+
# @param dtype [Symbol] data type of random array.
|
218
|
+
# @return [Numo::DFloat | Numo::SFloat]
|
219
|
+
def weibull(shape:, k:, scale: 1.0, dtype: :float64)
|
220
|
+
x = klass(dtype).new(shape)
|
221
|
+
rng.weibull(x, k: k, scale: scale)
|
222
|
+
x
|
223
|
+
end
|
224
|
+
|
60
225
|
# Generates array consists of random integer values in the interval [0, n).
|
61
226
|
#
|
62
227
|
# @example
|
data/lib/numo/random/version.rb
CHANGED
data/lib/numo/random.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
|
+
date: 2022-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: numo-narray
|
@@ -37,9 +37,9 @@ files:
|
|
37
37
|
- CODE_OF_CONDUCT.md
|
38
38
|
- LICENSE.txt
|
39
39
|
- README.md
|
40
|
+
- ext/numo/random/ext.cpp
|
41
|
+
- ext/numo/random/ext.hpp
|
40
42
|
- ext/numo/random/extconf.rb
|
41
|
-
- ext/numo/random/randomext.cpp
|
42
|
-
- ext/numo/random/randomext.hpp
|
43
43
|
- ext/numo/random/src/LICENSE.txt
|
44
44
|
- ext/numo/random/src/pcg_extras.hpp
|
45
45
|
- ext/numo/random/src/pcg_random.hpp
|