This task is an adjunct to Seven-sided dice from five-sided dice.



Task

Create a function to check that the random integers returned from a small-integer generator function have uniform distribution.



The function should take as arguments:

 The function (or object) producing random integers.
 The number of times to call the integer generator.
 A 'delta' value of some sort that indicates how close to a flat distribution is close enough.


The function should produce:

 Some indication of the distribution achieved.
 An 'error' if the distribution is not flat enough.


Show the distribution checker working when the produced distribution is flat enough and when it is not. (Use a generator from Seven-sided dice from five-sided dice).



See also:

Verify distribution uniformity/Chi-squared test


# rnd  : a co-expression, which will generate the random numbers
# n    : the number of numbers to test
# delta: tolerance in non-uniformity
# This procedure fails if after the sampling the difference 
# in uniformity exceeds delta, a proportion of n / number-of-alternatives
procedure verify_uniform (rnd, n, delta)
  # generate a table counting the outcome of the generator
  results := table (0)
  every (1 to n) do results[@rnd] +:= 1
  # retrieve the statistics
  smallest := n
  largest := 0
  every num := key(results) do { # record result and limits
    write (num || " " || results[num])
    if results[num] < smallest then smallest := results[num]
    if results[num] > largest  then largest  := results[num]
  }
  # decide if difference is within bounds defined by delta
  return largest-smallest < delta * n / *results
end
 
procedure main ()
  gen_1 := create (|?10) # uniform integers, 1 to 10
  if verify_uniform (gen_1, 1000000, 0.01) 
    then write ("uniform")
    else write ("skewed")
  gen_2 := create (|(if ?2 = 1 then 6 else ?10)) # skewed integers, 1 to 10
  if verify_uniform (gen_2, 1000000, 0.01) 
    then write ("uniform")
    else write ("skewed")
end