Ejemplo n.º 1
0
  private static int mauCanonicalSub(
      Tree tree, NodeRef node, int loc, NodeRef[] order, boolean[] wasSwaped) {
    if (tree.isExternal(node)) {
      order[loc] = node;
      assert (loc & 0x1) == 0;
      return loc + 1;
    }

    final boolean swap = MathUtils.nextBoolean();
    // wasSwaped[(loc-1)/2] = swap;

    int l = mauCanonicalSub(tree, tree.getChild(node, swap ? 1 : 0), loc, order, wasSwaped);

    order[l] = node;
    assert (l & 0x1) == 1;
    wasSwaped[(l - 1) / 2] = swap;

    l = mauCanonicalSub(tree, tree.getChild(node, swap ? 0 : 1), l + 1, order, wasSwaped);
    return l;
  }
  public double splitClade(Clade parent, Clade[] children) {
    // the number of all possible clades is 2^n with n the number of tips
    // reduced by 2 because we wont consider the clades with all or no tips
    // contained
    // divide this number by 2 because every clade has a matching clade to
    // form the split
    // #splits = 2^(n-1) - 1
    final double splits = Math.pow(2, parent.getSize() - 1) - 1;

    double prob = 0;

    if (cladeCoProbabilities.containsKey(parent.getBits())) {
      HashMap<BitSet, Clade> childClades = cladeCoProbabilities.get(parent.getBits());
      double noChildClades = 0.0;

      double sum = 0.0;
      Set<BitSet> keys = childClades.keySet();
      for (BitSet child : keys) {
        Clade tmp = childClades.get(child);
        if (parent.getSize() > tmp.getSize() + 1) {
          sum += (tmp.getSampleCount() + EPSILON) / 2.0;
          noChildClades += 0.5;
        } else {
          sum += (tmp.getSampleCount() + EPSILON);
          noChildClades += 1.0;
        }
      }

      // add epsilon for each not observed clade
      sum += EPSILON * (splits - noChildClades);

      // roulette wheel
      double randomNumber = Math.random() * sum;
      for (BitSet child : keys) {
        Clade tmp = childClades.get(child);
        if (parent.getSize() > tmp.getSize() + 1) {
          randomNumber -= (tmp.getSampleCount() + EPSILON) / 2.0;
        } else {
          randomNumber -= (tmp.getSampleCount() + EPSILON);
        }
        if (randomNumber < 0) {
          children[0] = tmp;
          prob = (tmp.getSampleCount() + EPSILON) / sum;
          break;
        }
      }

      if (randomNumber >= 0) {
        // randomNumber /= EPSILON;
        prob = EPSILON / sum;
        BitSet newChild;
        BitSet inverseBits;
        do {
          do {
            newChild = (BitSet) parent.getBits().clone();
            int index = -1;
            do {
              index = newChild.nextSetBit(index + 1);
              if (index > -1 && MathUtils.nextBoolean()) {
                newChild.clear(index);
              }
            } while (index > -1);
          } while (newChild.cardinality() == 0 || newChild.cardinality() == parent.getSize());
          inverseBits = (BitSet) newChild.clone();
          inverseBits.xor(parent.getBits());
        } while (childClades.containsKey(newChild) || childClades.containsKey(inverseBits));

        Clade randomClade = new Clade(newChild, 0.9999 * parent.getHeight());
        children[0] = randomClade;

        BitSet secondChild = (BitSet) children[0].getBits().clone();
        secondChild.xor(parent.getBits());
        children[1] = new Clade(secondChild, 0.9999 * parent.getHeight());
      } else {
        BitSet secondChild = (BitSet) children[0].getBits().clone();
        secondChild.xor(parent.getBits());
        children[1] = childClades.get(secondChild);
        if (children[1] == null) {
          children[1] = new Clade(secondChild, 0.9999 * parent.getHeight());
        }
      }

    } else {
      prob = 1.0 / splits;

      BitSet newChild;
      do {
        newChild = (BitSet) parent.getBits().clone();
        int index = -1;
        do {
          index = newChild.nextSetBit(index + 1);
          if (index > -1 && MathUtils.nextBoolean()) {
            newChild.clear(index);
          }
        } while (index > -1);
      } while (newChild.cardinality() == 0 || newChild.cardinality() == parent.getSize());
      Clade randomClade = new Clade(newChild, 0.9999 * parent.getHeight());
      // randomClade.addSample();
      randomClade.addHeight(0.9999 * parent.getHeight());
      children[0] = randomClade;
      BitSet secondChild = (BitSet) children[0].getBits().clone();
      secondChild.xor(parent.getBits());
      children[1] = new Clade(secondChild, 0.9999 * parent.getHeight());
      // children[1].addSample();
      randomClade.addHeight(0.9999 * parent.getHeight());
    }

    return Math.log(prob);
  }