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