/* utest_odds(): test accuracy of logf, expf on odds ratios, * our main intended use. */ static void utest_odds(ESL_GETOPTS *go, ESL_RANDOMNESS *r) { int N = esl_opt_GetInteger(go, "-N"); int verbose = esl_opt_GetBoolean(go, "-v"); int very_verbose = esl_opt_GetBoolean(go, "--vv"); int i; float p1, p2, odds; union { __m128 v; float x[4]; } r1; union { __m128 v; float x[4]; } r2; float scalar_r1, scalar_r2; double err1, maxerr1 = 0.0, avgerr1 = 0.0; /* errors on logf() */ double err2, maxerr2 = 0.0, avgerr2 = 0.0; /* errors on expf() */ for (i = 0; i < N; i++) { p1 = esl_rnd_UniformPositive(r); p2 = esl_rnd_UniformPositive(r); odds = p1 / p2; if (odds == 0.0) esl_fatal("whoa, odds ratio can't be 0!\n"); r1.v = esl_sse_logf(_mm_set1_ps(odds)); /* r1.x[z] = log(p1/p2) */ scalar_r1 = log(odds); err1 = (r1.x[0] == 0. && scalar_r1 == 0.) ? 0.0 : 2 * fabs(r1.x[0] - scalar_r1) / fabs(r1.x[0] + scalar_r1); if (err1 > maxerr1) maxerr1 = err1; avgerr1 += err1 / (float) N; if (isnan(avgerr1)) esl_fatal("whoa, what?\n"); r2.v = esl_sse_expf(r1.v); /* and back to odds */ scalar_r2 = exp(r1.x[0]); err2 = (r2.x[0] == 0. && scalar_r2 == 0.) ? 0.0 : 2 * fabs(r2.x[0] - scalar_r2) / fabs(r2.x[0] + scalar_r2); if (err2 > maxerr2) maxerr2 = err2; avgerr2 += err2 / (float) N; if (very_verbose) printf("%13.7g %13.7g %13.7g %13.7g %13.7g %13.7g %13.7g\n", odds, scalar_r1, r1.x[0], scalar_r2, r2.x[0], err1, err2); } if (verbose) { printf("Average [max] logf() relative error in %d odds trials: %13.8g [%13.8g]\n", N, avgerr1, maxerr1); printf("Average [max] expf() relative error in %d odds trials: %13.8g [%13.8g]\n", N, avgerr2, maxerr2); printf("(random seed : %" PRIu32 ")\n", esl_randomness_GetSeed(r)); } if (avgerr1 > 1e-8) esl_fatal("average error on logf() is intolerable\n"); if (maxerr1 > 1e-6) esl_fatal("maximum error on logf() is intolerable\n"); if (avgerr2 > 1e-8) esl_fatal("average error on expf() is intolerable\n"); if (maxerr2 > 1e-6) esl_fatal("maximum error on expf() is intolerable\n"); }
/* Function: esl_gev_Sample() * * Purpose: Sample a GEV-distributed random variate, * by the transformation method. */ double esl_gev_Sample(ESL_RANDOMNESS *r, double mu, double lambda, double alpha) { double p; p = esl_rnd_UniformPositive(r); return esl_gev_invcdf(p, mu, lambda, alpha); }
/* Function: esl_wei_Sample() * * Purpose: Sample a Weibull random variate, * by the transformation method. */ double esl_wei_Sample(ESL_RANDOMNESS *r, double mu, double lambda, double tau) { double p; p = esl_rnd_UniformPositive(r); return esl_wei_invcdf(p, mu, lambda, tau); }
/* Function: esl_exp_Sample() * Incept: SRE, Wed Aug 10 10:46:51 2005 [St. Louis] * * Purpose: Sample an exponential random variate * by the transformation method, given offset <mu> * and decay parameter <lambda>. */ double esl_exp_Sample(ESL_RANDOMNESS *r, double mu, double lambda) { double p, x; p = esl_rnd_UniformPositive(r); x = mu - 1./lambda * log(p); /* really log(1-p), but if p uniform on 0..1 * then so is 1-p. */ return x; }
static double gamma_integer(ESL_RANDOMNESS *r, unsigned int a) /* for small integer a, a < 12 */ { int i; double U,X; U = 1.; for (i = 0; i < a; i++) U *= esl_rnd_UniformPositive(r); X = -log(U); return X; }
static double gamma_fraction(ESL_RANDOMNESS *r, double a) /* for fractional a, 0 < a < 1 */ { /* Knuth 3.4.1, exercise 16, pp. 586-587 */ double p, U, V, X, q; p = eslCONST_E / (a + eslCONST_E); do { U = esl_random(r); V = esl_rnd_UniformPositive(r); if (U < p) { X = pow(V, 1./a); q = exp(-X); } else { X = 1. - log(V); q = pow(X, a-1.); } U = esl_random(r); } while (U >= q); return X; }