/*
	file automatically generated by make_test_files.pl
	Fri Jul  3 11:37:50 2026
*/

/*****************************************************************************
 *                                                                           *
 *          UNU.RAN -- Universal Non-Uniform Random number generator         *
 *                                                                           *
 *****************************************************************************/
    
/**
 ** Tests for PINV
 **/
    
/*---------------------------------------------------------------------------*/
#include "testunuran.h"

#ifdef UNUR_URNG_DEFAULT_RNGSTREAM
#include <RngStream.h>
#endif
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/* global variables                                                          */

static FILE *TESTLOG;               /* test log file                         */
static FILE *UNURANLOG;             /* unuran log file                       */

static int test_ok = TRUE;          /* all tests ok (boolean)                */
static int fullcheck = FALSE;       /* whether all checks are performed      */ 

static TIMER watch;                 /* stop watch                            */

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

void run_verify_generator( FILE *LOG, int line, UNUR_PAR *par );

int unur_pinv_set_verify( UNUR_PAR *par, int verify);


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

void test_new (void);
void test_set (void);
void test_get (void);
void test_chg (void);
void test_init (void);
void test_reinit (void);
void test_sample (void);
void test_validate (void);
void test_special(void);

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



/* header files */
#include <methods/x_gen_source.h>

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

#define DEVEL FALSE    /* whether to run tests in development mode */
#define ALL   TRUE

/* Remark:
   Setting ALL to FALSE is useful if a only a single validation test
   should be run. Thus the "if(ALL)" condition for that particular test
   has to be replaced by "if(TRUE)".
*/

#define UERROR_STANDARDDIST  TRUE
#define UERROR_QUASIPDF      TRUE
#define UERROR_VANISHINGPDF  TRUE
#define UERROR_TRUNCATED     TRUE
#define UERROR_UNBOUNDEDPDF  TRUE
#define UERROR_MULTIMODAL    TRUE
#define UERROR_MULTIMODAL_VANISHINGPDF TRUE

/* orders */
static int UERROR_ORDER_MIN  =  3;
static int UERROR_ORDER_MAX  = 17;
static int UERROR_ORDER_STEP =  1;

/* smoothness */
static int SMOOTHNESS_MAX = 2;

/* u-resolutions */
static double UERROR_URESOLUTION_MAX = 1.e-8;
static double UERROR_URESOLUTION_MIN = 0.99e-13;
static double UERROR_URESOLUTION_STEP = 0.1;

/* we run all tests only in 'fullcheck' mode */
#define set_uerror_tests() \
  if (!fullcheck) { \
     /* UERROR_ORDER_STEP =  3; */ \
     UERROR_URESOLUTION_MAX = 1.e-8; \
     UERROR_URESOLUTION_MIN = 0.99e-12; \
     UERROR_URESOLUTION_STEP = 0.01; \
  }
/* see also SKIPORDER in routine pinv_error_experiment() below */

/* sample size */
static const int UERROR_SAMPLESIZE = 100000;


/* -- constants -- */

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

/* #define SEED   (298346) */

#ifndef M_PI
#define M_PI       3.14159265358979323846264338328      /* pi */
#endif


/* -- macros -- */

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


/* -- prototypes -- */

int pinv_error_experiment( UNUR_PAR *par, int samplesize, int UERROR_PDF, int UERROR_CDF);
int pinv_error_gen_experiment( UNUR_GEN *gen, 
                               double u_resolution, int order, int samplesize ); 

double neg_exponential_cdf( double x, const UNUR_DISTR *distr );
double neg_exponential_pdf( double x, const UNUR_DISTR *distr );

double neg_exponential_1_cdf( double x, const UNUR_DISTR *distr );
double neg_exponential_1_pdf( double x, const UNUR_DISTR *distr );

double sin_2_cdf( double x, const UNUR_DISTR *distr );
double sin_2_pdf( double x, const UNUR_DISTR *distr );

double sin_10_cdf( double x, const UNUR_DISTR *distr );
double sin_10_pdf( double x, const UNUR_DISTR *distr );







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

#ifndef CHI2_FAILURES_TOLERATED
#  define CHI2_FAILURES_TOLERATED DEFAULT_CHI2_FAILURES_TOLERATED
#endif

/*---------------------------------------------------------------------------*/
/* [verbatim] */





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

int
pinv_error_gen_experiment( UNUR_GEN *gen,       /* generator object */
			   double u_resolution, /* maximal tolerated u-error */
			   int order,           /* order of polynomial */
			   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;
  const char *genid;
  int score;

  /* check for invalid NULL pointer */
  if (gen==NULL) {
    fprintf(TESTLOG,"\n--setup failed !! --\n");
    printf("(!!+)"); fflush(stdout);
    return 100;
  }

  /* get data about generator object */
  distr = unur_get_distr(gen);
  genid = unur_get_genid(gen);

  /* 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 PINV and for experiment */
  fprintf(TESTLOG,"%s:   setting: order = %d, u-error <= %g, samplesize = %d\n",
	  genid,order,u_resolution,samplesize);
  /* number of intervals */
  fprintf(TESTLOG,"%s:   #intervals = %d", genid, unur_pinv_get_n_intervals(gen));
  /* number of function calls */
  if (get_counter_pdf() > 0) {
    fprintf(TESTLOG,"\t#PDF calls = %d\t(per interval = %d)",
	    get_counter_pdf(), 
	    ( (unur_pinv_get_n_intervals(gen)!=0) ? 
	      get_counter_pdf() / unur_pinv_get_n_intervals(gen) : -1 ) );
  }
  if (get_counter_logpdf() > 0) {
    fprintf(TESTLOG,"\t#logPDF calls = %d\t(per interval = %d)",
	    get_counter_logpdf(), 
	    ( (unur_pinv_get_n_intervals(gen)!=0) ? 
	      get_counter_logpdf() / unur_pinv_get_n_intervals(gen) : -1 ) );
  }
  if (get_counter_cdf() > 0) {
    fprintf(TESTLOG,"\t#CDF calls = %d\t(per interval = %d)",
	    get_counter_cdf(), 
	    ( (unur_pinv_get_n_intervals(gen)!=0) ? 
	      get_counter_cdf() / unur_pinv_get_n_intervals(gen) : -1 ) );
  }
  fprintf(TESTLOG,"\n");

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

  /* return score */
  fprintf(TESTLOG,"\n"); fflush(TESTLOG);
  return score;

} /* end of pinv_error_gen_experiment() */

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

