/* * ARGReassortmentOperator.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.arg.operators; import dr.evomodel.arg.ARGModel; import dr.evomodelxml.tree.TreeModelParser; import dr.inference.model.CompoundParameter; import dr.inference.operators.SimpleMCMCOperator; import dr.math.MathUtils; import java.util.logging.Logger; public class ARGReassortmentOperator extends SimpleMCMCOperator { public static final String ADD_PROBABILITY = "addProbability"; public static final String ARG_REASSORTMENT_OPERATOR = "argReassortmentOperator"; public static final String INTERNAL_NODES = "internalNodes"; public static final String INTERNAL_AND_ROOT = "internalNodesPlusRoot"; public static final String NODE_RATES = TreeModelParser.NODE_RATES; public static final String CHOOSE_BRANCHES_FIRST = "chooseBranchesFirst"; public static final double LOG_TWO = Math.log(2.0); private double singlePartitionProbability = 0.0; private double probBelowRoot = 0.9; private double size = 0.0; //Used to choose add step private boolean branchesFirst; private ARGModel arg; private CompoundParameter internalNodeParameters; private CompoundParameter internalAndRootNodeParameters; private CompoundParameter nodeRates; public ARGReassortmentOperator(ARGModel arg, int weight, boolean branchesFirst, double singlePartProb, double addProbability, CompoundParameter internalNodeParameters, CompoundParameter internalAndRootNodeParameters, CompoundParameter nodeRates) { this.arg = arg; this.internalNodeParameters = internalNodeParameters; this.internalAndRootNodeParameters = internalAndRootNodeParameters; this.nodeRates = nodeRates; this.branchesFirst = branchesFirst; this.singlePartitionProbability = singlePartProb; setWeight(weight); this.size = addProbability; //Transformed for computation reasons probBelowRoot = -Math.log(1 - Math.sqrt(probBelowRoot)); } public double doOperation() { double logHastings = 0; if (MathUtils.nextDouble() < 1.0 / (1 + Math.exp(-size))) logHastings = addOperation() - size; else logHastings = removeOperation() + size; return logHastings; } private double addOperation() { if (branchesFirst) return addOperationBranchesFirst(); return addOperationHeightsFirst(); } private double addOperationBranchesFirst() { double logHastings = 0; double treeHeight = arg.getNodeHeight(arg.getRoot()); double newBifurcationHeight = Double.POSITIVE_INFINITY; double newReassortmentHeight = Double.POSITIVE_INFINITY; double theta = probBelowRoot / treeHeight; while (newBifurcationHeight > treeHeight && newReassortmentHeight > treeHeight) { newBifurcationHeight = MathUtils.nextExponential(theta); newReassortmentHeight = MathUtils.nextExponential(theta); } logHastings += theta * (newBifurcationHeight + newReassortmentHeight) - LOG_TWO - 2.0 * Math.log(theta) + Math.log(1 - Math.exp(-2.0 * treeHeight * theta)); if (newBifurcationHeight < newReassortmentHeight) { double temp = newBifurcationHeight; newBifurcationHeight = newReassortmentHeight; newReassortmentHeight = temp; } return 0; } private double addOperationHeightsFirst() { return 0; } private double removeOperation() { return 0; } public String getOperatorName() { return ARG_REASSORTMENT_OPERATOR; } public String getPerformanceSuggestion() { return "Try changing the add probability probability"; } private class NoReassortmentEventException extends Exception { private static final long serialVersionUID = 1L; public NoReassortmentEventException() { super(""); } } }