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

[main]

[main - data:]

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

[main - header:]

/* prototypes */

int unur_dari_set_pedantic( struct unur_par *par, int pedantic );

double pmf_poisson5(int k, const UNUR_DISTR *distr);
double pmf_poisson5_NaN(int k, const UNUR_DISTR *distr);
double pmf_poisson50(int k, const UNUR_DISTR *distr);

double pmf_negpoisson5(int k, const UNUR_DISTR *distr);
double pmf_negpoisson50(int k, const UNUR_DISTR *distr);

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

/* \#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();   /* no PMF */ ]

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

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

[set]

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

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

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

~_tablesize(par,100);
	--> expected_setfailed --> UNUR_ERR_NULL

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


[set - invalid parameter object:
   double fpar[1] = {0.5};
   distr = unur_distr_geometric(fpar,1);
   par = unur_dgt_new(distr); ]

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

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

~_tablesize(par,100);
	--> expected_setfailed --> UNUR_ERR_PAR_INVALID

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

unur_par_free(par);

[set - invalid parameters:
   double fpar[1] = {0.5};
   distr = unur_distr_geometric(fpar,1);
   par = unur_dari_new(distr); ]

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

~_cpfactor(par,3.);
	--> none --> UNUR_ERR_PAR_SET

~_tablesize(par,-100);
	--> expected_setfailed --> UNUR_ERR_PAR_SET

unur_par_free(par);

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

# [get]

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

[chg]

[chg - invalid generator object:
   double fpar[1] = {0.5};
   distr = unur_distr_geometric(fpar,1);
   par = unur_dgt_new(distr);
   unur_set_debug(par,0);
   gen = unur_init( par ); <-- ! NULL ]

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


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

# [init]

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

[reinit]

[reinit - exist:
   double fpar[1] = {0.5};
   distr = unur_distr_geometric(fpar,1);
   par = unur_dari_new(distr);
   gen = unur_init( par ); <-- ! NULL ]

unur_reinit( gen );
	--> expected_reinit

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

[sample]

[sample - compare:
   double fpar[] = {0.1};
   distr = unur_distr_geometric(fpar,1);
   par = NULL; ]

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

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

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

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

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

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

[sample - compare stringparser:
   double fpar[] = {20, 0.8};
   distr = NULL;
   par = NULL;
   gen = NULL; ]

distr = unur_distr_binomial(fpar,2);
par = unur_dari_new(distr);
unur_dari_set_cpfactor(par,0.7);
unur_dari_set_squeeze(par,TRUE);
unur_dari_set_tablesize(par,30);
unur_dari_set_verify(par,FALSE);
gen = unur_init(par);
	-->compare_sequence_gen_start
	
unur_free(gen); gen = NULL;
unur_distr_free(distr); distr = NULL;
gen = unur_str2gen( "binomial(20,0.8) & \
  method = dari; cpfactor = 0.7; squeeze; tablesize = 30; verify = off" );
	-->compare_sequence_gen


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

[validate]

[validate - generators:]

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

# with table and with squeeze
par[1] = unur_dari_new(@distr@);
unur_dari_set_tablesize(par, 100);
unur_dari_set_squeeze(par, 1);

# with table and without squeeze
par[2] = unur_dari_new(@distr@);
unur_dari_set_tablesize(par, 100);
unur_dari_set_squeeze(par, 0);

# without table and with squeeze
par[3] = unur_dari_new(@distr@);
unur_dari_set_tablesize(par, 0);
unur_dari_set_squeeze(par, 1);

# without table and without squeeze
par[4] = unur_dari_new(@distr@);
unur_dari_set_tablesize(par, 0);
unur_dari_set_squeeze(par, 0);

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

# default variant but reinitialized with changed pmf parameters
{ UNUR_DISTR *dg =NULL;
par[6] = unur_dari_new(@distr@);
fpm[0] = 0.4;
dg = unur_get_distr(gen); 
unur_distr_discr_set_pmfparams(dg,fpm,1);
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);
unur_distr_discr_set_domain(distr[10],1,1000);

