just gathering the comments from https://www.shadertoy.com/view/WttXWX in a place I can actually find, which also has more markdown :)
OK, results are in: as 32 bit RNGs, the 3-round Wellons function here is marked as weak in just 2 tests, with no failures. The 2-round Wellons function has 4 weaks and 1 failure, the murmurhash derivative only slightly worse with 5 weaks and 1 failure. Jenkins and Wang have many failures (Wang fails almost everything) so aren't really in the running.
http://webhome.phy.duke.edu/~rgb/General/dieharder.php http://simul.iro.umontreal.ca/testu01/guideshorttestu01.pdf p 88-157 https://github.com/umontreal-simul/latticetester
Individual tests (just the negative results from the 50 or so tests):
// --- choose one:
//#define hashi(x) lowbias32(x)
#define hashi(x) triple32(x)
#define hash(x) ( float( hashi(x) ) / float( 0xffffffffU ) )
//bias: 0.17353355999581582 ( very probably the best of its kind )
uint lowbias32(uint x)
{
x ^= x >> 16;
x *= 0x7feb352dU;
x ^= x >> 15;
x *= 0x846ca68bU;
x ^= x >> 16;
return x;
}
// bias: 0.020888578919738908 = minimal theoretic limit
uint triple32(uint x)
{
x ^= x >> 17;
x *= 0xed5ad4bbU;
x ^= x >> 11;
x *= 0xac4c1b51U;
x ^= x >> 15;
x *= 0x31848babU;
x ^= x >> 14;
return x;
}
TEST | RESULT | ||||
---|---|---|---|---|---|
diehard_opso | 0 | 2097152 | 100 | 0.00000001 | FAILED |
sts_serial | 15 | 100000 | 100 | 0.99636479 | WEAK |
rgb_minimum_distance | 4 | 10000 | 1000 | 0.99754988 | WEAK |
rgb_permutations | 3 | 100000 | 100 | 0.99946899 | WEAK |
rgb_lagged_sum | 5 | 1000000 | 100 | 0.99575897 | WEAK |
TEST | RESULT | ||||
---|---|---|---|---|---|
diehard_parking_lot | 0 | 12000 | 100 | 0.99650356 | WEAK |
rgb_minimum_distance | 5 | 10000 | 1000 | 0.00125775 | WEAK |
TEST | RESULT | ||||
---|---|---|---|---|---|
diehard_craps | 0 | 200000 | 100 | 0.00012089 | WEAK |
marsaglia_tsang_gcd | 0 | 10000000 | 100 | 0.00000000 | FAILED |
sts_serial | 6 | 100000 | 100 | 0.99932034 | WEAK |
rgb_bitdist | 5 | 100000 | 100 | 0.99933401 | WEAK |
rgb_permutations | 5 | 100000 | 100 | 0.99646826 | WEAK |
rgb_lagged_sum | 18 | 1000000 | 100 | 0.99788947 | WEAK |
Using the sine hash from https://www.shadertoy.com/view/ltyBWm (which visually looks fine) and using to generate 16-bit random numbers, C++ code:
float sinhash(uint x, uint y) {
float seed = 71.33*x+852.381*y;
return fmod(fabs(38351.43*sin(14.13*seed)),1.0);
}
uint sinhash(uint n) {
float x = sinhash(n >> 16, n & 0xffff);
return uint(x*0x10000);
}
Result is not awful, but not great:
TEST | RESULT | ||||
---|---|---|---|---|---|
diehard_operm5 | 0 | 1000000 | 100 | 0.00000000 | FAILED |
diehard_squeeze | 0 | 100000 | 100 | 0.00000000 | FAILED |
diehard_runs | 0 | 100000 | 100 | 0.99996083 | WEAK |
marsaglia_tsang_gcd | 0 | 10000000 | 100 | 0.00000000 | FAILED |
marsaglia_tsang_gcd | 0 | 10000000 | 100 | 0.00000000 | FAILED |
sts_runs | 2 | 100000 | 100 | 0.00000004 | FAILED |
sts_serial | 3 | 100000 | 100 | 0.00021384 | WEAK |
sts_serial | 13 | 100000 | 100 | 0.00145147 | WEAK |
rgb_bitdist | 4 | 100000 | 100 | 0.00050052 | WEAK |
rgb_bitdist | 8 | 100000 | 100 | 0.00000000 | FAILED |
rgb_lagged_sum | 0 | 1000000 | 100 | 0.00000000 | FAILED |
rgb_lagged_sum | 1 | 1000000 | 100 | 0.00000000 | FAILED |
rgb_lagged_sum | 2 | 1000000 | 100 | 0.00000000 | FAILED |
rgb_lagged_sum | 3 | 1000000 | 100 | 0.00000000 | FAILED |
rgb_lagged_sum | 4 | 1000000 | 100 | 0.00000000 | FAILED |
rgb_lagged_sum | 5 | 1000000 | 100 | 0.00000000 | FAILED |
rgb_lagged_sum | 6 | 1000000 | 100 | 0.00000000 | FAILED |
<more failures> |
Very similar results from the "official" sine hash:
float hash(vec2 p)
{
return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
}
TEST | RESULT | ||||
---|---|---|---|---|---|
diehard_operm5 | 0 | 1000000 | 100 | 0.00000000 | FAILED |
diehard_dna | 0 | 2097152 | 100 | 0.00144687 | WEAK |
diehard_squeeze | 0 | 100000 | 100 | 0.00000012 | FAILED |
diehard_runs | 0 | 100000 | 100 | 0.00000000 | FAILED |
diehard_runs | 0 | 100000 | 100 | 0.00000029 | FAILED |
diehard_craps | 0 | 200000 | 100 | 0.00000003 | FAILED |
sts_serial | 1 | 100000 | 100 | 0.00273519 | WEAK |
sts_serial | 9 | 100000 | 100 | 0.99532417 | WEAK |
sts_serial | 10 | 100000 | 100 | 0.99710812 | WEAK |
rgb_permutations | 3 | 100000 | 100 | 0.00008555 | WEAK |
rgb_permutations | 4 | 100000 | 100 | 0.00175526 | WEAK |
rgb_lagged_sum | 0 | 1000000 | 100 | 0.00000000 | FAILED |
rgb_lagged_sum | 1 | 1000000 | 100 | 0.00000008 | FAILED |
rgb_lagged_sum | 2 | 1000000 | 100 | 0.00000000 | FAILED |
rgb_lagged_sum | 3 | 1000000 | 100 | 0.00000000 | FAILED |
rgb_lagged_sum | 4 | 1000000 | 100 | 0.00000000 | FAILED |
rgb_lagged_sum | 5 | 1000000 | 100 | 0.00000000 | FAILED |
<more failures> |
OK, some more results for a 32-bit linear congruential generator, this one is from Numerical Recipes:
uint lcg(uint) {
static uint value = 1;
value *= 1664525U;
value += 1013904223U;
return value;
}
TEST | RESULT | ||||
---|---|---|---|---|---|
diehard_rank_6x8 | 0 | 100000 | 100 | 0.00000000 | FAILED |
diehard_bitstream | 0 | 2097152 | 100 | 0.00000000 | FAILED |
diehard_opso | 0 | 2097152 | 100 | 0.00000000 | FAILED |
diehard_oqso | 0 | 2097152 | 100 | 0.00000000 | FAILED |
diehard_dna | 0 | 2097152 | 100 | 0.00000000 | FAILED |
diehard_count_1s_str | 0 | 256000 | 100 | 0.00000000 | FAILED |
diehard_count_1s_byt | 0 | 256000 | 100 | 0.00000000 | FAILED |
diehard_parking_lot | 0 | 12000 | 100 | 0.99983528 | WEAK |
marsaglia_tsang_gcd | 0 | 10000000 | 100 | 0.00000000 | FAILED |
marsaglia_tsang_gcd | 0 | 10000000 | 100 | 0.00000000 | FAILED |
sts_serial | 2 | 100000 | 100 | 0.00001211 | WEAK |
sts_serial | 3 | 100000 | 100 | 0.00000001 | FAILED |
sts_serial | 3 | 100000 | 100 | 0.00001378 | WEAK |
sts_serial | 4 | 100000 | 100 | 0.00000000 | FAILED |
sts_serial | 4 | 100000 | 100 | 0.00000492 | WEAK |
sts_serial | 5 | 100000 | 100 | 0.00000000 | FAILED |
<more sts_serial failures> |
|||||
rgb_bitdist | 1 | 100000 | 100 | 0.00000000 | FAILED |
rgb_bitdist | 2 | 100000 | 100 | 0.00000000 | FAILED |
<more rgb_bitdist failures> |
|||||
rgb_minimum_distance | 2 | 10000 | 1000 | 0.00000000 | FAILED |
rgb_minimum_distance | 3 | 10000 | 1000 | 0.00292069 | WEAK |
rgb_minimum_distance | 4 | 10000 | 1000 | 0.00000000 | FAILED |
rgb_minimum_distance | 5 | 10000 | 1000 | 0.00000004 | FAILED |
rgb_lagged_sum | 11 | 1000000 | 100 | 0.99708426 | WEAK |
rgb_lagged_sum | 13 | 1000000 | 100 | 0.99998108 | WEAK |
rgb_lagged_sum | 22 | 1000000 | 100 | 0.99964562 | WEAK |
dab_bytedistrib | 0 | 51200000 | 1 | 1.00000000 | FAILED |
dab_dct | 256 | 50000 | 1 | 0.00000000 | FAILED |
dab_filltree2 | 0 | 5000000 | 1 | 0.00000000 | FAILED |
dab_filltree2 | 1 | 5000000 | 1 | 0.00000000 | FAILED |
dab_monobit2 | 12 | 65000000 | 1 | 1.00000000 | FAILED |