--------------------------------------------------------------------------
-- The following is an implementation of a "universal" random number --
-- generator algorithm developed by Dr. George Marsaglia of the --
-- Supercomputer Computations Research Institute (SCRI) at Florida --
-- State University. This generator has a period of ~2**144 and has --
-- been tailored for reproducibility in all CPU's with at least --
-- 16 bit integer arithmetic and 24 bit floating point. This algorithm --
-- does not generate random numbers < 2**-24. At the end of this file --
-- you will find a self test program that checks generated results --
-- against known expected results and reports any inaccuracies. --
-- --
-- Further references: "Toward a Universal Random Number Generator", --
-- appearing in the Journal of The American Statistical Association. --
-- --
-- This code appeared in the March/April publication of SIGAda's --
-- Ada Letters and is considered public domain. PCK --
--------------------------------------------------------------------------
--
-- Jul-2009: GdM: - Made generic and task safe: no more globals
-- - Procedure name aliases to make the replacement
-- of Ada95+'s Ada.Numerics.Float_Random easy.
-- Mar-1988: Published in Ada Letters (Volume VIII, Number 2)
generic
type Real is digits <>;
package U_Rand is
subtype Uniformly_Distributed is Real range 0.0 .. 1.0;
--
-- ^ also useful to have a type to refer to, when using
-- this random generator instead of Ada.Numerics.Float_Random
M1 : constant := 179 ;
M2 : constant := M1 - 10 ;
subtype SEED_RANGE_1 is Integer range 1..M1-1 ;
subtype SEED_RANGE_2 is Integer range 1..M2-1 ;
Default_I : constant SEED_RANGE_1 := 12 ;
Default_J : constant SEED_RANGE_1 := 34 ;
Default_K : constant SEED_RANGE_1 := 56 ;
Default_L : constant SEED_RANGE_1 := 78 ;
type Generator is limited private;
----------------------------------------------------
-- Initialization of the pseudo-random sequence --
----------------------------------------------------
-- Fixed seed initialization
--
procedure Start(Gen : out Generator;
New_I : SEED_RANGE_1 := Default_I ;
New_J : SEED_RANGE_1 := Default_J ;
New_K : SEED_RANGE_1 := Default_K ;
New_L : SEED_RANGE_2 := Default_L
) ;
subtype Seed_range_for_Reset is Integer range 0 .. ((M1-1) ** 3) * (M2-1) - 1;
-- NB: concretely, the range is: 0 .. 947'478'337
-- Generator initialization, compatible with Ada 95+
procedure Reset (Gen : out Generator; Initiator : Seed_range_for_Reset);
-- Randomize with real-time clock
--
procedure Randomize (Gen : out Generator);
procedure Reset (Gen : out Generator) renames Randomize; -- Ada 95+ style
-----------------------------------------------
-- Obtaining the next pseudo-random number --
-----------------------------------------------
--
function Next(Gen: Generator) return Uniformly_Distributed;
pragma Inline(Next);
function Random(Gen: Generator) return Uniformly_Distributed renames Next; -- Ada 95 style
private
M3 : constant := 97 ;
subtype RANGE_3 is Integer range 1..M3 ;
type U_array is array(RANGE_3) of Real;
type Generator is limited record
NI, NJ : Integer ;
C : Real ;
U : U_array;
end record;
end U_Rand ;