question: public double wide ( Prior prior , Likelihood likelihood ) throws OperatorFailedException { final int nodeCount = tree . getNodeCount ( ) ; final NodeRef root = tree . getRoot ( ) ; NodeRef i ; int indexI ; do { indexI = MathUtils . nextInt ( nodeCount ) ; i = tree . getNode ( indexI ) ; } while ( root == i || ( tree . getParent ( i ) == root && tree . getNodeHeight ( i ) > tree . getNodeHeight ( getOtherChild ( tree , tree . getParent ( i ) , i ) ) ) ) ; List < Integer > secondNodeIndices = new ArrayList < Integer > ( ) ; List < Double > probabilities = new ArrayList < Double > ( ) ; NodeRef j , jP ; NodeRef iP = tree . getParent ( i ) ; double heightIP = tree . getNodeHeight ( iP ) ; double heightI = tree . getNodeHeight ( i ) ; double sum = 0.0 ; double backward = calculateTreeLikelihood ( prior , likelihood , tree ) ; int offset = ( int ) - backward ; backward = Math . exp ( backward + offset ) ; for ( int n = 0 ; n < nodeCount ; n ++ ) { j = tree . getNode ( n ) ; if ( j != root ) { jP = tree . getParent ( j ) ; if ( ( iP != jP ) && ( tree . getNodeHeight ( j ) < heightIP ) && ( heightI < tree . getNodeHeight ( jP ) ) ) { secondNodeIndices . add ( n ) ; swap ( tree , i , j , iP , jP ) ; double prob = Math . exp ( calculateTreeLikelihood ( prior , likelihood , tree ) + offset ) ; probabilities . add ( prob ) ; swap ( tree , i , j , jP , iP ) ; sum += prob ; } } } if ( sum <= 1E-100 ) { throw new OperatorFailedException ( "Couldn't find another proposal with a decent likelihood." ) ; } double ran = Math . random ( ) * sum ; int index = 0 ; while ( ran > 0.0 ) { ran -= probabilities . get ( index ) ; index ++ ; } index -- ; j = tree . getNode ( secondNodeIndices . get ( index ) ) ; jP = tree . getParent ( j ) ; double heightJP = tree . getNodeHeight ( jP ) ; double heightJ = tree . getNodeHeight ( j ) ; double sumForward2 = 0.0 ; NodeRef k , kP ; for ( int n = 0 ; n < nodeCount ; n ++ ) { k = tree . getNode ( n ) ; if ( k != root ) { kP = tree . getParent ( k ) ; if ( ( jP != kP ) && ( tree . getNodeHeight ( k ) < heightJP ) && ( heightJ < tree . getNodeHeight ( kP ) ) ) { swap ( tree , j , k , jP , kP ) ; double prob = Math . exp ( calculateTreeLikelihood ( prior , likelihood , tree ) + offset ) ; sumForward2 += prob ; swap ( tree , j , k , kP , jP ) ; } } } swap ( tree , i , j , iP , jP ) ; double forward = probabilities . get ( index ) ; iP = jP ; heightIP = heightJP ; double sumBackward = 0.0 ; for ( int n = 0 ; n < nodeCount ; n ++ ) { j = tree . getNode ( n ) ; if ( j != root ) { jP = tree . getParent ( j ) ; if ( ( iP != jP ) && ( tree . getNodeHeight ( j ) < heightIP ) && ( heightI < tree . getNodeHeight ( jP ) ) ) { swap ( tree , i , j , iP , jP ) ; double prob = Math . exp ( calculateTreeLikelihood ( prior , likelihood , tree ) + offset ) ; sumBackward += prob ; swap ( tree , i , j , jP , iP ) ; } } } double sumBackward2 = 0.0 ; j = tree . getNode ( secondNodeIndices . get ( index ) ) ; jP = tree . getParent ( j ) ; heightJP = tree . getNodeHeight ( jP ) ; heightJ = tree . getNodeHeight ( j ) ; for ( int n = 0 ; n < nodeCount ; n ++ ) { k = tree . getNode ( n ) ; if ( k != root ) { kP = tree . getParent ( k ) ; if ( ( jP != kP ) && ( tree . getNodeHeight ( k ) < heightJP ) && ( heightJ < tree . getNodeHeight ( kP ) ) ) { swap ( tree , j , k , jP , kP ) ; double prob = Math . exp ( calculateTreeLikelihood ( prior , likelihood , tree ) + offset ) ; sumBackward2 += prob ; swap ( tree , j , k , kP , jP ) ; } } } double forwardProb = ( forward / sum ) + ( forward / sumForward2 ) ; double backwardProb = ( backward / sumBackward ) + ( backward / sumBackward2 ) ; double hastingsRatio = Math . log ( backwardProb / forwardProb ) ; return hastingsRatio ; }
target:  WARNING: Assumes strictly bifurcating tree.