Verify distribution uniformity/Naive: Difference between revisions

Content added Content deleted
No edit summary
m (syntax highlighting fixup automation)
Line 29: Line 29:
{{trans|Python}}
{{trans|Python}}


<lang 11l>F dice5()
<syntaxhighlight lang="11l">F dice5()
R random:(1..5)
R random:(1..5)


Line 41: Line 41:
print(bin)
print(bin)


distcheck(dice5, 1000000, 1)</lang>
distcheck(dice5, 1000000, 1)</syntaxhighlight>


{{out}}
{{out}}
Line 50: Line 50:
=={{header|Ada}}==
=={{header|Ada}}==


<lang Ada>with Ada.Numerics.Discrete_Random, Ada.Text_IO;
<syntaxhighlight lang="ada">with Ada.Numerics.Discrete_Random, Ada.Text_IO;


procedure Naive_Random is
procedure Naive_Random is
Line 100: Line 100:


Ada.Text_IO.Put_Line("Test Passed? (" & Boolean'Image(OK) & ")");
Ada.Text_IO.Put_Line("Test Passed? (" & Boolean'Image(OK) & ")");
end Naive_Random;</lang>
end Naive_Random;</syntaxhighlight>


Sample run 1 (all buckets good):<pre>7
Sample run 1 (all buckets good):<pre>7
Line 131: Line 131:


=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
<lang AutoHotkey>MsgBox, % DistCheck("dice7",10000,3)
<syntaxhighlight lang="autohotkey">MsgBox, % DistCheck("dice7",10000,3)


DistCheck(function, repetitions, delta)
DistCheck(function, repetitions, delta)
Line 153: Line 153:
}
}
Return, text
Return, text
}</lang>
}</syntaxhighlight>
<pre>Distribution check:
<pre>Distribution check:


Line 170: Line 170:
=={{header|BBC BASIC}}==
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
{{works with|BBC BASIC for Windows}}
<lang bbcbasic> MAXRND = 7
<syntaxhighlight lang="bbcbasic"> MAXRND = 7
FOR r% = 2 TO 5
FOR r% = 2 TO 5
check% = FNdistcheck(FNdice5, 10^r%, 0.05)
check% = FNdistcheck(FNdice5, 10^r%, 0.05)
Line 196: Line 196:
= s%
= s%
DEF FNdice5 = RND(5)</lang>
DEF FNdice5 = RND(5)</syntaxhighlight>
Output:
Output:
<pre>
<pre>
Line 206: Line 206:


=={{header|C}}==
=={{header|C}}==
<lang c>#include <stdlib.h>
<syntaxhighlight lang="c">#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <math.h>
#include <math.h>
Line 251: Line 251:


return 0;
return 0;
}</lang>output<pre>
}</syntaxhighlight>output<pre>
Count = 10: bin 1 out of range: 1 (-30% vs 3%), NOT flat
Count = 10: bin 1 out of range: 1 (-30% vs 3%), NOT flat
Count = 100: bin 1 out of range: 11 (-23% vs 3%), NOT flat
Count = 100: bin 1 out of range: 11 (-23% vs 3%), NOT flat
Line 261: Line 261:


=={{header|C++}}==
=={{header|C++}}==
<lang cpp>#include <map>
<syntaxhighlight lang="cpp">#include <map>
#include <iostream>
#include <iostream>
#include <cmath>
#include <cmath>
Line 291: Line 291:


return good;
return good;
}</lang>
}</syntaxhighlight>