# 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);

# Special tests with Poission distribution
distr[15] = unur_distr_discr_new();
unur_distr_discr_set_pmf(distr[15],pmf_poisson5);
unur_distr_set_name(distr[15],"test-poisson");

distr[16] = unur_distr_discr_new();
unur_distr_discr_set_pmf(distr[16],pmf_poisson5);
unur_distr_set_name(distr[16],"test-poisson");

distr[17] = unur_distr_discr_new();
unur_distr_discr_set_pmf(distr[17],pmf_poisson5);
unur_distr_set_name(distr[17],"test-poisson");

distr[18] = unur_distr_discr_new();
unur_distr_discr_set_pmf(distr[18],pmf_poisson5);
unur_distr_discr_set_domain(distr[18],INT_MIN,INT_MAX);
unur_distr_set_name(distr[18],"test-poisson");

distr[19] = unur_distr_discr_new();
unur_distr_discr_set_pmf(distr[19],pmf_negpoisson5);
unur_distr_discr_set_domain(distr[19],INT_MIN,INT_MAX);
unur_distr_set_name(distr[19],"test-poisson");

distr[20] = unur_distr_discr_new();
unur_distr_discr_set_pmf(distr[20],pmf_negpoisson5);
unur_distr_discr_set_domain(distr[20],INT_MIN,0);
unur_distr_set_name(distr[20],"test-poisson");

distr[21] = unur_distr_discr_new();
unur_distr_discr_set_pmf(distr[21],pmf_negpoisson50);
unur_distr_discr_set_domain(distr[21],INT_MIN,INT_MAX);
unur_distr_set_name(distr[21],"test-poisson");

distr[22] = unur_distr_discr_new();
unur_distr_discr_set_pmf(distr[22],pmf_negpoisson50);
unur_distr_discr_set_domain(distr[22],INT_MIN,0);
unur_distr_set_name(distr[22],"test-poisson");


# number of distributions: 23


[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] ... with table and with squeeze
#   [2] ... with table and without squeeze
#   [3] ... without table and with squeeze
#   [4] ... without table and without squeeze
#   [5] ... default variant but reinitialized with changed domain
#   [6] ... default variant but reinitialized with changed pmf parameters
#
#gen	0   1   2   3   4   5   6	# distribution
#-------------------------------------------------------------
  <0>	+   +   +   +   +   +   +	# geometric (0.5)
x <1>	+   +   +   +   +   +   +	# geometric (0.1)
  <2>	+   +   +   +   +   +   +	# geometric (0.001)
  <3>	+   +   +   +   +   +   +	# logarithmic (0.1)
  <4>	+   +   +   +   +   +   +	# logarithmic (0.9)
x <5>	+   +   +   +   +   +   .	# negativebinomial (0.5, 10)
  <6>	+   +   +   +   +   +   .	# negativebinomial (0.7, 5)
  <7>	+   +   +   +   +   +   .	# negativebinomial (0.1, 20)
  <8>	+   +   +   +   +   +   .	# poisson (3)
  <9>	+   +   +   +   +   +   .	# poisson (50)
 <10>	+   +   +   +   +   +   .	# zipf (2, 1)
 <11>	+   +   +   +   +   +   .	# binomial (20, 0.8)
 <12>	+   +   +   +   +   +   .	# binomial (2000, 0.0013)
 <13>	+   +   +   +   +   +   .	# hypergeometric (2000, 200, 20)
x<14>	+   +   +   +   +   +   .	# hypergeometric (2000, 200, 220)

 <15>	+   +   +   +   +   +   .	# poisson (5), search for mode
 <16>	+   +   +   +   +   +   .	# poisson (5), search for mode, returns NaN 
 <17>	+   +   +   +   +   +   .	# poisson (50), search for mode
