05-09-2003, 12:11 AM
Quote:Nope, nope.
Your random number generator has a pattern that is created from the code.
The code *is* the pattern.
Agamemnus,
I guess pattern is the wrong word...every sequence of numbers has a pattern...it's own. What I meant was that a pattern would be seen if the "random" numbers were plotted. That is, the output of the random number generator can be somehow represented with less data than the output itself. It's really a philosophical question. If every detail of a system is known...can one predict the outcome of that system? I suspect the answer is yes, even for radioactive decay...however, the amount of computation required should be equivalent to letting the system develop on it's own. As such...it is basically unanswerable without taking a wait and see approach. The same is true for the "rule 30" automata.
I adjusted the code to make it a random number generator with output in the 0 to 1 range, double precision. Of course if you seed it with the same value you will get the same sequence of numbers. However, that doesn't change the fact that the number sequence will stand up to any test for randomness that you can throw at it!!
Change the seed, and the sequence will be just as "random"...but a different sequence. Evaluate the numbers...you will find no local or long-distance coorelation between the numbers.
the other submissions do not pass the test:
SCREEN 11
DO
PSET(RND*640, RND*480)
LOOP
Furthermore, some of them rely on TIMER as input...which is essentially a random input to the system. My method is different. the only input is a single bit, and the output appears to follow no pattern...although it is not "random" in that it is reproducable. I should have used function, but wrote it with calls instead...sorry for the awkwardness...Here's the code...It doesn't need to be this long, but it helps make it easier to understand.
Code:
DECLARE SUB seed (a%(), randomnum#, b%(), maxwidth%)
DECLARE SUB stepautomata (a%(), randomnum#, b%(), maxwidth%)
DECLARE SUB rando (a%(), randomnum#, b%(), maxwidth%)
DEFINT A-Z
SCREEN 0
maxwidth% = 1000 'Set maxwidth% as big as you want, but at least as big
'as the bit-depth of the random number...in this case 32 is absolute minimum.
'if you make it small, the automata will repete and non-random output will
'be observed.
DIM a(0 TO maxwidth%) AS INTEGER 'arrays that hold automata
DIM b(0 TO maxwidth%) AS INTEGER 'a() is last complete line, b() is next line
CALL seed(a%(), randomnum#, b%(), maxwidth%)
'after this line, random numbers are available with CALL rando
'for example, the following loop fills screen with random dots.
SCREEN 11
DO
CALL rando(a%(), randomnum#, b%(), maxwidth%) 'get a random number...
x = 640 * randomnum# 'and scale it for your purposes
CALL rando(a%(), randomnum#, b%(), maxwidth%) 'get another...
y = 480 * randomnum#
PSET (x, y)
LOOP UNTIL INKEY$ <> ""
END
SUB rando (a%(), randomnum#, b%(), maxwidth%) STATIC
IF position + 32 > maxwidth% THEN 'checks to see if a new line is needed
CALL stepautomata(a%(), randomnum#, b%(), maxwidth%) 'update the array a%()
position = 0
END IF
grabaword# = 0 'reset value between calls
FOR x = 0 TO 31 'bit-depth of random number
grabaword# = grabaword# + (a%(position) * (2 ^ x)) 'grab a 32 bit chunk of a%() and convert to a double precision number
position = position + 1 'keep track of where you are on in array
NEXT x
'note...x=32 here
randomnum# = grabaword# / ((2 ^ x) - 1) 'normalize so that randomnum#
'will be in the range 0 to 1
END SUB 'just like the basic function RND
SUB seed (a%(), randomnum#, b%(), maxwidth%) STATIC
PRINT "seeding"
'this is needed to get array filled with indeterminate data.
a%(0) = 1 'starting condition...simplest case...a single "1" in a
'field of zeros. The output is "just as random" as with
'a more complex seed. Try the next line to see this.
'this is the "maximally random" starting condition:
'RANDOMIZE TIMER: FOR t = 0 TO maxsize%: a(t) = RND: NEXT t
FOR t = 0 TO maxwidth% \ 2 '2 is used b/c automata expands in both directions
CALL stepautomata(a%(), randomnum#, b%(), maxwidth%)
NEXT t
CLS
END SUB
SUB stepautomata (a%(), randomnum#, b%(), maxwidth%) STATIC
'this steps the automata forward...and is the source of the randomness
b%(0) = (a%(maxwidth%) XOR (a%(0) OR a%(1))) 'special case wrapping left
FOR x = 1 TO maxwidth% - 1
b%(x) = (a%(x - 1) XOR (a%(x) OR a%(x + 1))) 'normal case
NEXT x
b%(maxwidth%) = (a%(maxwidth% - 1) XOR (a%(maxwidth%) OR a%(0))) 'special case wrapping right
FOR x = 0 TO maxwidth% 'puts new values in a%()
SWAP a%(x), b%(x)
NEXT x
END SUB