00001 /* 00002 Copyright 2010-2011, D. E. Shaw Research. 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without 00006 modification, are permitted provided that the following conditions are 00007 met: 00008 00009 * Redistributions of source code must retain the above copyright 00010 notice, this list of conditions, and the following disclaimer. 00011 00012 * Redistributions in binary form must reproduce the above copyright 00013 notice, this list of conditions, and the following disclaimer in the 00014 documentation and/or other materials provided with the distribution. 00015 00016 * Neither the name of D. E. Shaw Research nor the names of its 00017 contributors may be used to endorse or promote products derived from 00018 this software without specific prior written permission. 00019 00020 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00021 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00022 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00023 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00024 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00026 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00027 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00028 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00029 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00030 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 #ifndef __r123_compat_gslrng_dot_h__ 00033 #define __r123_compat_gslrng_dot_h__ 00034 00035 #include <gsl/gsl_rng.h> 00036 #include <string.h> 00037 00067 #define GSL_CBRNG(NAME, CBRNGNAME) \ 00068 const gsl_rng_type *gsl_rng_##NAME; \ 00069 \ 00070 typedef struct{ \ 00071 CBRNGNAME##_ctr_t ctr; \ 00072 CBRNGNAME##_ctr_t r; \ 00073 CBRNGNAME##_key_t key; \ 00074 int elem; \ 00075 } NAME##_state; \ 00076 \ 00077 static unsigned long int NAME##_get(void *vstate){ \ 00078 NAME##_state *st = (NAME##_state *)vstate; \ 00079 const int N=sizeof(st->ctr.v)/sizeof(st->ctr.v[0]); \ 00080 if( st->elem == 0 ){ \ 00081 ++st->ctr.v[0]; \ 00082 if( N>1 && st->ctr.v[0] == 0 ) ++st->ctr.v[1]; \ 00083 if( N>2 && st->ctr.v[1] == 0 ) ++st->ctr.v[2]; \ 00084 if( N>3 && st->ctr.v[2] == 0 ) ++st->ctr.v[3]; \ 00085 st->r = CBRNGNAME(st->ctr, st->key); \ 00086 st->elem = N; \ 00087 } \ 00088 return 0xffffffffUL & st->r.v[--st->elem]; \ 00089 } \ 00090 \ 00091 static double \ 00092 NAME##_get_double (void * vstate) \ 00093 { \ 00094 return NAME##_get (vstate)/4294967296.0; \ 00095 } \ 00096 \ 00097 static void NAME##_set(void *vstate, unsigned long int s){ \ 00098 NAME##_state *st = (NAME##_state *)vstate; \ 00099 st->elem = 0; \ 00100 /* Assume that key and ctr have an array member, v, \ 00101 as if they are r123arrayNxW. If not, this will fail \ 00102 to compile. In particular, this macro fails to compile \ 00103 when the underlying CBRNG requires use of keyinit */ \ 00104 memset(&st->ctr.v[0], 0, sizeof(st->ctr.v)); \ 00105 memset(&st->key.v[0], 0, sizeof(st->key.v)); \ 00106 /* GSL 1.15 documentation says this about gsl_rng_set: \ 00107 Note that the most generators only accept 32-bit seeds, with higher \ 00108 values being reduced modulo 2^32. For generators with smaller \ 00109 ranges the maximum seed value will typically be lower. \ 00110 so we won't jump through any hoops here to deal with \ 00111 high bits if sizeof(unsigned long) > sizeof(uint32_t). */ \ 00112 st->key.v[0] = s; \ 00113 } \ 00114 \ 00115 static const gsl_rng_type NAME##_type = { \ 00116 #NAME, \ 00117 0xffffffffUL, \ 00118 0, \ 00119 sizeof(NAME##_state), \ 00120 &NAME##_set, \ 00121 &NAME##_get, \ 00122 &NAME##_get_double \ 00123 }; \ 00124 \ 00125 const gsl_rng_type *gsl_rng_##NAME = &NAME##_type 00126 00127 #endif 00128