1 /* PSPP - computes sample statistics.
2 Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
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.
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
32 /* Random number generator. */
35 /* RC4-based random bytes. */
39 /* Normal distribution. */
43 /* Creates a new random number generator, seeds it based on
44 the current time, and returns it. */
51 rng = xmalloc (sizeof *rng);
52 if (t == 0 || set_seed_used)
54 if (set_seed == NOT_LONG)
62 rng_seed (rng, &t, sizeof t);
63 rng->next_normal = NOT_DOUBLE;
69 rng_destroy (struct rng *rng)
76 swap_byte (uint8_t *a, uint8_t *b)
83 /* Seeds RNG based on the SIZE bytes in BUF.
84 At most the first 256 bytes of BUF are used. */
86 rng_seed (struct rng *rng, const void *key_, size_t size)
88 const uint8_t *key = key_;
97 for (i = 0; i < 256; i++)
99 for (key_idx = 0, i = j = 0; i < 256; i++)
101 j = (j + s[i] + key[key_idx]) & 255;
102 swap_byte (s + i, s + j);
103 if (++key_idx >= size)
108 /* Reads SIZE random bytes from RNG into BUF. */
110 rng_get_bytes (struct rng *rng, void *buf_, size_t size)
125 swap_byte (s + i, s + j);
126 *buf++ = s[(s[i] + s[j]) & 255];
132 /* Returns a random int in the range [0, INT_MAX]. */
134 rng_get_int (struct rng *rng)
140 rng_get_bytes (rng, &value, sizeof value);
148 /* Returns a random unsigned in the range [0, UINT_MAX]. */
150 rng_get_unsigned (struct rng *rng)
154 rng_get_bytes (rng, &value, sizeof value);
158 /* Returns a random number from the uniform distribution with
161 rng_get_double (struct rng *rng)
168 rng_get_bytes (rng, &ulng, sizeof ulng);
169 dbl = ulng / (ULONG_MAX + 1.0);
170 if (dbl >= 0 && dbl < 1)
175 /* Returns a random number from the distribution with mean 0 and
176 standard deviation 1. (Multiply the result by the desired
177 standard deviation, then add the desired mean.) */
179 rng_get_double_normal (struct rng *rng)
181 /* Knuth, _The Art of Computer Programming_, Vol. 2, 3.4.1C,
185 if (rng->next_normal != NOT_DOUBLE)
187 this_normal = rng->next_normal;
188 rng->next_normal = NOT_DOUBLE;
196 double u1 = rng_get_double (rng);
197 double u2 = rng_get_double (rng);
200 s = v1 * v1 + v2 * v2;
204 this_normal = v1 * sqrt (-2. * log (s) / s);
205 rng->next_normal = v2 * sqrt (-2. * log (s) / s);
211 /* Gets an initialized RNG for use in PSPP transformations and
216 static struct rng *rng;