#############################################################################

[main]

[main - data:]

# method (for information only: the program scans the file name)
method: DAU

[main - header:]

/* prototypes */

\#define COMPARE_SAMPLE_SIZE   (10000)
\#define VIOLATE_SAMPLE_SIZE   (20)

double *make_geometric_vector(double q, int len);
double *make_uniform_vector(double p, int len);
double *make_random_vector(int len);
UNUR_DISTR *get_distr_with_invalid_pv( void );
UNUR_DISTR *get_distr_with_pv( void );

#############################################################################

[new]

[new - invalid NULL ptr: 
   distr = NULL; ]

~( distr );
	--> expected_NULL --> UNUR_ERR_NULL

[new - invalid distribution type:
   distr = unur_distr_cont_new(); ]

~( distr );
	 --> expected_NULL --> UNUR_ERR_DISTR_INVALID

[new - data missing in distribution object:
   distr = unur_distr_discr_new();   /* no probability vector */ ]

~( distr );
	--> expected_NULL --> UNUR_ERR_DISTR_REQUIRED

#############################################################################

[set]

[set - invalid NULL ptr: 
   par = NULL; ]

~_urnfactor(par,1.);
	--> expected_setfailed --> UNUR_ERR_NULL

[set - invalid parameter object:
   distr = get_distr_with_pv();
   par = unur_dgt_new(distr); ]

~_urnfactor(par,1.);
	--> expected_setfailed --> UNUR_ERR_PAR_INVALID

unur_par_free(par);

[set - invalid parameters:
   distr = get_distr_with_pv();
   par = unur_dau_new(distr); ]

~_urnfactor(par,0.8);
	--> expected_setfailed --> UNUR_ERR_PAR_SET

unur_par_free(par);

#############################################################################

# [get]

#############################################################################

# [chg]

#############################################################################

[init]

[init - invalid NULL ptr: 
   par = NULL; ]

unur_init( par );
	--> expected_NULL --> UNUR_ERR_NULL


[init - invalid data:
   distr = get_distr_with_invalid_pv();
   par = unur_dau_new(distr); ]

unur_init( par );
	--> expected_NULL --> UNUR_ERR_GEN_DATA



#############################################################################

[reinit]

[reinit - exist:
   double fpar[2] = {10.,0.63};
   distr = unur_distr_binomial(fpar,2);
   par = unur_dau_new(distr);
   gen = unur_init( par ); <-- ! NULL ]

unur_reinit( gen );
	--> expected_reinit


#############################################################################

[sample]

[sample - compare clone:
   UNUR_GEN *clone;
   double fpar[] = {10,0.3}; 
   distr = unur_distr_binomial(fpar,2);
   par = NULL;
   gen = NULL; ]

/* original generator object */
par = unur_dau_new(distr);
gen = unur_init(par);
        -->compare_sequence_gen_start

/* clone */
clone = unur_gen_clone(gen);
unur_free(gen);
gen = clone;
        -->compare_sequence_gen

#.....................................................................

[sample - compare reinit:
   double fpar[] = {10,0.3}; 
   distr = unur_distr_binomial(fpar,2);
   par = NULL;
   gen = NULL; ]

/* original generator object */
par = unur_dau_new(distr);
gen = unur_init(par);
        -->compare_sequence_gen_start

/* reinit */
unur_reinit(gen);
        -->compare_sequence_gen

#.....................................................................

[sample - compare stringparser:
   double pv[] = {.1, .2, .3, .4, .5, .6, .7, .8, .9, 1.};
   double fpar[] = {0.8};
   distr = NULL;
   par = NULL;
   gen = NULL; ]

distr = unur_distr_discr_new();
unur_distr_discr_set_pv(distr,pv,10);
par = unur_dau_new(distr);
unur_dau_set_urnfactor(par,3.);
gen = unur_init(par);
	-->compare_sequence_gen_start
	
unur_free(gen); gen = NULL;
unur_distr_free(distr); distr = NULL;
gen = unur_str2gen( "discr; pv = (.1, .2, .3, .4, .5, .6, .7, .8, .9, 1.) & \
  method = dau; urnfactor = 3." );
	-->compare_sequence_gen


unur_free(gen); gen = NULL;
distr = unur_distr_geometric(fpar,1);
par = unur_dau_new(distr);
unur_dau_set_urnfactor(par,3.);
gen = unur_init(par);
	-->compare_sequence_gen_start
	
unur_free(gen); gen = NULL;
unur_distr_free(distr); distr = NULL;
gen = unur_str2gen( "geometric(0.8) & method = dau; urnfactor = 3." );
	-->compare_sequence_gen


#############################################################################

[validate]

[validate - generators:]

# default program
par[0] = unur_dau_new(@distr@);
#unur_set_debug(par, 1u);

# larger urn table size
par[1] = unur_dau_new(@distr@);
unur_dau_set_urnfactor(par[1],10.);
unur_set_debug(par, 1u);

