double PoissonGammaModel::Loglike(const Vector &ab, Vector &g, Matrix &H, uint nd) const { if (ab.size() != 2) { report_error("Wrong size argument."); } double a = ab[0]; double b = ab[1]; const std::vector<Ptr<PoissonData> > &data(dat()); int nobs = data.size(); // Initialize ans with the part that does not depend on the data. double ans = nobs * (a * log(b) - lgamma(a)); // If derivatives are requested fill in g and H with the parts // that don't depend on the data. if (nd > 0) { g[0] = nobs * (-digamma(a) + log(b)); g[1] = nobs * a / b; if (nd > 1) { H(0, 0) = -nobs * trigamma(a); H(1, 0) = nobs / b; H(0, 1) = nobs / b; H(1, 1) = -nobs * a / (b * b); } } for (int i = 0; i < nobs; ++i) { double apy = a + data[i]->number_of_events(); double npb = b + data[i]->number_of_trials(); ans += lgamma(apy) - apy * log(npb); if (nd > 0) { g[0] += digamma(apy) - log(npb); g[1] -= apy / (npb); if (nd > 1) { H(0, 0) += trigamma(apy); H(1, 0) -= 1.0 / npb; H(0, 1) -= 1.0 / npb; H(1, 1) += apy / (npb * npb); } } } return ans; }
double BetaBinomialModel::Loglike( const Vector &ab, Vec &g, Mat &h, uint nd)const{ if (ab.size() != 2) { report_error("Wrong size argument."); } double a = ab[0]; double b = ab[1]; if(a <= 0 || b <= 0) return BOOM::negative_infinity(); const std::vector<Ptr<BinomialData> > &data(dat()); int nobs = data.size(); double ans = 0; if (nd > 0) { g[0] = nobs * (digamma(a+b) - digamma(a)); g[1] = nobs * (digamma(a+b) - digamma(b)); if (nd > 1) { h(0, 0) = nobs * (trigamma(a+b) - trigamma(a)); h(1, 1) = nobs * (trigamma(a+b) - trigamma(b)); h(0, 1) = h(1, 0) = nobs * trigamma(a+b); } } for(int i = 0; i < nobs; ++i){ int y = data[i]->y(); int n = data[i]->n(); ans += logp(n, y, a, b); if (nd > 0) { double psin = digamma(a + b + n); g[0] += digamma(a + y) - psin; g[1] += digamma(b + n - y) - psin; if (nd > 1) { double trigamma_n = trigamma(a + b + n); h(0, 0) += trigamma(a + y) - trigamma_n; h(1, 1) += trigamma(b + n - y) - trigamma_n; h(0, 1) -= trigamma_n; h(1, 0) -= trigamma_n; } } } return ans; }