question: 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 ; }
target:  Do a probablistic subtree slide move.