=={{header|Clojure}}==
=={{header|Clojure}}==
The code could be shortened if the verify function did the output itself, but the "Clojure way" is to have functions, whenever possible, avoid side effects (like printing) and just return a result. Then the "application-level" code uses doseq and println to display the output to the user. The built-in (rand-int) function is used for all three runs of the verify function, but first with small N to simulate experimental error in a small sample size, then with larger N to show it working properly on large N.
The code could be shortened if the verify function did the output itself, but the "Clojure way" is to have functions, whenever possible, avoid side effects (like printing) and just return a result. Then the "application-level" code uses doseq and println to display the output to the user. The built-in (rand-int) function is used for all three runs of the verify function, but first with small N to simulate experimental error in a small sample size, then with larger N to show it working properly on large N.
<lang clojure>(defn verify [rand n & [delta]]
<syntaxhighlight lang="clojure">(defn verify [rand n & [delta]]
(let [rands (frequencies (repeatedly n rand))
(let [rands (frequencies (repeatedly n rand))
avg (/ (reduce + (map val rands)) (count rands))
avg (/ (reduce + (map val rands)) (count rands))
Line 306: Line 306:
[num count okay?] (verify #(rand-int 7) n)]
[num count okay?] (verify #(rand-int 7) n)]
(println "Saw" num count "times:"
(println "Saw" num count "times:"
(if okay? "that's" " not") "acceptable"))</lang>
(if okay? "that's" " not") "acceptable"))</syntaxhighlight>


<pre>Saw 1 13 times: that's acceptable
<pre>Saw 1 13 times: that's acceptable
Line 332: Line 332:
=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
{{trans|OCaml}}
{{trans|OCaml}}
<lang lisp>(defun check-distribution (function n &optional (delta 1.0))
<syntaxhighlight lang="lisp">(defun check-distribution (function n &optional (delta 1.0))
(let ((bins (make-hash-table)))
(let ((bins (make-hash-table)))
(loop repeat n do (incf (gethash (funcall function) bins 0)))
(loop repeat n do (incf (gethash (funcall function) bins 0)))
Line 340: Line 340:
do (format t "~&Distribution potentially skewed for ~w:~
do (format t "~&Distribution potentially skewed for ~w:~
expected around ~w got ~w." key target value)
expected around ~w got ~w." key target value)
finally (return bins))))</lang>
finally (return bins))))</syntaxhighlight>


<pre>> (check-distribution 'd7 1000)
<pre>> (check-distribution 'd7 1000)
Line 355: Line 355:


=={{header|D}}==
=={{header|D}}==
<lang d>import std.stdio, std.string, std.math, std.algorithm, std.traits;
<syntaxhighlight lang="d">import std.stdio, std.string, std.math, std.algorithm, std.traits;


/**
/**
Line 385: Line 385:
distCheck(() => uniform(1, 6), 1_000_000, 1);
distCheck(() => uniform(1, 6), 1_000_000, 1);
}
}
}</lang>
}</syntaxhighlight>
If compiled with -version=verify_distribution_uniformity_naive_main:
If compiled with -version=verify_distribution_uniformity_naive_main:
{{out}}
{{out}}
Line 395: Line 395:
=={{header|Elixir}}==
=={{header|Elixir}}==
{{trans|Erlang}}
{{trans|Erlang}}
<lang elixir>defmodule VerifyDistribution do
<syntaxhighlight lang="elixir">defmodule VerifyDistribution do
def naive( generator, times, delta_percent ) do
def naive( generator, times, delta_percent ) do
dict = Enum.reduce( List.duplicate(generator, times), Map.new, &update_counter/2 )
dict = Enum.reduce( List.duplicate(generator, times), Map.new, &update_counter/2 )
Line 416: Line 416:
fun = fn -> Dice.dice7 end
fun = fn -> Dice.dice7 end
IO.inspect VerifyDistribution.naive( fun, 100000, 3 )
IO.inspect VerifyDistribution.naive( fun, 100000, 3 )
IO.inspect VerifyDistribution.naive( fun, 100, 3 )</lang>
IO.inspect VerifyDistribution.naive( fun, 100, 3 )</syntaxhighlight>


{{out}}
{{out}}
Line 427: Line 427:


=={{header|Erlang}}==
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( verify_distribution_uniformity ).
-module( verify_distribution_uniformity ).


Line 448: Line 448:


update_counter( Fun, Dict ) -> dict:update_counter( Fun(), 1, Dict ).
update_counter( Fun, Dict ) -> dict:update_counter( Fun(), 1, Dict ).
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 466: Line 466:
Following the task verbatim.
Following the task verbatim.


<lang>
<syntaxhighlight lang="text">
>function checkrandom (frand$, n:index, delta:positive real) ...
>function checkrandom (frand$, n:index, delta:positive real) ...
$ v=zeros(1,n);
$ v=zeros(1,n);
Line 482: Line 482:
>checkrandom("wrongdice",1000000,1)
>checkrandom("wrongdice",1000000,1)
0
0
</syntaxhighlight>
</lang>


Checking the dice7 from dice5 generator.
Checking the dice7 from dice5 generator.


<lang>
<syntaxhighlight lang="text">
>function dice5 () := intrandom(1,1,5);
>function dice5 () := intrandom(1,1,5);
>function dice7 () ...
>function dice7 () ...
Line 496: Line 496:
>checkrandom("dice7",1000000,1)
>checkrandom("dice7",1000000,1)
1
1
</syntaxhighlight>
</lang>


Faster implementation with the matrix language.
Faster implementation with the matrix language.


<lang>
<syntaxhighlight lang="text">
>function dice5(n) := intrandom(1,n,5)-1;
>function dice5(n) := intrandom(1,n,5)-1;
>function dice7(n) ...
>function dice7(n) ...
Line 519: Line 519:
>checkrandom(wrongdice(1000000))
>checkrandom(wrongdice(1000000))
0
0
</syntaxhighlight>
</lang>


=={{header|Factor}}==
=={{header|Factor}}==
<lang factor>USING: kernel random sequences assocs locals sorting prettyprint
<syntaxhighlight lang="factor">USING: kernel random sequences assocs locals sorting prettyprint
math math.functions math.statistics math.vectors math.ranges ;
math math.functions math.statistics math.vectors math.ranges ;
IN: rosetta-code.dice7
IN: rosetta-code.dice7
Line 578: Line 578:
{ 1 10 100 1000 10000 100000 1000000 }
{ 1 10 100 1000 10000 100000 1000000 }
[| times | 0.02 7 [ dice7 ] times verify ] each
[| times | 0.02 7 [ dice7 ] times verify ] each
;</lang>
;</syntaxhighlight>


Output:
Output:
Line 599: Line 599:
=={{header|Forth}}==
=={{header|Forth}}==
requires Forth200x locals
requires Forth200x locals
<lang forth>: .bounds ( u1 u2 -- ) ." lower bound = " . ." upper bound = " 1- . cr ;
<syntaxhighlight lang="forth">: .bounds ( u1 u2 -- ) ." lower bound = " . ." upper bound = " 1- . cr ;
: init-bins ( n -- addr )
: init-bins ( n -- addr )
cells dup allocate throw tuck swap erase ;
cells dup allocate throw tuck swap erase ;
Line 622: Line 622:
and
and
loop
loop
bins free throw ;</lang>
bins free throw ;</syntaxhighlight>
{{output}}
{{output}}
<pre>cr ' d7 1000000 7 1 check-distribution .
<pre>cr ' d7 1000000 7 1 check-distribution .
Line 648: Line 648:
=={{header|Fortran}}==
=={{header|Fortran}}==
{{works with|Fortran|95 and later}}
{{works with|Fortran|95 and later}}
<lang fortran>subroutine distcheck(randgen, n, delta)
<syntaxhighlight lang="fortran">subroutine distcheck(randgen, n, delta)


interface
interface
Line 693: Line 693:
deallocate(buckets)
deallocate(buckets)
end subroutine</lang>
end subroutine</syntaxhighlight>




=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
{{trans|Liberty BASIC}}
{{trans|Liberty BASIC}}
<lang freebasic>
<syntaxhighlight lang="freebasic">
Randomize Timer
Randomize Timer
Function dice5() As Integer
Function dice5() As Integer
Line 758: Line 758:
Print
Print
Sleep
Sleep
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 766: Line 766:


=={{header|Go}}==
=={{header|Go}}==
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 821: Line 821:
max, flatEnough = distCheck(dice7, 7, calls, 500)
max, flatEnough = distCheck(dice7, 7, calls, 500)
fmt.Println("Max delta:", max, "Flat enough:", flatEnough)
fmt.Println("Max delta:", max, "Flat enough:", flatEnough)
}</lang>
}</syntaxhighlight>
Output:
Output:
<pre>
<pre>
Line 829: Line 829:


=={{header|Haskell}}==
=={{header|Haskell}}==
<lang haskell>import System.Random
<syntaxhighlight lang="haskell">import System.Random
import Data.List
import Data.List
import Control.Monad
import Control.Monad
Line 841: Line 841:
ul = round $ (100 + fromIntegral d)/100 * avg
ul = round $ (100 + fromIntegral d)/100 * avg
ll = round $ (100 - fromIntegral d)/100 * avg
ll = round $ (100 - fromIntegral d)/100 * avg
return $ map (head &&& (id &&& liftM2 (&&) (>ll)(<ul)).length) group</lang>
return $ map (head &&& (id &&& liftM2 (&&) (>ll)(<ul)).length) group</syntaxhighlight>
Example:
Example:
<lang haskell>*Main> mapM_ print .sort =<< distribCheck (randomRIO(1,6)) 100000 3
<syntaxhighlight lang="haskell">*Main> mapM_ print .sort =<< distribCheck (randomRIO(1,6)) 100000 3
(1,(16911,True))
(1,(16911,True))
(2,(16599,True))
(2,(16599,True))
Line 849: Line 849:
(4,(16624,True))
(4,(16624,True))
(5,(16526,True))
(5,(16526,True))
(6,(16670,True))</lang>
(6,(16670,True))</syntaxhighlight>


=={{header|Hy}}==
=={{header|Hy}}==


<lang lisp>(import [collections [Counter]])
<syntaxhighlight lang="lisp">(import [collections [Counter]])
(import [random [randint]])
(import [random [randint]])


Line 864: Line 864:
(all (list-comp
(all (list-comp
(<= (- target delta) (/ n repeats) (+ target delta))
(<= (- target delta) (/ n repeats) (+ target delta))
[n (.values bins)])))</lang>
[n (.values bins)])))</syntaxhighlight>


Examples of use:
Examples of use:


<lang lisp>(for [f [
<syntaxhighlight lang="lisp">(for [f [
(fn [] (randint 1 10))
(fn [] (randint 1 10))
(fn [] (if (randint 0 1) (randint 1 9) (randint 1 10)))]]
(fn [] (if (randint 0 1) (randint 1 9) (randint 1 10)))]]
(print (uniform? f 5000 .02)))</lang>
(print (uniform? f 5000 .02)))</syntaxhighlight>


=={{header|Icon}} and {{header|Unicon}}==
=={{header|Icon}} and {{header|Unicon}}==
This example assumes the random number generator is passed to <code>verify_uniform</code> as a co-expression. The co-expression <code>rnd</code> is prompted for its next value using <code>@rnd</code>. The co-expression is created using <code>create (|?10)</code> where the vertical bar means generate an infinite sequence of what is to its right (in this case, <code>?10</code> generates a random integer in the range [1,10]).
This example assumes the random number generator is passed to <code>verify_uniform</code> as a co-expression. The co-expression <code>rnd</code> is prompted for its next value using <code>@rnd</code>. The co-expression is created using <code>create (|?10)</code> where the vertical bar means generate an infinite sequence of what is to its right (in this case, <code>?10</code> generates a random integer in the range [1,10]).
<lang Icon># rnd : a co-expression, which will generate the random numbers
<syntaxhighlight lang="icon"># rnd : a co-expression, which will generate the random numbers
# n : the number of numbers to test
# n : the number of numbers to test
# delta: tolerance in non-uniformity
# delta: tolerance in non-uniformity
Line 905: Line 905:
then write ("uniform")
then write ("uniform")
else write ("skewed")
else write ("skewed")
end</lang>
end</syntaxhighlight>
Output:
Output:
<pre>
<pre>
Line 936: Line 936:


The ''delta'' is given as an optional left argument (<code>x</code>), defaulting to 5%. The right argument (<code>y</code>) is any valid argument to the distribution generating verb.
The ''delta'' is given as an optional left argument (<code>x</code>), defaulting to 5%. The right argument (<code>y</code>) is any valid argument to the distribution generating verb.
<lang j>checkUniform=: adverb define
<syntaxhighlight lang="j">checkUniform=: adverb define
0.05 u checkUniform y
0.05 u checkUniform y
:
:
Line 947: Line 947:
errmsg assert (delta * expected) > | expected - {:"1 freqtable
errmsg assert (delta * expected) > | expected - {:"1 freqtable
freqtable
freqtable
)</lang>
)</syntaxhighlight>
It is possible to use tacit expressions within an explicit definition enabling a more functional and concise style:
It is possible to use tacit expressions within an explicit definition enabling a more functional and concise style:
<lang j>checkUniformT=: adverb define
<syntaxhighlight lang="j">checkUniformT=: adverb define
0.05 u checkUniformT y
0.05 u checkUniformT y
:
:
Line 956: Line 956:
errmsg assert ((n % #) (x&*@[ > |@:-) {:"1) freqtable
errmsg assert ((n % #) (x&*@[ > |@:-) {:"1) freqtable
freqtable
freqtable
)</lang>
)</syntaxhighlight>
Show usage using <code>rollD7t</code> given in [[Seven-dice from Five-dice#J|Seven-dice from Five-dice]]:
Show usage using <code>rollD7t</code> given in [[Seven-dice from Five-dice#J|Seven-dice from Five-dice]]:
<lang j> 0.05 rollD7t checkUniform 1e5
<syntaxhighlight lang="j"> 0.05 rollD7t checkUniform 1e5
1 14082
1 14082
2 14337
2 14337
Line 968: Line 968:
0.05 rollD7t checkUniform 1e2
0.05 rollD7t checkUniform 1e2
|Distribution is potentially skewed: assert
|Distribution is potentially skewed: assert
| errmsg assert(delta*expected)>|expected-{:"1 freqtable</lang>
| errmsg assert(delta*expected)>|expected-{:"1 freqtable</syntaxhighlight>


=={{header|Java}}==
=={{header|Java}}==
{{trans|D}}
{{trans|D}}
{{works with|Java|8}}
{{works with|Java|8}}
<lang java>import static java.lang.Math.abs;
<syntaxhighlight lang="java">import static java.lang.Math.abs;
import java.util.*;
import java.util.*;
import java.util.function.IntSupplier;
import java.util.function.IntSupplier;
Line 1,001: Line 1,001:
distCheck(() -> (int) (Math.random() * 5) + 1, 1_000_000, 1);
distCheck(() -> (int) (Math.random() * 5) + 1, 1_000_000, 1);
}
}
}</lang>
}</syntaxhighlight>
<pre>1 200439
<pre>1 200439
2 201016
2 201016
Line 1,010: Line 1,010:
=={{header|JavaScript}}==
=={{header|JavaScript}}==
{{trans|Tcl}}
{{trans|Tcl}}
<lang javascript>function distcheck(random_func, times, opts) {
<syntaxhighlight lang="javascript">function distcheck(random_func, times, opts) {
if (opts === undefined) opts = {}
if (opts === undefined) opts = {}
opts['delta'] = opts['delta'] || 2;
opts['delta'] = opts['delta'] || 2;
Line 1,049: Line 1,049:
} catch (e) {
} catch (e) {
print(e);
print(e);
}</lang>
}</syntaxhighlight>
Output:
Output:
<pre>0 9945
<pre>0 9945
Line 1,065: Line 1,065:


=={{header|Julia}}==
=={{header|Julia}}==
<lang julia>using Printf
<syntaxhighlight lang="julia">using Printf


function distcheck(f::Function, rep::Int=10000, Δ::Int=3)
function distcheck(f::Function, rep::Int=10000, Δ::Int=3)
Line 1,081: Line 1,081:
distcheck(x -> rand(1:5, x))
distcheck(x -> rand(1:5, x))
# Dice7 check
# Dice7 check
distcheck(dice7)</lang>
distcheck(dice7)</syntaxhighlight>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
<lang scala>// version 1.1.3
<syntaxhighlight lang="scala">// version 1.1.3


import java.util.Random
import java.util.Random
Line 1,121: Line 1,121:
println()
println()
checkDist(::dice5, 100_000)
checkDist(::dice5, 100_000)
}</lang>
}</syntaxhighlight>


Sample output:
Sample output:
Line 1,152: Line 1,152:
=={{header|Liberty BASIC}}==
=={{header|Liberty BASIC}}==
LB cannot pass user-defined function by name, so we use predefined function name - GENERATOR
LB cannot pass user-defined function by name, so we use predefined function name - GENERATOR
<syntaxhighlight lang="lb">
<lang lb>
n=1000
n=1000
print "Testing ";n;" times"
print "Testing ";n;" times"
Line 1,211: Line 1,211:
GENERATOR = 1+int(rnd(0)*5) '1..5: dice5
GENERATOR = 1+int(rnd(0)*5) '1..5: dice5
end function
end function
</syntaxhighlight>
</lang>
{{Out}}
{{Out}}
<pre>
<pre>
Line 1,249: Line 1,249:


=={{header|Mathematica}}/{{header|Wolfram Language}}==
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<lang Mathematica>SetAttributes[CheckDistribution, HoldFirst]
<syntaxhighlight lang="mathematica">SetAttributes[CheckDistribution, HoldFirst]
CheckDistribution[function_,number_,delta_] :=(Print["Expected: ", N[number/7], ", Generated :",
CheckDistribution[function_,number_,delta_] :=(Print["Expected: ", N[number/7], ", Generated :",
Transpose[Tally[Table[function, {number}]]][[2]] // Sort]; If[(Max[#]-Min[#])&
Transpose[Tally[Table[function, {number}]]][[2]] // Sort]; If[(Max[#]-Min[#])&
[Transpose[Tally[Table[function, {number}]]][[2]]] < delta*number/700, "Flat", "Skewed"])</lang>
[Transpose[Tally[Table[function, {number}]]][[2]]] < delta*number/700, "Flat", "Skewed"])</syntaxhighlight>


Example usage:
Example usage:
Line 1,266: Line 1,266:


=={{header|Nim}}==
=={{header|Nim}}==
<lang Nim>import tables
<syntaxhighlight lang="nim">import tables




Line 1,293: Line 1,293:
proc rand5(): int = rand(1..5)
proc rand5(): int = rand(1..5)
checkDist(rand5, 1_000_000, 0.5)
checkDist(rand5, 1_000_000, 0.5)
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 1,301: Line 1,301:


=={{header|OCaml}}==
=={{header|OCaml}}==
<lang ocaml>let distcheck fn n ?(delta=1.0) () =
<syntaxhighlight lang="ocaml">let distcheck fn n ?(delta=1.0) () =
let h = Hashtbl.create 5 in
let h = Hashtbl.create 5 in
for i = 1 to n do
for i = 1 to n do
Line 1,319: Line 1,319:
key target value)
key target value)
) h;
) h;
;;</lang>
;;</syntaxhighlight>


=={{header|PARI/GP}}==
=={{header|PARI/GP}}==
This tests the purportedly random 7-sided die with a slightly biased 1000-sided die.
This tests the purportedly random 7-sided die with a slightly biased 1000-sided die.
<lang parigp>dice5()=random(5)+1;
<syntaxhighlight lang="parigp">dice5()=random(5)+1;
dice7()={
dice7()={
Line 1,352: Line 1,352:


test(dice7, 10^5)
test(dice7, 10^5)
test(()->if(random(1000),random(1000),1), 10^5)</lang>
test(()->if(random(1000),random(1000),1), 10^5)</syntaxhighlight>
Output:
Output:
<pre>Flat with significance 0.2931867820813680387842134664085280183
<pre>Flat with significance 0.2931867820813680387842134664085280183
Line 1,361: Line 1,361:
Testing two 'types' of 7-sided dice. Both appear to be fair.
Testing two 'types' of 7-sided dice. Both appear to be fair.
{{trans|Raku}}
{{trans|Raku}}
<lang perl>sub roll7 { 1+int rand(7) }
<syntaxhighlight lang="perl">sub roll7 { 1+int rand(7) }
sub roll5 { 1+int rand(5) }
sub roll5 { 1+int rand(5) }
sub roll7_5 {
sub roll7_5 {
Line 1,390: Line 1,390:
}
}
return $result . "\n";
return $result . "\n";
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre> 143 expected
<pre> 143 expected
Line 1,429: Line 1,429:


=={{header|Phix}}==
=={{header|Phix}}==
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">check</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">fid</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">range</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">iterations</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">delta</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">check</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">fid</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">range</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">iterations</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">delta</span><span style="color: #0000FF;">)</span>
Line 1,466: Line 1,466:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d iterations: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">flats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">flat</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d iterations: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">flats</span><span style="color: #0000FF;">[</span><span style="color: #000000;">flat</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 1,487: Line 1,487:
(one-tenth of a percent), and a 'prg' code body (i.e. an arbitrary number of
(one-tenth of a percent), and a 'prg' code body (i.e. an arbitrary number of
executable expressions).
executable expressions).
<lang PicoLisp>(de checkDistribution (Cnt Pm . Prg)
<syntaxhighlight lang="picolisp">(de checkDistribution (Cnt Pm . Prg)
(let Res NIL
(let Res NIL
(do Cnt (accu 'Res (run Prg 1) 1))
(do Cnt (accu 'Res (run Prg 1) 1))
Line 1,495: Line 1,495:
Max (*/ N (+ 1000 Pm) 1000) )
Max (*/ N (+ 1000 Pm) 1000) )
(for R Res
(for R Res
(prinl (cdr R) " " (if (>= Max (cdr R) Min) "Good" "Bad")) ) ) ) )</lang>
(prinl (cdr R) " " (if (>= Max (cdr R) Min) "Good" "Bad")) ) ) ) )</syntaxhighlight>
Output:
Output:
<pre>: (checkDistribution 100000 5 (rand 1 7))
<pre>: (checkDistribution 100000 5 (rand 1 7))
Line 1,507: Line 1,507:


