summaryrefslogtreecommitdiff
path: root/gsl-1.9/rng/ranmar.c
diff options
context:
space:
mode:
Diffstat (limited to 'gsl-1.9/rng/ranmar.c')
-rw-r--r--gsl-1.9/rng/ranmar.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/gsl-1.9/rng/ranmar.c b/gsl-1.9/rng/ranmar.c
new file mode 100644
index 0000000..fd53cb5
--- /dev/null
+++ b/gsl-1.9/rng/ranmar.c
@@ -0,0 +1,173 @@
+/* rng/ranmar.c
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <gsl/gsl_rng.h>
+
+/* This is the RANMAR lagged fibonacci generator of Marsaglia, Zaman
+ and Tsang. The sequence is a series of 24-bit integers, x_n,
+
+ x_n = (y_n - c_n + 2^24) mod 2^24
+
+ where,
+
+ y_n = (y_{n-97) - y_{n-33} + 2^24) mod 2^24
+ c_n = (c_{n-1} - 7654321 + 2^24 - 3) mod (2^24 - 3)
+
+ The period of this generator is 2^144.
+
+ The generator provides about 900 million different subsequences
+ each of length O(10^30). Thus each seed up to 900,000,000 gives an
+ independent sequence.
+
+ Although it was good in its day this generator now has known
+ statistical defects and has been superseded by RANLUX.
+
+ From: F. James, "A Review of Pseudorandom number generators",
+ Computer Physics Communications 60, 329 (1990).
+
+ G. Marsaglia, A. Zaman and W.W. Tsang, Stat. Prob. Lett. 9, 35 (1990) */
+
+static inline unsigned long int ranmar_get (void *vstate);
+static double ranmar_get_double (void *vstate);
+static void ranmar_set (void *state, unsigned long int s);
+
+static const unsigned long int two24 = 16777216; /* 2^24 */
+
+typedef struct
+ {
+ unsigned int i;
+ unsigned int j;
+ long int carry;
+ unsigned long int u[97];
+ }
+ranmar_state_t;
+
+static inline unsigned long int
+ranmar_get (void *vstate)
+{
+ ranmar_state_t *state = (ranmar_state_t *) vstate;
+
+ unsigned int i = state->i;
+ unsigned int j = state->j;
+ long int carry = state->carry;
+
+ long int delta = state->u[i] - state->u[j];
+
+ if (delta < 0)
+ delta += two24 ;
+
+ state->u[i] = delta;
+
+ if (i == 0)
+ {
+ i = 96;
+ }
+ else
+ {
+ i--;
+ }
+
+ state->i = i;
+
+ if (j == 0)
+ {
+ j = 96;
+ }
+ else
+ {
+ j--;
+ }
+
+ state->j = j;
+
+ carry += - 7654321 ;
+
+ if (carry < 0)
+ carry += two24 - 3;
+
+ state->carry = carry ;
+
+ delta += - carry ;
+
+ if (delta < 0)
+ delta += two24 ;
+
+ return delta;
+}
+
+static double
+ranmar_get_double (void *vstate)
+{
+ return ranmar_get (vstate) / 16777216.0 ;
+}
+
+static void
+ranmar_set (void *vstate, unsigned long int s)
+{
+ ranmar_state_t *state = (ranmar_state_t *) vstate;
+
+ unsigned long int ij = s / 30082 ;
+ unsigned long int kl = s % 30082 ;
+
+ int i = (ij / 177) % 177 + 2 ;
+ int j = (ij % 177) + 2 ;
+ int k = (kl / 169) % 178 + 1 ;
+ int l = (kl % 169) ;
+
+ int a, b;
+
+ for (a = 0; a < 97; a++)
+ {
+ unsigned long int sum = 0 ;
+ unsigned long int t = two24 ;
+
+ for (b = 0; b < 24; b++)
+ {
+ unsigned long int m = (((i * j) % 179) * k) % 179 ;
+ i = j ;
+ j = k ;
+ k = m ;
+ l = (53 * l + 1) % 169 ;
+ t >>= 1 ;
+
+ if ((l * m) % 64 >= 32)
+ sum += t ;
+ }
+
+ state->u[a] = sum ;
+ }
+
+ state->i = 96;
+ state->j = 32;
+ state->carry = 362436 ;
+
+}
+
+static const gsl_rng_type ranmar_type =
+{"ranmar", /* name */
+ 0x00ffffffUL, /* RAND_MAX */
+ 0, /* RAND_MIN */
+ sizeof (ranmar_state_t),
+ &ranmar_set,
+ &ranmar_get,
+ &ranmar_get_double};
+
+const gsl_rng_type *gsl_rng_ranmar = &ranmar_type;