private static NodeRef mauReconstructSub( MulSpeciesTreeModel tree, int from, int to, NodeRef[] order, boolean[] wasSwaped) { if (from == to) { return order[2 * from]; } int rootIndex = -1; { double h = -1; for (int i = from; i < to; ++i) { final double v = tree.getNodeHeight(order[2 * i + 1]); if (h < v) { h = v; rootIndex = i; } } } final NodeRef root = order[2 * rootIndex + 1]; final NodeRef lchild = tree.getChild(root, 0); final NodeRef rchild = tree.getChild(root, 1); NodeRef lTargetChild = mauReconstructSub(tree, from, rootIndex, order, wasSwaped); NodeRef rTargetChild = mauReconstructSub(tree, rootIndex + 1, to, order, wasSwaped); if (wasSwaped[rootIndex]) { NodeRef z = lTargetChild; lTargetChild = rTargetChild; rTargetChild = z; } if (lchild != lTargetChild) { tree.replaceChild(root, lchild, lTargetChild); } if (rchild != rTargetChild) { tree.replaceChild(root, rchild, rTargetChild); } return root; }
public void operateOneNode(final double factor) throws OperatorFailedException { // #print "operate: tree", ut.treerep(t) // if( verbose) System.out.println(" Mau at start: " + tree.getSimpleTree()); final int count = multree.getExternalNodeCount(); assert count == species.nSpSeqs(); NodeRef[] order = new NodeRef[2 * count - 1]; boolean[] swapped = new boolean[count - 1]; mauCanonical(multree, order, swapped); // internal node to change // count-1 - number of internal nodes int which = MathUtils.nextInt(count - 1); FixedBitSet left = new FixedBitSet(count); FixedBitSet right = new FixedBitSet(count); for (int k = 0; k < 2 * which + 1; k += 2) { left.set(multree.speciesIndex(order[k])); } for (int k = 2 * (which + 1); k < 2 * count; k += 2) { right.set(multree.speciesIndex(order[k])); } double newHeight; if (factor > 0) { newHeight = multree.getNodeHeight(order[2 * which + 1]) * factor; } else { final double limit = species.speciationUpperBound(left, right); newHeight = MathUtils.nextDouble() * limit; } multree.beginTreeEdit(); multree.setPreorderIndices(preOrderIndexBefore); final NodeRef node = order[2 * which + 1]; multree.setNodeHeight(node, newHeight); mauReconstruct(multree, order, swapped); // restore pre-order of pops - { multree.setPreorderIndices(preOrderIndexAfter); double[] splitPopValues = null; for (int k = 0; k < preOrderIndexBefore.length; ++k) { final int b = preOrderIndexBefore[k]; if (b >= 0) { final int a = preOrderIndexAfter[k]; if (a != b) { // if( verbose) System.out.println("pops: " + a + " <- " + b); final Parameter p1 = multree.sppSplitPopulations; if (splitPopValues == null) { splitPopValues = p1.getParameterValues(); } if (multree.constPopulation()) { p1.setParameterValue(count + a, splitPopValues[count + b]); } else { for (int i = 0; i < 2; ++i) { p1.setParameterValue(count + 2 * a + i, splitPopValues[count + 2 * b + i]); } } } } } } multree.endTreeEdit(); }