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

[main]

[main - data:]

# method
method: NINV

[main - header:]

\#include <methods/x_gen_source.h>

/* -- which tests for u-error should be performed (for development) -- */

\#define DEVEL (0)    /* whether to run tests in development mode */
\#define ALL   (1)

\#define UERROR_STANDARDDIST  (1)
\#define UERROR_QUASIPDF      DEVEL
\#define UERROR_VANISHINGPDF  DEVEL
\#define UERROR_TRUNCATED     (1)
\#define UERROR_UNBOUNDEDPDF  (0)
\#define UERROR_MULTIMODAL    DEVEL
\#define UERROR_MULTIMODAL_VANISHINGPDF DEVEL

/* variants */
static int UERROR_REGULA = TRUE;
static int UERROR_NEWTON = TRUE;


/* constants */

## \#define UERROR_SAMPLESIZE (100000)
\#define UERROR_SAMPLESIZE (10000)

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

/* Chi-square goodness-of-fit tests some times fail once due to numerical */
/* errors. So we accept more such failure than for other methods.         */
\#define CHI2_FAILURES_TOLERATED (5)

/* prototypes */

\#define set_debug_flag(par) \
   do { \
      if (fullcheck) unur_set_debug((par),~0u); \
      else           unur_set_debug((par),1u); \
   } while (0);

int ninv_error_experiment( UNUR_PAR *par, int samplesize );

int chg_domain_experiment( UNUR_PAR *par, int samplesize );

int ninv_error_gen_experiment( UNUR_GEN *gen, 
    			       double u_resolution, const char *method, int samplesize ); 


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

[new]

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

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

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

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

[new - data missing in distribution object:
   distr = unur_distr_cont_new(); ]

/* cdf */
~( distr );
	--> expected_NULL --> UNUR_ERR_DISTR_REQUIRED

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

[set]

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

~_usenewton( par );
	--> expected_setfailed --> UNUR_ERR_NULL

~_useregula( par );
	--> expected_setfailed --> UNUR_ERR_NULL

~_max_iter( par, 40 );
	--> expected_setfailed --> UNUR_ERR_NULL

~_x_resolution( par, 0.001 );
	--> expected_setfailed --> UNUR_ERR_NULL

~_u_resolution( par, 0.001 );
	--> expected_setfailed --> UNUR_ERR_NULL

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

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


[set - invalid parameter object:
   double fpar[2] = {0.,1.};
   distr = unur_distr_normal(fpar,2);
   par = unur_arou_new(distr); ]

~_usenewton( par );
	--> expected_setfailed --> UNUR_ERR_PAR_INVALID

~_useregula( par );
	--> expected_setfailed --> UNUR_ERR_PAR_INVALID

~_max_iter( par, 40 );
	--> expected_setfailed --> UNUR_ERR_PAR_INVALID

~_x_resolution( par, 0.001 );
	--> expected_setfailed --> UNUR_ERR_PAR_INVALID

~_u_resolution( par, 0.001 );
	--> expected_setfailed --> UNUR_ERR_PAR_INVALID

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

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

unur_par_free(par);


[set - invalid parameters:
   double fpar[2] = {0.,1.};
   distr = unur_distr_normal(fpar,2);
   par = unur_ninv_new(distr); ]

~_max_iter( par, 0 );
	--> expected_setfailed --> UNUR_ERR_PAR_SET

~_x_resolution( par, 1e-30 );
	--> none --> UNUR_ERR_PAR_SET

~_u_resolution( par, 1e-30 );
	--> none --> UNUR_ERR_PAR_SET

unur_par_free(par);


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

# [get]

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

[chg]

[chg - invalid generator object:
   double fpar[2] = {0.,1.};
   distr = unur_distr_normal(fpar,2);
   unur_distr_cont_set_domain(distr,-1.,2.);
   par = unur_tdr_new(distr);
   unur_set_debug(par,0);
   gen = unur_init( par ); <-- ! NULL ]

~_max_iter( gen, 100 );
	--> expected_setfailed --> UNUR_ERR_GEN_INVALID

~_x_resolution( gen, 1.e-10);
	--> expected_setfailed --> UNUR_ERR_GEN_INVALID

~_u_resolution( gen, 1.e-10);
	--> expected_setfailed --> UNUR_ERR_GEN_INVALID

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


