buffon-machines-1.1.0.0: Perfect simulation of discrete random variables

Data.Buffon.Machine

Description

• Buffon machines* is a simple, monadic implementation of Buffon machines [1] meant for *perfect* simulation of discrete random variables using a discrete oracle of random bits. Buffon machines are implemented as monadic computations consuming random bits, provided by a 32-bit buffered oracle. Bit regeneration and computation composition is handled within the monad itself.

The main purpose of *Buffon machines* is to provide an experimental framework for discrete random variable generation required in the design and implementation of various combinatorial samplers, such as analytic samplers (a.k.a. Boltzmann samplers). In particular, its goal is to provide tools to *perfectly* simulate discrete distributions using as few random bits as possible.

The current implementation provides several basic generators discussed in [1]. In particular, it offers perfect generators for geometric, Poisson, and logarithmic distributions with given rational or real (i.e. double-precision floating) parameters, as well as a bit-optimal discrete uniform variable and Bernoulli generators described in [2]. More involved Buffon machines can be compiled using the provided combinators.

General, non-uniform discrete variable generation, in the spirit of Knuth and Yao [3], is also available. However, it should be noted that the current implementation does not achieve optimal average bit consumption, except for a limited number of special cases.

References:

1
Ph. Flajolet, M. Pelletier, M. Soria : “On Buffon Machines and Numbers”, SODA'11 - ACM/SIAM Symposium on Discrete Algorithms, San Francisco, USA, pp. 172-183, (Society for Industrial and Applied Mathematics) (2011)
2
J. Lumbroso : "Optimal Discrete Uniform Generation from Coin Flips, and Applications".
3
D. Knuth, A. Yao : "The complexity of nonuniform random number generation", in Algorithms and Complexity: New Directions and Recent Results, Academic Press, (1976)
Synopsis

# Buffon machines and related utilities.

data Rand g Source #

32-bit buffered random bit generator (RBG).

Constructors

 Rand Fieldsbuffer :: !Word32Generator buffer.counter :: !IntNumber of consumed buffer bits.oracle :: !gRandom bit oracle.

empty :: Rand g -> Bool Source #

Checks if the given RBG is empty or not. In other words, if a buffer refill is required.

init :: RandomGen g => g -> Rand g Source #

A fresh RBG.

newtype BuffonMachine g a Source #

Computations consuming random bits using RBGs. Note that the implementation is essentially a State monad, passing RNG throughout its computations.

Constructors

 BuffonMachine FieldsrunR :: Rand g -> (a, Rand g)
Instances
 Source # Instance detailsDefined in Data.Buffon.Machine Methods(>>=) :: BuffonMachine g a -> (a -> BuffonMachine g b) -> BuffonMachine g b #(>>) :: BuffonMachine g a -> BuffonMachine g b -> BuffonMachine g b #return :: a -> BuffonMachine g a #fail :: String -> BuffonMachine g a # Source # Instance detailsDefined in Data.Buffon.Machine Methodsfmap :: (a -> b) -> BuffonMachine g a -> BuffonMachine g b #(<\$) :: a -> BuffonMachine g b -> BuffonMachine g a # Source # Instance detailsDefined in Data.Buffon.Machine Methodspure :: a -> BuffonMachine g a #(<*>) :: BuffonMachine g (a -> b) -> BuffonMachine g a -> BuffonMachine g b #liftA2 :: (a -> b -> c) -> BuffonMachine g a -> BuffonMachine g b -> BuffonMachine g c #(*>) :: BuffonMachine g a -> BuffonMachine g b -> BuffonMachine g b #(<*) :: BuffonMachine g a -> BuffonMachine g b -> BuffonMachine g a #

Runs the given Buffon machine within the IO monad using StdGen as its random bit oracle.

histogram :: RandomGen g => Discrete g -> Int -> BuffonMachine g [(Int, Occur)] Source #

Computes a histogram of the given discrete random variable. The variable (Buffon machine) is evaluated n times and the data is collected in form of a multiset occurrence list.

A histogram variant within the IO monad.

samples :: RandomGen g => BuffonMachine g a -> Int -> BuffonMachine g [a] Source #

Using the given discrete variable (Buffon machine) outputs n random samples.

samplesIO :: BuffonMachine StdGen a -> Int -> IO [a] Source #

Runs samples within the IO monad.

samplesIO' :: BuffonMachine StdGen a -> Int -> IO [a] Source #

A space efficient variant of samplesIO.

# Random variables.

type Bern g = BuffonMachine g Bool Source #

Bernoulli variables.

type Discrete g = BuffonMachine g Int Source #

General discrete variables.

Lifts a Bernoulli variable to a discrete one.

# Coin flips.

flip :: RandomGen g => Bern g Source #

Random coin flip. Note that the implementation handles the regeneration of the RBG, see Rand.

flip' :: RandomGen g => Bern g Source #