=={{header|PureBasic}}==
=={{header|PureBasic}}==
<lang PureBasic>Prototype RandNum_prt()
<syntaxhighlight lang="purebasic">Prototype RandNum_prt()


Procedure.s distcheck(*function.RandNum_prt, repetitions, delta.d)
Procedure.s distcheck(*function.RandNum_prt, repetitions, delta.d)
Line 1,537: Line 1,537:
EndProcedure
EndProcedure


MessageRequester("Results", distcheck(@dice7(), 1000000, 0.20))</lang>
MessageRequester("Results", distcheck(@dice7(), 1000000, 0.20))</syntaxhighlight>
A small delta was chosen to increase the chance of a skewed result in the sample output:
A small delta was chosen to increase the chance of a skewed result in the sample output:
<pre>Distribution check:
<pre>Distribution check:
Line 1,550: Line 1,550:
=={{header|Python}}==
=={{header|Python}}==
{{works with|Python|3.1}}
{{works with|Python|3.1}}
<lang python>from collections import Counter
<syntaxhighlight lang="python">from collections import Counter
from pprint import pprint as pp
from pprint import pprint as pp


Line 1,565: Line 1,565:
for key, count in sorted(bin.items()) ]
for key, count in sorted(bin.items()) ]
)
)
pp(dict(bin))</lang>
pp(dict(bin))</syntaxhighlight>
Sample output:
Sample output:
<pre>>>> distcheck(dice5, 1000000, 1)
<pre>>>> distcheck(dice5, 1000000, 1)
Line 1,581: Line 1,581:
The word <code>distribution</code> tests a specified word (Quackery function) which should return numbers in the range 1 to 7 inclusive. The word <code>dice7</code>, which satisfies this requirement, is defined at [[Seven-sided dice from five-sided dice#Quackery]].
The word <code>distribution</code> tests a specified word (Quackery function) which should return numbers in the range 1 to 7 inclusive. The word <code>dice7</code>, which satisfies this requirement, is defined at [[Seven-sided dice from five-sided dice#Quackery]].


<lang Quackery> [ stack [ 0 0 0 0 0 0 0 ] ] is bins ( --> s )
<syntaxhighlight lang="quackery"> [ stack [ 0 0 0 0 0 0 0 ] ] is bins ( --> s )


[ 7 times
[ 7 times
Line 1,605: Line 1,605:
say "s is sketchy."
say "s is sketchy."
cr ] ]
cr ] ]
2drop temp release ] is distribution ( x n n --> )</lang>
2drop temp release ] is distribution ( x n n --> )</syntaxhighlight>


