File Coverage

xs/ranlxd.c
Criterion Covered Total %
statement 88 92 95.6
branch 43 44 97.7
condition n/a
subroutine n/a
pod n/a
total 131 136 96.3


line stmt bran cond sub pod time code
1             /* rng/ranlxd.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 <stdlib.h>
21             #include "sandy_rng.h"
22              
23             /* This is an implementation of Martin Luescher's second generation
24             double-precision (48-bit) version of the RANLUX generator.
25              
26             Thanks to Martin Luescher for providing information on this
27             generator.
28              
29             */
30              
31             static inline unsigned long int ranlxd_get (void *vstate);
32             static double ranlxd_get_double (void *vstate);
33             static void ranlxd_set_lux (void *state, unsigned long int s, unsigned int luxury);
34             static void ranlxd1_set (void *state, unsigned long int s);
35             static void ranlxd2_set (void *state, unsigned long int s);
36              
37             static const int next[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0};
38              
39             static const double one_bit = 1.0 / 281474976710656.0; /* 1/2^48 */
40              
41             #define RANLUX_STEP(x1,x2,i1,i2,i3) \
42             x1=xdbl[i1] - xdbl[i2]; \
43             if (x2 < 0) \
44             { \
45             x1-=one_bit; \
46             x2+=1; \
47             } \
48             xdbl[i3]=x2
49              
50             typedef struct
51             {
52             double xdbl[12];
53             double carry;
54             unsigned int ir;
55             unsigned int jr;
56             unsigned int ir_old;
57             unsigned int pr;
58             }
59             ranlxd_state_t;
60              
61             static inline void increment_state (ranlxd_state_t * state);
62              
63             static inline void
64 11050           increment_state (ranlxd_state_t * state)
65             {
66             int k, kmax;
67             double y1, y2, y3;
68              
69 11050           double *xdbl = state->xdbl;
70 11050           double carry = state->carry;
71 11050           unsigned int ir = state->ir;
72 11050           unsigned int jr = state->jr;
73              
74 72021 100         for (k = 0; ir > 0; ++k)
75             {
76 60971           y1 = xdbl[jr] - xdbl[ir];
77 60971           y2 = y1 - carry;
78 60971 100         if (y2 < 0)
79             {
80 30133           carry = one_bit;
81 30133           y2 += 1;
82             }
83             else
84             {
85 30838           carry = 0;
86             }
87 60971           xdbl[ir] = y2;
88 60971           ir = next[ir];
89 60971           jr = next[jr];
90             }
91              
92 11050           kmax = state->pr - 12;
93              
94 366522 100         for (; k <= kmax; k += 12)
95             {
96 355472           y1 = xdbl[7] - xdbl[0];
97 355472           y1 -= carry;
98              
99 355472 100         RANLUX_STEP (y2, y1, 8, 1, 0);
100 355472 100         RANLUX_STEP (y3, y2, 9, 2, 1);
101 355472 100         RANLUX_STEP (y1, y3, 10, 3, 2);
102 355472 100         RANLUX_STEP (y2, y1, 11, 4, 3);
103 355472 100         RANLUX_STEP (y3, y2, 0, 5, 4);
104 355472 100         RANLUX_STEP (y1, y3, 1, 6, 5);
105 355472 100         RANLUX_STEP (y2, y1, 2, 7, 6);
106 355472 100         RANLUX_STEP (y3, y2, 3, 8, 7);
107 355472 100         RANLUX_STEP (y1, y3, 4, 9, 8);
108 355472 100         RANLUX_STEP (y2, y1, 5, 10, 9);
109 355472 100         RANLUX_STEP (y3, y2, 6, 11, 10);
110              
111 355472 100         if (y3 < 0)
112             {
113 177249           carry = one_bit;
114 177249           y3 += 1;
115             }
116             else
117             {
118 178223           carry = 0;
119             }
120 355472           xdbl[11] = y3;
121             }
122              
123 11050           kmax = state->pr;
124              
125 71265 100         for (; k < kmax; ++k)
126             {
127 60215           y1 = xdbl[jr] - xdbl[ir];
128 60215           y2 = y1 - carry;
129 60215 100         if (y2 < 0)
130             {
131 30180           carry = one_bit;
132 30180           y2 += 1;
133             }
134             else
135             {
136 30035           carry = 0;
137             }
138 60215           xdbl[ir] = y2;
139 60215           ir = next[ir];
140 60215           jr = next[jr];
141             }
142 11050           state->ir = ir;
143 11050           state->ir_old = ir;
144 11050           state->jr = jr;
145 11050           state->carry = carry;
146 11050           }
147              
148             static inline unsigned long int
149 123872           ranlxd_get (void *vstate)
150             {
151 123872           return ranlxd_get_double (vstate) * 4294967296.0; /* 2^32 */
152             }
153              
154             static double
155 132240           ranlxd_get_double (void *vstate)
156             {
157 132240           ranlxd_state_t *state = (ranlxd_state_t *) vstate;
158              
159 132240           int ir = state->ir;
160              
161 132240           state->ir = next[ir];
162              
163 132240 100         if (state->ir == state->ir_old)
164 11050           increment_state (state);
165              
166 132240           return state->xdbl[state->ir];
167             }
168              
169             static void
170 236           ranlxd_set_lux (void *vstate, unsigned long int s, unsigned int luxury)
171             {
172 236           ranlxd_state_t *state = (ranlxd_state_t *) vstate;
173              
174             int ibit, jbit, i, k, l, xbit[31];
175             double x, y;
176              
177             long int seed;
178              
179 236 50         if (s == 0)
180 0           s = 1; /* default seed is 1 */
181              
182 236           seed = s;
183              
184 236           i = seed & 0xFFFFFFFFUL;
185              
186 7552 100         for (k = 0; k < 31; ++k)
187             {
188 7316           xbit[k] = i % 2;
189 7316           i /= 2;
190             }
191              
192 236           ibit = 0;
193 236           jbit = 18;
194              
195 3068 100         for (k = 0; k < 12; ++k)
196             {
197 2832           x = 0;
198              
199 138768 100         for (l = 1; l <= 48; ++l)
200             {
201 135936           y = (double) ((xbit[ibit] + 1) % 2);
202 135936           x += x + y;
203 135936           xbit[ibit] = (xbit[ibit] + xbit[jbit]) % 2;
204 135936           ibit = (ibit + 1) % 31;
205 135936           jbit = (jbit + 1) % 31;
206             }
207 2832           state->xdbl[k] = one_bit * x;
208             }
209              
210 236           state->carry = 0;
211 236           state->ir = 11;
212 236           state->jr = 7;
213 236           state->ir_old = 0;
214 236           state->pr = luxury;
215 236           }
216              
217             static void
218 0           ranlxd1_set (void *vstate, unsigned long int s)
219             {
220 0           ranlxd_set_lux (vstate, s, 202);
221 0           }
222              
223             static void
224 236           ranlxd2_set (void *vstate, unsigned long int s)
225             {
226 236           ranlxd_set_lux (vstate, s, 397);
227 236           }
228              
229             static const gsl_rng_type ranlxd1_type =
230             {"ranlxd1", /* name */
231             0xffffffffUL, /* RAND_MAX */
232             0, /* RAND_MIN */
233             sizeof (ranlxd_state_t),
234             &ranlxd1_set,
235             &ranlxd_get,
236             &ranlxd_get_double};
237              
238             static const gsl_rng_type ranlxd2_type =
239             {"ranlxd2", /* name */
240             0xffffffffUL, /* RAND_MAX */
241             0, /* RAND_MIN */
242             sizeof (ranlxd_state_t),
243             &ranlxd2_set,
244             &ranlxd_get,
245             &ranlxd_get_double};
246              
247             const gsl_rng_type *gsl_rng_ranlxd1 = &ranlxd1_type;
248             const gsl_rng_type *gsl_rng_ranlxd2 = &ranlxd2_type;