private boolean traverse(Tree tree,NodeRef node,int[] operatorNumber,boolean flip){
  boolean update=false;
  int nodeNum=node.getNumber();
  NodeRef parent=tree.getParent(node);
  if (operatorNumber != null) {
    operatorNumber[0]=-1;
  }
  if (parent != null && updateNode[nodeNum]) {
    final double branchRate=branchRateModel.getBranchRate(tree,node);
    final double branchTime=branchRate * (tree.getNodeHeight(parent) - tree.getNodeHeight(node));
    if (branchTime < 0.0) {
      throw new RuntimeException("Negative branch length: " + branchTime);
    }
    if (flip) {
      matrixBufferHelper.flipOffset(nodeNum);
    }
    final int eigenIndex=0;
    final int updateCount=branchUpdateCount[eigenIndex];
    matrixUpdateIndices[eigenIndex][updateCount]=matrixBufferHelper.getOffsetIndex(nodeNum);
    branchLengths[eigenIndex][updateCount]=branchTime;
    branchUpdateCount[eigenIndex]++;
    update=true;
  }
  if (!tree.isExternal(node)) {
    NodeRef child1=tree.getChild(node,0);
    final int[] op1={-1};
    final boolean update1=traverse(tree,child1,op1,flip);
    NodeRef child2=tree.getChild(node,1);
    final int[] op2={-1};
    final boolean update2=traverse(tree,child2,op2,flip);
    if (update1 || update2) {
      int x=operationCount[operationListCount] * Beagle.OPERATION_TUPLE_SIZE;
      if (flip) {
        partialBufferHelper.flipOffset(nodeNum);
      }
      final int[] operations=this.operations[operationListCount];
      operations[x]=partialBufferHelper.getOffsetIndex(nodeNum);
      if (useScaleFactors) {
        int n=nodeNum - tipCount;
        if (recomputeScaleFactors) {
          scaleBufferHelper.flipOffset(n);
          scaleBufferIndices[n]=scaleBufferHelper.getOffsetIndex(n);
          operations[x + 1]=scaleBufferIndices[n];
          operations[x + 2]=Beagle.NONE;
        }
 else {
          operations[x + 1]=Beagle.NONE;
          operations[x + 2]=scaleBufferIndices[n];
        }
      }
 else {
        if (useAutoScaling) {
          scaleBufferIndices[nodeNum - tipCount]=partialBufferHelper.getOffsetIndex(nodeNum);
        }
        operations[x + 1]=Beagle.NONE;
        operations[x + 2]=Beagle.NONE;
      }
      operations[x + 3]=partialBufferHelper.getOffsetIndex(child1.getNumber());
      operations[x + 4]=matrixBufferHelper.getOffsetIndex(child1.getNumber());
      operations[x + 5]=partialBufferHelper.getOffsetIndex(child2.getNumber());
      operations[x + 6]=matrixBufferHelper.getOffsetIndex(child2.getNumber());
      operationCount[operationListCount]++;
      update=true;
    }
  }
  return update;
}

private boolean traverse ( Tree tree , NodeRef node , int [ ] operatorNumber , boolean flip ) { boolean update = false ; int nodeNum = node . getNumber ( ) ; NodeRef parent = tree . getParent ( node ) ; if ( operatorNumber != null ) { operatorNumber [ 0 ] = - 1 ; } if ( parent != null && updateNode [ nodeNum ] ) { final double branchRate = branchRateModel . getBranchRate ( tree , node ) ; final double branchTime = branchRate * ( tree . getNodeHeight ( parent ) - tree . getNodeHeight ( node ) ) ; if ( branchTime < 0.0 ) { throw new RuntimeException ( "Negative branch length: " + branchTime ) ; } if ( flip ) { matrixBufferHelper . flipOffset ( nodeNum ) ; } final int eigenIndex = 0 ; final int updateCount = branchUpdateCount [ eigenIndex ] ; matrixUpdateIndices [ eigenIndex ] [ updateCount ] = matrixBufferHelper . getOffsetIndex ( nodeNum ) ; branchLengths [ eigenIndex ] [ updateCount ] = branchTime ; branchUpdateCount [ eigenIndex ] ++ ; update = true ; } if ( ! tree . isExternal ( node ) ) { NodeRef child1 = tree . getChild ( node , 0 ) ; final int [ ] op1 = { - 1 } ; final boolean update1 = traverse ( tree , child1 , op1 , flip ) ; NodeRef child2 = tree . getChild ( node , 1 ) ; final int [ ] op2 = { - 1 } ; final boolean update2 = traverse ( tree , child2 , op2 , flip ) ; if ( update1 || update2 ) { int x = operationCount [ operationListCount ] * Beagle . OPERATION_TUPLE_SIZE ; if ( flip ) { partialBufferHelper . flipOffset ( nodeNum ) ; } final int [ ] operations = this . operations [ operationListCount ] ; operations [ x ] = partialBufferHelper . getOffsetIndex ( nodeNum ) ; if ( useScaleFactors ) { int n = nodeNum - tipCount ; if ( recomputeScaleFactors ) { scaleBufferHelper . flipOffset ( n ) ; scaleBufferIndices [ n ] = scaleBufferHelper . getOffsetIndex ( n ) ; operations [ x + 1 ] = scaleBufferIndices [ n ] ; operations [ x + 2 ] = Beagle . NONE ; } else { operations [ x + 1 ] = Beagle . NONE ; operations [ x + 2 ] = scaleBufferIndices [ n ] ; } } else { if ( useAutoScaling ) { scaleBufferIndices [ nodeNum - tipCount ] = partialBufferHelper . getOffsetIndex ( nodeNum ) ; } operations [ x + 1 ] = Beagle . NONE ; operations [ x + 2 ] = Beagle . NONE ; } operations [ x + 3 ] = partialBufferHelper . getOffsetIndex ( child1 . getNumber ( ) ) ; operations [ x + 4 ] = matrixBufferHelper . getOffsetIndex ( child1 . getNumber ( ) ) ; operations [ x + 5 ] = partialBufferHelper . getOffsetIndex ( child2 . getNumber ( ) ) ; operations [ x + 6 ] = matrixBufferHelper . getOffsetIndex ( child2 . getNumber ( ) ) ; operationCount [ operationListCount ] ++ ; update = true ; } } return update ; }
traverse the tree calculating partial likelihoods .
