public double doOperation() throws OperatorFailedException {
  double logq;
  final double alpha=(arctanTransform ? Math.atan(bias) * SCALE_ALPHA : Math.log(bias));
  final NodeRef root=tree.getRoot();
  double maxHeight=tree.getNodeHeight(root);
  NodeRef i;
  NodeRef iP=null;
  NodeRef CiP=null;
  NodeRef PiP=null;
  double height=Double.NaN;
  List<NodeRef> destinations=null;
  do {
    i=tree.getNode(MathUtils.nextInt(tree.getNodeCount()));
  }
 while (root == i || tree.getParent(i) == root);
  iP=tree.getParent(i);
  CiP=getOtherChild(tree,iP,i);
  PiP=tree.getParent(iP);
  height=tree.getNodeHeight(iP);
  destinations=getIntersectingEdges(tree,height);
  if (destinations.size() == 0) {
    throw new OperatorFailedException("No destinations found");
  }
  double[] pdf=getDestinationProbabilities(tree,i,height,maxHeight,destinations,alpha);
  destinations.remove(i);
  destinations.remove(CiP);
  int r=MathUtils.randomChoicePDF(pdf);
  double forwardProbability=pdf[r];
  final NodeRef j=destinations.get(r);
  final NodeRef jP=tree.getParent(j);
  tree.beginTreeEdit();
  tree.removeChild(iP,CiP);
  tree.removeChild(PiP,iP);
  tree.addChild(PiP,CiP);
  tree.removeChild(jP,j);
  tree.addChild(iP,j);
  tree.addChild(jP,iP);
  tree.endTreeEdit();
  final List<NodeRef> reverseDestinations=getIntersectingEdges(tree,height);
  double reverseProbability=getReverseProbability(tree,CiP,j,height,maxHeight,reverseDestinations,alpha);
  logq=Math.log(reverseProbability) - Math.log(forwardProbability);
  return logq;
}

public double doOperation ( ) throws OperatorFailedException { double logq ; final double alpha = ( arctanTransform ? Math . atan ( bias ) * SCALE_ALPHA : Math . log ( bias ) ) ; final NodeRef root = tree . getRoot ( ) ; double maxHeight = tree . getNodeHeight ( root ) ; NodeRef i ; NodeRef iP = null ; NodeRef CiP = null ; NodeRef PiP = null ; double height = Double . NaN ; List < NodeRef > destinations = null ; do { i = tree . getNode ( MathUtils . nextInt ( tree . getNodeCount ( ) ) ) ; } while ( root == i || tree . getParent ( i ) == root ) ; iP = tree . getParent ( i ) ; CiP = getOtherChild ( tree , iP , i ) ; PiP = tree . getParent ( iP ) ; height = tree . getNodeHeight ( iP ) ; destinations = getIntersectingEdges ( tree , height ) ; if ( destinations . size ( ) == 0 ) { throw new OperatorFailedException ( "No destinations found" ) ; } double [ ] pdf = getDestinationProbabilities ( tree , i , height , maxHeight , destinations , alpha ) ; destinations . remove ( i ) ; destinations . remove ( CiP ) ; int r = MathUtils . randomChoicePDF ( pdf ) ; double forwardProbability = pdf [ r ] ; final NodeRef j = destinations . get ( r ) ; final NodeRef jP = tree . getParent ( j ) ; tree . beginTreeEdit ( ) ; tree . removeChild ( iP , CiP ) ; tree . removeChild ( PiP , iP ) ; tree . addChild ( PiP , CiP ) ; tree . removeChild ( jP , j ) ; tree . addChild ( iP , j ) ; tree . addChild ( jP , iP ) ; tree . endTreeEdit ( ) ; final List < NodeRef > reverseDestinations = getIntersectingEdges ( tree , height ) ; double reverseProbability = getReverseProbability ( tree , CiP , j , height , maxHeight , reverseDestinations , alpha ) ; logq = Math . log ( reverseProbability ) - Math . log ( forwardProbability ) ; return logq ; }
do a subtree jump move .
