Permalink
Browse files

integrate Mersenne Twister based random number generator from 1.9 ups…

…tream

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@3519 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
1 parent a6878c4 commit 65814005b81a13732bceab91ec2e971c9398a3f4 @lrz lrz committed Feb 13, 2010
Showing with 1,040 additions and 189 deletions.
  1. +12 −0 bignum.c
  2. +5 −1 include/ruby/intern.h
  3. +2 −0 include/ruby/ruby.h
  4. +178 −0 mt.c
  5. +12 −0 object.c
  6. +779 −149 random.c
  7. +28 −0 range.c
  8. +20 −35 vm.cpp
  9. +4 −4 vm.h
View
@@ -53,6 +53,12 @@ bigzero_p(VALUE x)
}
int
+rb_bigzero_p(VALUE x)
+{
+ return BIGZEROP(x);
+}
+
+int
rb_cmpint(VALUE val, VALUE a, VALUE b)
{
if (NIL_P(val)) {
@@ -696,6 +702,12 @@ rb_bignum_new_retained(const char *str)
return v;
}
+VALUE
+rb_big_new(long len, int sign)
+{
+ return bignew(len, sign != 0);
+}
+
const char ruby_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
static VALUE bigsqr(VALUE x);
View
@@ -95,6 +95,8 @@ VALUE rb_cstr2inum(const char*, int);
VALUE rb_str2inum(VALUE, int);
VALUE rb_big2str(VALUE, int);
VALUE rb_big2str0(VALUE, int, int);
+VALUE rb_big_new(long len, int sign);
+int rb_bigzero_p(VALUE x);
SIGNED_VALUE rb_big2long(VALUE);
#define rb_big2int(x) rb_big2long(x)
VALUE rb_big2ulong(VALUE);
@@ -453,6 +455,7 @@ VALUE rb_String(VALUE);
VALUE rb_Array(VALUE);
double rb_cstr_to_dbl(const char*, int);
double rb_str_to_dbl(VALUE, int);
+VALUE rb_check_to_float(VALUE val);
/* parse.y */
RUBY_EXTERN int ruby_sourceline;
RUBY_EXTERN char *ruby_sourcefile;
@@ -497,8 +500,9 @@ VALUE rb_detach_process(rb_pid_t pid);
void rb_range_extract(VALUE range, VALUE *begp, VALUE *endp, bool *exclude);
VALUE rb_range_new(VALUE, VALUE, int);
VALUE rb_range_beg_len(VALUE, long*, long*, long, int);
+int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp);
/* random.c */
-unsigned long rb_genrand_int32(void);
+unsigned int rb_genrand_int32(void);
double rb_genrand_real(void);
/* re.c */
#define rb_memcmp memcmp
View
@@ -580,6 +580,7 @@ __rb_float_value(VALUE v)
}
#define RFLOAT_VALUE(v) (__rb_float_value((VALUE)v))
#define DOUBLE2NUM(dbl) rb_float_new(dbl)
+#define DBL2NUM DOUBLE2NUM
#if WITH_OBJC
struct RFixnum {
@@ -1130,6 +1131,7 @@ RUBY_EXTERN VALUE rb_cUnboundMethod;
RUBY_EXTERN VALUE rb_cISeq;
RUBY_EXTERN VALUE rb_cVM;
RUBY_EXTERN VALUE rb_cEnv;
+RUBY_EXTERN VALUE rb_cRandom;
#if WITH_OBJC
RUBY_EXTERN VALUE rb_cCFString;
View
178 mt.c
@@ -0,0 +1,178 @@
+/*
+ * This is based on trimmed version of MT19937. To get the original version,
+ * contact <http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html>.
+ *
+ * The original copyright notice follows.
+ *
+ * A C-program for MT19937, with initialization improved 2002/2/10.
+ * Coded by Takuji Nishimura and Makoto Matsumoto.
+ * This is a faster version by taking Shawn Cokus's optimization,
+ * Matthe Bellew's simplification, Isaku Wada's real version.
+ *
+ * Before using, initialize the state by using init_genrand(mt, seed)
+ * or init_by_array(mt, init_key, key_length).
+ *
+ * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. The names of its contributors may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Any feedback is very welcome.
+ * http://www.math.keio.ac.jp/matumoto/emt.html
+ * email: matumoto@math.keio.ac.jp
+ */
+
+#include <limits.h>
+typedef int int_must_be_32bit_at_least[sizeof(int) * CHAR_BIT < 32 ? -1 : 1];
+
+/* Period parameters */
+#define N 624
+#define M 397
+#define MATRIX_A 0x9908b0dfU /* constant vector a */
+#define UMASK 0x80000000U /* most significant w-r bits */
+#define LMASK 0x7fffffffU /* least significant r bits */
+#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
+#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1U ? MATRIX_A : 0U))
+
+enum {MT_MAX_STATE = N};
+
+struct MT {
+ /* assume int is enough to store 32bits */
+ unsigned int state[N]; /* the array for the state vector */
+ unsigned int *next;
+ int left;
+};
+
+#define genrand_initialized(mt) ((mt)->next != 0)
+#define uninit_genrand(mt) ((mt)->next = 0)
+
+/* initializes state[N] with a seed */
+static void
+init_genrand(struct MT *mt, unsigned int s)
+{
+ int j;
+ mt->state[0] = s & 0xffffffffU;
+ for (j=1; j<N; j++) {
+ mt->state[j] = (1812433253U * (mt->state[j-1] ^ (mt->state[j-1] >> 30)) + j);
+ /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
+ /* In the previous versions, MSBs of the seed affect */
+ /* only MSBs of the array state[]. */
+ /* 2002/01/09 modified by Makoto Matsumoto */
+ mt->state[j] &= 0xffffffff; /* for >32 bit machines */
+ }
+ mt->left = 1;
+ mt->next = mt->state + N;
+}
+
+/* initialize by an array with array-length */
+/* init_key is the array for initializing keys */
+/* key_length is its length */
+/* slight change for C++, 2004/2/26 */
+static void
+init_by_array(struct MT *mt, unsigned int init_key[], int key_length)
+{
+ int i, j, k;
+ init_genrand(mt, 19650218U);
+ i=1; j=0;
+ k = (N>key_length ? N : key_length);
+ for (; k; k--) {
+ mt->state[i] = (mt->state[i] ^ ((mt->state[i-1] ^ (mt->state[i-1] >> 30)) * 1664525U))
+ + init_key[j] + j; /* non linear */
+ mt->state[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */
+ i++; j++;
+ if (i>=N) { mt->state[0] = mt->state[N-1]; i=1; }
+ if (j>=key_length) j=0;
+ }
+ for (k=N-1; k; k--) {
+ mt->state[i] = (mt->state[i] ^ ((mt->state[i-1] ^ (mt->state[i-1] >> 30)) * 1566083941U))
+ - i; /* non linear */
+ mt->state[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */
+ i++;
+ if (i>=N) { mt->state[0] = mt->state[N-1]; i=1; }
+ }
+
+ mt->state[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */
+}
+
+static void
+next_state(struct MT *mt)
+{
+ unsigned int *p = mt->state;
+ int j;
+
+ /* if init_genrand() has not been called, */
+ /* a default initial seed is used */
+ if (!genrand_initialized(mt)) init_genrand(mt, 5489U);
+
+ mt->left = N;
+ mt->next = mt->state;
+
+ for (j=N-M+1; --j; p++)
+ *p = p[M] ^ TWIST(p[0], p[1]);
+
+ for (j=M; --j; p++)
+ *p = p[M-N] ^ TWIST(p[0], p[1]);
+
+ *p = p[M-N] ^ TWIST(p[0], mt->state[0]);
+}
+
+/* generates a random number on [0,0xffffffff]-interval */
+static unsigned int
+genrand_int32(struct MT *mt)
+{
+ unsigned int y;
+
+ if (--mt->left <= 0) next_state(mt);
+ y = *mt->next++;
+
+ /* Tempering */
+ y ^= (y >> 11);
+ y ^= (y << 7) & 0x9d2c5680;
+ y ^= (y << 15) & 0xefc60000;
+ y ^= (y >> 18);
+
+ return y;
+}
+
+/* generates a random number on [0,1) with 53-bit resolution*/
+static double
+genrand_real(struct MT *mt)
+{
+ unsigned int a = genrand_int32(mt)>>5, b = genrand_int32(mt)>>6;
+ return(a*67108864.0+b)*(1.0/9007199254740992.0);
+}
+
+/* generates a random number on [0,1] with 53-bit resolution*/
+// TODO
+#define genrand_real2 genrand_real
+
+/* These real versions are due to Isaku Wada, 2002/01/09 added */
+
+#undef N
+#undef M
View
@@ -2778,6 +2778,18 @@ rb_f_float(VALUE obj, SEL sel, VALUE arg)
return rb_Float(arg);
}
+VALUE
+rb_check_to_float(VALUE val)
+{
+ if (TYPE(val) == T_FLOAT) {
+ return val;
+ }
+ if (!rb_obj_is_kind_of(val, rb_cNumeric)) {
+ return Qnil;
+ }
+ return rb_check_convert_type(val, T_FLOAT, "Float", "to_f");
+}
+
double
rb_num2dbl(VALUE val)
{
Oops, something went wrong.

0 comments on commit 6581400

Please sign in to comment.