1 /*****************************************************************************
2 * *
3 * UNURAN -- Universal Non-Uniform Random number generator *
4 * *
5 *****************************************************************************
6 * *
7 * FILE: stringparser.c. *
8 * *
9 * *
10 * DESCRIPTION: *
11 * *
12 * The function unur_str2gen() takes a character string as its argument. *
13 * This string is parsed in the following ways and the information *
14 * obtained is used to make a generator object. (It returns NULL when *
15 * it is not possible to make a generator object either due to a syntax *
16 * error in the given string, or due to invalid data. *
17 * *
18 * First the given string is copied into a working string. Moreover letter *
19 * letters are transformed into their lower case counterparts and spaces *
20 * are eliminated (i.e. the working string does not contain any white *
21 * space characters any more.) Then the working string is splitted into *
22 * several blocks, separated by ampersands '&'. Each block consists of *
23 * <key>=<value> pairs, separated by semicolons ';'. The first key in *
24 * each block is used to indicate the corresponding block. *
25 * *
26 * We have three different blocks (yet): *
27 * distr ... contains the definition of the distribution *
28 * method ... contains the description of the transformation methdod *
29 * urng ... contains the definition of the uniform RNG *
30 * (currently it only supports URNGs from the PRNG library) *
31 * *
32 * The 'distr' block must be the very first block and is obligatory. *
33 * For that reason the keyword "distr" is optional and can be omitted *
34 * (together with the '=' character). Moreover it is almost ignored while *
35 * parsing the string. To avoid some possible confussion it only has to *
36 * start with the letter 'd' (if it is given at all). E.g. "dnormal" can *
37 * be used as keyword. *
38 * The value of the "distr" key is used to get a distribution object *
39 * either via a unur_distr_<value>() call for a standard distribution *
40 * or the unur_distr_<value>_new() calls are used to get an object for a *
41 * generic distribution. However not all generic distributions are *
42 * supported yet (see the list %UNSUPPORTED_DISTR_TYPES in file *
43 * make_stringparser.pl). *
44 * The parameters for the standard distribution are given as a list of *
45 * numbers enclosed in parenthesis. There must not be any character (other *
46 * than white space) between the name of the standard distribution and *
47 * this list. *
48 * *
49 * All the other blocks are optional and can be arranged in arbitrary *
50 * order. *
51 * The value of the "method" key is the name of the transformation method *
52 * and is used to execute the unur_<value>_new() call. *
53 * *
54 * The value of the "urng" key is passed to the PRNG interface. *
55 * However, it only works when using the PRNG library is enabled *
56 * --with-urng-prng flag and libprng is linked by the executable. *
57 * *
58 * In each block consecuting <key>=<value> pairs, separated by semicolons *
59 * ';', are used to set parameters. The name of the parameter is given as *
60 * key, the argument list is given as value. The arguments of the *
61 * corresponding set calls are given as tokens, separated by commata ','. *
62 * There are two types of tokens: *
63 * single tokens, that represent numbers, and *
64 * list, i.e. a list of single tokens, separated by commata ',', *
65 * enclosed in parenthesis. *
66 * The value (including the character '=') can be omitted when no argument *
67 * are required. *
68 * The key is deduced from the UNU.RAN set calls, such that it uses only *
69 * the part of the set call beyond "..._set_". *
70 * Not all set commands are supported yet (see the output to STDERR of *
71 * the make_stringparser.pl script). *
72 * As a rule of thumb only those set calls are supported that only have *
73 * numbers or arrays of numbers as arguments (besides the pointer to the *
74 * distribution or parameter object). *
75 * (See the code of make_stringparser.pl for details.) *
76 * *
77 * There are additional transformations before executing the necessary *
78 * set calls (listed by argument types) *
79 * int: 'true' and 'on' are transformed to 1, *
80 * 'false' and 'off' are transformed to 0. *
81 * a missing argument is transformed to 1. *
82 * int, int: Instead of two integers, a list with at least two *
83 * numbers can be given. *
84 * 'inf[...]' is transformed to INT_MAX, *
85 * '-inf[...]' is transformed to INT_MIN. *
86 * unsigned: string is interpreted as hexadecimal number. *
87 * double: 'inf[...]' is transformed to INFINITY, *
88 * '-inf[...]' is transformed to -INFINITY. *
89 * double, double: Instead of two doubles, a list with at least two *
90 * numbers can be given. *
91 * 'inf[...]' is transformed to INFINITY. *
92 * int, double*: If the first argument is missing, it is replaced *
93 * by the size of the array. *
94 * If the second argument is missing, the NULL pointer is *
95 * used instead an array as argument. *
96 * double*, int: Only for distributions! *
97 * If the second argument 'int' is missing, it is replaced *
98 * by the size of the array. *
99 * Important: there is no support for 'infinity' in lists! *
100 * (See also the source below for more details.) *
101 * *
102 *****************************************************************************
103 * *
104 * REMARK: *
105 * The stringparser always uses the default debugging flag. *
106 * *
107 *****************************************************************************
108 * *
109 * Copyright (c) 2000-2006 Wolfgang Hoermann and Josef Leydold *
110 * Department of Statistics and Mathematics, WU Wien, Austria *
111 * *
112 * This program is free software; you can redistribute it and/or modify *
113 * it under the terms of the GNU General Public License as published by *
114 * the Free Software Foundation; either version 2 of the License, or *
115 * (at your option) any later version. *
116 * *
117 * This program is distributed in the hope that it will be useful, *
118 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
119 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
120 * GNU General Public License for more details. *
121 * *
122 * You should have received a copy of the GNU General Public License *
123 * along with this program; if not, write to the *
124 * Free Software Foundation, Inc., *
125 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA *
126 * *
127 *****************************************************************************/
128
129 #include <stdarg.h>
130 #include <ctype.h>
131 #include <unur_source.h>
132 #include <methods/unur_methods_source.h>
133 #include <methods/x_gen.h>
134 #include "parser_source.h"
135 #include "parser.h"
136
137 #include <urng/urng.h>
138
139 #include <distr/distr_source.h>
140 #include <distr/distr.h>
141 #include <distr/cemp.h>
142 #include <distr/cont.h>
143 #include <distr/corder.h>
144 #include <distr/cvemp.h>
145 #include <distr/discr.h>
146
147 #include <distributions/unur_distributions.h>
148
149 #include <methods/arou.h>
150 #include <methods/ars.h>
151 #include <methods/auto.h>
152 #include <methods/cstd.h>
153 #include <methods/dari.h>
154 #include <methods/dau.h>
155 #include <methods/dgt.h>
156 #include <methods/dsrou.h>
157 #include <methods/dss.h>
158 #include <methods/dstd.h>
159 #include <methods/empk.h>
160 #include <methods/empl.h>
161 #include <methods/gibbs.h>
162 #include <methods/hinv.h>
163 #include <methods/hist.h>
164 #include <methods/hitro.h>
165 #include <methods/hrb.h>
166 #include <methods/hrd.h>
167 #include <methods/hri.h>
168 #include <methods/itdr.h>
169 #include <methods/mcorr.h>
170 #include <methods/mvstd.h>
171 #include <methods/mvtdr.h>
172 #include <methods/ninv.h>
173 #include <methods/norta.h>
174 #include <methods/nrou.h>
175 #include <methods/pinv.h>
176 #include <methods/srou.h>
177 #include <methods/ssr.h>
178 #include <methods/tabl.h>
179 #include <methods/tdr.h>
180 #include <methods/unif.h>
181 #include <methods/utdr.h>
182 #include <methods/vempk.h>
183 #include <methods/vnrou.h>
184
185 #if defined(UNUR_URNG_UNURAN) && defined(UNURAN_HAS_PRNG)
186 #include <uniform/urng_prng.h>
187 #endif
188
189 /*---------------------------------------------------------------------------*/
190 /* Variants: none */
191
192 /*---------------------------------------------------------------------------*/
193 /* Debugging flags */
194 /* bit 01 ... pameters and structure of generator (do not use here) */
195 /* bits 02-12 ... setup */
196 /* bits 13-24 ... adaptive steps */
197 /* bits 25-32 ... trace sampling */
198
199 /*---------------------------------------------------------------------------*/
200 /* Flags for logging set calls */
201
202 /*---------------------------------------------------------------------------*/
203
204 #define GENTYPE "STRING" /* (pseudo) type of generator */
205
206 /*---------------------------------------------------------------------------*/
207
208 static struct unur_distr *_unur_str_distr( char *str_distr );
209 /*---------------------------------------------------------------------------*/
210 /* get distribution object for given distribution. */
211 /*---------------------------------------------------------------------------*/
212
213 static struct unur_distr *_unur_str_distr_new( char *distribution );
214 /*---------------------------------------------------------------------------*/
215 /* get new distribution object. */
216 /*---------------------------------------------------------------------------*/
217
218 static struct unur_distr *_unur_str_distr_make_os( UNUR_DISTR *distr,
219 const char *key,
220 char *type_args, char **args );
221 /*---------------------------------------------------------------------------*/
222 /* Make distribution object for order statistics of given distribution. */
223 /*---------------------------------------------------------------------------*/
224
225 static int _unur_str_distr_set( UNUR_DISTR **ptr_distr, const char *key, char *value );
226 /*---------------------------------------------------------------------------*/
227 /* set parameters for distribution. */
228 /*---------------------------------------------------------------------------*/
229
230 /*---------------------------------------------------------------------------*/
231 /* Set parameter in given distribution object. */
232 /*---------------------------------------------------------------------------*/
233 typedef int distr_set_i( UNUR_DISTR *distr, int i );
234 typedef int distr_set_ii( UNUR_DISTR *distr, int i1, int i2 );
235 typedef int distr_set_d( UNUR_DISTR *distr, double d );
236 typedef int distr_set_dd( UNUR_DISTR *distr, double d1, double d2 );
237 typedef int distr_set_Di( UNUR_DISTR *distr, const double *array, int size );
238 typedef int distr_set_C( UNUR_DISTR *distr, const char *string );
239 /*---------------------------------------------------------------------------*/
240 /* types of set calls */
241 /*---------------------------------------------------------------------------*/
242
243 static int _unur_str_distr_set_i( UNUR_DISTR *distr, const char *key, char *type_args, char **args,
244 distr_set_i set );
245 /*---------------------------------------------------------------------------*/
246 /* integer. */
247 /*---------------------------------------------------------------------------*/
248
249 static int _unur_str_distr_set_ii( UNUR_DISTR *distr, const char *key, char *type_args, char **args,
250 distr_set_ii set );
251 /*---------------------------------------------------------------------------*/
252 /* 2 integers. */
253 /*---------------------------------------------------------------------------*/
254
255 static int _unur_str_distr_set_d( UNUR_DISTR *distr, const char *key, char *type_args, char **args,
256 distr_set_d set );
257 /*---------------------------------------------------------------------------*/
258 /* double. */
259 /*---------------------------------------------------------------------------*/
260
261 static int _unur_str_distr_set_dd( UNUR_DISTR *distr, const char *key, char *type_args, char **args,
262 distr_set_dd set );
263 /*---------------------------------------------------------------------------*/
264 /* 2 doubles. */
265 /*---------------------------------------------------------------------------*/
266
267 static int _unur_str_distr_set_Di( UNUR_DISTR *distr, const char *key, char *type_args, char **args,
268 distr_set_Di set );
269 /*---------------------------------------------------------------------------*/
270 /* array of doubles & integer. */
271 /*---------------------------------------------------------------------------*/
272
273 static int _unur_str_distr_set_C( UNUR_DISTR *distr, const char *key, char *type_args, char **args,
274 distr_set_C set );
275 /*---------------------------------------------------------------------------*/
276 /* constant string. */
277 /*---------------------------------------------------------------------------*/
278
279
280 static struct unur_par *_unur_str_par( char *str_method, const UNUR_DISTR *distr,
281 struct unur_slist *mlist );
282 /*---------------------------------------------------------------------------*/
283 /* get parameter object for distribution and method. */
284 /*---------------------------------------------------------------------------*/
285
286 static struct unur_par *_unur_str_par_new( const char *method, const UNUR_DISTR *distr );
287 /*---------------------------------------------------------------------------*/
288 /* get new parameter object for method. */
289 /*---------------------------------------------------------------------------*/
290
291 static int _unur_str_par_set( UNUR_PAR *par, const char *key, char *value,
292 struct unur_slist *mlist );
293 /*---------------------------------------------------------------------------*/
294 /* set parameters for method. */
295 /*---------------------------------------------------------------------------*/
296
297 /*---------------------------------------------------------------------------*/
298 /* Set parameter in given parameter object. */
299 /*---------------------------------------------------------------------------*/
300 typedef int par_set_void( UNUR_PAR *par );
301 typedef int par_set_i( UNUR_PAR *par, int i );
302 typedef int par_set_ii( UNUR_PAR *par, int i1, int i2 );
303 typedef int par_set_u( UNUR_PAR *par, unsigned u );
304 typedef int par_set_d( UNUR_PAR *par, double d );
305 typedef int par_set_dd( UNUR_PAR *par, double d1, double d2 );
306 typedef int par_set_iD( UNUR_PAR *par, int size, const double *array );
307 typedef int par_set_Di( UNUR_PAR *par, const double *array, int size );
308 /*---------------------------------------------------------------------------*/
309 /* types of set calls */
310 /*---------------------------------------------------------------------------*/
311
312 static int _unur_str_par_set_void( UNUR_PAR *par, const char *key, char *type_args, char **args,
313 par_set_void set );
314 /*---------------------------------------------------------------------------*/
315 /* void (no argument required). */
316 /*---------------------------------------------------------------------------*/
317
318 static int _unur_str_par_set_i( UNUR_PAR *par, const char *key, char *type_args, char **args,
319 par_set_i set );
320 /*---------------------------------------------------------------------------*/
321 /* integer. */
322 /*---------------------------------------------------------------------------*/
323
324 static int _unur_str_par_set_ii( UNUR_PAR *par, const char *key, char *type_args, char **args,
325 par_set_ii set );
326 /*---------------------------------------------------------------------------*/
327 /* 2 integers. */
328 /*---------------------------------------------------------------------------*/
329
330 static int _unur_str_par_set_u( UNUR_PAR *par, const char *key, char *type_args, char **args,
331 par_set_u set );
332 /*---------------------------------------------------------------------------*/
333 /* unsigned integer. */
334 /*---------------------------------------------------------------------------*/
335
336 static int _unur_str_par_set_d( UNUR_PAR *par, const char *key, char *type_args, char **args,
337 par_set_d set );
338 /*---------------------------------------------------------------------------*/
339 /* double. */
340 /*---------------------------------------------------------------------------*/
341
342 static int _unur_str_par_set_dd( UNUR_PAR *par, const char *key, char *type_args, char **args,
343 par_set_dd set );
344
345 /*---------------------------------------------------------------------------*/
346 /* 2 doubles. */
347 /*---------------------------------------------------------------------------*/
348
349 static int _unur_str_par_set_iD( UNUR_PAR *par, const char *key, char *type_args, char **args,
350 par_set_iD set, struct unur_slist *mlist );
351 /*---------------------------------------------------------------------------*/
352 /* integer & array of doubles. */
353 /*---------------------------------------------------------------------------*/
354
355 static int _unur_str_par_set_Di( UNUR_PAR *par, const char *key, char *type_args, char **args,
356 par_set_Di set, struct unur_slist *mlist );
357 /*---------------------------------------------------------------------------*/
358 /* array of doubles & integer. */
359 /*---------------------------------------------------------------------------*/
360
361
362 static UNUR_URNG *_unur_str2urng( char *str_urng );
363 /*---------------------------------------------------------------------------*/
364 /* get uniform RNG. */
365 /*---------------------------------------------------------------------------*/
366
367
368 static int _unur_str_set_args( char *value, char *type_args, char **args, int max_args );
369 /*---------------------------------------------------------------------------*/
370 /* parse argument string for set call. */
371 /*---------------------------------------------------------------------------*/
372
373 static int _unur_parse_ilist( char *liststr, int **iarray );
374 /*---------------------------------------------------------------------------*/
375 /* Process a comma separated list of integers. */
376 /*---------------------------------------------------------------------------*/
377
378 static int _unur_parse_dlist( char *liststr, double **darray );
379 /*---------------------------------------------------------------------------*/
380 /* Process a comma separated list of numbers. */
381 /*---------------------------------------------------------------------------*/
382
383 static int _unur_atoi ( const char *str );
384 /*---------------------------------------------------------------------------*/
385 /* Convert string into its integer representation. */
386 /*---------------------------------------------------------------------------*/
387
388 static unsigned _unur_atou ( const char *str );
389 /*---------------------------------------------------------------------------*/
390 /* Convert string into its unsigned representation (using hexadecimal). */
391 /*---------------------------------------------------------------------------*/
392
393 static double _unur_atod ( const char *str );
394 /*---------------------------------------------------------------------------*/
395 /* Convert string into its double value. */
396 /*---------------------------------------------------------------------------*/
397
398 /*---------------------------------------------------------------------------*/
399 #ifdef UNUR_ENABLE_LOGGING
400 /*---------------------------------------------------------------------------*/
401 /* the following functions print debugging information on output stream, */
402 /* i.e., into the LOG file if not specified otherwise. */
403 /*---------------------------------------------------------------------------*/
404
405 static void _unur_str_debug_string( int level, const char *key, const char *value );
406 /*---------------------------------------------------------------------------*/
407 /* print key & value info into LOG file. */
408 /*---------------------------------------------------------------------------*/
409
410 static void _unur_str_debug_distr( int level, const char *name, double *params, int n_params );
411 /*---------------------------------------------------------------------------*/
412 /* write info about distribution into LOG file. */
413 /*---------------------------------------------------------------------------*/
414
415 static void _unur_str_debug_set( int level, const char *key, const char *type, ... );
416
417 /*---------------------------------------------------------------------------*/
418 /* write info about set command into LOG file. */
419 /*---------------------------------------------------------------------------*/
420
421 #endif
422 /*---------------------------------------------------------------------------*/
423
424
425 static void _unur_str_error_unknown( const char *file, int line, const char *key, const char *type );
426 /*---------------------------------------------------------------------------*/
427 /* print error message: unknown keyword. */
428 /*---------------------------------------------------------------------------*/
429
430 static void _unur_str_error_invalid( const char *file, int line, const char *key, const char *type );
431 /*---------------------------------------------------------------------------*/
432 /* print error message: invalid data for keyword. */
433 /*---------------------------------------------------------------------------*/
434
435 static void _unur_str_error_args( const char *file, int line, const char *key );
436 /*---------------------------------------------------------------------------*/
437 /* print error message: invalid argument string for set call. */
438 /*---------------------------------------------------------------------------*/
439
440 /*---------------------------------------------------------------------------*/
441 /* abbreviations */
442
443 #define _unur_error_unknown(key,what) \
444 do { \
445 _unur_str_error_unknown( __FILE__,__LINE__, (key), (what) ); \
446 } while (0)
447
448 /* invalid data for key */
449 #define _unur_error_invalid(key,what) \
450 do { \
451 _unur_str_error_invalid( __FILE__,__LINE__, (key), (what) ); \
452 } while (0)
453
454 /* invalid argument string for set calls */
455 #define _unur_error_args(key) \
456 do { \
457 _unur_str_error_args( __FILE__,__LINE__, (key) ); \
458 } while (0)
459
460
461 /*---------------------------------------------------------------------------*/
462 /* constants */
463
464 #define MAX_SET_ARGS (10)
465 /* maximal number of arguments for set calls (must be at least 2) */
466
467 /*---------------------------------------------------------------------------*/
468
469 /*****************************************************************************/
470 /** Load lists of ..._new and ..._set calls **/
471 /*****************************************************************************/
472
473 #include "stringparser_lists.ch"
474
475 /*****************************************************************************/
476 /** User Interface **/
477 /*****************************************************************************/
478
479 /*---------------------------------------------------------------------------*/
480
481 struct unur_gen *
unur_str2gen(const char * string)482 unur_str2gen (const char *string)
483 /*----------------------------------------------------------------------*/
484 /* get generator object for distribution and method */
485 /* */
486 /* parameters: */
487 /* string ... string that contains description of generator */
488 /* */
489 /* return: */
490 /* generator object */
491 /* */
492 /* error: */
493 /* return NULL */
494 /*----------------------------------------------------------------------*/
495 {
496 UNUR_DISTR *distr = NULL; /* distribution object */
497 UNUR_PAR *par = NULL; /* parameter object */
498 UNUR_GEN *gen = NULL; /* generator object */
499 UNUR_URNG *urng = NULL; /* uniform random number generator */
500
501 char *str_distr = NULL; /* string for distribution */
502 char *str_method = NULL; /* string for method */
503 char *str_urng = NULL; /* string for uniform RNG */
504
505 char *str = NULL; /* pointer to working string */
506 char *token;
507
508 struct unur_slist *mlist; /* list of allocated memory blocks */
509
510 /* check arguments */
511 _unur_check_NULL( GENTYPE,string,NULL );
512
513 /* (empty) list of allocated memory blocks */
514 mlist = _unur_slist_new();
515
516 /* Prepare string for processing: */
517 /* Remove all white spaces, */
518 /* convert to lower case letters, */
519 /* copy into working string */
520 str = _unur_parser_prepare_string( string );
521
522 #ifdef UNUR_ENABLE_LOGGING
523 /* write info into LOG file */
524 if (_unur_default_debugflag)
525 _unur_str_debug_string(0,"[input]",str);
526 #endif
527
528 /* split string into blocks separated by ampersands '&' */
529
530 /* the first block must contain the distribution */
531 str_distr = strtok(str, "&");
532
533 /* new get all the other tokens */
534 for ( token = strtok(NULL, "&");
535 token != NULL;
536 token = strtok(NULL, "&") ) {
537
538 /* get type of block */
539 if (!strncmp(token,"method=",(size_t)7)) {
540 str_method = token;
541 }
542 else if (!strncmp(token,"urng=",(size_t)5)) {
543 str_urng = token;
544 }
545 else {
546 _unur_error_unknown(token,"category");
547 _unur_slist_free( mlist );
548 if (str) free(str);
549 return NULL;
550 }
551 }
552
553 /* make distribution object */
554 distr = _unur_str_distr(str_distr);
555 if ( distr == NULL ) {
556 /* error */
557 _unur_slist_free( mlist );
558 if (str) free(str);
559 return NULL;
560 }
561
562 /* get parameter object */
563 if ( str_method != NULL )
564 /* method is provided in string */
565 par = _unur_str_par(str_method, distr, mlist);
566 else
567 /* otherwise use default method */
568 par = unur_auto_new(distr);
569
570 /* make generator object */
571 gen = unur_init(par);
572
573 /* destroy distribution object */
574 unur_distr_free(distr);
575
576 /* set uniform random number generator -- if provided */
577 if ( str_urng != NULL )
578 if (gen != NULL) {
579 /* we need a valid generator object */
580 if ((urng = _unur_str2urng(str_urng)) != NULL )
581 unur_chg_urng(gen, urng);
582 }
583
584 /* free allocated memory blocks */
585 _unur_slist_free(mlist);
586 if (str) free(str);
587
588 /* check result: nothing to do */
589 /* if ( gen == NULL ) { */
590 /* error */
591 /* return NULL; */
592 /* } */
593
594 #ifdef UNUR_ENABLE_LOGGING
595 /* write info into LOG file */
596 if (_unur_default_debugflag)
597 _unur_str_debug_string(0,"",NULL);
598 #endif
599
600 /* return pointer to generator object */
601 return gen;
602
603 } /* end of unur_str2gen() */
604
605 /*---------------------------------------------------------------------------*/
606
607 struct unur_par *
_unur_str2par(const struct unur_distr * distr,const char * string,struct unur_slist ** mlist)608 _unur_str2par (const struct unur_distr *distr, const char *string, struct unur_slist **mlist )
609 /*----------------------------------------------------------------------*/
610 /* get parameter object for distribution and method */
611 /* */
612 /* parameters: */
613 /* distr ... pointer to distribution object */
614 /* string ... string that contains description of method */
615 /* mlist ... pointer to simple list for allocated memory blocks */
616 /* */
617 /* return: */
618 /* parameter object */
619 /* */
620 /* error: */
621 /* return NULL */
622 /*----------------------------------------------------------------------*/
623 {
624 UNUR_PAR *par = NULL; /* parameter object */
625 char *str = NULL; /* pointer to working string */
626
627 /* check arguments */
628 _unur_check_NULL( GENTYPE,distr,NULL );
629 _unur_check_NULL( GENTYPE,string,NULL );
630
631 /* (empty) list of allocated memory blocks */
632 *mlist = _unur_slist_new();
633
634 /* Prepare string for processing: */
635 /* Remove all white spaces, */
636 /* convert to lower case letters, */
637 /* copy into working string */
638 str = _unur_parser_prepare_string( string );
639
640 #ifdef UNUR_ENABLE_LOGGING
641 /* write info into LOG file */
642 if (_unur_default_debugflag)
643 _unur_str_debug_string(0,"[input]",str);
644 #endif
645
646 /* get parameter object */
647 par = _unur_str_par(str, distr, *mlist);
648
649 /* free allocated memory blocks */
650 if (str) free(str);
651
652 #ifdef UNUR_ENABLE_LOGGING
653 /* write info into LOG file */
654 if (_unur_default_debugflag)
655 if ( par != NULL )
656 _unur_str_debug_string(0,"",NULL);
657 #endif
658
659 /* return pointer to parameter object */
660 return par;
661
662 } /* end of _unur_str2par() */
663
664 /*---------------------------------------------------------------------------*/
665
666 struct unur_distr *
unur_str2distr(const char * string)667 unur_str2distr (const char *string)
668 /*----------------------------------------------------------------------*/
669 /* get distribution object for given distribution */
670 /* */
671 /* parameters: */
672 /* string ... string that contains description of distribution */
673 /* */
674 /* return: */
675 /* distribution object */
676 /* */
677 /* error: */
678 /* return NULL */
679 /*----------------------------------------------------------------------*/
680 {
681 UNUR_DISTR *distr = NULL; /* distribution object */
682 char *str = NULL; /* pointer to working string */
683
684 /* check arguments */
685 _unur_check_NULL( GENTYPE,string,NULL );
686
687 /* Prepare string for processing: */
688 /* Remove all white spaces, */
689 /* convert to lower case letters, */
690 /* copy into working string */
691 str = _unur_parser_prepare_string( string );
692
693 #ifdef UNUR_ENABLE_LOGGING
694 /* write info into LOG file */
695 if (_unur_default_debugflag)
696 _unur_str_debug_string(0,"[input]",str);
697 #endif
698
699 /* make distribution object */
700 distr = _unur_str_distr(str);
701
702 /* free allocated memory blocks */
703 if (str) free(str);
704
705 #ifdef UNUR_ENABLE_LOGGING
706 /* write info into LOG file */
707 if (_unur_default_debugflag)
708 if ( distr != NULL )
709 _unur_str_debug_string(0,"",NULL);
710 #endif
711
712 /* return pointer to distribution object */
713 return distr;
714
715 } /* end of unur_str2distr() */
716
717 /*---------------------------------------------------------------------------*/
718
719 struct unur_gen *
unur_makegen_ssu(const char * distrstr,const char * methodstr,UNUR_URNG * urng)720 unur_makegen_ssu( const char *distrstr, const char *methodstr, UNUR_URNG *urng )
721 /*----------------------------------------------------------------------*/
722 /* get generator object for distribution and method */
723 /* */
724 /* parameters: */
725 /* distrstr ... distribution described by a string */
726 /* methodstr ... chosen method described by a string */
727 /* urng ... pointer to uniform random number generator */
728 /* (NULL = default generator) */
729 /* */
730 /* return: */
731 /* generator object */
732 /* */
733 /* error: */
734 /* return NULL */
735 /*----------------------------------------------------------------------*/
736 {
737 UNUR_DISTR *distr = NULL; /* distribution object */
738 UNUR_PAR *par = NULL; /* parameter object */
739 UNUR_GEN *gen = NULL; /* generator object */
740
741 char *str_distr = NULL; /* string for distribution */
742 char *str_method = NULL; /* string for method */
743
744 struct unur_slist *mlist; /* list of allocated memory blocks */
745
746 /* check arguments */
747 _unur_check_NULL( GENTYPE, distrstr, NULL );
748
749 /* (empty) list of allocated memory blocks */
750 mlist = _unur_slist_new();
751
752 /* Prepare string for processing: */
753 /* Remove all white spaces, */
754 /* convert to lower case letters, */
755 /* copy into working string */
756 str_distr = _unur_parser_prepare_string( distrstr );
757 str_method = (methodstr)
758 ? _unur_parser_prepare_string( methodstr )
759 : NULL;
760
761 #ifdef UNUR_ENABLE_LOGGING
762 /* write info into LOG file */
763 if (_unur_default_debugflag) {
764 _unur_str_debug_string(0,"[input-distr]",str_distr);
765 _unur_str_debug_string(0,"[input-method]",
766 (str_method) ? str_method : "(NULL)" );
767 }
768 #endif
769
770 do {
771 /* make distribution object */
772 distr = _unur_str_distr(str_distr);
773 if (distr == NULL) break;
774
775 /* get parameter object */
776 if ( str_method != NULL && strlen(str_method)>0 )
777 /* method is provided in string */
778 par = _unur_str_par(str_method, distr, mlist);
779 else
780 /* otherwise use default method */
781 par = unur_auto_new(distr);
782 if (par == NULL) break;
783
784 /* make generator object */
785 gen = unur_init(par);
786 if (gen == NULL) break;
787
788 /* set uniform RNG */
789 if (urng != NULL)
790 unur_chg_urng(gen, urng);
791
792 } while (0);
793
794 /* destroy distribution object */
795 unur_distr_free(distr);
796
797 /* free allocated memory blocks */
798 _unur_slist_free(mlist);
799 if (str_distr) free(str_distr);
800 if (str_method) free(str_method);
801
802 #ifdef UNUR_ENABLE_LOGGING
803 /* write info into LOG file */
804 if (_unur_default_debugflag)
805 _unur_str_debug_string(0,"",NULL);
806 #endif
807
808 /* return pointer to generator object */
809 return gen;
810
811 } /* end of unur_makegen_ssu() */
812
813 /*---------------------------------------------------------------------------*/
814
815 struct unur_gen *
unur_makegen_dsu(const struct unur_distr * distr,const char * methodstr,UNUR_URNG * urng)816 unur_makegen_dsu( const struct unur_distr *distr, const char *methodstr, UNUR_URNG *urng )
817 /*----------------------------------------------------------------------*/
818 /* get generator object for distribution and method */
819 /* */
820 /* parameters: */
821 /* distr ... distribution object */
822 /* methodstr ... chosen method described by a string */
823 /* urng ... pointer to uniform random number generator */
824 /* (NULL = default generator) */
825 /* */
826 /* return: */
827 /* generator object */
828 /* */
829 /* error: */
830 /* return NULL */
831 /*----------------------------------------------------------------------*/
832 {
833 UNUR_PAR *par = NULL; /* parameter object */
834 UNUR_GEN *gen = NULL; /* generator object */
835
836 char *str_method = NULL; /* string for method */
837
838 struct unur_slist *mlist; /* list of allocated memory blocks */
839
840 /* check arguments */
841 _unur_check_NULL( GENTYPE,distr,NULL );
842
843 /* (empty) list of allocated memory blocks */
844 mlist = _unur_slist_new();
845
846 /* Prepare string for processing: */
847 /* Remove all white spaces, */
848 /* convert to lower case letters, */
849 /* copy into working string */
850 str_method = (methodstr)
851 ? _unur_parser_prepare_string( methodstr )
852 : NULL;
853
854 #ifdef UNUR_ENABLE_LOGGING
855 /* write info into LOG file */
856 if (_unur_default_debugflag) {
857 _unur_str_debug_string(0,"[input-distr]","(distribution object)");
858 _unur_str_debug_string(0,"[input-method]",
859 (str_method) ? str_method : "(NULL)" );
860 }
861 #endif
862
863 do {
864 /* get parameter object */
865 if ( str_method != NULL && strlen(str_method)>0 )
866 /* method is provided in string */
867 par = _unur_str_par(str_method, distr, mlist);
868 else
869 /* otherwise use default method */
870 par = unur_auto_new(distr);
871 if (par == NULL) break;
872
873 /* make generator object */
874 gen = unur_init(par);
875 if (gen == NULL) break;
876
877 /* set uniform RNG */
878 if (urng != NULL)
879 unur_chg_urng(gen, urng);
880
881 } while (0);
882
883 /* free allocated memory blocks */
884 _unur_slist_free(mlist);
885 if (str_method) free(str_method);
886
887 #ifdef UNUR_ENABLE_LOGGING
888 /* write info into LOG file */
889 if (_unur_default_debugflag)
890 _unur_str_debug_string(0,"",NULL);
891 #endif
892
893 /* return pointer to generator object */
894 return gen;
895
896 } /* end of unur_makegen_dsu() */
897
898 /*---------------------------------------------------------------------------*/
899
900 /*****************************************************************************/
901 /** Distributions **/
902 /*****************************************************************************/
903
904 /*---------------------------------------------------------------------------*/
905
906 struct unur_distr *
_unur_str_distr(char * str_distr)907 _unur_str_distr( char *str_distr )
908 /*----------------------------------------------------------------------*/
909 /* get distribution object for given distribution */
910 /* */
911 /* parameters: */
912 /* str_distr ... string that contains description of distribution */
913 /* */
914 /* return: */
915 /* distribution object */
916 /* */
917 /* error: */
918 /* return NULL */
919 /*----------------------------------------------------------------------*/
920 {
921 struct unur_distr *distr = NULL;
922
923 char *token; /* pointer to token in string */
924 char *next; /* pointer to next token in string */
925 char *key, *value; /* the key and its value */
926
927
928 /* tokenize the string using ';' as separator and handle the tokens */
929 for ( token = next = str_distr;
930 next != NULL && *token != '\0';
931 token = next ) {
932
933 /* find end of token (i.e. the pointer to next token) */
934 next = strchr(token,';');
935 if (next != NULL) {
936 /* next separator found */
937 *next = '\0'; /* terminate token string */
938 next++; /* set pointer to next token */
939 }
940
941 /* token points to a key */
942 key = token;
943
944 /* get the value from the pair key=value and terminate key string */
945 value = strchr(key, '=');
946 if (value != NULL) {
947 *value = '\0'; /* terminate key string */
948 value++; /* set pointer to value string */
949 }
950
951 /* the first key is treated differently: get new distribution object */
952 if (key == str_distr) {
953 /* the keyword "distr" is optional */
954 if (value == NULL) {
955 /* no "distribution" keyword given, so the key points to the value */
956 value = key;
957 }
958 else {
959 if (*key != 'd') {
960 _unur_error(GENTYPE,UNUR_ERR_STR_SYNTAX,"key for distribution does not start with 'd'");
961 _unur_distr_free(distr); /* remark: added for ROOT to make coverity integrity manager happy */
962 return NULL;
963 }
964 }
965
966 /* get new distribution object */
967 if (distr != NULL) {
968 _unur_error(GENTYPE,UNUR_ERR_SHOULD_NOT_HAPPEN,"");
969 _unur_distr_free(distr);
970 }
971
972 distr = _unur_str_distr_new(value);
973 if (distr == NULL) {
974 /* error */
975 /* _unur_error(GENTYPE,UNUR_ERR_STR,"setting distribution failed"); */
976 return NULL;
977 }
978 }
979
980 /* set parameters for distribution */
981 else {
982 if (_unur_str_distr_set(&distr, key, value)!=UNUR_SUCCESS ) {
983 /* error */
984 _unur_distr_free(distr);
985 /* _unur_error(GENTYPE,UNUR_ERR_STR,"setting distribution failed"); */
986 return NULL;
987 }
988 }
989 }
990
991 return distr;
992
993 } /* end of _unur_str_distr() */
994
995 /*---------------------------------------------------------------------------*/
996
997 struct unur_distr *
_unur_str_distr_make_os(UNUR_DISTR * distr,const char * key,char * type_args,char ** args)998 _unur_str_distr_make_os (UNUR_DISTR *distr, const char *key, char *type_args, char **args)
999 /*----------------------------------------------------------------------*/
1000 /* Make distribution object for order statistics of given distribution. */
1001 /* The given distribution `distr' is destroyed. */
1002 /* The list of arguments and their types are given as string. */
1003 /* */
1004 /* type: "ii" (int,int) */
1005 /* */
1006 /* input: "tt" (exactly two single tokens) */
1007 /* "L" (exactly one list) */
1008 /* */
1009 /* action: */
1010 /* if "tt": convert both to int. */
1011 /* execute set call. */
1012 /* if "L": convert list entries to int. */
1013 /* execute set call with first two entries. */
1014 /* (error if list has less than two entries) */
1015 /* otherwise: error */
1016 /* */
1017 /* parameters: */
1018 /* distr ... pointer to distribution object */
1019 /* key ... name of parameter to be set */
1020 /* type_args ... contains types of arguments. Possible values: */
1021 /* 't' for single token */
1022 /* 'L' for a list */
1023 /* args ... array of pointers to argument strings */
1024 /* */
1025 /* return: */
1026 /* pointer to distribution object for order statistics */
1027 /* */
1028 /* error: */
1029 /* return NULL */
1030 /*----------------------------------------------------------------------*/
1031 {
1032 int *iarray = NULL; /* pointer to working array */
1033 struct unur_distr *os = NULL; /* pointer to order statistics object */
1034
1035 /* either exactly two arguments are given */
1036 if ( !strcmp(type_args, "tt") ) {
1037 iarray = _unur_xmalloc( 2*sizeof(double) );
1038 iarray[0] = _unur_atoi( args[0] );
1039 iarray[1] = _unur_atoi( args[1] );
1040 }
1041
1042 /* or one list with 2 entries is given */
1043 else if ( !strcmp(type_args, "L") ) {
1044 if ( _unur_parse_ilist( args[0], &iarray ) < 2 ) {
1045 free (iarray);
1046 iarray = NULL;
1047 }
1048 }
1049
1050 if (iarray == NULL ) {
1051 /* data list empty (incorrect syntax) */
1052 _unur_error_args(key);
1053 #ifdef UNUR_ENABLE_LOGGING
1054 /* write info into LOG file */
1055 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1056 _unur_str_debug_set(2,key,"!");
1057 #endif
1058 return NULL;
1059 }
1060
1061 /* now make object to order statistics */
1062
1063 #ifdef UNUR_ENABLE_LOGGING
1064 /* write info into LOG file */
1065 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1066 _unur_str_debug_set(2,key,"ii",iarray[0],iarray[1] );
1067 #endif
1068
1069 os = unur_distr_corder_new( distr, iarray[0], iarray[1] );
1070
1071 /* free memory */
1072 _unur_distr_free(distr);
1073 free (iarray);
1074
1075 /* return order statistics (or NULL we could not make such a thing) */
1076 return os;
1077
1078 } /* end of _unur_str_distr_make_os() */
1079
1080 /*---------------------------------------------------------------------------*/
1081
1082 int
_unur_str_distr_set_i(UNUR_DISTR * distr,const char * key,char * type_args,char ** args,distr_set_i set)1083 _unur_str_distr_set_i (UNUR_DISTR *distr, const char *key, char *type_args, char **args, distr_set_i set)
1084 /*----------------------------------------------------------------------*/
1085 /* Set parameter in given distribution object. */
1086 /* The list of arguments and their types are given as string. */
1087 /* */
1088 /* type: "i" (int) */
1089 /* */
1090 /* input: "t" (exactly one single token) */
1091 /* void (no argument given) */
1092 /* */
1093 /* action: */
1094 /* convert token to int. */
1095 /* (if no argument is given, use 1.) */
1096 /* execute set call. */
1097 /* error if input != "t" */
1098 /* */
1099 /* parameters: */
1100 /* distr ... pointer to distribution object */
1101 /* key ... name of parameter to be set */
1102 /* type_args ... contains types of arguments. Possible values: */
1103 /* 't' for single token */
1104 /* 'L' for a list */
1105 /* args ... array of pointers to argument strings */
1106 /* set ... pointer to UNU.RAN function for set call */
1107 /* */
1108 /* return: */
1109 /* return code from set call, i.e. */
1110 /* UNUR_SUCCESS ... on success */
1111 /* error code ... on error */
1112 /*----------------------------------------------------------------------*/
1113 {
1114 int iarg;
1115
1116 if ( !strcmp(type_args, "t") ) {
1117 iarg = _unur_atoi( args[0] );
1118 }
1119 else if ( strlen(type_args) == 0 ) {
1120 iarg = 1;
1121 }
1122 else {
1123 _unur_error_args(key);
1124 #ifdef UNUR_ENABLE_LOGGING
1125 /* write info into LOG file */
1126 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1127 _unur_str_debug_set(2,key,"!");
1128 #endif
1129 return UNUR_ERR_STR_INVALID;
1130 }
1131
1132 #ifdef UNUR_ENABLE_LOGGING
1133 /* write info into LOG file */
1134 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1135 _unur_str_debug_set(2,key,"i",iarg);
1136 #endif
1137
1138 return set(distr,iarg);
1139
1140 } /* end of _unur_str_distr_set_i() */
1141
1142 /*---------------------------------------------------------------------------*/
1143
1144 int
_unur_str_distr_set_ii(UNUR_DISTR * distr,const char * key,char * type_args,char ** args,distr_set_ii set)1145 _unur_str_distr_set_ii (UNUR_DISTR *distr, const char *key, char *type_args, char **args, distr_set_ii set)
1146 /*----------------------------------------------------------------------*/
1147 /* Set parameter in given distribution object. */
1148 /* The list of arguments and their types are given as string. */
1149 /* */
1150 /* type: "ii" (int,int) */
1151 /* */
1152 /* input: "tt" (exactly two single tokens) */
1153 /* "L" (exactly one list) */
1154 /* */
1155 /* action: */
1156 /* if "tt": convert both to int. */
1157 /* execute set call. */
1158 /* if "L": convert list entries to int. */
1159 /* execute set call with first two entries. */
1160 /* (error if list has less than two entries) */
1161 /* otherwise: error */
1162 /* */
1163 /* parameters: */
1164 /* distr ... pointer to distribution object */
1165 /* key ... name of parameter to be set */
1166 /* type_args ... contains types of arguments. Possible values: */
1167 /* 't' for single token */
1168 /* 'L' for a list */
1169 /* args ... array of pointers to argument strings */
1170 /* set ... pointer to UNU.RAN function for set call */
1171 /* */
1172 /* return: */
1173 /* return code from set call, i.e. */
1174 /* UNUR_SUCCESS ... on success */
1175 /* error code ... on error */
1176 /*----------------------------------------------------------------------*/
1177 {
1178 int *iarray = NULL;
1179 int iarg[2];
1180 int result;
1181
1182 /* either exactly two arguments are given */
1183 if ( !strcmp(type_args, "tt") ) {
1184 iarg[0] = _unur_atoi( args[0] );
1185 iarg[1] = _unur_atoi( args[1] );
1186
1187 #ifdef UNUR_ENABLE_LOGGING
1188 /* write info into LOG file */
1189 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1190 _unur_str_debug_set(2,key,"ii",iarg[0],iarg[1]);
1191 #endif
1192
1193 return set( distr,iarg[0],iarg[1] );
1194 }
1195
1196 /* or one list with 2 entries is given */
1197 else if ( !strcmp(type_args, "L") ) {
1198 if ( _unur_parse_ilist( args[0], &iarray ) < 2 ) {
1199 _unur_error_args(key);
1200 free (iarray);
1201 #ifdef UNUR_ENABLE_LOGGING
1202 /* write info into LOG file */
1203 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1204 _unur_str_debug_set(2,key,"!");
1205 #endif
1206 return UNUR_ERR_STR_INVALID;
1207 }
1208 result = set( distr,iarray[0],iarray[1] );
1209
1210 #ifdef UNUR_ENABLE_LOGGING
1211 /* write info into LOG file */
1212 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1213 _unur_str_debug_set(2,key,"ii",iarray[0],iarray[1] );
1214 #endif
1215
1216 free (iarray);
1217 return result;
1218 }
1219
1220 else {
1221 _unur_error_args(key);
1222 #ifdef UNUR_ENABLE_LOGGING
1223 /* write info into LOG file */
1224 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1225 _unur_str_debug_set(2,key,"!");
1226 #endif
1227 return UNUR_ERR_STR_INVALID;
1228 }
1229
1230 } /* end of _unur_str_distr_set_ii() */
1231
1232 /*---------------------------------------------------------------------------*/
1233
1234 int
_unur_str_distr_set_d(UNUR_DISTR * distr,const char * key,char * type_args,char ** args,distr_set_d set)1235 _unur_str_distr_set_d (UNUR_DISTR *distr, const char *key, char *type_args, char **args, distr_set_d set)
1236 /*----------------------------------------------------------------------*/
1237 /* Set parameter in given distribution object. */
1238 /* The list of arguments and their types are given as string. */
1239 /* */
1240 /* type: "d" (double) */
1241 /* */
1242 /* input: "t" (exactly one single token) */
1243 /* */
1244 /* action: */
1245 /* convert token to double. */
1246 /* execute set call. */
1247 /* error if input != "t" */
1248 /* */
1249 /* parameters: */
1250 /* distr ... pointer to distribution object */
1251 /* key ... name of parameter to be set */
1252 /* type_args ... contains types of arguments. Possible values: */
1253 /* 't' for single token */
1254 /* 'L' for a list */
1255 /* args ... array of pointers to argument strings */
1256 /* set ... pointer to UNU.RAN function for set call */
1257 /* */
1258 /* return: */
1259 /* return code from set call, i.e. */
1260 /* UNUR_SUCCESS ... on success */
1261 /* error code ... on error */
1262 /*----------------------------------------------------------------------*/
1263 {
1264 double darg;
1265
1266 if ( strcmp(type_args, "t") ) {
1267 _unur_error_args(key);
1268 #ifdef UNUR_ENABLE_LOGGING
1269 /* write info into LOG file */
1270 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1271 _unur_str_debug_set(2,key,"!");
1272 #endif
1273 return UNUR_ERR_STR_INVALID;
1274 }
1275
1276 darg = _unur_atod( args[0] );
1277
1278 #ifdef UNUR_ENABLE_LOGGING
1279 /* write info into LOG file */
1280 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1281 _unur_str_debug_set(2,key,"d",darg);
1282 #endif
1283
1284 return set(distr,darg);
1285
1286 } /* end of _unur_str_distr_set_d() */
1287
1288 /*---------------------------------------------------------------------------*/
1289
1290 int
_unur_str_distr_set_dd(UNUR_DISTR * distr,const char * key,char * type_args,char ** args,distr_set_dd set)1291 _unur_str_distr_set_dd (UNUR_DISTR *distr, const char *key, char *type_args, char **args, distr_set_dd set)
1292 /*----------------------------------------------------------------------*/
1293 /* Set parameter in given distribution object. */
1294 /* The list of arguments and their types are given as string. */
1295 /* */
1296 /* type: "dd" (double,double) */
1297 /* */
1298 /* input: "tt" (exactly two single tokens) */
1299 /* "L" (exactly one list) */
1300 /* */
1301 /* action: */
1302 /* if "tt": convert both to double. */
1303 /* execute set call. */
1304 /* if "L": convert list entries to double. */
1305 /* execute set call with first two entries. */
1306 /* (error if list has less than two entries) */
1307 /* otherwise: error */
1308 /* */
1309 /* parameters: */
1310 /* distr ... pointer to distribution object */
1311 /* key ... name of parameter to be set */
1312 /* type_args ... contains types of arguments. Possible values: */
1313 /* 't' for single token */
1314 /* 'L' for a list */
1315 /* args ... array of pointers to argument strings */
1316 /* set ... pointer to UNU.RAN function for set call */
1317 /* */
1318 /* return: */
1319 /* return code from set call, i.e. */
1320 /* UNUR_SUCCESS ... on success */
1321 /* error code ... on error */
1322 /*----------------------------------------------------------------------*/
1323 {
1324 double *darray = NULL;
1325 double darg[2];
1326 int result;
1327
1328 /* either exactly two arguments are given */
1329 if ( !strcmp(type_args, "tt") ) {
1330 darg[0] = _unur_atod( args[0] );
1331 darg[1] = _unur_atod( args[1] );
1332
1333 #ifdef UNUR_ENABLE_LOGGING
1334 /* write info into LOG file */
1335 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1336 _unur_str_debug_set(2,key,"dd",darg[0],darg[1]);
1337 #endif
1338
1339 return set( distr,darg[0],darg[1] );
1340 }
1341
1342 /* or one list with 2 entries is given */
1343 else if ( !strcmp(type_args, "L") ) {
1344 if ( _unur_parse_dlist( args[0], &darray ) < 2 ) {
1345 _unur_error_args(key);
1346 free (darray);
1347 #ifdef UNUR_ENABLE_LOGGING
1348 /* write info into LOG file */
1349 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1350 _unur_str_debug_set(2,key,"!");
1351 #endif
1352 return UNUR_ERR_STR_INVALID;
1353 }
1354 result = set( distr,darray[0],darray[1] );
1355
1356 #ifdef UNUR_ENABLE_LOGGING
1357 /* write info into LOG file */
1358 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1359 _unur_str_debug_set(2,key,"dd",darray[0],darray[1] );
1360 #endif
1361
1362 free (darray);
1363 return result;
1364 }
1365
1366 else {
1367 _unur_error_args(key);
1368 #ifdef UNUR_ENABLE_LOGGING
1369 /* write info into LOG file */
1370 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1371 _unur_str_debug_set(2,key,"!");
1372 #endif
1373 return UNUR_ERR_STR_INVALID;
1374 }
1375
1376 } /* end of _unur_str_distr_set_dd() */
1377
1378 /*---------------------------------------------------------------------------*/
1379
1380 int
_unur_str_distr_set_Di(UNUR_DISTR * distr,const char * key,char * type_args,char ** args,distr_set_Di set)1381 _unur_str_distr_set_Di (UNUR_DISTR *distr, const char *key, char *type_args, char **args, distr_set_Di set)
1382 /*----------------------------------------------------------------------*/
1383 /* Set parameter in given distribution object. */
1384 /* The list of arguments and their types are given as string. */
1385 /* */
1386 /* type: "Di" (array of doubles, int) */
1387 /* */
1388 /* input: "Lt" (list & single token) */
1389 /* "L" (exactly one list) */
1390 /* */
1391 /* action: */
1392 /* if "L": convert list to array of doubles. */
1393 /* execute set with size if array as second argument. */
1394 /* if "Lt": convert list to array of doubles. */
1395 /* convert second token to int. */
1396 /* set int to min of int and size of array. */
1397 /* execute set call with int and array. */
1398 /* otherwise: error */
1399 /* */
1400 /* parameters: */
1401 /* distr ... pointer to distribution object */
1402 /* key ... name of parameter to be set */
1403 /* type_args ... contains types of arguments. Possible values: */
1404 /* 't' for single token */
1405 /* 'L' for a list */
1406 /* args ... array of pointers to argument strings */
1407 /* set ... pointer to UNU.RAN function for set call */
1408 /* */
1409 /* return: */
1410 /* return code from set call, i.e. */
1411 /* UNUR_SUCCESS ... on success */
1412 /* error code ... on error */
1413 /*----------------------------------------------------------------------*/
1414 {
1415 int result;
1416 int t_size;
1417 int size = -1;
1418 double *darray = NULL;
1419
1420 /* either an integer and a list are given */
1421 if ( !strcmp(type_args, "Lt") ) {
1422 t_size = _unur_atoi( args[1] );
1423 size = _unur_parse_dlist( args[0], &darray );
1424 if (size > t_size)
1425 size = t_size;
1426 }
1427
1428 /* or only a list is given */
1429 else if ( !strcmp(type_args, "L") ) {
1430 size = _unur_parse_dlist( args[0], &darray );
1431 }
1432
1433 /* or there is a syntax error */
1434 if ( !(size>0) ) {
1435 _unur_error_args(key);
1436 #ifdef UNUR_ENABLE_LOGGING
1437 /* write info into LOG file */
1438 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1439 _unur_str_debug_set(2,key,"!");
1440 #endif
1441 result = UNUR_ERR_STR_INVALID;
1442 }
1443
1444 else {
1445 /* execute set command */
1446 result = set( distr,darray,size );
1447 #ifdef UNUR_ENABLE_LOGGING
1448 /* write info into LOG file */
1449 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1450 _unur_str_debug_set(2,key,"Di",darray,size,size);
1451 #endif
1452 }
1453
1454 if (darray) free (darray);
1455
1456 return result;
1457
1458 } /* end of _unur_str_distr_set_Di() */
1459
1460 /*---------------------------------------------------------------------------*/
1461
1462 int
_unur_str_distr_set_C(UNUR_DISTR * distr,const char * key,char * type_args,char ** args,distr_set_C set)1463 _unur_str_distr_set_C (UNUR_DISTR *distr, const char *key, char *type_args, char **args, distr_set_C set)
1464 /*----------------------------------------------------------------------*/
1465 /* Set parameter in given distribution object. */
1466 /* The list of arguments and their types are given as string. */
1467 /* */
1468 /* type: "C" (string = array of char) */
1469 /* */
1470 /* input: "s" (exactly one string) */
1471 /* */
1472 /* action: */
1473 /* execute set call. */
1474 /* error if input != "s" */
1475 /* */
1476 /* parameters: */
1477 /* distr ... pointer to distribution object */
1478 /* key ... name of parameter to be set */
1479 /* type_args ... contains types of arguments. Possible values: */
1480 /* 's' for single string */
1481 /* args ... array of pointers to argument strings */
1482 /* set ... pointer to UNU.RAN function for set call */
1483 /* */
1484 /* return: */
1485 /* return code from set call, i.e. */
1486 /* UNUR_SUCCESS ... on success */
1487 /* error code ... on error */
1488 /*----------------------------------------------------------------------*/
1489 {
1490 char *string;
1491
1492 if ( strcmp(type_args, "s") ) {
1493 _unur_error_args(key);
1494 #ifdef UNUR_ENABLE_LOGGING
1495 /* write info into LOG file */
1496 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1497 _unur_str_debug_set(2,key,"!");
1498 #endif
1499 return UNUR_ERR_STR_INVALID;
1500 }
1501
1502 /* get string */
1503 string = args[0];
1504
1505 #ifdef UNUR_ENABLE_LOGGING
1506 /* write info into LOG file */
1507 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1508 _unur_str_debug_set(2,key,"C",string);
1509 #endif
1510
1511 return set(distr,string);
1512
1513 } /* end of _unur_str_distr_set_C() */
1514
1515 /*---------------------------------------------------------------------------*/
1516
1517 /*****************************************************************************/
1518 /** Methods **/
1519 /*****************************************************************************/
1520
1521 /*---------------------------------------------------------------------------*/
1522
1523 struct unur_par *
_unur_str_par(char * str_method,const UNUR_DISTR * distr,struct unur_slist * mlist)1524 _unur_str_par( char *str_method, const UNUR_DISTR *distr, struct unur_slist *mlist )
1525 /*----------------------------------------------------------------------*/
1526 /* get parameter object for distribution and method */
1527 /* */
1528 /* parameters: */
1529 /* str_method ... string that contains method description */
1530 /* distr ... pointer to distribution object */
1531 /* mlist ... list of allocated memory blocks */
1532 /* */
1533 /* return: */
1534 /* default parameters (pointer to structure) */
1535 /* */
1536 /* error: */
1537 /* return NULL */
1538 /*----------------------------------------------------------------------*/
1539 {
1540 struct unur_par *par = NULL; /* pointer to parameter object */
1541
1542 char *token; /* pointer to token in string */
1543 char *next; /* pointer to next token in string */
1544 char *key, *value; /* the key and its value */
1545
1546 /* tokenize the string using ';' as separator and handle the tokens */
1547 for ( token = next = str_method;
1548 next != NULL && *token != '\0';
1549 token = next ) {
1550
1551 /* find end of token (i.e. the pointer to next token) */
1552 next = strchr(token,';');
1553 if (next != NULL) {
1554 /* next separator found */
1555 *next = '\0'; /* terminate token string */
1556 next++; /* set pointer to next token */
1557 }
1558
1559 /* token points to a key */
1560 key = token;
1561
1562 /* get the value from the pair key=value and terminate key string */
1563 value = strchr(key, '=');
1564 if (value != NULL) {
1565 *value = '\0'; /* terminate key string */
1566 value++; /* set pointer to value string */
1567 }
1568
1569 /* the first key is treated differently: get new parameter object */
1570 if (key == str_method) {
1571 /* the keyword "method" is optional */
1572 if (value == NULL) {
1573 /* no "method" keyword given, so the key points to the value */
1574 value = key;
1575 }
1576 else {
1577 if (*key != 'm') {
1578 _unur_error(GENTYPE,UNUR_ERR_STR_SYNTAX,"key for method does not start with 'm'");
1579 return NULL;
1580 }
1581 }
1582
1583 /* get new parameter object */
1584 par = _unur_str_par_new(value,distr);
1585 if (par == NULL) {
1586 /* error */
1587 _unur_error(GENTYPE,UNUR_ERR_STR,"setting method failed");
1588 return NULL;
1589 }
1590 }
1591
1592 /* set parameters for method */
1593 else {
1594 if ( !_unur_str_par_set(par, key, value, mlist) ) {
1595 ; /* error: */
1596 }
1597 }
1598 }
1599
1600 /* end */
1601 return par;
1602
1603 } /* end of _unur_str_par() */
1604
1605 /*---------------------------------------------------------------------------*/
1606
1607 int
_unur_str_par_set_void(UNUR_PAR * par,const char * key,char * type_args,char ** args ATTRIBUTE__UNUSED,par_set_void set)1608 _unur_str_par_set_void (UNUR_PAR *par, const char *key,
1609 char *type_args, char **args ATTRIBUTE__UNUSED, par_set_void set)
1610 /*----------------------------------------------------------------------*/
1611 /* Set parameter in given parameter object. */
1612 /* The list of arguments and their types are given as string. */
1613 /* */
1614 /* type: void (no arguments required) */
1615 /* */
1616 /* input: void (no arguments should be given) */
1617 /* */
1618 /* action: */
1619 /* execute set call. */
1620 /* warning if any argument is given. */
1621 /* */
1622 /* parameters: */
1623 /* par ... pointer to parameter object */
1624 /* key ... name of parameter to be set */
1625 /* type_args ... contains types of arguments. Possible values: */
1626 /* 't' for single token */
1627 /* 'L' for a list */
1628 /* args ... array of pointers to argument strings */
1629 /* set ... pointer to UNU.RAN function for set call */
1630 /* */
1631 /* return: */
1632 /* return code from set call, i.e. */
1633 /* UNUR_SUCCESS ... on success */
1634 /* error code ... on error */
1635 /*----------------------------------------------------------------------*/
1636 {
1637
1638 #ifdef UNUR_ENABLE_LOGGING
1639 /* write info into LOG file */
1640 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1641 _unur_str_debug_set(2,key,"v");
1642 #endif
1643
1644 if (*type_args != '\0')
1645 _unur_error_args(key);
1646
1647 return set(par);
1648
1649 } /* end of _unur_str_par_set_void() */
1650
1651 /*---------------------------------------------------------------------------*/
1652
1653 int
_unur_str_par_set_i(UNUR_PAR * par,const char * key,char * type_args,char ** args,par_set_i set)1654 _unur_str_par_set_i (UNUR_PAR *par, const char *key, char *type_args, char **args, par_set_i set)
1655 /*----------------------------------------------------------------------*/
1656 /* Set parameter in given parameter object. */
1657 /* The list of arguments and their types are given as string. */
1658 /* */
1659 /* type: "i" (int) */
1660 /* */
1661 /* input: "t" (exactly one single token) */
1662 /* void (no argument given) */
1663 /* */
1664 /* action: */
1665 /* convert token to int. */
1666 /* (if no argument is given, use 1.) */
1667 /* execute set call. */
1668 /* error if input != "t" */
1669 /* */
1670 /* parameters: */
1671 /* par ... pointer to parameter object */
1672 /* key ... name of parameter to be set */
1673 /* type_args ... contains types of arguments. Possible values: */
1674 /* 't' for single token */
1675 /* 'L' for a list */
1676 /* args ... array of pointers to argument strings */
1677 /* set ... pointer to UNU.RAN function for set call */
1678 /* */
1679 /* return: */
1680 /* return code from set call, i.e. */
1681 /* UNUR_SUCCESS ... on success */
1682 /* error code ... on error */
1683 /*----------------------------------------------------------------------*/
1684 {
1685 int iarg;
1686
1687 if ( !strcmp(type_args, "t") ) {
1688 iarg = _unur_atoi( args[0] );
1689 }
1690 else if ( strlen(type_args) == 0 ) {
1691 iarg = 1;
1692 }
1693 else {
1694 _unur_error_args(key);
1695 #ifdef UNUR_ENABLE_LOGGING
1696 /* write info into LOG file */
1697 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1698 _unur_str_debug_set(2,key,"!");
1699 #endif
1700 return UNUR_ERR_STR_INVALID;
1701 }
1702
1703 #ifdef UNUR_ENABLE_LOGGING
1704 /* write info into LOG file */
1705 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1706 _unur_str_debug_set(2,key,"i",iarg);
1707 #endif
1708
1709 return set(par,iarg);
1710
1711 } /* end of _unur_str_par_set_i() */
1712
1713 /*---------------------------------------------------------------------------*/
1714
1715 int
_unur_str_par_set_ii(UNUR_PAR * par,const char * key,char * type_args,char ** args,par_set_ii set)1716 _unur_str_par_set_ii (UNUR_PAR *par, const char *key, char *type_args, char **args, par_set_ii set)
1717 /*----------------------------------------------------------------------*/
1718 /* Set parameter in given parameter object. */
1719 /* The list of arguments and their types are given as string. */
1720 /* */
1721 /* type: "ii" (int,int) */
1722 /* */
1723 /* input: "tt" (exactly two single tokens) */
1724 /* "L" (exactly one list) */
1725 /* */
1726 /* action: */
1727 /* if "tt": convert both to int. */
1728 /* execute set call. */
1729 /* if "L": convert list entries to int. */
1730 /* execute set call with first two entries. */
1731 /* (error if list has less than two entries) */
1732 /* otherwise: error */
1733 /* */
1734 /* parameters: */
1735 /* par ... pointer to parameter object */
1736 /* key ... name of parameter to be set */
1737 /* type_args ... contains types of arguments. Possible values: */
1738 /* 't' for single token */
1739 /* 'L' for a list */
1740 /* args ... array of pointers to argument strings */
1741 /* set ... pointer to UNU.RAN function for set call */
1742 /* */
1743 /* return: */
1744 /* return code from set call, i.e. */
1745 /* UNUR_SUCCESS ... on success */
1746 /* error code ... on error */
1747 /*----------------------------------------------------------------------*/
1748 {
1749 int *iarray = NULL;
1750 int iarg[2];
1751 int result;
1752
1753 /* either exactly two arguments are given */
1754 if ( !strcmp(type_args, "tt") ) {
1755 iarg[0] = _unur_atoi( args[0] );
1756 iarg[1] = _unur_atoi( args[1] );
1757
1758 #ifdef UNUR_ENABLE_LOGGING
1759 /* write info into LOG file */
1760 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1761 _unur_str_debug_set(2,key,"ii",iarg[0],iarg[1]);
1762 #endif
1763
1764 return set( par,iarg[0],iarg[1] );
1765 }
1766
1767 /* or one list with 2 entries is given */
1768 else if ( !strcmp(type_args, "L") ) {
1769 if ( _unur_parse_ilist( args[0], &iarray ) < 2 ) {
1770 _unur_error_args(key);
1771 free (iarray);
1772 #ifdef UNUR_ENABLE_LOGGING
1773 /* write info into LOG file */
1774 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1775 _unur_str_debug_set(2,key,"!");
1776 #endif
1777 return UNUR_ERR_STR_INVALID;
1778 }
1779 result = set( par,iarray[0],iarray[1] );
1780
1781 #ifdef UNUR_ENABLE_LOGGING
1782 /* write info into LOG file */
1783 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1784 _unur_str_debug_set(2,key,"ii",iarray[0],iarray[1] );
1785 #endif
1786
1787 free (iarray);
1788 return result;
1789 }
1790
1791 else {
1792 _unur_error_args(key);
1793 #ifdef UNUR_ENABLE_LOGGING
1794 /* write info into LOG file */
1795 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1796 _unur_str_debug_set(2,key,"!");
1797 #endif
1798 return UNUR_ERR_STR_INVALID;
1799 }
1800
1801 } /* end of _unur_str_par_set_ii() */
1802
1803 /*---------------------------------------------------------------------------*/
1804
1805 int
_unur_str_par_set_u(UNUR_PAR * par,const char * key,char * type_args,char ** args,par_set_u set)1806 _unur_str_par_set_u (UNUR_PAR *par, const char *key, char *type_args, char **args, par_set_u set)
1807 /*----------------------------------------------------------------------*/
1808 /* Set parameter in given parameter object. */
1809 /* The list of arguments and their types are given as string. */
1810 /* */
1811 /* type: "u" (unsigned) */
1812 /* */
1813 /* input: "t" (exactly one single token) */
1814 /* */
1815 /* action: */
1816 /* convert token to unsigned. */
1817 /* execute set call. */
1818 /* error if input != "t" */
1819 /* */
1820 /* parameters: */
1821 /* par ... pointer to parameter object */
1822 /* key ... name of parameter to be set */
1823 /* type_args ... contains types of arguments. Possible values: */
1824 /* 't' for single token */
1825 /* 'L' for a list */
1826 /* args ... array of pointers to argument strings */
1827 /* set ... pointer to UNU.RAN function for set call */
1828 /* */
1829 /* return: */
1830 /* return code from set call, i.e. */
1831 /* UNUR_SUCCESS ... on success */
1832 /* error code ... on error */
1833 /*----------------------------------------------------------------------*/
1834 {
1835 unsigned uarg;
1836
1837 if ( strcmp(type_args, "t") ) {
1838 _unur_error_args(key);
1839 #ifdef UNUR_ENABLE_LOGGING
1840 /* write info into LOG file */
1841 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1842 _unur_str_debug_set(2,key,"!");
1843 #endif
1844 return UNUR_ERR_STR_INVALID;
1845 }
1846
1847 uarg = _unur_atou( args[0] );
1848
1849 #ifdef UNUR_ENABLE_LOGGING
1850 /* write info into LOG file */
1851 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1852 _unur_str_debug_set(2,key,"u",uarg);
1853 #endif
1854
1855 return set(par,uarg);
1856
1857 } /* end of _unur_str_par_set_u() */
1858
1859 /*---------------------------------------------------------------------------*/
1860
1861 int
_unur_str_par_set_d(UNUR_PAR * par,const char * key,char * type_args,char ** args,par_set_d set)1862 _unur_str_par_set_d (UNUR_PAR *par, const char *key, char *type_args, char **args, par_set_d set)
1863 /*----------------------------------------------------------------------*/
1864 /* Set parameter in given parameter object. */
1865 /* The list of arguments and their types are given as string. */
1866 /* */
1867 /* type: "d" (double) */
1868 /* */
1869 /* input: "t" (exactly one single token) */
1870 /* */
1871 /* action: */
1872 /* convert token to double. */
1873 /* execute set call. */
1874 /* error if input != "t" */
1875 /* */
1876 /* parameters: */
1877 /* par ... pointer to parameter object */
1878 /* key ... name of parameter to be set */
1879 /* type_args ... contains types of arguments. Possible values: */
1880 /* 't' for single token */
1881 /* 'L' for a list */
1882 /* args ... array of pointers to argument strings */
1883 /* set ... pointer to UNU.RAN function for set call */
1884 /* */
1885 /* return: */
1886 /* return code from set call, i.e. */
1887 /* UNUR_SUCCESS ... on success */
1888 /* error code ... on error */
1889 /*----------------------------------------------------------------------*/
1890 {
1891 double darg;
1892
1893 if ( strcmp(type_args, "t") ) {
1894 _unur_error_args(key);
1895 #ifdef UNUR_ENABLE_LOGGING
1896 /* write info into LOG file */
1897 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1898 _unur_str_debug_set(2,key,"!");
1899 #endif
1900 return UNUR_ERR_STR_INVALID;
1901 }
1902
1903 darg = _unur_atod( args[0] );
1904
1905 #ifdef UNUR_ENABLE_LOGGING
1906 /* write info into LOG file */
1907 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1908 _unur_str_debug_set(2,key,"d",darg);
1909 #endif
1910
1911 return set(par,darg);
1912
1913 } /* end of _unur_str_par_set_d() */
1914
1915 /*---------------------------------------------------------------------------*/
1916
1917 int
_unur_str_par_set_dd(UNUR_PAR * par,const char * key,char * type_args,char ** args,par_set_dd set)1918 _unur_str_par_set_dd (UNUR_PAR *par, const char *key, char *type_args, char **args, par_set_dd set)
1919 /*----------------------------------------------------------------------*/
1920 /* Set parameter in given parameter object. */
1921 /* The list of arguments and their types are given as string. */
1922 /* */
1923 /* type: "dd" (double,double) */
1924 /* */
1925 /* input: "tt" (exactly two single tokens) */
1926 /* "L" (exactly one list) */
1927 /* */
1928 /* action: */
1929 /* if "tt": convert both to double. */
1930 /* execute set call. */
1931 /* if "L": convert list entries to double. */
1932 /* execute set call with first two entries. */
1933 /* (error if list has less than two entries) */
1934 /* otherwise: error */
1935 /* */
1936 /* parameters: */
1937 /* par ... pointer to parameter object */
1938 /* key ... name of parameter to be set */
1939 /* type_args ... contains types of arguments. Possible values: */
1940 /* 't' for single token */
1941 /* 'L' for a list */
1942 /* args ... array of pointers to argument strings */
1943 /* set ... pointer to UNU.RAN function for set call */
1944 /* */
1945 /* return: */
1946 /* return code from set call, i.e. */
1947 /* UNUR_SUCCESS ... on success */
1948 /* error code ... on error */
1949 /*----------------------------------------------------------------------*/
1950 {
1951 double *darray = NULL;
1952 double darg[2];
1953 int result;
1954
1955 /* either exactly two arguments are given */
1956 if ( !strcmp(type_args, "tt") ) {
1957 darg[0] = _unur_atod( args[0] );
1958 darg[1] = _unur_atod( args[1] );
1959
1960 #ifdef UNUR_ENABLE_LOGGING
1961 /* write info into LOG file */
1962 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1963 _unur_str_debug_set(2,key,"dd",darg[0],darg[1]);
1964 #endif
1965
1966 return set( par,darg[0],darg[1] );
1967 }
1968
1969 /* or one list with 2 entries is given */
1970 else if ( !strcmp(type_args, "L") ) {
1971 if ( _unur_parse_dlist( args[0], &darray ) < 2 ) {
1972 _unur_error_args(key);
1973 free (darray);
1974 #ifdef UNUR_ENABLE_LOGGING
1975 /* write info into LOG file */
1976 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1977 _unur_str_debug_set(2,key,"!");
1978 #endif
1979 return UNUR_ERR_STR_INVALID;
1980 }
1981 result = set( par,darray[0],darray[1] );
1982
1983 #ifdef UNUR_ENABLE_LOGGING
1984 /* write info into LOG file */
1985 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1986 _unur_str_debug_set(2,key,"dd",darray[0],darray[1] );
1987 #endif
1988
1989 free (darray);
1990 return result;
1991 }
1992
1993 else {
1994 _unur_error_args(key);
1995 #ifdef UNUR_ENABLE_LOGGING
1996 /* write info into LOG file */
1997 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
1998 _unur_str_debug_set(2,key,"!");
1999 #endif
2000 return UNUR_ERR_STR_INVALID;
2001 }
2002
2003 } /* end of _unur_str_par_set_dd() */
2004
2005 /*---------------------------------------------------------------------------*/
2006
2007 int
_unur_str_par_set_iD(UNUR_PAR * par,const char * key,char * type_args,char ** args,par_set_iD set,struct unur_slist * mlist)2008 _unur_str_par_set_iD (UNUR_PAR *par, const char *key, char *type_args, char **args,
2009 par_set_iD set, struct unur_slist *mlist )
2010 /*----------------------------------------------------------------------*/
2011 /* Set parameter in given parameter object. */
2012 /* The list of arguments and their types are given as string. */
2013 /* */
2014 /* type: "iD" (int, array of doubles) */
2015 /* */
2016 /* input: "tL" (single token & list) */
2017 /* "L" (exactly one list) */
2018 /* "t" (single token) */
2019 /* */
2020 /* action: */
2021 /* if "L": convert list to array of doubles. */
2022 /* execute set with size if array as first argument. */
2023 /* if "t": convert token to int. */
2024 /* execute set call with NULL as its second argument. */
2025 /* if "tL": convert list to array of doubles. */
2026 /* convert first token to int. */
2027 /* set int to min of int and size of array. */
2028 /* execute set call with int and array. */
2029 /* otherwise: error */
2030 /* */
2031 /* parameters: */
2032 /* par ... pointer to parameter object */
2033 /* key ... name of parameter to be set */
2034 /* type_args ... contains types of arguments. Possible values: */
2035 /* 't' for single token */
2036 /* 'L' for a list */
2037 /* args ... array of pointers to argument strings */
2038 /* set ... pointer to UNU.RAN function for set call */
2039 /* mlist ... list of allocated memory blocks */
2040 /* */
2041 /* return: */
2042 /* return code from set call, i.e. */
2043 /* UNUR_SUCCESS ... on success */
2044 /* error code ... on error */
2045 /*----------------------------------------------------------------------*/
2046 {
2047 int result;
2048 int t_size;
2049 int size = -1;
2050 double *darray = NULL;
2051
2052 /* either an integer and a list are given */
2053 if ( !strcmp(type_args, "tL") ) {
2054 t_size = _unur_atoi( args[0] );
2055 size = _unur_parse_dlist( args[1], &darray );
2056 if (size > 0) {
2057 if (size > t_size) size = t_size;
2058 }
2059 else {
2060 /* empty list */
2061 size = t_size;
2062 if (darray) free (darray);
2063 darray = NULL;
2064 }
2065 }
2066
2067 /* or only an integer is given */
2068 else if ( !strcmp(type_args, "t") ) {
2069 size = _unur_atoi( args[0] );
2070 darray = NULL;
2071 }
2072
2073 /* or only a list is given */
2074 else if ( !strcmp(type_args, "L") ) {
2075 size = _unur_parse_dlist( args[0], &darray );
2076 }
2077
2078 /* or there is a syntax error */
2079 if ( !(size>0) ) {
2080 _unur_error_args(key);
2081 #ifdef UNUR_ENABLE_LOGGING
2082 /* write info into LOG file */
2083 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
2084 _unur_str_debug_set(2,key,"!");
2085 #endif
2086 result = UNUR_ERR_STR_INVALID;
2087 }
2088
2089 else {
2090 /* execute set command */
2091 result = set( par,size,darray );
2092 #ifdef UNUR_ENABLE_LOGGING
2093 /* write info into LOG file */
2094 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
2095 _unur_str_debug_set(2,key,"iD",size,darray,size);
2096 #endif
2097 }
2098
2099 /* store pointer to allocated array */
2100 if (darray)
2101 _unur_slist_append( mlist, darray );
2102
2103 return result;
2104
2105 } /* end of _unur_str_par_set_iD() */
2106
2107 /*---------------------------------------------------------------------------*/
2108
2109 int
_unur_str_par_set_Di(UNUR_PAR * par,const char * key,char * type_args,char ** args,par_set_Di set,struct unur_slist * mlist)2110 _unur_str_par_set_Di (UNUR_PAR *par, const char *key, char *type_args, char **args,
2111 par_set_Di set, struct unur_slist *mlist )
2112 /*----------------------------------------------------------------------*/
2113 /* Set parameter in given parameter object. */
2114 /* The list of arguments and their types are given as string. */
2115 /* */
2116 /* type: "Di" (array of doubles, int) */
2117 /* */
2118 /* input: "Lt" (list & single token & list) */
2119 /* */
2120 /* action: */
2121 /* convert list to array of doubles. */
2122 /* convert token to int. */
2123 /* execute set call with array and int. */
2124 /* */
2125 /* parameters: */
2126 /* par ... pointer to parameter object */
2127 /* key ... name of parameter to be set */
2128 /* type_args ... contains types of arguments. Possible values: */
2129 /* 't' for single token */
2130 /* 'L' for a list */
2131 /* args ... array of pointers to argument strings */
2132 /* set ... pointer to UNU.RAN function for set call */
2133 /* mlist ... list of allocated memory blocks */
2134 /* */
2135 /* return: */
2136 /* return code from set call, i.e. */
2137 /* UNUR_SUCCESS ... on success */
2138 /* error code ... on error */
2139 /*----------------------------------------------------------------------*/
2140 {
2141 int result;
2142 int t_size;
2143 int size;
2144 double *darray = NULL;
2145
2146 if ( !strcmp(type_args, "Lt") ) {
2147 t_size = _unur_atoi( args[1] );
2148 size = _unur_parse_dlist( args[0], &darray );
2149 if (size > 0) {
2150 result = set( par,darray,t_size );
2151 #ifdef UNUR_ENABLE_LOGGING
2152 /* write info into LOG file */
2153 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
2154 _unur_str_debug_set(2,key,"Di",darray,size,size);
2155 #endif
2156
2157 /* store pointer to allocated array */
2158 if (darray)
2159 _unur_slist_append( mlist, darray );
2160
2161 return result;
2162 }
2163 }
2164
2165 /* there is a syntax error */
2166 _unur_error_args(key);
2167 #ifdef UNUR_ENABLE_LOGGING
2168 /* write info into LOG file */
2169 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
2170 _unur_str_debug_set(2,key,"!");
2171 #endif
2172
2173 return UNUR_ERR_STR_INVALID;
2174 } /* end of _unur_str_par_set_Di() */
2175
2176 /*---------------------------------------------------------------------------*/
2177
2178 /*****************************************************************************/
2179 /** Uniform RNG **/
2180 /*****************************************************************************/
2181
2182 UNUR_URNG *
_unur_str2urng(char * str_urng ATTRIBUTE__UNUSED)2183 _unur_str2urng( char *str_urng ATTRIBUTE__UNUSED)
2184 /*----------------------------------------------------------------------*/
2185 /* get uniform RNG */
2186 /* */
2187 /* parameters: */
2188 /* str_urng ... string that contains description of uniform RNG */
2189 /* */
2190 /* return: */
2191 /* pointer to uniform RNG */
2192 /* */
2193 /* The string must not contain any other keywords than "urng". */
2194 /* the argument is passed unchanged to the PRNG package. */
2195 /* */
2196 /* error: */
2197 /* return NULL */
2198 /*----------------------------------------------------------------------*/
2199 {
2200 /*---------------------------------------------------------------------------*/
2201 #if defined(UNUR_URNG_UNURAN) && defined(UNURAN_HAS_PRNG)
2202 /*---------------------------------------------------------------------------*/
2203
2204 UNUR_URNG *urng = NULL;
2205
2206 char *token; /* pointer to token in string */
2207 char *next; /* pointer to next token in string */
2208 char *key, *value; /* the key and its value */
2209
2210 /* tokenize the string using ';' as separator and handle the tokens */
2211 for ( token = next = str_urng;
2212 next != NULL && *token != '\0';
2213 token = next ) {
2214
2215 /* find end of token (i.e. the pointer to next token) */
2216 next = strchr(token,';');
2217 if (next != NULL) {
2218 /* next separator found */
2219 *next = '\0'; /* terminate token string */
2220 next++; /* set pointer to next token */
2221 }
2222
2223 /* token points to a key */
2224 key = token;
2225
2226 /* get the value from the pair key=value and terminate key string */
2227 value = strchr(key, '=');
2228 if (value != NULL) {
2229 *value = '\0'; /* terminate key string */
2230 value++; /* set pointer to value string */
2231 }
2232
2233 /* get (default) parameter object for method */
2234 if ( !strcmp( key, "urng") ) {
2235 if (key == str_urng) {
2236 /* "urng" must be the first key. */
2237 /* (on the other hand, the first keyword always must be "urng" */
2238 /* since otherwise we had not called this subroutine. */
2239 /* hence, we only check, whether the keyword "urng" is unique.) */
2240 urng = unur_urng_prng_new(value);
2241 if (urng == NULL) {
2242 /* error */
2243 _unur_error(GENTYPE,UNUR_ERR_STR,"setting URNG failed");
2244 return NULL;
2245 }
2246 else {
2247 #ifdef UNUR_ENABLE_LOGGING
2248 /* write info into LOG file */
2249 if (_unur_default_debugflag & UNUR_DEBUG_SETUP)
2250 _unur_str_debug_string(1,"urng",value);
2251 #endif
2252 ;
2253 }
2254 }
2255 else {
2256 if (urng) unur_urng_free (urng);
2257 _unur_error(GENTYPE,UNUR_ERR_STR_SYNTAX,"urng must be first key");
2258 return NULL;
2259 }
2260 }
2261
2262 /* there are no other parameters */
2263 else {
2264 /* error: unknown parameter */
2265 if (urng) unur_urng_free (urng);
2266 _unur_error_unknown(key,"parameter for uniform RNG");
2267 return NULL;
2268 }
2269 }
2270
2271 /*return pointer to uniform RNG */
2272 return urng;
2273
2274 /*---------------------------------------------------------------------------*/
2275 #else
2276 /*---------------------------------------------------------------------------*/
2277
2278 _unur_error(GENTYPE,UNUR_ERR_STR,"setting URNG requires PRNG library enabled");
2279 return NULL;
2280
2281 /*---------------------------------------------------------------------------*/
2282 #endif /* end defined(UNUR_URNG_UNURAN) && defined(UNURAN_HAS_PRNG) */
2283 /*---------------------------------------------------------------------------*/
2284 } /* end of _unur_str2urng() */
2285
2286 /*---------------------------------------------------------------------------*/
2287
2288 /*****************************************************************************/
2289 /** Misc **/
2290 /*****************************************************************************/
2291
2292 /*---------------------------------------------------------------------------*/
2293
2294 int
_unur_str_set_args(char * value,char * type_args,char ** args,int max_args)2295 _unur_str_set_args( char *value, char *type_args, char **args, int max_args )
2296 /*----------------------------------------------------------------------*/
2297 /* parse argument string for set call */
2298 /* */
2299 /* parameters: */
2300 /* value ... string that contains list of arguments for set call */
2301 /* type_args ... array containing info about arguments */
2302 /* args ... pointers to argument strings */
2303 /* max_args ... maximal number of argments */
2304 /* */
2305 /* tokenize string with arguments and store the pointer to each */
2306 /* argument in 'args'. Evaluate the type of each argument and store it */
2307 /* in 'type_args'. We have the following types: */
2308 /* 't' ... a single token, or */
2309 /* 'L' ... a list, indicated by (...) */
2310 /* */
2311 /* return: */
2312 /* number of parsed arguments */
2313 /* */
2314 /* error: */
2315 /* return -1 */
2316 /*----------------------------------------------------------------------*/
2317 {
2318 char *token; /* pointer to token in string */
2319 char *next; /* pointer to next token in string */
2320 int n_args; /* number of arguments in set call */
2321
2322 /* initialize pointers */
2323 n_args = 0;
2324 *type_args = '\0';
2325 *args = NULL;
2326
2327 /* we have two types of arguments:
2328 't' ... a single token, or
2329 'L' ... a list, indicated by (...)
2330 */
2331
2332 /* split value string into separate arguments */
2333 if (value && *value != '\0') {
2334 /* there is at least one argument */
2335
2336 for ( token = next = value;
2337 next != NULL && *token != '\0' && n_args < max_args;
2338 token = next, n_args++ ) {
2339
2340 /* get type of argument */
2341
2342 if ( *token == '(' ) {
2343 /* argument is a list */
2344 type_args[n_args] = 'L';
2345 /* skip to next character */
2346 token++;
2347 /* store pointer to argument */
2348 args[n_args] = token;
2349 /* find end of list using ')' as terminating character */
2350 next = strchr(token,')');
2351 if (next != NULL) {
2352 /* end of list found */
2353 *next = '\0'; /* terminate token string */
2354 token = ++next; /* set pointer to first character after ')' */
2355 /* first character after ')' must be ',' */
2356 if ( !(*token == ',' || *token == '\0') ) {
2357 _unur_error(GENTYPE,UNUR_ERR_STR_SYNTAX,") not followed by comma");
2358 return -1;
2359 }
2360 }
2361 else {
2362 /* no ')' found */
2363 token = NULL;
2364 }
2365 }
2366
2367 else if ( *token == '"' ) {
2368 /* argument is a string */
2369 type_args[n_args] = 's';
2370 /* skip to next character */
2371 token++;
2372 /* store pointer to argument */
2373 args[n_args] = token;
2374
2375 /* find end of string using '"' as terminating character */
2376 next = strchr(token,'"');
2377 if (next != NULL) {
2378 /* end of list found */
2379 *next = '\0'; /* terminate token string */
2380 token = ++next; /* set pointer to first character after ')' */
2381 /* first character after ')' must be ',' */
2382 if ( !(*token == ',' || *token == '\0') ) {
2383 _unur_error(GENTYPE,UNUR_ERR_STR_SYNTAX,"closing '\"' not followed by comma");
2384 return -1;
2385 }
2386 }
2387 else {
2388 /* no '"' found */
2389 token = NULL;
2390 }
2391 }
2392
2393 else {
2394 /* argument is a sigle item */
2395 type_args[n_args] = 't';
2396 /* store pointer to argument */
2397 args[n_args] = token;
2398 }
2399
2400 /* find end of argument string using ',' as separator */
2401 if (token) {
2402 next = strchr(token,',');
2403 if (next != NULL) {
2404 /* next separator found */
2405 *next = '\0'; /* terminate token string */
2406 next++; /* set pointer to next token */
2407 }
2408 }
2409 else {
2410 next = NULL;
2411 }
2412 }
2413
2414 /* terminate string */
2415 type_args[n_args] = '\0';
2416
2417 /* If there are two many arguments, we simply assume a syntax error */
2418 /* (This case should not happen.) */
2419 if (n_args >= max_args) {
2420 _unur_error( GENTYPE, UNUR_ERR_STR_SYNTAX, "too many arguments");
2421 return -1;
2422 }
2423 }
2424
2425 /* return number of parsed arguments */
2426 return n_args;
2427
2428 } /* end of _unur_str_set_args() */
2429
2430 /*---------------------------------------------------------------------------*/
2431
2432 /*****************************************************************************/
2433 /** Convert to numbers **/
2434 /*****************************************************************************/
2435
2436 /*---------------------------------------------------------------------------*/
2437
2438 int
_unur_parse_ilist(char * liststr,int ** iarray)2439 _unur_parse_ilist( char *liststr, int **iarray )
2440 /*----------------------------------------------------------------------*/
2441 /* Process a comma separated list of integers, convert it to ints and */
2442 /* store it an array. The list (string) is terminated by a closing */
2443 /* parenthesis ')' or '\0'. */
2444 /* */
2445 /* parameters: */
2446 /* liststr ... string containing list of numbers */
2447 /* iarray ... pointer to adress of double array for storing result */
2448 /* */
2449 /* return: */
2450 /* number of elements extracted */
2451 /* */
2452 /* comment: */
2453 /* as a side effect an int array of appropriate size is allocated. */
2454 /*----------------------------------------------------------------------*/
2455 {
2456 int *iarr = NULL; /* pointer to int array */
2457 int n_iarray = 0; /* number of elements in processed list */
2458 int n_alloc = 0; /* number allocated elements */
2459 char *token;
2460
2461 /* return 0 if no list is given */
2462 if (liststr == NULL) {
2463 *iarray = iarr;
2464 return 0;
2465 }
2466
2467 /* discard possible leading ',' or '(' characters in front of the numbers */
2468 while ( *liststr == ',' || *liststr == '(' ){
2469 liststr++; /* next char */
2470 }
2471
2472 /* new get integers */
2473 for ( token = strtok(liststr, ",)");
2474 token != NULL;
2475 token = strtok(NULL, ",)") ) {
2476
2477 /* check if there is enough space in iarr */
2478 if (n_iarray >= n_alloc) {
2479 /* no --> allocate memory */
2480 n_alloc += 100;
2481 iarr = _unur_xrealloc( iarr, n_alloc * sizeof(int) );
2482 }
2483
2484 /* get int */
2485 iarr[n_iarray++] = _unur_atoi(token);
2486
2487 } /* end while -- all elements of list read */
2488
2489 /* store pointer to double array */
2490 *iarray = iarr;
2491
2492 /* return number of elements in array */
2493 return n_iarray;
2494
2495 } /* end of _unur_parse_ilist() */
2496
2497 /*---------------------------------------------------------------------------*/
2498
2499 int
_unur_parse_dlist(char * liststr,double ** darray)2500 _unur_parse_dlist( char *liststr, double **darray )
2501 /*----------------------------------------------------------------------*/
2502 /* Process a comma separated list of numbers (doubles), convert it to */
2503 /* doubles and store it an array. The list (string) is terminated by */
2504 /* a closing parenthesis ')' or '\0'. */
2505 /* */
2506 /* parameters: */
2507 /* liststr ... string containing list of numbers */
2508 /* darray ... pointer to adress of double array for storing result */
2509 /* */
2510 /* return: */
2511 /* number of elements extracted */
2512 /* */
2513 /* comment: */
2514 /* as a side effect a double array of appropriate size is allocated. */
2515 /*----------------------------------------------------------------------*/
2516 {
2517 double *darr = NULL; /* pointer to double array */
2518 int n_darray = 0; /* number of elements in processed list */
2519 int n_alloc = 0; /* number allocated elements */
2520 char *token; /* pointer to token in string */
2521 char *next; /* pointer to next token in string */
2522
2523 /* return 0 if no list is given */
2524 if (liststr == NULL) {
2525 *darray = NULL;
2526 return 0;
2527 }
2528
2529 /* extract doubles from string and write them to array of doubles. */
2530 /* end of list is indicated by right bracket ')' or '\0'. */
2531
2532 /* pointer to first token in string */
2533 token = liststr;
2534
2535 /* remove (optional) leading parenthesis '(' */
2536 while (*token != '\0' && *token == '(')
2537 ++token;
2538
2539 /* tokenize the string using ',' as separator and handle the tokens */
2540 for ( next = token;
2541 next != NULL && *token != '\0' &&*token != ')';
2542 token = next ) {
2543
2544 /* find end of token (i.e. the pointer to next token) */
2545 next = strchr(token,',');
2546 if (next != NULL) {
2547 /* next separator found */
2548 *next = '\0'; /* terminate token string */
2549 next++; /* set pointer to next token */
2550 }
2551
2552 /* check if there is enough space in darr */
2553 if (n_darray >= n_alloc) {
2554 /* no --> allocate memory */
2555 n_alloc += 100;
2556 darr = _unur_xrealloc( darr, n_alloc * sizeof(double) );
2557 }
2558
2559 /* extract double and write to array and increase counter */
2560 darr[n_darray] = _unur_atod(token);
2561 n_darray++;
2562
2563 }
2564
2565 /* store pointer to double array */
2566 *darray = darr;
2567
2568 /* return number of elements in array */
2569 return n_darray;
2570
2571 } /* end of _unur_parse_dlist() */
2572
2573 /*---------------------------------------------------------------------------*/
2574
2575 int
_unur_atoi(const char * str)2576 _unur_atoi ( const char *str )
2577 /*----------------------------------------------------------------------*/
2578 /* Converts the string into its integer representation. */
2579 /* 'true' and 'on' are converted to 1, 'false' and 'off' to 0. */
2580 /* */
2581 /* parameters: */
2582 /* str ... pointer to string */
2583 /* */
2584 /* return: */
2585 /* integer */
2586 /*----------------------------------------------------------------------*/
2587 {
2588 if ( !strcmp(str,"true") || !strcmp(str,"on") )
2589 return 1;
2590
2591 else if ( !strcmp(str,"false") || !strcmp(str,"off") )
2592 return 0;
2593
2594 else if ( !strncmp(str,"inf",(size_t)3) )
2595 return INT_MAX;
2596
2597 else if ( !strncmp(str,"-inf",(size_t)4) )
2598 return INT_MIN;
2599
2600 else
2601 return atoi(str);
2602
2603 } /* end of _unur_atoi() */
2604
2605 /*---------------------------------------------------------------------------*/
2606
2607 unsigned
_unur_atou(const char * str)2608 _unur_atou ( const char *str )
2609 /*----------------------------------------------------------------------*/
2610 /* Converts the string into its unsigned representation. */
2611 /* strings are interprated as hexadecimal numbers. */
2612 /* 'true' and 'on' are converted to 1u, 'false' and 'off' to 0u. */
2613 /* */
2614 /* parameters: */
2615 /* str ... pointer to string */
2616 /* */
2617 /* return: */
2618 /* unsigned */
2619 /*----------------------------------------------------------------------*/
2620 {
2621 char *tail;
2622
2623 if ( !strcmp(str,"true") || !strcmp(str,"on") )
2624 return 1u;
2625
2626 else if ( !strcmp(str,"false") || !strcmp(str,"off") )
2627 return 0u;
2628
2629 else
2630 return ((unsigned) strtoul(str, &tail, 16));
2631 } /* end of _unur_atou() */
2632
2633 /*---------------------------------------------------------------------------*/
2634
2635 double
_unur_atod(const char * str)2636 _unur_atod ( const char *str )
2637 /*----------------------------------------------------------------------*/
2638 /* Converts the string into its double value. */
2639 /* */
2640 /* parameters: */
2641 /* str ... pointer to string */
2642 /* */
2643 /* return: */
2644 /* double */
2645 /*----------------------------------------------------------------------*/
2646 {
2647 if ( !strncmp(str,"inf",(size_t)3) )
2648 return INFINITY;
2649
2650 else if ( !strncmp(str,"-inf",(size_t)4) )
2651 return -INFINITY;
2652
2653 else
2654 return atof(str);
2655 } /* end of _unur_atod() */
2656
2657 /*---------------------------------------------------------------------------*/
2658
2659 /*****************************************************************************/
2660 /** Debugging utilities **/
2661 /*****************************************************************************/
2662
2663 /*---------------------------------------------------------------------------*/
2664 #ifdef UNUR_ENABLE_LOGGING
2665 /*---------------------------------------------------------------------------*/
2666
2667 void
_unur_str_debug_string(int level,const char * key,const char * value)2668 _unur_str_debug_string( int level, const char *key, const char *value )
2669 /*----------------------------------------------------------------------*/
2670 /* print key & value info into LOG file */
2671 /* */
2672 /* parameters: */
2673 /* level ... level of indentation */
2674 /* key ... pointer to key string */
2675 /* value ... pointer to value string */
2676 /*----------------------------------------------------------------------*/
2677 {
2678 FILE *LOG;
2679
2680 LOG = unur_get_stream();
2681
2682 /* fprintf(LOG,"%s: String Interface for UNU.RAN\n",GENTYPE); */
2683 fprintf(LOG,"%s: ",GENTYPE);
2684 for (; level>0; level--)
2685 fprintf(LOG,"\t");
2686 fprintf(LOG,"%s",key);
2687 if (value)
2688 fprintf(LOG,": %s",value);
2689 fprintf(LOG,"\n");
2690
2691 /* fprintf(LOG,"%s:\n",GENTYPE); */
2692
2693 } /* end of _unur_str_debug_string() */
2694
2695 /*---------------------------------------------------------------------------*/
2696
2697 void
_unur_str_debug_distr(int level,const char * name,double * params,int n_params)2698 _unur_str_debug_distr( int level, const char *name, double *params, int n_params )
2699 /*----------------------------------------------------------------------*/
2700 /* write info about distribution into LOG file */
2701 /* */
2702 /* parameters: */
2703 /* level ... level of indentation */
2704 /* name ... name of distribution */
2705 /* params ... array of parameters */
2706 /* n_params ... number of parameters */
2707 /*----------------------------------------------------------------------*/
2708 {
2709 FILE *LOG;
2710 int i;
2711
2712 LOG = unur_get_stream();
2713
2714 fprintf(LOG,"%s: ",GENTYPE);
2715 for (; level>0; level--)
2716 fprintf(LOG,"\t");
2717
2718 fprintf(LOG,"distribution = %s (",name);
2719 if (n_params >0) {
2720 fprintf(LOG,"%g",params[0]);
2721 for (i=1; i<n_params; i++)
2722 fprintf(LOG,", %g",params[i]);
2723 }
2724 fprintf(LOG,")\n");
2725
2726 } /* end of _unur_str_debug_distr() */
2727
2728 /*---------------------------------------------------------------------------*/
2729
2730 void
_unur_str_debug_set(int level,const char * key,const char * type,...)2731 _unur_str_debug_set( int level, const char *key, const char *type, ... )
2732 /*----------------------------------------------------------------------*/
2733 /* write info about set command into LOG file */
2734 /* */
2735 /* parameters: */
2736 /* level ... level of indentation */
2737 /* key ... pointer to key string */
2738 /* type ... list of types of argments */
2739 /* ... ... variable list of arguments */
2740 /*----------------------------------------------------------------------*/
2741 {
2742 va_list ap;
2743 FILE *LOG;
2744
2745 va_start(ap, type);
2746
2747 LOG = unur_get_stream();
2748
2749 /* print key name */
2750 fprintf(LOG,"%s: ",GENTYPE);
2751 for (; level>0; level--)
2752 fprintf(LOG,"\t");
2753 fprintf(LOG,"%s: ",key);
2754
2755 while (1) {
2756
2757 switch (*type) {
2758 case 'v':
2759 fprintf(LOG," -none-");
2760 break;
2761 case 'd':
2762 fprintf(LOG," %g",va_arg(ap,double));
2763 break;
2764 case 'i':
2765 fprintf(LOG," %d",va_arg(ap,int));
2766 break;
2767 case 'u':
2768 fprintf(LOG," %x",va_arg(ap,unsigned int));
2769 break;
2770 case 'C':
2771 fprintf(LOG," %s",va_arg(ap,char *));
2772 break;
2773 case 'D': {
2774 int i,size;
2775 double *darray;
2776 darray = va_arg(ap,double *);
2777 size = va_arg(ap,int);
2778 if (size > 0 && darray != NULL) {
2779 fprintf(LOG," (%g",darray[0]);
2780 for (i=1; i<size; i++)
2781 fprintf(LOG,",%g",darray[i]);
2782 fprintf(LOG,")");
2783 }
2784 else
2785 fprintf(LOG," (empty)");
2786 break;
2787 }
2788 case '!':
2789 default:
2790 fprintf(LOG," syntax error");
2791 break;
2792 }
2793
2794 if ( *(++type) != '\0' )
2795 /* skip. there is a next argument to be processed */
2796 fprintf(LOG,",");
2797 else
2798 /* done */
2799 break;
2800 }
2801
2802 /* dd, iD, Di */
2803
2804 fprintf(LOG,"\n");
2805 fflush(LOG); /* in case of a segmentation fault */
2806
2807 va_end(ap);
2808
2809 } /* end of _unur_str_debug_set() */
2810
2811 /*---------------------------------------------------------------------------*/
2812 #endif /* end UNUR_ENABLE_LOGGING */
2813 /*---------------------------------------------------------------------------*/
2814
2815 void
_unur_str_error_unknown(const char * file,int line,const char * key,const char * type)2816 _unur_str_error_unknown( const char *file, int line, const char *key, const char *type )
2817 /*----------------------------------------------------------------------*/
2818 /* print error message: unknown keyword. */
2819 /* */
2820 /* parameters: */
2821 /* file ... file name (inserted by __FILE__) */
2822 /* line ... line number in source file (inserted by __LINE__) */
2823 /* key ... keyword */
2824 /* type ... type of keyword */
2825 /*----------------------------------------------------------------------*/
2826 {
2827 struct unur_string *reason = _unur_string_new();
2828 _unur_string_append( reason, "unknown %s: '%s'", type, key );
2829 _unur_error_x( GENTYPE, file, line, "error", UNUR_ERR_STR_UNKNOWN,reason->text);
2830 _unur_string_free( reason );
2831 } /* end of _unur_str_error_unknown() */
2832
2833 /*---------------------------------------------------------------------------*/
2834
2835 void
_unur_str_error_invalid(const char * file,int line,const char * key,const char * type)2836 _unur_str_error_invalid( const char *file, int line, const char *key, const char *type )
2837 /*----------------------------------------------------------------------*/
2838 /* print error message: invalid data for keyword. */
2839 /* */
2840 /* parameters: */
2841 /* file ... file name (inserted by __FILE__) */
2842 /* line ... line number in source file (inserted by __LINE__) */
2843 /* key ... keyword */
2844 /* type ... type of keyword */
2845 /*----------------------------------------------------------------------*/
2846 {
2847 struct unur_string *reason = _unur_string_new();
2848 _unur_string_append( reason, "invalid data for %s '%s'", type, key );
2849 _unur_error_x( GENTYPE, file, line, "error", UNUR_ERR_STR_INVALID,reason->text);
2850 _unur_string_free( reason );
2851 } /* end of _unur_str_error_invalid() */
2852
2853 /*---------------------------------------------------------------------------*/
2854
2855 void
_unur_str_error_args(const char * file,int line,const char * key)2856 _unur_str_error_args( const char *file, int line, const char *key )
2857 /*----------------------------------------------------------------------*/
2858 /* print error message: invalid argument string for set call. */
2859 /* */
2860 /* parameters: */
2861 /* file ... file name (inserted by __FILE__) */
2862 /* line ... line number in source file (inserted by __LINE__) */
2863 /* key ... keyword */
2864 /*----------------------------------------------------------------------*/
2865 {
2866 struct unur_string *reason = _unur_string_new();
2867 _unur_string_append( reason, "invalid argument string for '%s'", key );
2868 _unur_error_x( GENTYPE, file, line, "error", UNUR_ERR_STR_INVALID,reason->text);
2869 _unur_string_free( reason );
2870 } /* end of _unur_str_error_args() */
2871
2872 /*---------------------------------------------------------------------------*/
2873