;;; ----------------------------------------------------------------------------
;;; glib.random.lisp
;;;
;;; This file contains code from a fork of cl-gtk2.
;;; See <http://common-lisp.net/project/cl-gtk2/>.
;;;
;;; The documentation of this file is taken from the GLib 2.38.2 Reference
;;; Manual and modified to document the Lisp binding to the GLib library.
;;; See <http://www.gtk.org>. The API documentation of the Lisp binding is
;;; available from <http://www.crategus.com/books/cl-cffi-gtk/>.
;;;
;;; Copyright (C) 2013, 2014 Dieter Kaiser
;;;
;;; This program is free software: you can redistribute it and/or modify
;;; it under the terms of the GNU Lesser General Public License for Lisp
;;; as published by the Free Software Foundation, either version 3 of the
;;; License, or (at your option) any later version and with a preamble to
;;; the GNU Lesser General Public License that clarifies the terms for use
;;; with Lisp programs and is referred as the LLGPL.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU Lesser General Public License for more details.
;;;
;;; You should have received a copy of the GNU Lesser General Public
;;; License along with this program and the preamble to the Gnu Lesser
;;; General Public License.  If not, see <http://www.gnu.org/licenses/>
;;; and <http://opensource.franz.com/preamble.html>.
;;; ----------------------------------------------------------------------------

;;; Random Numbers - pseudo-random number generator
;;;     
;;; Synopsis
;;; 
;;;     g_rand_new_with_seed
;;;     g_rand_new_with_seed_array
;;;     g_rand_new
;;;     g_rand_copy
;;;     g_rand_free
;;;     g_rand_set_seed
;;;     g_rand_set_seed_array
;;;     g_rand_boolean
;;;     g_rand_int
;;;     g_rand_int_range
;;;     g_rand_double
;;;     g_rand_double_range
;;;     g_random_set_seed
;;;     g_random_boolean
;;;     g_random_int
;;;     g_random_int_range
;;;     g_random_double
;;;     g_random_double_range
;;; 
;;; Description
;;; 
;;; The following functions allow you to use a portable, fast and good
;;; pseudo-random number generator (PRNG). It uses the Mersenne Twister PRNG,
;;; which was originally developed by Makoto Matsumoto and Takuji Nishimura.
;;; Further information can be found at
;;; http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html.
;;; 
;;; If you just need a random number, you simply call the g_random_* functions,
;;; which will create a globally used GRand and use the according g_rand_*
;;; functions internally. Whenever you need a stream of reproducible random
;;; numbers, you better create a GRand yourself and use the g_rand_* functions
;;; directly, which will also be slightly faster. Initializing a GRand with a
;;; certain seed will produce exactly the same series of random numbers on all
;;; platforms. This can thus be used as a seed for e. g. games.
;;; 
;;; The g_rand*_range functions will return high quality equally distributed
;;; random numbers, whereas for example the (g_random_int()%max) approach often
;;; doesn't yield equally distributed numbers.
;;; 
;;; GLib changed the seeding algorithm for the pseudo-random number generator
;;; Mersenne Twister, as used by GRand and GRandom. This was necessary, because
;;; some seeds would yield very bad pseudo-random streams. Also the
;;; pseudo-random integers generated by g_rand*_int_range() will have a slightly
;;; better equal distribution with the new version of GLib.
;;; 
;;; The original seeding and generation algorithms, as found in GLib 2.0.x, can
;;; be used instead of the new ones by setting the environment variable
;;; G_RANDOM_VERSION to the value of '2.0'. Use the GLib-2.0 algorithms only if
;;; you have sequences of numbers generated with Glib-2.0 that you need to
;;; reproduce exactly.
;;; ----------------------------------------------------------------------------

(in-package :glib)

;;; ----------------------------------------------------------------------------
;;; GRand
;;; 
;;; typedef struct _GRand GRand;
;;; 
;;; The GRand struct is an opaque data structure. It should only be accessed
;;; through the g_rand_* functions.
;;; ----------------------------------------------------------------------------

