1 /*****************************************************************************
2 * *
3 * UNURAN -- Universal Non-Uniform Random number generator *
4 * *
5 *****************************************************************************
6 * *
7 * FILE: distr.c *
8 * *
9 * manipulate distribution objects *
10 * *
11 * PARAMETER: struct unur_distr * *
12 * *
13 * return: *
14 * UNUR_SUCCESS ... on success *
15 * error code ... on error *
16 * *
17 *****************************************************************************
18 * *
19 * Copyright (c) 2000-2006 Wolfgang Hoermann and Josef Leydold *
20 * Department of Statistics and Mathematics, WU Wien, Austria *
21 * *
22 * This program is free software; you can redistribute it and/or modify *
23 * it under the terms of the GNU General Public License as published by *
24 * the Free Software Foundation; either version 2 of the License, or *
25 * (at your option) any later version. *
26 * *
27 * This program is distributed in the hope that it will be useful, *
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
30 * GNU General Public License for more details. *
31 * *
32 * You should have received a copy of the GNU General Public License *
33 * along with this program; if not, write to the *
34 * Free Software Foundation, Inc., *
35 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA *
36 * *
37 *****************************************************************************/
38
39 /*---------------------------------------------------------------------------*/
40
41 #include <unur_source.h>
42 #include <distributions/unur_stddistr.h>
43 #include "distr.h"
44 #include "distr_source.h"
45
46
47 /*---------------------------------------------------------------------------*/
48
49 /*****************************************************************************/
50 /** **/
51 /** routines for all distribution objects **/
52 /** **/
53 /*****************************************************************************/
54
55 /*---------------------------------------------------------------------------*/
56
57 struct unur_distr *
_unur_distr_generic_new(void)58 _unur_distr_generic_new( void )
59 /*----------------------------------------------------------------------*/
60 /* generic creator for distribution object */
61 /* */
62 /* parameters: none */
63 /* */
64 /* return: */
65 /* pointer empty distribution object */
66 /* NULL in case of an error */
67 /*----------------------------------------------------------------------*/
68 {
69 register struct unur_distr *distr;
70
71 /* allocate structure */
72 distr = _unur_xmalloc( sizeof(struct unur_distr) );
73 if (!distr) return NULL;
74
75 /* set type of distribution */
76 distr->type = UNUR_DISTR_GENERIC;
77
78 /* set id to generic distribution */
79 distr->id = UNUR_DISTR_GENERIC;
80
81 /* dimension of random vector */
82 distr->dim = 1; /* assume univariant */
83
84 /* name of distribution */
85 distr->name = "unknown";
86 distr->name_str = NULL;
87
88 /* this is not a derived distribution */
89 distr->base = NULL;
90
91 /* defaults */
92 distr->destroy = NULL; /* destructor: not set */
93 distr->clone = NULL; /* copy operator: not set */
94 distr->extobj = NULL; /* pointer to external object: empty */
95 distr->set = 0u; /* parameters: none set */
96
97 /* return pointer to object */
98 return distr;
99
100 } /* end of _unur_distr_generic_new() */
101
102 /*---------------------------------------------------------------------------*/
103
104 void
unur_distr_free(struct unur_distr * distr)105 unur_distr_free( struct unur_distr *distr )
106 /*----------------------------------------------------------------------*/
107 /* free distribution object */
108 /* */
109 /* parameters: */
110 /* distr ... pointer to distribution object */
111 /*----------------------------------------------------------------------*/
112 {
113 if (distr) _unur_distr_free( distr );
114 } /* end of unur_distr_free() */
115
116 /*---------------------------------------------------------------------------*/
117
118 int
unur_distr_set_name(struct unur_distr * distr,const char * name)119 unur_distr_set_name( struct unur_distr *distr, const char *name )
120 /*----------------------------------------------------------------------*/
121 /* set name of distribution */
122 /* */
123 /* parameters: */
124 /* distr ... pointer to distribution object */
125 /* name ... name of distribution */
126 /* */
127 /* return: */
128 /* UNUR_SUCCESS ... on success */
129 /* error code ... on error */
130 /*----------------------------------------------------------------------*/
131 {
132 size_t len;
133 char *name_str;
134
135 /* check arguments */
136 _unur_check_NULL( NULL, distr, UNUR_ERR_NULL );
137
138 /* allocate memory for storing string */
139 len = strlen(name) + 1;
140 name_str = _unur_xrealloc(distr->name_str,len);
141
142 /* copy string */
143 memcpy( name_str, name, len );
144
145 /* store string in distribution object */
146 distr->name_str = name_str;
147 distr->name = name_str;
148
149 return UNUR_SUCCESS;
150 } /* end of unur_distr_set_name() */
151
152 /*---------------------------------------------------------------------------*/
153
154 const char *
unur_distr_get_name(const struct unur_distr * distr)155 unur_distr_get_name( const struct unur_distr *distr )
156 /*----------------------------------------------------------------------*/
157 /* get name of distribution */
158 /* */
159 /* parameters: */
160 /* distr ... pointer to distribution object */
161 /* */
162 /* return: */
163 /* name of distribution */
164 /*----------------------------------------------------------------------*/
165 {
166 /* check arguments */
167 _unur_check_NULL( NULL, distr, NULL );
168
169 return distr->name;
170 } /* end of unur_distr_get_name() */
171
172 /*---------------------------------------------------------------------------*/
173
174 int
unur_distr_get_dim(const struct unur_distr * distr)175 unur_distr_get_dim( const struct unur_distr *distr )
176 /*----------------------------------------------------------------------*/
177 /* get number of components of random vector (i.e. its dimension) */
178 /* */
179 /* parameters: */
180 /* distr ... pointer to distribution object */
181 /* */
182 /* return: */
183 /* dimension */
184 /*----------------------------------------------------------------------*/
185 {
186 /* check arguments */
187 _unur_check_NULL( NULL, distr, 0 );
188
189 return distr->dim;
190 } /* end of unur_distr_get_dim() */
191
192 /*---------------------------------------------------------------------------*/
193
194 unsigned int
unur_distr_get_type(const struct unur_distr * distr)195 unur_distr_get_type( const struct unur_distr *distr )
196 /*----------------------------------------------------------------------*/
197 /* get type of distribution */
198 /* */
199 /* parameters: */
200 /* distr ... pointer to distribution object */
201 /* */
202 /* return: */
203 /* type of distribution */
204 /*----------------------------------------------------------------------*/
205 {
206 /* check arguments */
207 _unur_check_NULL( NULL, distr, 0u );
208
209 return (distr->type);
210 } /* end of unur_distr_get_type() */
211
212 /*---------------------------------------------------------------------------*/
213
214 int
unur_distr_is_cont(const struct unur_distr * distr)215 unur_distr_is_cont( const struct unur_distr *distr )
216 /*----------------------------------------------------------------------*/
217 /* TRUE if distribution is univariate continuous. */
218 /* */
219 /* parameters: */
220 /* distr ... pointer to distribution object */
221 /* */
222 /* return: */
223 /* TRUE ... if continuous distribution */
224 /* FALSE ... otherwise (and in case of an error) */
225 /*----------------------------------------------------------------------*/
226 {
227 /* check arguments */
228 _unur_check_NULL( NULL, distr, FALSE );
229
230 return ((distr->type == UNUR_DISTR_CONT) ? TRUE : FALSE);
231 } /* end of unur_distr_is_cont() */
232
233 /*---------------------------------------------------------------------------*/
234
235 int
unur_distr_is_cvec(const struct unur_distr * distr)236 unur_distr_is_cvec( const struct unur_distr *distr )
237 /*----------------------------------------------------------------------*/
238 /* TRUE if distribution is multivariate continuous. */
239 /* */
240 /* parameters: */
241 /* distr ... pointer to distribution object */
242 /* */
243 /* return: */
244 /* TRUE ... if multivariate continuous */
245 /* FALSE ... otherwise (and in case of an error) */
246 /*----------------------------------------------------------------------*/
247 {
248 /* check arguments */
249 _unur_check_NULL( NULL, distr, FALSE );
250
251 return ((distr->type == UNUR_DISTR_CVEC) ? TRUE : FALSE);
252 } /* end of unur_distr_is_cvec() */
253
254 /*---------------------------------------------------------------------------*/
255
256 int
unur_distr_is_cvemp(const struct unur_distr * distr)257 unur_distr_is_cvemp( const struct unur_distr *distr )
258 /*----------------------------------------------------------------------*/
259 /* TRUE if distribution is empirical multivariate continuous. */
260 /* */
261 /* parameters: */
262 /* distr ... pointer to distribution object */
263 /* */
264 /* return: */
265 /* TRUE ... if empirical multivariate continuous */
266 /* FALSE ... otherwise (and in case of an error) */
267 /*----------------------------------------------------------------------*/
268 {
269 /* check arguments */
270 _unur_check_NULL( NULL, distr, FALSE );
271
272 return ((distr->type == UNUR_DISTR_CVEMP) ? TRUE : FALSE);
273 } /* end of unur_distr_is_cvemp() */
274
275 /*---------------------------------------------------------------------------*/
276
277 int
unur_distr_is_matr(const struct unur_distr * distr)278 unur_distr_is_matr( const struct unur_distr *distr )
279 /*----------------------------------------------------------------------*/
280 /* TRUE if distribution is matrix distribution. */
281 /* */
282 /* parameters: */
283 /* distr ... pointer to distribution object */
284 /* */
285 /* return: */
286 /* TRUE ... if matrix distribution */
287 /* FALSE ... otherwise (and in case of an error) */
288 /*----------------------------------------------------------------------*/
289 {
290 /* check arguments */
291 _unur_check_NULL( NULL, distr, FALSE );
292
293 return ((distr->type == UNUR_DISTR_MATR) ? TRUE : FALSE);
294 } /* end of unur_distr_is_matr() */
295
296 /*---------------------------------------------------------------------------*/
297
298 int
unur_distr_is_discr(const struct unur_distr * distr)299 unur_distr_is_discr( const struct unur_distr *distr )
300 /*----------------------------------------------------------------------*/
301 /* TRUE if distribution is univariate discrete. */
302 /* */
303 /* parameters: */
304 /* distr ... pointer to distribution object */
305 /* */
306 /* return: */
307 /* TREU ... if univariate discrete */
308 /* FALSE ... otherwise (and in case of an error) */
309 /*----------------------------------------------------------------------*/
310 {
311 /* check arguments */
312 _unur_check_NULL( NULL, distr, FALSE );
313
314 return ((distr->type == UNUR_DISTR_DISCR) ? TRUE : FALSE);
315 } /* end of unur_distr_is_discr() */
316
317 /*---------------------------------------------------------------------------*/
318
319 int
unur_distr_is_cemp(const struct unur_distr * distr)320 unur_distr_is_cemp( const struct unur_distr *distr )
321 /*----------------------------------------------------------------------*/
322 /* TRUE if distribution is empirical univariate continuous, */
323 /* i.e. a sample. */
324 /* */
325 /* parameters: */
326 /* distr ... pointer to distribution object */
327 /* */
328 /* return: */
329 /* TRUE ... if univariate discrete */
330 /* FALSE ... otherwise (and in case of an error) */
331 /*----------------------------------------------------------------------*/
332 {
333 /* check arguments */
334 _unur_check_NULL( NULL, distr, FALSE );
335
336 return ((distr->type == UNUR_DISTR_CEMP) ? TRUE : FALSE);
337 } /* end of unur_distr_is_cemp() */
338
339 /*---------------------------------------------------------------------------*/
340
341 struct unur_distr *
unur_distr_clone(const struct unur_distr * distr)342 unur_distr_clone( const struct unur_distr *distr )
343 /*----------------------------------------------------------------------*/
344 /* copy (clone) distribution object */
345 /* */
346 /* parameters: */
347 /* distr ... pointer to distribution object */
348 /* */
349 /* return: */
350 /* pointer to clone of distribution object */
351 /* */
352 /* error: */
353 /* return NULL */
354 /*----------------------------------------------------------------------*/
355 {
356 /* check arguments */
357 _unur_check_NULL( "Clone", distr, NULL );
358 _unur_check_NULL( "Clone", distr->clone, NULL );
359
360 return (distr->clone(distr));
361 } /* end of unur_distr_clone() */
362
363 /*---------------------------------------------------------------------------*/
364
365 int
unur_distr_set_extobj(struct unur_distr * distr,const void * extobj)366 unur_distr_set_extobj( struct unur_distr *distr, const void *extobj )
367 /*----------------------------------------------------------------------*/
368 /* store a pointer to an external object */
369 /* */
370 /* parameters: */
371 /* distr ... pointer to distribution object */
372 /* extobj ... pointer to external object */
373 /* */
374 /* return: */
375 /* UNUR_SUCCESS ... on success */
376 /* error code ... on error */
377 /*----------------------------------------------------------------------*/
378 {
379 /* check arguments */
380 _unur_check_NULL( NULL, distr, UNUR_ERR_NULL );
381
382 /* store data */
383 distr->extobj = extobj;
384
385 return UNUR_SUCCESS;
386
387 } /* end of unur_distr_set_extobj() */
388
389 /*---------------------------------------------------------------------------*/
390
391 const void *
unur_distr_get_extobj(const struct unur_distr * distr)392 unur_distr_get_extobj( const struct unur_distr *distr )
393 /*----------------------------------------------------------------------*/
394 /* get the pointer to the external object */
395 /* */
396 /* parameters: */
397 /* distr ... pointer to distribution object */
398 /* */
399 /* return: */
400 /* pointer to external object */
401 /* (NULL if not is given) */
402 /* */
403 /* error: */
404 /* return NULL */
405 /*----------------------------------------------------------------------*/
406 {
407 /* check arguments */
408 _unur_check_NULL( NULL, distr, NULL );
409
410 return distr->extobj;
411 } /* unur_distr_get_extobj() */
412
413 /*---------------------------------------------------------------------------*/
414
415
416