numo-random 0.2.0 → 0.4.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: 18a6bedc77eb910e04462508a925d336fe2e5e8c29f9c159643adea1e0988a88
4
- data.tar.gz: 728c52eb3e9f390cae89d149e6d4305228be5330e90fa39494ac0a1ffa546126
3
+ metadata.gz: 9c0f7c2bfe21c7c499f2d18453607b78ccd48bfea287336a3ce8ca4bee1a30e0
4
+ data.tar.gz: cef6d2005611cabe21606d3b9e3fe31b82ee9e34e909206c6b0b89b6fc78115d
5
5
  SHA512:
6
- metadata.gz: cd851012b81e6cec4d4dc7e37113ca9c6d5e0a56604107bba201a67cc4935f3618f887285a0c745adf3ad6c25493bbe6bd5fe4af49cac08eead625cb0c6afa78
7
- data.tar.gz: 88f85185352601de72dbf8889095e2603c0b581750c11d683eddab26ab313f30c1b38577a1a3a099d2dc6834d29e0fbe2e53052e05918e5de00648adfcf9930d
6
+ metadata.gz: 7e42a2ecae4e48173c0f96a8d5170bed05165c378289a3b84c1fdad56bd8dcc392b53596c1d3501ddf151bfdd6b10ae82032b6b6ca4f1f03a38e87e8ff83f418
7
+ data.tar.gz: 96f8de00675b3762ed859a5a9afef3fa8f2fe8a7d48562a3aae267d78caa963e9ddc6c514a6c14a0121b4ab1d633d370a04b6fd64551a60b46e03f73c94682b9
data/CHANGELOG.md CHANGED
@@ -1,9 +1,11 @@
1
- ## [Unreleased]
2
- - Bernoulli distribution.
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.2.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 "randomext.hpp"
19
+ #include "ext.hpp"
20
20
 
21
- extern "C" void Init_randomext(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 NUMO_RANDOMEXT_HPP
20
- #define NUMO_RANDOMEXT_HPP 1
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 /* NUMO_RANDOMEXT_HPP */
848
+ #endif /* NUMO_RANDOM_EXT_HPP */
@@ -26,4 +26,4 @@ $CXXFLAGS << " -std=c++11"
26
26
  $INCFLAGS << " -I$(srcdir)/src"
27
27
  $VPATH << "$(srcdir)/src"
28
28
 
29
- create_makefile("numo/random/randomext")
29
+ create_makefile("numo/random/ext")
@@ -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
@@ -3,6 +3,6 @@
3
3
  module Numo
4
4
  module Random
5
5
  # The version of Numo::Random you install.
6
- VERSION = '0.2.0'
6
+ VERSION = '0.4.0'
7
7
  end
8
8
  end
data/lib/numo/random.rb CHANGED
@@ -3,5 +3,5 @@
3
3
  require 'numo/narray'
4
4
 
5
5
  require_relative 'random/version'
6
- require_relative 'random/randomext'
6
+ require_relative 'random/ext'
7
7
  require_relative 'random/generator'
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.2.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-10-30 00:00:00.000000000 Z
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