You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2015/08/30 18:21:31 UTC

[1/2] [math] Use new incrementor implementation (cf. MATH-1259).

Repository: commons-math
Updated Branches:
  refs/heads/master d17cabe29 -> 46e97d9e0


Use new incrementor implementation (cf. MATH-1259).


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

Branch: refs/heads/master
Commit: 47fa07eade06908ded4206651571e71a2fe684a6
Parents: d17cabe
Author: Gilles <er...@apache.org>
Authored: Sun Aug 30 18:08:31 2015 +0200
Committer: Gilles <er...@apache.org>
Committed: Sun Aug 30 18:08:31 2015 +0200

----------------------------------------------------------------------
 .../math4/optim/univariate/BracketFinder.java   | 78 +++++++++++++-------
 1 file changed, 51 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-math/blob/47fa07ea/src/main/java/org/apache/commons/math4/optim/univariate/BracketFinder.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/optim/univariate/BracketFinder.java b/src/main/java/org/apache/commons/math4/optim/univariate/BracketFinder.java
index cf05237..d2890b9 100644
--- a/src/main/java/org/apache/commons/math4/optim/univariate/BracketFinder.java
+++ b/src/main/java/org/apache/commons/math4/optim/univariate/BracketFinder.java
@@ -22,7 +22,7 @@ import org.apache.commons.math4.exception.NotStrictlyPositiveException;
 import org.apache.commons.math4.exception.TooManyEvaluationsException;
 import org.apache.commons.math4.optim.nonlinear.scalar.GoalType;
 import org.apache.commons.math4.util.FastMath;
-import org.apache.commons.math4.util.Incrementor;
+import org.apache.commons.math4.util.IntegerSequence.Incrementor;
 
 /**
  * Provide an interval that brackets a local optimum of a function.
@@ -43,9 +43,13 @@ public class BracketFinder {
      */
     private final double growLimit;
     /**
-     * Counter for function evaluations.
+     * Number of allowed function evaluations.
      */
-    private final Incrementor evaluations = new Incrementor();
+    private final int maxEvaluations;
+    /**
+     * Number of function evaluations performed in the last search.
+     */
+    private int evaluations;
     /**
      * Lower bound of the bracket.
      */
@@ -96,7 +100,7 @@ public class BracketFinder {
         }
 
         this.growLimit = growLimit;
-        evaluations.setMaximalCount(maxEvaluations);
+        this.maxEvaluations = maxEvaluations;
     }
 
     /**
@@ -113,11 +117,11 @@ public class BracketFinder {
                        GoalType goal,
                        double xA,
                        double xB) {
-        evaluations.resetCount();
+        final FunctionEvaluator eval = new FunctionEvaluator(func);
         final boolean isMinim = goal == GoalType.MINIMIZE;
 
-        double fA = eval(func, xA);
-        double fB = eval(func, xB);
+        double fA = eval.value(xA);
+        double fB = eval.value(xB);
         if (isMinim ?
             fA < fB :
             fA > fB) {
@@ -132,7 +136,7 @@ public class BracketFinder {
         }
 
         double xC = xB + GOLD * (xB - xA);
-        double fC = eval(func, xC);
+        double fC = eval.value(xC);
 
         while (isMinim ? fC < fB : fC > fB) {
             double tmp1 = (xB - xA) * (fB - fC);
@@ -146,7 +150,7 @@ public class BracketFinder {
 
             double fW;
             if ((w - xC) * (xB - w) > 0) {
-                fW = eval(func, w);
+                fW = eval.value(w);
                 if (isMinim ?
                     fW < fC :
                     fW > fC) {
@@ -163,12 +167,12 @@ public class BracketFinder {
                     break;
                 }
                 w = xC + GOLD * (xC - xB);
-                fW = eval(func, w);
+                fW = eval.value(w);
             } else if ((w - wLim) * (wLim - xC) >= 0) {
                 w = wLim;
-                fW = eval(func, w);
+                fW = eval.value(w);
             } else if ((w - wLim) * (xC - w) > 0) {
-                fW = eval(func, w);
+                fW = eval.value(w);
                 if (isMinim ?
                     fW < fC :
                     fW > fC) {
@@ -177,11 +181,11 @@ public class BracketFinder {
                     w = xC + GOLD * (xC - xB);
                     fB = fC;
                     fC =fW;
-                    fW = eval(func, w);
+                    fW = eval.value(w);
                 }
             } else {
                 w = xC + GOLD * (xC - xB);
-                fW = eval(func, w);
+                fW = eval.value(w);
             }
 
             xA = xB;
@@ -214,14 +218,14 @@ public class BracketFinder {
      * @return the number of evalutations.
      */
     public int getMaxEvaluations() {
-        return evaluations.getMaximalCount();
+        return maxEvaluations;
     }
 
     /**
      * @return the number of evalutations.
      */
     public int getEvaluations() {
-        return evaluations.getCount();
+        return evaluations;
     }
 
     /**
@@ -273,18 +277,38 @@ public class BracketFinder {
     }
 
     /**
-     * @param f Function.
-     * @param x Argument.
-     * @return {@code f(x)}
-     * @throws TooManyEvaluationsException if the maximal number of evaluations is
-     * exceeded.
+     * Utility for incrementing a counter at each function evaluation.
      */
