use of dr.inference.model.PathLikelihood in project beast-mcmc by beast-dev.
the class MarkovChain method runChain.
/**
* Run the chain for a given number of states.
*
* @param length number of states to run the chain.
*/
public long runChain(long length, boolean disableCoerce) {
likelihood.makeDirty();
currentScore = evaluate(likelihood);
long currentState = currentLength;
final Model currentModel = likelihood.getModel();
if (currentState == 0) {
initialScore = currentScore;
bestScore = currentScore;
fireBestModel(currentState, currentModel);
}
if (currentScore == Double.NEGATIVE_INFINITY) {
// identify which component of the score is zero...
String message = "The initial likelihood is zero";
if (likelihood instanceof CompoundLikelihood) {
message += ": " + ((CompoundLikelihood) likelihood).getDiagnosis();
} else if (likelihood instanceof PathLikelihood) {
message += ": " + ((CompoundLikelihood) ((PathLikelihood) likelihood).getSourceLikelihood()).getDiagnosis();
message += ": " + ((CompoundLikelihood) ((PathLikelihood) likelihood).getDestinationLikelihood()).getDiagnosis();
} else {
message += ".";
}
throw new IllegalArgumentException(message);
} else if (currentScore == Double.POSITIVE_INFINITY || Double.isNaN(currentScore)) {
String message = "A likelihood returned with a numerical error";
if (likelihood instanceof CompoundLikelihood) {
message += ": " + ((CompoundLikelihood) likelihood).getDiagnosis();
} else {
message += ".";
}
throw new IllegalArgumentException(message);
}
pleaseStop = false;
isStopped = false;
//int otfcounter = onTheFlyOperatorWeights > 0 ? onTheFlyOperatorWeights : 0;
double[] logr = { 0.0 };
boolean usingFullEvaluation = true;
// set ops count in mcmc element instead
if (// Temporary solution until full code review
fullEvaluationCount == 0)
usingFullEvaluation = false;
boolean fullEvaluationError = false;
while (!pleaseStop && (currentState < (currentLength + length))) {
String diagnosticStart = "";
// periodically log states
fireCurrentModel(currentState, currentModel);
if (pleaseStop) {
isStopped = true;
break;
}
// Get the operator
final int op = schedule.getNextOperatorIndex();
final MCMCOperator mcmcOperator = schedule.getOperator(op);
double oldScore = currentScore;
if (usingFullEvaluation) {
diagnosticStart = likelihood instanceof CompoundLikelihood ? ((CompoundLikelihood) likelihood).getDiagnosis() : "";
}
// The current model is stored here in case the proposal fails
if (currentModel != null) {
currentModel.storeModelState();
}
// assert Profiler.stopProfile("Store");
boolean operatorSucceeded = true;
double hastingsRatio = 1.0;
boolean accept = false;
logr[0] = -Double.MAX_VALUE;
long elaspedTime = 0;
if (PROFILE) {
elaspedTime = System.currentTimeMillis();
}
if (DEBUG) {
System.out.println("\n>> Iteration: " + currentState);
System.out.println("\n&& Operator: " + mcmcOperator.getOperatorName());
}
if (mcmcOperator instanceof GeneralOperator) {
hastingsRatio = ((GeneralOperator) mcmcOperator).operate(likelihood);
} else {
hastingsRatio = mcmcOperator.operate();
}
// assert Profiler.stopProfile("Operate");
if (hastingsRatio == Double.NEGATIVE_INFINITY) {
// Should the evaluation be short-cutted?
// Previously this was set to false if OperatorFailedException was thrown.
// Now a -Inf HR is returned.
operatorSucceeded = false;
}
if (PROFILE) {
long duration = System.currentTimeMillis() - elaspedTime;
if (DEBUG) {
System.out.println("Time: " + duration);
}
mcmcOperator.addEvaluationTime(duration);
}
double score = Double.NaN;
double deviation = Double.NaN;
// System.err.print("" + currentState + ": ");
if (operatorSucceeded) {
if (DEBUG) {
System.out.println("** Evaluate");
}
long elapsedTime = 0;
if (PROFILE) {
elapsedTime = System.currentTimeMillis();
}
// The new model is evaluated
score = evaluate(likelihood);
if (PROFILE) {
long duration = System.currentTimeMillis() - elapsedTime;
if (DEBUG) {
System.out.println("Time: " + duration);
}
mcmcOperator.addEvaluationTime(duration);
}
String diagnosticOperator = "";
if (usingFullEvaluation) {
diagnosticOperator = likelihood instanceof CompoundLikelihood ? ((CompoundLikelihood) likelihood).getDiagnosis() : "";
}
if (score == Double.NEGATIVE_INFINITY && mcmcOperator instanceof GibbsOperator) {
if (!(mcmcOperator instanceof GibbsIndependentNormalDistributionOperator) && !(mcmcOperator instanceof GibbsIndependentGammaOperator) && !(mcmcOperator instanceof GibbsIndependentCoalescentOperator) && !(mcmcOperator instanceof GibbsIndependentJointNormalGammaOperator)) {
Logger.getLogger("error").severe("State " + currentState + ": A Gibbs operator, " + mcmcOperator.getOperatorName() + ", returned a state with zero likelihood.");
}
}
if (score == Double.POSITIVE_INFINITY || Double.isNaN(score)) {
if (likelihood instanceof CompoundLikelihood) {
Logger.getLogger("error").severe("State " + currentState + ": A likelihood returned with a numerical error:\n" + ((CompoundLikelihood) likelihood).getDiagnosis());
} else {
Logger.getLogger("error").severe("State " + currentState + ": A likelihood returned with a numerical error.");
}
// If the user has chosen to ignore this error then we transform it
// to a negative infinity so the state is rejected.
score = Double.NEGATIVE_INFINITY;
}
if (usingFullEvaluation) {
// This is a test that the state was correctly evaluated. The
// likelihood of all components of the model are flagged as
// needing recalculation, then the full likelihood is calculated
// again and compared to the first result. This checks that the
// BEAST is aware of all changes that the operator induced.
likelihood.makeDirty();
final double testScore = evaluate(likelihood);
final String d2 = likelihood instanceof CompoundLikelihood ? ((CompoundLikelihood) likelihood).getDiagnosis() : "";
if (Math.abs(testScore - score) > evaluationTestThreshold) {
Logger.getLogger("error").severe("State " + currentState + ": State was not correctly calculated after an operator move.\n" + "Likelihood evaluation: " + score + "\nFull Likelihood evaluation: " + testScore + "\n" + "Operator: " + mcmcOperator + " " + mcmcOperator.getOperatorName() + (diagnosticOperator.length() > 0 ? "\n\nDetails\nBefore: " + diagnosticOperator + "\nAfter: " + d2 : "") + "\n\n");
fullEvaluationError = true;
}
}
if (score > bestScore) {
bestScore = score;
fireBestModel(currentState, currentModel);
}
accept = mcmcOperator instanceof GibbsOperator || acceptor.accept(oldScore, score, hastingsRatio, logr);
deviation = score - oldScore;
}
// The new model is accepted or rejected
if (accept) {
if (DEBUG) {
System.out.println("** Move accepted: new score = " + score + ", old score = " + oldScore);
}
mcmcOperator.accept(deviation);
currentModel.acceptModelState();
currentScore = score;
} else {
if (DEBUG) {
System.out.println("** Move rejected: new score = " + score + ", old score = " + oldScore + " (logr = " + logr[0] + ")");
}
mcmcOperator.reject();
// assert Profiler.startProfile("Restore");
currentModel.restoreModelState();
if (usingFullEvaluation) {
// This is a test that the state is correctly restored. The
// restored state is fully evaluated and the likelihood compared with
// that before the operation was made.
likelihood.makeDirty();
final double testScore = evaluate(likelihood);
final String d2 = likelihood instanceof CompoundLikelihood ? ((CompoundLikelihood) likelihood).getDiagnosis() : "";
if (Math.abs(testScore - oldScore) > evaluationTestThreshold) {
final Logger logger = Logger.getLogger("error");
logger.severe("State " + currentState + ": State was not correctly restored after reject step.\n" + "Likelihood before: " + oldScore + " Likelihood after: " + testScore + "\n" + "Operator: " + mcmcOperator + " " + mcmcOperator.getOperatorName() + (diagnosticStart.length() > 0 ? "\n\nDetails\nBefore: " + diagnosticStart + "\nAfter: " + d2 : "") + "\n\n");
fullEvaluationError = true;
}
}
}
if (!disableCoerce && mcmcOperator instanceof CoercableMCMCOperator) {
coerceAcceptanceProbability((CoercableMCMCOperator) mcmcOperator, logr[0]);
}
if (usingFullEvaluation) {
if (schedule.getMinimumAcceptAndRejectCount() >= minOperatorCountForFullEvaluation && currentState >= fullEvaluationCount) {
// full evaluation is only switched off when each operator has done a
// minimum number of operations (currently 1) and fullEvalationCount
// operations in total.
usingFullEvaluation = false;
if (fullEvaluationError) {
// If there has been an error then stop with an error
throw new RuntimeException("One or more evaluation errors occurred during the test phase of this\n" + "run. These errors imply critical errors which may produce incorrect\n" + "results.");
}
}
}
fireEndCurrentIteration(currentState);
currentState += 1;
}
currentLength = currentState;
return currentLength;
}
Aggregations