NAME¶
Data::Entropy::Algorithms - basic entropy-using algorithms
SYNOPSIS¶
use Data::Entropy::Algorithms
qw(rand_bits rand_int rand_prob);
$str = rand_bits(17);
$i = rand_int(12345);
$i = rand_int(Math::BigInt->new("1000000000000"));
$j = rand_prob(1, 2, 3);
$j = rand_prob([ 1, 2, 3 ]);
use Data::Entropy::Algorithms qw(rand_fix rand rand_flt);
$x = rand_fix(48);
$x = rand(7);
$x = rand_flt(0.0, 7.0);
use Data::Entropy::Algorithms
qw(pick pick_r choose choose_r shuffle shuffle_r);
$item = pick($item0, $item1, $item2);
$item = pick_r(\@items);
@chosen = choose(3, $item0, $item1, $item2, $item3, $item4);
$chosen = choose_r(3, \@items);
@shuffled = shuffle($item0, $item1, $item2, $item3, $item4);
$shuffled = shuffle_r(\@items);
DESCRIPTION¶
This module contains a collection of fundamental algorithms that use entropy.
They all use the entropy source mechanism described in Data::Entropy.
FUNCTIONS¶
All of these functions use entropy. The entropy source is not an explicit input
in any case. All functions use the current entropy source maintained by the
"Data::Entropy" module. To select an entropy source use the
"with_entropy_source" function in that module, or alternatively do
nothing to use the default source.
- rand_bits(NBITS)
- Returns NBITS bits of entropy, as a string of octets. If
NBITS is not a multiple of eight then the last octet in the string has its
most significant bits set to zero.
- rand_int(LIMIT)
- LIMIT must be a positive integer. Returns a
uniformly-distributed random integer in the range [0, LIMIT). LIMIT may be
either a native integer, a "Math::BigInt" object, or an
integer-valued "Math::BigRat" object; the returned number is of
the same type.
- rand_prob(PROB ...)
- rand_prob(PROBS)
- Returns a random integer selected with non-uniform
probability. The relative probabilities are supplied as a list of
non-negative integers (multiple PROB arguments) or a reference to an array
of integers (the PROBS argument). The relative probabilities may be native
integers, "Math::BigInt" objects, or integer-valued
"Math::BigRat" objects; they must all be of the same type. At
least one probability value must be positive.
The first relative probability value (the first PROB or the first element of
PROBS) is the relative probability of returning 0. The absolute
probability of returning 0 is this value divided by the total of all the
relative probability values. Similarly the second value controls the
probability of returning 1, and so on.
Numbers¶
- rand_fix(NBITS)
- Returns a uniformly-distributed random NBITS-bit
fixed-point fraction in the range [0, 1). That is, the result is a
randomly-chosen multiple of 2^-NBITS, the multiplier being a random
integer in the range [0, 2^NBITS). The value is returned in the form of a
native floating point number, so NBITS can be at most one greater than the
number of bits of significand in the floating point format.
With NBITS = 48 the range of output values is the same as that of the Unix
"drand48" function.
- rand([LIMIT])
- Generates a random fixed-point fraction by
"rand_fix" and then multiplies it by LIMIT, returning the
result. LIMIT defaults to 1, and if it is 0 then that is also treated as
1. The length of the fixed-point fraction is 48 bits, unless that can't be
represented in the native floating point type, in which case the longest
possible fraction will be generated instead.
This is a drop-in replacement for "CORE::rand": it produces
exactly the same range of output values, but using the current entropy
source instead of a sucky PRNG with linear relationships between
successive outputs. ("CORE::rand" does the type of calculation
described, but using the PRNG "drand48" to generate the
fixed-point fraction.) The details of behaviour may change in the future
if the behaviour of "CORE::rand" changes, to maintain the match.
Where the source of a module can't be readily modified, it can be made to
use this "rand" by an incantation such as
*Foreign::Module::rand = \&Data::Entropy::Algorithms::rand;
This must be done before the module is loaded, most likely in a
"BEGIN" block. It is also possible to override
"CORE::rand" for all modules, by performing this similarly
early:
*CORE::GLOBAL::rand = \&Data::Entropy::Algorithms::rand;
This function should not be used in any new code, because the kind of output
supplied by "rand" is hardly ever the right thing to use. The
"int(rand($n))" idiom to generate a random integer has
non-uniform probabilities of generating each possible value, except when
$n is a power of two. For floating point numbers, "rand" can't
generate most representable numbers in its output range, and the output is
biased towards zero. In new code use "rand_int" to generate
integers and "rand_flt" to generate floating point numbers.
- rand_flt(MIN, MAX)
- Selects a uniformly-distributed real number (with infinite
precision) in the range [MIN, MAX] and then rounds this number to the
nearest representable floating point value, which it returns. (Actually it
is only as if the function worked this way: in fact it never
generates the number with infinite precision. It selects between the
representable floating point values with the probabilities implied by this
process.)
This can return absolutely any floating point value in the range [MIN, MAX];
both MIN and MAX themselves are possible return values. All bits of the
floating point type are filled randomly, so the range of values that can
be returned depends on the details of the floating point format. (See
Data::Float for low-level floating point utilities.)
The function "die"s if MIN and MAX are not both finite. If MIN is
greater than MAX then their roles are swapped: the order of the limit
parameters actually doesn't matter. If the limits are identical then that
value is always returned. As a special case, if the limits are positive
zero and negative zero then a zero will be returned with a randomly-chosen
sign.
Combinatorics¶
- pick(ITEM ...)
- Randomly selects and returns one of the ITEMs. Each ITEM
has equal probability of being selected.
- pick_r(ITEMS)
- ITEMS must be a reference to an array. Randomly selects and
returns one of the elements of the array. Each element has equal
probability of being selected.
This is the same operation as that performed by "pick", but using
references to avoid expensive copying of arrays.
- choose(NCHOOSE, ITEM ...)
- Randomly selects NCHOOSE of the ITEMs. Each ITEM has equal
probability of being selected. The chosen items are returned in a list in
the same order in which they appeared in the argument list.
- choose_r(NCHOOSE, ITEMS)
- ITEMS must be a reference to an array. Randomly selects
NCHOOSE of the elements in the array. Each element has equal probability
of being selected. Returns a reference to an array containing the chosen
items in the same order in which they appeared in the input array.
This is the same operation as that performed by "choose", but
using references to avoid expensive copying of arrays.
- shuffle(ITEM ...)
- Reorders the ITEMs randomly, and returns them in a list in
random order. Each possible order has equal probability.
- shuffle_r(ITEMS)
- ITEMS must be a reference to an array. Reorders the
elements of the array randomly. Each possible order has equal probability.
Returns a reference to an array containing the elements in random order.
This is the same operation as that performed by "shuffle", but
using references to avoid expensive copying of arrays.
SEE ALSO¶
Data::Entropy, Data::Entropy::Source
AUTHOR¶
Andrew Main (Zefram) <zefram@fysh.org>
COPYRIGHT¶
Copyright (C) 2006, 2007, 2009, 2011 Andrew Main (Zefram)
<zefram@fysh.org>
LICENSE¶
This module is free software; you can redistribute it and/or modify it under the
same terms as Perl itself.