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 == NOT_LONG)
54 if (set_seed == NOT_LONG)
61 rng_seed (rng, &t, sizeof t);
62 rng->next_normal = NOT_DOUBLE;
68 rng_destroy (struct rng *rng)
75 swap_byte (uint8_t *a, uint8_t *b)
82 /* Seeds RNG based on the SIZE bytes in BUF.
83 At most the first 256 bytes of BUF are used. */
85 rng_seed (struct rng *rng, const void *key_, size_t size)
87 const uint8_t *key = key_;
96 for (i = 0; i < 256; i++)
98 for (key_idx = 0, i = j = 0; i < 256; i++)
100 j = (j + s[i] + key[key_idx]) & 255;
101 swap_byte (s + i, s + j);
102 if (++key_idx >= size)
107 /* Reads SIZE random bytes from RNG into BUF. */
109 rng_get_bytes (struct rng *rng, void *buf_, size_t size)
124 swap_byte (s + i, s + j);
125 *buf++ = s[(s[i] + s[j]) & 255];
131 /* Returns a random int in the range [0, INT_MAX]. */
133 rng_get_int (struct rng *rng)
139 rng_get_bytes (rng, &value, sizeof value);
147 /* Returns a random unsigned in the range [0, UINT_MAX]. */
149 rng_get_unsigned (struct rng *rng)
153 rng_get_bytes (rng, &value, sizeof value);
157 /* Returns a random number from the uniform distribution with
160 rng_get_double (struct rng *rng)
167 rng_get_bytes (rng, &ulng, sizeof ulng);
168 dbl = ulng / (ULONG_MAX + 1.0);
169 if (dbl >= 0 && dbl < 1)
174 /* Returns a random number from the distribution with mean 0 and
175 standard deviation 1. (Multiply the result by the desired
176 standard deviation, then add the desired mean.) */
178 rng_get_double_normal (struct rng *rng)
180 /* Knuth, _The Art of Computer Programming_, Vol. 2, 3.4.1C,
184 if (rng->next_normal != NOT_DOUBLE)
186 this_normal = rng->next_normal;
187 rng->next_normal = NOT_DOUBLE;
195 double u1 = rng_get_double (rng);
196 double u2 = rng_get_double (rng);
199 s = v1 * v1 + v2 * v2;
203 this_normal = v1 * sqrt (-2. * log (s) / s);
204 rng->next_normal = v2 * sqrt (-2. * log (s) / s);
210 /* Gets an initialized RNG for use in PSPP transformations and
215 static struct rng *rng;