EiffelBase class
(HTML page generated by ISE Eiffel 4.2)
Eiffel Class
indexing
description: "Pseudo-random number sequence, linear congruential method";
status: "See notice at end of class";
names: random;
date: "$Date: 2007-03-30 11:10:11 -0800 (Fri, 30 Mar 2007) $";
revision: "$Revision: 95354 $"
class RANDOM
inherit
COUNTABLE_SEQUENCE [INTEGER]
redefine
has
end;
DOUBLE_MATH
export
{NONE} all
end
creation
make,
set_seed
feature -- Initialization
make is
-- Initialize structure using a default seed.
do
set_seed (default_seed)
ensure
seed_set: seed = default_seed
end;
set_seed (s: INTEGER) is
-- Initialize sequence using s as the seed.
require
non_negative: s >= 0
do
seed := s;
last_result := seed;
last_item := 0
ensure
seed_set: seed = s
end;
feature -- Access
default_seed: INTEGER is
-- Default value 123,457;
-- may be redefined for a new generator.
once
Result := 123457
end;
modulus: INTEGER is
-- Default value 2^31 -1 = 2,147,483,647;
-- may be redefined for a new generator.
once
Result := 2147483647
end;
multiplier: INTEGER is
-- Default value 7^5 = 16,807;
-- may be redefined for a new generator.
once
Result := 16807
end;
increment: INTEGER is
-- Default value 0;
-- may be redefined for a new generator.
once
Result := 0
end;
seed: INTEGER;
-- Seed for sequence.
next_random (n: INTEGER): INTEGER is
-- Next random number after n
-- in pseudo-random order
require
in_range: (n < modulus) and (n >= 0)
do
Result := randomize (n)
ensure
in_range: (Result < modulus) and (Result >= 0)
end;
has (n: INTEGER): BOOLEAN is
-- Will n be part of the random number sequence?
do
Result := (n < modulus) and (n >= 0)
ensure
only_: Result = (n < modulus and n >= 0)
end;
i_th (i: INTEGER): INTEGER is
-- The i-th random number
local
count: INTEGER
do
if i >= last_item then
Result := last_result;
count := last_item
else
Result := seed
end;
from
until
count = i
loop
Result := randomize (Result);
count := count + 1
end;
last_result := Result;
last_item := i
ensure
in_range: (Result < modulus) and (Result >= 0)
end;
real_item: REAL is
-- The current random number as a real between 0 and 1
local
r1, r2: REAL
do
r1 := item;
r2 := modulus;
Result := r1 / r2
end;
double_item: DOUBLE is
-- The current random number as a double between 0 and 1
local
d: DOUBLE
do
d := item;
Result := d / dmod
end;
real_i_th (i: INTEGER): REAL is
-- The i-th random number as a real between 0 and 1
local
r1, r2: REAL
do
r1 := i_th (i);
r2 := modulus;
Result := r1 / r2
end;
double_i_th (i: INTEGER): DOUBLE is
-- The i-th random number as a double between 0 and 1
local
d: DOUBLE
do
d := i_th (i);
Result := d / dmod
end;
feature {NONE} -- Implementation
randomize (xn: INTEGER): INTEGER is
-- Next item
local
x: DOUBLE
do
x := double_mod (dmul * xn + dinc, dmod);
Result := x.truncated_to_integer
end;
double_mod (x, m: DOUBLE): DOUBLE is
-- x modulo m
do
Result := x - (floor (x / m) * m)
end;
last_item: INTEGER;
-- Last item requested
last_result: INTEGER;
-- Value from last call to item
dmod: DOUBLE is
-- Double value for modulus
once
Result := modulus
end;
dmul: DOUBLE is
-- Double value for multiplier
once
Result := multiplier
end;
dinc: DOUBLE is
-- Double value for increment
once
Result := increment
end;
invariant
non_negative_seed: seed >= 0;
non_negative_increment: increment >= 0;
positive_multiplier: multiplier > 0;
modulus_constraint: modulus > 1;
end -- class RANDOM
|