First, the smiley in my post was intended to indicate a non-serious post.
- The OPs request makes no sense at all -- other than an interesting academic diversion; or a way to explore Perl -- when there are modules like Math::Random::MT available.
Using the non-determinacy of threading as a source of entropy is an interesting academic exercise.
- Running 4 threads flat out to generate random numbers is ... shall we say 'overkill' :)
When I run it with threaded Perl 5.14.2 on Ubuntu 13.04 (the only threaded Perl I have built at the moment), my distributions are not nearly so nice as yours. I keep seeing things like: { "0" => 3810, "2" => 5960, "16" => 230 }. I have no idea why there's a difference.
I suspect the *nix threading primitives are the cause. Inserting a 10 second delay after the threads are spawned and before $rand is used might allow the threads to get up a running. But that is a guess. (This is not the only area of difference I've seen between threads on windows and *nix; the root of which lies beyond the scope of Perl.)
I also wonder if you need to consider modulo bias. Well, actually looking at the code again, I don't wonder, I'm pretty sure modulo bias can be an issue if $M is set to a number that doesn't divide evenly into 2^32.
Nope.
Every PRNG in existance uses modulo operations; the statistics of doing so are thoroughly examined and well documented. Modulo operation bias on fixed-width (32/64-bit) random integer generators output is confined to the highest integer, and very minor. (ie. if mod 24, then 23 has a slightly less chance of being picked; but well within the statistical variation expected.)
I've also tested this fairly extensively (on my system):
And with FIPS-140-2:
...
my $bytes = join '', map chr( unpack( 'V', $rand ) % 256 ), 1 .. $N;
my $set = unpack '%32b*', $bytes;
printf "In $N bytes, there are %d ones and %d zeros\n", $set, length(
+$bytes ) *8 - $set;
__END__
C:\test>rand -M=97 -N=1e5
In 1e5 bytes, there are 401004 ones and 398996 zeros
C:\test>rand -M=97 -N=1e5
In 1e5 bytes, there are 400686 ones and 399314 zeros
C:\test>rand -N=1e6
In 1e6 bytes, there are 4002738 ones and 3997262 zeros
C:\test>rand -N=1e6
In 1e6 bytes, there are 3997975 ones and 4002025 zeros
In this test, I extend that notion to runs of 1s of various lengths (the 5-sigma figure is equivalent to 21 heads in a row):
C:\test>rand -N=1e6
...
my $bytes = join '', map chr( unpack( 'V', $rand ) % 256 ), 1 .. $N;
my $set = unpack '%32b*', $bytes;
printf "In $N bytes, there are %d ones and %d zeros\n", $set, length(
+$bytes ) *8 - $set;
use Statistics::Basic qw[ stddev ];
my @bytes;
++$bytes[ ord( substr $bytes, $_, 1 ) ] for 0 .. length( $bytes ) -1;
#pp \@bytes;
print "Stddev: ", stddev( @bytes );
my %runs;
my $bits = unpack 'b*', $bytes;
for my $n ( 2 .. 40 ) {
++$runs{ length() } for $bits =~ m[(?<=0)(1{$n})(?=0)]g;
}
pp \%runs;
__END__
C:\test>rand -N=1e6
In 1e6 bytes, there are 4000292 ones and 3999708 zeros
Stddev: 191.23
{ 2 => 500474, 3 => 249154, 4 => 124655, 5 => 61747, 6 => 31528, 7 =>
+25885, 8 => 4672, 9 => 656, 10 => 175, 11 => 42, 12 => 17, 13 => 16,
+14 => 18, 15 => 13, 16 => 91, 17 => 38, 18 => 21, 19 => 13, 20 => 10,
+ 21 => 6, 22 => 5, 23 => 9, 24 => 50, 25 => 23, 26 => 17, 27 => 5, 28
+ => 6, 29 => 2, 30 => 2, 31 => 3, 32 => 37, 33 => 21, 34 => 9, 35 =>
+2, 36 => 2, 38 => 4, 39 => 5, 40 => 29 }
C:\test>rand -N=1e6
In 1e6 bytes, there are 3991425 ones and 4008575 zeros
Stddev: 197.76
{ 2 => 500058, 3 => 248757, 4 => 124893, 5 => 62380, 6 => 30268, 7 =>
+24800, 8 => 4693, 9 => 582, 10 => 153, 11 => 59, 12 => 26, 13 => 13,
+14 => 10, 15 => 11, 16 => 108, 17 => 45, 18 => 14, 19 => 11, 20 => 5,
+ 21 => 8, 22 => 7, 23 => 2, 24 => 46, 25 => 13, 26 => 10, 27 => 6, 28
+ => 5, 29 => 3, 30 => 3, 31 => 1, 32 => 50, 33 => 10, 34 => 6, 35 =>
+3, 36 => 5, 37 => 3, 38 => 1, 39 => 1, 40 => 40 }
If you want to plot those out, you'll find that all those numbers correspond uncannily with statistical expectations.
Indeed, if you can find a test -- preferably one that doesn't require a Masters in *nixisms for me to get to run on my system -- I'll run it.
It is, to the best of my ability to test it. truly random. Just horribly expensive for a PRNG! :)
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.