public double doOperation() throws OperatorFailedException {
  double logq;
  final NodeRef root=tree.getRoot();
  final double oldTreeHeight=tree.getNodeHeight(root);
  NodeRef i;
  do {
    i=tree.getNode(MathUtils.nextInt(tree.getNodeCount()));
  }
 while (root == i);
  final NodeRef iP=tree.getParent(i);
  final NodeRef CiP=getOtherChild(tree,iP,i);
  final NodeRef PiP=tree.getParent(iP);
  final double delta=getDelta();
  final double oldHeight=tree.getNodeHeight(iP);
  final double newHeight=oldHeight + delta;
  if (delta > 0) {
    if (PiP != null && tree.getNodeHeight(PiP) < newHeight) {
      NodeRef newParent=PiP;
      NodeRef 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);
        if (tree.hasNodeTraits()) {
          tree.swapAllTraits(newChild,iP);
        }
        if (tree.hasRates()) {
          final double rootNodeRate=tree.getNodeRate(newChild);
          tree.setNodeRate(newChild,tree.getNodeRate(iP));
          tree.setNodeRate(iP,rootNodeRate);
        }
      }
 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();
      final int possibleSources=intersectingEdges(tree,newChild,oldHeight,null);
      logq=-Math.log(possibleSources);
    }
 else {
      tree.setNodeHeight(iP,newHeight);
      logq=0.0;
    }
  }
 else {
    if (tree.getNodeHeight(i) > newHeight) {
      return Double.NEGATIVE_INFINITY;
    }
    if (tree.getNodeHeight(CiP) > newHeight) {
      List<NodeRef> newChildren=new ArrayList<NodeRef>();
      final int possibleDestinations=intersectingEdges(tree,CiP,newHeight,newChildren);
      if (newChildren.size() == 0) {
        return Double.NEGATIVE_INFINITY;
      }
      final int childIndex=MathUtils.nextInt(newChildren.size());
      NodeRef newChild=newChildren.get(childIndex);
      NodeRef 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);
        if (tree.hasNodeTraits()) {
          tree.swapAllTraits(iP,CiP);
        }
        if (tree.hasRates()) {
          final double rootNodeRate=tree.getNodeRate(iP);
          tree.setNodeRate(iP,tree.getNodeRate(CiP));
          tree.setNodeRate(CiP,rootNodeRate);
        }
      }
 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();
      logq=Math.log(possibleDestinations);
    }
 else {
      tree.setNodeHeight(iP,newHeight);
      logq=0.0;
    }
  }
  if (swapInRandomRate) {
    final NodeRef j=tree.getNode(MathUtils.nextInt(tree.getNodeCount()));
    if (j != i) {
      final double tmp=tree.getNodeRate(i);
      tree.setNodeRate(i,tree.getNodeRate(j));
      tree.setNodeRate(j,tmp);
    }
  }
  if (swapInRandomTrait) {
    final NodeRef j=tree.getNode(MathUtils.nextInt(tree.getNodeCount()));
    if (j != i) {
      tree.swapAllTraits(i,j);
    }
  }
  if (logq == Double.NEGATIVE_INFINITY)   throw new OperatorFailedException("invalid slide");
  if (scaledDirichletBranches) {
    if (oldTreeHeight != tree.getNodeHeight(tree.getRoot()))     throw new OperatorFailedException("Temporarily disabled.");
  }
  return logq;
}

public double doOperation ( ) throws OperatorFailedException { double logq ; final NodeRef root = tree . getRoot ( ) ; final double oldTreeHeight = tree . getNodeHeight ( root ) ; NodeRef i ; do { i = tree . getNode ( MathUtils . nextInt ( tree . getNodeCount ( ) ) ) ; } while ( root == i ) ; final NodeRef iP = tree . getParent ( i ) ; final NodeRef CiP = getOtherChild ( tree , iP , i ) ; final NodeRef PiP = tree . getParent ( iP ) ; final double delta = getDelta ( ) ; final double oldHeight = tree . getNodeHeight ( iP ) ; final double newHeight = oldHeight + delta ; if ( delta > 0 ) { if ( PiP != null && tree . getNodeHeight ( PiP ) < newHeight ) { NodeRef newParent = PiP ; NodeRef 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 ) ; if ( tree . hasNodeTraits ( ) ) { tree . swapAllTraits ( newChild , iP ) ; } if ( tree . hasRates ( ) ) { final double rootNodeRate = tree . getNodeRate ( newChild ) ; tree . setNodeRate ( newChild , tree . getNodeRate ( iP ) ) ; tree . setNodeRate ( iP , rootNodeRate ) ; } } 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 ( ) ; final int possibleSources = intersectingEdges ( tree , newChild , oldHeight , null ) ; logq = - Math . log ( possibleSources ) ; } else { tree . setNodeHeight ( iP , newHeight ) ; logq = 0.0 ; } } else { if ( tree . getNodeHeight ( i ) > newHeight ) { return Double . NEGATIVE_INFINITY ; } if ( tree . getNodeHeight ( CiP ) > newHeight ) { List < NodeRef > newChildren = new ArrayList < NodeRef > ( ) ; final int possibleDestinations = intersectingEdges ( tree , CiP , newHeight , newChildren ) ; if ( newChildren . size ( ) == 0 ) { return Double . NEGATIVE_INFINITY ; } final int childIndex = MathUtils . nextInt ( newChildren . size ( ) ) ; NodeRef newChild = newChildren . get ( childIndex ) ; NodeRef 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 ) ; if ( tree . hasNodeTraits ( ) ) { tree . swapAllTraits ( iP , CiP ) ; } if ( tree . hasRates ( ) ) { final double rootNodeRate = tree . getNodeRate ( iP ) ; tree . setNodeRate ( iP , tree . getNodeRate ( CiP ) ) ; tree . setNodeRate ( CiP , rootNodeRate ) ; } } 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 ( ) ; logq = Math . log ( possibleDestinations ) ; } else { tree . setNodeHeight ( iP , newHeight ) ; logq = 0.0 ; } } if ( swapInRandomRate ) { final NodeRef j = tree . getNode ( MathUtils . nextInt ( tree . getNodeCount ( ) ) ) ; if ( j != i ) { final double tmp = tree . getNodeRate ( i ) ; tree . setNodeRate ( i , tree . getNodeRate ( j ) ) ; tree . setNodeRate ( j , tmp ) ; } } if ( swapInRandomTrait ) { final NodeRef j = tree . getNode ( MathUtils . nextInt ( tree . getNodeCount ( ) ) ) ; if ( j != i ) { tree . swapAllTraits ( i , j ) ; } } if ( logq == Double . NEGATIVE_INFINITY ) throw new OperatorFailedException ( "invalid slide" ) ; if ( scaledDirichletBranches ) { if ( oldTreeHeight != tree . getNodeHeight ( tree . getRoot ( ) ) ) throw new OperatorFailedException ( "Temporarily disabled." ) ; } return logq ; }
do a probablistic subtree slide move .
