Beispiel #1
0
void Mcmc::runChain(void) {

	// get initial likelihood
	modelPtr->updateAllFlags();
	double oldLnL = modelPtr->lnLikelihood();
	
	for (int n=1; n<=numCycles; n++)
		{
		// pick a parameter to change
		Parm* parm = modelPtr->pickParmAtRandom();
		
		// propose a new state for the parameter
		double lnProposalRatio = parm->change();
		
		// calculate the prior ratio 
		double lnPriorRatio = parm->lnPriorRatio();
		
		// calculate the likelihood
		modelPtr->updateQ(parm);
		double lnL = modelPtr->lnLikelihood();
		double lnLikelihoodRatio = lnL - oldLnL;
		
		// calculate the acceptance probability of the proposed state
		double r = safeExp( lnLikelihoodRatio + lnPriorRatio + lnProposalRatio );
		
		// accept or reject the proposed state as the next state of the chain
		bool acceptState = false;
		if (ranPtr->uniformRv() < r)
			acceptState = true;
			
		// print information to the screen
		if ( n % printFrequency == 0 )
			{
			std::cout << std::setw(5) << n << " -- ";
			std::cout << std::fixed << std::setprecision(8) << oldLnL << " -> " << lnL;
			if (acceptState == true)
				std::cout << " -- Accepted change to " << parm->getName() << std::endl;
			else
				std::cout << " -- Rejected change to " << parm->getName() << std::endl;
			}
		
		// update the state of the chain
		if (acceptState == true)
			{
			parm->incrementNumAccepted();
			oldLnL = lnL;
			modelPtr->keep(parm);
			}
		else 
			{
			modelPtr->restore(parm);
			modelPtr->restoreQ(parm);
			}

		// print out current chain state
		if ( n == 1 || n % sampleFrequency == 0 || n == numCycles )
			printChainState(n, oldLnL);
			
		// print summary of chain
		if ( n % summarizeFrequency == 0 )
			treeSummary->printSummary();
		}
		
	treeSummary->print();
	modelPtr->printAcceptanceInfo();
}
Beispiel #2
0
Mcmc::Mcmc(Model *m, MbRandom *r, Settings *s, IoManager *outputPtr) {

	/* initialize some pointers and variables */
	modelPtr    = m;
	rnd         = r;
	chainLength = s->getChainLength();
	printFreq   = s->getPrintFrequency();
	sampleFreq  = s->getSampleFrequency();

	/* open files for output */
	string fileName = "";
	if (outputPtr->getFileName() == "")
		fileName = "mcmc_out";
	else
		fileName = outputPtr->getFileName();
	string filePathAndName = outputPtr->getFilePath() + PATH_SEPERATOR + fileName;
	string parmFile = filePathAndName + ".parm";
	string treeFile = filePathAndName + ".tree";
	ofstream parmOut( parmFile.c_str(), ios::out );
	ofstream treeOut( treeFile.c_str(), ios::out );
	if (!parmOut) 
		{
		cerr << "Cannot open file \"" + parmFile + "\"" << endl;
		exit(1);
		}
	if (!treeOut) 
		{
		cerr << "Cannot open file \"" + treeFile + "\"" << endl;
		exit(1);
		}
	
	cout << "   Running Markov chain" << endl;
	cout << "      Number of cycles      = " << chainLength << endl;
	cout << "      Print frequency       = " << printFreq << endl;
	cout << "      Sample frequency      = " << sampleFreq << endl;
	cout << "      Parameter file name   = " << fileName + ".parm" << endl;
	cout << "      Tree file name        = " << fileName + ".tree" << endl << endl;
	cout << "   Chain" << endl;
	
	/* run the Markov chain */
	int timeOn = clock();
	for (int n=1; n<=chainLength; n++)
		{
		/* pick a parameter to change */
		int whichParm = modelPtr->pickParm();
		Parm *parmOld = modelPtr->getCurParameter(whichParm);
		modelPtr->flipActiveParm();
		Parm *parmNew = modelPtr->getCurParameter(whichParm);

		/* change the parameter */
		double lnProposalRatio = parmNew->change();
		
		/* calculate likelihood for new state */
		modelPtr->upDateQ(parmNew);
		modelPtr->upDateTiProbs();
		double lnLOld = modelPtr->getLnL();
		double lnLNew = modelPtr->lnLikelihood();

		if (n % printFreq == 0)
			cout << setw(8) << n << " -- " << fixed << setprecision(2) << lnLOld << " -> " << fixed << setprecision(2) << lnLNew;
		
		/* calculate the acceptance probability */
		double lnLikelihoodRatio = lnLNew - lnLOld;
		double lnPriorRatio = parmNew->getLnPriorProbability() - parmOld->getLnPriorProbability();
		double lnR = lnLikelihoodRatio + lnPriorRatio + lnProposalRatio;
		double r = 0.0;
		if (lnR > 0.0)
			r = 1.0;
		else if (lnR < -100.0)
			r = 0.0;
		else
			r = exp(lnR);
		
		/* accept or reject the move */
		bool acceptMove = false;
		if (rnd->uniformRv() < r)
			acceptMove = true;
			
		/* update state of chain */
		if (acceptMove == true)
			{
			modelPtr->setLnL(lnLNew);
			int from = modelPtr->getActiveParm();
			int to   = flip(from);
			modelPtr->copyParms( from, to );
			if (n % printFreq == 0)
				cout << " -- Accepted change to " << parmNew->getParmName() << endl;
			}
		else
			{
			modelPtr->restoreQ(parmNew);
			int to = modelPtr->getActiveParm();
			int from   = flip(to);
			modelPtr->copyParms( from, to );
			modelPtr->flipActiveParm();
			if (n % printFreq == 0)
				cout << " -- Rejected change to " << parmNew->getParmName() << endl;
			}
			
		/* print state of the chain to a file */
		if (n == 1 || n == chainLength || n % sampleFreq == 0)
			sampleChainState(n, parmOut, treeOut);
			
		}
	int timeOff = clock();
	cout << "   Markov chain completed in " << (static_cast<float>(timeOff - timeOn)) / CLOCKS_PER_SEC << " seconds" << endl;

	/* close files for output */
	parmOut.close();
	treeOut.close();
	
}