[Shootout-list] Statistics Ada bench
Pascal Obry
pascal@obry.net
Sat, 19 Mar 2005 08:55:27 +0100
Here is a fixed version of the statistic bench for Ada.
-- $Id: moments-gnat.code,v 1.7 2005/03/15 06:18:00 bfulgham Exp $
-- http://dada.perl.it/shootout/
-- Ada 95 code by C.C.
-- Modified by Pascal Obry on 2005/03/18
-- Annotated Ada Reference Manual ISO/IEC 8652:1995: http://www.ada-auth.org/
with System, Ada.Numerics.Generic_Elementary_Functions;
with Ada.Unchecked_Deallocation;
with Ada.Text_IO; use Ada.Text_IO;
procedure Moments is
type Real is digits Positive'Max (15, System.Max_Digits);
package AF is new Ada.Numerics.Generic_Elementary_Functions (Real);
package RIO is new Ada.Text_IO.Float_IO (Num => Real);
procedure Put
(Item : Real; Fore : Field := 0; Aft : Field := 6;
Exp : Field := 0) renames RIO.Put;
generic
type Item_Type is private;
with function "<=" (X, Y : Item_Type) return Boolean;
type Sequence is array (Integer range <>) of Item_Type;
package Sort_Pkg is
procedure Quick_Sort (S : in out Sequence);
end Sort_Pkg; -- Copied from Southampton Ada MPICH supercomputer bindings
package body Sort_Pkg is
procedure Quick_Sort (S : in out Sequence) is
procedure Sort_Recursive (Lwb, Upb : Integer) is
Pivot : Item_Type := S (Upb);
Front : Integer := Lwb;
Back : Integer := Upb;
Temp : Item_Type;
begin
if Lwb < Upb then
while Front <= Back loop
while not (Pivot <= S (Front)) loop
Front := Front + 1;
end loop;
while not (S (Back) <= Pivot) loop
Back := Back - 1;
end loop;
if Front <= Back then
Temp := S (Front);
S (Front) := S (Back);
S (Back) := Temp;
Front := Front + 1;
Back := Back - 1;
end if;
end loop;
Sort_Recursive (Lwb, Back);
Sort_Recursive (Front, Upb);
end if;
end Sort_Recursive;
begin
Sort_Recursive (S'First, S'Last);
end Quick_Sort;
end Sort_Pkg;
type Real_Array is array (Integer range <>) of Real;
type Real_Array_Ptr is access Real_Array;
procedure Deallocate_Real_Array is new Ada.Unchecked_Deallocation
(Object => Real_Array, Name => Real_Array_Ptr);
package Sort is new Sort_Pkg (Real, "<=" => "<=", Sequence => Real_Array);
Data : Real_Array_Ptr := new Real_Array (1 .. 4_096);
Temp_Array : Real_Array_Ptr;
Dev, D_2, Mean, Median : Real;
Standard_Deviation : Real;
Sum, Avg_Abs_Deviation : Real := 0.0;
Variance, Skew, Kurtosis : Real := 0.0;
M : Natural := 0;
begin
while not End_Of_File loop
M := M + 1;
if M > Data'Last then
Temp_Array := new Real_Array (1 .. Data'Last * 4);
Temp_Array (Data'Range) := Data.all;
Deallocate_Real_Array (Data);
Data := Temp_Array;
end if;
RIO.Get (Item => Data (M));
Sum := Sum + Data (M);
end loop;
Mean := Sum / Real (M);
for K in 1 .. M loop
Dev := Data (K) - Mean;
Avg_Abs_Deviation := Avg_Abs_Deviation + abs Dev;
D_2 := Dev * Dev;
Variance := Variance + D_2;
Skew := Skew + (D_2 * Dev);
Kurtosis := Kurtosis + (D_2 * D_2);
end loop;
Avg_Abs_Deviation := Avg_Abs_Deviation / Real (M);
Variance := Variance / Real (M - 1);
Standard_Deviation := AF.Sqrt (Variance);
if Variance < 10.0 * Real'Model_Epsilon then
Put_Line ("> Reduced accuracy results: 0 = ((Variance/10 + 1) - 1)");
else
Skew := Skew / (Real (M) * Variance * Standard_Deviation);
Kurtosis := -3.0 + Kurtosis / (Real (M) * Variance * Variance);
end if;
Sort.Quick_Sort (S => Data (1 .. M));
if 1 = (M mod 2) then
Median := Data ((M + 1) / 2);
else
Median := (Data (M / 2) + Data (1 + M / 2)) / 2.0;
end if;
Put_Line ("n: " & Integer'Image (M));
Put ("median: "); Put (Median); New_Line;
Put ("mean: "); Put (Mean); New_Line;
Put ("average_deviation: "); Put (Avg_Abs_Deviation); New_Line;
Put ("standard_deviation: "); Put (Standard_Deviation); New_Line;
Put ("variance: "); Put (Variance); New_Line;
Put ("skew: "); Put (Skew); New_Line;
Put ("kurtosis: "); Put (Kurtosis); New_Line;
end Moments;
Pascal.
--
--|------------------------------------------------------
--| Pascal Obry Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--| http://www.obry.org
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595