private double calculateConditionalBranchColouringEM(NodeRef node,double time,double childHeight,double[] matrixElements,BranchColouring branchColouring){
  double currentHeight=time + childHeight;
  int nextEvent=branchColouring.getNextForwardEvent(currentHeight);
  int currentColour=branchColouring.getForwardColourBelow(nextEvent - 1);
  double logLikelihood=0.0;
  int numEvents=0;
  while (currentHeight > childHeight) {
    double nextEventHeight;
    if (nextEvent == branchColouring.getNumEvents() + 1) {
      nextEventHeight=childHeight - 1.0;
    }
 else {
      nextEventHeight=branchColouring.getForwardTime(nextEvent);
    }
    double dt=currentHeight - nextEventHeight;
    double totalRate, migrationRate;
    if (currentColour == 0) {
      totalRate=matrixElements[0] / time;
      migrationRate=matrixElements[1] / time;
    }
 else {
      totalRate=matrixElements[3] / time;
      migrationRate=matrixElements[2] / time;
    }
    if (nextEventHeight < childHeight) {
      dt=currentHeight - childHeight;
      logLikelihood+=-totalRate * dt;
    }
 else {
      logLikelihood+=(-totalRate * dt) + Math.log(migrationRate);
      currentColour=branchColouring.getForwardColourBelow(nextEvent);
      numEvents+=1;
    }
    currentHeight=nextEventHeight;
    nextEvent+=1;
  }
  return logLikelihood;
}

private double calculateConditionalBranchColouringEM ( NodeRef node , double time , double childHeight , double [ ] matrixElements , BranchColouring branchColouring ) { double currentHeight = time + childHeight ; int nextEvent = branchColouring . getNextForwardEvent ( currentHeight ) ; int currentColour = branchColouring . getForwardColourBelow ( nextEvent - 1 ) ; double logLikelihood = 0.0 ; int numEvents = 0 ; while ( currentHeight > childHeight ) { double nextEventHeight ; if ( nextEvent == branchColouring . getNumEvents ( ) + 1 ) { nextEventHeight = childHeight - 1.0 ; } else { nextEventHeight = branchColouring . getForwardTime ( nextEvent ) ; } double dt = currentHeight - nextEventHeight ; double totalRate , migrationRate ; if ( currentColour == 0 ) { totalRate = matrixElements [ 0 ] / time ; migrationRate = matrixElements [ 1 ] / time ; } else { totalRate = matrixElements [ 3 ] / time ; migrationRate = matrixElements [ 2 ] / time ; } if ( nextEventHeight < childHeight ) { dt = currentHeight - childHeight ; logLikelihood += - totalRate * dt ; } else { logLikelihood += ( - totalRate * dt ) + Math . log ( migrationRate ) ; currentColour = branchColouring . getForwardColourBelow ( nextEvent ) ; numEvents += 1 ; } currentHeight = nextEventHeight ; nextEvent += 1 ; } return logLikelihood ; }
this samples events along an interval , and adds these events to a branchcolouring . also returns the ( unconditional ) log probability density for these events
