// Args: // probs: A vector of probabilities to be evaluated. If no // derivatives are desired then probs can either match the // dimension of nu(), in which case it must sum to 1, or its // dimension must be one less, in which case its sum must be // non-negative but can't exceed 1. Element 0 is assumed to be // the function of the other elements, so that probs0 = 1 - // sum(probs). If derivatives are desired then probs.size() // must be nu().size() - 1. // gradient: The derivative of the unconstrained elements of // probs. This is only accessed if nderivs > 0. It will be // resized if needed, so that its dimension is one less than the // dimension of nu(). // Hessian: Second derivative of logp with respect to the free // elements of probs (i.e. not the first one). This matrix is // only accessed if nderiv > 1, in which case it will be resized. // nderiv: The number of derivatives desired. double DirichletModel::Logp(const Vector &probs, Vector &gradient, Matrix &Hessian, uint nderiv) const { // Because sum(p)=1, there are only p.size()-1 free elements in p. // The constraint is enforced by expressing the first element of p // as a function of the other variables. The corresponding elements // in g and h are zeroed. if (probs.size() == nu().size() && nderiv == 0) { return ddirichlet(probs, nu(), true); } else if (probs.size() + 1 != nu().size()) { report_error( "probs is the wrong size in DirichletModel::Logp. " "Its dimension should be one less than nu().size()"); } const Vector &n(nu()); double p0 = 1 - sum(probs); Vector full_probs(probs.size() + 1); full_probs[0] = p0; VectorView(full_probs, 1) = probs; double ans = ddirichlet(full_probs, n, true); if (nderiv > 0) { gradient.resize(probs.size()); for (int i = 0; i < probs.size(); ++i) { gradient[i] = (n[i + 1] - 1) / probs[i] - (n[0] - 1) / p0; if (nderiv > 1) { Hessian.resize(probs.size(), probs.size()); for (int j = 0; j < probs.size(); ++j) { Hessian(i, j) = -(n[0] - 1) / square(p0) - (i == j ? (1.0 - n[i + 1]) / square(probs[i]) : 0.0); } } } } return ans; }
double MCS::logpri()const{ const Mat &Nu(this->Nu()); const Mat &Q(mod_->Q()); assert(Nu.same_dim(Q)); uint S = Nu.nrow(); double ans = 0; for(uint s=0; s<S; ++s){ ans += ddirichlet(Q.row(s), Nu.row(s), true); } if(mod_->pi0_fixed()) return ans; check_pi0(); ans += ddirichlet(mod_->pi0(), this->nu(), true); return ans; }
double PDM::pdf(const Matrix &Pi, bool logscale) const { double ans(0); for (uint i = 0; i < Pi.nrow(); ++i) { ans += ddirichlet(Pi.row(i), Nu().row(1), true); } return logscale ? ans : exp(ans); }
double DM::pdf(const Vector &pi, bool logscale) const { return ddirichlet(pi, nu(), logscale); }