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

[main]

[main - data:]

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

[main - header:]

/* prototypes */

int check_init(UNUR_GEN *gen);
int check_sample(UNUR_GEN *gen);

int geom12_sample(UNUR_GEN *gen);

int geoma_sample(UNUR_GEN *gen);

int geomb_init(UNUR_GEN *gen);
int geomb_sample(UNUR_GEN *gen);

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

/* \#define SEED   (298346) */


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

[new]

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

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


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

[set]

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

~_init(par,NULL);
	--> expected_setfailed --> UNUR_ERR_NULL

~_sample(par,NULL);
	--> expected_setfailed --> UNUR_ERR_NULL


[set - invalid parameter object:
   distr = unur_distr_normal(NULL,0);
   par = unur_arou_new(distr); ]

~_init(par,NULL);
	--> expected_setfailed --> UNUR_ERR_PAR_INVALID

~_sample(par,NULL);
	--> expected_setfailed --> UNUR_ERR_NULL

~_sample(par,check_sample);
	--> expected_setfailed --> UNUR_ERR_PAR_INVALID

unur_par_free(par);


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

[get]

[get - invalid NULL ptr: 
   gen = NULL; ]

~_params(gen,(size_t)0);
	--> expected_NULL --> UNUR_ERR_NULL

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

# [chg]

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

[init]

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

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


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

[reinit]

#[reinit - does not exist:
#   distr = unur_distr_exponential(NULL,0);
#   par = unur_dext_new(distr);
#   unur_dext_set_sample(par,geom12_sample);
#   gen = unur_init(par); <-- ! NULL ]

#unur_reinit( gen );
#	--> expected_reinit


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

[sample]

[sample - compare clone:
   UNUR_GEN *clone;
   double fpar[1] = {0.5};
   distr = unur_distr_geometric(fpar,1);
   par = NULL;
   gen = NULL; ]

/* external generator 1 */
par = unur_dext_new(distr);
unur_dext_set_sample(par,geom12_sample);
gen = unur_init(par);
	-->compare_sequence_gen_start

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

/* dstd */
unur_free(gen);
par = unur_dstd_new(distr);
gen = unur_init(par);
	-->compare_sequence_gen


/* external generator A */
unur_free(gen);
par = unur_dext_new(distr);
unur_dext_set_sample(par,geoma_sample);
gen = unur_init(par);
	-->compare_sequence_gen

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

/* external generator B */
unur_free(gen);
par = unur_dext_new(distr);
unur_dext_set_init(par,geomb_init);
unur_dext_set_sample(par,geomb_sample);
gen = unur_init(par);
	-->compare_sequence_gen

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

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

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

/* external generator A */
unur_free(gen);
par = unur_dext_new(distr);
unur_dext_set_sample(par,geoma_sample);
gen = unur_init(par);
	-->compare_sequence_gen_start

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

/* external generator B */
unur_free(gen);
par = unur_dext_new(distr);
unur_dext_set_init(par,geomb_init);
unur_dext_set_sample(par,geomb_sample);
gen = unur_init(par);
	-->compare_sequence_gen

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

/* dstd */
unur_free(gen);
par = unur_dstd_new(distr);
gen = unur_init(par);
	-->compare_sequence_gen


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

[validate]

[validate - generators:]

# geometric(0.5):
#	geometric distribution; do not read any parameters
par[0] = unur_dext_new(@distr@);
unur_dext_set_sample(par,geom12_sample);

# geometric(p):
#	use pointer to parameter of distribution in sampling routine
par[1] = unur_dext_new(@distr@);
unur_dext_set_sample(par,geoma_sample);

# geometric(p):
#	store parameter of distribution in generator object during init
par[2] = unur_dext_new(@distr@);
unur_dext_set_init(par,geomb_init);
unur_dext_set_sample(par,geomb_sample);

# geometric(p):
#	store parameter of distribution in generator object during init
#      change parameters
{ UNUR_DISTR *dg =NULL;
par[3] = unur_dext_new(@distr@);
unur_dext_set_init(par,geomb_init);
unur_dext_set_sample(par,geomb_sample);
fpm[0] = 0.2;
dg = unur_get_distr(gen);
unur_distr_discr_set_pmfparams(dg,fpm,1);
unur_reinit(gen); }


[validate - distributions:]

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

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

## number of distributions: 2

[validate - test chi2:]

#  + ... pass test
#  0 ... fail to initialize generator (given variant does not exist)
#  - ... fail test
#  / ... either init fails or test passes
#  . ... do not run test
#  # ... comment
#
# generators:
#   [0] ... Geometric(p)
#   [1] ... Geometric(p): use pointer to distribution
#   [2] ... Geometric(p): store distrparams in object
#   [3] ... Geometric, reinit with changed parameters
#
#gen	0  1  2  3	# distribution
#-------------------------------------------------------------
 <0>	+  +  +  +	# geometric(0.5)
 <1>	-  +  +  +	# geometric(0.1)


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

[verbatim]

int check_init(UNUR_GEN *gen ATTRIBUTE__UNUSED) { return UNUR_SUCCESS; }
int check_sample(UNUR_GEN *gen ATTRIBUTE__UNUSED) { return 0; }

/* ............. */

int geom12_sample(UNUR_GEN *gen) { 
	double U = unur_sample_urng(gen);
	return ((int) ceil(log(1.-U) / log(0.5) - 1.));
}

/* ............. */

int geoma_sample(UNUR_GEN *gen) { 
\#	define p (params[0])     /* scale */
	double U = unur_sample_urng(gen);
	double *params = unur_dext_get_distrparams(gen);
	return ((int) ceil(log(1.-U) / log(1.-p) - 1.));
\#	undef p
}

/* ............. */

int geomb_init(UNUR_GEN *gen) { 
\#	define p (params[0])     /* scale */
	double *params = unur_dext_get_distrparams(gen);
	double *genpar = unur_dext_get_params(gen, sizeof(double));
	genpar[0] = p;
	return UNUR_SUCCESS;
\#	undef p
}

int geomb_sample(UNUR_GEN *gen) { 
\#	define p (params[0])     /* scale */
	double *params = unur_dext_get_params(gen,(size_t)0);
	double U = unur_sample_urng(gen);
	return ((int) ceil(log(1.-U) / log(1.-p) - 1.));
\#	undef p
}

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