double truncNorm(const double mean, const double var) { // Implements a rejection sampler for a left // truncated normal distribution double rv; rv = gsl_ran_gaussian_tail(rng,-mean,sqrt(var)); return rv + mean; }
void librdist_gaussian_tail(gsl_rng *rng, int argc, void *argv, int bufc, float *buf){ t_atom *av = (t_atom *)argv; if(argc != librdist_getnargs(ps_gaussian_tail)){ return; } const double a = librdist_atom_getfloat(av); const double sigma = librdist_atom_getfloat(av + 1); int i; for(i = 0; i < bufc; i++) buf[i] = (float)gsl_ran_gaussian_tail(rng, a, sigma); }
double ighmm_rand_normal_right (double a, double mue, double u, int seed) { # define CUR_PROC "ighmm_rand_normal_right" double x = -1; double sigma; #ifdef DO_WITH_GSL double s; #else double U, Us, Us1, Feps, t, T; #endif if (u <= 0.0) { GHMM_LOG(LCONVERTED, "u <= 0.0 not allowed\n"); goto STOP; } sigma = sqrt(u); if (seed != 0) { GHMM_RNG_SET (RNG, seed); } #ifdef DO_WITH_GSL /* move boundary to lower values in order to achieve maximum at mue gsl_ran_gaussian_tail(generator, lower_boundary, sigma) */ return mue + gsl_ran_gaussian_tail(RNG, a - mue, sqrt (u)); #else /* DO_WITH_GSL */ /* Inverse transformation with restricted sampling by Fishman */ U = GHMM_RNG_UNIFORM(RNG); Feps = ighmm_rand_get_PHI((a-mue) / sigma); Us = Feps + (1-Feps) * U; Us1 = 1-Us; t = m_min (Us, Us1); t = sqrt (-log (t * t)); T = sigma * (t - (C0 + t * (C1 + t * C2)) / (1 + t * (D1 + t * (D2 + t * D3)))); if (Us < Us1) x = mue - T; else x = mue + T; #endif /* DO_WITH_GSL */ STOP: return x; # undef CUR_PROC } /* randvar_normal_pos */
int main() { gsl_rng *r = gsl_rng_alloc(gsl_rng_default); const double tol1 = 1.0e-8; const double tol2 = 1.0e-3; gsl_ieee_env_setup(); { const size_t N = 2000000; double *data = random_data(N, r); double data2[] = { 4.0, 7.0, 13.0, 16.0 }; size_t i; test_basic(2, data, tol1); test_basic(100, data, tol1); test_basic(1000, data, tol1); test_basic(10000, data, tol1); test_basic(50000, data, tol1); test_basic(80000, data, tol1); test_basic(1500000, data, tol1); test_basic(2000000, data, tol1); for (i = 0; i < 4; ++i) data2[i] += 1.0e9; test_basic(4, data2, tol1); free(data); } { /* dataset from Jain and Chlamtac paper */ const size_t n_jain = 20; const double data_jain[] = { 0.02, 0.15, 0.74, 3.39, 0.83, 22.37, 10.15, 15.43, 38.62, 15.92, 34.60, 10.28, 1.47, 0.40, 0.05, 11.39, 0.27, 0.42, 0.09, 11.37 }; double expected_jain = 4.44063435326; test_quantile(0.5, data_jain, n_jain, expected_jain, tol1, "jain"); } { size_t n = 1000000; double *data = malloc(n * sizeof(double)); double *sorted_data = malloc(n * sizeof(double)); gsl_rstat_workspace *rstat_workspace_p = gsl_rstat_alloc(); double p; size_t i; for (i = 0; i < n; ++i) { data[i] = gsl_ran_gaussian_tail(r, 1.3, 1.0); gsl_rstat_add(data[i], rstat_workspace_p); } memcpy(sorted_data, data, n * sizeof(double)); gsl_sort(sorted_data, 1, n); /* test quantile calculation */ for (p = 0.1; p <= 0.9; p += 0.1) { double expected = gsl_stats_quantile_from_sorted_data(sorted_data, 1, n, p); test_quantile(p, data, n, expected, tol2, "gauss"); } /* test mean, variance */ { const double expected_mean = gsl_stats_mean(data, 1, n); const double expected_var = gsl_stats_variance(data, 1, n); const double expected_sd = gsl_stats_sd(data, 1, n); const double expected_skew = gsl_stats_skew(data, 1, n); const double expected_kurtosis = gsl_stats_kurtosis(data, 1, n); const double expected_median = gsl_stats_quantile_from_sorted_data(sorted_data, 1, n, 0.5); const double mean = gsl_rstat_mean(rstat_workspace_p); const double var = gsl_rstat_variance(rstat_workspace_p); const double sd = gsl_rstat_sd(rstat_workspace_p); const double skew = gsl_rstat_skew(rstat_workspace_p); const double kurtosis = gsl_rstat_kurtosis(rstat_workspace_p); const double median = gsl_rstat_median(rstat_workspace_p); gsl_test_rel(mean, expected_mean, tol1, "mean"); gsl_test_rel(var, expected_var, tol1, "variance"); gsl_test_rel(sd, expected_sd, tol1, "stddev"); gsl_test_rel(skew, expected_skew, tol1, "skew"); gsl_test_rel(kurtosis, expected_kurtosis, tol1, "kurtosis"); gsl_test_abs(median, expected_median, tol2, "median"); } free(data); free(sorted_data); gsl_rstat_free(rstat_workspace_p); } gsl_rng_free(r); exit (gsl_test_summary()); }
int main (int argc, char *argv[]) { size_t i,j; size_t n = 0; double mu = 0, nu = 0, nu1 = 0, nu2 = 0, sigma = 0, a = 0, b = 0, c = 0; double zeta = 0, sigmax = 0, sigmay = 0, rho = 0; double p = 0; double x = 0, y =0, z=0 ; unsigned int N = 0, t = 0, n1 = 0, n2 = 0 ; unsigned long int seed = 0 ; const char * name ; gsl_rng * r ; if (argc < 4) { printf ( "Usage: gsl-randist seed n DIST param1 param2 ...\n" "Generates n samples from the distribution DIST with parameters param1,\n" "param2, etc. Valid distributions are,\n" "\n" " beta\n" " binomial\n" " bivariate-gaussian\n" " cauchy\n" " chisq\n" " dir-2d\n" " dir-3d\n" " dir-nd\n" " erlang\n" " exponential\n" " exppow\n" " fdist\n" " flat\n" " gamma\n" " gaussian-tail\n" " gaussian\n" " geometric\n" " gumbel1\n" " gumbel2\n" " hypergeometric\n" " laplace\n" " landau\n" " levy\n" " levy-skew\n" " logarithmic\n" " logistic\n" " lognormal\n" " negative-binomial\n" " pareto\n" " pascal\n" " poisson\n" " rayleigh-tail\n" " rayleigh\n" " tdist\n" " ugaussian-tail\n" " ugaussian\n" " weibull\n") ; exit (0); } argv++ ; seed = atol (argv[0]); argc-- ; argv++ ; n = atol (argv[0]); argc-- ; argv++ ; name = argv[0] ; argc-- ; argc-- ; gsl_rng_env_setup() ; if (gsl_rng_default_seed != 0) { fprintf(stderr, "overriding GSL_RNG_SEED with command line value, seed = %ld\n", seed) ; } gsl_rng_default_seed = seed ; r = gsl_rng_alloc(gsl_rng_default) ; #define NAME(x) !strcmp(name,(x)) #define OUTPUT(x) for (i = 0; i < n; i++) { printf("%g\n", (x)) ; } #define OUTPUT1(a,x) for(i = 0; i < n; i++) { a ; printf("%g\n", x) ; } #define OUTPUT2(a,x,y) for(i = 0; i < n; i++) { a ; printf("%g %g\n", x, y) ; } #define OUTPUT3(a,x,y,z) for(i = 0; i < n; i++) { a ; printf("%g %g %g\n", x, y, z) ; } #define INT_OUTPUT(x) for (i = 0; i < n; i++) { printf("%d\n", (x)) ; } #define ARGS(x,y) if (argc != x) error(y) ; #define DBL_ARG(x) if (argc) { x=atof((++argv)[0]);argc--;} else {error( #x);}; #define INT_ARG(x) if (argc) { x=atoi((++argv)[0]);argc--;} else {error( #x);}; if (NAME("bernoulli")) { ARGS(1, "p = probability of success"); DBL_ARG(p) INT_OUTPUT(gsl_ran_bernoulli (r, p)); } else if (NAME("beta")) { ARGS(2, "a,b = shape parameters"); DBL_ARG(a) DBL_ARG(b) OUTPUT(gsl_ran_beta (r, a, b)); } else if (NAME("binomial")) { ARGS(2, "p = probability, N = number of trials"); DBL_ARG(p) INT_ARG(N) INT_OUTPUT(gsl_ran_binomial (r, p, N)); } else if (NAME("cauchy")) { ARGS(1, "a = scale parameter"); DBL_ARG(a) OUTPUT(gsl_ran_cauchy (r, a)); } else if (NAME("chisq")) { ARGS(1, "nu = degrees of freedom"); DBL_ARG(nu) OUTPUT(gsl_ran_chisq (r, nu)); } else if (NAME("erlang")) { ARGS(2, "a = scale parameter, b = order"); DBL_ARG(a) DBL_ARG(b) OUTPUT(gsl_ran_erlang (r, a, b)); } else if (NAME("exponential")) { ARGS(1, "mu = mean value"); DBL_ARG(mu) ; OUTPUT(gsl_ran_exponential (r, mu)); } else if (NAME("exppow")) { ARGS(2, "a = scale parameter, b = power (1=exponential, 2=gaussian)"); DBL_ARG(a) ; DBL_ARG(b) ; OUTPUT(gsl_ran_exppow (r, a, b)); } else if (NAME("fdist")) { ARGS(2, "nu1, nu2 = degrees of freedom parameters"); DBL_ARG(nu1) ; DBL_ARG(nu2) ; OUTPUT(gsl_ran_fdist (r, nu1, nu2)); } else if (NAME("flat")) { ARGS(2, "a = lower limit, b = upper limit"); DBL_ARG(a) ; DBL_ARG(b) ; OUTPUT(gsl_ran_flat (r, a, b)); } else if (NAME("gamma")) { ARGS(2, "a = order, b = scale"); DBL_ARG(a) ; DBL_ARG(b) ; OUTPUT(gsl_ran_gamma (r, a, b)); } else if (NAME("gaussian")) { ARGS(1, "sigma = standard deviation"); DBL_ARG(sigma) ; OUTPUT(gsl_ran_gaussian (r, sigma)); } else if (NAME("gaussian-tail")) { ARGS(2, "a = lower limit, sigma = standard deviation"); DBL_ARG(a) ; DBL_ARG(sigma) ; OUTPUT(gsl_ran_gaussian_tail (r, a, sigma)); } else if (NAME("ugaussian")) { ARGS(0, "unit gaussian, no parameters required"); OUTPUT(gsl_ran_ugaussian (r)); } else if (NAME("ugaussian-tail")) { ARGS(1, "a = lower limit"); DBL_ARG(a) ; OUTPUT(gsl_ran_ugaussian_tail (r, a)); } else if (NAME("bivariate-gaussian")) { ARGS(3, "sigmax = x std.dev., sigmay = y std.dev., rho = correlation"); DBL_ARG(sigmax) ; DBL_ARG(sigmay) ; DBL_ARG(rho) ; OUTPUT2(gsl_ran_bivariate_gaussian (r, sigmax, sigmay, rho, &x, &y), x, y); } else if (NAME("dir-2d")) { OUTPUT2(gsl_ran_dir_2d (r, &x, &y), x, y); } else if (NAME("dir-3d")) { OUTPUT3(gsl_ran_dir_3d (r, &x, &y, &z), x, y, z); } else if (NAME("dir-nd")) { double *xarr; ARGS(1, "n1 = number of dimensions of hypersphere"); INT_ARG(n1) ; xarr = (double *)malloc(n1*sizeof(double)); for(i = 0; i < n; i++) { gsl_ran_dir_nd (r, n1, xarr) ; for (j = 0; j < n1; j++) { if (j) putchar(' '); printf("%g", xarr[j]) ; } putchar('\n'); } ; free(xarr); } else if (NAME("geometric")) { ARGS(1, "p = bernoulli trial probability of success"); DBL_ARG(p) ; INT_OUTPUT(gsl_ran_geometric (r, p)); } else if (NAME("gumbel1")) { ARGS(2, "a = order, b = scale parameter"); DBL_ARG(a) ; DBL_ARG(b) ; OUTPUT(gsl_ran_gumbel1 (r, a, b)); } else if (NAME("gumbel2")) { ARGS(2, "a = order, b = scale parameter"); DBL_ARG(a) ; DBL_ARG(b) ; OUTPUT(gsl_ran_gumbel2 (r, a, b)); } else if (NAME("hypergeometric")) { ARGS(3, "n1 = tagged population, n2 = untagged population, t = number of trials"); INT_ARG(n1) ; INT_ARG(n2) ; INT_ARG(t) ; INT_OUTPUT(gsl_ran_hypergeometric (r, n1, n2, t)); } else if (NAME("laplace")) { ARGS(1, "a = scale parameter"); DBL_ARG(a) ; OUTPUT(gsl_ran_laplace (r, a)); } else if (NAME("landau")) { ARGS(0, "no arguments required"); OUTPUT(gsl_ran_landau (r)); } else if (NAME("levy")) { ARGS(2, "c = scale, a = power (1=cauchy, 2=gaussian)"); DBL_ARG(c) ; DBL_ARG(a) ; OUTPUT(gsl_ran_levy (r, c, a)); } else if (NAME("levy-skew")) { ARGS(3, "c = scale, a = power (1=cauchy, 2=gaussian), b = skew"); DBL_ARG(c) ; DBL_ARG(a) ; DBL_ARG(b) ; OUTPUT(gsl_ran_levy_skew (r, c, a, b)); } else if (NAME("logarithmic")) { ARGS(1, "p = probability"); DBL_ARG(p) ; INT_OUTPUT(gsl_ran_logarithmic (r, p)); } else if (NAME("logistic")) { ARGS(1, "a = scale parameter"); DBL_ARG(a) ; OUTPUT(gsl_ran_logistic (r, a)); } else if (NAME("lognormal")) { ARGS(2, "zeta = location parameter, sigma = scale parameter"); DBL_ARG(zeta) ; DBL_ARG(sigma) ; OUTPUT(gsl_ran_lognormal (r, zeta, sigma)); } else if (NAME("negative-binomial")) { ARGS(2, "p = probability, a = order"); DBL_ARG(p) ; DBL_ARG(a) ; INT_OUTPUT(gsl_ran_negative_binomial (r, p, a)); } else if (NAME("pareto")) { ARGS(2, "a = power, b = scale parameter"); DBL_ARG(a) ; DBL_ARG(b) ; OUTPUT(gsl_ran_pareto (r, a, b)); } else if (NAME("pascal")) { ARGS(2, "p = probability, n = order (integer)"); DBL_ARG(p) ; INT_ARG(N) ; INT_OUTPUT(gsl_ran_pascal (r, p, N)); } else if (NAME("poisson")) { ARGS(1, "mu = scale parameter"); DBL_ARG(mu) ; INT_OUTPUT(gsl_ran_poisson (r, mu)); } else if (NAME("rayleigh")) { ARGS(1, "sigma = scale parameter"); DBL_ARG(sigma) ; OUTPUT(gsl_ran_rayleigh (r, sigma)); } else if (NAME("rayleigh-tail")) { ARGS(2, "a = lower limit, sigma = scale parameter"); DBL_ARG(a) ; DBL_ARG(sigma) ; OUTPUT(gsl_ran_rayleigh_tail (r, a, sigma)); } else if (NAME("tdist")) { ARGS(1, "nu = degrees of freedom"); DBL_ARG(nu) ; OUTPUT(gsl_ran_tdist (r, nu)); } else if (NAME("weibull")) { ARGS(2, "a = scale parameter, b = exponent"); DBL_ARG(a) ; DBL_ARG(b) ; OUTPUT(gsl_ran_weibull (r, a, b)); } else { fprintf(stderr,"Error: unrecognized distribution: %s\n", name) ; } return 0 ; }
double test_gaussian_tail2 (void) { return gsl_ran_gaussian_tail (r_global, 0.1, 2.0); }
double test_gaussian_tail1 (void) { return gsl_ran_gaussian_tail (r_global, -1.7, 5.0); }
double test_gaussian_tail (void) { return gsl_ran_gaussian_tail (r_global, 1.7, 0.25); }
double gsl_ran_ugaussian_tail (const gsl_rng * r, const double a) { return gsl_ran_gaussian_tail (r, a, 1.0) ; }
double randvar_normal_pos (double mue, double u, int seed) { # define CUR_PROC "randvar_normal_pos" double x = -1; double sigma; #ifdef DO_WITH_GSL double s; #else double U, Us, Us1, Feps, Feps1, t, T; #endif if (u <= 0.0) { mes_prot ("u <= 0.0 not allowed\n"); goto STOP; } sigma = sqrt (u); if (seed != 0) { GHMM_RNG_SET (RNG, seed); return (1.0); } #ifdef DO_WITH_GSL /* up to version 0.8 gsl_ran_gaussian_tail can not handle negative cutoff */ #define GSL_RAN_GAUSSIAN_TAIL_BUG 1 #ifdef GSL_RAN_GAUSSIAN_TAIL_BUG s = (-mue) / sigma; if (s < 1) { do { x = gsl_ran_gaussian (RNG, 1.0); } while (x < s); return x * sigma + mue; } #endif /* GSL_RAN_GAUSSIAN_TAIL_BUG */ /* move boundary to lower values in order to achieve maximum at mue gsl_ran_gaussian_tail(generator, lower_boundary, sigma) */ return gsl_ran_gaussian_tail (RNG, -mue, sqrt (u)) + mue; #else /* DO_WITH_GSL */ /* Method: Generate Gauss-distributed random nunbers (with GSL-lib.), until a positive one is found -> not very effective if mue << 0 while (x < 0.0) { x = sigma * randvar_std_normal(seed) + mue; } */ /* Inverse transformation with restricted sampling by Fishman */ U = GHMM_RNG_UNIFORM (RNG); Feps = randvar_get_PHI (-(EPS_NDT + mue) / sigma); Us = Feps + (1 - Feps) * U; /* Numerically better: 1-Us = 1-Feps - (1-Feps)*U, therefore: Feps1 = 1-Feps, Us1 = 1-Us */ Feps1 = randvar_get_PHI ((EPS_NDT + mue) / sigma); Us1 = Feps1 - Feps1 * U; t = m_min (Us, Us1); t = sqrt (-log (t * t)); T = sigma * (t - (C0 + t * (C1 + t * C2)) / (1 + t * (D1 + t * (D2 + t * D3)))); if (Us - 0.5 < 0) x = mue - T; else x = mue + T; #endif /* DO_WITH_GSL */ STOP: return (x); # undef CUR_PROC } /* randvar_normal_pos */