;;; ----------------------------------------------------------------------------
;;; g_rand_new_with_seed ()
;;; 
;;; GRand * g_rand_new_with_seed (guint32 seed);
;;; 
;;; Creates a new random number generator initialized with seed.
;;; 
;;; seed :
;;;     a value to initialize the random number generator.
;;; 
;;; Returns :
;;;     the new GRand.
;;; ----------------------------------------------------------------------------

;;; ----------------------------------------------------------------------------
;;; g_rand_new_with_seed_array ()
;;; 
;;; GRand * g_rand_new_with_seed_array (const guint32 *seed, guint seed_length)
;;; 
;;; Creates a new random number generator initialized with seed.
;;; 
;;; seed :
;;;     an array of seeds to initialize the random number generator.
;;; 
;;; seed_length :
;;;     an array of seeds to initialize the random number generator.
;;; 
;;; Returns :
;;;     the new GRand.
;;; 
;;; Since 2.4
;;; ----------------------------------------------------------------------------

;;; ----------------------------------------------------------------------------
;;; g_rand_new ()
;;; 
;;; GRand * g_rand_new (void);
;;; 
;;; Creates a new random number generator initialized with a seed taken either
;;; from /dev/urandom (if existing) or from the current time (as a fallback).
;;; 
;;; Returns :
;;;     the new GRand.
;;; ----------------------------------------------------------------------------

;;; ----------------------------------------------------------------------------
;;; g_rand_copy ()
;;; 
;;; GRand * g_rand_copy (GRand *rand_);
;;; 
;;; Copies a GRand into a new one with the same exact state as before. This way
;;; you can take a snapshot of the random number generator for replaying later.
;;; 
;;; rand_ :
;;;     a GRand.
;;; 
;;; Returns :
;;;     the new GRand.
;;; 
;;; Since 2.4
;;; ----------------------------------------------------------------------------

;;; ----------------------------------------------------------------------------
;;; g_rand_free ()
;;; 
;;; void g_rand_free (GRand *rand_);
;;; 
;;; Frees the memory allocated for the GRand.
;;; 
;;; rand_ :
;;;     a GRand.
;;; ----------------------------------------------------------------------------

;;; ----------------------------------------------------------------------------
;;; g_rand_set_seed ()
;;; 
;;; void g_rand_set_seed (GRand *rand_, guint32 seed);
;;; 
;;; Sets the seed for the random number generator GRand to seed.
;;; 
;;; rand_ :
;;;     a GRand.
;;; 
;;; seed :
;;;     a value to reinitialize the random number generator.
;;; ----------------------------------------------------------------------------

;;; ----------------------------------------------------------------------------
;;; g_rand_set_seed_array ()
;;; 
;;; void g_rand_set_seed_array (GRand *rand_,
;;;                             const guint32 *seed,
;;;                             guint seed_length);
;;; 
;;; Initializes the random number generator by an array of longs. Array can be
;;; of arbitrary size, though only the first 624 values are taken. This function
;;; is useful if you have many low entropy seeds, or if you require more then
;;; 32bits of actual entropy for your application.
;;; 
;;; rand_ :
;;;     a GRand.
;;; 
;;; seed :
;;;     array to initialize with
;;; 
;;; seed_length :
;;;     length of array
;;; 
;;; Since 2.4
;;; ----------------------------------------------------------------------------

;;; ----------------------------------------------------------------------------
;;; g_rand_boolean()
;;; 
;;; #define g_rand_boolean(rand_)
;;; 
;;; Returns a random gboolean from rand_. This corresponds to a unbiased coin
;;; toss.
;;; 
;;; rand_ :
;;;     a GRand.
;;; 
;;; Returns :
;;;     a random gboolean.
;;; ----------------------------------------------------------------------------

;;; ----------------------------------------------------------------------------
;;; g_rand_int ()
;;; 
;;; guint32 g_rand_int (GRand *rand_);
;;; 
;;; Returns the next random guint32 from rand_ equally distributed over the
;;; range [0..2^32-1].
;;; 
;;; rand_ :
;;;     a GRand.
;;; 
;;; Returns :
;;;     A random number.
;;; ----------------------------------------------------------------------------

