Repository: commons-math
Updated Branches:
  refs/heads/master 924e1e906 -> f36090e31


Fixed SOFM U-matrix (individual distances)

Some "diagonal" pixels were overwritten.


Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/f36090e3
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/f36090e3
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/f36090e3

Branch: refs/heads/master
Commit: f36090e3141cd3cd6fd58f1f46a30af2582559be
Parents: 924e1e9
Author: Gilles <[email protected]>
Authored: Sat Sep 19 14:51:51 2015 +0200
Committer: Gilles <[email protected]>
Committed: Sat Sep 19 14:51:51 2015 +0200

----------------------------------------------------------------------
 .../twod/util/UnifiedDistanceMatrix.java        | 119 ++++++++++---------
 1 file changed, 62 insertions(+), 57 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-math/blob/f36090e3/src/main/java/org/apache/commons/math4/ml/neuralnet/twod/util/UnifiedDistanceMatrix.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/commons/math4/ml/neuralnet/twod/util/UnifiedDistanceMatrix.java
 
b/src/main/java/org/apache/commons/math4/ml/neuralnet/twod/util/UnifiedDistanceMatrix.java
index 4b6f67a..1445f55 100644
--- 
a/src/main/java/org/apache/commons/math4/ml/neuralnet/twod/util/UnifiedDistanceMatrix.java
+++ 
b/src/main/java/org/apache/commons/math4/ml/neuralnet/twod/util/UnifiedDistanceMatrix.java
@@ -33,12 +33,18 @@ public class UnifiedDistanceMatrix implements 
MapVisualization {
     /** Distance. */
     private final DistanceMeasure distance;
 
-    /** Simple constructor.
+    /**
+     * Simple constructor.
+     *
      * @param individualDistances If {@code true}, the 8 individual
      * inter-units distances will be {@link #computeImage(NeuronSquareMesh2D)
      * computed}.  They will be stored in additional pixels around each of
-     * the original units of the 2D-map.  The value zero will be stored in the
-     * pixel corresponding to the location of a unit of the 2D-map.
+     * the original units of the 2D-map.  The additional pixels that lie
+     * along a "diagonal" are shared by <em>two</em> pairs of units: their
+     * value will be set to the average distance between the units belonging
+     * to each of the pairs.  The value zero will be stored in the pixel
+     * corresponding to the location of a unit of the 2D-map.
+     * <br>
      * If {@code false}, only the average distance between a unit and all its
      * neighbours will be computed (and stored in the pixel corresponding to
      * that unit of the 2D-map).  In that case, the number of neighbours taken
@@ -54,7 +60,6 @@ public class UnifiedDistanceMatrix implements 
MapVisualization {
     }
 
     /** {@inheritDoc} */
-    @Override
     public double[][] computeImage(NeuronSquareMesh2D map) {
         if (individualDistances) {
             return individualDistances(map);
@@ -80,6 +85,10 @@ public class UnifiedDistanceMatrix implements 
MapVisualization {
 
         final double[][] uMatrix = new double[numRows * 2 + 1][numCols * 2 + 
1];
 
+        // 1.
+        // Fill right and bottom slots of each unit's location with the
+        // distance between the current unit and each of the two neighbours,
+        // respectively.
         for (int i = 0; i < numRows; i++) {
             // Current unit's row index in result image.
             final int iR = 2 * i + 1;
@@ -91,42 +100,6 @@ public class UnifiedDistanceMatrix implements 
MapVisualization {
                 final double[] current = map.getNeuron(i, j).getFeatures();
                 Neuron neighbour;
 
-                // Top-left neighbour.
-                neighbour = map.getNeuron(i, j,
-                                          
NeuronSquareMesh2D.HorizontalDirection.LEFT,
-                                          
NeuronSquareMesh2D.VerticalDirection.UP);
-                if (neighbour != null) {
-                    uMatrix[iR - 1][jR - 1] = distance.compute(current,
-                                                               
neighbour.getFeatures());
-                }
-
-                // Top-center neighbour.
-                neighbour = map.getNeuron(i, j,
-                                          
NeuronSquareMesh2D.HorizontalDirection.CENTER,
-                                          
NeuronSquareMesh2D.VerticalDirection.UP);
-                if (neighbour != null) {
-                    uMatrix[iR - 1][jR] = distance.compute(current,
-                                                           
neighbour.getFeatures());
-                }
-
-                // Top-right neighbour.
-                neighbour = map.getNeuron(i, j,
-                                          
NeuronSquareMesh2D.HorizontalDirection.RIGHT,
-                                          
NeuronSquareMesh2D.VerticalDirection.UP);
-                if (neighbour != null) {
-                    uMatrix[iR - 1][jR + 1] = distance.compute(current,
-                                                               
neighbour.getFeatures());
-                }
-
-                // Left neighbour.
-                neighbour = map.getNeuron(i, j,
-                                          
NeuronSquareMesh2D.HorizontalDirection.LEFT,
-                                          
NeuronSquareMesh2D.VerticalDirection.CENTER);
-                if (neighbour != null) {
-                    uMatrix[iR][jR - 1] = distance.compute(current,
-                                                           
neighbour.getFeatures());
-                }
-
                 // Right neighbour.
                 neighbour = map.getNeuron(i, j,
                                           
NeuronSquareMesh2D.HorizontalDirection.RIGHT,
@@ -136,15 +109,6 @@ public class UnifiedDistanceMatrix implements 
MapVisualization {
                                                            
neighbour.getFeatures());
                 }
 
-                // Bottom-left neighbour.
-                neighbour = map.getNeuron(i, j,
-                                          
NeuronSquareMesh2D.HorizontalDirection.LEFT,
-                                          
NeuronSquareMesh2D.VerticalDirection.DOWN);
-                if (neighbour != null) {
-                    uMatrix[iR + 1][jR - 1] = distance.compute(current,
-                                                               
neighbour.getFeatures());
-                }
-
                 // Bottom-center neighbour.
                 neighbour = map.getNeuron(i, j,
                                           
NeuronSquareMesh2D.HorizontalDirection.CENTER,
@@ -153,18 +117,59 @@ public class UnifiedDistanceMatrix implements 
MapVisualization {
                     uMatrix[iR + 1][jR] = distance.compute(current,
                                                            
neighbour.getFeatures());
                 }
+            }
+        }
 
-                // Bottom-right neighbour.
-                neighbour = map.getNeuron(i, j,
-                                          
NeuronSquareMesh2D.HorizontalDirection.RIGHT,
-                                          
NeuronSquareMesh2D.VerticalDirection.DOWN);
-                if (neighbour != null) {
-                    uMatrix[iR + 1][jR + 1] = distance.compute(current,
-                                                               
neighbour.getFeatures());
-                }
+        // 2.
+        // Fill the bottom-rigth slot of each unit's location with the average
+        // of the distances between
+        //  * the current unit and its bottom-right neighbour, and
+        //  * the bottom-center neighbour and the right neighbour.
+        for (int i = 0; i < numRows; i++) {
+            // Current unit's row index in result image.
+            final int iR = 2 * i + 1;
+
+            for (int j = 0; j < numCols; j++) {
+                // Current unit's column index in result image.
+                final int jR = 2 * j + 1;
+
+                final Neuron current = map.getNeuron(i, j);
+                final Neuron right = map.getNeuron(i, j,
+                                                   
NeuronSquareMesh2D.HorizontalDirection.RIGHT,
+                                                   
NeuronSquareMesh2D.VerticalDirection.CENTER);
+                final Neuron bottom = map.getNeuron(i, j,
+                                                    
NeuronSquareMesh2D.HorizontalDirection.CENTER,
+                                                    
NeuronSquareMesh2D.VerticalDirection.DOWN);
+                final Neuron bottomRight = map.getNeuron(i, j,
+                                                         
NeuronSquareMesh2D.HorizontalDirection.RIGHT,
+                                                         
NeuronSquareMesh2D.VerticalDirection.DOWN);
+
+                final double current2BottomRight = bottomRight == null ?
+                    0 :
+                    distance.compute(current.getFeatures(),
+                                     bottomRight.getFeatures());
+                final double right2Bottom = (right == null ||
+                                             bottom == null) ?
+                    0 :
+                    distance.compute(right.getFeatures(),
+                                     bottom.getFeatures());
+
+                // Bottom-right slot.
+                uMatrix[iR + 1][jR + 1] = 0.5 * (current2BottomRight + 
right2Bottom);
             }
         }
 
+        // 3. Copy last row into first row.
+        final int lastRow = uMatrix.length - 1;
+        uMatrix[0] = uMatrix[lastRow];
+
+        // 4.
+        // Copy last column into first column.
+        final int lastCol = uMatrix[0].length - 1;
+        for (int r = 0; r < lastRow; r++) {
+            uMatrix[r][0] = uMatrix[r][lastCol];
+        }
+
         return uMatrix;
     }
 

Reply via email to