-    private double eval(UnivariateFunction f, double x) {
-        try {
-            evaluations.incrementCount();
-        } catch (MaxCountExceededException e) {
-            throw new TooManyEvaluationsException(e.getMax());
+    private class FunctionEvaluator {
+        /** Function. */
+        private final UnivariateFunction func;
+        /** Counter. */
+        private final Incrementor inc;
+
+        /**
+         * @param func Function.
+         */
+        FunctionEvaluator(UnivariateFunction func) {
+            this.func = func;
+            inc = Incrementor.create().withMaximalCount(maxEvaluations);
+            evaluations = 0;
+        }
+
+        /**
+         * @param x Argument.
+         * @return {@code f(x)}
+         * @throws TooManyEvaluationsException if the maximal number of evaluations is
+         * exceeded.
+         */
+        double value(double x) {
+            try {
+                inc.increment();
+                evaluations = inc.getCount();
+            } catch (MaxCountExceededException e) {
+                throw new TooManyEvaluationsException(e.getMax());
+            }
+
+            return func.value(x);
         }
-        return f.value(x);
     }
 }


[2/2] [math] MATH-1263

Posted by er...@apache.org.
MATH-1263

Accessor to get neighbouring neurons (in a square grid).


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

Branch: refs/heads/master
Commit: 46e97d9e04591e8198ff38bd2949fd5514da0d3e
Parents: 47fa07e
Author: Gilles <er...@apache.org>
Authored: Sun Aug 30 18:20:19 2015 +0200
Committer: Gilles <er...@apache.org>
Committed: Sun Aug 30 18:20:19 2015 +0200

----------------------------------------------------------------------
 src/changes/changes.xml                         |   3 +
 .../ml/neuralnet/twod/NeuronSquareMesh2D.java   | 132 +++++++++++++++
 .../neuralnet/twod/NeuronSquareMesh2DTest.java  | 163 +++++++++++++++++++
 3 files changed, 298 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-math/blob/46e97d9e/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 52297c0..2dc0628 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -54,6 +54,9 @@ If the output is not quite correct, check for invisible trailing spaces!
     </release>
 
     <release version="4.0" date="XXXX-XX-XX" description="">
+      <action dev="erans" type="add" issue="MATH-1263">
+        Accessor (class "o.a.c.m.ml.neuralnet.twod.NeuronSquareMesh2D").
+      </action>
       <action dev="erans" type="add" issue="MATH-1259">
         New "IntegerSequence" class (in package "o.a.c.m.util") with "Incrementor" inner class.
       </action>

http://git-wip-us.apache.org/repos/asf/commons-math/blob/46e97d9e/src/main/java/org/apache/commons/math4/ml/neuralnet/twod/NeuronSquareMesh2D.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/ml/neuralnet/twod/NeuronSquareMesh2D.java b/src/main/java/org/apache/commons/math4/ml/neuralnet/twod/NeuronSquareMesh2D.java
index 3463b75..dd6cf6a 100644
--- a/src/main/java/org/apache/commons/math4/ml/neuralnet/twod/NeuronSquareMesh2D.java
+++ b/src/main/java/org/apache/commons/math4/ml/neuralnet/twod/NeuronSquareMesh2D.java
@@ -64,6 +64,29 @@ public class NeuronSquareMesh2D implements Serializable {
     private final long[][] identifiers;
 
     /**
+     * Horizontal (along row) direction.
+     */
+    public enum HorizontalDirection {
+        /** Column at the right of the current column. */
+       RIGHT,
+       /** Current column. */
+       CENTER,
+       /** Column at the left of the current column. */
+       LEFT,
+    }
+    /**
+     * Vertical (along column) direction.
+     */
+    public enum VerticalDirection {
+        /** Row above the current row. */
+        UP,
+        /** Current row. */
+        CENTER,
+        /** Row below the current row. */
+        DOWN,
+    }
+
+    /**
      * Constructor with restricted access, solely used for deserialization.
      *
      * @param wrapRowDim Whether to wrap the first dimension (i.e the first
@@ -205,12 +228,16 @@ public class NeuronSquareMesh2D implements Serializable {
 
     /**
      * Retrieves the neuron at location {@code (i, j)} in the map.
+     * The neuron at position {@code (0, 0)} is located at the upper-left
+     * corner of the map.
      *
      * @param i Row index.
      * @param j Column index.
      * @return the neuron at {@code (i, j)}.
      * @throws OutOfRangeException if {@code i} or {@code j} is
      * out of range.
+     *
+     * @see #getNeuron(int,int,HorizontalDirection,VerticalDirection)
      */
     public Neuron getNeuron(int i,
                             int j) {
@@ -227,6 +254,111 @@ public class NeuronSquareMesh2D implements Serializable {
     }
 
     /**
+     * Retrieves the requested neuron relative to the given {@code (row, col)}
+     * position.
+     * The neuron at position {@code (0, 0)} is located at the upper-left
+     * corner of the map.
+     *
+     * @param row Row index.
+     * @param col Column index.
+     * @param alongRowDir Direction along the given {@code row} (i.e. an
+     * offset will be added to the given <em>column</em> index.
+     * @param alongColDir Direction along the given {@code col} (i.e. an
+     * offset will be added to the given <em>row</em> index.
+     * @return the neuron at the requested location, or {@code null} if
+     * the location is not on the map.
+     *
+     * @see #getNeuron(int,int)
+     */
+    public Neuron getNeuron(int row,
+                            int col,
+                            HorizontalDirection alongRowDir,
+                            VerticalDirection alongColDir) {
+        final int[] location = getLocation(row, col, alongRowDir, alongColDir);
+
+        return location == null ? null : getNeuron(location[0], location[1]);
+    }
+
+    /**
+     * Computes the location of a neighbouring neuron.
+     * Returns {@code null} if the resulting location is not part
+     * of the map.
+     * Position {@code (0, 0)} is at the upper-left corner of the map.
+     *
+     * @param row Row index.
+     * @param col Column index.
+     * @param alongRowDir Direction along the given {@code row} (i.e. an
+     * offset will be added to the given <em>column</em> index.
+     * @param alongColDir Direction along the given {@code col} (i.e. an
+     * offset will be added to the given <em>row</em> index.
+     * @return an array of length 2 containing the indices of the requested
+     * location, or {@code null} if that location is not part of the map.
+     *
+     * @see #getNeuron(int,int)
+     */
+    private int[] getLocation(int row,
+                              int col,
+                              HorizontalDirection alongRowDir,
+                              VerticalDirection alongColDir) {
+        final int colOffset;
+        switch (alongRowDir) {
+        case LEFT:
+            colOffset = -1;
+            break;
+        case RIGHT:
+            colOffset = 1;
+            break;
+        case CENTER:
+            colOffset = 0;
+            break;
+        default:
+            // Should never happen.
+            throw new MathInternalError();
+        }
+        int colIndex = col + colOffset;
+        if (wrapColumns) {
+            if (colIndex < 0) {
+                colIndex += numberOfColumns;
+            } else {
+                colIndex %= numberOfColumns;
+            }
+        }
+
+        int rowOffset = 0;
+        switch (alongColDir) {
+        case UP:
+            rowOffset = -1;
+            break;
+        case DOWN:
+            rowOffset = 1;
+            break;
+        case CENTER:
+            rowOffset = 0;
+            break;
+        default:
+            // Should never happen.
+            throw new MathInternalError();
+        }
+        int rowIndex = row + rowOffset;
+        if (wrapRows) {
+            if (rowIndex < 0) {
+                rowIndex += numberOfRows;
+            } else {
+                rowIndex %= numberOfRows;
+            }
+        }
+
+        if (rowIndex < 0 ||
+            rowIndex >= numberOfRows ||
+            colIndex < 0 ||
+            colIndex >= numberOfColumns) {
+            return null;
+        } else {
+            return new int[] { rowIndex, colIndex };
+        }
+     }
+
+    /**
      * Creates the neighbour relationships between neurons.
      */
     private void createLinks() {

http://git-wip-us.apache.org/repos/asf/commons-math/blob/46e97d9e/src/test/java/org/apache/commons/math4/ml/neuralnet/twod/NeuronSquareMesh2DTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math4/ml/neuralnet/twod/NeuronSquareMesh2DTest.java b/src/test/java/org/apache/commons/math4/ml/neuralnet/twod/NeuronSquareMesh2DTest.java
index f5395b4..a48a1ce 100644
--- a/src/test/java/org/apache/commons/math4/ml/neuralnet/twod/NeuronSquareMesh2DTest.java
+++ b/src/test/java/org/apache/commons/math4/ml/neuralnet/twod/NeuronSquareMesh2DTest.java
@@ -26,6 +26,7 @@ import java.util.Collection;
 import java.util.HashSet;
 
 import org.apache.commons.math4.exception.NumberIsTooSmallException;
+import org.apache.commons.math4.exception.OutOfRangeException;
 import org.apache.commons.math4.ml.neuralnet.FeatureInitializer;
 import org.apache.commons.math4.ml.neuralnet.FeatureInitializerFactory;
 import org.apache.commons.math4.ml.neuralnet.Network;
@@ -682,4 +683,166 @@ public class NeuronSquareMesh2DTest {
             }
         }
     }
+
+    /*
+     * Test assumes that the network is
+     *
+     *  0-----1
+     *  |     |
+     *  |     |
+     *  2-----3
+     */
+    @Test
+    public void testGetNeuron() {
+        final FeatureInitializer[] initArray = { init };
+        final NeuronSquareMesh2D net = new NeuronSquareMesh2D(2, false,
+                                                              2, true,
+                                                              SquareNeighbourhood.VON_NEUMANN,
+                                                              initArray);
+        Assert.assertEquals(0, net.getNeuron(0, 0).getIdentifier());
+        Assert.assertEquals(1, net.getNeuron(0, 1).getIdentifier());
+        Assert.assertEquals(2, net.getNeuron(1, 0).getIdentifier());
+        Assert.assertEquals(3, net.getNeuron(1, 1).getIdentifier());
+
+        try {
+            net.getNeuron(2, 0);
+            Assert.fail("exception expected");
+        } catch (OutOfRangeException e) {
+            // Expected.
+        }
+        try {
+            net.getNeuron(0, 2);
+            Assert.fail("exception expected");
+        } catch (OutOfRangeException e) {
+            // Expected.
+        }
+        try {
+            net.getNeuron(-1, 0);
+            Assert.fail("exception expected");
+        } catch (OutOfRangeException e) {
+            // Expected.
+        }
+        try {
+            net.getNeuron(0, -1);
+            Assert.fail("exception expected");
+        } catch (OutOfRangeException e) {
+            // Expected.
+        }
+    }
+
+    /*
+     * Test assumes that the network is
+     *
+     *  0-----1-----2
+     *  |     |     |
+     *  |     |     |
+     *  3-----4-----5
+     *  |     |     |
+     *  |     |     |
+     *  6-----7-----8
+     */
+    @Test
+    public void testGetNeuronAlongDirection() {
+        final FeatureInitializer[] initArray = { init };
+        final NeuronSquareMesh2D net = new NeuronSquareMesh2D(3, false,
+                                                              3, false,
+                                                              SquareNeighbourhood.VON_NEUMANN,
+                                                              initArray);
+        Assert.assertEquals(0, net.getNeuron(1, 1,
+                                             NeuronSquareMesh2D.HorizontalDirection.LEFT,
+                                             NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
+        Assert.assertEquals(1, net.getNeuron(1, 1,
+                                             NeuronSquareMesh2D.HorizontalDirection.CENTER,
+                                             NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
+        Assert.assertEquals(2, net.getNeuron(1, 1,
+                                             NeuronSquareMesh2D.HorizontalDirection.RIGHT,
+                                             NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
+        Assert.assertEquals(3, net.getNeuron(1, 1,
+                                             NeuronSquareMesh2D.HorizontalDirection.LEFT,
+                                             NeuronSquareMesh2D.VerticalDirection.CENTER).getIdentifier());
+        Assert.assertEquals(4, net.getNeuron(1, 1,
+                                             NeuronSquareMesh2D.HorizontalDirection.CENTER,
+                                             NeuronSquareMesh2D.VerticalDirection.CENTER).getIdentifier());
+        Assert.assertEquals(5, net.getNeuron(1, 1,
+                                             NeuronSquareMesh2D.HorizontalDirection.RIGHT,
+                                             NeuronSquareMesh2D.VerticalDirection.CENTER).getIdentifier());
+        Assert.assertEquals(6, net.getNeuron(1, 1,
+                                             NeuronSquareMesh2D.HorizontalDirection.LEFT,
+                                             NeuronSquareMesh2D.VerticalDirection.DOWN).getIdentifier());
+        Assert.assertEquals(7, net.getNeuron(1, 1,
+                                             NeuronSquareMesh2D.HorizontalDirection.CENTER,
+                                             NeuronSquareMesh2D.VerticalDirection.DOWN).getIdentifier());
+        Assert.assertEquals(8, net.getNeuron(1, 1,
+                                             NeuronSquareMesh2D.HorizontalDirection.RIGHT,
+                                             NeuronSquareMesh2D.VerticalDirection.DOWN).getIdentifier());
+
+        // Locations not in map.
+        Assert.assertNull(net.getNeuron(0, 1,
+                                        NeuronSquareMesh2D.HorizontalDirection.CENTER,
+                                        NeuronSquareMesh2D.VerticalDirection.UP));
+        Assert.assertNull(net.getNeuron(1, 0,
+                                        NeuronSquareMesh2D.HorizontalDirection.LEFT,
+                                        NeuronSquareMesh2D.VerticalDirection.CENTER));
+        Assert.assertNull(net.getNeuron(2, 1,
+                                        NeuronSquareMesh2D.HorizontalDirection.CENTER,
+                                        NeuronSquareMesh2D.VerticalDirection.DOWN));
+        Assert.assertNull(net.getNeuron(1, 2,
+                                        NeuronSquareMesh2D.HorizontalDirection.RIGHT,
+                                        NeuronSquareMesh2D.VerticalDirection.CENTER));
+    }
+
+    /*
+     * Test assumes that the network is
+     *
+     *  0-----1-----2
+     *  |     |     |
+     *  |     |     |
+     *  3-----4-----5
+     *  |     |     |
+     *  |     |     |
+     *  6-----7-----8
+     */
+    @Test
+    public void testGetNeuronAlongDirectionWrappedMap() {
+        final FeatureInitializer[] initArray = { init };
+        final NeuronSquareMesh2D net = new NeuronSquareMesh2D(3, true,
+                                                              3, true,
+                                                              SquareNeighbourhood.VON_NEUMANN,
+                                                              initArray);
+        // No wrapping.
+        Assert.assertEquals(3, net.getNeuron(0, 0,
+                                             NeuronSquareMesh2D.HorizontalDirection.CENTER,
+                                             NeuronSquareMesh2D.VerticalDirection.DOWN).getIdentifier());
+        // With wrapping.
+        Assert.assertEquals(2, net.getNeuron(0, 0,
+                                             NeuronSquareMesh2D.HorizontalDirection.LEFT,
+                                             NeuronSquareMesh2D.VerticalDirection.CENTER).getIdentifier());
+        Assert.assertEquals(7, net.getNeuron(0, 0,
+                                             NeuronSquareMesh2D.HorizontalDirection.RIGHT,
+                                             NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
+        Assert.assertEquals(8, net.getNeuron(0, 0,
+                                             NeuronSquareMesh2D.HorizontalDirection.LEFT,
+                                             NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
+        Assert.assertEquals(6, net.getNeuron(0, 0,
+                                             NeuronSquareMesh2D.HorizontalDirection.CENTER,
+                                             NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
+        Assert.assertEquals(5, net.getNeuron(0, 0,
+                                             NeuronSquareMesh2D.HorizontalDirection.LEFT,
+                                             NeuronSquareMesh2D.VerticalDirection.DOWN).getIdentifier());
+
+        // No wrapping.
+        Assert.assertEquals(1, net.getNeuron(1, 2,
+                                             NeuronSquareMesh2D.HorizontalDirection.LEFT,
+                                             NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
+        // With wrapping.
+        Assert.assertEquals(0, net.getNeuron(1, 2,
+                                             NeuronSquareMesh2D.HorizontalDirection.RIGHT,
+                                             NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
+        Assert.assertEquals(3, net.getNeuron(1, 2,
+                                             NeuronSquareMesh2D.HorizontalDirection.RIGHT,
+                                             NeuronSquareMesh2D.VerticalDirection.CENTER).getIdentifier());
+        Assert.assertEquals(6, net.getNeuron(1, 2,
+                                             NeuronSquareMesh2D.HorizontalDirection.RIGHT,
+                                             NeuronSquareMesh2D.VerticalDirection.DOWN).getIdentifier());
+    }
 }