[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
(fwd) Random Numbers - Results of testing BSD random()
Newsgroups: sci.stat.math,sci.math,sci.math.num-analysis
Path: bga.com!news.sprintlink.net!news.onramp.net!convex!cs.utexas.edu!swrinde!ihnp4.ucsd.edu!library.ucla.edu!csulb.edu!csus.edu!netcom.com!deleyd
From: [email protected]
Subject: Random Numbers - Results of testing BSD random()
Message-ID: <[email protected]>
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
Date: Wed, 6 Jul 1994 06:49:42 GMT
Lines: 119
Xref: bga.com sci.stat.math:1314 sci.math:15352 sci.math.num-analysis:3353
BSD random()
Here are the partial results. Further tests were not performed due to
lack of time. So far the generator appears to be comparable to a
shuffled linear congruential generator.
DEFINITION:
Generating polynomial: x^31 + x^3 + 1 (primitive polynomial)
Initialize circular queue of 31 elements using ANSI C linear
congruential generator.
Recursion formula: a[i] = a[i] + a[i-3]
RATING:
1-D FAILS above 800,000 bpd (bins per dimension)
2-D FAILS above 3000 bpd
3-D FAILS above 210 bpd
4-D PASSES at 50 bpd (highest tested so far)
5-D not tested
6-D not tested
7-D not tested
8-D not tested
This is an additive congruential type random number generator. An array
table[31] is initially filled with random numbers using the ANSI C
linear congruential random number generator. Random numbers are then
generated using the recursion formula:
table[k] = (table[k-31] + table[k-3]) mod 32
(Note that x**31 + x**3 + 1 is a primitive polynomial mod 2, which is
being used here as a generator.) Since we are using the array table[]
as a circular queue with 31 elements then table[k-31] is just table[k]
before it gets replaced with the new value. The recursion formula
becomes:
table[k] = table[k] + table[k-3]
The generator works well in practice. Knuth claims the sequence will
have period 2**31 - 1. Knuth also claims there is very little theory to
prove that this generator does or does not have desirable random
properties. I would be interested if anyone knows of any recent
developments in this area.
-David Deley
[email protected]
(So sorry, I lost the name of the original person who posted this code below
which was used in the tests. -D.D.)
/***
Code to implement random() & srandom() of BSD Unix. It was taken
(though coded somewhat differently) from the Gnu BSD implementation.
***/
#include <stdio.h>
#include <stdlib.h>
#define LONG31
#ifdef LONG31 /* x^31 + x^3 + 1 */
#define SIZE 31
#define SIZE1 30
#define P1 3
#define P2 0
#else /* LONG63: x^63 + x + 1 */
#define SIZE 63
#define SIZE1 62
#define P1 1
#define P2 0
#endif
#define LONG_MAX 0x7fffffff
int p1=P1, p2=P2;
long table[SIZE];
/*** return a "random" number in range [0, LONG_MAX] */
long xrand ()
{
int r;
table[p1] = table[p1] + table[p2]; /* add two table elements */
r = (table[p1] >> 1) & LONG_MAX; /* throw least significant bit away */
if (p1 == SIZE1) { /* increment the table indexes */
p1 = 0;
p2 = p2 + 1;
}
else if (p2 == SIZE1) {
p1 = p1 + 1;
p2 = 0;
}
else {
p1 = p1 + 1;
p2 = p2 + 1;
}
return (r);
}
/*** use a linear congruential type generator to seed the
state table & cycle the entire table 10 times */
void sxrand (seed)
long seed;
{
int i;
table[0] = seed;
for (i=1; i<SIZE; ++i)
table[i] = (table[i-1] * 1103515145) + 12345; /* lousy */
for (i=0; i<10*SIZE; ++i)
(void) xrand();
}