X-shooter Pipeline Reference Manual 3.8.15
xsh_model_r250.c
Go to the documentation of this file.
1/* $Id: xsh_model_r250.c,v 1.6 2011-12-02 14:15:28 amodigli Exp $
2 *
3 *Not sure about the copyright stuff here!
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 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20/*
21 * $Author: amodigli $
22 * $Date: 2011-12-02 14:15:28 $
23 * $Revision: 1.6 $
24 * $Name: not supported by cvs2svn $
25 */
26/* r250.c the r250 uniform random number algorithm
27
28 Kirkpatrick, S., and E. Stoll, 1981; "A Very Fast
29 Shift-Register Sequence Random Number Generator",
30 Journal of Computational Physics, V.40
31
32 also:
33
34 see W.L. Maier, DDJ May 1991
35
36
37
38*/
39#ifdef HAVE_CONFIG_H
40#include <config.h>
41#endif
42/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
51/*-----------------------------------------------------------------------------
52 Includes
53 -----------------------------------------------------------------------------*/
54
55#include <cpl.h>
56
57#include "xsh_model_kernel.h"
58
59/*----------------------------------------------------------------------------*/
60
61//static char rcsid[] = "@(#)r250.c 1.2 15:50:31 11/21/94 EFC";
62
63
64#include <limits.h>
65
66#include "xsh_model_r250.h"
67
68/* set the following if you trust rand(), otherwise the minimal standard
69 generator is used
70*/
71/* #define TRUST_RAND */
72
73
74#ifndef TRUST_RAND
75#include "xsh_model_randlcg.h"
76#endif
77
78/* defines to allow for 16 or 32 bit integers */
79#define BITS 31
80#define WORD_BIT 32
81
82#if WORD_BIT == 32
83#ifndef BITS
84#define BITS 32
85#endif
86#else
87#ifndef BITS
88#define BITS 16
89#endif
90#endif
91
92#if BITS == 31
93#define MSB 0x40000000L
94#define ALL_BITS 0x7fffffffL
95#define HALF_RANGE 0x20000000L
96#define STEP 7
97#endif
98
99#if BITS == 32
100#define MSB 0x80000000L
101#define ALL_BITS 0xffffffffL
102#define HALF_RANGE 0x40000000L
103#define STEP 7
104#endif
105
106#if BITS == 16
107#define MSB 0x8000
108#define ALL_BITS 0xffff
109#define HALF_RANGE 0x4000
110#define STEP 11
111#endif
112
113static unsigned int r250_buffer[ 250 ];
114static int r250_index;
115
116#ifdef NO_PROTO
117void xsh_r250_init(sd)
118int seed;
119#else
120void xsh_r250_init(int sd)
121#endif
122{
123 int j, k;
124 unsigned int mask, msb;
125
126#ifdef TRUST_RAND
127
128#if BITS == 32 || BITS == 31
129 srand48( sd );
130#else
131 srand( sd );
132#endif
133
134
135#else
136 xsh_set_seed( sd );
137#endif
138
139 r250_index = 0;
140 for (j = 0; j < 250; j++) /* fill r250 buffer with BITS-1 bit values */
141#ifdef TRUST_RAND
142#if BITS == 32 || BITS == 31
143 r250_buffer[j] = (unsigned int)lrand48();
144#else
145 r250_buffer[j] = rand();
146#endif
147#else
149#endif
150
151
152 for (j = 0; j < 250; j++) /* set some MSBs to 1 */
153#ifdef TRUST_RAND
154 if ( rand() > HALF_RANGE )
155 r250_buffer[j] |= MSB;
156#else
157 if ( xsh_randlcg() > HALF_RANGE )
158 r250_buffer[j] |= MSB;
159#endif
160
161
162 msb = MSB; /* turn on diagonal bit */
163 mask = ALL_BITS; /* turn off the leftmost bits */
164
165 for (j = 0; j < BITS; j++)
166 {
167 k = STEP * j + 3; /* select a word to operate on */
168 r250_buffer[k] &= mask; /* turn off bits left of the diagonal */
169 r250_buffer[k] |= msb; /* turn on the diagonal bit */
170 mask >>= 1;
171 msb >>= 1;
172 }
173
174}
175
176unsigned int r250(void) /* returns a random unsigned integer */
177{
178 register int j;
179 register unsigned int new_rand;
180
181 if ( r250_index >= 147 )
182 j = r250_index - 147; /* wrap pointer around */
183 else
184 j = r250_index + 103;
185
186 new_rand = r250_buffer[ r250_index ] ^ r250_buffer[ j ];
187 r250_buffer[ r250_index ] = new_rand;
188
189 if ( r250_index >= 249 ) /* increment pointer for next time */
190 r250_index = 0;
191 else
192 r250_index++;
193
194 return new_rand;
195
196}
197
198
199double xsh_dr250(void) /* returns a random double in range 0..1 */
200{
201 register int j;
202 register unsigned int new_rand;
203
204 if ( r250_index >= 147 )
205 j = r250_index - 147; /* wrap pointer around */
206 else
207 j = r250_index + 103;
208
209 new_rand = r250_buffer[ r250_index ] ^ r250_buffer[ j ];
210 r250_buffer[ r250_index ] = new_rand;
211
212 if ( r250_index >= 249 ) /* increment pointer for next time */
213 r250_index = 0;
214 else
215 r250_index++;
216
217 return (double)new_rand / ALL_BITS;
218
219}
220
221#ifdef MAIN
222
223/* test driver prints out either NMR_RAND values or a histogram */
224
225#include <stdio.h>
226
227#define NMR_RAND 5000
228#define MAX_BINS 500
229
230#ifdef NO_PROTO
231void main(argc, argv)
232int argc;
233char **argv;
234#else
235void main(int argc, char **argv)
236#endif
237{
238 int j,k,nmr_bins,seed;
239 int bins[MAX_BINS];
240 double randm, bin_inc;
241 double bin_limit[MAX_BINS];
242
243 if ( argc != 3 )
244 {
245 printf("Usage -- %s nmr_bins seed\n", argv[0]);
246 abort();
247 }
248
249 nmr_bins = atoi( argv[1] );
250 if ( nmr_bins > MAX_BINS )
251 {
252 printf("ERROR -- maximum number of bins is %d\n", MAX_BINS);
253 abort();
254 }
255
256 seed = atoi( argv[2] );
257
258 xsh_r250_init( seed );
259
260 if ( nmr_bins < 1 ) /* just print out the numbers */
261 {
262 for (j = 0; j < NMR_RAND; j++)
263 printf("%f\n", xsh_dr250() );
264 abort();
265 }
266
267 bin_inc = 1.0 / nmr_bins;
268 for (j = 0; j < nmr_bins; j++) /* initialize bins to zero */
269 {
270 bins[j] = 0;
271 bin_limit[j] = (j + 1) * bin_inc;
272 }
273
274 bin_limit[nmr_bins-1] = 1.0e7; /* make sure all others are in last bin */
275
276 for (j = 0; j < NMR_RAND; j++)
277 {
278 randm = r250() / (double)ALL_BITS;
279 for (k = 0; k < nmr_bins; k++)
280 if ( randm < bin_limit[k] )
281 {
282 bins[k]++;
283 break;
284 }
285 }
286
287
288 for (j = 0; j < nmr_bins; j++)
289 printf("%d\n", bins[j]);
290
291}
292
293#endif
int main()
Unit test of xsh_bspline_interpol.
#define MSB
#define HALF_RANGE
double xsh_dr250(void)
static int r250_index
#define STEP
static unsigned int r250_buffer[250]
void xsh_r250_init(int sd)
#define BITS
long xsh_set_seed(long int sd)
unsigned int r250(void)
unsigned long int xsh_randlcg(void)
#define ALL_BITS