I checked TestU01, but i seems like it only accepts powers of 2 as the output range of your PRNG. So i was not able to run the samplers against it.
Edit: If the upper range of the interval is divides the upper bound of the generator, no bias for any sampler is expected.
Edit2: Unless, of course, the underlying PRNG is also biased.
Edit3: Actually, I can convert the output of the sampler to some floating point number and assume some precision. Then i can feed to the testsuit. Maybe i try this.
Edit4: Ok, i tested the samplers against SmallCrush. Find the details and results below. However i don't think i will run this against BigCrush, because completing this takes forever and i cannot run my PC overnight. Also i have read somwhere, that the Mersenne Twister fails some test in big crush? Would this mean it will also fail for the composite number, even when the rejecting maps are working correctly?
Results:
As expected both naive non rejecting methods fail several tests. To be precise:
========= Summary results of SmallCrush =========
Version: TestU01 1.2.3
Generator: TMulSampler
Number of statistics: 15
Total CPU time: 00:00:41.60
The following tests gave p-values outside [0.001, 0.9990]:
(eps means a value < 1.0e-300):
(eps1 means a value < 1.0e-15):
Test p-value
----------------------------------------------
3 Gap eps
4 SimpPoker eps
5 CouponCollector eps
7 WeightDistrib eps
9 HammingIndep eps
10 RandomWalk1 H eps
10 RandomWalk1 M eps
10 RandomWalk1 J eps
10 RandomWalk1 C 2.5e-5
----------------------------------------------
All other tests were passed
========= Summary results of SmallCrush =========
Version: TestU01 1.2.3
Generator: TModSampler
Number of statistics: 15
Total CPU time: 00:00:41.26
The following tests gave p-values outside [0.001, 0.9990]:
(eps means a value < 1.0e-300):
(eps1 means a value < 1.0e-15):
Test p-value
----------------------------------------------
2 Collision eps
6 MaxOft eps
6 MaxOft AD 1 - eps1
7 WeightDistrib eps
9 HammingIndep 5.6e-16
10 RandomWalk1 H eps
10 RandomWalk1 M eps
10 RandomWalk1 J eps
10 RandomWalk1 R eps
10 RandomWalk1 C eps
----------------------------------------------
All other tests were passed
TMulSampler refers to the multiply and shift method and TModSampler refers to the modulo maping, both (at least in a somewhat similar form) currently implemented in the RTL.
All other implemented rejecting methods pass SmallCrush without failing any test. I attached the full output log to this post.
Used method:
To feed the output of the samplers into testsuite i construct a floating point number iterative (via Random(L)/(L-1) + Random(L)/(L-1)^2 + ...) until the number has absorbed at least 52 random bits. For the test i used a generator width of 31 bit (backed by the mersenne twister generator in the RTL) and target output interval size of L= 1610612736.
I attached the source code to this post (The code is a bit ugly, but well...). To build it you need fpc, gcc, testu01 installed and all header files and libraries in the respective search path. First call "gcc -c bat.c" and after this build the pascal application. If you do not want to run against testu01, remove the testu01 define in the pascal program and it should compile on any fpc installation. Since all samplers are tested against testu01 directly after each other it is helpful to pipe the output in some file and just watch it with tail -f or something.
Feel free to run it against big or small crush yourself.
I will also remove the attached code on the older forums post, to avoid having two different sources online.
Edit5: Actually it should be Random(L)/L + Random(L)/L^2 + ... . I will rerun the test with the correct formula ....
Edit6: Ok, it yields basically the same results. I updated the attachments.