random numbers, dices and statistics

hippy

Ex-Staff (retired)
Looks very interesting and good information for anyone wanting to produce better random numbers. I'll be the first to admit that my math is weak and especially so when it comes to statistics so I cannot say I understand all of what's presented.

One thing where I think there's always going to be some skewing is in "b13=w0//6+1" as for all 65536 possible w0's that is going to give 10923 of 1, 2, 3 and 4, 10922 of 4 and 5.

That said, your results seem to show good distribution and the imbalance is minimal and and skew probably only starts to show after a huge number of rolls.

There's also some scope for improving the speed and performance of the LFSR, for example -

b3 = w0 & $0004
b3 = b3 / 4

By utilising bit variables, what you have in 'b3' is automatically set in 'bit2' when 'w0' is assigned. You can also combine multiple consecutive operations onto one line for increased speed such as -

b2 = b2 ^ b3 ^ b4 ^ b5

I appreciate though that this wasn't an exercise in optimisation.

What is intriguing is that RANDOM does implement its own LFSR ( on the variable specified, not a separate internal number ) so I'm surprised there's a considerable difference. Does it come down to simply initialising the five dice differently ? Does RANDOM on five separate variables all initialised as for your own LFSR and run for at least 65536 iterations perform equally well ?

That is, replace your 'fibonacci:' with -

fibonacci:
Random w0
Return
 
Last edited:

westaust55

Moderator
random numbers

The code you have using the straight PICAXE "RANDOM" command will always (by my understand) start with the same number, so you always have a same series of numbers. This is an age old problem with computer generated "random" numbers.

For the X1 and X2 parts, a initial seed value can be changed easily as described in manual 2 (rev 6.6) on page 130 using:
let w0 = timer ‘ seed w0 with timer value

For other PICAXE, you will need to use other methods to vary the seed.

For example, use in push button switch on an input and measure the duration of the contact closure with the PULSIN command. Even a momentary press will give different durations.
 

hesinije

Member
What is intriguing is that RANDOM does implement its own LFSR ( on the variable specified, not a separate internal number ) so I'm surprised there's a considerable difference. Does it come down to simply initialising the five dice differently ? Does RANDOM on five separate variables all initialised as for your own LFSR and run for at least 65536 iterations perform equally well ?

That is, replace your 'fibonacci:' with -

fibonacci:
Random w0
Return
like this?


setfreq m8

w0 = $ACE1 'prime number 44257
poke 80, word w0
w0 = $6A8D 'prime number 27277
poke 82, word w0
w0 = $EA35 'prime number 59957
poke 84, word w0
w0 = $8621 'prime number 34337
poke 86, word w0
w0 = $2FF5 'prime number 12277
poke 88, word w0

main:
peek 80, word w0
gosub fibonacci
poke 80, word w0
b10=w0//6+1

peek 82, word w0
gosub fibonacci
poke 82, word w0
b11=w0//6+1

peek 84, word w0
gosub fibonacci
poke 84, word w0
b12=w0//6+1

peek 86, word w0
gosub fibonacci
poke 86, word w0
b13=w0//6+1

peek 88, word w0
gosub fibonacci
poke 88, word w0
b9=w0//6+1

sertxd (#b10,9,#b11,9,#b12,9,#b13,9,#b9,13,10)
goto main

fibonacci:
random w0
return

end


After 65.000 rolls the statistical distributions indeed look gaussian. But when I reduce the code to:


setfreq m8

main:
gosub fibonacci
b10=w0//6+1

gosub fibonacci
b11=w0//6+1

gosub fibonacci
b12=w0//6+1

gosub fibonacci
b13=w0//6+1

gosub fibonacci
b9=w0//6+1

sertxd (#b10,9,#b11,9,#b12,9,#b13,9,#b9,13,10)
goto main

fibonacci:
random w0
return

end

then the statistical distributions are not gaussian. The first code looks to have excess code: the PEEK and POKE and the initialization of W0 as RANDOM overwrites the value of W0.
I don't think that RANDOM can be affected by initializing W0. Or is RANDOM a free running LFSR which generates better statistical numbers as the interval between two calls increases? Then the PEEK and POKE could be replaced by a FOR NEXT loop to make some delay. Interesting :)

Herman
NL
 

hippy

Ex-Staff (retired)
I think it is the initialisation and separation of variables which affects the outcome. In your code -

dice1 = random(dice1)
dice2 = random(dice2)
dice3 = random(dice3) etc

whereas for the other -

dice1 = random(dice1)
dice2 = random(dice1)
dice3 = random(dice2) etc
 
Top