예제 #1
0
  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();
  }