{{out}}
{{out}}
Line 1,625: Line 1,625:


=={{header|R}}==
=={{header|R}}==
<lang r>distcheck <- function(fn, repetitions=1e4, delta=3)
<syntaxhighlight lang="r">distcheck <- function(fn, repetitions=1e4, delta=3)
{
{
if(is.character(fn))
if(is.character(fn))
Line 1,644: Line 1,644:
data.frame(value=names(counts), counts=as.vector(counts), status=status)
data.frame(value=names(counts), counts=as.vector(counts), status=status)
}
}
distcheck(dice7.vec)</lang>
distcheck(dice7.vec)</syntaxhighlight>


=={{header|Racket}}==
=={{header|Racket}}==
Line 1,651: Line 1,651:
Returns a pair of a boolean stating uniformity and either the "uniform" distribution or a report of the first skew number found.
Returns a pair of a boolean stating uniformity and either the "uniform" distribution or a report of the first skew number found.


<lang racket>#lang racket
<syntaxhighlight lang="racket">#lang racket
(define (pretty-fraction f)
(define (pretty-fraction f)
(if (integer? f) f
(if (integer? f) f
Line 1,687: Line 1,687:
(test-uniformity/naive straight-die 1000 5)
(test-uniformity/naive straight-die 1000 5)
; Test whether a biased die fails:
; Test whether a biased die fails:
(test-uniformity/naive crooked-die 1000 5)</lang>
(test-uniformity/naive crooked-die 1000 5)</syntaxhighlight>


{{out}}
{{out}}
Line 1,697: Line 1,697:
(formerly Perl 6)
(formerly Perl 6)
Since the tested function is rolls of a 7 sided die, the test numbers are magnitudes of 10<sup>x</sup> bumped up to the closest multiple of 7. This reduces spurious error from there not being an integer expected value.
Since the tested function is rolls of a 7 sided die, the test numbers are magnitudes of 10<sup>x</sup> bumped up to the closest multiple of 7. This reduces spurious error from there not being an integer expected value.
<lang perl6>my $d7 = 1..7;
<syntaxhighlight lang="raku" line>my $d7 = 1..7;
sub roll7 { $d7.roll };
sub roll7 { $d7.roll };


Line 1,721: Line 1,721:
}
}
say '';
say '';
}</lang>
}</syntaxhighlight>
Sample output:
Sample output:
<pre>
<pre>
Line 1,780: Line 1,780:


