Search in sources :

Example 1 with GibbsIndependentCoalescentOperator

use of dr.evomodel.continuous.GibbsIndependentCoalescentOperator 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;
}
Also used : CompoundLikelihood(dr.inference.model.CompoundLikelihood) PathLikelihood(dr.inference.model.PathLikelihood) Logger(java.util.logging.Logger) Model(dr.inference.model.Model) GibbsIndependentCoalescentOperator(dr.evomodel.continuous.GibbsIndependentCoalescentOperator)

Aggregations

GibbsIndependentCoalescentOperator (dr.evomodel.continuous.GibbsIndependentCoalescentOperator)1 CompoundLikelihood (dr.inference.model.CompoundLikelihood)1 Model (dr.inference.model.Model)1 PathLikelihood (dr.inference.model.PathLikelihood)1 Logger (java.util.logging.Logger)1