'randx_randy_mod_congr_4.bas ' johnf 12 Sept 2004 'A demo of the mod-congruent random number generator & its limitations. 'Since this is (presumably) the mechanism Carl uses, it also shows the problems. ' of these pseude-random generators. 'We English, realising this, made our first 'random generating' computer, called 'Ernie' ' with a non algorithmic generator based on thermal noise in gas-filled thermionic tubes. ' (used for what were called Premium Bonds- savings bonds with a chance of a prize) ' ( Electronic Random Number == ERN) 'NB this prog version does not clear the graphic window for a second run.. NOMAINWIN WindowWidth = 530 WindowHeight = 460 UpperLeftX = INT(( DisplayWidth -WindowWidth) /2) UpperLeftY = INT(( DisplayHeight -WindowHeight) /2) graphicbox #main.gb1, 10, 10, 200, 200 graphicbox #main.gb2, 310, 10, 200, 200 textbox #main.t1, 10, 220, 500, 20 texteditor #main.t2, 20, 250, 470, 150 button #main.b0, "Start", [start], UL, 230, 10 button #main.b1, "Faster?", speed, UL, 230, 160 button #main.b2, "Carl's", typec, UL, 230, 60 button #main.b3, "johnf's", typej, UL, 230, 110 global r, c, n, k, d, flag 'flag selects my randoms or Carl's d =1000 'initially slow by calling a 1000ms delay in loop. Later toggle 0 or 1/10s. r =1234 'any seed between 0 and n- it becomes a succession of new 'random values all in range 0 to n k = 106 'these three numbers are carefully chosen 'chain code gives n numbers at random before repeating 'r is replaced by (r * k +c) mod n c =1283 n =6075 'Change these numbers at your peril! Look up in a good comp. math ref'ce! 'eg 'Numerical Recipes' from Cambridge University Press ' Note how since successive values are calculated & therefore related 'the results of successive pairs used as coordinates will be regular patterns. 'It will repeat itself after n calls of the function. 'However the distribution brings up every number equally often. 'Such sequences are mathemagically called 'pseudorandom'. dim bin( 200) Open "rnd(x) v. modcongruent!" for window as #main #main "trapclose [quit]" #main.t2 "!font arial 8" #main.t2 " Left window shows result of throwing two random #s between 0 & 199" #main.t2 " & using them as x,y Cartesian coordinates." #main.t2 " On right an (inverted) histogram shows how many of each # have been thrown." #main.t2 " The histogram should shows that all numbers come up on average equally often." #main.t2 " However the x,y plot shows that since successive values are related" #main.t2 " there is a failure to 'hit' all locations in this 2-D space." #main.t2 " If you choose my simple one, they seem all to come out equally." #main.t2 " but highly correlated in pairs" #main.t2 "Carl's LB function gives less correlation but also less visible equal prob'y" #main.t2, "In a mod-congruent pseudorandom number generator, r is replaced by (r +kc) modulo n" #main.t2, "The choice of k, c and n is very critical- look it up in say p276," #main.t2, "http://www.library.cornell.edu/nr/bookcpdf/c7-1.pdf" #main.t2, "Which is a fantastic resource if you don't own 'Numerical Recipes'!" wait [start] for x = 1 to 10 *n/2 'choose random locations for x and y locations to draw at 'By calling rand() n times we will have seen all values ( n /2 *2) 'so once the initial set have been seen they are re-cycled a = rand( 200) 'find a new random integer a in range 0 to 200 bin( a) =bin( a) +1 'count number of times it has come up by incrementing its bin locx = a 'use as x coordinate #main.gb2, "color "; a; " "; bin( a); " "; 255-a 'colour code dot to be plotted. #main.gb2 "down ; set "; a ; " "; bin( a) ' and increment histogram b = rand( 200) 'find a second random integer b in same range bin( b) =bin( b) +1 locy = b 'use as y coordinate #main.gb2, "color "; b; " "; bin( b); " "; 255-b #main.gb2 "down ; set "; b ; " "; bin( b) #main.gb1 "down ; color black ; set "; locx; " "; locy #main.t1 "Latest values were "; right$( "____" +str$( a), 3); " & "; right$( "____" +str$( b), 3); " after "; x; " throws." 'NB ?Bug? if you use " " rather than "0000" or "____" why does this fail???? if bin( a) >200 or bin( b) >200 then [hold] call Pause d ' NB Without the discard the repeated plot commands cause exhaustion of memory resourses. ' This memory leak is NOT reclaimed when program ends. ' I had hoped that doing discards here would help- it does not. Hence rem'd out. '#main.gb1 "discard" '#main.gb2 "discard" scan next x #main.gb1 "flush" #main.gb2 "flush" [hold] Wait [about] [quit] print #main.gb1, "getbmp drawing 1 1 530 370" bmpsave "drawing", "rndcong.bmp" close #main : END function rand( range) 's is a dummy & not used... r1 =( r *k +c) 'the value here now has to be reduced mod n j =int( r1 /n) 'find r1 div n, the whole number part r =r1 -j *n 'these three lines have simulated r --> (r*k +c) mod n if flag =1 then res =int( 200 *rnd( 1)) 'if you want to use Carl's random numbers. else res =int( range *r /n) 'if you want to use my random generator. end if rand =res end function sub Pause mil t =time$( "milliseconds") while time$( "milliseconds") <( t +mil) wend end sub sub speed h$ if d =0 then d =100 #main.b1 "Slow" else d=0 #main.b1 "Fast" end if end sub sub typec h$ flag =1 end sub sub typej h$ flag =0 end sub