int
pinv_error_experiment( UNUR_PAR *par,     /* parameter object */
		       int samplesize,    /* samplesize for error experiment */
		       int UERROR_PDF,   /* if TRUE, check variant usePDF */
		       int UERROR_CDF)   /* if TRUE, check variant useCDF */
     /* returns 0 if maxerror < u_resolution, errorcode otherwise */
{ 
  UNUR_PAR *par_clone;  /* working copy of parameter object */
  UNUR_GEN *gen;        /* generator object */
  
  int order = 3;
  int smooth = 0;
  double u_resolution = 1.e-8;  /* maximal tolerated u-error */
  int errorsum = 0;

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

  /* -- loop smoothness -- */
  for (smooth=0; smooth <= SMOOTHNESS_MAX; smooth++) {
   
    /* -- loop variante -- */
    for (variant=0; variant <= 1; ++variant) {
      /* variant==0 --> use PDF */
      /* variant==1 --> use CDF */
      
      switch (variant) {
	
      case 0: /* run variant PDF+Lobatto */
	if (UERROR_PDF) printf("<PDF:%d>",smooth);
	else continue;
	break;
	
      case 1: /* run variant CDF */
	if (UERROR_CDF) printf("<CDF:%d>",smooth); 
	else continue;
	break;
	
      default:
	continue;
      }
      
      /* -- loop order -- */
      for ( order=UERROR_ORDER_MIN; order<=UERROR_ORDER_MAX; order+=UERROR_ORDER_STEP) {   
	
	/* prevent warning from invalid order */
	if (smooth==1 && order % 2 != 1) continue;
	if (smooth==2 && order % 3 != 2) continue;

	/* SKIPORDER:
	 * when we do not run in fullcheck mode, we skip some orders. */
	if (!fullcheck) {
	  switch (smooth) {
	  case 0:
	    if (! (order==3 || order==5 || order==8 || order==12 || order==17) )
	      continue;
	    break;
	  case 1:
	    if (order==7 || order==11 || order==15)
	      continue;
	    break;
	  case 2:
	    if (order == 14) 
	      continue;
	    break;
	  }
	}

	/* -- loop u-resolution -- */
	for ( u_resolution = UERROR_URESOLUTION_MAX; 
	      u_resolution > UERROR_URESOLUTION_MIN; u_resolution *= UERROR_URESOLUTION_STEP ) {

	  if (!fullcheck) {
	    if (smooth==2 && u_resolution < 0.99e-10)
	      /* setup fails for some truncated distributions. */
	      /* so we skip it when not run in fullcheck mode. */
	      continue;
	  }
	  
	  /* make a working copy */
	  par_clone = _unur_par_clone(par);
	  
	  /* set variant */
	  switch (variant) {
	  case 0: unur_pinv_set_usepdf(par_clone); break;
	  case 1: unur_pinv_set_usecdf(par_clone); break;
	  }
	  
	  /* maximum number of subintervals */
	  /**/   if (order <= 3 && u_resolution < 1.e-12) {
	    unur_pinv_set_max_intervals(par_clone,100000);
	  } else if (u_resolution < 1.e13) {
	    unur_pinv_set_max_intervals(par_clone,100000);
	  }
	  
	  /* start counter for PDF calls */
	  start_counter_fcalls(par_clone);
	  
	  /* create generator object */
	  unur_pinv_set_order(par_clone,order);
	  unur_pinv_set_smoothness(par_clone,smooth);
	  unur_pinv_set_u_resolution(par_clone,u_resolution);
	  set_debug_flag(par_clone);
	  gen = unur_init(par_clone);
	  
	  /* run test */
	  errorsum += pinv_error_gen_experiment(gen, u_resolution, order, samplesize);
	  
	  /* clear memory */
	  unur_free(gen);
	  stop_counter_fcalls();
	  
	} /* -- end loop u-resolution -- */
	
      } /* -- end end loop order -- */
      
    } /* -- end loop variant */
    
  } /* -- end loop smoothness -- */

  unur_par_free(par);
  
  return errorsum;
} /* end of pinv_error_experiment() */

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


