protected void scalePartials(int nodeIndex){
  int u=0;
  for (int i=0; i < patternCount; i++) {
    double scaleFactor=0.0;
    int v=u;
    for (int k=0; k < matrixCount; k++) {
      for (int j=0; j < stateCount; j++) {
        if (partials[currentPartialsIndices[nodeIndex]][nodeIndex][v] > scaleFactor) {
          scaleFactor=partials[currentPartialsIndices[nodeIndex]][nodeIndex][v];
        }
        v++;
      }
      v+=(patternCount - 1) * stateCount;
    }
    if (scaleFactor < scalingThreshold) {
      v=u;
      for (int k=0; k < matrixCount; k++) {
        for (int j=0; j < stateCount; j++) {
          partials[currentPartialsIndices[nodeIndex]][nodeIndex][v]/=scaleFactor;
          v++;
        }
        v+=(patternCount - 1) * stateCount;
      }
      scalingFactors[currentPartialsIndices[nodeIndex]][nodeIndex][i]=Math.log(scaleFactor);
    }
 else {
      scalingFactors[currentPartialsIndices[nodeIndex]][nodeIndex][i]=0.0;
    }
    u+=stateCount;
  }
}

protected void scalePartials ( int nodeIndex ) { int u = 0 ; for ( int i = 0 ; i < patternCount ; i ++ ) { double scaleFactor = 0.0 ; int v = u ; for ( int k = 0 ; k < matrixCount ; k ++ ) { for ( int j = 0 ; j < stateCount ; j ++ ) { if ( partials [ currentPartialsIndices [ nodeIndex ] ] [ nodeIndex ] [ v ] > scaleFactor ) { scaleFactor = partials [ currentPartialsIndices [ nodeIndex ] ] [ nodeIndex ] [ v ] ; } v ++ ; } v += ( patternCount - 1 ) * stateCount ; } if ( scaleFactor < scalingThreshold ) { v = u ; for ( int k = 0 ; k < matrixCount ; k ++ ) { for ( int j = 0 ; j < stateCount ; j ++ ) { partials [ currentPartialsIndices [ nodeIndex ] ] [ nodeIndex ] [ v ] /= scaleFactor ; v ++ ; } v += ( patternCount - 1 ) * stateCount ; } scalingFactors [ currentPartialsIndices [ nodeIndex ] ] [ nodeIndex ] [ i ] = Math . log ( scaleFactor ) ; } else { scalingFactors [ currentPartialsIndices [ nodeIndex ] ] [ nodeIndex ] [ i ] = 0.0 ; } u += stateCount ; } }
scale the partials at a given node . this uses a scaling suggested by ziheng yang in yang ( 2000 ) j . mol . evol . 51 : 423 - 432 < p / > this function looks over the partial likelihoods for each state at each pattern and finds the largest . if this is less than the scalingthreshold ( currently set to 1e - 40 ) then it rescales the partials for that pattern by dividing by this number ( i . e . , normalizing to between 0 , 1 ) . it then stores the log of this scaling . this is called for every internal node after the partials are calculated so provides most of the performance hit . ziheng suggests only doing this on a proportion of nodes but this sounded like a headache to organize ( and he doesn ' t use the threshold idea which improves the performance quite a bit ) .
