private double[] prune(Tree tree,NodeRef node,ColourChangeMatrix mm){
  double[] p=new double[colourCount];
  if (tree.isExternal(node)) {
    p[getColour(node)]=1.0;
  }
 else {
    NodeRef leftChild=tree.getChild(node,0);
    NodeRef rightChild=tree.getChild(node,1);
    double[] left=prune(tree,leftChild,mm);
    double[] right=prune(tree,rightChild,mm);
    double nodeHeight=tree.getNodeHeight(node);
    double leftTime=nodeHeight - tree.getNodeHeight(tree.getChild(node,0));
    double rightTime=nodeHeight - tree.getNodeHeight(tree.getChild(node,1));
    double maxp=0.0;
    for (int i=0; i < colourCount; i++) {
      double leftSum=0.0;
      double rightSum=0.0;
      for (int j=0; j < colourCount; j++) {
        leftSum+=mm.forwardTimeEvolution(i,j,leftTime) * left[j];
        rightSum+=mm.forwardTimeEvolution(i,j,rightTime) * right[j];
      }
      p[i]=leftSum * rightSum;
      if (p[i] > maxp) {
        maxp=p[i];
      }
    }
    if (maxp < 1.0e-100) {
      for (int i=0; i < colourCount; i++) {
        p[i]*=1.0e+100;
      }
      logNodePartialsRescaling-=Math.log(1.0e+100);
    }
  }
  nodePartials[node.getNumber()]=p;
  if (debugNodePartials) {
    prettyPrint("Node " + node.getNumber() + " prune=",p);
  }
  return p;
}

private double [ ] prune ( Tree tree , NodeRef node , ColourChangeMatrix mm ) { double [ ] p = new double [ colourCount ] ; if ( tree . isExternal ( node ) ) { p [ getColour ( node ) ] = 1.0 ; } else { NodeRef leftChild = tree . getChild ( node , 0 ) ; NodeRef rightChild = tree . getChild ( node , 1 ) ; double [ ] left = prune ( tree , leftChild , mm ) ; double [ ] right = prune ( tree , rightChild , mm ) ; double nodeHeight = tree . getNodeHeight ( node ) ; double leftTime = nodeHeight - tree . getNodeHeight ( tree . getChild ( node , 0 ) ) ; double rightTime = nodeHeight - tree . getNodeHeight ( tree . getChild ( node , 1 ) ) ; double maxp = 0.0 ; for ( int i = 0 ; i < colourCount ; i ++ ) { double leftSum = 0.0 ; double rightSum = 0.0 ; for ( int j = 0 ; j < colourCount ; j ++ ) { leftSum += mm . forwardTimeEvolution ( i , j , leftTime ) * left [ j ] ; rightSum += mm . forwardTimeEvolution ( i , j , rightTime ) * right [ j ] ; } p [ i ] = leftSum * rightSum ; if ( p [ i ] > maxp ) { maxp = p [ i ] ; } } if ( maxp < 1.0e-100 ) { for ( int i = 0 ; i < colourCount ; i ++ ) { p [ i ] *= 1.0e+100 ; } logNodePartialsRescaling -= Math . log ( 1.0e+100 ) ; } } nodePartials [ node . getNumber ( ) ] = p ; if ( debugNodePartials ) { prettyPrint ( "Node " + node . getNumber ( ) + " prune=" , p ) ; } return p ; }
calculate probability of data at descendants from node , given a color at the node ( ' partials ' ) , by a felsenstein - like pruning algorithm . ( first step in the color sampling algorithm ) side effect : updates nodepartials [ ] for this node and all its descendants .
