public List<ColourChange> sampleConditionalMigrationEvents(int parentColour,double parentHeight,int childColour,double childHeight,double[] m){
  List<ColourChange> colourChanges=new ArrayList<ColourChange>();
  int currentColour;
  double currentHeight;
  do {
    colourChanges.clear();
    currentColour=parentColour;
    currentHeight=parentHeight;
    do {
      double totalRate=m[1 - currentColour];
      double U=MathUtils.nextDouble();
      if ((parentColour != childColour) && (colourChanges.size() == 0)) {
        double minU=Math.exp(-totalRate * (parentHeight - childHeight));
        U=minU + U * (1.0 - minU);
      }
      double time=-Math.log(U) / totalRate;
      currentHeight-=time;
      if (currentHeight > childHeight) {
        currentColour=1 - currentColour;
        colourChanges.add(new ColourChange(currentHeight,currentColour));
      }
    }
 while (currentHeight > childHeight);
  }
 while (currentColour != childColour);
  reverseColourChangeList(colourChanges,parentColour);
  return colourChanges;
}

public List < ColourChange > sampleConditionalMigrationEvents ( int parentColour , double parentHeight , int childColour , double childHeight , double [ ] m ) { List < ColourChange > colourChanges = new ArrayList < ColourChange > ( ) ; int currentColour ; double currentHeight ; do { colourChanges . clear ( ) ; currentColour = parentColour ; currentHeight = parentHeight ; do { double totalRate = m [ 1 - currentColour ] ; double U = MathUtils . nextDouble ( ) ; if ( ( parentColour != childColour ) && ( colourChanges . size ( ) == 0 ) ) { double minU = Math . exp ( - totalRate * ( parentHeight - childHeight ) ) ; U = minU + U * ( 1.0 - minU ) ; } double time = - Math . log ( U ) / totalRate ; currentHeight -= time ; if ( currentHeight > childHeight ) { currentColour = 1 - currentColour ; colourChanges . add ( new ColourChange ( currentHeight , currentColour ) ) ; } } while ( currentHeight > childHeight ) ; } while ( currentColour != childColour ) ; reverseColourChangeList ( colourChanges , parentColour ) ; return colourChanges ; }
samples migration events on a two - coloured branch , conditional on colours at both ends migration process is forwards in ( natural ) time , so we are going down the tree . returns a list of events , ordered forward in time ( i . e . colour refers to branch * below * the event ) this version implements a rejection algorithm that can be easily extended to more than 2 colours *