=={{header|REXX}}==
=={{header|REXX}}==
<lang rexx>/*REXX program simulates a number of trials of a random digit and show it's skew %. */
<syntaxhighlight lang="rexx">/*REXX program simulates a number of trials of a random digit and show it's skew %. */
parse arg func times delta seed . /*obtain arguments (options) from C.L. */
parse arg func times delta seed . /*obtain arguments (options) from C.L. */
if func=='' | func=="," then func= 'RANDOM' /*function not specified? Use default.*/
if func=='' | func=="," then func= 'RANDOM' /*function not specified? Use default.*/
Line 1,813: Line 1,813:
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: parse arg _; do jc=length(_)-3 to 1 by -3; _=insert(',', _, jc); end; return _
commas: parse arg _; do jc=length(_)-3 to 1 by -3; _=insert(',', _, jc); end; return _
sep: say pad '─────' center('', w, '─') '──────' "──────" '──────'; return</lang>
sep: say pad '─────' center('', w, '─') '──────' "──────" '──────'; return</syntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
<pre>
Line 1,834: Line 1,834:


=={{header|Ring}}==
=={{header|Ring}}==
<lang ring>
<syntaxhighlight lang="ring">
# Project : Verify distribution uniformity/Naive
# Project : Verify distribution uniformity/Naive


