"True Random" C prog Conversion

Blitz3D Forums/Blitz3D Beginners Area/"True Random" C prog Conversion

Mikorians(Posted 2014) [#1]
Interesting, but not very accurate for some reason...

;randomlib.c (global here)
Global u#[97],c#,cd#,cm#
Global i97%,j97%
Global test% = False

;randomtest.c
rmin#=1+e32
rmax#=-1+e32

;gaustest.c
Const N=1000
Const M=100000
Global Bins#[N+1]

   ;Generate 20000 random numbers
   RandomInitialise(1802,9373)
   For i=0 To 19999
      r# = RandomUniform();
      If (r# < rmin#) rmin = r#
      If (r# > rmax#) rmax = r#
   Next
		Print "randomtest.c"
   Print "Numbers range from "+rmin#+" To "+rmax#

				Print "If the random number generator is working properly,"
				Print "the Next six random numbers should be:"
				Print "6533892.0
				Print "14220222.0"
				Print "7275067.0"
				Print "6172232.0"
				Print"8354498.0"
				Print"10633180.0"
				Print
   For i=0 To 5
      Print (4096.0 * 4096.0) * RandomUniform#()
		Next
WaitKey()

r#=0
sum#=0
sum2#=0
Cls:Locate 0,0
Print "gaustest.c"
   RandomInitialise(1802,9373)
   For i=0 To M-1
      r# = RandomGaussian(1.0,0.5)
      sum = sum + r
      sum2 = sum2 + (r*r)
      ;Print r
      If (r < -4) Then r = -4
      If (r > 4) Then r = 4
      bins[Floor(N/2 + r * (N/2) / 4.0)]=bins[Floor(N/2 + r * (N/2) / 4.0)]+1
   Next
   Print "Mean = "+(sum / M)
   Print "Standard deviation = "+Str(Sqr((sum2 - (sum*sum)/M)/M))
WaitKey()
   For i=0 To N-1
      Print i/Float(N)+" "+bins[i]
   Next
WaitKey()
End



;Below are the functions from randomlib.c
;and reckard.c respectively, comprising all necessary
;code to deploy them.

Function RandomInitialise(ij%,kl%)

   ;This is the initialization routine For the random number generator.
   ;NOTE: The seed variables can have values between:    0 <= IJ <= 31328
   ;                                                     0 <= KL <= 30081
   ;The random number sequences created by these two seeds are of sufficient
   ;length To complete an entire calculation with. For example, If sveral
   ;different groups are working on different parts of the same calculation,
   ;Each group could be assigned its own IJ seed. This would leave Each group
   ;with 30000 choices For the second seed. That is To say, this random
   ;number generator can create 900 million different subsequences -- with
   ;Each subsequence having a length of approximately 10^30.

Local s#,t#
Local ii%,i%,j%,k%,l%,jj%,m%

		;Handle the seed range errors
		;First random number seed must be between 0 And 31328
		;Second seed must have a value between 0 And 30081

   If (ij < 0 Or ij > 31328 Or kl < 0 Or kl > 30081) Then
			ij = 1802
			kl = 9373
		End If

   i = ((ij / 177) Mod 177) + 2
   j = (ij Mod 177)         + 2
   k = ((kl / 169) Mod 178) + 1
   l = (kl Mod 169)

   For ii=0 To 96
      s = 0.0
      t = 0.5
      For jj=0 To 23
         m = (((i * j) Mod 179.0) * k) Mod 179.0
         i = j
         j = k
         k = m
         l = (53.0 * l + 1.0) Mod 169.0
         If ((l * m Mod 64.0) >= 32.0) Then s = s + t
         t = t * 0.5
				Next
      u[ii] = s#
   Next

   c    = 362436.0 / 16777216.0
   cd   = 7654321.0 / 16777216.0
   cm   = 16777213.0 / 16777216.0
   i97  = 97
   j97  = 33
   test = True
End Function

Function RandomUniform#()

		;This is the random number generator proposed by George Marsaglia in
		;Florida State University Report: FSU-SCRI-87-50

   Local uni#

   ;Make sure the initialisation routine has been called
   If (Not test) Then RandomInitialise(1802,9373)

   uni = u[i97-1] - u[j97-1]
   If (uni <= 0.0) Then uni=uni+1
   u[i97-1] = uni
   i97=i97-1
   If (i97 = 0) Then i97 = 97
   j97=j97-1
   If (j97 = 0) Then j97 = 97
   c = c - cd
   If (c < 0.0) Then c=c+cm
   uni = uni - c
   If (uni < 0.0) Then uni=uni+1
   Return uni
End Function

Function RandomGaussian#(mean#,stddev#)

		;ALGORITHM 712, COLLECTED ALGORITHMS FROM ACM.
		;THIS WORK PUBLISHED IN TRANSACTIONS ON MATHEMATICAL SOFTWARE,
		;VOL. 18, NO. 4, DECEMBER, 1992, PP. 434-435.
		;The Function returns a normally distributed pseudo-random number
		;with a given mean And standard devaiation.  Calls are made To a
		;Function subprogram which must Return independent random
		;numbers uniform in the interval (0,1).
		;The algorithm uses the ratio of uniforms method of A.J. Kinderman
		;And J.F. Monahan augmented with quadratic bounding curves.

   Local q#,u#,v#,x#,y#

		;Generate P = (u,v) uniform in Rect. enclosing acceptance region 
		;Make sure that any random numbers <= 0 are rejected, since
		;gaussian() requires uniforms > 0, but RandomUniform() delivers >= 0.

   Repeat
    u = RandomUniform()
    v = RandomUniform()
   	If (u <= 0.0 Or v <= 0.0) Then
       	u = 1.0
       	v = 1.0
			End If
    v = 1.7156 * (v - 0.5)

     ;Evaluate the quadratic form
				x = u - 0.449871
				y = Abs(v) + 0.386595
				q = x * x + y * (0.19600 * y - 0.25472 * x)

      ;Accept P If inside inner ellipse
      If (q < 0.27597) Then Exit
      ;Reject P If outside outer ellipse, Or outside acceptance region

    Until Not ((q > 0.27846) Or (v * v > -4.0 * Log(u) * u * u))

    ;Return ratio of P's coordinates as the normal deviate
    Return (mean + (stddev * (v / u)))
End Function

Function RandomInt%(Low%,Up%)
;Return random Integer within a range, Lower -> Upper
Return (Floor(RandomUniform() * (Up% - Low% + 1)) + Low%)
End Function

Function RandomFloat#(Low#,Up#) ;Random "Double"
;Return random Float within a range, Lower -> Upper
Return ((Up - Low) * RandomUniform() + Low)
End Function

Function ForwardRandomUniform(forward#)

   ;Skip ahead in the random sequence.   
   ;by Stan Reckard  

   Local uni#

   ;Make sure the initialisation routine has been called */
   If (Not test) Then RandomInitialise(1802,9373)

   While forward
					forward=forward-1
       uni = u[i97-1] - u[j97-1]
       If (uni <= 0.0) Then uni=uni+1
       u[i97-1] = uni
       i97=i97-1
       If (i97 = 0) Then i97 = 97
       j97=j97-1
       If (j97 = 0) Then j97 = 97
       c = c - cd
       If (c < 0.0) Then c = c + cm
		Wend
End Function

Function BackupRandomUniform(backup#)

   ;Backup in the random sequence 'backup' times.   
   ;by Stan Reckard  

   Local uni#, uniAlt#, prev#
   Local cTmp#

   While backup
      backup=backup-1
      If (c >= cm) Then c = c - cm

      c = c + cd

      If (j97 = 97) Then j97 = 0
      j97=j97+1

      If (i97 = 97) Then i97 = 0
      i97=i97+1

      uni = u[i97-1]
      uniAlt = uni - 1

      prev = uni + u[j97-1]
      If ((prev > 0.0) And (prev < 1.0)) Then
         u[i97-1] = prev
      Else
         u[i97-1] = uniAlt + u[j97-1]
      End If
   Wend
End Function

Function UnRandomUniform() 

   ;Backup in the random sequence.   
   ;by Stan Reckard 

   Local uni#,uniAlt#,prev#
   Local cTmp#

   If (c >= cm) Then c = c - cm

   c = c + cd

   If (j97 = 97) Then j97 = 0
   j97=j97+1

   If (i97 = 97) Then i97 = 0
   i97=i96+1

   uni = u[i97-1]
   uniAlt = uni - 1

   prev = uni + u[j97-1]
   If ((prev > 0.0) And (prev < 1.0)) Then
      u[i97-1] = prev
   Else
      u[i97-1] = uniAlt + u[j97-1]
   End If
      ;RandomUniform() has been completely undone at this point.

      ;Now get the random# that was Last retrieved To
      ;Return without altering the random sequence.
      ;uni holds old value of u[i97-1]

   cTmp = c
   cTmp = cTmp - cd
   If (cTmp < 0.0) Then cTmp = cTmp + cm
   uni = uni - cTmp
   If (uni < 0.0) Then uni=uni+1

   Return uni  ;prev random# returned
End Function

;These functions by Stan Reckard do not convert to Basic

;Function rand24?()
;Above from C: "unsigned Int rand24(void)" ? means no symbol
			;24-bit precision
;Return RandomUniform()? * (4096 * 4096)
;End Function

;Function unRand24?()
;Above from C: "unsigned Int unRand24(void)" ? means no symbol
			;24-bit precision
;Return UnRandomUniform()? * (4096 * 4096);
;End Function



Mikorians(Posted 2014) [#2]
I tried to be accurate, but I am NOT a C programmer.


Guy Fawkes(Posted 2014) [#3]
Are you SURE this is "TRUE" random?

I heard the only code that can do that is called "LavaRnd".


Mikorians(Posted 2014) [#4]
This was made by a university.
I didn't write this code.
It was stated as being "The best code the world has available"
Hm.


Guy Fawkes(Posted 2014) [#5]
My brother is a nuclear physicist, & he told me that lavarnd is the best code in the world for TRUE randomness. It used to take lava lamps to generate random numbers based on the pixels of the lava in the lava lamp, but now it can use stuff like a camera lens cap to generate the true random numbers.


Guy Fawkes(Posted 2014) [#6]
Does this help you?




Mikorians(Posted 2014) [#7]
Did you find a bug in it? Ah, good.
I'll have to examine this in greater detail later.
But anybody who has an improvement for randomness can feel free to post here.
This was just for fun and a public service.
If anyone knows more about the blitz randomization algorithm...
I assume it's the standard for C?
Just curious.


Guy Fawkes(Posted 2014) [#8]
It helps to write your code like this, Mikorians (using tabs instead of spaces):



If you write your code to look like a DNA helix & use returns (enter key), then you're good! :)

You can now read it a whole lot easier now, can't you?

Hope that helps! :)

~GF


Mikorians(Posted 2014) [#9]
Thanks for the reformat of the almost totally ORIGINAL source from the Internet (white space wise)!


Guy Fawkes(Posted 2014) [#10]
No problem buddy! :)


Mikorians(Posted 2014) [#11]
He he!


virtlands(Posted 2014) [#12]
Here's some code from 1 year ago, {created by me}, it generates pseudo-random numbers for Integers,

--> http://www.blitzbasic.com/Community/posts.php?topic=100055

The plus side of this is that it has no repetitive values.
------------------------------------------------------------------

I shall try Mikorians' code too.


Mikorians(Posted 2014) [#13]
'Taint mine, but enjoy!


Guy Fawkes(Posted 2014) [#14]
Guys, any leads on figuring out how to generate TRUE random and not PSUEDO true random? :)


xlsior(Posted 2014) [#15]
TRUE random is only possible by taking an external, random input -- on a home PC, the most 'random' input you'll be able to find will likely be listening for background noise on the microphone, or grabbing a frame from a connected webcam, monitor fluctuations in CPU voltage levels, or something like that.

In lab environments there are 'randomizer' peripherals that will create a signal based on radioactive decay, etc....

The problem with true randomness is that computers themselves are inherently not random -- the entire point is that whatever they do should be 100% reproducable everyt ime you run it. All pseudo-randomness simply uses an ever-changing value (the timer) and uses that as a seed value for a pseudo-random process that typically creates a return value based on some maths based on the seed value, and the randomness of the result is due to rounding errors in inaccurate math operations.
It has the appearance and distribution of 'real' randomness, but theorethically if someone were to execute the program on two identical PC's at the same microsecond, the 'random' results *could* theorethically be identical... But realistically for all but some VERY specialized scenarios, pseudo-randomness is good enough.


Mikorians(Posted 2014) [#16]
I -agree-

I remember hearing about some old 'pop-up-bubble' device for computers.
But most applications today would wear something like that out.
Even concepts like camera frames, audio, and user keypresses can have inherent patterns to them.

True randomness is illusive at best.
Perhaps my topic would have been better titled
'Improved' random number generation.


Matty(Posted 2014) [#17]
For games except maybe gambling ones a simple random number generator is all thats needed. Theres enough randomness thrown into the mix with the human factor that it doesnt matter.


Guy Fawkes(Posted 2014) [#18]
TRUE random is only possible by taking an external, random input -- on a home PC, the most 'random' input you'll be able to find will likely be listening for background noise on the microphone, or grabbing a frame from a connected webcam, monitor fluctuations in CPU voltage levels, or something like that.

In lab environments there are 'randomizer' peripherals that will create a signal based on radioactive decay, etc....

The problem with true randomness is that computers themselves are inherently not random -- the entire point is that whatever they do should be 100% reproducable everyt ime you run it. All pseudo-randomness simply uses an ever-changing value (the timer) and uses that as a seed value for a pseudo-random process that typically creates a return value based on some maths based on the seed value, and the randomness of the result is due to rounding errors in inaccurate math operations.
It has the appearance and distribution of 'real' randomness, but theorethically if someone were to execute the program on two identical PC's at the same microsecond, the 'random' results *could* theorethically be identical... But realistically for all but some VERY specialized scenarios, pseudo-randomness is good enough.


Then what's this?

http://sourceforge.net/projects/lavarnd/


Mikorians(Posted 2014) [#19]
Page describing project in detail didn't load (yet?) 404

Using a natural source of randomness is fine if you have a good one hooked up.
I don't even have a mic. (Lazy me)


Floyd(Posted 2014) [#20]
The README-first file directs you to a page which doesn't seem to exist.
Here's the December 8, 2014 version courtesy of the Wayback Machine:

https://web.archive.org/web/20131208104446/http://www.lavarnd.org/index.html

I occasionally make small donations to worthy sites such as Wikipedia. The most recent was $10 to archive.org, one of the true gems of the web.


Floyd(Posted 2014) [#21]
Before I forget, the original post at the top of this thread mentions results not being very accurate. This is a quirk in the way Blitz3D displays floating point numbers. It actually displays them by rounding to six digits, converting to a string and displaying that. This often results in neater output, but can very misleading. If a float fits exactly into an integer, as with the code here, then you can see exact values by converting to integer:

   For i=0 To 5    ; A better look at the results.
     temp# = (4096.0 * 4096.0) * RandomUniform#()
     Print RSet( temp, 12 ) + RSet( Int( temp ), 12 ) 
   Next



Mikorians(Posted 2014) [#22]
Yeah, I had noticed this numerical quirk.
It seems similar to 3DS Max.
Nothing really wrong with that, maxscript rounds to 3 digits too.
-thought I should say so!


xlsior(Posted 2014) [#23]
Then what's this?


The very first line on that page says it creates random numbers based on a digitized external source, like an image of the lenscap of the camera...

...Which is exactly what I mentioned as a necessity for true randomness: an actual upredictable/random external source.


Who was John Galt?(Posted 2014) [#24]
It's open to argument, but in my mental model the universe is deterministic- i.e. there's no such thing as a random number in reality. There are of course processes with the statistics of a random source.

There are also sites that provide 'true' random numbers.
http://www.random.org/


Mikorians(Posted 2014) [#25]
I would ask again if I am correct in assuming that having been written in C (I also assume), that
Blitz3D uses whatever standard C lib random number function is relevant?
-pardon- half awake here. Ramble ramble... Hem hem.

In other words, nothing unusual random-wise...?
Just curious.
Amusing and relaxing topic!


Mikorians(Posted 2014) [#26]
Incidentally, Guy Faukes---
Your nuclear physicist brother-

Can he offer me any assurances that reality is real, or is it for certain that this is all nothing but probability shells, and force and energy vectors?
I have trouble believing in reality, especially when just by viewing it, we change it.


virtlands(Posted 2014) [#27]
@G.F.
Guys, any leads on figuring out how to generate TRUE random and not PSUEDO true random? :)

LavaRnd is one of the few exceptions that is truly random;

In my opinion, most programmers actually prefer pseudo-random numbers since
these sequences can be duplicated over and over, (they are deterministic).

Uses for Pseudo-randoms include encryption and cryptography.

XorShift Pseudo-Random number generator :: http://en.wikipedia.org/wiki/Xorshift
Best Pseudo-Random number generator? :: http://tinyurl.com/mjpfzj4
SIMD-oriented Fast Mersenne Twister (SFMT):: http://tinyurl.com/ydp2wgj
WELL Random number generator :: http://tinyurl.com/7dpkjam


Mikorians(Posted 2014) [#28]
Thank you for the links!

(To G.F.- I'm not mocking you, trolling, nor joking -
Somebody ELSE might bite at your reply, but I wouldn't)


Pakz(Posted 2014) [#29]
I was watching a episode of a Lets play from a Guy named gix. Hè was a game designer. Hè was talking About a used random method. It was About a random bag.
It worked by adding 1 to max Numbers to a list. You would then take a number from that list as a random number to use. And then delete it.
You would not get random Numbers 4 times in a row becourse you only filed the list for that 3 times with 3.
This method hè Saïd was used in games.

Sorry for the text. Typing it on a different language device and spellcorrect keeps modifying letters.


Mikorians(Posted 2014) [#30]
Random bag is an excellent idea too!


Guy Fawkes(Posted 2014) [#31]
I know YOU wont, @Mikorians! =)

But some people, I am VERY skeptical of. -.- (You know who you are)! :D

@Mikorians, what is "Random bag" ?


Mikorians(Posted 2014) [#32]
Pakz idea just above. Like drawing tiles from a bag, or straws. Fixed non-repeatable set.


Guy Fawkes(Posted 2014) [#33]
Wait... Is that a true-random method, Mikorians? :O


Mikorians(Posted 2014) [#34]
Uh, no. I just thought it was neat. (Actually, I have also used this method)
Unless we're talking about a DEVICE, none of these methods would be...

The PROGRAM would merely exclude duplicates from the random selection array.
It's also nice because you can adjust your set's range on the fly for like conical shrinking stuff.
(?)
Don't ask me what I'm talking about...


Guy Fawkes(Posted 2014) [#35]
Do you think you can show an example to prove this? Because even if it's pseudo-random, it will take millions of years to crack, right?


Mikorians(Posted 2014) [#36]
Well, uh, depending on your set size or if you WANT to flag a COUNTDOWN for each number's destruction, eventually the bag is empty.

It's good fun, but if you're seeking perfection, it'll look dumb to you.
I'll submit a simple sample if you want to get the gist of it, but it really IS simple.
It's just an array.

Creating the array can take a moment. It just means a counter and picking open slots to fill at random with a retry if the slot isn't empty. (I'm sure there's a faster way to make a list of unique random numbers).
Picking from the array, start at 0 slot and work your way to the end of the array.
For non-unique multi pick at random from the array, 2nd array has destruction countdown.
See? Basic and silly.