1/* ------------------------------------------------------------- */
2/* File: example_cext.c                                          */
3/* ------------------------------------------------------------- */
4
5/* Include UNURAN header file.                                   */
6#include <unuran.h>
7
8/* ------------------------------------------------------------- */
9
10/* This example shows how an external generator for the          */
11/* exponential distribution with one scale parameter can be      */
12/* used within the UNURAN framework.                             */
13/*                                                               */
14/* Notice, that this example does not provide the simplest       */
15/* solution.                                                     */
16
17/* ------------------------------------------------------------- */
18/* Initialization routine.                                       */
19/*                                                               */
20/*   Here we simply read the scale parameter of the exponential  */
21/*   distribution and store it in an array for parameters of     */
22/*   the external generator.                                     */
23/*   [ Of course we could do this in the sampling routine as     */
24/*   and avoid the necessity of this initialization routine. ]   */
25
26int exponential_init (UNUR_GEN *gen)
27@{
28  /* Get pointer to parameters of exponential distribution       */
29  double *params = unur_cext_get_distrparams(gen);
30
31  /* The scale parameter is the first entry (see manual)         */
32  double lambda = (params) ? params[0] : 1.;
33
34  /* Get array to store this parameter for external generator    */
35  double *genpar = unur_cext_get_params(gen, sizeof(double));
36  genpar[0] = lambda;
37
38  /* Executed successfully                                       */
39  return UNUR_SUCCESS;
40@}
41
42/* ------------------------------------------------------------- */
43/* Sampling routine.                                             */
44/*                                                               */
45/*   Contains the code for the external generator.               */
46
47double exponential_sample (UNUR_GEN *gen)
48@{
49  /* Get scale parameter                                         */
50  double *genpar = unur_cext_get_params(gen,0);
51  double lambda = genpar[0];
52
53  /* Sample a uniformly distributed random number                */
54  double U = unur_sample_urng(gen);
55
56  /* Transform into exponentially distributed random variate     */
57  return ( -log(1. - U) * lambda );
58@}
59
60/* ------------------------------------------------------------- */
61
62int main(void)
63@{
64  int    i;     /* loop variable                                 */
65  double x;     /* will hold the random number                   */
66
67  /* Declare the three UNURAN objects.                           */
68  UNUR_DISTR *distr;    /* distribution object                   */
69  UNUR_PAR   *par;      /* parameter object                      */
70  UNUR_GEN   *gen;      /* generator object                      */
71
72  /* Use predefined exponential distribution with scale param. 2 */
73  double fpar[1] = @{ 2. @};
74  distr = unur_distr_exponential(fpar, 1);
75
76  /* Use method CEXT                                             */
77  par = unur_cext_new(distr);
78
79  /* Set initialization and sampling routines.                   */
80  unur_cext_set_init(par, exponential_init);
81  unur_cext_set_sample(par, exponential_sample);
82
83  /* Create the generator object.                                */
84  gen = unur_init(par);
85
86  /* It is important to check if the creation of the generator   */
87  /* object was successful. Otherwise `gen' is the NULL pointer  */
88  /* and would cause a segmentation fault if used for sampling.  */
89  if (gen == NULL) @{
90     fprintf(stderr, "ERROR: cannot create generator object\n");
91     exit (EXIT_FAILURE);
92  @}
93
94  /* It is possible to reuse the distribution object to create   */
95  /* another generator object. If you do not need it any more,   */
96  /* it should be destroyed to free memory.                      */
97  unur_distr_free(distr);
98
99  /* Now you can use the generator object `gen' to sample from   */
100  /* the standard Gaussian distribution.                         */
101  /* Eg.:                                                        */
102  for (i=0; i<10; i++) @{
103    x = unur_sample_cont(gen);
104    printf("%f\n",x);
105  @}
106
107  /* When you do not need the generator object any more, you     */
108  /* can destroy it.                                             */
109  unur_free(gen);
110
111  exit (EXIT_SUCCESS);
112
113@} /* end of main() */
114
115/* ------------------------------------------------------------- */
116
117