#!/usr/bin/env ruby # Ruby/GSL implementation of GSL "rng/test.c" require("gsl") require("./gsl_test2.rb") include GSL::Test include Math N = 1000 N2 = 20000 GSL::IEEE::env_setup() GSL::Rng::env_setup() def rng_test(type, seed, n, result) r = GSL::Rng.alloc(type) if seed != 0; r.set(seed); end for i in 0...n k = r.get end status = (k != result) ? 1 : 0 GSL::Test::test(status, "#{r.name}, #{n} steps (#{k} observed vs #{result} expected)") end def rng_float_test(type) ri = GSL::Rng.alloc(type) rf = GSL::Rng.alloc(type) k = 0 status = 0 begin k = ri.get u = rf.get end while k == 0 c = k/u for i in 0...N2 k = ri.get u = rf.get if (c*k != u) status = 1 break end end GSL::Test::test(status, "#{ri.name}, ratio of int to double (#{c} observed vs #{k/u} expected)") end def rng_state_test(type) r = GSL::Rng.alloc(type) r_save = GSL::Rng.alloc(type) for i in 0...N; r.get; end GSL::Rng.memcpy(r_save, r) test_a = GSL::Vector.alloc(N) test_b = GSL::Vector.alloc(N) for i in 0...N; test_a[i] = r.get; end GSL::Rng.memcpy(r, r_save) for i in 0...N; test_b[i] = r.get; end status = 0 for i in 0...N status |= (test_b[i] != test_a[i]) ? 1 : 0 end GSL::Test::test(status, "#{r.name}, random number state consistency") end def rng_parallel_state_test(type) r1 = GSL::Rng.alloc(type) r2 = GSL::Rng.alloc(type) test_a = GSL::Vector.alloc(N) test_b = GSL::Vector.alloc(N) test_c = GSL::Vector.alloc(N) test_d = GSL::Vector.alloc(N) test_e = GSL::Vector.alloc(N) test_f = GSL::Vector.alloc(N) for i in 0...N; r1.get; end GSL::Rng.memcpy(r2, r1) for i in 0...N test_a[i] = r1.get test_b[i] = r2.get test_c[i] = r1.uniform_int(1234) test_d[i] = r2.uniform_int(1234) test_e[i] = r1.uniform test_f[i] = r2.uniform end status = 0 for i in 0...N status |= (test_b[i] != test_a[i]) ? 1 : 0 status |= (test_c[i] != test_d[i]) ? 1 : 0 status |= (test_e[i] != test_f[i]) ? 1 : 0 end GSL::Test::test(status, "#{r1.name}, parallel random number state consistency") end def rng_read_write_test(type) r = GSL::Rng.alloc(type) test_a = GSL::Vector.alloc(N) test_b = GSL::Vector.alloc(N) for i in 0...N; r.get; end r.fwrite("test.dat") for i in 0...N; test_a[i] = r.get; end r.fread("test.dat") for i in 0...N; test_b[i] = r.get; end status = 0 for i in 0...N status |= (test_b[i] != test_a[i]) ? 1 : 0 end GSL::Test::test(status, "#{r.name}, random number generator read and write") if FileTest.exist?("test.dat") File.delete("test.dat") end end def rng_max_test(r, ran_max) max = 0 for i in 0...N2 k = r.get if k > max; max = k; end end actual_uncovered = ran_max - max; expect_uncovered = ran_max.to_f / (N2.to_f); status = ((max > ran_max) || (actual_uncovered > 7 * expect_uncovered)) ? 1 : 0 return max, status; end def rng_min_test(r, ran_min, ran_max) min = 1000000000 for i in 0...N2 k = r.get if k < min; min = k; end end actual_uncovered = min - ran_min expect_uncovered = ran_max.to_f/(N2.to_f) status = ((min < ran_min) || (actual_uncovered > 7 * expect_uncovered)) ? 1 : 0 return min, status end def rng_sum_test(r) sum = 0.0 for i in 0...N2 x = r.uniform - 0.5 sum += x end sum = sum / (N2.to_f) sigma = sum*sqrt(12.0*N2) status = (sigma.abs > 3 || sigma.abs < 0.003) ? 1 : 0 if status == 1 fprintf(STDERR, "sum=%g, sigma=%g\n", sum. sigma) end return sigma, status end BINS = 17 EXTRA = 10 def rng_bin_test(r) count = GSL::Vector.calloc(BINS+EXTRA) chisq = 0.0 for i in 0...N2 j = r.uniform_int(BINS) count[j] = count[j] + 1 end for i in 0...BINS x = (N2.to_f)/(BINS) d = count[i] - x chisq += (d*d)/(x) end sigma = sqrt(chisq/(BINS)) status = (sigma.abs > 3 || sigma.abs < 0.003) ? 1 : 0 for i in BINS...EXTRA if count[i] != 0 status = 1 GSL::Test::test(status, "#{r.name}, wrote outside range in bin test (#{i} observed vs #{BINS-1} expected)") end end return sigma, status end def generic_rng_test(type) r = GSL::Rng.alloc(type) name = r.name kmax = 0 kmin = 1000 sigma = 0.0 ran_max = r.max ran_min = r.min kmax, status = rng_max_test(r, ran_max) GSL::Test::test(status, "#{name}, observed vs theoretical maximum (#{kmax} vs #{ran_max})") kmin, status = rng_min_test(r, ran_min, ran_max) GSL::Test::test(status, "#{name}, observed vs theoretical minimum (#{kmin} vs #{ran_min})") sigma, status = rng_sum_test(r) GSL::Test::test(status, "#{r.name}, sum test within acceptable sigma (observed #{sigma} sigma)") sigma, status = rng_bin_test(r) GSL::Test::test(status, "#{r.name}, bin test within acceptable chisq (observed #{sigma} sigma)") r.set(1) kmax, status = rng_max_test(r, ran_max) r.set(1) kmin, s = rng_min_test(r, ran_min, ran_max) status |= s r.set(1) sigma, s = rng_sum_test(r) status |= s r.set(12345) kmax, s = rng_max_test(r, ran_max) status |= s r.set(12345) kmin, s = rng_min_test(r, ran_min, ran_max) status |= s r.set(12345) sigma, s = rng_sum_test(r) status |= s GSL::Test::test(status, "#{r.name}, maximum and sum tests for non-default seeds") end rng_test("rand", 1, 10000, 1910041713); rng_test("randu", 1, 10000, 1623524161); rng_test("cmrg", 1, 10000, 719452880); rng_test("minstd", 1, 10000, 1043618065); rng_test("mrg", 1, 10000, 2064828650); rng_test("taus", 1, 10000, 2733957125); rng_test("taus113", 1, 1000, 1925420673); rng_test("transputer", 1, 10000, 1244127297); rng_test("vax", 1, 10000, 3051034865); rng_test("borosh13", 1, 10000, 2513433025); rng_test("fishman18", 1, 10000, 330402013); rng_test("fishman2x", 1, 10000, 540133597); rng_test("knuthran2", 1, 10000, 1084477620); rng_test("knuthran", 310952, 1009 * 2009 + 1, 461390032); rng_test("lecuyer21", 1, 10000, 2006618587); rng_test("waterman14", 1, 10000, 3776680385); rng_test("coveyou", 6, 10000, 1416754246); rng_test("fishman20", 6, 10000, 248127575); rng_test("ranlux", 314159265, 10000, 12077992); rng_test("ranlux389", 314159265, 10000, 165942); rng_test("ranlxs0", 1, 10000, 11904320); rng_test("ranlxs1", 1, 10000, 8734328); rng_test("ranlxs2", 1, 10000, 6843140); rng_test("ranlxd1", 1, 10000, 1998227290); rng_test("ranlxd2", 1, 10000, 3949287736); rng_test("slatec", 1, 10000, 45776); rng_test("uni", 1, 10000, 9214); rng_test("uni32", 1, 10000, 1155229825); rng_test("zuf", 1, 10000, 3970); rng_test("r250", 1, 10000, 1100653588); rng_test("mt19937", 4357, 1000, 1186927261); rng_test("mt19937_1999", 4357, 1000, 1030650439); rng_test("mt19937_1998", 4357, 1000, 1309179303); rng_test("tt800", 0, 10000, 2856609219); rng_test("ran0", 0, 10000, 1115320064); rng_test("ran1", 0, 10000, 1491066076); rng_test("ran2", 0, 10000, 1701364455); rng_test("ran3", 0, 10000, 186340785); rng_test("ranmar", 1, 10000, 14428370); rng_test("rand48", 0, 10000, 0xDE095043); rng_test("rand48", 1, 10000, 0xEDA54977); rng_test("random_glibc2", 0, 10000, 1908609430); rng_test("random8_glibc2", 0, 10000, 1910041713); rng_test("random32_glibc2", 0, 10000, 1587395585); rng_test("random64_glibc2", 0, 10000, 52848624); rng_test("random128_glibc2", 0, 10000, 1908609430); rng_test("random256_glibc2", 0, 10000, 179943260); rng_test("random_bsd", 0, 10000, 1457025928); rng_test("random8_bsd", 0, 10000, 1910041713); rng_test("random32_bsd", 0, 10000, 1663114331); rng_test("random64_bsd", 0, 10000, 864469165); rng_test("random128_bsd", 0, 10000, 1457025928); rng_test("random256_bsd", 0, 10000, 1216357476); rng_test("random_libc5", 0, 10000, 428084942); rng_test("random8_libc5", 0, 10000, 1910041713); rng_test("random32_libc5", 0, 10000, 1967452027); rng_test("random64_libc5", 0, 10000, 2106639801); rng_test("random128_libc5", 0, 10000, 428084942); rng_test("random256_libc5", 0, 10000, 116367984); rng_test("ranf", 0, 10000, 2152890433); rng_test("ranf", 2, 10000, 339327233); Rng.types.each do |type| rng_float_test(type) end Rng.types.each do |type| rng_state_test(type) end Rng.types.each do |type| rng_parallel_state_test(type) end Rng.types.each do |type| rng_read_write_test(type) end Rng.types.each do |type| generic_rng_test(type) end