static int multinomial_rng(double *out, gsl_rng *r, apop_model* est){ Nullcheck_mp(est, 1); double * p = est->parameters->vector->data; //the trick where we turn the params into a p-vector int N = p[0]; if (est->parameters->vector->size == 2) { *out = gsl_ran_binomial_knuth(r, 1-gsl_vector_get(est->parameters->vector, 1), N); out[1] = N-*out; goto done; } //else, multinomial //cut/pasted/modded from the GSL. Copyright them. p[0] = 1 - (apop_sum(est->parameters->vector)-N); double sum_p = 0.0; int sum_n = 0; for (int i = 0; i < est->parameters->vector->size; i++) { out[i] = (p[i] > 0) ? gsl_ran_binomial (r, p[i] / (1 - sum_p), N - sum_n) : 0; sum_p += p[i]; sum_n += out[i]; } done: p[0] = N; return 0; }
double test_binomial_huge_knuth (void) { return gsl_ran_binomial_knuth (r_global, 0.3, 5500); }