Fair variant of flip. Implements the following, standard trick. Use flip twice and continue if and only if both coin flips yield the same bits. Although such a trick yields a truly fair coin flip, it should be noted that the standard flip is reasonably fair (and at the same time more efficient).

# Bernoulli variable generators.

rational :: RandomGen g => Int -> Int -> Bern g Source #

Given parameters a < b, both positive, returns a Bernoulli variable with rational parameter λ = a/b. Note: Implements the algorithm Bernoulli described by J. Lumbroso.

real :: RandomGen g => Double -> Bern g Source #

Bernoulli variable with the given double-precision parameter. Note: the given parameter has to lie within 0 and 1 as otherwise the outcome is undefined.

# Buffon machine combinators.

repeat :: RandomGen g => Int -> Bern g -> BuffonMachine g [Bool] Source #

Evaluates the given Bernoulli variable n times and returns a list of resulting values.

Arguments

 :: Bern g 'if' condition ... -> BuffonMachine g a ... 'then' expression ... -> BuffonMachine g a ... 'else' expression. -> BuffonMachine g a

Conditional if-then-else combinator.

neg :: Bern g -> Bern g Source #

Negation combinator.

(/\) :: Bern g -> Bern g -> Bern g Source #

Conjunction combinator.

(\/) :: Bern g -> Bern g -> Bern g Source #

Disjunction combinator.

square :: Bern g -> Bern g Source #

Squaring combinator.

mean :: RandomGen g => BuffonMachine g a -> BuffonMachine g a -> BuffonMachine g a Source #

Mean combinator.

even :: RandomGen g => Bern g -> Bern g Source #

Even-parity combinator.

exp :: RandomGen g => Bern g -> Bern g Source #

Given a Bernoulli variable with parameter λ realises a Bernoulli variable with the parameter exp(-λ).

recipLog :: RandomGen g => Bern g -> Bern g Source #

Given a Bernoulli variable with parameter λ realises a Bernoulli variable with the parameter λ/(log(1-λ)^{-1}).

# Discrete variable generators.

geometric :: Bern g -> Discrete g Source #

Given a Bernoulli variable with parameter λ, realises a geometric variable with the same parameter λ.

A variant of geometric using the real Bernoulli generator.

A variant of geometric using the rational Bernoulli generator.

Arguments

 :: RandomGen g => ([Int] -> Bool) Permutation tester. -> Discrete g Geometric variable (Buffon machine). -> Discrete g

General, von Neumann generation scheme.

poisson :: RandomGen g => Discrete g -> Discrete g Source #

Given a geometric variable with parameter λ realises a Poisson variable with the same parameter λ. Note: the parameter λ has to lie within (0,1).

Given a geometric variable with parameter λ realises a Poisson variable with the same parameter λ. Note: the current implementation is linear in the parameter λ.

Poisson distribution with the given double-precision parameter.

Given two positive and relatively prime integers p and q realises a Poisson variable with the paramter p/q.

logarithmic :: RandomGen g => Discrete g -> Discrete g Source #

Given a geometric variable with parameter λ realises a logarithmic variable with the same parameter λ.

Logarithmic distribution with the given double-precision parameter.

Given two positive and relatively prime integers p and q realises a logarithmic variable with the paramter p/q.

# Uniform variable generator.

uniform :: RandomGen g => Int -> Discrete g Source #

Uniform random variable with support {0,1,...,n-1}. Note: uniform is an implementation of the FastDiceRoller algorithm described by J. Lumbroso.

# Non-uniform variable generator.

data DecisionTree a Source #

Decision trees.

Constructors

 Decision a Toss (DecisionTree a) (DecisionTree a)
Instances
 Show a => Show (DecisionTree a) Source # Instance detailsDefined in Data.Buffon.Machine MethodsshowsPrec :: Int -> DecisionTree a -> ShowS #show :: DecisionTree a -> String #showList :: [DecisionTree a] -> ShowS # Lift a => Lift (DecisionTree a) Source # Instance detailsDefined in Data.Buffon.Machine Methodslift :: DecisionTree a -> Q Exp #

Computes a decition tree for the given set of probabilities corresponding to successive outcomes 0,1,...,n-1. Note: the outcome decision tree is not guaranteed to be optimal, in the sense that it minimises the average-case bit consumption. Also, the final probability corresponding to the outcome n is computed automatically, so that it holds p_1 + ... + p_n = 1.

unveil :: Show a => Int -> DecisionTree a -> String Source #

Returns a string representation of a suitably truncated variant of the given decision tree up to the given depth parameter.

Computes the maximal number of flips required to make a definite decision for the given tree.

Computes the minimal number of flips required to make a definite decision for the given tree.

Computes the average-case number of flips required to make a definite decision for the given tree.

choice :: RandomGen g => DecisionTree a -> BuffonMachine g a Source #

Draws a discrete variable according to the given decision tree.