source: sasview/src/sans/models/c_extension/cephes/drand.c @ 79d5b6c

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 79d5b6c was 230f479, checked in by Mathieu Doucet <doucetm@…>, 11 years ago

Rename C source dir for models (minor updates)

  • Property mode set to 100644
File size: 3.1 KB
Line 
1/*                                                      drand.c
2 *
3 *      Pseudorandom number generator
4 *
5 *
6 *
7 * SYNOPSIS:
8 *
9 * double y, drand();
10 *
11 * drand( &y );
12 *
13 *
14 *
15 * DESCRIPTION:
16 *
17 * Yields a random number 1.0 <= y < 2.0.
18 *
19 * The three-generator congruential algorithm by Brian
20 * Wichmann and David Hill (BYTE magazine, March, 1987,
21 * pp 127-8) is used. The period, given by them, is
22 * 6953607871644.
23 *
24 * Versions invoked by the different arithmetic compile
25 * time options DEC, IBMPC, and MIEEE, produce
26 * approximately the same sequences, differing only in the
27 * least significant bits of the numbers. The UNK option
28 * implements the algorithm as recommended in the BYTE
29 * article.  It may be used on all computers. However,
30 * the low order bits of a double precision number may
31 * not be adequately random, and may vary due to arithmetic
32 * implementation details on different computers.
33 *
34 * The other compile options generate an additional random
35 * integer that overwrites the low order bits of the double
36 * precision number.  This reduces the period by a factor of
37 * two but tends to overcome the problems mentioned.
38 *
39 */
40
41
42/*  Three-generator random number algorithm
43 * of Brian Wichmann and David Hill
44 * BYTE magazine, March, 1987 pp 127-8
45 *
46 * The period, given by them, is (p-1)(q-1)(r-1)/4 = 6.95e12.
47 */
48
49#include "mconf.h"
50#ifdef ANSIPROT
51static int ranwh ( void );
52#else
53static int ranwh();
54#endif
55
56static int sx = 1;
57static int sy = 10000;
58static int sz = 3000;
59
60static union {
61 double d;
62 unsigned short s[4];
63} unkans;
64
65/* This function implements the three
66 * congruential generators.
67 */
68 
69static int ranwh()
70{
71int r, s;
72
73/*  sx = sx * 171 mod 30269 */
74r = sx/177;
75s = sx - 177 * r;
76sx = 171 * s - 2 * r;
77if( sx < 0 )
78        sx += 30269;
79
80
81/* sy = sy * 172 mod 30307 */
82r = sy/176;
83s = sy - 176 * r;
84sy = 172 * s - 35 * r;
85if( sy < 0 )
86        sy += 30307;
87
88/* sz = 170 * sz mod 30323 */
89r = sz/178;
90s = sz - 178 * r;
91sz = 170 * s - 63 * r;
92if( sz < 0 )
93        sz += 30323;
94/* The results are in static sx, sy, sz. */
95return 0;
96}
97
98/*      drand.c
99 *
100 * Random double precision floating point number between 1 and 2.
101 *
102 * C callable:
103 *      drand( &x );
104 */
105
106int drand( a )
107double *a;
108{
109unsigned short r;
110#ifdef DEC
111unsigned short s, t;
112#endif
113
114/* This algorithm of Wichmann and Hill computes a floating point
115 * result:
116 */
117ranwh();
118unkans.d = sx/30269.0  +  sy/30307.0  +  sz/30323.0;
119r = unkans.d;
120unkans.d -= r;
121unkans.d += 1.0;
122
123/* if UNK option, do nothing further.
124 * Otherwise, make a random 16 bit integer
125 * to overwrite the least significant word
126 * of unkans.
127 */
128#ifdef UNK
129/* do nothing */
130#else
131ranwh();
132r = sx * sy + sz;
133#endif
134
135#ifdef DEC
136/* To make the numbers as similar as possible
137 * in all arithmetics, the random integer has
138 * to be inserted 3 bits higher up in a DEC number.
139 * An alternative would be put it 3 bits lower down
140 * in all the other number types.
141 */
142s = unkans.s[2];
143t = s & 07;     /* save these bits to put in at the bottom */
144s &= 0177770;
145s |= (r >> 13) & 07;
146unkans.s[2] = s;
147t |= r << 3;
148unkans.s[3] = t;
149#endif
150
151#ifdef IBMPC
152unkans.s[0] = r;
153#endif
154
155#ifdef MIEEE
156unkans.s[3] = r;
157#endif
158
159*a = unkans.d;
160return 0;
161}
Note: See TracBrowser for help on using the repository browser.