1 /* rng/rng.c
2  *
3  * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or (at
8  * your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
20 #include <config.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <gsl/gsl_errno.h>
25 #include <gsl/gsl_rng.h>
26 
27 gsl_rng *
gsl_rng_alloc(const gsl_rng_type * T)28 gsl_rng_alloc (const gsl_rng_type * T)
29 {
30 
31   gsl_rng *r = (gsl_rng *) malloc (sizeof (gsl_rng));
32 
33   if (r == 0)
34     {
35       GSL_ERROR_VAL ("failed to allocate space for rng struct",
36                         GSL_ENOMEM, 0);
37     };
38 
39   r->state = calloc (1, T->size);
40 
41   if (r->state == 0)
42     {
43       free (r);         /* exception in constructor, avoid memory leak */
44 
45       GSL_ERROR_VAL ("failed to allocate space for rng state",
46                         GSL_ENOMEM, 0);
47     };
48 
49   r->type = T;
50 
51   gsl_rng_set (r, gsl_rng_default_seed);        /* seed the generator */
52 
53   return r;
54 }
55 
56 int
gsl_rng_memcpy(gsl_rng * dest,const gsl_rng * src)57 gsl_rng_memcpy (gsl_rng * dest, const gsl_rng * src)
58 {
59   if (dest->type != src->type)
60     {
61       GSL_ERROR ("generators must be of the same type", GSL_EINVAL);
62     }
63 
64   memcpy (dest->state, src->state, src->type->size);
65 
66   return GSL_SUCCESS;
67 }
68 
69 gsl_rng *
gsl_rng_clone(const gsl_rng * q)70 gsl_rng_clone (const gsl_rng * q)
71 {
72   gsl_rng *r = (gsl_rng *) malloc (sizeof (gsl_rng));
73 
74   if (r == 0)
75     {
76       GSL_ERROR_VAL ("failed to allocate space for rng struct",
77                         GSL_ENOMEM, 0);
78     };
79 
80   r->state = malloc (q->type->size);
81 
82   if (r->state == 0)
83     {
84       free (r);         /* exception in constructor, avoid memory leak */
85 
86       GSL_ERROR_VAL ("failed to allocate space for rng state",
87                         GSL_ENOMEM, 0);
88     };
89 
90   r->type = q->type;
91 
92   memcpy (r->state, q->state, q->type->size);
93 
94   return r;
95 }
96 
97 void
gsl_rng_set(const gsl_rng * r,unsigned long int seed)98 gsl_rng_set (const gsl_rng * r, unsigned long int seed)
99 {
100   (r->type->set) (r->state, seed);
101 }
102 
103 unsigned long int
gsl_rng_max(const gsl_rng * r)104 gsl_rng_max (const gsl_rng * r)
105 {
106   return r->type->max;
107 }
108 
109 unsigned long int
gsl_rng_min(const gsl_rng * r)110 gsl_rng_min (const gsl_rng * r)
111 {
112   return r->type->min;
113 }
114 
115 const char *
gsl_rng_name(const gsl_rng * r)116 gsl_rng_name (const gsl_rng * r)
117 {
118   return r->type->name;
119 }
120 
121 size_t
gsl_rng_size(const gsl_rng * r)122 gsl_rng_size (const gsl_rng * r)
123 {
124   return r->type->size;
125 }
126 
127 void *
gsl_rng_state(const gsl_rng * r)128 gsl_rng_state (const gsl_rng * r)
129 {
130   return r->state;
131 }
132 
133 void
gsl_rng_print_state(const gsl_rng * r)134 gsl_rng_print_state (const gsl_rng * r)
135 {
136   size_t i;
137   unsigned char *p = (unsigned char *) (r->state);
138   const size_t n = r->type->size;
139 
140   for (i = 0; i < n; i++)
141     {
142       /* FIXME: we're assuming that a char is 8 bits */
143       printf ("%.2x", *(p + i));
144     }
145 
146 }
147 
148 void
gsl_rng_free(gsl_rng * r)149 gsl_rng_free (gsl_rng * r)
150 {
151   RETURN_IF_NULL (r);
152   free (r->state);
153   free (r);
154 }
155