[chg - invalid parameters:
   double fpar[2] = {0.,1.};
   distr = unur_distr_normal(fpar,2);
   unur_distr_cont_set_domain(distr,-1.,2.);
   par = unur_ninv_new(distr);
   unur_set_debug(par,0);
   gen = unur_init( par ); <-- ! NULL ]


~_max_iter( gen, 0 );
	--> expected_setfailed --> UNUR_ERR_PAR_SET

~_x_resolution( gen, 1.e-30);
	--> none --> UNUR_ERR_PAR_SET

~_u_resolution( gen, 1.e-30);
	--> none --> UNUR_ERR_PAR_SET

~_truncated( gen, 1., 0. );
	--> expected_setfailed --> UNUR_ERR_DISTR_SET

~_truncated( gen, -2., 0. );
	--> none --> UNUR_ERR_DISTR_SET

~_truncated( gen, 0., 10. );
	--> none --> UNUR_ERR_DISTR_SET


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

[init]

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

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

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

[reinit]

[reinit - does not exist:
   distr = unur_distr_normal(NULL,0);
   par = unur_ninv_new(distr);
   gen = unur_init( par ); <-- ! NULL ]

unur_reinit( gen );
	--> expected_reinit

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

[sample]

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

unur_ninv_eval_approxinvcdf(gen,0.5);
	--> expected_INFINITY --> UNUR_ERR_NULL

[sample - invalid generator object:
   distr = unur_distr_normal(NULL,0);
   par = unur_hinv_new(distr);
   gen = unur_init(par); <-- ! NULL ]

unur_ninv_eval_approxinvcdf(gen,0.5);
	--> expected_INFINITY --> UNUR_ERR_GEN_INVALID

[sample - invalid domain:
   distr = unur_distr_normal(NULL,0);
   par = unur_ninv_new(distr);
   unur_set_debug(par,0);
   gen = unur_init( par ); <-- ! NULL ]

unur_ninv_eval_approxinvcdf(gen,1.5);
	--> expected_INFINITY --> UNUR_ERR_DOMAIN

unur_ninv_eval_approxinvcdf(gen,-0.5);
	--> expected_negINFINITY --> UNUR_ERR_DOMAIN

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

[sample - compare clone:
   UNUR_GEN *clone;
   distr = unur_distr_normal(NULL,0); 
   par = NULL;
   gen = NULL; ]

/* original generator object */
par = unur_ninv_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:
   distr = unur_distr_normal(NULL,0); 
   par = NULL;
   gen = NULL; ]

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

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

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

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


distr = unur_distr_gamma(fpar,2);
unur_distr_cont_set_domain(distr,2.,UNUR_INFINITY);
par = unur_ninv_new(distr);
unur_ninv_set_max_iter(par,10);
unur_ninv_set_start(par,4.,10.);
unur_ninv_set_table(par,100);
unur_ninv_set_usenewton(par);
unur_ninv_set_x_resolution(par,1.E-6);
unur_set_debug(par,1u);
gen = unur_init(par);
	-->compare_sequence_gen_start
	
unur_free(gen); gen = NULL;
unur_distr_free(distr); distr = NULL;
gen = unur_str2gen( "gamma(3.,4.); domain = 2,infinity & \
  method = ninv; max_iter = 10; start = 4., 10.; table = 100; \
  usenewton; x_resolution = 1.E-6; debug = 0x1" );
	-->compare_sequence_gen

unur_free(gen); gen = NULL;
distr = unur_distr_gamma(fpar,2);
unur_distr_cont_set_domain(distr,2.,UNUR_INFINITY);
par = unur_ninv_new(distr);
unur_ninv_set_useregula(par);
unur_set_debug(par,1u);
gen = unur_init(par);
	-->compare_sequence_gen_start
	
unur_free(gen); gen = NULL;
unur_distr_free(distr); distr = NULL;
gen = unur_str2gen( "gamma(3.,4.); domain = (2,inf) & method = ninv; useregula; debug = 0x1" );
	-->compare_sequence_gen


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

[validate]

[validate - generators:]

# default (Newton)
par[0] = unur_ninv_new(@distr@);
unur_ninv_set_usenewton(par);

# no table, starting points (Newton)
par[1] = unur_ninv_new(@distr@);
unur_ninv_set_usenewton(par);
unur_ninv_set_start(par, 0.1, 0.9);

