double operator()(double nu)const{ nu_[which_] = nu; double ans = pri_->logp(nu); if(!std::isfinite(ans)) return ans; ans += dirichlet_loglike(nu_, 0, 0, sumlog_, nobs_); return ans; }
double PDM::loglike(const Vector &Nu_columns) const { Matrix Nu(dim(), dim(), Nu_columns.data()); const Matrix &sumlog(suf()->sumlog()); double n = suf()->n(); double ans = 0; for (uint i = 0; i < nrow(Nu); ++i) ans += dirichlet_loglike(Nu.row(i), 0, 0, sumlog.row(i), n); return ans; }
//====================================================================== double DirichletModel::Loglike(const Vector &nu, Vector &g, Matrix &h, uint nd) const { /* returns log likelihood for the parameters of a Dirichlet distribution with sufficient statistic sumlogpi(lo..hi). If pi(1)(lo..hi)..pi(nobs)(lo..hi) are probability vectors, then sumlogpi(j) = sum_i log(pi(i,j)) if(nd>0) then the g(lo..hi) is filled with the gradient (with respect to nu). If nd>1 then hess(lo..hi)(lo..hi) is filled with the hessian (wrt nu). Otherwise the algorithm can be called with either g or hess = 0. */ const Vector &sumlogpi(suf()->sumlog()); double nobs = suf()->n(); Vector *G(nd > 0 ? &g : nullptr); Matrix *H(nd > 1 ? &h : nullptr); return dirichlet_loglike(nu, G, H, sumlogpi, nobs); }
double PDM::dloglike(const Vector &Nu_columns, Vector &g) const { Matrix Nu(dim(), dim(), Nu_columns.data()); const Matrix &sumlog(suf()->sumlog()); double n = suf()->n(); uint nr = nrow(Nu); Matrix G(nr, nr); Vector g_row(nr); double ans = 0; for (uint i = 0; i < nrow(Nu); ++i) { ans += dirichlet_loglike(Nu.row(i), &g_row, 0, sumlog.row(i), n); G.row(i) = g_row; } G = G.transpose(); g.assign(G.begin(), G.end()); // need to check that g is vectorized in the right way.. virtual // functions might expect columns instead of rows. return ans; }