| 753 | } |
| 754 | |
| 755 | RAND_INT_TYPE random_binomial_inversion(bitgen_t *bitgen_state, RAND_INT_TYPE n, |
| 756 | double p, binomial_t *binomial) { |
| 757 | double q, qn, np, px, U; |
| 758 | RAND_INT_TYPE X, bound; |
| 759 | |
| 760 | if (!(binomial->has_binomial) || (binomial->nsave != n) || |
| 761 | (binomial->psave != p)) { |
| 762 | binomial->nsave = n; |
| 763 | binomial->psave = p; |
| 764 | binomial->has_binomial = 1; |
| 765 | binomial->q = q = 1.0 - p; |
| 766 | binomial->r = qn = exp(n * log(q)); |
| 767 | binomial->c = np = n * p; |
| 768 | binomial->m = bound = (RAND_INT_TYPE)MIN(n, np + 10.0 * sqrt(np * q + 1)); |
| 769 | } else { |
| 770 | q = binomial->q; |
| 771 | qn = binomial->r; |
| 772 | np = binomial->c; |
| 773 | bound = binomial->m; |
| 774 | } |
| 775 | X = 0; |
| 776 | px = qn; |
| 777 | U = next_double(bitgen_state); |
| 778 | while (U > px) { |
| 779 | X++; |
| 780 | if (X > bound) { |
| 781 | X = 0; |
| 782 | px = qn; |
| 783 | U = next_double(bitgen_state); |
| 784 | } else { |
| 785 | U -= px; |
| 786 | px = ((n - X + 1) * p * px) / (X * q); |
| 787 | } |
| 788 | } |
| 789 | return X; |
| 790 | } |
| 791 | |
| 792 | int64_t random_binomial(bitgen_t *bitgen_state, double p, int64_t n, |
| 793 | binomial_t *binomial) { |
no test coverage detected