/* * SimpleMetropolizedGibbsOperator.java * * Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard * * This file is part of BEAST. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership and licensing. * * BEAST is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * BEAST is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with BEAST; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ /** * */ package dr.inference.operators; import dr.inference.model.Likelihood; import dr.inference.model.Model; import java.util.logging.Logger; /** * @author Sebastian Hoehna */ public abstract class SimpleMetropolizedGibbsOperator extends SimpleOperator implements GeneralOperator { /** * */ public SimpleMetropolizedGibbsOperator() { // Do nothing } public abstract double doOperation(Likelihood likelihood) ; /* * (non-Javadoc) * * @see dr.inference.operators.GibbsOperator#getStepCount() */ public abstract int getStepCount(); /* * (non-Javadoc) * * @see dr.inference.operators.SimpleOperator#getOperatorName() */ @Override public abstract String getOperatorName(); public final double operate() { return operate(null); } public final double operate(Likelihood likelihood) { if (operateAllowed) { operateAllowed = false; return doOperation(likelihood); } else throw new RuntimeException( "Operate called twice without accept/reject in between!"); } /* * (non-Javadoc) * * @see dr.inference.operators.MCMCOperator#getMaximumAcceptanceLevel() */ public final double getMaximumAcceptanceLevel() { return 1.0; } /* * (non-Javadoc) * * @see dr.inference.operators.MCMCOperator#getMaximumGoodAcceptanceLevel() */ public final double getMaximumGoodAcceptanceLevel() { return 1.0; } /* * (non-Javadoc) * * @see dr.inference.operators.MCMCOperator#getMinimumAcceptanceLevel() */ public final double getMinimumAcceptanceLevel() { return 0.005; } /* * (non-Javadoc) * * @see dr.inference.operators.MCMCOperator#getMinimumGoodAcceptanceLevel() */ public final double getMinimumGoodAcceptanceLevel() { return 0.01; } /* * (non-Javadoc) * * @see dr.inference.operators.MCMCOperator#getPerformanceSuggestion() */ public final String getPerformanceSuggestion() { return ""; } /* * (non-Javadoc) * * @see dr.inference.operators.MCMCOperator#getTargetAcceptanceProbability() */ public final double getTargetAcceptanceProbability() { return 1.0; } protected double evaluate(Likelihood likelihood, double pathParameter) { double logPosterior = 0.0; final double logLikelihood = likelihood.getLogLikelihood() * pathParameter; if (Double.isNaN(logLikelihood)) { return Double.NEGATIVE_INFINITY; } // System.err.println("** " + logPosterior + " + " + logLikelihood + " = // " + (logPosterior + logLikelihood)); logPosterior += logLikelihood; return logPosterior; } protected void restore(Likelihood likelihood, Model currentModel, MCMCOperator mcmcOperator, double oldScore) { currentModel.restoreModelState(); // 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, 1.0); if (Math.abs(testScore - oldScore) > 1e-6) { Logger.getLogger("error").severe( "State was not correctly restored after reject step.\n" + "Likelihood before: " + oldScore + " Likelihood after: " + testScore + "\n" + "Operator: " + mcmcOperator + " " + mcmcOperator.getOperatorName()); } } }