* Note: random_beta assumes that a != 0 and b != 0. */
| 409 | * Note: random_beta assumes that a != 0 and b != 0. |
| 410 | */ |
| 411 | double random_beta(bitgen_t *bitgen_state, double a, double b) { |
| 412 | double Ga, Gb; |
| 413 | |
| 414 | if ((a <= 1.0) && (b <= 1.0)) { |
| 415 | double U, V, X, Y, XpY; |
| 416 | |
| 417 | if (a < BETA_TINY_THRESHOLD && b < BETA_TINY_THRESHOLD) { |
| 418 | /* |
| 419 | * When a and b are this small, the probability that the |
| 420 | * sample would be a double precision float that is not |
| 421 | * 0 or 1 is less than approx. 1e-100. So we use the |
| 422 | * proportion a/(a + b) and a single uniform sample to |
| 423 | * generate the result. |
| 424 | */ |
| 425 | U = next_double(bitgen_state); |
| 426 | return (a + b)*U < a; |
| 427 | } |
| 428 | |
| 429 | /* Use Johnk's algorithm */ |
| 430 | |
| 431 | while (1) { |
| 432 | U = next_double(bitgen_state); |
| 433 | V = next_double(bitgen_state); |
| 434 | X = pow(U, 1.0 / a); |
| 435 | Y = pow(V, 1.0 / b); |
| 436 | XpY = X + Y; |
| 437 | /* Reject if both U and V are 0.0, which is approx 1 in 10^106 */ |
| 438 | if ((XpY <= 1.0) && (U + V > 0.0)) { |
| 439 | if (XpY > 0) { |
| 440 | return X / XpY; |
| 441 | } else { |
| 442 | double logX = log(U) / a; |
| 443 | double logY = log(V) / b; |
| 444 | double logM = logX > logY ? logX : logY; |
| 445 | logX -= logM; |
| 446 | logY -= logM; |
| 447 | |
| 448 | return exp(logX - log(exp(logX) + exp(logY))); |
| 449 | } |
| 450 | } |
| 451 | } |
| 452 | } else { |
| 453 | Ga = random_standard_gamma(bitgen_state, a); |
| 454 | Gb = random_standard_gamma(bitgen_state, b); |
| 455 | return Ga / (Ga + Gb); |
| 456 | } |
| 457 | } |
| 458 | |
| 459 | double random_chisquare(bitgen_t *bitgen_state, double df) { |
| 460 | return 2.0 * random_standard_gamma(bitgen_state, df / 2.0); |
nothing calls this directly
no test coverage detected