/* * RateSampleOperator.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.evomodel.operators; import dr.evolution.tree.NodeRef; import dr.oldevomodel.clock.RateEvolutionLikelihood; import dr.evomodel.tree.TreeModel; import dr.evomodelxml.operators.RateSampleOperatorParser; import dr.inference.operators.SimpleMCMCOperator; import dr.math.MathUtils; /** * A special operator for sampling rates in a subtree * according to a RateEvolutionLikelihood such as the autocorrelated clock model * * @author Michael Defoin Platel */ public class RateSampleOperator extends SimpleMCMCOperator { private TreeModel tree; private boolean sampleAll; RateEvolutionLikelihood rateEvolution; public RateSampleOperator(TreeModel tree, boolean sampleAll, RateEvolutionLikelihood rateEvolution) { this.tree = tree; this.sampleAll = sampleAll; this.rateEvolution = rateEvolution; } /** * sample the rates of a subtree and return the hastings ratio. */ public final double doOperation() { int index; if (sampleAll) { index = tree.getRoot().getNumber(); } else { do { index = MathUtils.nextInt(tree.getNodeCount()); } while (tree.isExternal(tree.getNode(index))); } double logBackward = rateEvolution.getLogLikelihood(); //sampleOne(tree.getNode(index)); //sampleSubtree(tree.getNode(index)); sampleNode(tree.getNode(index)); //sampleSister(tree.getNode(index)); double logForward = rateEvolution.getLogLikelihood(); return logBackward - logForward; } void sampleSubtree(NodeRef parent) { int nbChildren = tree.getChildCount(parent); for (int c = 0; c < nbChildren; c++) { final NodeRef node = tree.getChild(parent, c); rateEvolution.sampleRate(node); sampleSubtree(node); } } void sampleSister(NodeRef parent) { int nbChildren = tree.getChildCount(parent); for (int c = 0; c < nbChildren; c++) { final NodeRef node = tree.getChild(parent, c); rateEvolution.sampleRate(node); } } void sampleNode(NodeRef parent) { int nbChildren = tree.getChildCount(parent); if (nbChildren > 0) { final int c = MathUtils.nextInt(nbChildren); final NodeRef node = tree.getChild(parent, c); rateEvolution.sampleRate(node); } } void sampleOne(NodeRef parent) { int nbChildren = tree.getChildCount(parent); if (nbChildren > 0) { final NodeRef node = tree.getChild(parent, 0); rateEvolution.sampleRate(node); } } /** * This method should be overridden by operators that need to do something just before the return of doOperation. * * @param newValue the proposed parameter value * @param oldValue the old parameter value */ void cleanupOperation(double newValue, double oldValue) { // DO NOTHING } //MCMCOperator INTERFACE public final String getOperatorName() { return "rateSample"; } public double getTargetAcceptanceProbability() { return 0.234; } public double getMinimumAcceptanceLevel() { return 0.1; } public double getMaximumAcceptanceLevel() { return 0.4; } public double getMinimumGoodAcceptanceLevel() { return 0.20; } public double getMaximumGoodAcceptanceLevel() { return 0.30; } public final String getPerformanceSuggestion() { return "No suggestions"; } public String toString() { return RateSampleOperatorParser.SAMPLE_OPERATOR + "("; } //PRIVATE STUFF }