numo-random 0.4.0 → 0.5.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 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