diff options
author | Andreas Rottmann <a.rottmann@gmx.at> | 2010-07-22 18:26:00 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2010-07-26 15:00:49 +0200 |
commit | 77b139121d0344d8a89f4d8b85739a3447bac196 (patch) | |
tree | 6288de8faa1e1c9df7a9c545a50f9078f7b3467a /libguile/random.c | |
parent | 2d6a14adc901ea71409ef82c4021f235e99d420d (diff) | |
download | guile-77b139121d0344d8a89f4d8b85739a3447bac196.tar.gz |
Allow exposing of random number generator state
Now the random number generator state can be obtained in external
(i.e. `read'/`write'-able) form via the new procedure
`random-state->external'. An externalized state can be reinstantiated by
calling `external->random-state'.
* libguile/random.c (scm_i_init_rstate_scm, scm_i_expose_rstate): New
internal functions.
* libguile/random.c (scm_c_make_rstate_scm, scm_external_to_random_state,
scm_random_state_to_external): New public functions.
* libguile/random.h: Add prototypes for the above functions.
* libguile/random.h (scm_t_rng): Add new fields `init_rstate_scm' and
`expose_rstate'.
* libguile/random.c (scm_init_random): Initialize the new fields in
`scm_the_rng'.
Diffstat (limited to 'libguile/random.c')
-rw-r--r-- | libguile/random.c | 72 |
1 files changed, 68 insertions, 4 deletions
diff --git a/libguile/random.c b/libguile/random.c index 1a9fd59ac..f028272f6 100644 --- a/libguile/random.c +++ b/libguile/random.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1999,2000,2001, 2003, 2005, 2006, 2009 Free Software Foundation, Inc. +/* Copyright (C) 1999,2000,2001, 2003, 2005, 2006, 2009, 2010 Free Software Foundation, Inc. * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 3 of @@ -151,6 +151,35 @@ scm_i_copy_rstate (scm_t_i_rstate *state) return memcpy (new_state, state, scm_the_rng.rstate_size); } +SCM_SYMBOL(scm_i_rstate_tag, "multiply-with-carry"); + +void +scm_i_init_rstate_scm (scm_t_i_rstate *state, SCM value) +#define FUNC_NAME "scm_i_init_rstate_scm" +{ + unsigned long w, c; + long length; + + SCM_VALIDATE_LIST_COPYLEN (SCM_ARG1, value, length); + SCM_ASSERT (length == 3, value, SCM_ARG1, FUNC_NAME); + SCM_ASSERT (scm_is_eq (SCM_CAR (value), scm_i_rstate_tag), + value, SCM_ARG1, FUNC_NAME); + SCM_VALIDATE_ULONG_COPY (SCM_ARG1, SCM_CADR (value), w); + SCM_VALIDATE_ULONG_COPY (SCM_ARG1, SCM_CADDR (value), c); + + state->w = w; + state->c = c; +} +#undef FUNC_NAME + +SCM +scm_i_expose_rstate (scm_t_i_rstate *state) +{ + return scm_list_3 (scm_i_rstate_tag, + scm_from_ulong (state->w), + scm_from_ulong (state->c)); +} + /* * Random number library functions @@ -168,6 +197,17 @@ scm_c_make_rstate (const char *seed, int n) return state; } +scm_t_rstate * +scm_c_make_rstate_scm (SCM external) +{ + scm_t_rstate *state; + + state = scm_gc_malloc_pointerless (scm_the_rng.rstate_size, + "random-state"); + state->reserved0 = 0; + scm_the_rng.init_rstate_scm (state, external); + return state; +} scm_t_rstate * scm_c_default_rstate () @@ -420,6 +460,28 @@ SCM_DEFINE (scm_seed_to_random_state, "seed->random-state", 1, 0, 0, } #undef FUNC_NAME +SCM_DEFINE (scm_external_to_random_state, "external->random-state", 1, 0, 0, + (SCM external), + "Return a new random state using @var{external}.\n" + "\n" + "@var{external} must be an external state representation obtained\n" + "from @code{random-state->external}.") +#define FUNC_NAME s_scm_external_to_random_state +{ + return make_rstate (scm_c_make_rstate_scm (external)); +} +#undef FUNC_NAME + +SCM_DEFINE (scm_random_state_to_external, "random-state->external", 1, 0, 0, + (SCM state), + "Return an external representation of @var{state}.") +#define FUNC_NAME s_scm_random_state_to_external +{ + SCM_VALIDATE_RSTATE (1, state); + return scm_the_rng.expose_rstate (SCM_RSTATE (state)); +} +#undef FUNC_NAME + SCM_DEFINE (scm_random_uniform, "random:uniform", 0, 1, 0, (SCM state), "Return a uniformly distributed inexact real random number in\n" @@ -616,9 +678,11 @@ scm_init_random () scm_t_rng rng = { sizeof (scm_t_i_rstate), - (unsigned long (*)()) scm_i_uniform32, - (void (*)()) scm_i_init_rstate, - (scm_t_rstate *(*)()) scm_i_copy_rstate + (unsigned long (*)()) scm_i_uniform32, + (void (*)()) scm_i_init_rstate, + (scm_t_rstate *(*)()) scm_i_copy_rstate, + (void (*)(scm_t_rstate *, SCM)) scm_i_init_rstate_scm, + (SCM (*)(scm_t_rstate *)) scm_i_expose_rstate }; scm_the_rng = rng; |