1 /*****************************************************************************
2  *                                                                           *
3  *          UNURAN -- Universal Non-Uniform Random number generator          *
4  *                                                                           *
5  *****************************************************************************
6  *                                                                           *
7  *   FILE:      unif.c                                                       *
8  *                                                                           *
9  *   dummy generator, produces uniform random numbers in UNURAN framework    *
10  *                                                                           *
11  *****************************************************************************
12  *                                                                           *
13  *   Copyright (c) 2000-2006 Wolfgang Hoermann and Josef Leydold             *
14  *   Department of Statistics and Mathematics, WU Wien, Austria              *
15  *                                                                           *
16  *   This program is free software; you can redistribute it and/or modify    *
17  *   it under the terms of the GNU General Public License as published by    *
18  *   the Free Software Foundation; either version 2 of the License, or       *
19  *   (at your option) any later version.                                     *
20  *                                                                           *
21  *   This program is distributed in the hope that it will be useful,         *
22  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
23  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
24  *   GNU General Public License for more details.                            *
25  *                                                                           *
26  *   You should have received a copy of the GNU General Public License       *
27  *   along with this program; if not, write to the                           *
28  *   Free Software Foundation, Inc.,                                         *
29  *   59 Temple Place, Suite 330, Boston, MA 02111-1307, USA                  *
30  *                                                                           *
31  *****************************************************************************/
32 
33 /*---------------------------------------------------------------------------*/
34 
35 #include <unur_source.h>
36 #include <urng/urng.h>
37 #include "unur_methods_source.h"
38 #include "x_gen_source.h"
39 #include "unif.h"
40 #include "unif_struct.h"
41 
42 /*---------------------------------------------------------------------------*/
43 /* Variants: none                                                            */
44 
45 /*---------------------------------------------------------------------------*/
46 /* Debugging flags                                                           */
47 /*    bit  01    ... pameters and structure of generator (do not use here)   */
48 /*    bits 02-12 ... setup                                                   */
49 /*    bits 13-24 ... adaptive steps                                          */
50 /*    bits 25-32 ... trace sampling                                          */
51 
52 /*---------------------------------------------------------------------------*/
53 
54 #define GENTYPE "UNIF"         /* type of generator                          */
55 
56 /*---------------------------------------------------------------------------*/
57 
58 static struct unur_gen *_unur_unif_init( struct unur_par *par );
59 /*---------------------------------------------------------------------------*/
60 /* Initialize new generator.                                                 */
61 /*---------------------------------------------------------------------------*/
62 
63 static int _unur_unif_reinit( struct unur_gen *gen );
64 /*---------------------------------------------------------------------------*/
65 /* Reinitialize generator.                                                   */
66 /*---------------------------------------------------------------------------*/
67 
68 static struct unur_gen *_unur_unif_create( struct unur_par *par );
69 /*---------------------------------------------------------------------------*/
70 /* create new (almost empty) generator object.                               */
71 /*---------------------------------------------------------------------------*/
72 
73 static struct unur_gen *_unur_unif_clone( const struct unur_gen *gen );
74 /*---------------------------------------------------------------------------*/
75 /* copy (clone) generator object.                                            */
76 /*---------------------------------------------------------------------------*/
77 
78 static void _unur_unif_free( struct unur_gen *gen);
79 /*---------------------------------------------------------------------------*/
80 /* destroy generator object.                                                 */
81 /*---------------------------------------------------------------------------*/
82 
83 static double _unur_unif_sample( struct unur_gen *gen );
84 /*---------------------------------------------------------------------------*/
85 /* sample from generator                                                     */
86 /*---------------------------------------------------------------------------*/
87 
88 #ifdef UNUR_ENABLE_INFO
89 static void _unur_unif_info( struct unur_gen *gen, int help );
90 /*---------------------------------------------------------------------------*/
91 /* create info string.                                                       */
92 /*---------------------------------------------------------------------------*/
93 #endif
94 
95 /*---------------------------------------------------------------------------*/
96 /* abbreviations */
97 
98 #define PAR       ((struct unur_unif_par*)par->datap) /* data for parameter object */
99 #define GEN       ((struct unur_unif_gen*)gen->datap) /* data for generator object */
100 #define SAMPLE  gen->sample.cont
101 
102 /*---------------------------------------------------------------------------*/
103 
104 #define _unur_unif_getSAMPLE(gen)  ( _unur_unif_sample )
105 
106 /*---------------------------------------------------------------------------*/
107 
108 /*****************************************************************************/
109 /**  Public: User Interface (API)                                           **/
110 /*****************************************************************************/
111 
112 struct unur_par *
unur_unif_new(const struct unur_distr * dummy ATTRIBUTE__UNUSED)113 unur_unif_new( const struct unur_distr *dummy ATTRIBUTE__UNUSED )
114      /*----------------------------------------------------------------------*/
115      /* get default parameters                                               */
116      /*                                                                      */
117      /* parameters:                                                          */
118      /*   dummy ... dummy pointer to distribution object (not used!)         */
119      /*                                                                      */
120      /* return:                                                              */
121      /*   default parameters (pointer to structure)                          */
122      /*                                                                      */
123      /* error:                                                               */
124      /*   return NULL                                                        */
125      /*                                                                      */
126      /* comment:                                                             */
127      /*   for testing.                                                       */
128      /*----------------------------------------------------------------------*/
129 {
130   struct unur_par *par;
131 
132   /* allocate structure */
133   par = _unur_par_new( sizeof(struct unur_unif_par) );
134   COOKIE_SET(par,CK_UNIF_PAR);
135 
136   /* there is no need for a distribution object */
137   par->distr = NULL;
138 
139   /* set default values */
140   par->method   = UNUR_METH_UNIF;  /* method and default variant             */
141   par->variant  = 0u;              /* default variant                        */
142   par->set      = 0u;              /* inidicate default parameters           */
143   par->urng     = unur_get_default_urng(); /* use default urng               */
144   par->urng_aux = NULL;                    /* no auxilliary URNG required    */
145 
146   par->debug    = _unur_default_debugflag; /* set default debugging flags    */
147 
148   /* routine for starting generator */
149   par->init = _unur_unif_init;
150 
151   return par;
152 
153 } /* end of unur_unif_new() */
154 
155 
156 /*****************************************************************************/
157 /**  Private                                                                **/
158 /*****************************************************************************/
159 
160 struct unur_gen *
_unur_unif_init(struct unur_par * par)161 _unur_unif_init( struct unur_par *par )
162      /*----------------------------------------------------------------------*/
163      /* initialize new generator                                             */
164      /*                                                                      */
165      /* parameters:                                                          */
166      /*   params  pointer to paramters for building generator object         */
167      /*                                                                      */
168      /* return:                                                              */
169      /*   pointer to generator object                                        */
170      /*                                                                      */
171      /* error:                                                               */
172      /*   return NULL                                                        */
173      /*----------------------------------------------------------------------*/
174 {
175   struct unur_gen *gen;
176 
177   /* check arguments */
178   CHECK_NULL(par,NULL);
179 
180   /* check input */
181   if ( par->method != UNUR_METH_UNIF ) {
182     _unur_error(GENTYPE,UNUR_ERR_PAR_INVALID,"");
183     return NULL; }
184   COOKIE_CHECK(par,CK_UNIF_PAR,NULL);
185 
186   /* create a new empty generator object */
187   gen = _unur_unif_create(par);
188 
189   /* free parameters */
190   _unur_par_free(par);
191 
192   return gen;
193 
194 } /* end of _unur_unif_init() */
195 
196 /*---------------------------------------------------------------------------*/
197 
198 int
_unur_unif_reinit(struct unur_gen * gen)199 _unur_unif_reinit( struct unur_gen *gen )
200      /*----------------------------------------------------------------------*/
201      /* re-initialize (existing) generator.                                  */
202      /*                                                                      */
203      /* parameters:                                                          */
204      /*   gen ... pointer to generator object                                */
205      /*                                                                      */
206      /* return:                                                              */
207      /*   UNUR_SUCCESS ... on success                                        */
208      /*   error code   ... on error                                          */
209      /*----------------------------------------------------------------------*/
210 {
211   /* (re)set sampling routine */
212   SAMPLE = _unur_unif_getSAMPLE(gen);
213 
214   /* nothing sensible to do */
215   return UNUR_SUCCESS;
216 } /* end of _unur_utdr_reinit() */
217 
218 /*---------------------------------------------------------------------------*/
219 
220 static struct unur_gen *
_unur_unif_create(struct unur_par * par)221 _unur_unif_create( struct unur_par *par )
222      /*----------------------------------------------------------------------*/
223      /* allocate memory for generator                                        */
224      /*                                                                      */
225      /* parameters:                                                          */
226      /*   par ... pointer to parameter for building generator object         */
227      /*                                                                      */
228      /* return:                                                              */
229      /*   pointer to (empty) generator object with default settings          */
230      /*                                                                      */
231      /* error:                                                               */
232      /*   return NULL                                                        */
233      /*----------------------------------------------------------------------*/
234 {
235   struct unur_gen *gen;
236 
237   /* check arguments */
238   CHECK_NULL(par,NULL);
239   COOKIE_CHECK(par,CK_UNIF_PAR,NULL);
240 
241   /* create new generic generator object */
242   gen = _unur_generic_create( par, sizeof(struct unur_unif_gen) );
243 
244   /* magic cookies */
245   COOKIE_SET(gen,CK_UNIF_GEN);
246 
247   /* set generator identifier */
248   gen->genid = _unur_set_genid(GENTYPE);
249 
250   /* routines for sampling and destroying generator */
251   SAMPLE = _unur_unif_getSAMPLE(gen);
252   gen->destroy = _unur_unif_free;
253   gen->clone = _unur_unif_clone;
254   gen->reinit = _unur_unif_reinit;
255 
256 #ifdef UNUR_ENABLE_INFO
257   /* set function for creating info string */
258   gen->info = _unur_unif_info;
259 #endif
260 
261   /* return pointer to (almost empty) generator object */
262   return gen;
263 
264 } /* end of _unur_unif_create() */
265 
266 /*---------------------------------------------------------------------------*/
267 
268 struct unur_gen *
_unur_unif_clone(const struct unur_gen * gen)269 _unur_unif_clone( const struct unur_gen *gen )
270      /*----------------------------------------------------------------------*/
271      /* copy (clone) generator object                                        */
272      /*                                                                      */
273      /* parameters:                                                          */
274      /*   gen ... pointer to generator object                                */
275      /*                                                                      */
276      /* return:                                                              */
277      /*   pointer to clone of generator object                               */
278      /*                                                                      */
279      /* error:                                                               */
280      /*   return NULL                                                        */
281      /*----------------------------------------------------------------------*/
282 {
283   struct unur_gen *clone;
284 
285   /* check arguments */
286   CHECK_NULL(gen,NULL);  COOKIE_CHECK(gen,CK_UNIF_GEN,NULL);
287 
288   /* create generic clone */
289   clone = _unur_generic_clone( gen, GENTYPE );
290 
291   return clone;
292 } /* end of _unur_unif_clone() */
293 
294 /*---------------------------------------------------------------------------*/
295 
296 void
_unur_unif_free(struct unur_gen * gen)297 _unur_unif_free( struct unur_gen *gen )
298      /*----------------------------------------------------------------------*/
299      /* deallocate generator object                                          */
300      /*                                                                      */
301      /* parameters:                                                          */
302      /*   gen ... pointer to generator object                                */
303      /*----------------------------------------------------------------------*/
304 {
305 
306   /* check arguments */
307   if( !gen ) /* nothing to do */
308     return;
309 
310   /* check input */
311   if ( gen->method != UNUR_METH_UNIF ) {
312     _unur_warning(gen->genid,UNUR_ERR_GEN_INVALID,"");
313     return; }
314   COOKIE_CHECK(gen,CK_UNIF_GEN,RETURN_VOID);
315 
316   /* we cannot use this generator object any more */
317   SAMPLE = NULL;   /* make sure to show up a programming error */
318 
319   /* free memory */
320   _unur_generic_free(gen);
321 
322 } /* end of _unur_unif_free() */
323 
324 /*****************************************************************************/
325 
326 double
_unur_unif_sample(struct unur_gen * gen)327 _unur_unif_sample( struct unur_gen *gen )
328      /*----------------------------------------------------------------------*/
329      /* sample from generator                                                */
330      /*                                                                      */
331      /* parameters:                                                          */
332      /*   gen ... pointer to generator object                                */
333      /*                                                                      */
334      /* return:                                                              */
335      /*   double (sample from random variate)                                */
336      /*                                                                      */
337      /* error:                                                               */
338      /*   return INFINITY                                                    */
339      /*----------------------------------------------------------------------*/
340 {
341   /* check arguments */
342   CHECK_NULL(gen,INFINITY);
343   COOKIE_CHECK(gen,CK_UNIF_GEN,INFINITY);
344 
345   /* sample uniform random number */
346   return _unur_call_urng(gen->urng);
347 
348 } /* end of _unur_unif_sample() */
349 
350 /*****************************************************************************/
351 /**  Auxilliary Routines                                                    **/
352 /*****************************************************************************/
353 
354 /*****************************************************************************/
355 /**  Debugging utilities                                                    **/
356 /*****************************************************************************/
357 
358 /*---------------------------------------------------------------------------*/
359 #ifdef UNUR_ENABLE_LOGGING
360 /*---------------------------------------------------------------------------*/
361 
362 /** None **/
363 
364 /*---------------------------------------------------------------------------*/
365 #endif   /* end UNUR_ENABLE_LOGGING */
366 /*---------------------------------------------------------------------------*/
367 
368 
369 /*---------------------------------------------------------------------------*/
370 #ifdef UNUR_ENABLE_INFO
371 /*---------------------------------------------------------------------------*/
372 
373 void
_unur_unif_info(struct unur_gen * gen,int help)374 _unur_unif_info( struct unur_gen *gen, int help )
375      /*----------------------------------------------------------------------*/
376      /* create character string that contains information about the          */
377      /* given generator object.                                              */
378      /*                                                                      */
379      /* parameters:                                                          */
380      /*   gen  ... pointer to generator object                               */
381      /*   help ... whether to print additional comments                      */
382      /*----------------------------------------------------------------------*/
383 {
384   struct unur_string *info = gen->infostr;
385 
386   /* generator ID */
387   _unur_string_append(info,"generator ID: %s\n\n", gen->genid);
388 
389   /* distribution */
390   _unur_string_append(info,"distribution: uniform (0,1)\n\n");
391 
392   /* method */
393   _unur_string_append(info,"method: UNIF (wrapper for UNIForm random number generator)\n\n");
394 
395   /* Hints */
396   if (help) {
397     _unur_string_append(info,"[Remark: allows using uniform random number generator in UNU.RAN framework]\n");
398   }
399 
400 } /* end of _unur_unif_info() */
401 
402 /*---------------------------------------------------------------------------*/
403 #endif   /* end UNUR_ENABLE_INFO */
404 /*---------------------------------------------------------------------------*/
405