public double doOperation() throws OperatorFailedException {
  double logq;
  final double delta=getDelta();
  final NodeRef root=tree.getRoot();
  NodeRef node;
  do {
    node=tree.getNode(MathUtils.nextInt(tree.getNodeCount()));
  }
 while (node == root);
  final NodeRef parent=tree.getParent(node);
  final NodeRef sibling=getOtherChild(tree,parent,node);
  final NodeRef grandParent=tree.getParent(parent);
  final Map<NodeRef,Double> destinations=getDestinations(node,parent,sibling,delta);
  final List<NodeRef> destinationNodes=new ArrayList<NodeRef>(destinations.keySet());
  int r=MathUtils.nextInt(destinations.size());
  double forwardProbability=1.0 / destinations.size();
  final NodeRef j=destinationNodes.get(r);
  final double newHeight=destinations.get(j);
  final NodeRef jParent=tree.getParent(j);
  if (jParent != null && newHeight > tree.getNodeHeight(jParent)) {
    throw new IllegalArgumentException("height error");
  }
  if (newHeight < tree.getNodeHeight(j)) {
    throw new IllegalArgumentException("height error");
  }
  tree.beginTreeEdit();
  if (j == parent || jParent == parent) {
  }
 else {
    if (grandParent == null) {
      tree.removeChild(parent,sibling);
      tree.setRoot(sibling);
    }
 else {
      tree.removeChild(parent,sibling);
      tree.removeChild(grandParent,parent);
      tree.addChild(grandParent,sibling);
    }
    if (jParent == null) {
      tree.addChild(parent,j);
      tree.setRoot(parent);
    }
 else {
      tree.removeChild(jParent,j);
      tree.addChild(parent,j);
      tree.addChild(jParent,parent);
    }
  }
  tree.endTreeEdit();
  tree.setNodeHeight(parent,newHeight);
  if (tree.getParent(parent) != null && newHeight > tree.getNodeHeight(tree.getParent(parent))) {
    throw new IllegalArgumentException("height error");
  }
  if (newHeight < tree.getNodeHeight(node)) {
    throw new IllegalArgumentException("height error");
  }
  if (newHeight < tree.getNodeHeight(getOtherChild(tree,parent,node))) {
    throw new IllegalArgumentException("height error");
  }
  final Map<NodeRef,Double> reverseDestinations=getDestinations(node,parent,getOtherChild(tree,parent,node),delta);
  double reverseProbability=1.0 / reverseDestinations.size();
  logq=Math.log(reverseProbability) - Math.log(forwardProbability);
  return logq;
}

public double doOperation ( ) throws OperatorFailedException { double logq ; final double delta = getDelta ( ) ; final NodeRef root = tree . getRoot ( ) ; NodeRef node ; do { node = tree . getNode ( MathUtils . nextInt ( tree . getNodeCount ( ) ) ) ; } while ( node == root ) ; final NodeRef parent = tree . getParent ( node ) ; final NodeRef sibling = getOtherChild ( tree , parent , node ) ; final NodeRef grandParent = tree . getParent ( parent ) ; final Map < NodeRef , Double > destinations = getDestinations ( node , parent , sibling , delta ) ; final List < NodeRef > destinationNodes = new ArrayList < NodeRef > ( destinations . keySet ( ) ) ; int r = MathUtils . nextInt ( destinations . size ( ) ) ; double forwardProbability = 1.0 / destinations . size ( ) ; final NodeRef j = destinationNodes . get ( r ) ; final double newHeight = destinations . get ( j ) ; final NodeRef jParent = tree . getParent ( j ) ; if ( jParent != null && newHeight > tree . getNodeHeight ( jParent ) ) { throw new IllegalArgumentException ( "height error" ) ; } if ( newHeight < tree . getNodeHeight ( j ) ) { throw new IllegalArgumentException ( "height error" ) ; } tree . beginTreeEdit ( ) ; if ( j == parent || jParent == parent ) { } else { if ( grandParent == null ) { tree . removeChild ( parent , sibling ) ; tree . setRoot ( sibling ) ; } else { tree . removeChild ( parent , sibling ) ; tree . removeChild ( grandParent , parent ) ; tree . addChild ( grandParent , sibling ) ; } if ( jParent == null ) { tree . addChild ( parent , j ) ; tree . setRoot ( parent ) ; } else { tree . removeChild ( jParent , j ) ; tree . addChild ( parent , j ) ; tree . addChild ( jParent , parent ) ; } } tree . endTreeEdit ( ) ; tree . setNodeHeight ( parent , newHeight ) ; if ( tree . getParent ( parent ) != null && newHeight > tree . getNodeHeight ( tree . getParent ( parent ) ) ) { throw new IllegalArgumentException ( "height error" ) ; } if ( newHeight < tree . getNodeHeight ( node ) ) { throw new IllegalArgumentException ( "height error" ) ; } if ( newHeight < tree . getNodeHeight ( getOtherChild ( tree , parent , node ) ) ) { throw new IllegalArgumentException ( "height error" ) ; } final Map < NodeRef , Double > reverseDestinations = getDestinations ( node , parent , getOtherChild ( tree , parent , node ) , delta ) ; double reverseProbability = 1.0 / reverseDestinations . size ( ) ; logq = Math . log ( reverseProbability ) - Math . log ( forwardProbability ) ; return logq ; }
do a subtree leap move .
