public double doOperation() throws OperatorFailedException { if (DEBUG) { c2cLikelihood.debugOutputTree("BeforeTWWB.nex", false); } proposeTree(); if (c2cLikelihood.getTreeModel().getExternalNodeCount() != tipCount) { int newCount = c2cLikelihood.getTreeModel().getExternalNodeCount(); throw new RuntimeException( "Lost some tips in modified SPR! (" + tipCount + "-> " + newCount + ")"); } if (DEBUG) { c2cLikelihood.debugOutputTree("AfterTWWB.nex", false); } return logq; }
public void proposeTree() throws OperatorFailedException { TreeModel tree = c2cLikelihood.getTreeModel(); BranchMapModel branchMap = c2cLikelihood.getBranchMap(); NodeRef i; double oldMinAge, newMinAge, newRange, oldRange, newAge, q; // choose a random node avoiding root, and nodes that are ineligible for this move because they // have nowhere to // go final int nodeCount = tree.getNodeCount(); do { i = tree.getNode(MathUtils.nextInt(nodeCount)); } while (tree.getRoot() == i || !eligibleForMove(i, tree, branchMap)); final NodeRef iP = tree.getParent(i); // this one can go anywhere NodeRef j = tree.getNode(MathUtils.nextInt(tree.getNodeCount())); NodeRef k = tree.getParent(j); while ((k != null && tree.getNodeHeight(k) <= tree.getNodeHeight(i)) || (i == j)) { j = tree.getNode(MathUtils.nextInt(tree.getNodeCount())); k = tree.getParent(j); } if (iP == tree.getRoot() || j == tree.getRoot()) { throw new OperatorFailedException("Root changes not allowed!"); } if (k == iP || j == iP || k == i) throw new OperatorFailedException("move failed"); final NodeRef CiP = getOtherChild(tree, iP, i); NodeRef PiP = tree.getParent(iP); newMinAge = Math.max(tree.getNodeHeight(i), tree.getNodeHeight(j)); newRange = tree.getNodeHeight(k) - newMinAge; newAge = newMinAge + (MathUtils.nextDouble() * newRange); oldMinAge = Math.max(tree.getNodeHeight(i), tree.getNodeHeight(CiP)); oldRange = tree.getNodeHeight(PiP) - oldMinAge; q = newRange / Math.abs(oldRange); // need to account for the random repainting of iP if (branchMap.get(PiP.getNumber()) != branchMap.get(CiP.getNumber())) { q *= 0.5; } if (branchMap.get(k.getNumber()) != branchMap.get(j.getNumber())) { q *= 2; } tree.beginTreeEdit(); if (j == tree.getRoot()) { // 1. remove edges <iP, CiP> tree.removeChild(iP, CiP); tree.removeChild(PiP, iP); // 2. add edges <k, iP>, <iP, j>, <PiP, CiP> tree.addChild(iP, j); tree.addChild(PiP, CiP); // iP is the new root tree.setRoot(iP); } else if (iP == tree.getRoot()) { // 1. remove edges <k, j>, <iP, CiP>, <PiP, iP> tree.removeChild(k, j); tree.removeChild(iP, CiP); // 2. add edges <k, iP>, <iP, j>, <PiP, CiP> tree.addChild(iP, j); tree.addChild(k, iP); // CiP is the new root tree.setRoot(CiP); } else { // 1. remove edges <k, j>, <iP, CiP>, <PiP, iP> tree.removeChild(k, j); tree.removeChild(iP, CiP); tree.removeChild(PiP, iP); // 2. add edges <k, iP>, <iP, j>, <PiP, CiP> tree.addChild(iP, j); tree.addChild(k, iP); tree.addChild(PiP, CiP); } tree.setNodeHeight(iP, newAge); tree.endTreeEdit(); // logq = Math.log(q); // repaint the parent to match either its new parent or its new child (50% chance of each). if (MathUtils.nextInt(2) == 0) { branchMap.set(iP.getNumber(), branchMap.get(k.getNumber()), true); } else { branchMap.set(iP.getNumber(), branchMap.get(j.getNumber()), true); } if (DEBUG) { c2cLikelihood.checkPartitions(); } }
public TransmissionWilsonBaldingB(CaseToCaseTreeLikelihood c2cLikelihood, double weight) { this.c2cLikelihood = c2cLikelihood; setWeight(weight); tipCount = c2cLikelihood.getTreeModel().getExternalNodeCount(); }
@Override public String getOperatorName() { return TRANSMISSION_WILSON_BALDING_B + " (" + c2cLikelihood.getTreeModel().getId() + ")"; }