Sophie

Sophie

distrib > Fedora > 14 > x86_64 > media > os > by-pkgid > b12fa7ce9cec8c963ac9af841906d872 > files > 19

unuran-devel-1.7.1-1.fc14.i686.rpm

/* ------------------------------------------------------------- */
/* File: example_cext.c                                          */
/* ------------------------------------------------------------- */

/* Include UNURAN header file.                                   */
#include <unuran.h>

/* ------------------------------------------------------------- */

/* This example shows how an external generator for the          */
/* exponential distribution with one scale parameter can be      */
/* used within the UNURAN framework.                             */
/*                                                               */
/* Notice, that this example does not provide the simplest       */
/* solution.                                                     */

/* ------------------------------------------------------------- */
/* Initialization routine.                                       */
/*                                                               */
/*   Here we simply read the scale parameter of the exponential  */
/*   distribution and store it in an array for parameters of     */
/*   the external generator.                                     */
/*   [ Of course we could do this in the sampling routine as     */
/*   and avoid the necessity of this initialization routine. ]   */

int exponential_init (UNUR_GEN *gen)
{ 
  /* Get pointer to parameters of exponential distribution       */
  double *params = unur_cext_get_distrparams(gen);

  /* The scale parameter is the first entry (see manual)         */
  double lambda = (params) ? params[0] : 1.;

  /* Get array to store this parameter for external generator    */
  double *genpar = unur_cext_get_params(gen, sizeof(double));
  genpar[0] = lambda;

  /* Executed successfully                                       */
  return UNUR_SUCCESS;
}

/* ------------------------------------------------------------- */
/* Sampling routine.                                             */
/*                                                               */
/*   Contains the code for the external generator.               */

double exponential_sample (UNUR_GEN *gen)
{ 
  /* Get scale parameter                                         */
  double *genpar = unur_cext_get_params(gen,0);
  double lambda = genpar[0];

  /* Sample a uniformly distributed random number                */
  double U = unur_sample_urng(gen);

  /* Transform into exponentially distributed random variate     */
  return ( -log(1. - U) * lambda );
}

/* ------------------------------------------------------------- */

int main(void)
{
  int    i;     /* loop variable                                 */
  double x;     /* will hold the random number                   */

  /* Declare the three UNURAN objects.                           */
  UNUR_DISTR *distr;    /* distribution object                   */
  UNUR_PAR   *par;      /* parameter object                      */
  UNUR_GEN   *gen;      /* generator object                      */

  /* Use predefined exponential distribution with scale param. 2 */
  double fpar[1] = { 2. };
  distr = unur_distr_exponential(fpar, 1);

  /* Use method CEXT                                             */
  par = unur_cext_new(distr);

  /* Set initialization and sampling routines.                   */
  unur_cext_set_init(par, exponential_init);
  unur_cext_set_sample(par, exponential_sample);

  /* Create the generator object.                                */
  gen = unur_init(par);

  /* It is important to check if the creation of the generator   */
  /* object was successful. Otherwise `gen' is the NULL pointer  */ 
  /* and would cause a segmentation fault if used for sampling.  */
  if (gen == NULL) {
     fprintf(stderr, "ERROR: cannot create generator object\n");
     exit (EXIT_FAILURE);
  }

  /* It is possible to reuse the distribution object to create   */
  /* another generator object. If you do not need it any more,   */
  /* it should be destroyed to free memory.                      */
  unur_distr_free(distr);

  /* Now you can use the generator object `gen' to sample from   */
  /* the standard Gaussian distribution.                         */
  /* Eg.:                                                        */
  for (i=0; i<10; i++) {
    x = unur_sample_cont(gen);
    printf("%f\n",x);
  }

  /* When you do not need the generator object any more, you     */
  /* can destroy it.                                             */
  unur_free(gen);

  exit (EXIT_SUCCESS);

} /* end of main() */

/* ------------------------------------------------------------- */