# use small table (Newton)
par[2] = unur_ninv_new(@distr@);
unur_ninv_set_usenewton(par);
unur_ninv_set_table(par,11);

# use large table (Newton)
par[3] = unur_ninv_new(@distr@);
unur_ninv_set_usenewton(par);
unur_ninv_set_table(par,1000);

# default with truncated distribution (Newton)
par[4] = unur_ninv_new(@distr@);
unur_ninv_set_usenewton(par);
unur_ninv_chg_truncated(gen,0.5,0.9);

# use small table with truncated distribution (Newton)
par[5] = unur_ninv_new(@distr@);
unur_ninv_set_usenewton(par);
unur_ninv_set_table(par,11);
unur_ninv_chg_truncated(gen,0.5,0.9);

# use large table with truncated distribution (Newton)
par[6] = unur_ninv_new(@distr@);
unur_ninv_set_usenewton(par);
unur_ninv_set_table(par,1000);
unur_ninv_chg_truncated(gen,0.5,0.9);

# default with changed pdf parameters after setup (Newton)
{ UNUR_DISTR *dg =NULL;
par[7] = unur_ninv_new(@distr@);
unur_ninv_set_usenewton(par);
fpm[0] = 2.;
fpm[1] = 4.;
dg = unur_get_distr(gen);
unur_distr_cont_set_pdfparams(dg,fpm,2);
unur_reinit(gen); }

# use small table with changed pdf parameters after setup (Newton)
{ UNUR_DISTR *dg =NULL;
par[8] = unur_ninv_new(@distr@);
unur_ninv_set_usenewton(par);
unur_ninv_set_table(par,11);
fpm[0] = 2.;
fpm[1] = 4.;
dg = unur_get_distr(gen);
unur_distr_cont_set_pdfparams(dg,fpm,2);
unur_reinit(gen); }

# use large table with changed pdf parameters after setup (Newton)
{ UNUR_DISTR *dg =NULL;
par[9] = unur_ninv_new(@distr@);
unur_ninv_set_usenewton(par);
unur_ninv_set_table(par,1000);
fpm[0] = 2.;
fpm[1] = 4.;
dg = unur_get_distr(gen);
unur_distr_cont_set_pdfparams(dg,fpm,2);
unur_reinit(gen); }

# default (regula falsi)
par[10] = unur_ninv_new(@distr@);
unur_ninv_set_useregula(par);

# no table, starting points (regula falsi)
par[11] = unur_ninv_new(@distr@);
unur_ninv_set_useregula(par);
unur_ninv_set_start(par, 0.1, 0.9);

# use small table (regula falsi)
par[12] = unur_ninv_new(@distr@);
unur_ninv_set_useregula(par);
unur_ninv_set_table(par,11);

# use large table (regula falsi)
par[13] = unur_ninv_new(@distr@);
unur_ninv_set_useregula(par);
unur_ninv_set_table(par,1000);

# default with truncated distribution (regula falsi)
par[14] = unur_ninv_new(@distr@);
unur_ninv_set_useregula(par);
unur_ninv_chg_truncated(gen,0.5,0.9);

# use small table with truncated distribution (regula falsi)
par[15] = unur_ninv_new(@distr@);
unur_ninv_set_useregula(par);
unur_ninv_set_table(par,11);
unur_ninv_chg_truncated(gen,0.5,0.9);

# use large table with truncated distribution (regula falsi)
par[16] = unur_ninv_new(@distr@);
unur_ninv_set_useregula(par);
unur_ninv_set_table(par,1000);
unur_ninv_chg_truncated(gen,0.5,0.9);

# default with changed pdf parameters after setup (regula falsi)
{ UNUR_DISTR *dg =NULL;
par[17] = unur_ninv_new(@distr@);
unur_ninv_set_useregula(par);
fpm[0] = 2.;
fpm[1] = 4.;
dg = unur_get_distr(gen);
unur_distr_cont_set_pdfparams(dg,fpm,2);
unur_reinit(gen); }

# use small table with changed pdf parameters after setup (regula falsi)
{ UNUR_DISTR *dg =NULL;
par[18] = unur_ninv_new(@distr@);
unur_ninv_set_useregula(par);
unur_ninv_set_table(par,11);
fpm[0] = 2.;
fpm[1] = 4.;
dg = unur_get_distr(gen);
unur_distr_cont_set_pdfparams(dg,fpm,2);
unur_reinit(gen); }

