double wishpdfln(const MatrixXd &X, const MatrixXd &Sigma, const double df) { double ldX = logdet(X); double ldS = logdet(Sigma); int n = X.rows(); return (0.5*(-df*ldS - Sigma.selfadjointView<Lower>().llt().solve(X).trace() + (df-n-1.0)*ldX - df*n*log_2) - mvgammaln(0.5*df,n)); }
// Not a general pseudowishpdfln (because L*Diff*L' at a single locus has rank 1 double pseudowishpdfln(const MatrixXd &X, const MatrixXd &Sigma, const int df) { int rank = 1; double ldX = pseudologdet(X,rank); double ldS = logdet(Sigma); int n = X.rows(); int q = (df<n) ? df : n; return (0.5*(-df*ldS - Sigma.selfadjointView<Lower>().llt().solve(X).trace() + (df-n-1.0)*ldX - df*n*log_2 - df*(n-q)*log_pi) - mvgammaln(0.5*df,q)); }
void EEMS::update_sigma2( ) { double nowdf_2 = 0.5 * nowdf; nowll_atfixdf += nowtriDeltaQD/nowsigma2 + nmin1*log(nowsigma2); nowpi += (params.sigmaShape_2+1.0)*log(nowsigma2) + params.sigmaScale_2/nowsigma2; nowsigma2 = draw.rinvgam( params.sigmaShape_2 + nowdf_2*nmin1, params.sigmaScale_2 + nowdf_2*nowtriDeltaQD ); nowll_atfixdf -= nowtriDeltaQD/nowsigma2 + nmin1*log(nowsigma2); nowpi -= (params.sigmaShape_2+1.0)*log(nowsigma2) + params.sigmaScale_2/nowsigma2; nowll = nowdf_2 * nowll_atfixdf + nmin1*nowdf_2*log(nowdf_2) - mvgammaln(nowdf_2,nmin1) - n_2*ldLDLt; }
/* This function implements the computations described in the Section S1.3 in the Supplementary Information, "Computing the Wishart log likelihood l(k, m, q, sigma2)", and I have tried to used similar notation For example, MatrixXd X = lu.solve(T) is equation (S20) since lu is the decomposition of (B*C - W) and T is B * inv(W) Returns wishpdfln( -L*D*L' ; - (sigma2/df) * L*Delta(m,q)*L' , df ) */ double EEMS::EEMS_wishpdfln(const MatrixXd &Binv, const VectorXd &W, const double sigma2, const double df, double &triDeltaQD, double &ll_atfixdf) const { double df_2 = 0.5 * df; MatrixXd iDelta = Binv.topLeftCorner(o,o); MatrixXd DiDDi = iDelta * JtDobsJ * iDelta; double oDinvo = iDelta.sum(); // oDinvo = 1'*inv(Delta)*1 double oDiDDi = DiDDi.sum(); // oDiDDi = 1'*inv(Delta)*D*inv(D)*1 MatrixXd Q = MatrixXd::Constant(o,o,-1.0/oDinvo); Q *= iDelta; Q += cvec.asDiagonal(); MatrixXd iDeltaQ = iDelta*Q; double ldetDinvQ = pseudologdet(-1.0 * iDeltaQ,o-1); // ldetDinvQ = logDet(-inv(Delta)*Q) triDeltaQD = (iDeltaQ*JtDobsJ).trace(); // triDeltaQD = tr(inv(Delta)*Q*D) ll_atfixdf = ldetDinvQ - triDeltaQD/sigma2 - nmin1*log(sigma2) - ldDiQ; return (df_2*ll_atfixdf + nmin1*df_2*log(df_2) - mvgammaln(df_2,nmin1) - n_2*ldLDLt); }
void EEMS::propose_df(Proposal &proposal,const MCMC &mcmc) { proposal.move = DF_UPDATE; proposal.newtriDeltaQD = nowtriDeltaQD; proposal.newll_atfixdf = nowll_atfixdf; proposal.newpi = -Inf; proposal.newll = -Inf; // EEMS is initialized with df = nIndiv // Keep df = nIndiv for the first mcmc.numBurnIter/2 iterations // This should make it easier to move in the parameter space // since the likelihood is proportional to 0.5 * pdf * ll_atfixdf if (mcmc.currIter > (mcmc.numBurnIter/2)) { double newdf = draw.rnorm(nowdf,params.dfProposalS2); double newdf_2 = 0.5 * newdf; if ( (newdf>params.dfmin) && (newdf<params.dfmax) ) { proposal.newdf = newdf; proposal.newpi = nowpi + log(nowdf) - log(newdf); proposal.newll = newdf_2*nowll_atfixdf + nmin1*newdf_2*log(newdf_2) - mvgammaln(newdf_2,nmin1) - n_2*ldLDLt; } } }