numo-random 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +26 -0
- data/ext/numo/random/ext.cpp +4 -1
- data/ext/numo/random/ext.hpp +140 -84
- data/lib/numo/random/generator.rb +15 -4
- 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: d9c0d26c2b1751451a84c8b53c6e38b9257a82ff7d2c3479bd94d7311cfb1628
|
4
|
+
data.tar.gz: ae9262ff84d81abb58af7d4856e0936160c33f3a824818515878ae97ce3c9ea0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f153a0090d65b3ee39d5f8cde36a3669e0d12b6e4f84c56045156c42c2f5fe7dfe3de7b6d649c994bafec730ff8bbcaff09e9befa6aba04e9b5fd0d77dae8d91
|
7
|
+
data.tar.gz: 27af398428b05b955c690f36d948112329484f47146631b2a4f58ef60551a84039144c387e96ad49ee0d13815225930100659823ece1040fb59898e73c13dc0d
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
## [0.5.0]
|
2
|
+
- Support 32-bit PCG and Mersenne Twister.
|
3
|
+
|
4
|
+
```ruby
|
5
|
+
require 'numo/random'
|
6
|
+
|
7
|
+
# specify the pseudo random number generation algorithm by setting the algorithm argument of constructor.
|
8
|
+
rng = Numo::Random::Generator.new(algorithm: 'pcg32')
|
9
|
+
rng = Numo::Random::Generator.new(algorithm: 'pcg64') # default
|
10
|
+
rng = Numo::Random::Generator.new(algorithm: 'mt32')
|
11
|
+
rng = Numo::Random::Generator.new(algorithm: 'mt64')
|
12
|
+
```
|
13
|
+
|
1
14
|
## [0.4.0]
|
2
15
|
- Add method for random number generation with bernoulli distribution: bernoulli, binomial, negative_binomial, and geometric.
|
3
16
|
|
data/README.md
CHANGED
@@ -50,6 +50,32 @@ end
|
|
50
50
|
![normal2d.png](https://user-images.githubusercontent.com/5562409/197376738-ee8d2b12-1902-4a12-bcf3-757461f2f2db.png)
|
51
51
|
|
52
52
|
|
53
|
+
An example of generating random numbers according to the Poisson distribution:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
require 'numo/narray'
|
57
|
+
require 'numo/gnuplot'
|
58
|
+
|
59
|
+
require 'numo/random'
|
60
|
+
|
61
|
+
# Creating random number generator.
|
62
|
+
rng = Numo::Random::Generator.new(seed: 9)
|
63
|
+
|
64
|
+
# Generating random numbers with Poisson distribution.
|
65
|
+
x = rng.poisson(shape: 10000, mean: 12)
|
66
|
+
|
67
|
+
# Plotting the generated result.
|
68
|
+
h = x.bincount
|
69
|
+
|
70
|
+
Numo.gnuplot do
|
71
|
+
set(terminal: 'png')
|
72
|
+
set(output: 'poisson2d.png')
|
73
|
+
plot(h, with: 'boxes')
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
![poisson2d.png](https://user-images.githubusercontent.com/5562409/201478863-61d31eb8-7c0b-4406-b255-fff29187a16a.png)
|
78
|
+
|
53
79
|
## Contributing
|
54
80
|
|
55
81
|
Bug reports and pull requests are welcome on GitHub at https://github.com/yoshoku/numo-random.
|
data/ext/numo/random/ext.cpp
CHANGED
@@ -22,5 +22,8 @@ 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");
|
25
|
-
|
25
|
+
RbNumoRandomPCG32::define_class(rb_mNumoRandom, "PCG32");
|
26
|
+
RbNumoRandomPCG64::define_class(rb_mNumoRandom, "PCG64");
|
27
|
+
RbNumoRandomMT32::define_class(rb_mNumoRandom, "MT32");
|
28
|
+
RbNumoRandomMT64::define_class(rb_mNumoRandom, "MT64");
|
26
29
|
}
|
data/ext/numo/random/ext.hpp
CHANGED
@@ -28,74 +28,74 @@
|
|
28
28
|
|
29
29
|
#include <pcg_random.hpp>
|
30
30
|
|
31
|
-
class
|
31
|
+
template<class Rng, class Impl> class RbNumoRandom {
|
32
32
|
public:
|
33
|
-
static
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
// static const rb_data_type_t rng_type;
|
34
|
+
|
35
|
+
static VALUE numo_random_alloc(VALUE self) {
|
36
|
+
Rng* ptr = (Rng*)ruby_xmalloc(sizeof(Rng));
|
37
|
+
new (ptr) Rng();
|
38
|
+
return TypedData_Wrap_Struct(self, &Impl::rng_type, ptr);
|
37
39
|
}
|
38
40
|
|
39
|
-
static void
|
40
|
-
((
|
41
|
+
static void numo_random_free(void* ptr) {
|
42
|
+
((Rng*)ptr)->~Rng();
|
41
43
|
ruby_xfree(ptr);
|
42
44
|
}
|
43
45
|
|
44
|
-
static size_t
|
45
|
-
return sizeof(*((
|
46
|
+
static size_t numo_random_size(const void* ptr) {
|
47
|
+
return sizeof(*((Rng*)ptr));
|
46
48
|
}
|
47
49
|
|
48
|
-
static
|
49
|
-
|
50
|
-
TypedData_Get_Struct(self,
|
50
|
+
static Rng* get_rng(VALUE self) {
|
51
|
+
Rng* ptr;
|
52
|
+
TypedData_Get_Struct(self, Rng, &Impl::rng_type, ptr);
|
51
53
|
return ptr;
|
52
54
|
}
|
53
55
|
|
54
|
-
static VALUE define_class(VALUE rb_mNumoRandom) {
|
55
|
-
VALUE
|
56
|
-
rb_define_alloc_func(
|
57
|
-
rb_define_method(
|
58
|
-
rb_define_method(
|
59
|
-
rb_define_method(
|
60
|
-
rb_define_method(
|
61
|
-
rb_define_method(
|
62
|
-
rb_define_method(
|
63
|
-
rb_define_method(
|
64
|
-
rb_define_method(
|
65
|
-
rb_define_method(
|
66
|
-
rb_define_method(
|
67
|
-
rb_define_method(
|
68
|
-
rb_define_method(
|
69
|
-
rb_define_method(
|
70
|
-
rb_define_method(
|
71
|
-
rb_define_method(
|
72
|
-
rb_define_method(
|
73
|
-
rb_define_method(
|
74
|
-
rb_define_method(
|
75
|
-
rb_define_method(
|
76
|
-
rb_define_method(
|
77
|
-
return
|
56
|
+
static VALUE define_class(VALUE rb_mNumoRandom, const char* class_name) {
|
57
|
+
VALUE rb_cRng = rb_define_class_under(rb_mNumoRandom, class_name, rb_cObject);
|
58
|
+
rb_define_alloc_func(rb_cRng, numo_random_alloc);
|
59
|
+
rb_define_method(rb_cRng, "initialize", RUBY_METHOD_FUNC(_numo_random_init), -1);
|
60
|
+
rb_define_method(rb_cRng, "seed=", RUBY_METHOD_FUNC(_numo_random_set_seed), 1);
|
61
|
+
rb_define_method(rb_cRng, "seed", RUBY_METHOD_FUNC(_numo_random_get_seed), 0);
|
62
|
+
rb_define_method(rb_cRng, "random", RUBY_METHOD_FUNC(_numo_random_random), 0);
|
63
|
+
rb_define_method(rb_cRng, "binomial", RUBY_METHOD_FUNC(_numo_random_binomial), -1);
|
64
|
+
rb_define_method(rb_cRng, "negative_binomial", RUBY_METHOD_FUNC(_numo_random_negative_binomial), -1);
|
65
|
+
rb_define_method(rb_cRng, "geometric", RUBY_METHOD_FUNC(_numo_random_geometric), -1);
|
66
|
+
rb_define_method(rb_cRng, "exponential", RUBY_METHOD_FUNC(_numo_random_exponential), -1);
|
67
|
+
rb_define_method(rb_cRng, "gamma", RUBY_METHOD_FUNC(_numo_random_gamma), -1);
|
68
|
+
rb_define_method(rb_cRng, "gumbel", RUBY_METHOD_FUNC(_numo_random_gumbel), -1);
|
69
|
+
rb_define_method(rb_cRng, "poisson", RUBY_METHOD_FUNC(_numo_random_poisson), -1);
|
70
|
+
rb_define_method(rb_cRng, "weibull", RUBY_METHOD_FUNC(_numo_random_weibull), -1);
|
71
|
+
rb_define_method(rb_cRng, "discrete", RUBY_METHOD_FUNC(_numo_random_discrete), -1);
|
72
|
+
rb_define_method(rb_cRng, "uniform", RUBY_METHOD_FUNC(_numo_random_uniform), -1);
|
73
|
+
rb_define_method(rb_cRng, "cauchy", RUBY_METHOD_FUNC(_numo_random_cauchy), -1);
|
74
|
+
rb_define_method(rb_cRng, "chisquare", RUBY_METHOD_FUNC(_numo_random_chisquare), -1);
|
75
|
+
rb_define_method(rb_cRng, "f", RUBY_METHOD_FUNC(_numo_random_f), -1);
|
76
|
+
rb_define_method(rb_cRng, "normal", RUBY_METHOD_FUNC(_numo_random_normal), -1);
|
77
|
+
rb_define_method(rb_cRng, "lognormal", RUBY_METHOD_FUNC(_numo_random_lognormal), -1);
|
78
|
+
rb_define_method(rb_cRng, "standard_t", RUBY_METHOD_FUNC(_numo_random_standard_t), -1);
|
79
|
+
return rb_cRng;
|
78
80
|
}
|
79
81
|
|
80
82
|
private:
|
81
|
-
static const rb_data_type_t pcg64_type;
|
82
|
-
|
83
83
|
// #initialize
|
84
84
|
|
85
|
-
static VALUE
|
85
|
+
static VALUE _numo_random_init(int argc, VALUE* argv, VALUE self) {
|
86
86
|
VALUE kw_args = Qnil;
|
87
87
|
ID kw_table[1] = { rb_intern("seed") };
|
88
88
|
VALUE kw_values[1] = { Qundef };
|
89
89
|
rb_scan_args(argc, argv, ":", &kw_args);
|
90
90
|
rb_get_kwargs(kw_args, kw_table, 0, 1, kw_values);
|
91
|
-
|
91
|
+
Rng* ptr = get_rng(self);
|
92
92
|
if (kw_values[0] == Qundef || NIL_P(kw_values[0])) {
|
93
93
|
std::random_device rd;
|
94
94
|
const unsigned int seed = rd();
|
95
|
-
new (ptr)
|
95
|
+
new (ptr) Rng(seed);
|
96
96
|
rb_iv_set(self, "seed", UINT2NUM(seed));
|
97
97
|
} else {
|
98
|
-
new (ptr)
|
98
|
+
new (ptr) Rng(NUM2LONG(kw_values[0]));
|
99
99
|
rb_iv_set(self, "seed", kw_values[0]);
|
100
100
|
}
|
101
101
|
return Qnil;
|
@@ -103,23 +103,23 @@ private:
|
|
103
103
|
|
104
104
|
// #seed=
|
105
105
|
|
106
|
-
static VALUE
|
107
|
-
|
106
|
+
static VALUE _numo_random_set_seed(VALUE self, VALUE seed) {
|
107
|
+
get_rng(self)->seed(NUM2LONG(seed));
|
108
108
|
rb_iv_set(self, "seed", seed);
|
109
109
|
return Qnil;
|
110
110
|
}
|
111
111
|
|
112
112
|
// #seed
|
113
113
|
|
114
|
-
static VALUE
|
114
|
+
static VALUE _numo_random_get_seed(VALUE self) {
|
115
115
|
return rb_iv_get(self, "seed");
|
116
116
|
}
|
117
117
|
|
118
118
|
// #random
|
119
119
|
|
120
|
-
static VALUE
|
120
|
+
static VALUE _numo_random_random(VALUE self) {
|
121
121
|
std::uniform_real_distribution<double> uniform_dist(0, 1);
|
122
|
-
|
122
|
+
Rng* ptr = get_rng(self);
|
123
123
|
const double x = uniform_dist(*ptr);
|
124
124
|
return DBL2NUM(x);
|
125
125
|
}
|
@@ -128,7 +128,7 @@ private:
|
|
128
128
|
|
129
129
|
template<class D> struct rand_opt_t {
|
130
130
|
D dist;
|
131
|
-
|
131
|
+
Rng* rnd;
|
132
132
|
};
|
133
133
|
|
134
134
|
template<class D, typename T> static void _iter_rand(na_loop_t* const lp) {
|
@@ -155,7 +155,7 @@ private:
|
|
155
155
|
// #binomial
|
156
156
|
|
157
157
|
template<typename T> static void _rand_binomial(VALUE& self, VALUE& x, const long n, const double& p) {
|
158
|
-
|
158
|
+
Rng* ptr = get_rng(self);
|
159
159
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
160
160
|
std::binomial_distribution<T> binomial_dist(n, p);
|
161
161
|
ndfunc_t ndf = { _iter_rand<std::binomial_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -163,7 +163,7 @@ private:
|
|
163
163
|
na_ndloop3(&ndf, &opt, 1, x);
|
164
164
|
}
|
165
165
|
|
166
|
-
static VALUE
|
166
|
+
static VALUE _numo_random_binomial(int argc, VALUE* argv, VALUE self) {
|
167
167
|
VALUE x = Qnil;
|
168
168
|
VALUE kw_args = Qnil;
|
169
169
|
ID kw_table[2] = { rb_intern("n"), rb_intern("p") };
|
@@ -206,7 +206,7 @@ private:
|
|
206
206
|
// #negative_binomial
|
207
207
|
|
208
208
|
template<typename T> static void _rand_negative_binomial(VALUE& self, VALUE& x, const long n, const double& p) {
|
209
|
-
|
209
|
+
Rng* ptr = get_rng(self);
|
210
210
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
211
211
|
std::negative_binomial_distribution<T> negative_binomial_dist(n, p);
|
212
212
|
ndfunc_t ndf = { _iter_rand<std::negative_binomial_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -214,7 +214,7 @@ private:
|
|
214
214
|
na_ndloop3(&ndf, &opt, 1, x);
|
215
215
|
}
|
216
216
|
|
217
|
-
static VALUE
|
217
|
+
static VALUE _numo_random_negative_binomial(int argc, VALUE* argv, VALUE self) {
|
218
218
|
VALUE x = Qnil;
|
219
219
|
VALUE kw_args = Qnil;
|
220
220
|
ID kw_table[2] = { rb_intern("n"), rb_intern("p") };
|
@@ -257,7 +257,7 @@ private:
|
|
257
257
|
// #geometric
|
258
258
|
|
259
259
|
template<typename T> static void _rand_geometric(VALUE& self, VALUE& x, const double& p) {
|
260
|
-
|
260
|
+
Rng* ptr = get_rng(self);
|
261
261
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
262
262
|
std::geometric_distribution<T> geometric_dist(p);
|
263
263
|
ndfunc_t ndf = { _iter_rand<std::geometric_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -265,7 +265,7 @@ private:
|
|
265
265
|
na_ndloop3(&ndf, &opt, 1, x);
|
266
266
|
}
|
267
267
|
|
268
|
-
static VALUE
|
268
|
+
static VALUE _numo_random_geometric(int argc, VALUE* argv, VALUE self) {
|
269
269
|
VALUE x = Qnil;
|
270
270
|
VALUE kw_args = Qnil;
|
271
271
|
ID kw_table[1] = { rb_intern("p") };
|
@@ -306,7 +306,7 @@ private:
|
|
306
306
|
// #exponential
|
307
307
|
|
308
308
|
template<typename T> static void _rand_exponential(VALUE& self, VALUE& x, const double& lam) {
|
309
|
-
|
309
|
+
Rng* ptr = get_rng(self);
|
310
310
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
311
311
|
std::exponential_distribution<T> exponential_dist(lam);
|
312
312
|
ndfunc_t ndf = { _iter_rand<std::exponential_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -314,7 +314,7 @@ private:
|
|
314
314
|
na_ndloop3(&ndf, &opt, 1, x);
|
315
315
|
}
|
316
316
|
|
317
|
-
static VALUE
|
317
|
+
static VALUE _numo_random_exponential(int argc, VALUE* argv, VALUE self) {
|
318
318
|
VALUE x = Qnil;
|
319
319
|
VALUE kw_args = Qnil;
|
320
320
|
ID kw_table[1] = { rb_intern("scale") };
|
@@ -342,7 +342,7 @@ private:
|
|
342
342
|
// #gamma
|
343
343
|
|
344
344
|
template<typename T> static void _rand_gamma(VALUE& self, VALUE& x, const double& k, const double&scale) {
|
345
|
-
|
345
|
+
Rng* ptr = get_rng(self);
|
346
346
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
347
347
|
std::gamma_distribution<T> gamma_dist(k, scale);
|
348
348
|
ndfunc_t ndf = { _iter_rand<std::gamma_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -350,7 +350,7 @@ private:
|
|
350
350
|
na_ndloop3(&ndf, &opt, 1, x);
|
351
351
|
}
|
352
352
|
|
353
|
-
static VALUE
|
353
|
+
static VALUE _numo_random_gamma(int argc, VALUE* argv, VALUE self) {
|
354
354
|
VALUE x = Qnil;
|
355
355
|
VALUE kw_args = Qnil;
|
356
356
|
ID kw_table[2] = { rb_intern("k"), rb_intern("scale") };
|
@@ -379,7 +379,7 @@ private:
|
|
379
379
|
// #gumbel
|
380
380
|
|
381
381
|
template<typename T> static void _rand_gumbel(VALUE& self, VALUE& x, const double& loc, const double&scale) {
|
382
|
-
|
382
|
+
Rng* ptr = get_rng(self);
|
383
383
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
384
384
|
std::extreme_value_distribution<T> extreme_value_dist(loc, scale);
|
385
385
|
ndfunc_t ndf = { _iter_rand<std::extreme_value_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -387,7 +387,7 @@ private:
|
|
387
387
|
na_ndloop3(&ndf, &opt, 1, x);
|
388
388
|
}
|
389
389
|
|
390
|
-
static VALUE
|
390
|
+
static VALUE _numo_random_gumbel(int argc, VALUE* argv, VALUE self) {
|
391
391
|
VALUE x = Qnil;
|
392
392
|
VALUE kw_args = Qnil;
|
393
393
|
ID kw_table[2] = { rb_intern("loc"), rb_intern("scale") };
|
@@ -415,7 +415,7 @@ private:
|
|
415
415
|
// #poisson
|
416
416
|
|
417
417
|
template<typename T> static void _rand_poisson(VALUE& self, VALUE& x, const double& mean) {
|
418
|
-
|
418
|
+
Rng* ptr = get_rng(self);
|
419
419
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
420
420
|
std::poisson_distribution<T> poisson_dist(mean);
|
421
421
|
ndfunc_t ndf = { _iter_rand<std::poisson_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -423,7 +423,7 @@ private:
|
|
423
423
|
na_ndloop3(&ndf, &opt, 1, x);
|
424
424
|
}
|
425
425
|
|
426
|
-
static VALUE
|
426
|
+
static VALUE _numo_random_poisson(int argc, VALUE* argv, VALUE self) {
|
427
427
|
VALUE x = Qnil;
|
428
428
|
VALUE kw_args = Qnil;
|
429
429
|
ID kw_table[1] = { rb_intern("mean") };
|
@@ -464,7 +464,7 @@ private:
|
|
464
464
|
// #weibull
|
465
465
|
|
466
466
|
template<typename T> static void _rand_weibull(VALUE& self, VALUE& x, const double& k, const double&scale) {
|
467
|
-
|
467
|
+
Rng* ptr = get_rng(self);
|
468
468
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
469
469
|
std::weibull_distribution<T> weibull_dist(k, scale);
|
470
470
|
ndfunc_t ndf = { _iter_rand<std::weibull_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -472,7 +472,7 @@ private:
|
|
472
472
|
na_ndloop3(&ndf, &opt, 1, x);
|
473
473
|
}
|
474
474
|
|
475
|
-
static VALUE
|
475
|
+
static VALUE _numo_random_weibull(int argc, VALUE* argv, VALUE self) {
|
476
476
|
VALUE x = Qnil;
|
477
477
|
VALUE kw_args = Qnil;
|
478
478
|
ID kw_table[2] = { rb_intern("k"), rb_intern("scale") };
|
@@ -501,7 +501,7 @@ private:
|
|
501
501
|
// #discrete
|
502
502
|
|
503
503
|
template<typename T, typename P> static void _rand_discrete(VALUE& self, VALUE& x, const std::vector<P>& weight) {
|
504
|
-
|
504
|
+
Rng* ptr = get_rng(self);
|
505
505
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
506
506
|
std::discrete_distribution<T> discrete_dist(weight.begin(), weight.end());
|
507
507
|
ndfunc_t ndf = { _iter_rand<std::discrete_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -509,7 +509,7 @@ private:
|
|
509
509
|
na_ndloop3(&ndf, &opt, 1, x);
|
510
510
|
}
|
511
511
|
|
512
|
-
static VALUE
|
512
|
+
static VALUE _numo_random_discrete(int argc, VALUE* argv, VALUE self) {
|
513
513
|
VALUE x = Qnil;
|
514
514
|
VALUE kw_args = Qnil;
|
515
515
|
ID kw_table[1] = { rb_intern("weight") };
|
@@ -584,7 +584,7 @@ private:
|
|
584
584
|
// #uniform
|
585
585
|
|
586
586
|
template<typename T> static void _rand_uniform(VALUE& self, VALUE& x, const double& low, const double& high) {
|
587
|
-
|
587
|
+
Rng* ptr = get_rng(self);
|
588
588
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
589
589
|
std::uniform_real_distribution<T> uniform_dist(low, high);
|
590
590
|
ndfunc_t ndf = { _iter_rand<std::uniform_real_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -592,7 +592,7 @@ private:
|
|
592
592
|
na_ndloop3(&ndf, &opt, 1, x);
|
593
593
|
}
|
594
594
|
|
595
|
-
static VALUE
|
595
|
+
static VALUE _numo_random_uniform(int argc, VALUE* argv, VALUE self) {
|
596
596
|
VALUE x = Qnil;
|
597
597
|
VALUE kw_args = Qnil;
|
598
598
|
ID kw_table[2] = { rb_intern("low"), rb_intern("high") };
|
@@ -620,7 +620,7 @@ private:
|
|
620
620
|
// #cauchy
|
621
621
|
|
622
622
|
template<typename T> static void _rand_cauchy(VALUE& self, VALUE& x, const double& loc, const double& scale) {
|
623
|
-
|
623
|
+
Rng* ptr = get_rng(self);
|
624
624
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
625
625
|
std::cauchy_distribution<T> cauchy_dist(loc, scale);
|
626
626
|
ndfunc_t ndf = { _iter_rand<std::cauchy_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -628,7 +628,7 @@ private:
|
|
628
628
|
na_ndloop3(&ndf, &opt, 1, x);
|
629
629
|
}
|
630
630
|
|
631
|
-
static VALUE
|
631
|
+
static VALUE _numo_random_cauchy(int argc, VALUE* argv, VALUE self) {
|
632
632
|
VALUE x = Qnil;
|
633
633
|
VALUE kw_args = Qnil;
|
634
634
|
ID kw_table[2] = { rb_intern("loc"), rb_intern("scale") };
|
@@ -656,7 +656,7 @@ private:
|
|
656
656
|
// #chisqure
|
657
657
|
|
658
658
|
template<typename T> static void _rand_chisquare(VALUE& self, VALUE& x, const double& df) {
|
659
|
-
|
659
|
+
Rng* ptr = get_rng(self);
|
660
660
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
661
661
|
std::chi_squared_distribution<T> chisquare_dist(df);
|
662
662
|
ndfunc_t ndf = { _iter_rand<std::chi_squared_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -664,7 +664,7 @@ private:
|
|
664
664
|
na_ndloop3(&ndf, &opt, 1, x);
|
665
665
|
}
|
666
666
|
|
667
|
-
static VALUE
|
667
|
+
static VALUE _numo_random_chisquare(int argc, VALUE* argv, VALUE self) {
|
668
668
|
VALUE x = Qnil;
|
669
669
|
VALUE kw_args = Qnil;
|
670
670
|
ID kw_table[1] = { rb_intern("df") };
|
@@ -691,7 +691,7 @@ private:
|
|
691
691
|
// #f
|
692
692
|
|
693
693
|
template<typename T> static void _rand_f(VALUE& self, VALUE& x, const double& dfnum, const double& dfden) {
|
694
|
-
|
694
|
+
Rng* ptr = get_rng(self);
|
695
695
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
696
696
|
std::fisher_f_distribution<T> f_dist(dfnum, dfden);
|
697
697
|
ndfunc_t ndf = { _iter_rand<std::fisher_f_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -699,7 +699,7 @@ private:
|
|
699
699
|
na_ndloop3(&ndf, &opt, 1, x);
|
700
700
|
}
|
701
701
|
|
702
|
-
static VALUE
|
702
|
+
static VALUE _numo_random_f(int argc, VALUE* argv, VALUE self) {
|
703
703
|
VALUE x = Qnil;
|
704
704
|
VALUE kw_args = Qnil;
|
705
705
|
ID kw_table[2] = { rb_intern("dfnum"), rb_intern("dfden") };
|
@@ -728,7 +728,7 @@ private:
|
|
728
728
|
// #normal
|
729
729
|
|
730
730
|
template<typename T> static void _rand_normal(VALUE& self, VALUE& x, const double& loc, const double& scale) {
|
731
|
-
|
731
|
+
Rng* ptr = get_rng(self);
|
732
732
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
733
733
|
std::normal_distribution<T> normal_dist(loc, scale);
|
734
734
|
ndfunc_t ndf = { _iter_rand<std::normal_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -736,7 +736,7 @@ private:
|
|
736
736
|
na_ndloop3(&ndf, &opt, 1, x);
|
737
737
|
}
|
738
738
|
|
739
|
-
static VALUE
|
739
|
+
static VALUE _numo_random_normal(int argc, VALUE* argv, VALUE self) {
|
740
740
|
VALUE x = Qnil;
|
741
741
|
VALUE kw_args = Qnil;
|
742
742
|
ID kw_table[2] = { rb_intern("loc"), rb_intern("scale") };
|
@@ -764,7 +764,7 @@ private:
|
|
764
764
|
// #lognormal
|
765
765
|
|
766
766
|
template<typename T> static void _rand_lognormal(VALUE& self, VALUE& x, const double& mean, const double& sigma) {
|
767
|
-
|
767
|
+
Rng* ptr = get_rng(self);
|
768
768
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
769
769
|
std::lognormal_distribution<T> lognormal_dist(mean, sigma);
|
770
770
|
ndfunc_t ndf = { _iter_rand<std::lognormal_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -772,7 +772,7 @@ private:
|
|
772
772
|
na_ndloop3(&ndf, &opt, 1, x);
|
773
773
|
}
|
774
774
|
|
775
|
-
static VALUE
|
775
|
+
static VALUE _numo_random_lognormal(int argc, VALUE* argv, VALUE self) {
|
776
776
|
VALUE x = Qnil;
|
777
777
|
VALUE kw_args = Qnil;
|
778
778
|
ID kw_table[2] = { rb_intern("mean"), rb_intern("sigma") };
|
@@ -800,7 +800,7 @@ private:
|
|
800
800
|
// #standard_t
|
801
801
|
|
802
802
|
template<typename T> static void _rand_t(VALUE& self, VALUE& x, const double& df) {
|
803
|
-
|
803
|
+
Rng* ptr = get_rng(self);
|
804
804
|
ndfunc_arg_in_t ain[1] = { { OVERWRITE, 0 } };
|
805
805
|
std::student_t_distribution<T> t_dist(df);
|
806
806
|
ndfunc_t ndf = { _iter_rand<std::student_t_distribution<T>, T>, FULL_LOOP, 1, 0, ain, 0 };
|
@@ -808,7 +808,7 @@ private:
|
|
808
808
|
na_ndloop3(&ndf, &opt, 1, x);
|
809
809
|
}
|
810
810
|
|
811
|
-
static VALUE
|
811
|
+
static VALUE _numo_random_standard_t(int argc, VALUE* argv, VALUE self) {
|
812
812
|
VALUE x = Qnil;
|
813
813
|
VALUE kw_args = Qnil;
|
814
814
|
ID kw_table[1] = { rb_intern("df") };
|
@@ -833,16 +833,72 @@ private:
|
|
833
833
|
}
|
834
834
|
};
|
835
835
|
|
836
|
-
|
836
|
+
class RbNumoRandomPCG32 : public RbNumoRandom<pcg32, RbNumoRandomPCG32> {
|
837
|
+
public:
|
838
|
+
static const rb_data_type_t rng_type;
|
839
|
+
};
|
840
|
+
|
841
|
+
const rb_data_type_t RbNumoRandomPCG32::rng_type = {
|
842
|
+
"RbNumoRandomPCG32",
|
843
|
+
{
|
844
|
+
NULL,
|
845
|
+
RbNumoRandomPCG32::numo_random_free,
|
846
|
+
RbNumoRandomPCG32::numo_random_size
|
847
|
+
},
|
848
|
+
NULL,
|
849
|
+
NULL,
|
850
|
+
0
|
851
|
+
};
|
852
|
+
|
853
|
+
class RbNumoRandomPCG64 : public RbNumoRandom<pcg64, RbNumoRandomPCG64> {
|
854
|
+
public:
|
855
|
+
static const rb_data_type_t rng_type;
|
856
|
+
};
|
857
|
+
|
858
|
+
const rb_data_type_t RbNumoRandomPCG64::rng_type = {
|
837
859
|
"RbNumoRandomPCG64",
|
838
860
|
{
|
839
861
|
NULL,
|
840
|
-
RbNumoRandomPCG64::
|
841
|
-
RbNumoRandomPCG64::
|
862
|
+
RbNumoRandomPCG64::numo_random_free,
|
863
|
+
RbNumoRandomPCG64::numo_random_size
|
864
|
+
},
|
865
|
+
NULL,
|
866
|
+
NULL,
|
867
|
+
0
|
868
|
+
};
|
869
|
+
|
870
|
+
class RbNumoRandomMT32 : public RbNumoRandom<std::mt19937, RbNumoRandomMT32> {
|
871
|
+
public:
|
872
|
+
static const rb_data_type_t rng_type;
|
873
|
+
};
|
874
|
+
|
875
|
+
const rb_data_type_t RbNumoRandomMT32::rng_type = {
|
876
|
+
"RbNumoRandomMT32",
|
877
|
+
{
|
878
|
+
NULL,
|
879
|
+
RbNumoRandomMT32::numo_random_free,
|
880
|
+
RbNumoRandomMT32::numo_random_size
|
881
|
+
},
|
882
|
+
NULL,
|
883
|
+
NULL,
|
884
|
+
0
|
885
|
+
};
|
886
|
+
|
887
|
+
class RbNumoRandomMT64 : public RbNumoRandom<std::mt19937_64, RbNumoRandomMT64> {
|
888
|
+
public:
|
889
|
+
static const rb_data_type_t rng_type;
|
890
|
+
};
|
891
|
+
|
892
|
+
const rb_data_type_t RbNumoRandomMT64::rng_type = {
|
893
|
+
"RbNumoRandomMT64",
|
894
|
+
{
|
895
|
+
NULL,
|
896
|
+
RbNumoRandomMT64::numo_random_free,
|
897
|
+
RbNumoRandomMT64::numo_random_size
|
842
898
|
},
|
843
899
|
NULL,
|
844
900
|
NULL,
|
845
|
-
|
901
|
+
0
|
846
902
|
};
|
847
903
|
|
848
904
|
#endif /* NUMO_RANDOM_EXT_HPP */
|
@@ -24,10 +24,21 @@ module Numo
|
|
24
24
|
# Creates a new random number generator.
|
25
25
|
#
|
26
26
|
# @param seed [Integer] random seed used to initialize the random number generator.
|
27
|
-
# @param algorithm [String] random number generation algorithm.
|
28
|
-
def initialize(seed: nil, algorithm: 'pcg64') # rubocop:disable
|
29
|
-
@algorithm =
|
30
|
-
@rng =
|
27
|
+
# @param algorithm [String] random number generation algorithm ('mt32', 'mt64', 'pcg32', and 'pcg64').
|
28
|
+
def initialize(seed: nil, algorithm: 'pcg64') # rubocop:disable Metrics/MethodLength
|
29
|
+
@algorithm = algorithm.to_s
|
30
|
+
@rng = case @algorithm
|
31
|
+
when 'mt32'
|
32
|
+
MT32.new(seed: seed)
|
33
|
+
when 'mt64'
|
34
|
+
MT64.new(seed: seed)
|
35
|
+
when 'pcg32'
|
36
|
+
PCG32.new(seed: seed)
|
37
|
+
when 'pcg64'
|
38
|
+
PCG64.new(seed: seed)
|
39
|
+
else
|
40
|
+
raise ArgumentError, "Numo::Random::Generator does not support '#{@algorithm}' algorithm"
|
41
|
+
end
|
31
42
|
end
|
32
43
|
|
33
44
|
# Returns the seed of random number generator.
|
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.5.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-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: numo-narray
|