# use large table with changed pdf parameters after setup (regula falsi)
{ UNUR_DISTR *dg =NULL;
par[19] = unur_ninv_new(@distr@);
unur_ninv_set_useregula(par);
unur_ninv_set_table(par,1000);
fpm[0] = 2.;
fpm[1] = 4.;
dg = unur_get_distr(gen);
unur_distr_cont_set_pdfparams(dg,fpm,2);
unur_reinit(gen); }


[validate - distributions:]

# Beta distributions
fpm[0] = 1.;
fpm[1] = 2.;
distr[0] = unur_distr_beta(fpm,2);

fpm[0] = 1.;
fpm[1] = 5.;
distr[1] = unur_distr_beta(fpm,2);

fpm[0] = 1.;
fpm[1] = 100.;
distr[2] = unur_distr_beta(fpm,2);

fpm[0] = 3.;
fpm[1] = 4.;
distr[3] = unur_distr_beta(fpm,2);

fpm[0] = 5.;
fpm[1] = 100.;
distr[4] = unur_distr_beta(fpm,2);

fpm[0] = 500.;
fpm[1] = 300.;
distr[5] = unur_distr_beta(fpm,2);

fpm[0] = 5.;
fpm[1] = 10.;
fpm[2] = -3.;
fpm[3] = 15.;
distr[6] = unur_distr_beta(fpm,4);

fpm[0] = 0.5;
fpm[1] = 3.;
distr[28] = unur_distr_beta(fpm,2);

fpm[0] = 5.;
fpm[1] = 0.3;
distr[29] = unur_distr_beta(fpm,2);

fpm[0] = 0.5;
fpm[1] = 0.4;
distr[30] = unur_distr_beta(fpm,2);

# Cauchy distributions
distr[7] = unur_distr_cauchy(NULL,0);

fpm[0] = 1.;
fpm[1] = 20.;
distr[8] = unur_distr_cauchy(fpm,2);

# Exponential distributions
distr[24] = unur_distr_exponential(NULL,0);

fpm[0] = 30.;
fpm[1] = -5.;
distr[25] = unur_distr_exponential(fpm,2);

# Gamma distributions
fpm[0] = 1.;
distr[9] = unur_distr_gamma(fpm,1);

fpm[0] = 2.;
distr[10] = unur_distr_gamma(fpm,1);

fpm[0] = 3.;
distr[11] = unur_distr_gamma(fpm,1);

fpm[0] = 10.;
distr[12] = unur_distr_gamma(fpm,1);

fpm[0] = 1000.;
distr[13] = unur_distr_gamma(fpm,1);

fpm[0] = 5.;
fpm[1] = 1000.;
distr[14] = unur_distr_gamma(fpm,2);

fpm[0] = 5.;
fpm[1] = 1.e-5;
distr[15] = unur_distr_gamma(fpm,2);

fpm[0] = 5.;
fpm[1] = 10.;
fpm[2] = 1000;
distr[16] = unur_distr_gamma(fpm,3);

fpm[0] = 0.5;
distr[31] = unur_distr_gamma(fpm,1);

fpm[0] = 0.2;
distr[32] = unur_distr_gamma(fpm,1);

# Laplace distributions
distr[26] = unur_distr_laplace(NULL,0);

fpm[0] = -10.;
fpm[1] = 100.;
distr[27] = unur_distr_laplace(fpm,2);

# Normal distributions
distr[17] = unur_distr_normal(NULL,0);

fpm[0] = 1.;
fpm[1] = 1.e-5;
distr[18] = unur_distr_normal(fpm,2);

fpm[0] = 0.;
fpm[1] = 1.e+5;
distr[19] = unur_distr_normal(fpm,2);

# Uniform distributions
distr[20] = unur_distr_uniform(NULL,0);

fpm[0] = 1.;
fpm[1] = 20.;
distr[21] = unur_distr_uniform(fpm,2);

# truncated distributions
distr[22] = unur_distr_cauchy(NULL,0);
unur_distr_cont_set_domain(distr[22],0.1,1.);
unur_distr_cont_upd_mode(distr[22]);
unur_distr_cont_upd_pdfarea(distr[22]);

# domain exceeds support of pdf
fpm[0] = 3.;
fpm[1] = 4.;
distr[23] = unur_distr_beta(fpm,2);
unur_distr_cont_set_domain(distr[23],-2.,5.);


