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(); }