Verify distribution uniformity/Naive: Difference between revisions
Content added Content deleted
(Update Factor implementation: some functions were simplified thanks to John Benediktsson.) |
(Added Elixir) |
||
Line 1: | Line 1: | ||
{{task|Probability and statistics}} |
{{task|Probability and statistics}} |
||
<small>This task is an adjunct to [[Seven-dice from |
<small>This task is an adjunct to [[Seven-sided dice from five-sided dice]].</small> |
||
Create a function to check that the random integers returned from a small-integer generator function have uniform distribution. |
Create a function to check that the random integers returned from a small-integer generator function have uniform distribution. |
||
Line 13: | Line 13: | ||
* An 'error' if the distribution is not flat enough. |
* 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-dice from |
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: |
See also: |
||
Line 362: | Line 362: | ||
4 200016 |
4 200016 |
||
5 200424</pre> |
5 200424</pre> |
||
=={{header|Elixir}}== |
|||
{{trans|Erlang}} |
|||
<lang elixir>defmodule VerifyDistribution do |
|||
def naive( generator, times, delta_percent \\ 3 ) do |
|||
dict = Enum.reduce( List.duplicate(generator, times), Map.new, fn f,d -> update_counter(f,d) end ) |
|||
values = for x <- Dict.keys(dict), do: Dict.get(dict, x) |
|||
average = Enum.sum( values ) / Dict.size( dict ) |
|||
delta = average * (delta_percent / 100) |
|||
fun = fn {_key, value} -> abs(value - average) > delta end |
|||
too_large_dict = Enum.filter( dict, fun ) |
|||
return( Dict.size(too_large_dict), too_large_dict, average, delta_percent ) |
|||
end |
|||
def return( 0, _too_large_dict, _average, _delta ), do: :ok |
|||
def return( _n, too_large_dict, average, delta ) do |
|||
{:error, {Dict.to_list(too_large_dict), :failed_expected_average, average, 'with_delta_%', delta}} |
|||
end |
|||
def update_counter( fun, dict ), do: Dict.update( dict, fun.(), 1, fn(val) -> val+1 end ) |
|||
end |
|||
:random.seed(:erlang.now) |
|||
fun = fn -> Dice.dice7 end |
|||
IO.inspect VerifyDistribution.naive( fun, 100000, 3 ) |
|||
IO.inspect VerifyDistribution.naive( fun, 100, 3 )</lang> |
|||
{{out}} |
|||
<pre> |
|||
:ok |
|||
{:error, |
|||
{[{1, 16}, {2, 10}, {4, 15}, {5, 8}, {6, 20}, {7, 17}], |
|||
:failed_expected_average, 14.285714285714286, 'with_delta_%', 3}} |
|||
</pre> |
|||
=={{header|Erlang}}== |
=={{header|Erlang}}== |