A generic "ziggurat algorithm" implementation. Fairly rough right now.
There is a lot of room for improvement in findBin0
especially.
It needs a fair amount of cleanup and elimination of redundant
calculation, as well as either a justification for using the simple
findMinFrom
or a proper rootfinding algorithm.
It would also be nice to add (preferably by pulling in an external package) support for numerical integration and differentiation, so that tables can be derived from only a PDF (if the end user is willing to take the performance and accuracy hit for the convenience).
 data Ziggurat v t = Ziggurat {}
 mkZigguratRec :: (RealFloat t, Vector v t, Distribution Uniform t) => Bool > (t > t) > (t > t) > (t > t) > t > Int > (forall m. RVarT m (Int, t)) > Ziggurat v t
 mkZiggurat :: (RealFloat t, Vector v t, Distribution Uniform t) => Bool > (t > t) > (t > t) > (t > t) > t > Int > (forall m. RVarT m (Int, t)) > (forall m. t > RVarT m t) > Ziggurat v t
 mkZiggurat_ :: (RealFloat t, Vector v t, Distribution Uniform t) => Bool > (t > t) > (t > t) > Int > t > t > (forall m. RVarT m (Int, t)) > (forall m. RVarT m t) > Ziggurat v t
 findBin0 :: RealFloat b => Int > (b > b) > (b > b) > (b > b) > b > (b, b)
 runZiggurat :: (Num a, Ord a, Vector v a) => Ziggurat v a > RVarT m a
Documentation
A data structure containing all the data that is needed to implement Marsaglia & Tang's "ziggurat" algorithm for sampling certain kinds of random distributions.
The documentation here is probably not sufficient to tell a user exactly
how to build one of these from scratch, but it is not really intended to
be. There are several helper functions that will build Ziggurat
s.
The pathologically curious may wish to read the runZiggurat
source.
That is the ultimate specification of the semantics of all these fields.
Ziggurat  

(Num t, Ord t, Vector v t) => Distribution (Ziggurat v) t 
mkZigguratRec :: (RealFloat t, Vector v t, Distribution Uniform t) => Bool > (t > t) > (t > t) > (t > t) > t > Int > (forall m. RVarT m (Int, t)) > Ziggurat v tSource
Build a lazy recursive ziggurat. Uses a lazilyconstructed ziggurat as its tail distribution (with another as its tail, ad nauseum).
Arguments:
 flag indicating whether to mirror the distribution
 the (onesided antitone) PDF, not necessarily normalized
 the inverse of the PDF
 the integral of the PDF (definite, from 0)
 the estimated volume under the PDF (from 0 to +infinity)
 the chunk size (number of bins in each layer). 64 seems to perform well in practice.
 an RVar providing the
zGetIU
random tuple
mkZiggurat :: (RealFloat t, Vector v t, Distribution Uniform t) => Bool > (t > t) > (t > t) > (t > t) > t > Int > (forall m. RVarT m (Int, t)) > (forall m. t > RVarT m t) > Ziggurat v tSource
Build the tables to implement the "ziggurat algorithm" devised by Marsaglia & Tang, attempting to automatically compute the R and V values.
Arguments are the same as for mkZigguratRec
, with an additional
argument for the tail distribution as a function of the selected
R value.
mkZiggurat_ :: (RealFloat t, Vector v t, Distribution Uniform t) => Bool > (t > t) > (t > t) > Int > t > t > (forall m. RVarT m (Int, t)) > (forall m. RVarT m t) > Ziggurat v tSource
Build the tables to implement the "ziggurat algorithm" devised by Marsaglia & Tang, attempting to automatically compute the R and V values.
Arguments:
 flag indicating whether to mirror the distribution
 the (onesided antitone) PDF, not necessarily normalized
 the inverse of the PDF
 the number of bins
 R, the x value of the first bin
 V, the volume of each bin
 an RVar providing the
zGetIU
random tuple  an RVar sampling from the tail (the region where x > R)
findBin0 :: RealFloat b => Int > (b > b) > (b > b) > (b > b) > b > (b, b)Source
I suspect this isn't completely right, but it works well so far. Search the distribution for an appropriate R and V.
Arguments:
 Number of bins
 target function (onesided antitone PDF, not necessarily normalized)
 function inverse
 function definite integral (from 0 to _)
 estimate of total volume under function (integral from 0 to infinity)
Result: (R,V)