private float[][] _d_values;
private final DecimalFormat _df;
private PhylogenyNode[] _external_nodes;
- private float[][] _m_values;
private int[] _mappings;
private int _n;
private float[] _r;
private final boolean _verbose;
+ private int _min_i;
+ private int _min_j;
private NeighborJoiningF() {
_verbose = false;
reset( distance );
final Phylogeny phylogeny = new Phylogeny();
while ( _n > 2 ) {
- updateM();
// Calculates the minimal distance.
// If more than one minimal distances, always the first found is used
- // could randomize this, so that any would be returned in a randomized fashion...
- double minimum = _m_values[ 0 ][ 1 ];
- int otu1 = 0;
- int otu2 = 1;
- for( int j = 1; j < _n; ++j ) {
- for( int i = 0; i < j; ++i ) {
- if ( _m_values[ i ][ j ] < minimum ) {
- minimum = _m_values[ i ][ j ];
- otu1 = i;
- otu2 = j;
- }
- }
- }
+ updateM();
+ final int otu1 = _min_i;
+ final int otu2 = _min_j;
// It is a condition that otu1 < otu2.
final PhylogenyNode node = new PhylogenyNode();
final float d = _d_values[ _mappings[ otu1 ] ][ _mappings[ otu2 ] ];
}
private final void printProgress( final int otu1, final int otu2 ) {
- final PhylogenyNode n1 = getExternalPhylogenyNode( otu1 );
- final PhylogenyNode n2 = getExternalPhylogenyNode( otu2 );
- System.out.println( "Node " + ( ForesterUtil.isEmpty( n1.getName() ) ? n1.getId() : n1.getName() ) + " joins "
- + ( ForesterUtil.isEmpty( n2.getName() ) ? n2.getId() : n2.getName() ) );
+ System.out.println( "Node " + printProgressNodeToString( getExternalPhylogenyNode( otu1 ) ) + " joins "
+ + ( printProgressNodeToString( getExternalPhylogenyNode( otu2 ) ) ) );
+ }
+
+ private final String printProgressNodeToString( final PhylogenyNode n ) {
+ if ( n.isExternal() ) {
+ if ( ForesterUtil.isEmpty( n.getName() ) ) {
+ return Long.toString( n.getId() );
+ }
+ return n.getName();
+ }
+ return n.getId()
+ + " ("
+ + ( ForesterUtil.isEmpty( n.getChildNode1().getName() ) ? n.getChildNode1().getId() : n.getChildNode1()
+ .getName() )
+ + "+"
+ + ( ForesterUtil.isEmpty( n.getChildNode2().getName() ) ? n.getChildNode2().getId() : n.getChildNode2()
+ .getName() ) + ")";
}
// only the values in the lower triangle are used.
_d_values[ i ][ j ] = ( float ) distances.getValue( i, j );
}
}
- _m_values = new float[ _n ][ _n ];
initExternalNodes();
}
private final void updateM() {
calculateNetDivergences();
final int n_minus_2 = _n - 2;
+ float min = Float.MAX_VALUE;
+ _min_i = -1;
+ _min_j = -1;
for( int j = 1; j < _n; ++j ) {
final float r_j = _r[ j ];
final int m_j = _mappings[ j ];
for( int i = 0; i < j; ++i ) {
- _m_values[ i ][ j ] = _d_values[ _mappings[ i ] ][ m_j ] - ( ( _r[ i ] + r_j ) / n_minus_2 );
+ final float m = _d_values[ _mappings[ i ] ][ m_j ] - ( ( _r[ i ] + r_j ) / n_minus_2 );
+ if ( m < min ) {
+ min = m;
+ _min_i = i;
+ _min_j = j;
+ }
}
}
}