/* Sample-based estimate of Normalization constant Assume the normalized distribution P(x), and a sample-generating distribution p(x), such that: P(x) = zp(x) We would like to find z. The domain of x here is the 4-simplex with volume V. Each sample point is centered around a sub-volume, where all N sub-volumes constitute V (a 'tesselation' if you like). One notional definition of "fair sample points" is that one can estimate the total mass of the density in the sub-volume as volume times density, where the estimate of the density over that subvolume is taken to be constant and having the value of the density at that point. Taking total mass to be 1, each sub-volume contributes 1/N mass. And, volume = mass/density, so by summing over sub-volumes, we have: sum_i{(1/N) / P(x_i)} = V sum_i{(1/N) / (zp(x_i)} = V (1/Nz) sum_i{1/p(x_i)} = V z = (1/NV) sum_i{1/p(x_i)} ~ (1/N) sum_i{1/p(x_i)} */ void populate_points(struct wpoint *points, unsigned npoints, double *alpha_dist, double *alpha_weights, gsl_rng *rand, const char *name, double *dist_norm) { struct wpoint *s, *se = points + npoints; /* double ln_dist_norm = NAN; */ double dn = 0; for (s = points; s != se; ++s) { gsl_ran_dirichlet(rand, NUCS, alpha_dist, s->x); s->d = gsl_ran_dirichlet_pdf(NUCS, alpha_dist, s->x); s->o = gsl_ran_dirichlet_pdf(NUCS, alpha_weights, s->x); s->ln_d = gsl_ran_dirichlet_lnpdf(NUCS, alpha_dist, s->x); s->ln_o = gsl_ran_dirichlet_lnpdf(NUCS, alpha_weights, s->x); strcpy(s->dist, name); s->num_samples = npoints; dn += 1.0 / s->d; /* ln_dist_norm = safe_sum(ln_dist_norm, -s->ln_d); */ } /* ln_dist_norm -= gsl_sf_log(npoints); */ /* *dist_norm = gsl_sf_exp(ln_dist_norm); */ dn /= (double)npoints; *dist_norm = dn; }
void test_dirichlet(void){ double alpha[SIZE] = { .4, .9, .4, .2 }; double theta[SIZE] = { 0.0, 0.0, 0.0, 0.0 }; double prob; int i; gsl_ran_dirichlet (rng, SIZE, alpha, theta); printf("gsl_ran_dirichlet\t"); print_double_array(alpha, SIZE); printf("\t"); print_double_array(theta, SIZE); printf("\n"); theta[0] = 0.107873072217; theta[1] = 0.518033738502; theta[2] = 0.220000000209; theta[3] = 0.154093189072; /* theta and alpha flipped in perl interface */ prob = gsl_ran_dirichlet_pdf (SIZE, alpha, theta); printf("gsl_ran_dirichlet_pdf\t"); print_double_array(theta, SIZE); printf("\t"); print_double_array(alpha, SIZE); printf("\t%.12f\n", prob); prob = gsl_ran_dirichlet_lnpdf (SIZE, alpha, theta); printf("gsl_ran_dirichlet_lnpdf\t"); print_double_array(theta, SIZE); printf("\t"); print_double_array(alpha, SIZE); printf("\t%.12f\n", prob); }
CAMLprim value ml_gsl_ran_dirichlet_lnpdf(value alpha, value theta) { const size_t K = Double_array_length(alpha); double r ; if(Double_array_length(theta) != K) GSL_ERROR("alpha and theta must have same size", GSL_EBADLEN); r = gsl_ran_dirichlet_lnpdf(K, Double_array_val(alpha), Double_array_val(theta)); return copy_double(r); }
double logpdf_Dirichlet(long n, double *a, double *x) { return gsl_ran_dirichlet_lnpdf(n, a, x); }
double gsl_ran_dirichlet_pdf (const size_t K, const double alpha[], const double theta[]) { return exp (gsl_ran_dirichlet_lnpdf (K, alpha, theta)); }