Verify distribution uniformity/Chi-squared test: Difference between revisions
Content added Content deleted
Line 4: | Line 4: | ||
More information about the <math>\chi^2</math> distribution may be found at |
More information about the <math>\chi^2</math> distribution may be found at |
||
[http://mathworld.wolfram.com/Chi-SquaredDistribution.html mathworld]. |
[http://mathworld.wolfram.com/Chi-SquaredDistribution.html mathworld]. |
||
=={{header|Ada}}== |
|||
First, we specifay a simple package to compute the Chi-Square Distance from the uniform distribution: |
|||
<lang Ada>package Chi_Square is |
|||
type Flt is digits 18; |
|||
type Bins_Type is array(Positive range <>) of Natural; |
|||
function Distance(Bins: Bins_Type) return Flt; |
|||
end Chi_Square;</lang> |
|||
Next, we implement that package: |
|||
<lang Ada>package body Chi_Square is |
|||
function Distance(Bins: Bins_Type) return Flt is |
|||
Bad_Bins: Natural := 0; |
|||
Sum: Natural := 0; |
|||
Expected: Flt; |
|||
Result: Flt; |
|||
begin |
|||
for I in Bins'Range loop |
|||
if Bins(I) < 5 then |
|||
Bad_Bins := Bad_Bins + 1; |
|||
end if; |
|||
Sum := Sum + Bins(I); |
|||
end loop; |
|||
if 5*Bad_Bins > Bins'Length then |
|||
raise Program_Error with "too many (almost) empty bins"; |
|||
end if; |
|||
Expected := Flt(Sum) / Flt(Bins'Length); |
|||
Result := 0.0; |
|||
for I in Bins'Range loop |
|||
Result := Result + ((Flt(Bins(I)) - Expected)**2) / Expected; |
|||
end loop; |
|||
return Result; |
|||
end Distance; |
|||
end Chi_Square;</lang> |
|||
Finally, we actually implement the Chi-square test. We do not actually compute the Chi-square probability; rather we hardcode a table of values for 5% significance level, which has been picked from Wikipedia [http://en.wikipedia.org/wiki/Chi-squared_distribution]: |
|||
<lang Ada>with Ada.Text_IO, Ada.Command_Line, Chi_Square; use Ada.Text_IO; |
|||
procedure Test_Chi_Square is |
|||
package Ch2 renames Chi_Square; use Ch2; |
|||
package FIO is new Float_IO(Flt); |
|||
B: Bins_Type(1 .. Ada.Command_Line.Argument_Count); |
|||
Bound_For_5_Per_Cent: constant array(Positive range <>) of Flt := |
|||
( 1 => 3.84, 2 => 5.99, 3 => 7.82, 4 => 9.49, 5 => 11.07, |
|||
6 => 12.59, 7 => 14.07, 8 => 15.51, 9 => 16.92, 10 => 18.31); |
|||
-- picked from http://en.wikipedia.org/wiki/Chi-squared_distribution |
|||
Dist: Flt; |
|||
begin |
|||
for I in B'Range loop |
|||
B(I) := Natural'Value(Ada.Command_Line.Argument(I)); |
|||
end loop; |
|||
Dist := Distance(B); |
|||
Put("Degrees of Freedom:" & Integer'Image(B'Length-1) & ", Distance: "); |
|||
FIO.Put(Dist, Fore => 6, Aft => 2, Exp => 0); |
|||
if Dist <= Bound_For_5_Per_Cent(B'Length-1) then |
|||
Put_Line("; (apparently uniform)"); |
|||
else |
|||
Put_Line("; (deviates significantly from uniform)"); |
|||
end if; |
|||
end;</lang> |
|||
{{out}} |
|||
<pre>$ ./Test_Chi_Square 199809 200665 199607 200270 199649 |
|||
Degrees of Freedom: 4, Distance: 4.15; (apparently uniform) |
|||
$ ./Test_Chi_Square 522573 244456 139979 71531 21461 |
|||
Degrees of Freedom: 4, Distance: 790063.28; (deviates significantly from uniform)</pre> |
|||
=={{header|C}}== |
=={{header|C}}== |
||
This first sections contains the functions required to compute the Chi-Squared probability. |
This first sections contains the functions required to compute the Chi-Squared probability. |
||
Line 130: | Line 210: | ||
return 0; |
return 0; |
||
}</lang> |
}</lang> |
||
=={{header|D}}== |
=={{header|D}}== |
||
<lang d>import std.stdio, std.algorithm, std.mathspecial; |
<lang d>import std.stdio, std.algorithm, std.mathspecial; |