@Override public double proposal() { Tree tree = treeInput.get(this); // randomly select leaf node int i = Randomizer.nextInt(taxonIndices.length); Node node = tree.getNode(taxonIndices[i]); double upper = node.getParent().getHeight(); // double lower = 0.0; // final double newValue = (Randomizer.nextDouble() * (upper -lower)) + lower; // scale node double scale = (scaleFactor + (Randomizer.nextDouble() * ((1.0 / scaleFactor) - scaleFactor))); final double newValue = node.getHeight() * scale; // check the tree does not get negative branch lengths if (newValue > upper) { return Double.NEGATIVE_INFINITY; } node.setHeight(newValue); return -Math.log(scale); }
/** Recalculates all the intervals for the given beast.tree. */ @SuppressWarnings("unchecked") protected void calculateIntervals() { Tree tree = treeInput.get(); final int nodeCount = tree.getNodeCount(); times = new double[nodeCount]; int[] childCounts = new int[nodeCount]; collectTimes(tree, times, childCounts); indices = new int[nodeCount]; HeapSort.sort(times, indices); if (intervals == null || intervals.length != nodeCount) { intervals = new double[nodeCount]; lineageCounts = new int[nodeCount]; lineagesAdded = new List[nodeCount]; lineagesRemoved = new List[nodeCount]; // lineages = new List[nodeCount]; storedIntervals = new double[nodeCount]; storedLineageCounts = new int[nodeCount]; } else { for (List<Node> l : lineagesAdded) { if (l != null) { l.clear(); } } for (List<Node> l : lineagesRemoved) { if (l != null) { l.clear(); } } } // start is the time of the first tip double start = times[indices[0]]; int numLines = 0; int nodeNo = 0; intervalCount = 0; while (nodeNo < nodeCount) { int lineagesRemoved = 0; int lineagesAdded = 0; double finish = times[indices[nodeNo]]; double next; do { final int childIndex = indices[nodeNo]; final int childCount = childCounts[childIndex]; // don't use nodeNo from here on in do loop nodeNo += 1; if (childCount == 0) { addLineage(intervalCount, tree.getNode(childIndex)); lineagesAdded += 1; } else { lineagesRemoved += (childCount - 1); // record removed lineages final Node parent = tree.getNode(childIndex); // assert childCounts[indices[nodeNo]] == beast.tree.getChildCount(parent); // for (int j = 0; j < lineagesRemoved + 1; j++) { for (int j = 0; j < childCount; j++) { Node child = j == 0 ? parent.getLeft() : parent.getRight(); removeLineage(intervalCount, child); } // record added lineages addLineage(intervalCount, parent); // no mix of removed lineages when 0 th if (multifurcationLimit == 0.0) { break; } } if (nodeNo < nodeCount) { next = times[indices[nodeNo]]; } else break; } while (Math.abs(next - finish) <= multifurcationLimit); if (lineagesAdded > 0) { if (intervalCount > 0 || ((finish - start) > multifurcationLimit)) { intervals[intervalCount] = finish - start; lineageCounts[intervalCount] = numLines; intervalCount += 1; } start = finish; } // add sample event numLines += lineagesAdded; if (lineagesRemoved > 0) { intervals[intervalCount] = finish - start; lineageCounts[intervalCount] = numLines; intervalCount += 1; start = finish; } // coalescent event numLines -= lineagesRemoved; } intervalsKnown = true; }