# number of distributions: 33


[validate - test chi2:]

#  + ... pass test
#  0 ... fail to initialize generator
#  - ... fail test
#  . ... do not run test
#  # ... comment
#
# generators:
#  [0]  ... (Newton) default (no table) (but with increased number of max iterations)
#  [1]  ... (Newton) no table, starting points
#  [2]  ... (Newton) use small table
#  [3]  ... (Newton) use large table
#  [4]  ... (Newton) default with truncated distribution
#  [5]  ... (Newton) use small table with truncated distribution
#  [6]  ... (Newton) use large table with truncated distribution
#  [7]  ... (Newton) default with changed pdf parameters after setup
#  [8]  ... (Newton) use small table with changed pdf parameters after setup
#  [9]  ... (Newton) use large table with changed pdf parameters after setup
#
#  [10] ... (regula) default (no table)
#  [11] ... (regula) no table, starting points
#  [12] ... (regula) use small table
#  [13] ... (regula) use large table
#  [14] ... (regula) default with truncated distribution
#  [15] ... (regula) use small table with truncated distribution
#  [16] ... (regula) use large table with truncated distribution
#  [17] ... (regula) default with changed pdf parameters after setup
#  [18] ... (regula) use small table with changed pdf parameters after setup
#  [19] ... (regula) use large table with changed pdf parameters after setup
#
#	                                1  1  1  1  1  1  1  1  1  1
#	0  1  2  3  4  5  6  7  8  9	0  1  2  3  4  5  6  7  8  9	# distribution
#------------------------------------------------------------------------------------------
x <0>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# beta (1, 2)
  <1>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# beta (1, 5)
x <2>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# beta (1, 100)
  <3>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# beta (3, 4)
  <4>  x+ x+ x+  + x+ x+  +  +  +  +   x+ x+ x+  + x+ x+  +  +  +  +	# beta (5, 100)
  <5>  x+ x+ x+  + x+ x+  +  +  +  +   x+ x+ x+  + x+ x+  +  +  +  +	# beta (500, 300)
  <6>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# beta (5, 10, -3, 15)
 <28>  x+ x+ x+  + x+ x+  +  +  +  +   x+ x+ x+  + x+ x+  +  +  +  +	# beta (0.5, 3)
 <29>  x+ x+ x.  + x+ x+  +  +  +  +   x+ x+ x+  + x+ x+  +  +  +  +	# beta (5, 0.3)
 <30>  x+ x+ x.  + x+ x+  +  +  +  +   x+ x+ x+  + x+ x+  +  +  +  +	# beta (0.5, 0.4)
  <7>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# cauchy ()
  <8> 	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# cauchy (1, 20)
 <24>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# exponential ()
 <25>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# exponential (30, -5)
x <9>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# gamma (1)
 <10>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# gamma (2)
 <11>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# gamma (3)
 <12>	+  .  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# gamma (10)
x<13>	+  .  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# gamma (1000)
 <14>	+  .  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# gamma (5, 1000, 0)
x<15>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# gamma (5, 1e-05, 0)
x<16>	+  +  +  +  +  +  +  +  +  +	+  .  +  +  +  +  +  +  +  +	# gamma (5, 10, 1000)
 <31>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# gamma (0.5)
 <32>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# gamma (0.2)
 <26>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# laplace ()
 <27>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# laplace (-10, 100)
 <17>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# normal ()
x<18>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# normal (1, 1e-05)
 <19>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# normal (1, 1e+05)
 <20>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# uniform ()
 <21>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# uniform (1, 20)
 <22>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# cauchy () - truncated
 <23>	+  +  +  +  +  +  +  +  +  +	+  +  +  +  +  +  +  +  +  +	# beta () - domain superset of support

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

[special]

[special - decl:]

  int samplesize = UERROR_SAMPLESIZE;
  int errorsum = 0;
#  double fpar[4];
#  double cpoints[10];     

  UNUR_DISTR *distr;
  UNUR_PAR   *par;

[special - start:]

  /* test for maximal u-error */
  printf("\n[test maximal u-error]"); 
  fprintf(TESTLOG,"\n* Test maximal u-error *\n"); 

