public double slideSubtree(MutableTree tree){
  double logHastingsRatio;
  NodeRef i, newParent, newChild;
  do {
    i=tree.getNode(MathUtils.nextInt(tree.getNodeCount()));
  }
 while (tree.getRoot() == i);
  NodeRef iP=tree.getParent(i);
  NodeRef CiP=getOtherChild(tree,iP,i);
  NodeRef PiP=tree.getParent(iP);
  double delta=getDelta();
  double oldHeight=tree.getNodeHeight(iP);
  double newHeight=oldHeight + delta;
  if (delta > 0) {
    if (PiP != null && tree.getNodeHeight(PiP) < newHeight) {
      newParent=PiP;
      newChild=iP;
      while (tree.getNodeHeight(newParent) < newHeight) {
        newChild=newParent;
        newParent=tree.getParent(newParent);
        if (newParent == null)         break;
      }
      tree.beginTreeEdit();
      if (tree.isRoot(newChild)) {
        tree.removeChild(iP,CiP);
        tree.removeChild(PiP,iP);
        tree.addChild(iP,newChild);
        tree.addChild(PiP,CiP);
        tree.setRoot(iP);
      }
 else {
        tree.removeChild(iP,CiP);
        tree.removeChild(PiP,iP);
        tree.removeChild(newParent,newChild);
        tree.addChild(iP,newChild);
        tree.addChild(PiP,CiP);
        tree.addChild(newParent,iP);
      }
      tree.setNodeHeight(iP,newHeight);
      tree.endTreeEdit();
      int possibleSources=intersectingEdges(tree,newChild,oldHeight,null);
      logHastingsRatio=Math.log(1.0 / (double)possibleSources);
    }
 else {
      tree.setNodeHeight(iP,newHeight);
      logHastingsRatio=0.0;
    }
  }
 else {
    if (tree.getNodeHeight(i) > newHeight) {
      return Double.NEGATIVE_INFINITY;
    }
    if (tree.getNodeHeight(CiP) > newHeight) {
      ArrayList newChildren=new ArrayList();
      int possibleDestinations=intersectingEdges(tree,CiP,newHeight,newChildren);
      if (newChildren.size() == 0) {
        return Double.NEGATIVE_INFINITY;
      }
      int childIndex=MathUtils.nextInt(newChildren.size());
      newChild=(NodeRef)newChildren.get(childIndex);
      newParent=tree.getParent(newChild);
      tree.beginTreeEdit();
      if (tree.isRoot(iP)) {
        tree.removeChild(iP,CiP);
        tree.removeChild(newParent,newChild);
        tree.addChild(iP,newChild);
        tree.addChild(newParent,iP);
        tree.setRoot(CiP);
      }
 else {
        tree.removeChild(iP,CiP);
        tree.removeChild(PiP,iP);
        tree.removeChild(newParent,newChild);
        tree.addChild(iP,newChild);
        tree.addChild(PiP,CiP);
        tree.addChild(newParent,iP);
      }
      tree.setNodeHeight(iP,newHeight);
      tree.endTreeEdit();
      logHastingsRatio=Math.log((double)possibleDestinations);
    }
 else {
      tree.setNodeHeight(iP,newHeight);
      logHastingsRatio=0.0;
    }
  }
  return logHastingsRatio;
}

public double slideSubtree ( MutableTree tree ) { double logHastingsRatio ; NodeRef i , newParent , newChild ; do { i = tree . getNode ( MathUtils . nextInt ( tree . getNodeCount ( ) ) ) ; } while ( tree . getRoot ( ) == i ) ; NodeRef iP = tree . getParent ( i ) ; NodeRef CiP = getOtherChild ( tree , iP , i ) ; NodeRef PiP = tree . getParent ( iP ) ; double delta = getDelta ( ) ; double oldHeight = tree . getNodeHeight ( iP ) ; double newHeight = oldHeight + delta ; if ( delta > 0 ) { if ( PiP != null && tree . getNodeHeight ( PiP ) < newHeight ) { newParent = PiP ; newChild = iP ; while ( tree . getNodeHeight ( newParent ) < newHeight ) { newChild = newParent ; newParent = tree . getParent ( newParent ) ; if ( newParent == null ) break ; } tree . beginTreeEdit ( ) ; if ( tree . isRoot ( newChild ) ) { tree . removeChild ( iP , CiP ) ; tree . removeChild ( PiP , iP ) ; tree . addChild ( iP , newChild ) ; tree . addChild ( PiP , CiP ) ; tree . setRoot ( iP ) ; } else { tree . removeChild ( iP , CiP ) ; tree . removeChild ( PiP , iP ) ; tree . removeChild ( newParent , newChild ) ; tree . addChild ( iP , newChild ) ; tree . addChild ( PiP , CiP ) ; tree . addChild ( newParent , iP ) ; } tree . setNodeHeight ( iP , newHeight ) ; tree . endTreeEdit ( ) ; int possibleSources = intersectingEdges ( tree , newChild , oldHeight , null ) ; logHastingsRatio = Math . log ( 1.0 / ( double ) possibleSources ) ; } else { tree . setNodeHeight ( iP , newHeight ) ; logHastingsRatio = 0.0 ; } } else { if ( tree . getNodeHeight ( i ) > newHeight ) { return Double . NEGATIVE_INFINITY ; } if ( tree . getNodeHeight ( CiP ) > newHeight ) { ArrayList newChildren = new ArrayList ( ) ; int possibleDestinations = intersectingEdges ( tree , CiP , newHeight , newChildren ) ; if ( newChildren . size ( ) == 0 ) { return Double . NEGATIVE_INFINITY ; } int childIndex = MathUtils . nextInt ( newChildren . size ( ) ) ; newChild = ( NodeRef ) newChildren . get ( childIndex ) ; newParent = tree . getParent ( newChild ) ; tree . beginTreeEdit ( ) ; if ( tree . isRoot ( iP ) ) { tree . removeChild ( iP , CiP ) ; tree . removeChild ( newParent , newChild ) ; tree . addChild ( iP , newChild ) ; tree . addChild ( newParent , iP ) ; tree . setRoot ( CiP ) ; } else { tree . removeChild ( iP , CiP ) ; tree . removeChild ( PiP , iP ) ; tree . removeChild ( newParent , newChild ) ; tree . addChild ( iP , newChild ) ; tree . addChild ( PiP , CiP ) ; tree . addChild ( newParent , iP ) ; } tree . setNodeHeight ( iP , newHeight ) ; tree . endTreeEdit ( ) ; logHastingsRatio = Math . log ( ( double ) possibleDestinations ) ; } else { tree . setNodeHeight ( iP , newHeight ) ; logHastingsRatio = 0.0 ; } } return logHastingsRatio ; }
do a probablistic subtree slide move .