# default variant but reinitialized with changed domain
{ UNUR_DISTR *dg =NULL;
par[2] = unur_dau_new(@distr@);
dg = unur_get_distr(gen);
unur_distr_discr_set_domain(dg,2,7);
unur_distr_discr_upd_pmfsum(dg);
unur_reinit(gen); }

# default variant but reinitialized with changed pdf parameters
{ UNUR_DISTR *dg =NULL;
par[3] = unur_dau_new(@distr@);
fpm[0] = 10.;
fpm[1] = 0.63;
dg = unur_get_distr(gen);
unur_distr_discr_set_pmfparams(dg,fpm,2);
unur_distr_discr_upd_pmfsum(dg);
unur_reinit(gen); }

[validate - distributions:]

# probability vector with random entries
distr[0] = unur_distr_discr_new();
darray = make_random_vector(10);
unur_distr_discr_set_pv(distr[0],darray,10);
free(darray);
unur_distr_set_name(distr[0],"pv(random)");

distr[1] = unur_distr_discr_new();
darray = make_random_vector(100);
unur_distr_discr_set_pv(distr[1],darray,100);
free(darray);
unur_distr_set_name(distr[1],"pv(random)");

distr[2] = unur_distr_discr_new();
darray = make_random_vector(1000);
unur_distr_discr_set_pv(distr[2],darray,1000);
free(darray);
unur_distr_set_name(distr[2],"pv(random)");

distr[3] = unur_distr_discr_new();
darray = make_random_vector(10000);
unur_distr_discr_set_pv(distr[3],darray,10000);
free(darray);
unur_distr_set_name(distr[3],"pv(random)");

# probability vector with geometrically distributed entries
distr[4] = unur_distr_discr_new();
darray = make_geometric_vector(1.,1000);
unur_distr_discr_set_pv(distr[4],darray,1000);
free(darray);
unur_distr_set_name(distr[4],"pv(geometric)");

distr[5] = unur_distr_discr_new();
darray = make_geometric_vector(0.99,1000);
unur_distr_discr_set_pv(distr[5],darray,1000);
free(darray);
unur_distr_set_name(distr[5],"pv(geometric)");

distr[6] = unur_distr_discr_new();
darray = make_geometric_vector(0.9,1000);
unur_distr_discr_set_pv(distr[6],darray,1000);
free(darray);
unur_distr_set_name(distr[6],"pv(geometric)");

distr[7] = unur_distr_discr_new();
darray = make_geometric_vector(0.5,1000);
unur_distr_discr_set_pv(distr[7],darray,1000);
free(darray);
unur_distr_set_name(distr[7],"pv(geometric)");

distr[8] = unur_distr_discr_new();
darray = make_geometric_vector(0.1,1000);
unur_distr_discr_set_pv(distr[8],darray,1000);
free(darray);
unur_distr_set_name(distr[8],"pv(geometric)");

# probability vecotr with geometrically distributed entries and shifted domain
distr[9] = unur_distr_discr_new();
darray = make_geometric_vector(0.9,100);
unur_distr_discr_set_pv(distr[9],darray,100);
unur_distr_discr_set_domain(distr[9],10,209);
free(darray);
unur_distr_set_name(distr[9],"pv(geometric) - shifted domain");

distr[10] = unur_distr_discr_new();
darray = make_geometric_vector(0.9,100);
unur_distr_discr_set_pv(distr[10],darray,100);
unur_distr_discr_set_domain(distr[10],-10,209);
free(darray);
unur_distr_set_name(distr[10],"pv(geometric) - shifted domain");

# uniform distribution
# (failed ib former version of algorithm)
distr[23] = unur_distr_discr_new();
darray = make_uniform_vector(exp(1.),1533);
unur_distr_discr_set_pv(distr[23],darray,1533);
free(darray);
unur_distr_set_name(distr[23],"pv(uniform)");

# PMF instead of PV

# geometric disctribution
fpm[0] = 0.5;
distr[11] = unur_distr_geometric(fpm,1);

fpm[0] = 0.001;
distr[12] = unur_distr_geometric(fpm,1);

# logarithmic distribution
fpm[0] = 0.1;
distr[13] = unur_distr_logarithmic(fpm,1);

fpm[0] = 0.999;
distr[14] = unur_distr_logarithmic(fpm,1);

# negative binomial distribution
fpm[0] = 0.5;
fpm[1] = 10.;
distr[15] = unur_distr_negativebinomial(fpm,2);

fpm[0] = 0.01;
fpm[1] = 20.;
distr[16] = unur_distr_negativebinomial(fpm,2);

# poisson distribution
fpm[0] = 0.1;
distr[17] = unur_distr_poisson(fpm,1);

fpm[0] = 0.999;
distr[18] = unur_distr_poisson(fpm,1);