## ----------------------------------------------------
if (UERROR_STANDARDDIST) { /* --------------------------- */

  printf("\nStandard distributions:\n"); 
  fprintf(TESTLOG,"\n--- Standard distributions --- \n\n"); 

  ## --- Normal ---
if (ALL) {
  printf(" normal");
  distr = unur_distr_normal(NULL,0);
  par = unur_ninv_new(distr);
  errorsum += ninv_error_experiment(par,samplesize);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}
	
} /* endif (UERROR_STANDARDDIST) */
## ----------------------------------------------------

  /* test finished */
  FAILED = (errorsum < 2) ? 0 : 1;

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

[verbatim]

#############################################################################
#
# routines for special tests
#
#############################################################################


/*****************************************************************************/
/* run unur_test_u_error for a particular generator object and print result  */

int
ninv_error_gen_experiment( UNUR_GEN *gen,       /* generator object */
			   double u_resolution, /* maximal tolerated u-error */
			   const char *method,  /* chosen method */
			   int samplesize )     /* sample size for error experiment */
     /* returns 0 if maxerror < u_resolution, errorcode otherwise */
{   
  int i, nfpar;
  const double *fpar;     
  const UNUR_DISTR *distr = unur_get_distr(gen);
  const char *genid = unur_get_genid(gen);
  double score;

  /* print data about distribution */
  fprintf(TESTLOG,"%s: %s distribution",genid,unur_distr_get_name(distr));
  nfpar = unur_distr_cont_get_pdfparams(distr,&fpar);
  if (nfpar) { 
     fprintf(TESTLOG," with parameters ");
     for(i=0;i<nfpar;i++) fprintf(TESTLOG," | %g",fpar[i]);
     fprintf(TESTLOG," |");
  }
  fprintf(TESTLOG,":\n");

  /* print chosen parameter for method NINV and for experiment */
  fprintf(TESTLOG,"%s:   setting: method = %s, u-error <= %g, samplesize = %d\n",
                  genid,method,u_resolution,samplesize);

  /* run test */
  score = run_validate_u_error( TESTLOG, gen, distr, u_resolution, samplesize );

  /* return score */
  return score;

} /* end of ninv_error_gen_experiment() */

/*****************************************************************************/
/* run experiment for a particular distribution object                       */

int
ninv_error_experiment( UNUR_PAR *par,     /* parameter object */
		       int samplesize )   /* samplesize for error experiment */
     /* returns 0 if maxerror < u_resolution, errorcode otherwise */
{ 
  UNUR_PAR *par_clone;  /* working copy of parameter object */
  UNUR_GEN *gen;        /* generator object */

  double u_resolution = 1.e-8;  /* maximal tolerate u-error */
  int errorsum = 0;

  int variant;
  char *method;

  /* check for invalid NULL pointer */
  if (par==NULL) {
     printf(" NULL! ");
     return 1000;
  }

  /* test all variants */
  for (variant=0; variant<3; ++variant) {
    /* variant==0 --> use regula falsi */
    /* variant==1 --> use Newton */
    /* variant==2 --> use bisection */

    switch (variant) {
    case 0: /* run regula */
      method = "regula";
      if (UERROR_REGULA) printf("<regula falsi>");
      else continue;
      break;
    case 1: /* run Newton */
      method = "newton";
      if (UERROR_NEWTON) printf("<newton>");
      else continue;
      break;
    case 2: /* run bisection method */
      method = "bisect";
      if (UERROR_NEWTON) printf("<bisect>");
      else continue;
      break;
    default:
      continue;
    }

    for ( u_resolution = 1.e-6; u_resolution > 1.e-10; u_resolution *= 0.01 ) {
      
      /* make a working copy */
      par_clone = _unur_par_clone(par);
      
      /* set variant */
      switch (variant) {
      case 0: unur_ninv_set_useregula(par_clone); break;
      case 1: unur_ninv_set_usenewton(par_clone); break;
      case 2: unur_ninv_set_usebisect(par_clone); break;
      }

      /* create generator object */
      unur_ninv_set_x_resolution(par_clone,-1.);
      unur_ninv_set_u_resolution(par_clone,u_resolution);
      set_debug_flag(par_clone);
      gen = unur_init(par_clone);
      
      /* run test */
      errorsum += ninv_error_gen_experiment(gen, u_resolution, method, samplesize);
      fprintf(TESTLOG,"\n");
      
      /* clear memory */
      unur_free(gen);
    }

  }

  unur_par_free(par);

  return errorsum;
} /* end of ninv_error_experiment() */

/*****************************************************************************/

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