inprogress
[jalview.git] / forester / java / src / org / forester / evoinference / distance / NeighborJoiningF.java
index dd984ae..a696a38 100644 (file)
@@ -40,11 +40,12 @@ public final class NeighborJoiningF {
     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;
@@ -66,22 +67,11 @@ public final class NeighborJoiningF {
         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 ] ];
@@ -202,10 +192,24 @@ public final class NeighborJoiningF {
     }
 
     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.
@@ -220,18 +224,25 @@ public final class NeighborJoiningF {
                 _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;
+                }
             }
         }
     }