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

[main]

[main - data:]

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

[main - header:]

/* prototypes */
int unur_dsrou_set_pedantic( struct unur_par *par, int pedantic );

double pmf( int k, const UNUR_DISTR *distr );
double pmf_invalidmode( int k, const UNUR_DISTR *distr );

double pmf_geom05( int k, const UNUR_DISTR *distr );
double cdf_geom05( int k, const UNUR_DISTR *distr );

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

/* \#define SEED   (298346) */

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

[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(); ]

/* pmf, mode, pmfsum */
~( distr );
	--> expected_NULL --> UNUR_ERR_DISTR_REQUIRED

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

[set]

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

~_cdfatmode(par,0.);
	--> expected_setfailed --> UNUR_ERR_NULL

~_verify(par,1);
	--> expected_setfailed --> UNUR_ERR_NULL

[set - invalid parameter object:
   double fpar[2] = {10,0.63};
   distr = unur_distr_binomial(fpar,2);
   par = unur_dari_new(distr); ]

~_cdfatmode(par,0.);
	--> expected_setfailed --> UNUR_ERR_PAR_INVALID

~_verify(par,1);
	--> expected_setfailed --> UNUR_ERR_PAR_INVALID

unur_par_free(par);

[set - invalid parameters:
   double fpar[2] = {10.,0.63};
   distr = unur_distr_binomial(fpar,2);
   par = unur_dsrou_new(distr); ]

~_cdfatmode(par,-1.);
	--> expected_setfailed --> UNUR_ERR_PAR_SET

unur_par_free(par);

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

# [get]

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

[chg]

[chg - invalid generator object:
   double fpar[2] = {10.,0.63};
   distr = unur_distr_binomial(fpar,2);
   par = unur_dari_new(distr);
   unur_set_debug(par,0);
   gen = unur_init( par ); <-- ! NULL ]

~_verify(gen,1);
	--> expected_setfailed --> UNUR_ERR_GEN_INVALID

~_cdfatmode(gen,1.);
	--> expected_setfailed --> UNUR_ERR_GEN_INVALID


[chg - invalid parameters:
   double fpar[2] = {10.,0.63};
   distr = unur_distr_binomial(fpar,2);
   par = unur_dsrou_new(distr);
   gen = unur_init( par ); <-- ! NULL ]

~_cdfatmode(gen,-1.);
	--> expected_setfailed --> UNUR_ERR_PAR_SET


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

[init]

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

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


[init - invalid data:
   distr = unur_distr_discr_new();
   unur_distr_discr_set_pmf(distr,pmf);
   unur_distr_discr_set_mode(distr,2);
   unur_distr_discr_set_pmfsum(distr,1.);
   par = unur_dsrou_new(distr); ]

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

[init - data missing in distribution object:
   distr = unur_distr_discr_new();
   par = NULL; ]

/* mode, pmfsum */
unur_distr_discr_set_pmf(distr,pmf);
par = unur_dsrou_new( distr );
unur_init(par);
	--> expected_NULL --> UNUR_ERR_DISTR_REQUIRED

/* pmfsum */
unur_distr_discr_set_mode(distr,0);
par = unur_dsrou_new( distr );
unur_init(par);
	--> expected_NULL --> UNUR_ERR_DISTR_REQUIRED

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

[reinit]

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

unur_reinit( gen );
	--> expected_reinit

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

[sample]

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

/* default algorithm */
par = unur_dsrou_new(distr);
        -->compare_sequence_par_start

/* default algorithm - verifying mode */
par = unur_dsrou_new(distr);
unur_dsrou_set_verify(par,1);
        -->compare_sequence_par

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

[sample - violate condition:
   double fpar[2] = {10.,0.63};
   distr = unur_distr_binomial(fpar,2);
   par = NULL; ]

/* use cdf at mode */
par = unur_dsrou_new(distr);
unur_dsrou_set_cdfatmode(par,0.1);
        --> run_verify_generator --> UNUR_ERR_GEN_CONDITION

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