;;; ----------------------------------------------------------------------------
;;; g_rand_int_range ()
;;; 
;;; gint32 g_rand_int_range (GRand *rand_, gint32 begin, gint32 end);
;;; 
;;; Returns the next random gint32 from rand_ equally distributed over the range
;;; [begin..end-1].
;;; 
;;; rand_ :
;;;     a GRand.
;;; 
;;; begin :
;;;     lower closed bound of the interval.
;;; 
;;; end :
;;;     upper open bound of the interval.
;;; 
;;; Returns :
;;;     A random number.
;;; ----------------------------------------------------------------------------

;;; ----------------------------------------------------------------------------
;;; g_rand_double ()
;;; 
;;; gdouble g_rand_double (GRand *rand_);
;;; 
;;; Returns the next random gdouble from rand_ equally distributed over the
;;; range [0..1).
;;; 
;;; rand_ :
;;;     a GRand.
;;; 
;;; Returns :
;;;     A random number.
;;; ----------------------------------------------------------------------------

;;; ----------------------------------------------------------------------------
;;; g_rand_double_range ()
;;; 
;;; gdouble g_rand_double_range (GRand *rand_, gdouble begin, gdouble end);
;;; 
;;; Returns the next random gdouble from rand_ equally distributed over the
;;; range [begin..end).
;;; 
;;; rand_ :
;;;     a GRand.
;;; 
;;; begin :
;;;     lower closed bound of the interval.
;;; 
;;; end :
;;;     upper open bound of the interval.
;;; 
;;; Returns :
;;;     A random number.
;;; ----------------------------------------------------------------------------

;;; ----------------------------------------------------------------------------
;;; g_random_set_seed ()
;;; ----------------------------------------------------------------------------

(defcfun ("g_random_set_seed" g-random-set-seed) :void
 #+cl-cffi-gtk-documentation
 "@version{2013-12-13}
  @argument[seed]{a value to reinitialize the global random number generator}
  Sets the seed for the global random number generator, which is used by the
  @code{g-random-*} functions, to seed.
  @see-function{g-random-int}
  @see-function{g-random-int-range}"
  (seed :uint32))
  
(export 'g-random-set-seed)

;;; ----------------------------------------------------------------------------
;;; g_random_boolean
;;; 
;;; #define g_random_boolean()
;;; 
;;; Returns a random gboolean. This corresponds to a unbiased coin toss.
;;; 
;;; Returns :
;;;     a random gboolean.
;;; ----------------------------------------------------------------------------

;;; ----------------------------------------------------------------------------
;;; g_random_int ()
;;; ----------------------------------------------------------------------------

(defcfun ("g_random_int" g-random-int) :uint32
 #+cl-cffi-gtk-documentation
 "@version{2014-1-29}
  @return{A random number.}
  Return a random @code{:uint32} equally distributed over the range
  [0 ... 2^32-1].
  @see-function{g-random-int-range}")

;;; ----------------------------------------------------------------------------
;;; g_random_int_range ()
;;; ----------------------------------------------------------------------------

(defcfun ("g_random_int_range" g-random-int-range) :int32
 #+cl-cffi-gtk-documentation
 "@version{2013-12-13}
  @argument[begin]{lower closed bound of the interval}
  @argument[end]{upper open bound of the interval}
  @return{A random number.}
  Returns a random integer equally distributed over the range [@arg{begin} ..
  @arg{end} -1 ].
  @see-function{g-random-int}"
  (begin :int32)
  (end :int32))

(export 'g-random-int-range)

;;; ----------------------------------------------------------------------------
;;; g_random_double ()
;;; 
;;; gdouble g_random_double (void);
;;; 
;;; Returns a random gdouble equally distributed over the range [0..1).
;;; 
;;; Returns :
;;;     A random number.
;;; ----------------------------------------------------------------------------

;;; ----------------------------------------------------------------------------
;;; g_random_double_range ()
;;; 
;;; gdouble g_random_double_range (gdouble begin, gdouble end);
;;; 
;;; Returns a random gdouble equally distributed over the range [begin..end).
;;; 
;;; begin :
;;;     lower closed bound of the interval.
;;; 
;;; end :
;;;     upper open bound of the interval.
;;; 
;;; Returns :
;;;     A random number.

;;; --- End of file glib.random.lisp -------------------------------------------
