public double prunedWide(Prior prior,Likelihood likelihood) throws OperatorFailedException {
  final int nodeCount=tree.getNodeCount();
  final NodeRef root=tree.getRoot();
  NodeRef i;
  int indexI;
  do {
    indexI=MathUtils.nextInt(nodeCount);
    i=tree.getNode(indexI);
  }
 while (root == i || (tree.getParent(i) == root && tree.getNodeHeight(i) > tree.getNodeHeight(getOtherChild(tree,tree.getParent(i),i))));
  List<Integer> secondNodeIndices=new ArrayList<Integer>();
  List<Double> probabilities=new ArrayList<Double>();
  NodeRef j, jP;
  NodeRef iP=tree.getParent(i);
  double heightIP=tree.getNodeHeight(iP);
  double heightI=tree.getNodeHeight(i);
  double sum=0.0;
  double backward=calculateTreeLikelihood(prior,likelihood,tree);
  int offset=(int)-backward;
  backward=Math.exp(backward + offset);
  for (int n=0; n < nodeCount; n++) {
    j=tree.getNode(n);
    if (j != root) {
      jP=tree.getParent(j);
      if ((iP != jP) && (tree.getNodeHeight(j) < heightIP) && (heightI < tree.getNodeHeight(jP))&& getNodeDistance(iP,jP) <= MAX_DISTANCE) {
        secondNodeIndices.add(n);
        swap(tree,i,j,iP,jP);
        double prob=Math.exp(calculateTreeLikelihood(prior,likelihood,tree) + offset);
        probabilities.add(prob);
        swap(tree,i,j,jP,iP);
        sum+=prob;
      }
    }
  }
  if (sum <= 1E-100) {
    throw new OperatorFailedException("Couldn't find another proposal with a decent likelihood.");
  }
  double ran=Math.random() * sum;
  int index=0;
  while (ran > 0.0) {
    ran-=probabilities.get(index);
    index++;
  }
  index--;
  j=tree.getNode(secondNodeIndices.get(index));
  jP=tree.getParent(j);
  double heightJP=tree.getNodeHeight(jP);
  double heightJ=tree.getNodeHeight(j);
  double sumForward2=0.0;
  NodeRef k, kP;
  for (int n=0; n < nodeCount; n++) {
    k=tree.getNode(n);
    if (k != root) {
      kP=tree.getParent(k);
      if ((jP != kP) && (tree.getNodeHeight(k) < heightJP) && (heightJ < tree.getNodeHeight(kP))&& getNodeDistance(kP,jP) <= MAX_DISTANCE) {
        swap(tree,j,k,jP,kP);
        double prob=Math.exp(calculateTreeLikelihood(prior,likelihood,tree) + offset);
        sumForward2+=prob;
        swap(tree,j,k,kP,jP);
      }
    }
  }
  swap(tree,i,j,iP,jP);
  double forward=probabilities.get(index);
  iP=jP;
  heightIP=heightJP;
  double sumBackward=0.0;
  for (int n=0; n < nodeCount; n++) {
    j=tree.getNode(n);
    if (j != root) {
      jP=tree.getParent(j);
      if ((iP != jP) && (tree.getNodeHeight(j) < heightIP) && (heightI < tree.getNodeHeight(jP))&& getNodeDistance(iP,jP) <= MAX_DISTANCE) {
        swap(tree,i,j,iP,jP);
        double prob=Math.exp(calculateTreeLikelihood(prior,likelihood,tree) + offset);
        sumBackward+=prob;
        swap(tree,i,j,jP,iP);
      }
    }
  }
  double sumBackward2=0.0;
  j=tree.getNode(secondNodeIndices.get(index));
  jP=tree.getParent(j);
  heightJP=tree.getNodeHeight(jP);
  heightJ=tree.getNodeHeight(j);
  for (int n=0; n < nodeCount; n++) {
    k=tree.getNode(n);
    if (k != root) {
      kP=tree.getParent(k);
      if ((jP != kP) && (tree.getNodeHeight(k) < heightJP) && (heightJ < tree.getNodeHeight(kP))&& getNodeDistance(kP,jP) <= MAX_DISTANCE) {
        swap(tree,j,k,jP,kP);
        double prob=Math.exp(calculateTreeLikelihood(prior,likelihood,tree) + offset);
        sumBackward2+=prob;
        swap(tree,j,k,kP,jP);
      }
    }
  }
  double forwardProb=(forward / sum) + (forward / sumForward2);
  double backwardProb=(backward / sumBackward) + (backward / sumBackward2);
  double hastingsRatio=Math.log(backwardProb / forwardProb);
  return hastingsRatio;
}

