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