// 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;
 }
Exemple #2
0
  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;
  }
Exemple #3
0
 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);
 }