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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9c0f7c2bfe21c7c499f2d18453607b78ccd48bfea287336a3ce8ca4bee1a30e0
4
- data.tar.gz: cef6d2005611cabe21606d3b9e3fe31b82ee9e34e909206c6b0b89b6fc78115d
3
+ metadata.gz: d9c0d26c2b1751451a84c8b53c6e38b9257a82ff7d2c3479bd94d7311cfb1628
4
+ data.tar.gz: ae9262ff84d81abb58af7d4856e0936160c33f3a824818515878ae97ce3c9ea0
5
5
  SHA512:
6
- metadata.gz: 7e42a2ecae4e48173c0f96a8d5170bed05165c378289a3b84c1fdad56bd8dcc392b53596c1d3501ddf151bfdd6b10ae82032b6b6ca4f1f03a38e87e8ff83f418
7
- data.tar.gz: 96f8de00675b3762ed859a5a9afef3fa8f2fe8a7d48562a3aae267d78caa963e9ddc6c514a6c14a0121b4ab1d633d370a04b6fd64551a60b46e03f73c94682b9
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.
@@ -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
- RbNumoRandomPCG64::define_class(rb_mNumoRandom);
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
  }
@@ -28,74 +28,74 @@
28
28
 
29
29
  #include <pcg_random.hpp>
30
30
 
31
- class RbNumoRandomPCG64 {
31
+ template<class Rng, class Impl> class RbNumoRandom {
32
32
  public:
33
- static VALUE numo_random_pcg64_alloc(VALUE self) {
34
- pcg64* ptr = (pcg64*)ruby_xmalloc(sizeof(pcg64));
35
- new (ptr) pcg64();
36
- return TypedData_Wrap_Struct(self, &pcg64_type, ptr);
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 numo_random_pcg64_free(void* ptr) {
40
- ((pcg64*)ptr)->~pcg64();
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 numo_random_pcg64_size(const void* ptr) {
45
- return sizeof(*((pcg64*)ptr));
46
+ static size_t numo_random_size(const void* ptr) {
47
+ return sizeof(*((Rng*)ptr));
46
48
  }
47
49
 
48
- static pcg64* get_pcg64(VALUE self) {
49
- pcg64* ptr;
50
- TypedData_Get_Struct(self, pcg64, &pcg64_type, ptr);
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 rb_cPCG64 = rb_define_class_under(rb_mNumoRandom, "PCG64", rb_cObject);
56
- rb_define_alloc_func(rb_cPCG64, numo_random_pcg64_alloc);
57
- rb_define_method(rb_cPCG64, "initialize", RUBY_METHOD_FUNC(_numo_random_pcg64_init), -1);
58
- rb_define_method(rb_cPCG64, "seed=", RUBY_METHOD_FUNC(_numo_random_pcg64_set_seed), 1);
59
- rb_define_method(rb_cPCG64, "seed", RUBY_METHOD_FUNC(_numo_random_pcg64_get_seed), 0);
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);
69
- rb_define_method(rb_cPCG64, "discrete", RUBY_METHOD_FUNC(_numo_random_pcg64_discrete), -1);
70
- rb_define_method(rb_cPCG64, "uniform", RUBY_METHOD_FUNC(_numo_random_pcg64_uniform), -1);
71
- rb_define_method(rb_cPCG64, "cauchy", RUBY_METHOD_FUNC(_numo_random_pcg64_cauchy), -1);
72
- rb_define_method(rb_cPCG64, "chisquare", RUBY_METHOD_FUNC(_numo_random_pcg64_chisquare), -1);
73
- rb_define_method(rb_cPCG64, "f", RUBY_METHOD_FUNC(_numo_random_pcg64_f), -1);
74
- rb_define_method(rb_cPCG64, "normal", RUBY_METHOD_FUNC(_numo_random_pcg64_normal), -1);
75
- rb_define_method(rb_cPCG64, "lognormal", RUBY_METHOD_FUNC(_numo_random_pcg64_lognormal), -1);
76
- rb_define_method(rb_cPCG64, "standard_t", RUBY_METHOD_FUNC(_numo_random_pcg64_standard_t), -1);
77
- return rb_cPCG64;
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 _numo_random_pcg64_init(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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) pcg64(seed);
95
+ new (ptr) Rng(seed);
96
96
  rb_iv_set(self, "seed", UINT2NUM(seed));
97
97
  } else {
98
- new (ptr) pcg64(NUM2LONG(kw_values[0]));
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 _numo_random_pcg64_set_seed(VALUE self, VALUE seed) {
107
- get_pcg64(self)->seed(NUM2LONG(seed));
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 _numo_random_pcg64_get_seed(VALUE self) {
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 _numo_random_pcg64_random(VALUE self) {
120
+ static VALUE _numo_random_random(VALUE self) {
121
121
  std::uniform_real_distribution<double> uniform_dist(0, 1);
122
- pcg64* ptr = get_pcg64(self);
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
- pcg64* rnd;
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_binomial(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_negative_binomial(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_geometric(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_exponential(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_gamma(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_gumbel(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_poisson(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_weibull(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_discrete(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_uniform(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_cauchy(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_chisquare(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_f(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_normal(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_lognormal(int argc, VALUE* argv, VALUE self) {
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
- pcg64* ptr = get_pcg64(self);
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 _numo_random_pcg64_standard_t(int argc, VALUE* argv, VALUE self) {
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
- const rb_data_type_t RbNumoRandomPCG64::pcg64_type = {
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::numo_random_pcg64_free,
841
- RbNumoRandomPCG64::numo_random_pcg64_size
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
- RUBY_TYPED_FREE_IMMEDIATELY
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 Lint/UnusedMethodArgument
29
- @algorithm = 'pcg64'
30
- @rng = PCG64.new(seed: seed)
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.
@@ -3,6 +3,6 @@
3
3
  module Numo
4
4
  module Random
5
5
  # The version of Numo::Random you install.
6
- VERSION = '0.4.0'
6
+ VERSION = '0.5.0'
7
7
  end
8
8
  end
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.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-09 00:00:00.000000000 Z
11
+ date: 2022-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: numo-narray