Verify distribution uniformity/Chi-squared test: Difference between revisions

Line 4:
More information about the <math>\chi^2</math> distribution may be found at
[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}}==
This first sections contains the functions required to compute the Chi-Squared probability.
Line 130 ⟶ 210:
return 0;
}</lang>
 
=={{header|D}}==
<lang d>import std.stdio, std.algorithm, std.mathspecial;
Anonymous user