Line 1,865: Line 1,865:
func dice5
func dice5
return random(5)
return random(5)
</syntaxhighlight>
</lang>
Output:
Output:
<pre>
<pre>
Line 1,876: Line 1,876:
=={{header|Ruby}}==
=={{header|Ruby}}==
{{trans|Tcl}}
{{trans|Tcl}}
<lang ruby>def distcheck(n, delta=1)
<syntaxhighlight lang="ruby">def distcheck(n, delta=1)
unless block_given?
unless block_given?
raise ArgumentError, "pass a block to this method"
raise ArgumentError, "pass a block to this method"
Line 1,902: Line 1,902:
p e
p e
end
end
end</lang>
end</syntaxhighlight>


{{out}}
{{out}}
Line 1,919: Line 1,919:


=={{header|Run BASIC}}==
=={{header|Run BASIC}}==
<lang runbasic>s$ = "#########################"
<syntaxhighlight lang="runbasic">s$ = "#########################"
dim num(100)
dim num(100)
for i = 1 to 1000
for i = 1 to 1000
Line 1,928: Line 1,928:
for i = 1 to 10
for i = 1 to 10
print using("###",i);" "; using("#####",num(i));" ";left$(s$,num(i) / 5)
print using("###",i);" "; using("#####",num(i));" ";left$(s$,num(i) / 5)
next i</lang><pre>
next i</syntaxhighlight><pre>
1 90 ##################
1 90 ##################
2 110 ######################
2 110 ######################
Line 1,942: Line 1,942:
=={{header|Scala}}==
=={{header|Scala}}==
===Imperative, ugly, mutable data===
===Imperative, ugly, mutable data===
<lang Scala>object DistrubCheck1 extends App {
<syntaxhighlight lang="scala">object DistrubCheck1 extends App {


private def distCheck(f: () => Int, nRepeats: Int, delta: Double): Unit = {
private def distCheck(f: () => Int, nRepeats: Int, delta: Double): Unit = {
Line 1,965: Line 1,965:
distCheck(() => 1 + util.Random.nextInt(5), 1_000_000, 1)
distCheck(() => 1 + util.Random.nextInt(5), 1_000_000, 1)


}</lang>
}</syntaxhighlight>


===Functional Style===
===Functional Style===
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/oYJWUvX/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/O513W3VoQ7ulspUMnGvTiQ Scastie (remote JVM)].
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/oYJWUvX/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/O513W3VoQ7ulspUMnGvTiQ Scastie (remote JVM)].
<lang Scala>object DistrubCheck2 extends App {
<syntaxhighlight lang="scala">object DistrubCheck2 extends App {
private def distCheck(f: () => Int, nRepeats: Int, delta: Double): Unit = {
private def distCheck(f: () => Int, nRepeats: Int, delta: Double): Unit = {
val counts: Map[Int, Int] =
val counts: Map[Int, Int] =
Line 1,983: Line 1,983:
distCheck(() => 1 + util.Random.nextInt(5), 1_000_000, 1)
distCheck(() => 1 + util.Random.nextInt(5), 1_000_000, 1)


}</lang>
}</syntaxhighlight>


=={{header|Tcl}}==
=={{header|Tcl}}==
<lang tcl>proc distcheck {random times {delta 1}} {
<syntaxhighlight lang="tcl">proc distcheck {random times {delta 1}} {
for {set i 0} {$i<$times} {incr i} {incr vals([uplevel 1 $random])}
for {set i 0} {$i<$times} {incr i} {incr vals([uplevel 1 $random])}
set target [expr {$times / [array size vals]}]
set target [expr {$times / [array size vals]}]
Line 1,996: Line 1,996:
foreach k [lsort -integer [array names vals]] {lappend result $k $vals($k)}
foreach k [lsort -integer [array names vals]] {lappend result $k $vals($k)}
return $result
return $result
}</lang>
}</syntaxhighlight>
Demonstration:
Demonstration:
<lang tcl># First, a uniformly distributed random variable
<syntaxhighlight lang="tcl"># First, a uniformly distributed random variable
puts [distcheck {expr {int(10*rand())}} 100000]
puts [distcheck {expr {int(10*rand())}} 100000]


# Now, one that definitely isn't!
# Now, one that definitely isn't!
puts [distcheck {expr {rand()>0.95}} 100000]</lang>
puts [distcheck {expr {rand()>0.95}} 100000]</syntaxhighlight>
Which produces this output (error in red):
Which produces this output (error in red):
0 10003 1 9851 2 10058 3 10193 4 10126 5 10002 6 9852 7 9964 8 9957 9 9994
0 10003 1 9851 2 10058 3 10193 4 10126 5 10002 6 9852 7 9964 8 9957 9 9994
Line 2,008: Line 2,008:


=={{header|VBScript}}==
=={{header|VBScript}}==
<lang vb>Option Explicit
<syntaxhighlight lang="vb">Option Explicit


sub verifydistribution(calledfunction, samples, delta)
sub verifydistribution(calledfunction, samples, delta)
Line 2,031: Line 2,031:
& ", desired limit is " & FormatPercent(delta, 2) & "."
& ", desired limit is " & FormatPercent(delta, 2) & "."
if maxdiff > delta then wscript.echo "Skewed!" else wscript.echo "Smooth!"
if maxdiff > delta then wscript.echo "Skewed!" else wscript.echo "Smooth!"
end sub</lang>
end sub</syntaxhighlight>
Demonstration with included [[Seven-sided dice from five-sided dice#VBScript]] code:
Demonstration with included [[Seven-sided dice from five-sided dice#VBScript]] code:
<lang vb>verifydistribution "dice7", 1000, 0.03
<syntaxhighlight lang="vb">verifydistribution "dice7", 1000, 0.03
verifydistribution "dice7", 100000, 0.03</lang>
verifydistribution "dice7", 100000, 0.03</syntaxhighlight>
Which produces this output:
Which produces this output:
Running "dice7" 1000 times...
Running "dice7" 1000 times...
Line 2,061: Line 2,061:
=={{header|Vlang}}==
=={{header|Vlang}}==
{{trans|go}}
{{trans|go}}
<lang vlang>import rand
<syntaxhighlight lang="vlang">import rand
import rand.seed
import rand.seed
import math
import math
Line 2,112: Line 2,112:
max, flat_enough = dist_check(dice7, 7, calls, 500)
max, flat_enough = dist_check(dice7, 7, calls, 500)
println("Max delta: $max Flat enough: $flat_enough")
println("Max delta: $max Flat enough: $flat_enough")
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,123: Line 2,123:
{{libheader|Wren-fmt}}
{{libheader|Wren-fmt}}
{{libheader|Wren-sort}}
{{libheader|Wren-sort}}
<lang ecmascript>import "random" for Random
<syntaxhighlight lang="ecmascript">import "random" for Random
import "/fmt" for Fmt
import "/fmt" for Fmt
import "/sort" for Sort
import "/sort" for Sort
Line 2,157: Line 2,157:
checkDist.call(dice5, 1e6, 0.5)
checkDist.call(dice5, 1e6, 0.5)
System.print()
System.print()
checkDist.call(dice5, 1e5, 0.5)</lang>
checkDist.call(dice5, 1e5, 0.5)</syntaxhighlight>


{{out}}
{{out}}
Line 2,189: Line 2,189:
=={{header|zkl}}==
=={{header|zkl}}==
This tests the random spread over 0..9. It starts at 10 samples and doubles the sample size until the spread is within 0.1% of 10% for each bucket.
This tests the random spread over 0..9. It starts at 10 samples and doubles the sample size until the spread is within 0.1% of 10% for each bucket.
<lang zkl>fcn rtest(N){
<syntaxhighlight lang="zkl">fcn rtest(N){
dist:=L(0,0,0,0,0,0,0,0,0,0);
dist:=L(0,0,0,0,0,0,0,0,0,0);
do(N){n:=(0).random(10); dist[n]=dist[n]+1}
do(N){n:=(0).random(10); dist[n]=dist[n]+1}
Line 2,200: Line 2,200:


n:=10;
n:=10;
while(not rtest(n)) {n*=2}</lang>
while(not rtest(n)) {n*=2}</syntaxhighlight>
{{out}}
{{out}}
Reported numbers is the percent that bucket has of all samples.
Reported numbers is the percent that bucket has of all samples.