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