# zipf distribution
fpm[0] = 2.;
fpm[1] = 1.;
distr[19] = unur_distr_zipf(fpm,2);
unur_distr_discr_set_domain(distr[19],1,1000);

fpm[0] = 0.001;
fpm[1] = 1.;
distr[20] = unur_distr_zipf(fpm,2);
unur_distr_discr_set_domain(distr[20],1,1000);

# binomial distribution
fpm[0] = 20.;
fpm[1] = 0.8;
distr[21] = unur_distr_binomial(fpm,2);

fpm[0] = 2000.;
fpm[1] = 0.0013;
distr[22] = unur_distr_binomial(fpm,2);

# number of distributions: 24


[validate - test chi2:]

#  + ... pass test
#  0 ... fail to initialize generator
#  - ... fail test
#  . ... do not run test
#  # ... comment
#
#   [0] ... default
#   [1] ... larger urn table size
#   [2] ... default variant but reinitialized with changed domain
#   [3] ....default variant but reinitialized with changed pdf parameters
#
#gen	0   1   2   3		# distribution
#-------------------------------------
  <0>	+   +   +   .		# PV with random entries
  <1>	+   +   +   .
  <2>	+   +   +   .
x <3>	+   +   +   .

x <4>	+   +   +   .		# PV with geometrically distributed entries
  <5>	+   +   +   .
x <6>	+   +   +   .
  <7>	+   +   +   .
x <8>	+   +   +   .

  <9>	+   +   +   .		# PV with geom. distr. entries and shifted domain
 <10>	+   +   +   .

 <23>   +   +   .   .           # PV with uniform distr. (0.1, size=100)

# PMF instead of PV

 <11>	+   +   +   .		# geometric (0.5)
 <12>	+   +   +   .		# geometric (0.001)
 <13>	+   +   +   .		# logarithmic (0.1)
 <14>	+   +   +   .		# logarithmic (0.999)
 <15>	+   +   +   .		# negativebinomial (0.5, 10)
x<16>	+   +   +   .		# negativebinomial (0.01, 20)
x<17>	+   +   +   .		# poisson (0.1)
 <18>	+   +   +   .		# poisson (0.999)
 <19>	+   +   +   .		# zipf (2, 1)
x<20>	+   +   +   .		# zipf (0.001, 1)
 <21>	+   +   +   +		# binomial (20, 0.8)
x<22>	+   +   +   +		# binomial (2000, 0.0013)

# number of distributions: 24

#############################################################################
#############################################################################

[verbatim]

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

/* make a probability vector (need not sum to one)
   (use random entries)                                                      */
double *make_random_vector(int len)
{
  double *pv;
  int i;

  /* allocate memory */
  pv = malloc(len*sizeof(double));
  if (!pv) abort();
     
  /* main part of geometric distribution */
  for( i=0; i<len; i++ ) 
    pv[i] = unur_urng_fish(NULL);

  return pv;

} /* end of make_random_vector() */

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

/* make a probability vector (need not sum to one)
   (use geometric distribution)                                              */
double *make_geometric_vector(double q, int len)
{
  double *pv;
  int i;

  /* allocate memory */
  pv = malloc(len * sizeof(double));
  if (!pv) abort();

  /* main part of geometric distribution */
  pv[0] = 1.;
  for( i=1; i<len; i++ ) 
    pv[i] = pv[i-1] * q;

  return pv;

} /* end of make_geometric_vector() */

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

/* make a probability vector (need not sum to one)
   (use uniform distribution)                                                */
double *make_uniform_vector(double p, int len)
{
  double *pv;
  int i;

  /* allocate memory */
  pv = malloc(len * sizeof(double));
  if (!pv) abort();

  /* main part of geometric distribution */
  for( i=0; i<len; i++ ) 
    pv[i] = p;

  return pv;

} /* end of make_uniform_vector() */

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

UNUR_DISTR *get_distr_with_pv( void )
{
\#define PV_SIZE 200
  double pv[PV_SIZE];
  UNUR_DISTR *distr;
  int i;

  for (i=0; i<PV_SIZE; i++)
    pv[i] = unur_urng_fish(NULL);

  distr = unur_distr_discr_new();
  unur_distr_discr_set_pv(distr,pv,PV_SIZE);

  return distr;

\#undef PV_SIZE
} /* end of get_distr_with_pv() */

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

UNUR_DISTR *get_distr_with_invalid_pv( void )
{
\#define PV_SIZE 10
  double pv[PV_SIZE];
  UNUR_DISTR *distr;
  int i;

  pv[0] = -1.;    /* invalid ! */

  for (i=1; i<PV_SIZE; i++)
    pv[i] = unur_urng_fish(NULL);

  distr = unur_distr_discr_new();
  unur_distr_discr_set_pv(distr,pv,PV_SIZE);

  return distr;
  
\#undef PV_SIZE
} /* end of get_distr_with_invalid_pv() */

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

#############################################################################
