Random-number generation
Re: Random-number generation
Arlet wrote:
Quote:
so I could easily see how the state vector evolves (especially with numbers other than 0x45)
Re: Random-number generation
Quote:
How did you come up with this idea?
With PractRand, it's easy to test a few ideas. If they suck, then it only takes 5 seconds before it tells you. I started with the basic ADC chain, and then inserted a few EORs here and there.
Re: Random-number generation
Arlet, what command line do you use with PractRand to test your PRNG ?
Re: Random-number generation
my_test | RNG_test stdin
Re: Random-number generation
Arlet wrote:
my_test | RNG_test stdin
Re: Random-number generation
I think stdin8 is more optimized for finding faults in 8 bit wide inputs, so that's probably better.
Re: Random-number generation
Arlet wrote:
Quote:
How did you come up with this idea?
With PractRand, it's easy to test a few ideas. If they suck, then it only takes 5 seconds before it tells you. I started with the basic ADC chain, and then inserted a few EORs here and there.
Re: Random-number generation
Alex1 wrote:
The problem is that since it is not based on sound mathematics, we do not know if there are loops for some seeds or not. It would be necessary to test all the seeds of 1 to $FFFFFF and check if for each seed we obtain 2^32 bytes without loop. So you should run rng_test for each 2^32 seed.
Code: Select all
ADD( s0, 0x45 );
ADC( s1, s0 );
ADC( s2, s1 );
ADC( s3, s2 );
Code: Select all
ADC( s4, s3 ^ s6 );
The same argument goes for s1->s2 and s2->s3.
Last edited by Arlet on Wed Mar 22, 2023 9:25 am, edited 1 time in total.
Re: Random-number generation
That's neat - you're proving first that the cycle length must be a multiple of 256 (so that s0 returns to zero), then that it must be a further multiple of 256 more (so that s1 returns to zero at the same time as s0), then x256 more so that s2 returns to zero at the same time, and finally another x256 so that s3 also returns to zero at this time. So the period is maximised and hence there are no short loops for these four bytes, every state is part of the same cycle, and the only thing you relied on was that the amount added to s0 each time was odd.
It's still not clear to me that we can guarantee that the rest of the longer chain of adds with feedback doesn't ever reduce this period at the output end, but I'm no expert on this!
It's still not clear to me that we can guarantee that the rest of the longer chain of adds with feedback doesn't ever reduce this period at the output end, but I'm no expert on this!
Re: Random-number generation
Quote:
It's still not clear to me that we can guarantee that the rest of the longer chain of adds with feedback doesn't ever reduce this period
Worst case is when you stop after 2^32 rounds, and then s4-s6 happen to have the same values as in the beginning, which makes 4GB the shortest possible period.
Re: Random-number generation
Here's a version that only requires 6 bytes of RAM, and 1 less instruction. Also, just for fun, only uses ADC. Passes PractRand <= 4GB then fails hard.
Working Owlet BBC code
Code: Select all
CLC
LDA #&45
ADC seed+0
STA seed+0
ADC seed+1
STA seed+1
ADC seed+2
STA seed+2
ADC seed+3
STA seed+3
ADC seed+4
ADC seed+5
STA seed+4
ADC seed+5
STA seed+5
ADC seed+4
ADC seed+2
RTS
Re: Random-number generation
Quick thought: if you take only the MSBits, or conversely only the LSBits, are they also adequately random as a bitstream?
Re: Random-number generation
PractRand does extensive testing for isolated lower bits, so I would think so. It doesn't test the MSBits separately, I think, but I would expect those to be better quality.
For instance, this is a typical failure output message:
The "Low1/8" part means that for each byte, the least significant bit was isolated, and all those single bits were then fed into the "BCFN" test.
For instance, this is a typical failure output message:
Code: Select all
[Low1/8]BCFN(2+6,13-0,T) R= +30.4 p = 9.1e-16 FAIL
Re: Random-number generation
Got rid of one more instruction. First couple of output bytes don't look so good with all-zero seed value, but it still (barely) passes PractRand to 4GB. I don't think any more cycles can be removed unless you don't mind a somewhat lower quality (which could be fine for a lot of purposes).
BBC code
Code: Select all
CLC
LDA #&45
ADC seed+0
STA seed+0
ADC seed+1
STA seed+1
ADC seed+2
STA seed+2
ADC seed+3
STA seed+3
EOR seed+4
ADC seed+5
STA seed+4
ADC seed+5
EOR seed+2
STA seed+5
RTS
Re: Random-number generation
I feel like there's a bug somewhere. I used my code in C (which is a literal translation of your 6502 code to C) and your code in C. I have the same output on both sides up to byte 326 and then it's different. My byte 326 is at $46 and yours is at $45. Do you know what could be the problem?
My C code :
Your C code:
And with your C code i've loops :
But not with my C code.
My C code :
Your C code:
And with your C code i've loops :
Quote:
Found '008AA873' at index 0 !
Found '008AA873' at index 11EC9D07 !
Found '008AA873' at index 36982356 !
Found '008AA873' at index B20751BF !
Found '008AA873' at index 11EC9D07 !
Found '008AA873' at index 36982356 !
Found '008AA873' at index B20751BF !