public double prunedWide ( Prior prior , Likelihood likelihood ) throws OperatorFailedException { final int nodeCount = tree . getNodeCount ( ) ; final NodeRef root = tree . getRoot ( ) ; NodeRef i ; int indexI ; do { indexI = MathUtils . nextInt ( nodeCount ) ; i = tree . getNode ( indexI ) ; } while ( root == i || ( tree . getParent ( i ) == root && tree . getNodeHeight ( i ) > tree . getNodeHeight ( getOtherChild ( tree , tree . getParent ( i ) , i ) ) ) ) ; List < Integer > secondNodeIndices = new ArrayList < Integer > ( ) ; List < Double > probabilities = new ArrayList < Double > ( ) ; NodeRef j , jP ; NodeRef iP = tree . getParent ( i ) ; double heightIP = tree . getNodeHeight ( iP ) ; double heightI = tree . getNodeHeight ( i ) ; double sum = 0.0 ; double backward = calculateTreeLikelihood ( prior , likelihood , tree ) ; int offset = ( int ) - backward ; backward = Math . exp ( backward + offset ) ; for ( int n = 0 ; n < nodeCount ; n ++ ) { j = tree . getNode ( n ) ; if ( j != root ) { jP = tree . getParent ( j ) ; if ( ( iP != jP ) && ( tree . getNodeHeight ( j ) < heightIP ) && ( heightI < tree . getNodeHeight ( jP ) ) && getNodeDistance ( iP , jP ) <= MAX_DISTANCE ) { secondNodeIndices . add ( n ) ; swap ( tree , i , j , iP , jP ) ; double prob = Math . exp ( calculateTreeLikelihood ( prior , likelihood , tree ) + offset ) ; probabilities . add ( prob ) ; swap ( tree , i , j , jP , iP ) ; sum += prob ; } } } if ( sum <= 1E-100 ) { throw new OperatorFailedException ( "Couldn't find another proposal with a decent likelihood." ) ; } double ran = Math . random ( ) * sum ; int index = 0 ; while ( ran > 0.0 ) { ran -= probabilities . get ( index ) ; index ++ ; } index -- ; j = tree . getNode ( secondNodeIndices . get ( index ) ) ; jP = tree . getParent ( j ) ; double heightJP = tree . getNodeHeight ( jP ) ; double heightJ = tree . getNodeHeight ( j ) ; double sumForward2 = 0.0 ; NodeRef k , kP ; for ( int n = 0 ; n < nodeCount ; n ++ ) { k = tree . getNode ( n ) ; if ( k != root ) { kP = tree . getParent ( k ) ; if ( ( jP != kP ) && ( tree . getNodeHeight ( k ) < heightJP ) && ( heightJ < tree . getNodeHeight ( kP ) ) && getNodeDistance ( kP , jP ) <= MAX_DISTANCE ) { swap ( tree , j , k , jP , kP ) ; double prob = Math . exp ( calculateTreeLikelihood ( prior , likelihood , tree ) + offset ) ; sumForward2 += prob ; swap ( tree , j , k , kP , jP ) ; } } } swap ( tree , i , j , iP , jP ) ; double forward = probabilities . get ( index ) ; iP = jP ; heightIP = heightJP ; double sumBackward = 0.0 ; for ( int n = 0 ; n < nodeCount ; n ++ ) { j = tree . getNode ( n ) ; if ( j != root ) { jP = tree . getParent ( j ) ; if ( ( iP != jP ) && ( tree . getNodeHeight ( j ) < heightIP ) && ( heightI < tree . getNodeHeight ( jP ) ) && getNodeDistance ( iP , jP ) <= MAX_DISTANCE ) { swap ( tree , i , j , iP , jP ) ; double prob = Math . exp ( calculateTreeLikelihood ( prior , likelihood , tree ) + offset ) ; sumBackward += prob ; swap ( tree , i , j , jP , iP ) ; } } } double sumBackward2 = 0.0 ; j = tree . getNode ( secondNodeIndices . get ( index ) ) ; jP = tree . getParent ( j ) ; heightJP = tree . getNodeHeight ( jP ) ; heightJ = tree . getNodeHeight ( j ) ; for ( int n = 0 ; n < nodeCount ; n ++ ) { k = tree . getNode ( n ) ; if ( k != root ) { kP = tree . getParent ( k ) ; if ( ( jP != kP ) && ( tree . getNodeHeight ( k ) < heightJP ) && ( heightJ < tree . getNodeHeight ( kP ) ) && getNodeDistance ( kP , jP ) <= MAX_DISTANCE ) { swap ( tree , j , k , jP , kP ) ; double prob = Math . exp ( calculateTreeLikelihood ( prior , likelihood , tree ) + offset ) ; sumBackward2 += prob ; swap ( tree , j , k , kP , jP ) ; } } } double forwardProb = ( forward / sum ) + ( forward / sumForward2 ) ; double backwardProb = ( backward / sumBackward ) + ( backward / sumBackward2 ) ; double hastingsRatio = Math . log ( backwardProb / forwardProb ) ; return hastingsRatio ; }
warning : assumes strictly bifurcating tree .
