//---------------------------------------------------------------------- // log posterior if R(i_,j_) is replaced by r. performs work needed // for slice sampling in draw_R(i,j) double SepStratSampler::logp_slice_R(double r){ set_R(r); fill_siginv(false); // false means we need to compute Rinv const Spd & Siginv(cand_); double ans = .5 * n_ * logdet(Siginv); // positive .5 ans += -.5 * traceAB(Siginv, sumsq_); ans += Rpri_->logp(R_); // skip the jacobian because it only has products of sigma^2's in it return ans; }
double ZMMM::loglike()const{ const double log2pi = 1.83787706641; double dim = mu_.size(); double n = suf()->n(); const Vec ybar = suf()->ybar(); const Spd sumsq = suf()->center_sumsq(); double qform = n*(siginv().Mdist(ybar)); qform+= traceAB(siginv(), sumsq); double nc = 0.5*n*( -dim*log2pi + ldsi()); double ans = nc - .5*qform; return ans; }
double WeightedMvnModel::loglike(const Vector &mu_siginv_triangle)const{ const double log2pi = 1.83787706641; const ConstVectorView mu(mu_siginv_triangle, 0, dim()); SpdMatrix siginv(dim()); Vector::const_iterator it = mu_siginv_triangle.begin() + dim(); siginv.unvectorize(it, true); double ldsi = siginv.logdet(); double sumlogw = suf()->sumlogw(); const SpdMatrix sumsq = suf()->center_sumsq(); double n = suf()->n(); double ans = n*.5*(log2pi + ldsi) + dim() * .5 *sumlogw; ans -= -.5*traceAB(siginv, suf()->center_sumsq(mu)); return ans; }
//---------------------------------------------------------------------- // returns the log posterior distribution if element i_ of 1/sd_^2 // is replaced by ivar. supports slice sampler in draw_sigsq(i_); double SepStratSampler::logp_slice_ivar(double ivar){ double ans = sinv_pri_[i_]->logp(ivar); // prior on ivar ans += .5 * n_ * log(ivar); // determinant sd_[i_] = 1.0/sqrt(ivar); fill_siginv(true); const Spd & Siginv(cand_); ans += -.5 * traceAB(Siginv, sumsq_); // exponential double logsd = log(sd_[i_]); // jacobian Sigma -> S int dim = sd_.size(); ans += dim * logsd; // see notes in "logprior" member function ans += -3 * logsd; // jacobian S -> ivar return ans; }
double WishartModel::Loglike(const Vector &sumsq_triangle_nu, Vector &g, uint nd)const{ const double log2 = 0.69314718055994529; const double logpi = 1.1447298858494002; int k=dim(); SpdParams Sumsq_arg(dim()); Vector::const_iterator it = Sumsq_arg.unvectorize(sumsq_triangle_nu, true); double nu = *it; const SpdMatrix &SS(Sumsq_arg.var()); if(nu <k) return negative_infinity(); double ldSS = 0; bool ok=true; ldSS = SS.logdet(ok); if(!ok) return negative_infinity(); double n = suf()->n(); double sumldw = suf()->sumldw(); const SpdMatrix &sumW(suf()->sumW()); double tab = traceAB(SS, sumW); double tmp1(0), tmp2(0); for(int i = 1; i<=k; ++i){ double tmp = .5*(nu-i+1); tmp1+= lgamma(tmp); if(nd>0) tmp2+= digamma(tmp); } double ans = .5*( n*(-nu*k*log2 - .5*k*(k-1)*logpi -2*tmp1 + nu*ldSS) +(nu-k-1)*sumldw - tab); if(nd>0){ double dnu = .5*( n*(-k*log2 - tmp2+ldSS) + sumldw); SpdMatrix SSinv(SS.inv()); int m=0; for(int i=0; i<k; ++i){ for(int j=0; j<=i; ++j){ g[m] = .5*n*nu * (i==j? SSinv(i,i) : 2*SSinv(i,j)); g[m] -= .5*(i==j ? sumW(i,i) : 2* sumW(i,j)); ++m; }} g[m] = dnu; } return ans; }