Example #1
0
// NHPP_lik with median Gamma Rates
std::vector<double> PyRateC_NHPP_lik(
	bool useDA,
	std::vector <int> ind, 
	std::vector<double> ts, 
  std::vector<double> te,
	double qRate,
  std::vector<double> gammaRates,
  double covPar,
  double extRate) {

	std::vector<int> indNHPP, indExtent;
	for(size_t iI=0; iI<ind.size(); ++iI) {
		size_t iF = ind[iI];
		if(fossils[iF].back() == 0.) {
			indExtent.push_back(iF);
		} else {
			indNHPP.push_back(iF);
		}
	}

	// Compute for extent species
	std::vector<double> logLikExtent, logLikNHPP;
	if(useDA) {
		logLikExtent = processDataAugNHPP(indExtent, ts, qRate, extRate);
	} else {
		logLikExtent = PyRateC_HOMPP_lik(indExtent, ts, te, qRate, gammaRates, covPar, extRate);
	}

	logLikNHPP = processNHPPLikelihood(indNHPP, ts, te, qRate, gammaRates);
	
	// Merge results
	std::vector<double> logLik(fossils.size(), 0);
	for(size_t iL=0; iL<logLik.size(); ++iL) {
		logLik[iL] = logLikExtent[iL] + logLikNHPP[iL] ;
	}

	return logLik;
}
Example #2
0
//extern "C"{
SEXP sampler(
		/*prior params*/
		double *a1, double *a2, /* prior for tau2*/
		double *b1, double *b2, /* prior for sigma2 */
		double *alphaW, double *betaW, /* prior for w */
		double *v0, /* gamma */
		double *varKsi, /*vector length qKsiUpdate!!*/

		/*model dimensions*/
		int *q, /*length of ksi*/
		int *qKsiUpdate, /*length of updated ksi*/
		int *p,   /*length alpha*/
		int *pPen,   /*length penalized alpha/ tau2 / gamma*/
		int *n,   /* no. of  obs.*/
		int *d,   /*vector (length p): group sizes*/

		/*parameter vectors*/
		double *beta,
		double *alpha,
		double *ksi,
		double *tau2,
		double *gamma,
		double *sigma2,
		double *w,

		/* (precomputed) constants */
		double *y,
		double *X,
		double *G,
		double *scale,
		double *offset,

		/*info about updateBlocks*/
		int *blocksAlpha,
		int *indA1Alpha,
		int *indA2Alpha,

		int *blocksKsi,
		int *indA1Ksi,
		int *indA2Ksi,

		/*MCMC parameters*/
		int *pcts,
		int *burnin,
		int *thin,
		int *totalLength,
		int *verbose,
		double *ksiDF,
		int *scaleMode,
		double *modeSwitching,
		int *family,
		double *acceptKsi,
		double *acceptAlpha,

		/*return matrices*/
		double *betaMatR,
		double *alphaMatR,
		double *ksiMatR,
		double *gammaMatR,
		double *probV1MatR,
		double *tau2MatR,
		double *sigma2MatR,
		double *wMatR,
		double *likMatR,
		double *logPostMatR
)
{
	// ############################################### //
	// ######## unwrap/initialize args ############### //
	// ############################################### //
	int pIncluded=0, i=0, j=0, startPen = *p-*pPen, qKsiNoUpdate = *q - *qKsiUpdate,
			save = 0, keep = *burnin,  nrv =1,  info=0,
			nSamp=(*totalLength-*burnin)/(*thin), oneInt = 1, zeroInt = 0;

	double *p1 =Calloc(*pPen, double);

	double infV  = 100000, oneV = 1.0, zeroV = 0.0, minusOneV =-1.0;
	double *one=&oneV, *zero=&zeroV, *minusOne=&minusOneV, *inf=&infV, acceptance=0;
	double invSigma2 = 1 / *sigma2, sqrtInvSigma2 = R_pow(invSigma2, 0.5);
	double  *penAlphaSq, *alphaLong, *varAlpha, *priorMeanAlpha, *modeAlpha, *offsetAlpha;;
	penAlphaSq	= Calloc(*pPen, double);
	for(int i=*p-*pPen; i<*p; i++) penAlphaSq[i- *p + *pPen] = R_pow(alpha[i], 2.0);
	alphaLong = Calloc(*q, double);
	F77_CALL(dgemm)("N","N", q, &oneInt, p, one, G, q, alpha, p, zero, alphaLong, q);
	varAlpha = Calloc(*p, double);
	for(int i=0; i<startPen; i++) varAlpha[i] = *inf; /*unpenalized*/
	for(int i=startPen; i<*p; i++) varAlpha[i] = tau2[i-startPen]*gamma[i-startPen]; /*penalized*/
	priorMeanAlpha	= Calloc(*p, double);
	setToZero(priorMeanAlpha, *p);
	modeAlpha = Calloc(*p, double);
	F77_CALL(dcopy)(p, alpha, &oneInt, modeAlpha, &oneInt);
	offsetAlpha = Calloc(*n, double);
	F77_CALL(dcopy)(n, offset, &oneInt, offsetAlpha, &oneInt);


	double *ksiUpdate, *priorMeanKsi, *modeKsi,  *offsetKsi;
	int safeQKsiUpdate = imax2(1, *qKsiUpdate);
	//ksiUpdate contains the last qKsiUpdate elements in ksi
	ksiUpdate = Calloc(safeQKsiUpdate, double);
	F77_CALL(dcopy)(&safeQKsiUpdate, &ksi[*q-safeQKsiUpdate], &oneInt, ksiUpdate, &oneInt);
	priorMeanKsi = Calloc(safeQKsiUpdate, double);
	setToZero(priorMeanKsi, safeQKsiUpdate);
	for(int i=0; i<*qKsiUpdate; i++) priorMeanKsi[i] = 1.0;
	modeKsi = Calloc(safeQKsiUpdate, double);
	setToZero(modeKsi, safeQKsiUpdate);
	for(int i=0; i<*qKsiUpdate; i++) modeKsi[i] = ksi[i+qKsiNoUpdate];
	// offsetKsi = offset + X_d=1*alpha : use lin.predictor of grps with ksi==1 as offset
	offsetKsi = Calloc(*n, double);
	F77_CALL(dcopy)(n, offset, &oneInt, offsetKsi, &oneInt);
	if(qKsiNoUpdate < *q){
		if(qKsiNoUpdate > 0){
			F77_CALL(dgemm)("N","N", n, &oneInt, &qKsiNoUpdate, one, X, n, alpha, &qKsiNoUpdate, one, offsetKsi, n);
		}
	}

	double	*eta, *resid, rss, *XAlpha, *XKsiUpdate, *etaOffset;
	eta	= Calloc(*n, double);
	F77_CALL(dgemm)("N","N", n, &oneInt, q, one, X, n, beta, q, zero, eta, n);
	resid = Calloc(*n, double);
	rss = 0;
	for(int i=0; i<*n; i++) {
		resid[i] = y[i]-eta[i] - offset[i];
		rss += R_pow(resid[i], 2.0);
	}
	XAlpha = Calloc(*p * (*n), double);
	updateXAlpha(XAlpha, X, G, ksi, q, qKsiUpdate, p, n);
	XKsiUpdate = Calloc( *n * safeQKsiUpdate, double);
	setToZero(XKsiUpdate, *n * safeQKsiUpdate);
	if(qKsiNoUpdate < *q){
		updateXKsi(XKsiUpdate, X, alphaLong, q, &qKsiNoUpdate, n);
	}
	etaOffset	= Calloc(*n, double);
	for(int i=0; i<*n; i++) etaOffset[i] = eta[i]+offset[i];


	// ############################################################ //
	// ######## set up blocks for blockwise updates ############### //
	// ############################################################ //

	XBlockQR *AlphaBlocks = Calloc(*blocksAlpha, XBlockQR);
	XBlockQR *KsiBlocks = Calloc(*blocksKsi, XBlockQR);


	for(int i=0; i < *blocksAlpha; i++){
		(AlphaBlocks[i]).indA1 = indA1Alpha[i];
		(AlphaBlocks[i]).indA2 = indA2Alpha[i];

		(AlphaBlocks[i]).qA = (AlphaBlocks[i]).indA2 - (AlphaBlocks[i]).indA1 + 1;
		(AlphaBlocks[i]).qI = *p - (AlphaBlocks[i]).qA;

		(AlphaBlocks[i]).qraux = Calloc((AlphaBlocks[i]).qA, double);
		setToZero((AlphaBlocks[i]).qraux, (AlphaBlocks[i]).qA);
		(AlphaBlocks[i]).work = Calloc((AlphaBlocks[i]).qA, double);
		setToZero((AlphaBlocks[i]).work, (AlphaBlocks[i]).qA);
		(AlphaBlocks[i]).pivots = Calloc((AlphaBlocks[i]).qA, int);
		for(int j=0; j < (AlphaBlocks[i]).qA; j++) (AlphaBlocks[i]).pivots[j] = 0;

		(AlphaBlocks[i]).coefI = Calloc((AlphaBlocks[i]).qI, double);
		setToZero((AlphaBlocks[i]).coefI, (AlphaBlocks[i]).qI);

		(AlphaBlocks[i]).Xa = Calloc(((AlphaBlocks[i]).qA + *n) * (AlphaBlocks[i]).qA, double);
		setToZero((AlphaBlocks[i]).Xa, ((AlphaBlocks[i]).qA + *n) * (AlphaBlocks[i]).qA);
		(AlphaBlocks[i]).Xi = Calloc(*n * (AlphaBlocks[i]).qI, double);
		setToZero((AlphaBlocks[i]).Xi, *n * (AlphaBlocks[i]).qI );
		(AlphaBlocks[i]).ya = Calloc(((AlphaBlocks[i]).qA + *n), double);
		F77_CALL(dcopy)(n, y, &nrv, (AlphaBlocks[i]).ya, &nrv);
		setToZero((AlphaBlocks[i]).ya + *n, (AlphaBlocks[i]).qA);

		(AlphaBlocks[i]).m = Calloc((AlphaBlocks[i]).qA, double);
			setToZero((AlphaBlocks[i]).m, (AlphaBlocks[i]).qA);
		(AlphaBlocks[i]).err = Calloc((AlphaBlocks[i]).qA, double);
			setToZero((AlphaBlocks[i]).err, (AlphaBlocks[i]).qA);

	}
	initializeBlocksQR(AlphaBlocks, XAlpha, *n, *blocksAlpha, *p, varAlpha, scale);


	if(*qKsiUpdate > 0){
		for(int i=0; i < *blocksKsi; i++){
			(KsiBlocks[i]).indA1 = indA1Ksi[i];
			(KsiBlocks[i]).indA2 = indA2Ksi[i];

			(KsiBlocks[i]).qA = (KsiBlocks[i]).indA2 - (KsiBlocks[i]).indA1 + 1;
			(KsiBlocks[i]).qI = *qKsiUpdate - (KsiBlocks[i]).qA;

			(KsiBlocks[i]).qraux = Calloc((KsiBlocks[i]).qA, double);
			setToZero((KsiBlocks[i]).qraux, (KsiBlocks[i]).qA);
			(KsiBlocks[i]).work = Calloc((KsiBlocks[i]).qA, double);
			setToZero((KsiBlocks[i]).work, (KsiBlocks[i]).qA);
			(KsiBlocks[i]).pivots = Calloc((KsiBlocks[i]).qA, int);
			for(int j=0; j < (KsiBlocks[i]).qA; j++) (KsiBlocks[i]).pivots[j] = 0;

			(KsiBlocks[i]).coefI = Calloc((KsiBlocks[i]).qI, double);
			setToZero((KsiBlocks[i]).coefI, (KsiBlocks[i]).qI);

			(KsiBlocks[i]).Xa = Calloc(((KsiBlocks[i]).qA + *n) * (KsiBlocks[i]).qA, double);
			setToZero((KsiBlocks[i]).Xa, ((KsiBlocks[i]).qA + *n) * (KsiBlocks[i]).qA);
			(KsiBlocks[i]).Xi = Calloc(*n * (KsiBlocks[i]).qI, double);
			setToZero((KsiBlocks[i]).Xi, *n * (KsiBlocks[i]).qI );
			(KsiBlocks[i]).ya = Calloc(((KsiBlocks[i]).qA + *n), double);
			F77_CALL(dcopy)(n, y, &nrv, (KsiBlocks[i]).ya, &nrv);
			setToZero((KsiBlocks[i]).ya + *n, (KsiBlocks[i]).qA);

			(KsiBlocks[i]).m = Calloc((KsiBlocks[i]).qA, double);
			setToZero((KsiBlocks[i]).m, (KsiBlocks[i]).qA);
			(KsiBlocks[i]).err = Calloc((KsiBlocks[i]).qA, double);
			setToZero((KsiBlocks[i]).err, (KsiBlocks[i]).qA);
		}
		initializeBlocksQR(KsiBlocks, XKsiUpdate, *n, *blocksKsi, *qKsiUpdate, varKsi, scale);
	}

	// ############################################### //
	// ########     start sampling     ############### //
	// ############################################### //


#ifdef Win32
	R_FlushConsole();
#endif
	/* sampling */
	GetRNGstate();
	for(i = 0; i < *totalLength; i++)
	{
		debugMsg("\n###########################################\n\n");
		//update alpha
		{
			//update varAlpha
			for(j=startPen; j<*p; j++) varAlpha[j] = tau2[j-startPen] * gamma[j-startPen];
			//update alpha
			updateCoefQR(y, XAlpha, AlphaBlocks,
					*blocksAlpha,
					alpha,
					varAlpha, *p,
					scale,
					*n, nrv, oneInt, info, *minusOne, *zero, *one, 1, priorMeanAlpha,
					*family, modeAlpha, eta, acceptAlpha, offsetAlpha, *modeSwitching, zeroInt);
		}


		//update ksi
		if(qKsiNoUpdate < *q){

			//update alphaLong = G %*% alpha
			F77_CALL(dgemm)("N","N", q, &oneInt, p, one, G, q, alpha, p, zero, alphaLong, q);

			//update design for ksi
			updateXKsi(XKsiUpdate, X, alphaLong, q, &qKsiNoUpdate, n);

			//update offsetKsi
			if(qKsiNoUpdate > 0){
				F77_CALL(dcopy)(n, offset, &oneInt, offsetKsi, &oneInt);
				F77_CALL(dgemm)("N","N", n, &oneInt, &qKsiNoUpdate, one, X, n, alpha, &qKsiNoUpdate, one, offsetKsi, n);
			}

			for(j = 0; j < *qKsiUpdate; j++){
				priorMeanKsi[j] = sign(  1/(1 + exp(-2*ksiUpdate[j]/varKsi[j])) - runif(0,1) );
			}


			if(*ksiDF>0){
				updateVarKsi(ksiUpdate, varKsi, ksiDF, priorMeanKsi, qKsiNoUpdate, *q);
			}


			updateCoefQR(y, XKsiUpdate, KsiBlocks,
					*blocksKsi,
					ksiUpdate, varKsi, *qKsiUpdate,
					scale,
					*n, nrv, oneInt, info, *minusOne, *zero, *one, 1, priorMeanKsi,
					*family, modeKsi, eta, acceptKsi, offsetKsi, *modeSwitching, *scaleMode);
			//write back to ksi
			F77_CALL(dcopy)(qKsiUpdate, ksiUpdate, &oneInt, &ksi[*q-*qKsiUpdate], &oneInt);


			//rescale ksi, alpha & put back in ksiUpdate
			if(*scaleMode > 0){
				rescaleKsiAlpha(ksi, alpha, varKsi, tau2, G, d, *p, *q, qKsiNoUpdate, *pPen, *scaleMode, modeAlpha, modeKsi, *family);
				F77_CALL(dcopy)(qKsiUpdate, &ksi[*q-*qKsiUpdate], &oneInt, ksiUpdate, &oneInt);
			}

			//update XAlpha
			updateXAlpha(XAlpha, X, G, ksi, q, qKsiUpdate, p, n);

			//update alphaLong = G %*% alpha
			F77_CALL(dgemm)("N","N", q, &oneInt, p, one, G, q, alpha, p, zero, alphaLong, q);

		} else {
			F77_CALL(dcopy)(q, alpha, &oneInt, alphaLong, &oneInt);
		}

		for(int i = *p-*pPen; i < *p; i++) penAlphaSq[i - *p + *pPen] = R_pow(alpha[i], 2.0);
		updateTau(penAlphaSq, gamma, tau2, *a1, *a2, *pPen);

		updateP1Gamma(penAlphaSq, tau2, p1, gamma, *v0, *w, *pPen);
		pIncluded = 0;
		for(j=0; j<*p - startPen; j++) pIncluded += (gamma[j] == 1.0);

		*w = rbeta( *alphaW + pIncluded, *betaW + *p - pIncluded );

		// update beta
		for(j = 0; j < *q; j++){
			beta[j] = alphaLong[j]*ksi[j];
		}

		//update eta, eta+offset
		F77_CALL(dgemm)("N", "N", n, &oneInt, q, one, X, n, beta, q, zero, eta, n);
		for(int i=0; i<*n; i++) etaOffset[i] = eta[i] + offset[i];

		//update sigma_eps
		if(*family == 0){
			//resid = y - eta - offset
			F77_CALL(dcopy)(n, y, &nrv, resid, &nrv);  //resid <- y
			F77_CALL(daxpy)(n, minusOne, etaOffset, &nrv, resid, &nrv); //resid <- resid - eta - offset

			//rss = resid'resid
			rss = F77_CALL(ddot)(n, resid, &oneInt, resid, &oneInt);

			//update sigma2
			invSigma2 = rgamma(*n/2 + *b1, 1/(rss/2 + *b2));
			sqrtInvSigma2 = R_pow(invSigma2, 0.5);
			scale[0] = sqrtInvSigma2;
			*sigma2 = 1 / invSigma2;
		}


		if(i >= *burnin){
			/* report progress */
			if(*verbose){
				for(j=0; j<9; j++){
					if(i == pcts[j]){
						Rprintf(".");
						#ifdef Win32
							R_FlushConsole();
						#endif
						break;
					}
				}
			}
			/* save samples*/
			if(i == keep){
				for(j = 0; j < *q; j++){
					(betaMatR)[save + j*nSamp] = beta[j];
					(ksiMatR)[save + j*nSamp] = ksi[j];
				}
				for(j=0; j < *p; j++){
					(alphaMatR)[save + j*nSamp] = alpha[j];
				}
				for(j=0; j < *pPen; j++){
					(tau2MatR)[save + j*nSamp] = tau2[j];
					(gammaMatR)[save + j*nSamp] = gamma[j];
					(probV1MatR)[save + j*nSamp] = p1[j];
				}
				(wMatR)[save] = *w;
				(sigma2MatR)[save] = *sigma2;
				likMatR[save] = logLik(y, etaOffset, *family, scale, *n);
				(logPostMatR)[save] = updateLogPost(y, 	alpha, varAlpha,
						ksi, varKsi, scale, *b1, *b2, gamma, *w, *alphaW, *betaW,
						tau2, *a1, *a2,	*n, *q, *p, *pPen, pIncluded, qKsiNoUpdate, priorMeanKsi, *family, likMatR[save]);
				keep = keep + *thin;
				save ++;
				R_CheckUserInterrupt();
			}
		} else {
			if(*verbose){
				if(i == (*burnin-1)){
					Rprintf("b");
					#ifdef Win32
						R_FlushConsole();
					#endif
				}
			}
		}
	} /* end for i*/

	PutRNGstate();

	if(*verbose) Rprintf(".");
	if(*family > 0) {
		acceptance = 0.0;
		for(j=0; j<*blocksAlpha; j++) acceptance += acceptAlpha[j];
		acceptance = 0.0;
		if(qKsiNoUpdate < *q){
			for(j=0; j<*blocksKsi; j++) acceptance += acceptKsi[j];
		}
	}

	Free(etaOffset); Free(XKsiUpdate); Free(XAlpha);  Free(resid); Free(eta);
	Free(offsetKsi); Free(modeKsi); Free(priorMeanKsi);	Free(ksiUpdate);
	Free(offsetAlpha);
	Free(modeAlpha);
	Free(priorMeanAlpha);
	Free(varAlpha);
	Free(alphaLong);
	Free(penAlphaSq);
	freeXBlockQR(AlphaBlocks, *blocksAlpha);
	if(qKsiNoUpdate < *q) freeXBlockQR(KsiBlocks, *blocksKsi);
	Free(p1);
	return(R_NilValue);
}/* end sampler ()*/
Example #3
0
// HPP_vec_lik using MEDIAN Yang discrete gamma rates
std::vector<double> PyRateC_HPP_vec_lik(std::vector <int> ind, 
																				std::vector<double> ts, 
																				std::vector<double> te, 
																				std::vector<double> epochs,
																				std::vector<double> qRates,
																				std::vector<double> gammaRates) {

	const size_t N_GAMMA = gammaRates.size();

	// Get logGamma and logQRates 
	// This way we will required N_GAMMA + N_RATE log(...) instead of N_GAMMA*N_RATE
	std::vector<double> logGammaRates, logQRates;
	std::vector< std::vector <double> > qGammas, logQGammas;

	precomputeRatesAndLogRates(qRates, gammaRates, logGammaRates, logQRates, qGammas, logQGammas);

	// Compute the likelihood for each specie
	std::vector<double> logLik(fossils.size(), 0);
	double logDivisor = log((double)N_GAMMA);
	for(size_t iI=0; iI<ind.size(); ++iI) {
		size_t iF = ind[iI]; // Specie index in fossils
		std::pair<size_t, size_t> span;
		std::vector<double> timePerEpoch;
		defineEpochSpanAndTime(ts[iF], te[iF], epochs, span, timePerEpoch);

		size_t nFossils = fossils[iF].back() == 0 ? fossils[iF].size()-1 : fossils[iF].size();
		if(N_GAMMA > 1 && nFossils > 1) {
			double spLogLik = 0.; 
			for(size_t iG = 0; iG < N_GAMMA; ++iG) {
				// For each gamma compute :
				// qGamma= YangGamma[i]*q_rates
				// lik_vec[i] = sum(-qGamma[ind]*d + log(qGamma[ind])*k_vec[ind]) - log(1-exp(sum(-qGamma[ind]*d))) -sum(log(np.arange(1,sum(k_vec)+1)))

				double sum1 = 0.; // sum(-qGamma[ind]*d)
				double sum2 = 0.; // sum(log(qGamma[ind])*k_vec[ind])
				// For each epoch where the specie was living
				for(size_t iE=span.first; iE<=span.second; ++iE) {
					sum1 += -qGammas[iG][iE]*timePerEpoch[iE-span.first];
					sum2 += logQGammas[iG][iE]*fossilCountPerEpoch[iF][iE];
				}

				double term1 = sum1+sum2; 														// sum(-qGamma[ind]*d + log(qGamma[ind])*k_vec[ind])
				double term2 = -log(1-exp(sum1)); 										// - log(1-exp(sum(-qGamma[ind]*d)))
				double term3 = -logFactorialFossilCntPerSpecie[iF];		// -sum(log(np.arange(1,sum(k_vec)+1)))

				double spGammaLogLik = term1+term2+term3;
				if(iG == 0) spLogLik = spGammaLogLik;
				else 				spLogLik = LOG_PLUS(spLogLik,spGammaLogLik);
			}
			logLik[iF] = spLogLik-logDivisor; // Average the sum
		} else {
			//lik = sum(-q_rates[ind]*d + log(q_rates[ind])*k_vec[ind]) - log(1-exp(sum(-q_rates[ind]*d))) -sum(log(np.arange(1,sum(k_vec)+1))) 
			double sum1 = 0.; // sum(-q_rates[ind]*d)
			double sum2 = 0.; // sum(log(q_rates[ind])*k_vec[ind])
			// For each epoch where the specie was living
			for(size_t iE=span.first; iE<=span.second; ++iE) {
				sum1 += -qRates[iE]*timePerEpoch[iE-span.first];
				sum2 += logQRates[iE]*fossilCountPerEpoch[iF][iE];
			}

			double term1 = sum1+sum2; 														// sum(-qGamma[ind]*d + log(qGamma[ind])*k_vec[ind])
			double term2 = -log(1-exp(sum1)); 										// - log(1-exp(sum(-q_rates[ind]*d)))
			double term3 = -logFactorialFossilCntPerSpecie[iF];		// -sum(log(np.arange(1,sum(k_vec)+1))) 
			logLik[iF] = term1+term2+term3;
		}
	}
	return logLik;
}
Example #4
0
std::vector<double> processNHPPLikelihood(const std::vector<int> &ind, const std::vector<double> &ts, const std::vector<double> &te, 
														 							const double qRate, const std::vector<double> &gammaRates) {

	size_t N_GAMMA = gammaRates.size();
	const double LOG_DIVISOR = log((double)N_GAMMA);

	double LOG_Q_RATE = log(qRate);
	//double LOG_Q_GAMMA_RATE[N_GAMMA];
	double* LOG_Q_GAMMA_RATE = new double[N_GAMMA];
	for(size_t iG=0; iG<N_GAMMA; ++iG) {
		LOG_Q_GAMMA_RATE[iG] = log(gammaRates[iG]*qRate);
	}	

	std::vector<double> logLik(fossils.size(), 0.);
	for(size_t iI=0; iI<ind.size(); ++iI) {
		size_t iF=ind[iI];
		const double tl = ts[iF]-te[iF];

		// LOG PERT
		double globalLik=0.;
		for(size_t iX=0; iX<fossils[iF].size(); ++iX){
			globalLik += log(pow((ts[iF]-fossils[iF][iX]),BM1)*pow((fossils[iF][iX]-te[iF]), AM1));
		}
		// F -= nFossils * (log(tl^4) * fBeta(a,b)))
		globalLik -= static_cast<double>(fossils[iF].size())*log(F_BETA*pow(tl,4.));
	
		double spLogLik = 0.;
		if(fossils[iF].size() > 1) { // Go for gamma
			double maxTmpL = 0.;
			double sumTmpL = 0.;
			for(size_t iG=0; iG<N_GAMMA; ++iG){
				double spGammaLogLik = 0.;
				const double qGamma = gammaRates[iG]*qRate;
				const double qtl = qGamma*tl;
				double tempL = 1.-exp(-qtl);
				maxTmpL = maxTmpL < tempL ? tempL : maxTmpL;
				tempL = log(tempL);
				sumTmpL += tempL;

				spGammaLogLik = -qtl - tempL;
				spGammaLogLik += globalLik;
				spGammaLogLik += static_cast<double>(fossils[iF].size())*LOG_Q_GAMMA_RATE[iG];

				if(iG == 0) spLogLik = spGammaLogLik;
				else 				spLogLik = LOG_PLUS(spLogLik,spGammaLogLik);
			}
			spLogLik -= LOG_DIVISOR;
			double error = (maxTmpL>1.) || sumTmpL == std::numeric_limits<double>::infinity();
			if(error) spLogLik = -100000;
		} else {
			const double qtl = qRate*tl;
			spLogLik = -qtl - log(1.-exp(-qtl));
			spLogLik += globalLik;
			spLogLik += static_cast<double>(fossils[iF].size())*LOG_Q_RATE;
		}

		logLik[iF] = spLogLik - logFactorialFossilCntPerSpecie[iF];
	}

	return logLik;
}
Example #5
0
// Data augmentation
std::vector<double> processDataAugNHPP(const std::vector<int> &ind, const std::vector<double> &ts, const double qRate, const double extRate) {

	// Gamma rates
	boost::math::gamma_distribution<double> gammaDist(1., extRate);
	double sumGammaPDF = 0.;
	double GM[N_QUANTILE], gammaPDF[N_QUANTILE];
	for(size_t iQ=0; iQ<N_QUANTILE; ++iQ){
		GM[iQ] = log(1.-QUANTILE[iQ])/extRate;
		gammaPDF[iQ] = boost::math::pdf(gammaDist, -GM[iQ]);
		sumGammaPDF += gammaPDF[iQ];
	}

	// Precompute
	const double LOG_Q_RATE	= log(qRate);
	double LOG_RATIO_GAMMA_PDF[N_QUANTILE];
	for(size_t iQ=0; iQ<N_QUANTILE; ++iQ){
		LOG_RATIO_GAMMA_PDF[iQ] = log(gammaPDF[iQ]/(sumGammaPDF+1e-50));
	}

	if(sumGammaPDF <= 0.0) {
		std::vector<double> badLogLik(fossils.size(), -100000);
		return badLogLik;
	}

	std::vector<double> logLik(fossils.size(), 0.);
	for(size_t iI=0; iI<ind.size(); ++iI) {
		size_t iF = ind[iI];

		// Likelihood
		double globLik = 0.;
		for(unsigned int iX=0; iX<fossils[iF].size()-1; ++iX){
			globLik += log(pow((ts[iF]-fossils[iF][iX]), BM1));
		}
		globLik += static_cast<double>(fossils[iF].size()-1)*LOG_Q_RATE;

		// For each QUANTILE
		double locLiks[N_QUANTILE];
		for(unsigned int iQ=0; iQ<N_QUANTILE; ++iQ){
			double tl = ts[iF]-GM[iQ];
			//assert(tl != 0);
			double xB = (ts[iF])/tl; // is fossils[iF][last] always tStart-0 ?
			double intQ = boost::math::ibeta(A, B, xB) * tl * qRate;

			// Processing the equivalent of function logPERT4_density
			double F=0.;
			for(unsigned int iX=0; iX<fossils[iF].size()-1; ++iX){
				F += log(pow((fossils[iF][iX]-GM[iQ]), AM1));
			}
			F -= static_cast<double>(fossils[iF].size()-1)*log(F_BETA*pow(tl,4.));
			F += globLik;

			// Likelihood
			locLiks[iQ]  = F;															// np.sum((logPERT4_density(MM,z[:,0:k],aa,bb,X)+log(q)), axis=1)
			locLiks[iQ] += -intQ;													// -(int_q)
			locLiks[iQ] += LOG_RATIO_GAMMA_PDF[iQ];				// + log(G_density(-GM,1,l)/den)
			locLiks[iQ] += -log(1.-exp(-intQ));						// - log(1-exp(-int_q))
		}

		double likelihood = locLiks[0];
		for(unsigned int iQ=1; iQ<N_QUANTILE; ++iQ) {
			likelihood = LOG_PLUS(likelihood, locLiks[iQ]);
		}
		likelihood -= LOG_N_QUANTILE;

		if(likelihood > 100000) likelihood = -100000;
		logLik[iF] = likelihood - logFactorialFossilCntPerSpecie[iF];
	}


	return logLik;
}