[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_dsrou_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_dsrou_new(distr);
gen = unur_init(par);
        -->compare_sequence_gen_start

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

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

[sample - compare stringparser:
   double fpar[] = {3.};
   distr = NULL;
   par = NULL;
   gen = NULL; ]

distr = unur_distr_poisson(fpar,1);
par = unur_dsrou_new(distr);
gen = unur_init(par);
	-->compare_sequence_gen_start
	
unur_free(gen); gen = NULL;
unur_distr_free(distr); distr = NULL;
gen = unur_str2gen( "poisson(3.) & method = dsrou" );
	-->compare_sequence_gen

unur_free(gen); gen = NULL;
unur_distr_free(distr); distr = NULL;
distr = unur_distr_poisson(fpar,1);
par = unur_dsrou_new(distr);
unur_dsrou_set_cdfatmode(par,0.3);
unur_dsrou_set_verify(par,1);
gen = unur_init(par);
	-->compare_sequence_gen_start
	
unur_free(gen); gen = NULL;
unur_distr_free(distr); distr = NULL;
gen = unur_str2gen( "poisson(3.) & method = dsrou; cdfatmode=0.3; verify=on" );
	-->compare_sequence_gen


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

[validate]

[validate - generators:]

# default variant
par[0] = unur_dsrou_new(@distr@);

# use cdf at mode
{ double Fmode = unur_distr_discr_eval_cdf( unur_distr_discr_get_mode(@distr@), @distr@ );
par[1] = unur_dsrou_new(@distr@);
unur_dsrou_set_cdfatmode(par,Fmode); }

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

# default variant but reinitialized with changed pdf parameters
{ UNUR_DISTR *dg =NULL;
par[3] = unur_dsrou_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_distr_discr_upd_mode(dg);
unur_reinit(gen); }


[validate - distributions:]

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

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

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

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

fpm[0] = 0.9;
distr[4] = unur_distr_logarithmic(fpm,1);

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

fpm[0] = 0.7;
fpm[1] = 5.;
distr[6] = unur_distr_negativebinomial(fpm,2);

fpm[0] = 0.1;
fpm[1] = 20.;
distr[7] = unur_distr_negativebinomial(fpm,2);

# poisson distribution
fpm[0] = 3.;
distr[8] = unur_distr_poisson(fpm,1);

fpm[0] = 50.;
distr[9] = unur_distr_poisson(fpm,1);

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

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

# binomial distribution
fpm[0] = 2000.;
fpm[1] = 0.0013;
distr[12] = unur_distr_binomial(fpm,2);

# Hyper geometric distribution
fpm[0] = 2000.;
fpm[1] = 200.;
fpm[2] = 20;
distr[13] = unur_distr_hypergeometric(fpm,3);

# Hyper geometric distribution
fpm[0] = 2000.;
fpm[1] = 200.;
fpm[2] = 220;
distr[14] = unur_distr_hypergeometric(fpm,3);

# Test for mode finding algorithm
distr[15] = unur_distr_discr_new();
unur_distr_discr_set_pmf(distr[15],pmf_geom05);
unur_distr_discr_set_cdf(distr[15],cdf_geom05);
unur_distr_set_name(distr[15],"test find_mode");

# number of distributions: 16

[validate - test chi2:]

#  + ... pass test
#  0 ... fail to initialize generator (given variant does not exist)
#  - ... fail test
#  . ... do not run test
#  # ... comment
#
# generators:
#   [0] ... default
#   [1] ... use cdf at mode-1
#   [2] ... default variant but reinitialized with changed domain
#   [3] ....default variant but reinitialized with changed pdf parameters
#
#gen	0   1   2   3   # distribution
#----------------------------------------------------
  <0>	+   +   +   .	# geometric (0.5)
  <1>	+   +   +   .	# geometric (0.1)
  <2>	+   +   +   .	# geometric (0.001)
  <3>	+   +   +   .	# logarithmic (0.1)
  <4>	+   +   +   .	# logarithmic (0.9)
  <5>	+   +   +   .	# negativebinomial (0.5, 10)
  <6>	+   +   +   .	# negativebinomial (0.7, 5)
  <7>	+   +   +   .	# negativebinomial (0.1, 20)
  <8>	+   +   +   .	# poisson (3)
  <9>	+   +   +   .	# poisson (20)
#<10>	.   .   .   .	# zipf (2, 1)
 <11>	+   +   +   +	# binomial (20, 0.8)
 <12>	+   +   +   +	# binomial (2000, 0.0013)
 <13>	+   +   +   .	# hypergeometric (2000, 200, 20)
 <14>	+   +   +   .	# hypergeometric (2000, 200, 220)
 <15>	+   .   .   .	# geomtric(0.5) with domain (1,inf)

# number of distributions: 16


[validate - verify hat:]

#  + ... pass test
#  ~ ... fail in at most 1% of samples
#  0 ... fail to initialize generator
#  - ... fail test
#  . ... do not run test
#  # ... comment
#
#
# generators:
#   [0] ... default
#   [1] ... use cdf at mode-1
#   [2] ... default variant but reinitialized with changed domain
#   [3] ....default variant but reinitialized with changed pdf parameters
#
#gen	0   1   2   3   # distribution
#----------------------------------------------------
  <0>	+   +   +   .	# geometric (0.5)
  <1>	+   +   +   .	# geometric (0.1)
  <2>	+   +   +   .	# geometric (0.001)
  <3>	+   +   +   .	# logarithmic (0.1)
  <4>	+   +   +   .	# logarithmic (0.9)
  <5>	+   +   +   .	# negativebinomial (0.5, 10)
  <6>	+   +   +   .	# negativebinomial (0.7, 5)
  <7>	+   +   .   .	# negativebinomial (0.1, 20)
  <8>	+   +   +   .	# poisson (3)
  <9>	+   +   +   .	# poisson (20)
#<10>	.   .   .   .	# zipf (2, 1)
 <11>	+   +   +   +	# binomial (20, 0.8)
 <12>	+   +   +   +	# binomial (2000, 0.0013)
 <13>	+   +   +   .	# hypergeometric (2000, 200, 20)
 <14>	+   +   +   .	# hypergeometric (2000, 200, 220)
 <15>	+   .   .   .	# geomtric(0.5) with domain (1,inf)

# number of distributions: 16


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

[verbatim]

/* pmf that does not work */
double pmf( int k, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{ 
	return ((k==2) ? 0. : pow(0.5,(double)k));
} /* end of pmf */

double pmf_invalidmode( int k, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{ 
	return ((k==2) ? 0.01 : pow(0.5,(double)k));
} /* end of pmf */


/* pmf for geometric(0.5) distribution with domain (1,inf) */
double pmf_geom05( int k, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{
	return (pow(0.5,(double)k));
}

double cdf_geom05( int k, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{
	return (1.-pow(0.5,(double)k));
}


/* dummy function */
int unur_dsrou_set_pedantic( struct unur_par *par ATTRIBUTE__UNUSED, int pedantic ATTRIBUTE__UNUSED)
{ return 1; }

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