/* The gradient of the NLL w.r.t. each free parameter in p. */ static void hyperexp_complete_gradient(double *p, int np, void *dptr, double *dp) { struct hyperexp_data *data = (struct hyperexp_data *) dptr; ESL_HYPEREXP *h = data->h; double pdf; int i,k; int pidx; hyperexp_unpack_paramvector(p, np, h); esl_vec_DSet(dp, np, 0.); for (i = 0; i < data->n; i++) { /* FIXME: I think the calculation below may need to be done * in log space, to avoid underflow errors; see complete_binned_gradient() */ /* Precalculate q_k PDF_k(x) terms, and their sum */ for (k = 0; k < h->K; k++) h->wrk[k] = h->q[k] * esl_exp_pdf(data->x[i], h->mu, h->lambda[k]); pdf = esl_vec_DSum(h->wrk, h->K); pidx = 0; if (! h->fixmix) { for (k = 1; k < h->K; k++) /* generic d/dQ solution for mixture models */ dp[pidx++] -= h->wrk[k]/pdf - h->q[k]; } for (k = 0; k < h->K; k++) if (! h->fixlambda[k]) dp[pidx++] -= (1.-h->lambda[k]*(data->x[i]-h->mu))*h->wrk[k]/pdf; /* d/dw */ } }
/* Function: esl_hxp_pdf() * * Purpose: Returns the probability density function $P(X=x)$ for * quantile <x>, given hyperexponential parameters <h>. */ double esl_hxp_pdf(double x, ESL_HYPEREXP *h) { double pdf = 0.; int k; if (x < h->mu) return 0.; for (k = 0; k < h->K; k++) pdf += h->q[k] * esl_exp_pdf(x, h->mu, h->lambda[k]); return pdf; }
/* Function: esl_exp_generic_pdf() * Incept: SRE, Thu Aug 25 07:58:34 2005 [St. Louis] * * Purpose: Generic-API version of PDF. */ double esl_exp_generic_pdf(double x, void *params) { double *p = (double *) params; return esl_exp_pdf(x, p[0], p[1]); }