Added script front-end for primer-design code
[htsworkflow.git] / htswanalysis / MACS / lib / gsl / gsl-1.11 / rng / ranmar.c
1 /* rng/ranmar.c
2  * 
3  * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or (at
8  * your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19
20 #include <config.h>
21 #include <stdlib.h>
22 #include <gsl/gsl_rng.h>
23
24 /* This is the RANMAR lagged fibonacci generator of Marsaglia, Zaman
25    and Tsang.  The sequence is a series of 24-bit integers, x_n,
26
27    x_n = (y_n - c_n + 2^24) mod 2^24
28
29    where,
30
31    y_n = (y_{n-97) - y_{n-33} + 2^24) mod 2^24
32    c_n = (c_{n-1} - 7654321 + 2^24 - 3) mod (2^24 - 3)
33
34    The period of this generator is 2^144.
35
36    The generator provides about 900 million different subsequences
37    each of length O(10^30). Thus each seed up to 900,000,000 gives an
38    independent sequence.
39
40    Although it was good in its day this generator now has known
41    statistical defects and has been superseded by RANLUX.
42
43    From: F. James, "A Review of Pseudorandom number generators",
44    Computer Physics Communications 60, 329 (1990).
45
46    G. Marsaglia, A. Zaman and W.W. Tsang, Stat. Prob. Lett. 9, 35 (1990)  */
47
48 static inline unsigned long int ranmar_get (void *vstate);
49 static double ranmar_get_double (void *vstate);
50 static void ranmar_set (void *state, unsigned long int s);
51
52 static const unsigned long int two24 = 16777216;        /* 2^24 */
53
54 typedef struct
55   {
56     unsigned int i;
57     unsigned int j;
58     long int carry;
59     unsigned long int u[97];
60   }
61 ranmar_state_t;
62
63 static inline unsigned long int
64 ranmar_get (void *vstate)
65 {
66   ranmar_state_t *state = (ranmar_state_t *) vstate;
67
68   unsigned int i = state->i;
69   unsigned int j = state->j;
70   long int carry = state->carry;
71
72   long int delta = state->u[i] - state->u[j];
73
74   if (delta < 0)
75     delta += two24 ;
76   
77   state->u[i] = delta;
78
79   if (i == 0)
80     {
81       i = 96;
82     }
83   else
84     {
85       i--;
86     }
87
88   state->i = i;
89
90   if (j == 0)
91     {
92       j = 96;
93     }
94   else
95     {
96       j--;
97     }
98
99   state->j = j;
100
101   carry += - 7654321 ;
102   
103   if (carry < 0)
104     carry += two24 - 3;
105   
106   state->carry = carry ;
107
108   delta += - carry ;
109   
110   if (delta < 0)
111     delta += two24 ;
112
113   return delta;
114 }
115
116 static double
117 ranmar_get_double (void *vstate)
118 {
119   return ranmar_get (vstate) / 16777216.0 ;
120 }
121
122 static void
123 ranmar_set (void *vstate, unsigned long int s)
124 {
125   ranmar_state_t *state = (ranmar_state_t *) vstate;
126   
127   unsigned long int ij = s / 30082 ;
128   unsigned long int kl = s % 30082 ;
129   
130   int i = (ij / 177) % 177 + 2 ;
131   int j = (ij % 177) + 2 ;
132   int k = (kl / 169) % 178 + 1 ;
133   int l = (kl % 169) ;
134
135   int a, b;
136   
137   for (a = 0; a < 97; a++)
138     {
139       unsigned long int sum = 0 ;
140       unsigned long int t = two24 ;
141
142       for (b = 0; b < 24; b++)
143         {
144           unsigned long int m = (((i * j) % 179) * k) % 179 ;
145           i = j ;
146           j = k ;
147           k = m ;
148           l = (53 * l + 1) % 169 ;
149           t >>= 1 ;
150           
151           if ((l * m) % 64 >= 32)
152             sum += t ;
153         }
154
155       state->u[a] = sum ;
156     }
157
158   state->i = 96;
159   state->j = 32;
160   state->carry = 362436 ;
161
162 }
163
164 static const gsl_rng_type ranmar_type =
165 {"ranmar",                      /* name */
166  0x00ffffffUL,                  /* RAND_MAX */
167  0,                             /* RAND_MIN */
168  sizeof (ranmar_state_t),
169  &ranmar_set,
170  &ranmar_get,
171  &ranmar_get_double};
172
173 const gsl_rng_type *gsl_rng_ranmar = &ranmar_type;