/*
rng.c
Ruby/GSL: Ruby extension library for GSL (GNU Scientific Library)
(C) Copyright 2001-2006 by Yoshiki Tsunesada
Ruby/GSL is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY.
*/
/*
Document-class: GSL::Rng
Random number generator
*/
#include "include/rb_gsl_rng.h"
#ifdef HAVE_RNGEXTRA_RNGEXTRA_H
#include "rngextra/rngextra.h"
#endif
/* Global, since used in other source files */
VALUE cgsl_rng;
enum rb_gsl_rng_generator {
GSL_RNG_DEFAULT,
GSL_RNG_MT19937, GSL_RNG_MT19937_1999, GSL_RNG_MT19937_1998,
GSL_RNG_RANLXS0, GSL_RNG_RANLXS1, GSL_RNG_RANLXS2,
GSL_RNG_RANLXD1, GSL_RNG_RANLXD2,
GSL_RNG_RANLUX, GSL_RNG_RANLUX389,
GSL_RNG_CMRG, GSL_RNG_MRG,
GSL_RNG_TAUS, GSL_RNG_TAUS2, GSL_RNG_TAUS113, GSL_RNG_GFSR4,
GSL_RNG_RAND,
GSL_RNG_RANDOM_BSD, GSL_RNG_RANDOM_GLIBC2,
GSL_RNG_RANDOM8_GLIBC2, GSL_RNG_RANDOM32_GLIBC2, GSL_RNG_RANDOM64_GLIBC2,
GSL_RNG_RANDOM128_GLIBC2, GSL_RNG_RANDOM256_GLIBC2,
GSL_RNG_RANDOM8_BSD, GSL_RNG_RANDOM32_BSD, GSL_RNG_RANDOM64_BSD,
GSL_RNG_RANDOM128_BSD, GSL_RNG_RANDOM256_BSD,
GSL_RNG_RANDOM_LIBC5, GSL_RNG_RANDOM8_LIBC5, GSL_RNG_RANDOM32_LIBC5,
GSL_RNG_RANDOM64_LIBC5, GSL_RNG_RANDOM128_LIBC5, GSL_RNG_RANDOM256_LIBC5,
GSL_RNG_RAND48,
GSL_RNG_RAN0, GSL_RNG_RAN1, GSL_RNG_RAN2, GSL_RNG_RAN3,
GSL_RNG_RANF, GSL_RNG_RANMAR, GSL_RNG_R250, GSL_RNG_TT800, GSL_RNG_VAX,
GSL_RNG_TRANSPUTER, GSL_RNG_RANDU, GSL_RNG_MINSTD,
GSL_RNG_UNI, GSL_RNG_UNI32, GSL_RNG_SLATEC, GSL_RNG_ZUF,
/* from gsl-1.1 */
GSL_RNG_BOROSH13, GSL_RNG_COVEYOU, GSL_RNG_FISHMAN18, GSL_RNG_FISHMAN20,
GSL_RNG_FISHMAN2X, GSL_RNG_KNUTHRAN, GSL_RNG_KNUTHRAN2,
GSL_RNG_LECUYER21, GSL_RNG_WATERMAN14,
/* For the rngextra package */
/* Tue Oct 19 22:55:56 JST 2004 by Y.Tsunesada */
GSL_RNGEXTRA_RNG1, GSL_RNGEXTRA_RNG2,
/* GSL-1.9 */
GSL_RNG_KNUTHRAN2002,
};
static const gsl_rng_type* get_gsl_rng_type(VALUE t);
/*
Document-method: GSL::Rng.alloc
Constructor.
*/
static VALUE rb_gsl_rng_alloc(int argc, VALUE *argv, VALUE klass)
{
gsl_rng *r = NULL;
const gsl_rng_type *T;
unsigned long seed;
int itype;
gsl_rng_env_setup();
if (argc == 0) {
T = gsl_rng_default;
seed = gsl_rng_default_seed;
} else {
T = get_gsl_rng_type(argv[0]);
if (argc == 1) {
seed = gsl_rng_default_seed;
} else if (argc == 2) {
itype = TYPE(argv[1]);
if (itype == T_FIXNUM || itype == T_BIGNUM) {
seed = FIX2INT(argv[1]);
} else {
rb_raise(rb_eArgError,
"bad argument 2, seed must be an integer.");
}
} else {
rb_raise(rb_eArgError, "too many arguments (%d for 0 or 1)", argc);
}
}
r = gsl_rng_alloc(T);
gsl_rng_set(r, seed);
return Data_Wrap_Struct(klass, 0, gsl_rng_free, r);
}
static const gsl_rng_type* get_gsl_rng_type_int(int itype);
static const gsl_rng_type* get_gsl_rng_type_name(char *name);
static const gsl_rng_type* get_gsl_rng_type(VALUE t)
{
switch (TYPE(t)) {
case T_STRING:
return get_gsl_rng_type_name(STR2CSTR(t));
break;
case T_FIXNUM:
return get_gsl_rng_type_int(FIX2INT(t));
break;
default:
rb_raise(rb_eTypeError, "String or Fixnum expected");
}
}
static const gsl_rng_type* get_gsl_rng_type_name(char *name)
{
if (str_tail_grep(name, "default") == 0) return gsl_rng_default;
else if (str_tail_grep(name, "mt19937") == 0) return gsl_rng_mt19937;
else if (str_tail_grep(name, "borosh13") == 0) return gsl_rng_borosh13;
else if (str_tail_grep(name, "coveyou") == 0) return gsl_rng_coveyou;
else if (str_tail_grep(name, "fishman18") == 0) return gsl_rng_fishman18;
else if (str_tail_grep(name, "fishman20") == 0) return gsl_rng_fishman20;
else if (str_tail_grep(name, "fishman2x") == 0) return gsl_rng_fishman2x;
else if (str_tail_grep(name, "lecuyer21") == 0) return gsl_rng_lecuyer21;
else if (str_tail_grep(name, "waterman14") == 0) return gsl_rng_waterman14;
else if (str_tail_grep(name, "knuthran") == 0) return gsl_rng_knuthran;
else if (str_tail_grep(name, "knuthran2") == 0) return gsl_rng_knuthran2;
else if (str_tail_grep(name, "mt19937_1999") == 0) return gsl_rng_mt19937_1999;
else if (str_tail_grep(name, "mt19937-1999") == 0) return gsl_rng_mt19937_1999;
else if (str_tail_grep(name, "mt19937_1998") == 0) return gsl_rng_mt19937_1998;
else if (str_tail_grep(name, "mt19937-1998") == 0) return gsl_rng_mt19937_1998;
else if (str_tail_grep(name, "taus113") == 0) return gsl_rng_taus113;
else if (str_tail_grep(name, "taus2") == 0) return gsl_rng_taus2;
else if (str_tail_grep(name, "mt19937") == 0) return gsl_rng_mt19937;
else if (str_tail_grep(name, "ranlxs0") == 0) return gsl_rng_ranlxs0;
else if (str_tail_grep(name, "ranlxs1") == 0) return gsl_rng_ranlxs1;
else if (str_tail_grep(name, "ranlxs2") == 0) return gsl_rng_ranlxs2;
else if (str_tail_grep(name, "ranlxd1") == 0) return gsl_rng_ranlxd1;
else if (str_tail_grep(name, "ranlxd2") == 0) return gsl_rng_ranlxd2;
else if (str_tail_grep(name, "ranlux") == 0) return gsl_rng_ranlux;
else if (str_tail_grep(name, "ranlux389") == 0) return gsl_rng_ranlux389;
else if (str_tail_grep(name, "cmrg") == 0) return gsl_rng_cmrg;
else if (str_tail_grep(name, "mrg") == 0) return gsl_rng_mrg;
else if (str_tail_grep(name, "taus") == 0) return gsl_rng_taus;
else if (str_tail_grep(name, "gfsr4") == 0) return gsl_rng_gfsr4;
else if (str_tail_grep(name, "rand") == 0) return gsl_rng_rand;
else if (str_tail_grep(name, "random_libc5") == 0) return gsl_rng_random_libc5;
else if (str_tail_grep(name, "random8_libc5") == 0) return gsl_rng_random8_libc5;
else if (str_tail_grep(name, "random32_libc5") == 0) return gsl_rng_random32_libc5;
else if (str_tail_grep(name, "random64_libc5") == 0) return gsl_rng_random64_libc5;
else if (str_tail_grep(name, "random128_libc5") == 0) return gsl_rng_random128_libc5;
else if (str_tail_grep(name, "random256_libc5") == 0) return gsl_rng_random256_libc5;
else if (str_tail_grep(name, "random-libc5") == 0) return gsl_rng_random_libc5;
else if (str_tail_grep(name, "random8-libc5") == 0) return gsl_rng_random8_libc5;
else if (str_tail_grep(name, "random32-libc5") == 0) return gsl_rng_random32_libc5;
else if (str_tail_grep(name, "random64-libc5") == 0) return gsl_rng_random64_libc5;
else if (str_tail_grep(name, "random128-libc5") == 0) return gsl_rng_random128_libc5;
else if (str_tail_grep(name, "random256-libc5") == 0) return gsl_rng_random256_libc5;
else if (str_tail_grep(name, "random_glibc2") == 0) return gsl_rng_random_glibc2;
else if (str_tail_grep(name, "random8_glibc2") == 0) return gsl_rng_random8_glibc2;
else if (str_tail_grep(name, "random32_glibc2") == 0) return gsl_rng_random32_glibc2;
else if (str_tail_grep(name, "random64_glibc2") == 0) return gsl_rng_random64_glibc2;
else if (str_tail_grep(name, "random128_glibc2") == 0) return gsl_rng_random128_glibc2;
else if (str_tail_grep(name, "random256_glibc2") == 0) return gsl_rng_random256_glibc2;
else if (str_tail_grep(name, "random-glibc2") == 0) return gsl_rng_random_glibc2;
else if (str_tail_grep(name, "random8-glibc2") == 0) return gsl_rng_random8_glibc2;
else if (str_tail_grep(name, "random32-glibc2") == 0) return gsl_rng_random32_glibc2;
else if (str_tail_grep(name, "random64-glibc2") == 0) return gsl_rng_random64_glibc2;
else if (str_tail_grep(name, "random128-glibc2") == 0) return gsl_rng_random128_glibc2;
else if (str_tail_grep(name, "random256-glibc2") == 0) return gsl_rng_random256_glibc2;
else if (str_tail_grep(name, "random_bsd") == 0) return gsl_rng_random_bsd;
else if (str_tail_grep(name, "random8_bsd") == 0) return gsl_rng_random8_bsd;
else if (str_tail_grep(name, "random32_bsd") == 0) return gsl_rng_random32_bsd;
else if (str_tail_grep(name, "random64_bsd") == 0) return gsl_rng_random64_bsd;
else if (str_tail_grep(name, "random128_bsd") == 0) return gsl_rng_random128_bsd;
else if (str_tail_grep(name, "random256_bsd") == 0) return gsl_rng_random256_bsd;
else if (str_tail_grep(name, "random-bsd") == 0) return gsl_rng_random_bsd;
else if (str_tail_grep(name, "random8-bsd") == 0) return gsl_rng_random8_bsd;
else if (str_tail_grep(name, "random32-bsd") == 0) return gsl_rng_random32_bsd;
else if (str_tail_grep(name, "random64-bsd") == 0) return gsl_rng_random64_bsd;
else if (str_tail_grep(name, "random128-bsd") == 0) return gsl_rng_random128_bsd;
else if (str_tail_grep(name, "random256-bsd") == 0) return gsl_rng_random256_bsd;
else if (str_tail_grep(name, "rand48") == 0) return gsl_rng_rand48;
else if (str_tail_grep(name, "ran0") == 0) return gsl_rng_ran0;
else if (str_tail_grep(name, "ran1") == 0) return gsl_rng_ran1;
else if (str_tail_grep(name, "ran2") == 0) return gsl_rng_ran2;
else if (str_tail_grep(name, "ran3") == 0) return gsl_rng_ran3;
else if (str_tail_grep(name, "ranf") == 0) return gsl_rng_ranf;
else if (str_tail_grep(name, "ranmar") == 0) return gsl_rng_ranmar;
else if (str_tail_grep(name, "r250") == 0) return gsl_rng_r250;
else if (str_tail_grep(name, "tt800") == 0) return gsl_rng_tt800;
else if (str_tail_grep(name, "vax") == 0) return gsl_rng_vax;
else if (str_tail_grep(name, "transputer") == 0) return gsl_rng_transputer;
else if (str_tail_grep(name, "randu") == 0) return gsl_rng_randu;
else if (str_tail_grep(name, "minstd") == 0) return gsl_rng_minstd;
else if (str_tail_grep(name, "uni") == 0) return gsl_rng_uni;
else if (str_tail_grep(name, "uni32") == 0) return gsl_rng_uni32;
else if (str_tail_grep(name, "slatec") == 0) return gsl_rng_slatec;
else if (str_tail_grep(name, "zuf") == 0) return gsl_rng_zuf;
#ifdef HAVE_RNGEXTRA_RNGEXTRA_H
else if (str_tail_grep(name, "rngextra_rng1") == 0) return rngextra_rng1;
else if (str_tail_grep(name, "rngextra_rng2") == 0) return rngextra_rng2;
else if (str_tail_grep(name, "rngextra-rng1") == 0) return rngextra_rng1;
else if (str_tail_grep(name, "rngextra-rng2") == 0) return rngextra_rng2;
#else
else if (str_tail_grep(name, "rngextra_rng1")*str_tail_grep(name, "rngextra_rng2") == 0)
rb_raise(rb_eNotImpError, "Install the rngextra package found at .");
else if (str_tail_grep(name, "rngextra_rng2")*str_tail_grep(name, "rngextra_rng2") == 0)
rb_raise(rb_eNotImpError, "Install the rngextra package found at .");
else if (str_tail_grep(name, "rngextra-rng1")*str_tail_grep(name, "rngextra_rng2") == 0)
rb_raise(rb_eNotImpError, "Install the rngextra package found at .");
else if (str_tail_grep(name, "rngextra-rng2")*str_tail_grep(name, "rngextra_rng2") == 0)
rb_raise(rb_eNotImpError, "Install the rngextra package found at .");
#endif
else if (str_tail_grep(name, "knuthran2002") == 0) return gsl_rng_knuthran2002;
else
rb_raise(rb_eArgError, "unknown generator type \"%s\"", name);
}
static const gsl_rng_type* get_gsl_rng_type_int(int itype)
{
const gsl_rng_type *T;
switch (itype) {
case GSL_RNG_DEFAULT: T = gsl_rng_default; break;
case GSL_RNG_MT19937: T = gsl_rng_mt19937; break; /* default */
case GSL_RNG_MT19937_1999: T = gsl_rng_mt19937_1999; break;
case GSL_RNG_MT19937_1998: T = gsl_rng_mt19937_1998; break;
case GSL_RNG_TAUS113: T = gsl_rng_taus113; break;
case GSL_RNG_TAUS2: T = gsl_rng_taus2; break;
case GSL_RNG_RANLXS0: T = gsl_rng_ranlxs0; break;
case GSL_RNG_RANLXS1: T = gsl_rng_ranlxs1; break;
case GSL_RNG_RANLXS2: T = gsl_rng_ranlxs2; break;
case GSL_RNG_RANLXD1: T = gsl_rng_ranlxd1; break;
case GSL_RNG_RANLXD2: T = gsl_rng_ranlxd2; break;
case GSL_RNG_RANLUX: T = gsl_rng_ranlux; break;
case GSL_RNG_RANLUX389: T = gsl_rng_ranlux389; break;
case GSL_RNG_CMRG: T = gsl_rng_cmrg; break;
case GSL_RNG_MRG: T = gsl_rng_mrg; break;
case GSL_RNG_TAUS: T = gsl_rng_taus; break;
case GSL_RNG_GFSR4: T = gsl_rng_gfsr4; break;
case GSL_RNG_RAND: T = gsl_rng_rand; break;
case GSL_RNG_RANDOM_LIBC5: T = gsl_rng_random_libc5; break;
case GSL_RNG_RANDOM8_LIBC5: T = gsl_rng_random8_libc5; break;
case GSL_RNG_RANDOM32_LIBC5: T = gsl_rng_random32_libc5; break;
case GSL_RNG_RANDOM64_LIBC5: T = gsl_rng_random64_libc5; break;
case GSL_RNG_RANDOM128_LIBC5: T = gsl_rng_random128_libc5; break;
case GSL_RNG_RANDOM256_LIBC5: T = gsl_rng_random256_libc5; break;
case GSL_RNG_RANDOM_GLIBC2: T = gsl_rng_random_glibc2; break;
case GSL_RNG_RANDOM8_GLIBC2: T = gsl_rng_random8_glibc2; break;
case GSL_RNG_RANDOM32_GLIBC2: T = gsl_rng_random32_glibc2; break;
case GSL_RNG_RANDOM64_GLIBC2: T = gsl_rng_random64_glibc2; break;
case GSL_RNG_RANDOM128_GLIBC2: T = gsl_rng_random128_glibc2; break;
case GSL_RNG_RANDOM256_GLIBC2: T = gsl_rng_random256_glibc2; break;
case GSL_RNG_RANDOM_BSD: T = gsl_rng_random_bsd; break;
case GSL_RNG_RANDOM8_BSD: T = gsl_rng_random8_bsd; break;
case GSL_RNG_RANDOM32_BSD: T = gsl_rng_random32_bsd; break;
case GSL_RNG_RANDOM64_BSD: T = gsl_rng_random64_bsd; break;
case GSL_RNG_RANDOM128_BSD: T = gsl_rng_random128_bsd; break;
case GSL_RNG_RANDOM256_BSD: T = gsl_rng_random256_bsd; break;
case GSL_RNG_RAND48: T = gsl_rng_rand48; break;
case GSL_RNG_RAN0: T = gsl_rng_ran0; break;
case GSL_RNG_RAN1: T = gsl_rng_ran1; break;
case GSL_RNG_RAN2: T = gsl_rng_ran2; break;
case GSL_RNG_RAN3: T = gsl_rng_ran3; break;
case GSL_RNG_RANF: T = gsl_rng_ranf; break;
case GSL_RNG_RANMAR: T = gsl_rng_ranmar; break;
case GSL_RNG_R250: T = gsl_rng_r250; break;
case GSL_RNG_TT800: T = gsl_rng_tt800; break;
case GSL_RNG_VAX: T = gsl_rng_vax; break;
case GSL_RNG_TRANSPUTER: T = gsl_rng_transputer; break;
case GSL_RNG_RANDU: T = gsl_rng_randu; break;
case GSL_RNG_MINSTD: T = gsl_rng_minstd; break;
case GSL_RNG_UNI: T = gsl_rng_uni; break;
case GSL_RNG_UNI32: T = gsl_rng_uni32; break;
case GSL_RNG_SLATEC: T = gsl_rng_slatec; break;
case GSL_RNG_ZUF: T = gsl_rng_zuf; break;
case GSL_RNG_BOROSH13: T = gsl_rng_borosh13; break;
case GSL_RNG_COVEYOU: T = gsl_rng_coveyou; break;
case GSL_RNG_FISHMAN18: T = gsl_rng_fishman18; break;
case GSL_RNG_FISHMAN20: T = gsl_rng_fishman20; break;
case GSL_RNG_FISHMAN2X: T = gsl_rng_fishman2x; break;
case GSL_RNG_KNUTHRAN: T = gsl_rng_knuthran; break;
case GSL_RNG_KNUTHRAN2: T = gsl_rng_knuthran2; break;
case GSL_RNG_LECUYER21: T = gsl_rng_lecuyer21; break;
case GSL_RNG_WATERMAN14: T = gsl_rng_waterman14; break;
#ifdef HAVE_RNGEXTRA_RNGEXTRA_H
case GSL_RNGEXTRA_RNG1: T = rngextra_rng1; break;
case GSL_RNGEXTRA_RNG2: T = rngextra_rng2; break;
#else
case GSL_RNGEXTRA_RNG1:
case GSL_RNGEXTRA_RNG2:
rb_raise(rb_eNotImpError, "Install the rngextra package found at .");
break;
#endif
case GSL_RNG_KNUTHRAN2002: T = gsl_rng_knuthran2002; break;
default:
rb_raise(rb_eTypeError, "wrong generator type");
}
return T;
}
static void rb_gsl_rng_define_const_type(VALUE module)
{
rb_define_const(cgsl_rng, "DEFAULT", INT2FIX(GSL_RNG_DEFAULT));
rb_define_const(cgsl_rng, "MT19937", INT2FIX(GSL_RNG_MT19937));
rb_define_const(cgsl_rng, "MT19937_1999", INT2FIX(GSL_RNG_MT19937_1999));
rb_define_const(cgsl_rng, "MT19937_1998", INT2FIX(GSL_RNG_MT19937_1999));
rb_define_const(cgsl_rng, "RANLXS0", INT2FIX(GSL_RNG_RANLXS0));
rb_define_const(cgsl_rng, "RANLXS1", INT2FIX(GSL_RNG_RANLXS1));
rb_define_const(cgsl_rng, "RANLXS2", INT2FIX(GSL_RNG_RANLXS2));
rb_define_const(cgsl_rng, "RANLXD1", INT2FIX(GSL_RNG_RANLXD1));
rb_define_const(cgsl_rng, "RANLXD2", INT2FIX(GSL_RNG_RANLXD2));
rb_define_const(cgsl_rng, "RANLUX", INT2FIX(GSL_RNG_RANLUX));
rb_define_const(cgsl_rng, "RANLUX389", INT2FIX(GSL_RNG_RANLUX389));
rb_define_const(cgsl_rng, "CMRG", INT2FIX(GSL_RNG_CMRG));
rb_define_const(cgsl_rng, "MRG", INT2FIX(GSL_RNG_MRG));
rb_define_const(cgsl_rng, "TAUS", INT2FIX(GSL_RNG_TAUS));
rb_define_const(cgsl_rng, "TAUS2", INT2FIX(GSL_RNG_TAUS2));
rb_define_const(cgsl_rng, "TAUS113", INT2FIX(GSL_RNG_TAUS113));
rb_define_const(cgsl_rng, "GFSR4", INT2FIX(GSL_RNG_GFSR4));
rb_define_const(cgsl_rng, "RAND", INT2FIX(GSL_RNG_RAND));
rb_define_const(cgsl_rng, "RANDOM_LIBC5", INT2FIX(GSL_RNG_RANDOM_LIBC5));
rb_define_const(cgsl_rng, "RANDOM8_LIBC5", INT2FIX(GSL_RNG_RANDOM8_LIBC5));
rb_define_const(cgsl_rng, "RANDOM32_LIBC5", INT2FIX(GSL_RNG_RANDOM32_LIBC5));
rb_define_const(cgsl_rng, "RANDOM64_LIBC5", INT2FIX(GSL_RNG_RANDOM64_LIBC5));
rb_define_const(cgsl_rng, "RANDOM128_LIBC5", INT2FIX(GSL_RNG_RANDOM128_LIBC5));
rb_define_const(cgsl_rng, "RANDOM256_LIBC5", INT2FIX(GSL_RNG_RANDOM256_LIBC5));
rb_define_const(cgsl_rng, "RANDOM_GLIBC2", INT2FIX(GSL_RNG_RANDOM_GLIBC2));
rb_define_const(cgsl_rng, "RANDOM8_GLIBC2", INT2FIX(GSL_RNG_RANDOM8_GLIBC2));
rb_define_const(cgsl_rng, "RANDOM32_GLIBC2", INT2FIX(GSL_RNG_RANDOM32_GLIBC2));
rb_define_const(cgsl_rng, "RANDOM64_GLIBC2", INT2FIX(GSL_RNG_RANDOM64_GLIBC2));
rb_define_const(cgsl_rng, "RANDOM128_GLIBC2", INT2FIX(GSL_RNG_RANDOM128_GLIBC2));
rb_define_const(cgsl_rng, "RANDOM256_GLIBC2", INT2FIX(GSL_RNG_RANDOM256_GLIBC2));
rb_define_const(cgsl_rng, "RANDOM_BSD", INT2FIX(GSL_RNG_RANDOM_BSD));
rb_define_const(cgsl_rng, "RANDOM8_BSD", INT2FIX(GSL_RNG_RANDOM8_BSD));
rb_define_const(cgsl_rng, "RANDOM32_BSD", INT2FIX(GSL_RNG_RANDOM32_BSD));
rb_define_const(cgsl_rng, "RANDOM64_BSD", INT2FIX(GSL_RNG_RANDOM64_BSD));
rb_define_const(cgsl_rng, "RANDOM128_BSD", INT2FIX(GSL_RNG_RANDOM128_BSD));
rb_define_const(cgsl_rng, "RANDOM256_BSD", INT2FIX(GSL_RNG_RANDOM256_BSD));
rb_define_const(cgsl_rng, "RAND48", INT2FIX(GSL_RNG_RAND48));
rb_define_const(cgsl_rng, "RAN0", INT2FIX(GSL_RNG_RAN0));
rb_define_const(cgsl_rng, "RAN1", INT2FIX(GSL_RNG_RAN1));
rb_define_const(cgsl_rng, "RAN2", INT2FIX(GSL_RNG_RAN2));
rb_define_const(cgsl_rng, "RAN3", INT2FIX(GSL_RNG_RAN3));
rb_define_const(cgsl_rng, "RANF", INT2FIX(GSL_RNG_RANF));
rb_define_const(cgsl_rng, "RANMAR", INT2FIX(GSL_RNG_RANMAR));
rb_define_const(cgsl_rng, "R250", INT2FIX(GSL_RNG_R250));
rb_define_const(cgsl_rng, "TT800", INT2FIX(GSL_RNG_TT800));
rb_define_const(cgsl_rng, "VAX", INT2FIX(GSL_RNG_VAX));
rb_define_const(cgsl_rng, "TRANSPUTER", INT2FIX(GSL_RNG_TRANSPUTER));
rb_define_const(cgsl_rng, "RANDU", INT2FIX(GSL_RNG_RANDU));
rb_define_const(cgsl_rng, "MINSTD", INT2FIX(GSL_RNG_MINSTD));
rb_define_const(cgsl_rng, "UNI", INT2FIX(GSL_RNG_UNI));
rb_define_const(cgsl_rng, "UNI32", INT2FIX(GSL_RNG_UNI32));
rb_define_const(cgsl_rng, "SLATEC", INT2FIX(GSL_RNG_SLATEC));
rb_define_const(cgsl_rng, "ZUF", INT2FIX(GSL_RNG_ZUF));
/* from gsl-1.1 */
rb_define_const(cgsl_rng, "BOROSH13", INT2FIX(GSL_RNG_BOROSH13));
rb_define_const(cgsl_rng, "COVEYOU", INT2FIX(GSL_RNG_COVEYOU));
rb_define_const(cgsl_rng, "FISHMAN18", INT2FIX(GSL_RNG_FISHMAN18));
rb_define_const(cgsl_rng, "FISHMAN20", INT2FIX(GSL_RNG_FISHMAN20));
rb_define_const(cgsl_rng, "FISHMAN2X", INT2FIX(GSL_RNG_FISHMAN2X));
rb_define_const(cgsl_rng, "KNUTHRAN", INT2FIX(GSL_RNG_KNUTHRAN));
rb_define_const(cgsl_rng, "KNUTHRAN2", INT2FIX(GSL_RNG_KNUTHRAN2));
rb_define_const(cgsl_rng, "LECUYER21", INT2FIX(GSL_RNG_LECUYER21));
rb_define_const(cgsl_rng, "WATERMAN14", INT2FIX(GSL_RNG_WATERMAN14));
rb_define_const(cgsl_rng, "RNGEXTRA_RNG1", INT2FIX(GSL_RNGEXTRA_RNG1));
rb_define_const(cgsl_rng, "RNGEXTRA_RNG2", INT2FIX(GSL_RNGEXTRA_RNG2));
rb_define_const(module, "RNGEXTRA_RNG1", INT2FIX(GSL_RNGEXTRA_RNG1));
rb_define_const(module, "RNGEXTRA_RNG2", INT2FIX(GSL_RNGEXTRA_RNG2));
}
/* singleton */
static VALUE rb_gsl_rng_default_seed(VALUE obj)
{
return UINT2NUM(gsl_rng_default_seed);
}
/* singleton */
static VALUE rb_gsl_rng_set_default_seed(VALUE obj, VALUE seed)
{
gsl_rng_default_seed = NUM2UINT(seed);
return seed;
}
static VALUE rb_gsl_rng_set(VALUE obj, VALUE s)
{
gsl_rng *r = NULL;
unsigned long seed;
seed = NUM2UINT(s);
Data_Get_Struct(obj, gsl_rng, r);
gsl_rng_set(r, seed);
return obj;
}
/*
Document-method: GSL::Rng#get
Returns a random integer from the generator.
The minimum and maximum values depend on the algorithm used,
but all integers in the range [min,max] are equally likely.
The values of min and max can determined using the auxiliary
methodss GSL::Rng#max and GSL::Rng#min.
*/
static VALUE rb_gsl_rng_get(int argc, VALUE *argv, VALUE obj)
{
gsl_rng *r = NULL;
gsl_vector_int *v;
size_t n, i;
Data_Get_Struct(obj, gsl_rng, r);
switch (argc) {
case 0:
return UINT2NUM(gsl_rng_get(r));
break;
case 1:
n = NUM2INT(argv[0]);
v = gsl_vector_int_alloc(n);
for (i = 0; i < n; i++) gsl_vector_int_set(v, i, (int) gsl_rng_get(r));
return Data_Wrap_Struct(cgsl_vector_int, 0, gsl_vector_int_free, v);
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
break;
}
}
static VALUE rb_gsl_rng_uniform(int argc, VALUE *argv, VALUE obj)
{
gsl_rng *r = NULL;
gsl_vector *v;
size_t n, i;
Data_Get_Struct(obj, gsl_rng, r);
switch (argc) {
case 0:
return rb_float_new(gsl_rng_uniform(r));
break;
case 1:
n = NUM2INT(argv[0]);
v = gsl_vector_alloc(n);
for (i = 0; i < n; i++) gsl_vector_set(v, i, gsl_rng_uniform(r));
return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, v);
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
break;
}
}
static VALUE rb_gsl_rng_uniform_pos(VALUE obj)
{
gsl_rng *r = NULL;
Data_Get_Struct(obj, gsl_rng, r);
return rb_float_new(gsl_rng_uniform_pos(r));
}
static VALUE rb_gsl_rng_uniform_int(VALUE obj, VALUE n)
{
gsl_rng *r = NULL;
unsigned long int nn;
nn = NUM2UINT(n);
Data_Get_Struct(obj, gsl_rng, r);
return UINT2NUM(gsl_rng_uniform_int(r, nn));
}
static VALUE rb_gsl_rng_name(VALUE obj)
{
gsl_rng *r = NULL;
Data_Get_Struct(obj, gsl_rng, r);
return rb_str_new2(gsl_rng_name(r));
}
static VALUE rb_gsl_rng_max(VALUE obj, VALUE s)
{
gsl_rng *r = NULL;
Data_Get_Struct(obj, gsl_rng, r);
return UINT2NUM(gsl_rng_max(r));
}
static VALUE rb_gsl_rng_min(VALUE obj, VALUE s)
{
gsl_rng *r = NULL;
Data_Get_Struct(obj, gsl_rng, r);
return UINT2NUM(gsl_rng_min(r));
}
static VALUE rb_gsl_rng_size(VALUE obj, VALUE s)
{
gsl_rng *r = NULL;
Data_Get_Struct(obj, gsl_rng, r);
return UINT2NUM(gsl_rng_size(r));
}
/* get a list of the available generator types */
/* module function */
static VALUE rb_gsl_rng_types_setup(VALUE obj)
{
const gsl_rng_type **t, **t0;
VALUE ary;
t0 = gsl_rng_types_setup();
ary = rb_ary_new();
for (t = t0; *t != 0; t++) rb_ary_push(ary, rb_str_new2((*t)->name));
return ary;
}
/* module function */
static VALUE rb_gsl_rng_env_setup(VALUE obj)
{
gsl_rng_env_setup();
return obj;
}
static VALUE rb_gsl_rng_clone(VALUE obj)
{
gsl_rng *r = NULL, *rnew = NULL;
Data_Get_Struct(obj, gsl_rng, r);
rnew = gsl_rng_clone(r);
return Data_Wrap_Struct(CLASS_OF(obj), 0, gsl_rng_free, rnew);
}
static VALUE rb_gsl_rng_print_state(VALUE obj)
{
gsl_rng *r = NULL;
Data_Get_Struct(obj, gsl_rng, r);
gsl_rng_print_state(r);
return obj;
}
static VALUE rb_gsl_rng_fwrite(VALUE obj, VALUE io)
{
gsl_rng *h = NULL;
FILE *f = NULL;
int status, flag = 0;
Data_Get_Struct(obj, gsl_rng, h);
f = rb_gsl_open_writefile(io, &flag);
status = gsl_rng_fwrite(f, h);
if (flag == 1) fclose(f);
return INT2FIX(status);
}
static VALUE rb_gsl_rng_fread(VALUE obj, VALUE io)
{
gsl_rng *h = NULL;
FILE *f = NULL;
int status, flag = 0;
Data_Get_Struct(obj, gsl_rng, h);
f = rb_gsl_open_readfile(io, &flag);
status = gsl_rng_fread(f, h);
if (flag == 1) fclose(f);
return INT2FIX(status);
}
static VALUE rb_gsl_rng_memcpy(VALUE obj, VALUE dst, VALUE org)
{
gsl_rng *dest, *src;
CHECK_RNG(dst); CHECK_RNG(org);
Data_Get_Struct(dst, gsl_rng, dest);
Data_Get_Struct(org, gsl_rng, src);
gsl_rng_memcpy(dest, src);
return dst;
}
void Init_gsl_rng(VALUE module)
{
cgsl_rng = rb_define_class_under(module, "Rng", cGSL_Object);
rb_gsl_rng_define_const_type(module);
rb_define_singleton_method(cgsl_rng, "alloc", rb_gsl_rng_alloc, -1);
rb_define_singleton_method(cgsl_rng, "default_seed", rb_gsl_rng_default_seed, 0);
rb_define_singleton_method(cgsl_rng, "set_default_seed", rb_gsl_rng_set_default_seed, 1);
rb_define_singleton_method(cgsl_rng, "default_seed=", rb_gsl_rng_set_default_seed, 1);
rb_define_method(cgsl_rng, "set", rb_gsl_rng_set, 1);
rb_define_alias(cgsl_rng, "set_seed", "set");
rb_define_alias(cgsl_rng, "seed=", "set");
rb_define_method(cgsl_rng, "get", rb_gsl_rng_get, -1);
rb_define_alias(cgsl_rng, "gen", "get");
rb_define_method(cgsl_rng, "uniform", rb_gsl_rng_uniform, -1);
rb_define_method(cgsl_rng, "uniform_pos", rb_gsl_rng_uniform_pos, 0);
rb_define_method(cgsl_rng, "uniform_int", rb_gsl_rng_uniform_int, 1);
rb_define_method(cgsl_rng, "name", rb_gsl_rng_name, 0);
rb_define_method(cgsl_rng, "max", rb_gsl_rng_max, 0);
rb_define_method(cgsl_rng, "min", rb_gsl_rng_min, 0);
rb_define_method(cgsl_rng, "size", rb_gsl_rng_size, 0);
rb_define_singleton_method(cgsl_rng, "types_setup", rb_gsl_rng_types_setup, 0);
rb_define_singleton_method(cgsl_rng, "types", rb_gsl_rng_types_setup, 0);
rb_define_singleton_method(cgsl_rng, "env_setup", rb_gsl_rng_env_setup, 0);
rb_define_method(cgsl_rng, "clone", rb_gsl_rng_clone, 0);
rb_define_alias(cgsl_rng, "duplicate", "clone");
rb_define_method(cgsl_rng, "print_state", rb_gsl_rng_print_state, 0);
rb_define_method(cgsl_rng, "fwrite", rb_gsl_rng_fwrite, 1);
rb_define_method(cgsl_rng, "fread", rb_gsl_rng_fread, 1);
rb_define_singleton_method(cgsl_rng, "memcpy", rb_gsl_rng_memcpy, 2);
}