#<18>	+   +   +   +   +   +   .	# poisson (5), search for mode, domain = (-oo,oo)
#<19>	+   +   +   +   +   +   .	# -poisson (5), search for mode, domain = (-oo,oo)
#<20>	+   +   +   +   +   +   .	# -poisson (5), search for mode, domain = (-oo,0)
#<21>	+   +   +   +   +   +   .	# -poisson (50), search for mode, domain = (-oo,oo)
#<22>	+   +   +   +   +   +   .	# -poisson (50), search for mode, domain = (-oo,0)


[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] ... with table and with squeeze
#   [2] ... with table and without squeeze
#   [3] ... without table and with squeeze
#   [4] ... without table and without squeeze
#   [5] ... default variant but reinitialized with changed domain
#   [6] ... default variant but reinitialized with changed pmf parameters
#
#gen	0   1   2   3   4   5   6	# distribution
#-------------------------------------------------------------
  <0>	+   +   +   +   +   +   +	# geometric (0.5)
x <1>	+   +   +   +   +   +   +	# geometric (0.1)
  <2>	+   +   +   +   +   +   +	# geometric (0.001)
  <3>	+   +   +   +   +   +   +	# logarithmic (0.1)
  <4>	+   +   +   +   +   +   +	# logarithmic (0.9  )
x <5>	+   +   +   +   +   +   .	# negativebinomial (0.5, 10)
  <6>	+   +   +   +   +   +   .	# negativebinomial (0.7, 5)
  <7>	+   +   +   +   +   +   .	# negativebinomial (0.1, 20)
  <8>	+   +   +   +   +   +   .	# poisson (3)
  <9>	+   +   +   +   +   +   .	# poisson (50)
 <10>	+   +   +   +   +   +   .	# zipf (2, 1)
 <11>	+   +   +   +   +   +   .	# binomial (20, 0.8)
 <12>	+   +   +   +   +   +   .	# binomial (2000, 0.0013)
 <13>	+   +   +   +   +   +   .	# hypergeometric (2000, 200, 20)
x<14>	+   +   +   +   +   +   .	# hypergeometric (2000, 200, 220)

 <15>	+   +   +   +   +   +   .	# poisson (5), search for mode
 <16>	+   +   +   +   +   +   .	# poisson (5), search for mode, returns NaN 
 <17>	+   +   +   +   +   +   .	# poisson (50), search for mode
#<18>	+   +   +   +   +   +   .	# poisson (5), search for mode, domain = (-oo,oo)
 <19>	0   0   0   0   0   0   .	# -poisson (5), search for mode, domain = (-oo,oo)
#<20>	+   +   +   +   +   +   .	# -poisson (5), search for mode, domain = (-oo,0)
#<21>	+   +   +   +   +   +   .	# -poisson (50), search for mode, domain = (-oo,oo)
#<22>	+   +   +   +   +   +   .	# -poisson (50), search for mode, domain = (-oo,0)


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

[verbatim]

/* no such function */
int unur_dari_set_pedantic( struct unur_par *par ATTRIBUTE__UNUSED, int pedantic ATTRIBUTE__UNUSED)
{ return 1; }

\#include <unur_source.h>

double pmf_poisson5(int k, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{ 
	double theta = 5.;
	return ((k<0) ? 0. : exp( -theta + k * log(theta) - _unur_SF_ln_factorial(k) ));
}

double pmf_poisson5_NaN(int k, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{ 
	double theta = 5.;
	return ((k<0) ? 0. : exp( -theta + k * log(theta)) / exp (_unur_SF_ln_factorial(k) ));
}

double pmf_poisson50(int k, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{ 
	double theta = 50.;
	return ((k<0) ? 0. : exp( -theta + k * log(theta) - _unur_SF_ln_factorial(k) ));
}

double pmf_negpoisson5(int k, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{ 
	double theta = 5.;
	k *= -1;
	return ((k<0) ? 0. : exp( -theta + k * log(theta) - _unur_SF_ln_factorial(k) ));
}

double pmf_negpoisson50(int k, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{ 
	double theta = 50.;
	k *= -1;
	return ((k<0) ? 0. : exp( -theta + k * log(theta) - _unur_SF_ln_factorial(k) ));
}

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