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 11052           increment_state (ranlxd_state_t * state)
65             {
66             int k, kmax;
67             double y1, y2, y3;
68              
69 11052           double *xdbl = state->xdbl;
70 11052           double carry = state->carry;
71 11052           unsigned int ir = state->ir;
72 11052           unsigned int jr = state->jr;
73              
74 71992 100         for (k = 0; ir > 0; ++k)
75             {
76 60940           y1 = xdbl[jr] - xdbl[ir];
77 60940           y2 = y1 - carry;
78 60940 100         if (y2 < 0)
79             {
80 30307           carry = one_bit;
81 30307           y2 += 1;
82             }
83             else
84             {
85 30633           carry = 0;
86             }
87 60940           xdbl[ir] = y2;
88 60940           ir = next[ir];
89 60940           jr = next[jr];
90             }
91              
92 11052           kmax = state->pr - 12;
93              
94 366594 100         for (; k <= kmax; k += 12)
95             {
96 355542           y1 = xdbl[7] - xdbl[0];
97 355542           y1 -= carry;
98              
99 355542 100         RANLUX_STEP (y2, y1, 8, 1, 0);
100 355542 100         RANLUX_STEP (y3, y2, 9, 2, 1);
101 355542 100         RANLUX_STEP (y1, y3, 10, 3, 2);
102 355542 100         RANLUX_STEP (y2, y1, 11, 4, 3);
103 355542 100         RANLUX_STEP (y3, y2, 0, 5, 4);
104 355542 100         RANLUX_STEP (y1, y3, 1, 6, 5);
105 355542 100         RANLUX_STEP (y2, y1, 2, 7, 6);
106 355542 100         RANLUX_STEP (y3, y2, 3, 8, 7);
107 355542 100         RANLUX_STEP (y1, y3, 4, 9, 8);
108 355542 100         RANLUX_STEP (y2, y1, 5, 10, 9);
109 355542 100         RANLUX_STEP (y3, y2, 6, 11, 10);
110              
111 355542 100         if (y3 < 0)
112             {
113 177703           carry = one_bit;
114 177703           y3 += 1;
115             }
116             else
117             {
118 177839           carry = 0;
119             }
120 355542           xdbl[11] = y3;
121             }
122              
123 11052           kmax = state->pr;
124              
125 71252 100         for (; k < kmax; ++k)
126             {
127 60200           y1 = xdbl[jr] - xdbl[ir];
128 60200           y2 = y1 - carry;
129 60200 100         if (y2 < 0)
130             {
131 30308           carry = one_bit;
132 30308           y2 += 1;
133             }
134             else
135             {
136 29892           carry = 0;
137             }
138 60200           xdbl[ir] = y2;
139 60200           ir = next[ir];
140 60200           jr = next[jr];
141             }
142 11052           state->ir = ir;
143 11052           state->ir_old = ir;
144 11052           state->jr = jr;
145 11052           state->carry = carry;
146 11052           }
147              
148             static inline unsigned long int
149 123840           ranlxd_get (void *vstate)
150             {
151 123840           return ranlxd_get_double (vstate) * 4294967296.0; /* 2^32 */
152             }
153              
154             static double
155 132198           ranlxd_get_double (void *vstate)
156             {
157 132198           ranlxd_state_t *state = (ranlxd_state_t *) vstate;
158              
159 132198           int ir = state->ir;
160              
161 132198           state->ir = next[ir];
162              
163 132198 100         if (state->ir == state->ir_old)
164 11052           increment_state (state);
165              
166 132198           return state->xdbl[state->ir];
167             }
168              
169             static void
170 228           ranlxd_set_lux (void *vstate, unsigned long int s, unsigned int luxury)
171             {
172 228           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 228 50         if (s == 0)
180 0           s = 1; /* default seed is 1 */
181              
182 228           seed = s;
183              
184 228           i = seed & 0xFFFFFFFFUL;
185              
186 7296 100         for (k = 0; k < 31; ++k)
187             {
188 7068           xbit[k] = i % 2;
189 7068           i /= 2;
190             }
191              
192 228           ibit = 0;
193 228           jbit = 18;
194              
195 2964 100         for (k = 0; k < 12; ++k)
196             {
197 2736           x = 0;
198              
199 134064 100         for (l = 1; l <= 48; ++l)
200             {
201 131328           y = (double) ((xbit[ibit] + 1) % 2);
202 131328           x += x + y;
203 131328           xbit[ibit] = (xbit[ibit] + xbit[jbit]) % 2;
204 131328           ibit = (ibit + 1) % 31;
205 131328           jbit = (jbit + 1) % 31;
206             }
207 2736           state->xdbl[k] = one_bit * x;
208             }
209              
210 228           state->carry = 0;
211 228           state->ir = 11;
212 228           state->jr = 7;
213 228           state->ir_old = 0;
214 228           state->pr = luxury;
215 228           }
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 228           ranlxd2_set (void *vstate, unsigned long int s)
225             {
226 228           ranlxd_set_lux (vstate, s, 397);
227 228           }
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;