/*---------------------------------------------------------------------------*/
/* "negative" exponential distribution                                       */
/*                                                                           */
/*          /  exp(x) if x <= 0                                              */
/*  f(x) = <                                                                 */
/*          \  0      otherwise                                              */
/*                                                                           */
double neg_exponential_pdf( double x, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{
  if (x>0.)
    return 0.;
  else
    return (exp(x));
}

double neg_exponential_cdf( double x, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{
  if (x>0.)
    return 1.;
  else
    return (exp(x));
}

/*---------------------------------------------------------------------------*/
/* "shifted negative" exponential distribution                               */
/*                                                                           */
/*          /  exp(x-s) if x <= s                                            */
/*  f(x) = <                                                                 */
/*          \  0      otherwise                                              */
/*                                                                           */

#define shift (-1.)

double neg_exponential_1_pdf( double x, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{
  x = x-shift;

  if (x>0.)
    return 0.;
  else
    return (exp(x));
}

double neg_exponential_1_cdf( double x, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{
  x = x-shift;

  if (x>=0.)
    return 1.;
  else
    return (exp(x));
}

#undef shift


/*---------------------------------------------------------------------------*/
/*                                                                           */
/*          /  0.05 + 0.45*(1 +sin(2 Pi x))  if |x| <= 1                     */
/*  f(x) = <                                                                 */
/*          \  0        otherwise                                            */
/*                                                                           */
double sin_2_pdf( double x, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{
  if (fabs(x) > 1.)
    return 0.;
  else
    return (0.05 + 0.45*(1.+sin(2.*M_PI*x)));
} /* end of sin_pdf() */

/* The CDF of our distribution:                                  */
double sin_2_cdf( double x, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{
  if (x < -1.)
    return 0.;
  else if(x<=1.)
    return (0.05*(x+1) + 0.9*(1.+2.*M_PI*(1+x)-cos((2.*M_PI)*x))/(4.*M_PI));
  else return 1.;
} /* end of sin_cdf() */


/*---------------------------------------------------------------------------*/
/*                                                                           */
/*          /  0.05 + 0.45*(1 +sin(2 Pi x))  if |x| <= 5                     */
/*  f(x) = <                                                                 */
/*          \  0        otherwise                                            */
/*                                                                           */
double sin_10_pdf( double x, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{
  if (fabs(x) > 5.)
    return 0.;
  else
    return (0.05 + 0.45*(1.+sin(2.*M_PI*x)));
} /* end of sin_pdf() */

/* The CDF of our distribution:                                  */
double sin_10_cdf( double x, const UNUR_DISTR *distr ATTRIBUTE__UNUSED)
{
  if (x < -5.)
    return 0.;
  else if(x<=5.)
    return ((x/10.+0.5) + 0.09/(2*M_PI)*(cos(10*M_PI)-cos(2*M_PI*x)));
  else return 1.;
} /* end of sin_cdf() */

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* [new] */

void test_new (void)
{
        int n_tests_failed;          /* number of failed tests */

	/* start test */
	printf("[new "); fflush(stdout);
	fprintf(TESTLOG,"\n[new]\n");

	/* reset counter */
	n_tests_failed = 0;

	/* set stop watch */
	stopwatch_lap(&watch);
  
{ /* invalid NULL ptr */
UNUR_DISTR *distr = NULL;
   distr = NULL; 


unur_reset_errno();
n_tests_failed += (check_expected_NULL(TESTLOG,111,(unur_pinv_new( distr )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,111,UNUR_ERR_NULL)==UNUR_SUCCESS)?0:1;
unur_distr_free(distr);
}

{ /* invalid distribution type */
UNUR_DISTR *distr = NULL;
   distr = unur_distr_discr_new(); 


unur_reset_errno();
n_tests_failed += (check_expected_NULL(TESTLOG,117,(unur_pinv_new( distr )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,117,UNUR_ERR_DISTR_INVALID)==UNUR_SUCCESS)?0:1;
unur_distr_free(distr);
}

{ /* data missing in distribution object */
UNUR_DISTR *distr = NULL;
   distr = unur_distr_cont_new(); 


unur_reset_errno();
/* pdf */
n_tests_failed += (check_expected_NULL(TESTLOG,124,(unur_pinv_new( distr )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,124,UNUR_ERR_DISTR_REQUIRED)==UNUR_SUCCESS)?0:1;
unur_distr_free(distr);
}


	/* timing */
	stopwatch_print(TESTLOG,"\n<*>time = %.3f ms\n\n", stopwatch_lap(&watch));

	/* test finished */
	test_ok &= (n_tests_failed) ? 0 : 1;
	(n_tests_failed) ? printf(" ==> failed] ") : printf(" ==> ok] ");

} /* end of test_new() */

/*---------------------------------------------------------------------------*/
/* [set] */

void test_set (void)
{
        int n_tests_failed;          /* number of failed tests */

	/* start test */
	printf("[set "); fflush(stdout);
	fprintf(TESTLOG,"\n[set]\n");

	/* reset counter */
	n_tests_failed = 0;

	/* set stop watch */
	stopwatch_lap(&watch);
  
{ /* invalid NULL ptr */
UNUR_PAR   *par = NULL;
   /* double stp[] = {1.,2.,3.}; */
   par = NULL; 


unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,135,(unur_pinv_set_order( par, 3 )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,135,UNUR_ERR_NULL)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,138,(unur_pinv_set_smoothness( par, 1 )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,138,UNUR_ERR_NULL)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,141,(unur_pinv_set_u_resolution( par, 1.e-8 )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,141,UNUR_ERR_NULL)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,144,(unur_pinv_set_use_upoints( par, TRUE )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,144,UNUR_ERR_NULL)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,147,(unur_pinv_set_usepdf( par )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,147,UNUR_ERR_NULL)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,150,(unur_pinv_set_usecdf( par )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,150,UNUR_ERR_NULL)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,153,(unur_pinv_set_boundary(par,1.,3.)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,153,UNUR_ERR_NULL)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,156,(unur_pinv_set_searchboundary(par, TRUE, TRUE )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,156,UNUR_ERR_NULL)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,159,(unur_pinv_set_max_intervals(par,1000)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,159,UNUR_ERR_NULL)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,162,(unur_pinv_set_extra_testpoints(par,10)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,162,UNUR_ERR_NULL)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,165,(unur_pinv_set_keepcdf(par,TRUE)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,165,UNUR_ERR_NULL)==UNUR_SUCCESS)?0:1;
}

{ /* invalid parameter object */
UNUR_DISTR *distr = NULL;
UNUR_PAR   *par = NULL;
   /* double stp[] = {1.,2.,3.}; */
   distr = unur_distr_normal(NULL,0);
   par = unur_arou_new(distr); 


unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,174,(unur_pinv_set_order( par, 3 )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,174,UNUR_ERR_PAR_INVALID)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,177,(unur_pinv_set_smoothness( par, 1 )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,177,UNUR_ERR_PAR_INVALID)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,180,(unur_pinv_set_u_resolution( par, 1.e-8 )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,180,UNUR_ERR_PAR_INVALID)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,183,(unur_pinv_set_use_upoints( par, TRUE )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,183,UNUR_ERR_PAR_INVALID)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,186,(unur_pinv_set_usepdf( par )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,186,UNUR_ERR_PAR_INVALID)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,189,(unur_pinv_set_usecdf( par )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,189,UNUR_ERR_PAR_INVALID)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,192,(unur_pinv_set_boundary(par,1.,3.)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,192,UNUR_ERR_PAR_INVALID)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,195,(unur_pinv_set_searchboundary(par, TRUE, TRUE )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,195,UNUR_ERR_PAR_INVALID)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,198,(unur_pinv_set_max_intervals(par,1000)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,198,UNUR_ERR_PAR_INVALID)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,201,(unur_pinv_set_extra_testpoints(par,10)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,201,UNUR_ERR_PAR_INVALID)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,204,(unur_pinv_set_keepcdf(par,TRUE)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,204,UNUR_ERR_PAR_INVALID)==UNUR_SUCCESS)?0:1;
unur_par_free(par);
unur_distr_free(distr);
}

{ /* invalid parameters */
UNUR_DISTR *distr = NULL;
UNUR_PAR   *par = NULL;
   distr = unur_distr_normal(NULL,0);
   par = unur_pinv_new(distr); 


unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,214,(unur_pinv_set_order( par, 30 )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,214,UNUR_ERR_PAR_SET)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,217,(unur_pinv_set_order( par, 1 )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,217,UNUR_ERR_PAR_SET)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,220,(unur_pinv_set_smoothness( par, 4 )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,220,UNUR_ERR_PAR_SET)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,223,(unur_pinv_set_boundary(par,1.,-3.)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,223,UNUR_ERR_PAR_SET)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,226,(unur_pinv_set_boundary(par,1.,UNUR_INFINITY)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,226,UNUR_ERR_PAR_SET)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,229,(unur_pinv_set_max_intervals(par,1)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,229,UNUR_ERR_PAR_SET)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,232,(unur_pinv_set_max_intervals(par,10000000)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,232,UNUR_ERR_PAR_SET)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,235,(unur_pinv_set_extra_testpoints(par,-1)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,235,UNUR_ERR_PAR_SET)==UNUR_SUCCESS)?0:1;
unur_par_free(par);
unur_distr_free(distr);
}

{ /* invalid parameters */
UNUR_DISTR *distr = NULL;
   UNUR_PAR *par;    
   UNUR_GEN *gen;    
   distr = unur_distr_normal(NULL,0); 


unur_reset_errno();
par = unur_pinv_new(distr);
unur_pinv_set_order( par, 4 );
unur_pinv_set_smoothness( par, 1 );
gen = unur_init(par);
n_tests_failed += (check_errorcode(TESTLOG,249,UNUR_ERR_GENERIC)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
unur_free(gen);
par = unur_pinv_new(distr);
unur_pinv_set_order( par, 4 );
unur_pinv_set_smoothness( par, 2 );
gen = unur_init(par);
n_tests_failed += (check_errorcode(TESTLOG,256,UNUR_ERR_GENERIC)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
unur_free(gen);
par = unur_pinv_new(distr);
unur_pinv_set_order( par, 6 );
unur_pinv_set_smoothness( par, 2 );
gen = unur_init(par);
n_tests_failed += (check_errorcode(TESTLOG,263,UNUR_ERR_GENERIC)==UNUR_SUCCESS)?0:1;
unur_free(gen);
unur_distr_free(distr);
}

{ /* missing CDF */
UNUR_DISTR *distr = NULL;
UNUR_PAR   *par = NULL;
   distr = unur_distr_cont_new();
   unur_distr_cont_set_pdf(distr, neg_exponential_pdf);
   par = unur_pinv_new(distr); 


unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,274,(unur_pinv_set_usecdf( par )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,274,UNUR_ERR_PAR_SET)==UNUR_SUCCESS)?0:1;
unur_par_free(par);
unur_distr_free(distr);
}

{ /* missing PDF */
UNUR_DISTR *distr = NULL;
UNUR_PAR   *par = NULL;
   distr = unur_distr_cont_new();
   unur_distr_cont_set_cdf(distr, neg_exponential_cdf);
   par = unur_pinv_new(distr); 


unur_reset_errno();
n_tests_failed += (check_expected_setfailed(TESTLOG,285,(unur_pinv_set_usepdf( par )))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,285,UNUR_ERR_PAR_SET)==UNUR_SUCCESS)?0:1;
unur_par_free(par);
unur_distr_free(distr);
}

{ /* missing PDF */
UNUR_DISTR *distr = NULL;
   UNUR_PAR *par;    
   UNUR_GEN *gen;    
   distr = unur_distr_cont_new();
   unur_distr_cont_set_cdf(distr, neg_exponential_cdf); 


unur_reset_errno();
par = unur_pinv_new(distr);
unur_pinv_set_usecdf( par );
unur_pinv_set_smoothness( par, 1 );
gen = unur_init(par);
n_tests_failed += (check_errorcode(TESTLOG,300,UNUR_ERR_DISTR_REQUIRED)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
unur_free(gen);
par = unur_pinv_new(distr);
unur_pinv_set_usecdf( par );
unur_pinv_set_smoothness( par, 2 );
gen = unur_init(par);
n_tests_failed += (check_errorcode(TESTLOG,307,UNUR_ERR_DISTR_REQUIRED)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
unur_free(gen);
unur_distr_cont_set_pdf(distr, neg_exponential_pdf);
par = unur_pinv_new(distr);
unur_pinv_set_usecdf( par );
unur_pinv_set_smoothness( par, 2 );
gen = unur_init(par);
n_tests_failed += (check_errorcode(TESTLOG,315,UNUR_ERR_DISTR_REQUIRED)==UNUR_SUCCESS)?0:1;
unur_free(gen);
unur_distr_free(distr);
}


	/* timing */
	stopwatch_print(TESTLOG,"\n<*>time = %.3f ms\n\n", stopwatch_lap(&watch));

	/* test finished */
	test_ok &= (n_tests_failed) ? 0 : 1;
	(n_tests_failed) ? printf(" ==> failed] ") : printf(" ==> ok] ");

} /* end of test_set() */

/*---------------------------------------------------------------------------*/
/* [get] */

void test_get (void)
{
        int n_tests_failed;          /* number of failed tests */

	/* start test */
	printf("[get "); fflush(stdout);
	fprintf(TESTLOG,"\n[get]\n");

	/* reset counter */
	n_tests_failed = 0;

	/* set stop watch */
	stopwatch_lap(&watch);
  
{ /* invalid generator object */
UNUR_DISTR *distr = NULL;
UNUR_PAR   *par = NULL;
UNUR_GEN   *gen = NULL;
   distr = unur_distr_normal(NULL,0);
   par = unur_srou_new(distr);
   gen = unur_init(par); 
abort_if_NULL(TESTLOG, 326,    gen );


unur_reset_errno();
n_tests_failed += (check_expected_zero(TESTLOG,330,(unur_pinv_get_n_intervals(gen)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,330,UNUR_ERR_GEN_INVALID)==UNUR_SUCCESS)?0:1;
unur_distr_free(distr);
unur_free(gen);
}


	/* timing */
	stopwatch_print(TESTLOG,"\n<*>time = %.3f ms\n\n", stopwatch_lap(&watch));

	/* test finished */
	test_ok &= (n_tests_failed) ? 0 : 1;
	(n_tests_failed) ? printf(" ==> failed] ") : printf(" ==> ok] ");

} /* end of test_get() */

/*---------------------------------------------------------------------------*/
/* [sample] */

void test_sample (void)
{
        int n_tests_failed;          /* number of failed tests */

	/* start test */
	printf("[sample "); fflush(stdout);
	fprintf(TESTLOG,"\n[sample]\n");

	/* reset counter */
	n_tests_failed = 0;

	/* set stop watch */
	stopwatch_lap(&watch);
  
{ /* invalid NULL ptr */
UNUR_GEN   *gen = NULL;
   gen = NULL; 


unur_reset_errno();
n_tests_failed += (check_expected_INFINITY(TESTLOG,361,(unur_pinv_eval_approxinvcdf(gen,0.5)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,361,UNUR_ERR_NULL)==UNUR_SUCCESS)?0:1;
unur_free(gen);
}

{ /* invalid generator object */
UNUR_DISTR *distr = NULL;
UNUR_PAR   *par = NULL;
UNUR_GEN   *gen = NULL;
   distr = unur_distr_normal(NULL,0);
   par = unur_srou_new(distr);
   gen = unur_init(par); 
abort_if_NULL(TESTLOG, 367,    gen );


unur_reset_errno();
n_tests_failed += (check_expected_INFINITY(TESTLOG,371,(unur_pinv_eval_approxinvcdf(gen,0.5)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,371,UNUR_ERR_GEN_INVALID)==UNUR_SUCCESS)?0:1;
unur_distr_free(distr);
unur_free(gen);
}

{ /* invalid domain */
UNUR_DISTR *distr = NULL;
UNUR_PAR   *par = NULL;
UNUR_GEN   *gen = NULL;
   distr = unur_distr_normal(NULL,0);
   par = unur_pinv_new(distr);
   unur_set_debug(par,0);
   gen = unur_init( par ); 
abort_if_NULL(TESTLOG, 377,    gen );


unur_reset_errno();
n_tests_failed += (check_expected_INFINITY(TESTLOG,381,(unur_pinv_eval_approxinvcdf(gen,1.5)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,381,UNUR_ERR_DOMAIN)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
n_tests_failed += (check_expected_negINFINITY(TESTLOG,384,(unur_pinv_eval_approxinvcdf(gen,-0.5)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,384,UNUR_ERR_DOMAIN)==UNUR_SUCCESS)?0:1;
unur_distr_free(distr);
unur_free(gen);
}

{ /* cdf table removed */
UNUR_DISTR *distr = NULL;
UNUR_PAR   *par = NULL;
UNUR_GEN   *gen = NULL;
   distr = unur_distr_normal(NULL,0);
   par = unur_pinv_new(distr);
   unur_set_debug(par,0);
   gen = unur_init( par ); 
abort_if_NULL(TESTLOG, 391,    gen );


unur_reset_errno();
n_tests_failed += (check_expected_INFINITY(TESTLOG,395,(unur_pinv_eval_approxcdf(gen,1.5)))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,395,UNUR_ERR_GENERIC)==UNUR_SUCCESS)?0:1;
unur_distr_free(distr);
unur_free(gen);
}

{ /* check approximate cdf */
UNUR_GEN   *gen = NULL;
   int i, cdffailed=0;
   double x,u,d;
   gen = unur_str2gen("cont;logpdf='5-x';domain=(0,infinity)&method=pinv;keepcdf=on;debug=0"); 


unur_reset_errno();
for (i=1; i<1000; i++) {
    x = 5.*i/1000.;
    u = unur_pinv_eval_approxcdf(gen,x);
    d = fabs(u - (1-exp(-x)));
    if (d > 1.e-11) { cdffailed = 1; }}
n_tests_failed += (check_expected_zero(TESTLOG,410,(cdffailed))==UNUR_SUCCESS)?0:1;
n_tests_failed += (check_errorcode(TESTLOG,410,UNUR_SUCCESS)==UNUR_SUCCESS)?0:1;
unur_free(gen);
}

{ /* compare clone */
UNUR_DISTR *distr = NULL;
UNUR_PAR   *par = NULL;
UNUR_GEN   *gen = NULL;
   UNUR_GEN *clone;
   distr = unur_distr_normal(NULL,0); 
   par = NULL;
   gen = NULL; 


unur_reset_errno();
/* original generator object */
par = unur_pinv_new(distr);
gen = unur_init(par);
n_tests_failed += (compare_sequence_gen_start(TESTLOG,423,gen,COMPARE_SAMPLE_SIZE)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
/* clone */
clone = unur_gen_clone(gen);
unur_free(gen);
gen = clone;
n_tests_failed += (compare_sequence_gen(TESTLOG,429,gen,COMPARE_SAMPLE_SIZE)==UNUR_SUCCESS)?0:1;
unur_distr_free(distr);
unur_free(gen);
}

{ /* compare stringparser */
UNUR_DISTR *distr = NULL;
UNUR_PAR   *par = NULL;
UNUR_GEN   *gen = NULL;
   double fpar[] = {3.,4.};
   distr = NULL;
   par = NULL;
   gen = NULL; 


unur_reset_errno();
distr = unur_distr_gamma(fpar,2);
unur_distr_cont_set_domain(distr,2.,UNUR_INFINITY);
par = unur_pinv_new(distr);
set_debug_flag(par);
gen = unur_init(par);
n_tests_failed += (compare_sequence_gen_start(TESTLOG,461,gen,COMPARE_SAMPLE_SIZE)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
unur_free(gen); gen = NULL;
unur_distr_free(distr); distr = NULL;
gen = unur_str2gen( "gamma(3.,4.); domain = (2,infinity) & \
    method = pinv; debug = 0x1" );
n_tests_failed += (compare_sequence_gen(TESTLOG,467,gen,COMPARE_SAMPLE_SIZE)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
unur_free(gen); gen = NULL;
distr = unur_distr_normal(NULL,0);
unur_distr_cont_set_domain(distr,2.,UNUR_INFINITY);
par = unur_pinv_new(distr);
unur_pinv_set_order(par,10);
unur_pinv_set_u_resolution(par,1.e-6);
unur_pinv_set_boundary(par,1.,1000.);
unur_pinv_set_max_intervals(par,1000);
set_debug_flag(par);
gen = unur_init(par);
n_tests_failed += (compare_sequence_gen_start(TESTLOG,480,gen,COMPARE_SAMPLE_SIZE)==UNUR_SUCCESS)?0:1;

unur_reset_errno();
unur_free(gen); gen = NULL;
unur_distr_free(distr); distr = NULL;
gen = unur_str2gen( "normal; domain = (2,inf) & \
         method = pinv; order = 10; u_resolution = 1.e-6; \
         boundary = (1,1000); max_intervals = 1000; debug = 0x1" );
n_tests_failed += (compare_sequence_gen(TESTLOG,487,gen,COMPARE_SAMPLE_SIZE)==UNUR_SUCCESS)?0:1;
unur_distr_free(distr);
unur_free(gen);
}


	/* timing */
	stopwatch_print(TESTLOG,"\n<*>time = %.3f ms\n\n", stopwatch_lap(&watch));

	/* test finished */
	test_ok &= (n_tests_failed) ? 0 : 1;
	(n_tests_failed) ? printf(" ==> failed] ") : printf(" ==> ok] ");

} /* end of test_sample() */

/*---------------------------------------------------------------------------*/
/* [validate] */

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

/* [validate] */

void test_validate (void)
{
	/* suppress GCC compiler warning */
GCC_DIAG_OFF(unused-variable)

	UNUR_DISTR *distr[6];
	UNUR_PAR *par;
	UNUR_GEN *gen;
	double *darray;
	double fpm[10];
	int n_tests_failed;
	int rcode;

	/* start test */
	printf("[validate "); fflush(stdout);
	fprintf(TESTLOG,"\n[validate]\n");

	/* reset counter */
	n_tests_failed = 0;

	/* set stop watch */
	stopwatch_lap(&watch);


/* distributions: 6 */
{
distr[0] = unur_distr_normal(NULL,0);
}

{
distr[1] = unur_distr_multPDF( distr[0], 100. );
}

{
distr[2] = unur_str2distr( "cont; pdf='x/(1+x*x*x*x)'; center=1" );
}

{
distr[3] = unur_str2distr( "cont; pdf='-x/(1+x*x*x*x)'; center=-1" );
}

{
distr[4] = unur_str2distr( "cont; pdf='cos(2*x)'; cdf='(1+sin(2*x))/2'; center=0; domain=(-0.7853981633974482, 0.7853981633974482)" );
}

{
distr[5] = unur_str2distr( "cont; pdf='1-x^2+1e-16'; cdf='( 2-(x^2-3)*x) / 4'; center=0; domain=(-1, 1)" );
}

	/* timing */
	stopwatch_print(TESTLOG,"\n<*>setup time = %.3f ms\n", stopwatch_lap(&watch));

	printf("\n(chi^2) "); fflush(stdout);

/* chi^2 tests: 6 */

	unur_set_default_debug(~UNUR_DEBUG_SAMPLE);
	fprintf( TESTLOG,"\nChi^2 Test:\n");

/* distribution [0] */

	if(TRUE) {
	unur_reset_errno();
	do {
	UNUR_DISTR *distr_localcopy = unur_distr_clone(distr[0]);
par = unur_pinv_new(distr_localcopy);
	gen = unur_init(par);
	rcode = run_validate_chi2(TESTLOG,0,gen,distr[0],'+');
	n_tests_failed += (rcode==UNUR_SUCCESS)?0:1;
	n_tests_failed += (rcode==UNUR_FAILURE)?1000:0;
	unur_free(gen);
	unur_distr_free(distr_localcopy);
	} while (0);
	}

/* distribution [1] */

	if(TRUE) {
	unur_reset_errno();
	do {
	UNUR_DISTR *distr_localcopy = unur_distr_clone(distr[1]);
par = unur_pinv_new(distr_localcopy);
	gen = unur_init(par);
	rcode = run_validate_chi2(TESTLOG,0,gen,distr[1],'+');
	n_tests_failed += (rcode==UNUR_SUCCESS)?0:1;
	n_tests_failed += (rcode==UNUR_FAILURE)?1000:0;
	unur_free(gen);
	unur_distr_free(distr_localcopy);
	} while (0);
	}

/* distribution [2] */

	if(TRUE) {
	unur_reset_errno();
	do {
	UNUR_DISTR *distr_localcopy = unur_distr_clone(distr[2]);
par = unur_pinv_new(distr_localcopy);
	gen = unur_init(par);
	rcode = run_validate_chi2(TESTLOG,0,gen,distr[2],'0');
	n_tests_failed += (rcode==UNUR_SUCCESS)?0:1;
	n_tests_failed += (rcode==UNUR_FAILURE)?1000:0;
	unur_free(gen);
	unur_distr_free(distr_localcopy);
	} while (0);
	}

/* distribution [3] */

	if(TRUE) {
	unur_reset_errno();
	do {
	UNUR_DISTR *distr_localcopy = unur_distr_clone(distr[3]);
par = unur_pinv_new(distr_localcopy);
	gen = unur_init(par);
	rcode = run_validate_chi2(TESTLOG,0,gen,distr[3],'0');
	n_tests_failed += (rcode==UNUR_SUCCESS)?0:1;
	n_tests_failed += (rcode==UNUR_FAILURE)?1000:0;
	unur_free(gen);
	unur_distr_free(distr_localcopy);
	} while (0);
	}

/* distribution [4] */

	if(TRUE) {
	unur_reset_errno();
	do {
	UNUR_DISTR *distr_localcopy = unur_distr_clone(distr[4]);
par = unur_pinv_new(distr_localcopy);
	gen = unur_init(par);
	rcode = run_validate_chi2(TESTLOG,0,gen,distr[4],'+');
	n_tests_failed += (rcode==UNUR_SUCCESS)?0:1;
	n_tests_failed += (rcode==UNUR_FAILURE)?1000:0;
	unur_free(gen);
	unur_distr_free(distr_localcopy);
	} while (0);
	}

/* distribution [5] */

	if(TRUE) {
	unur_reset_errno();
	do {
	UNUR_DISTR *distr_localcopy = unur_distr_clone(distr[5]);
par = unur_pinv_new(distr_localcopy);
	gen = unur_init(par);
	rcode = run_validate_chi2(TESTLOG,0,gen,distr[5],'+');
	n_tests_failed += (rcode==UNUR_SUCCESS)?0:1;
	n_tests_failed += (rcode==UNUR_FAILURE)?1000:0;
	unur_free(gen);
	unur_distr_free(distr_localcopy);
	} while (0);
	}

	/* timing */
	stopwatch_print(TESTLOG,"\n<*>time = %.0f ms\n", stopwatch_lap(&watch));


/* free distributions */
	unur_distr_free(distr[0]);
	unur_distr_free(distr[1]);
	unur_distr_free(distr[2]);
	unur_distr_free(distr[3]);
	unur_distr_free(distr[4]);
	unur_distr_free(distr[5]);

	/* test finished */
	test_ok &= (n_tests_failed>CHI2_FAILURES_TOLERATED) ? 0 : 1;
	/* we accept CHI2_FAILURES_TOLERATED failures */
	(n_tests_failed>CHI2_FAILURES_TOLERATED) ? printf(" ==> failed] ") : printf(" ==> ok] ");

} /* end of test_validate */

/* enable GCC compiler warning */
GCC_DIAG_ON(unused-variable)

/*---------------------------------------------------------------------------*/
/* [special] */

void test_special (void)
{
	/* set boolean to FALSE */
	int FAILED = 0;





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

  UNUR_DISTR *distr, *qdistr;
  UNUR_PAR   *par;

/* start test */
printf("[special "); fflush(stdout);
fprintf(TESTLOG,"\n[special]\n");

/* set stop watch */
stopwatch_lap(&watch);



  /* set u-error tests */
  set_uerror_tests();

  /* 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"); 

  
if (ALL) {
  printf(" normal");
  distr = unur_distr_normal(NULL,0);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}
	
  
if (ALL) {
  printf(" cauchy");
  distr = unur_distr_cauchy(NULL,0);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" exponential");
  distr = unur_distr_exponential(NULL,0);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" gamma(0.9)");
  fpar[0] = 0.9;
  distr = unur_distr_gamma(fpar,1);
  unur_distr_cont_set_center(distr,1.);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" gamma(1.02)");
  fpar[0] = 1.02;
  distr = unur_distr_gamma(fpar,1);
  unur_distr_cont_set_center(distr,1.);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" gamma(1.5)");
  fpar[0] = 1.5;
  distr = unur_distr_gamma(fpar,1);
  unur_distr_cont_set_center(distr,1.);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" gamma(2)");
  fpar[0] = 2.;
  distr = unur_distr_gamma(fpar,1);
  unur_distr_cont_set_center(distr,1.);
  par = unur_pinv_new(distr);
  unur_pinv_set_boundary(par,0., 1.e100);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" gamma(5)");
  fpar[0] = 5.;
  distr = unur_distr_gamma(fpar,1);
  unur_distr_cont_set_center(distr,1.);
  par = unur_pinv_new(distr);
  unur_pinv_set_boundary(par,0., 1.e100);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" beta(2,3)");
  fpar[0] = 2;
  fpar[1] = 3;
  distr = unur_distr_beta(fpar,2);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" Gumbel");
  distr = unur_distr_extremeI(NULL,0);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" shifted normal");
  fpar[0] = 200.;
  fpar[1] = 1.;
  distr = unur_distr_normal(fpar,2);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");

  printf(" shifted normal");
  fpar[0] = -200;
  fpar[1] = 1.;
  distr = unur_distr_normal(fpar,2);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (0) {
  printf(" lognormal(2,0.5)");
  fpar[0] = 2.;
  fpar[1] = 0.5;
  distr = unur_distr_lognormal(fpar,2);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");

  printf(" lognormal(2.0.5,4.)");
  fpar[0] = 2.;
  fpar[1] = 0.5;
  fpar[2] = 4.;
  distr = unur_distr_lognormal(fpar,3);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}
	
} /* endif (UERROR_STANDARDDIST) */
if (UERROR_QUASIPDF) { /* --------------------------- */

  printf("\nDistributions with quasi-densities:\n"); 
  fprintf(TESTLOG,"\n--- Distributions with quasi-densities --- \n\n"); 

if (ALL) {
  distr = unur_distr_normal(NULL,0);

  printf(" (normal*1e10)");
  qdistr = unur_distr_multPDF( distr, 1.e10 );
  par = unur_pinv_new(qdistr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE, DEVEL);
  unur_distr_free(qdistr);
  fprintf(TESTLOG,"\n");

  printf(" (normal*1e-10)");
  qdistr = unur_distr_multPDF( distr, 1.e-10 );
  par = unur_pinv_new(qdistr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE, DEVEL);
  unur_distr_free(qdistr);
  fprintf(TESTLOG,"\n");

  unur_distr_free(distr);
}

} /* endif (UERROR_QUASIPDF) */
if (UERROR_VANISHINGPDF) { /* --------------------------- */

  printf("\nDistributions with vanishing PDF:\n"); 
  fprintf(TESTLOG,"\n--- Distributions with vanishing PDF --- \n\n"); 

  
if (ALL) {
  printf(" (exponential_on_(-oo,oo))");
  distr = unur_distr_exponential(NULL,0);
  unur_distr_cont_set_domain(distr,-UNUR_INFINITY,UNUR_INFINITY);
  unur_distr_set_name(distr,"exponential_(-oo,oo)");
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

if (ALL) {
  printf(" (exponential(1,1)_on_(-oo,oo))");
  fpar[0] = 1.;
  fpar[1] = 1.;
  distr = unur_distr_exponential(fpar,2);
  unur_distr_cont_set_center(distr,2.);
  unur_distr_cont_set_domain(distr,-UNUR_INFINITY,UNUR_INFINITY);
  unur_distr_set_name(distr,"exponential(1,1)_(-oo,oo)");
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

if (ALL) {
  printf(" (exponential(1,1)_on_(-oo,oo))");
  fpar[0] = 1.;
  fpar[1] = 1.;
  distr = unur_distr_exponential(fpar,2);
  unur_distr_cont_set_center(distr,2.);
  unur_distr_cont_set_domain(distr,-UNUR_INFINITY,UNUR_INFINITY);
  unur_distr_cont_set_center(distr,2.);
  unur_distr_set_name(distr,"exponential(1,1)_(-oo,oo)");
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

if (ALL) {
  printf(" (exponential(1,-1)_on_(-oo,oo))");
  fpar[0] = 1.;
  fpar[1] = -1.;
  distr = unur_distr_exponential(fpar,2);
  unur_distr_cont_set_center(distr,2.);
  unur_distr_cont_set_domain(distr,-UNUR_INFINITY,UNUR_INFINITY);
  unur_distr_set_name(distr,"exponential(1,-1)_(-oo,oo)");
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

if (ALL) {
  printf(" (exponential(0.1,0.1)_on_(-oo,oo))");
  fpar[0] = 0.1;
  fpar[1] = 0.1;
  distr = unur_distr_exponential(fpar,2);
  unur_distr_cont_set_center(distr,2.);
  unur_distr_cont_set_domain(distr,-UNUR_INFINITY,UNUR_INFINITY);
  unur_distr_set_name(distr,"exponential(0.1,0.1)_(-oo,oo)");
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

if (ALL) {
  printf(" (exponential(1000,1000)_on_(-oo,oo))");
  fpar[0] = 1000;
  fpar[1] = 1000;
  distr = unur_distr_exponential(fpar,2);
  unur_distr_cont_set_center(distr,1000.);
  unur_distr_cont_set_domain(distr,-UNUR_INFINITY,UNUR_INFINITY);
  unur_distr_set_name(distr,"exponential(1000,1000)_(-oo,oo)");
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" neg_exponential");
  distr = unur_distr_cont_new();
  unur_distr_set_name(distr,"neg_exponential");
  unur_distr_cont_set_cdf( distr, neg_exponential_cdf );
  unur_distr_cont_set_pdf( distr, neg_exponential_pdf );
  unur_distr_cont_set_domain(distr,-UNUR_INFINITY,UNUR_INFINITY);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

if (ALL) {
  printf(" neg_exponential_1");
  distr = unur_distr_cont_new();
  unur_distr_set_name(distr,"neg_exponential_1");
  unur_distr_cont_set_cdf( distr, neg_exponential_1_cdf );
  unur_distr_cont_set_pdf( distr, neg_exponential_1_pdf );
  unur_distr_cont_set_domain(distr,-UNUR_INFINITY,UNUR_INFINITY);
  unur_distr_cont_set_center(distr,-2.);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" gamma(2)");
  fpar[0] = 2.;
  distr = unur_distr_gamma(fpar,1);
  unur_distr_cont_set_center(distr,1.);
  unur_distr_cont_set_domain(distr,-UNUR_INFINITY,UNUR_INFINITY);
  par = unur_pinv_new(distr);
  unur_pinv_set_boundary(par,0., 1.e100);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" gamma(5)");
  fpar[0] = 5.;
  distr = unur_distr_gamma(fpar,1);
  unur_distr_cont_set_center(distr,1.);
  unur_distr_cont_set_domain(distr,-UNUR_INFINITY,UNUR_INFINITY);
  par = unur_pinv_new(distr);
  unur_pinv_set_boundary(par,0., 1.e100);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" gamma(1.02)");
  fpar[0] = 1.02;
  distr = unur_distr_gamma(fpar,1);
  unur_distr_cont_set_center(distr,1.);
  unur_distr_cont_set_domain(distr,-UNUR_INFINITY,UNUR_INFINITY);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

} /* endif (UERROR_VANISHINGPDF) */
if (UERROR_TRUNCATED) { /* --------------------------- */

  printf("\nTruncated Distributions:\n"); 
  fprintf(TESTLOG,"\n--- Truncated Distributions --- \n\n"); 

  
if (ALL) {
  printf(" truncated normal[3,inf]");
  distr = unur_distr_normal(NULL,0);
  unur_distr_cont_set_domain(distr,3.,UNUR_INFINITY);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

if (ALL && DEVEL) {
  printf(" truncated normal[15,inf]");
  distr = unur_distr_normal(NULL,0);
  unur_distr_cont_set_domain(distr,15.,UNUR_INFINITY);
  par = unur_pinv_new(distr);
  /* using CDF does not work here. */
  errorsum += pinv_error_experiment(par,samplesize,TRUE, DEVEL);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

} /* endif (UERROR_TRUNCATED) */
if (UERROR_UNBOUNDEDPDF) { /* --------------------------- */

  printf("\nDistributions with unbounded PDF:\n"); 
  fprintf(TESTLOG,"\n--- Distributions with unbounded PDF --- \n\n"); 

  
if (ALL) {
  printf(" gamma(0.2)");
  fpar[0] = 0.2;
  distr = unur_distr_gamma(fpar,1);
  unur_distr_cont_set_center(distr,1.);
  par = unur_pinv_new(distr);
  unur_pinv_set_extra_testpoints(par,50);
  errorsum += pinv_error_experiment(par,samplesize,TRUE, DEVEL);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" gamma(0.5)");
  fpar[0] = 0.5;
  distr = unur_distr_gamma(fpar,1);
  unur_distr_cont_set_center(distr,1.);
  par = unur_pinv_new(distr);
  unur_pinv_set_extra_testpoints(par,40);
  errorsum += pinv_error_experiment(par,samplesize,TRUE, DEVEL);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

} /* endif (UERROR_UNBOUNDEDPDF) */
if (UERROR_MULTIMODAL) { /* --------------------------- */

  printf("\nMultimodal distributions:\n"); 
  fprintf(TESTLOG,"\n--- Multimodal distributions --- \n\n"); 

  
if (ALL) {
  printf(" sin-2-example");
  distr = unur_distr_cont_new();
  unur_distr_set_name(distr,"sin-2-example");
  unur_distr_cont_set_cdf( distr, sin_2_cdf );
  unur_distr_cont_set_pdf( distr, sin_2_pdf );
  unur_distr_cont_set_domain( distr, -1., 1. );
  unur_distr_cont_set_center(distr,0.25);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" sin-10-example");
  distr = unur_distr_cont_new();
  unur_distr_set_name(distr,"sin-10-example");
  unur_distr_cont_set_cdf( distr, sin_10_cdf );
  unur_distr_cont_set_pdf( distr, sin_10_pdf );
  unur_distr_cont_set_domain( distr, -5., 5. );
  unur_distr_cont_set_center(distr,0.25);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE, DEVEL);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

} /* endif (UERROR_MULTIMODAL) */
if (UERROR_MULTIMODAL_VANISHINGPDF) { /* --------------------------- */

  printf("\nMultimodal distributions with vanishing PDF:\n"); 
  fprintf(TESTLOG,"\n--- Multimodal distributions with vanishing PDF --- \n\n"); 

  
if (ALL) {
  printf(" sin-2-example");fflush(stdout);
  distr = unur_distr_cont_new();
  unur_distr_set_name(distr,"sin-0-example");
  unur_distr_cont_set_cdf( distr, sin_2_cdf );
  unur_distr_cont_set_pdf( distr, sin_2_pdf );
  unur_distr_cont_set_domain( distr, -2., 2. );
  unur_distr_cont_set_center(distr,0.25);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

if (ALL) {
  printf(" sin-2-example");fflush(stdout);
  distr = unur_distr_cont_new();
  unur_distr_set_name(distr,"sin-0-example");
  unur_distr_cont_set_cdf( distr, sin_2_cdf );
  unur_distr_cont_set_pdf( distr, sin_2_pdf );
  unur_distr_cont_set_domain(distr,-UNUR_INFINITY,UNUR_INFINITY);
  unur_distr_cont_set_center(distr,0.25);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE,TRUE);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

  
if (ALL) {
  printf(" sin-10-example");
  distr = unur_distr_cont_new();
  unur_distr_set_name(distr,"sin-10-example");
  unur_distr_cont_set_cdf( distr, sin_10_cdf );
  unur_distr_cont_set_pdf( distr, sin_10_pdf );
  unur_distr_cont_set_domain(distr,-UNUR_INFINITY,UNUR_INFINITY);
  unur_distr_cont_set_center(distr,0.25);
  par = unur_pinv_new(distr);
  errorsum += pinv_error_experiment(par,samplesize,TRUE, DEVEL);
  unur_distr_free(distr);
  fprintf(TESTLOG,"\n");
}

} /* endif (UERROR_MULTIMODAL_VANISHINGPDF) */

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

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




	/* timing */
	stopwatch_print(TESTLOG,"\n<*>time = %.3f ms\n\n", stopwatch_lap(&watch));

	/* test finished */
	test_ok &= (FAILED) ? 0 : 1;
	(FAILED) ? printf(" ==> failed] ") : printf(" ==> ok] ");

} /* end of test_special() */


/*---------------------------------------------------------------------------*/
/* run generator in verifying mode */

void run_verify_generator( FILE *LOG, int line, UNUR_PAR *par )
{
	UNUR_GEN *gen;
	int i;

	/* switch to verifying mode */
	unur_pinv_set_verify(par,1);

	/* initialize generator */
	gen = unur_init( par ); abort_if_NULL(LOG, line, gen);

	/* run generator */
	for (i=0; i<VIOLATE_SAMPLE_SIZE; i++)
		unur_sample_cont(gen);

	/* destroy generator */
	unur_free(gen); 

} /* end of run_verify_generator() */

int unur_pinv_set_verify(UNUR_PAR *par ATTRIBUTE__UNUSED, int verify ATTRIBUTE__UNUSED) {return 0;}

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

int main(void)
{ 
        unsigned long seed;
	char *str_seed, *str_tail;

	/* start stop watch */
	stopwatch_init();
	stopwatch_start(&watch);

        /* open log file for unuran and set output stream for unuran messages */
        UNURANLOG = fopen( "t_pinv_unuran.log","w" );
        abort_if_NULL( stderr,-1, UNURANLOG );
        unur_set_stream( UNURANLOG );

        /* open log file for testing */
	TESTLOG = fopen( "t_pinv_test.log","w" );
	abort_if_NULL( stderr,-1, TESTLOG );

        /* seed for uniform generators */

	/* seed set by environment */
	str_seed = getenv("SEED");

	if (str_seed != NULL) {
	    seed = strtol(str_seed, &str_tail, 10);
	    if (seed == 0u) 
		seed = 217101;
	}
	else {
#ifdef SEED
	    seed = SEED;
#else
	    seed = 217101;
#endif
	}

        /* seed build-in uniform generators */
        unur_urng_MRG31k3p_seed(NULL,seed);
        unur_urng_fish_seed(NULL,seed);
	unur_urng_mstd_seed(NULL,seed);

	/* seed uniform random number generator */
#ifdef UNUR_URNG_UNURAN
#  ifdef UNUR_URNG_DEFAULT_RNGSTREAM
	{
	        unsigned long sa[6];
	        int i;
	        for (i=0; i<6; i++) sa[i] = seed;
                RngStream_SetPackageSeed(sa);
        }
#  else
	if (unur_urng_seed(NULL,seed) != UNUR_SUCCESS) {
	        fprintf(stderr,"WARNING: Seed could not be set at random\n");
                seed = ~0u;
	}
#  endif  /* UNUR_URNG_DEFAULT_RNGSTREAM */
#endif  /* UNUR_URNG_UNURAN */
 
	/* set default debugging flag */
	unur_set_default_debug(UNUR_DEBUG_ALL);

        /* detect required check mode */
        fullcheck = (getenv("UNURANFULLCHECK")==NULL) ? FALSE : TRUE;

	/* write header into log file */
        print_test_log_header( TESTLOG, seed, fullcheck );

	/* set timer for sending SIGALRM signal */
	set_alarm(TESTLOG);

	/* start test */
	printf("pinv: ");

	/* run tests */
test_new();
test_set();
test_get();
test_sample();
test_validate();
test_special();


	/* test finished */
	printf("\n");  fflush(stdout);

	/* close log files */
	fprintf(TESTLOG,"\n====================================================\n\n");
	if (test_ok)
		fprintf(TESTLOG,"All tests PASSED.\n");
	else
		fprintf(TESTLOG,"Test(s) FAILED.\n");

	/* timing */
	stopwatch_print(TESTLOG,"\n<*>total time = %.0f ms\n\n", stopwatch_stop(&watch));

	fclose(UNURANLOG);
	fclose(TESTLOG);

	/* free memory */
	compare_free_memory();
	unur_urng_free(unur_get_default_urng());
	unur_urng_free(unur_get_default_urng_aux());

	/* exit */
	exit( (test_ok) ? EXIT_SUCCESS : EXIT_FAILURE );

} /* end of main */

