question: 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 ; } }
target:  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).