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:58:04 UTC
[math] MATH-1263
Repository: commons-math
Updated Branches:
refs/heads/MATH_3_X b54dbfb6e -> 2762c6600
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/2762c660
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/2762c660
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/2762c660
Branch: refs/heads/MATH_3_X
Commit: 2762c66008fe76c9ae697351140a5f5b3516d80a
Parents: b54dbfb
Author: Gilles <er...@apache.org>
Authored: Sun Aug 30 18:56:50 2015 +0200
Committer: Gilles <er...@apache.org>
Committed: Sun Aug 30 18:56:50 2015 +0200
----------------------------------------------------------------------
src/changes/changes.xml | 3 +
.../ml/neuralnet/twod/NeuronSquareMesh2D.java | 131 +++++++++++++++
.../neuralnet/twod/NeuronSquareMesh2DTest.java | 163 +++++++++++++++++++
3 files changed, 297 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/2762c660/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index be42bb3..29ce88f 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -51,6 +51,9 @@ If the output is not quite correct, check for invisible trailing spaces!
</properties>
<body>
<release version="3.6" 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/2762c660/src/main/java/org/apache/commons/math3/ml/neuralnet/twod/NeuronSquareMesh2D.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ml/neuralnet/twod/NeuronSquareMesh2D.java b/src/main/java/org/apache/commons/math3/ml/neuralnet/twod/NeuronSquareMesh2D.java
index deb2a8c..24b70af 100644
--- a/src/main/java/org/apache/commons/math3/ml/neuralnet/twod/NeuronSquareMesh2D.java
+++ b/src/main/java/org/apache/commons/math3/ml/neuralnet/twod/NeuronSquareMesh2D.java
@@ -63,6 +63,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
@@ -204,12 +227,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) {
@@ -226,6 +253,110 @@ public class NeuronSquareMesh2D implements Serializable {
}
/**
+ * Retrieves the neuron at {@code (location[0], location[1])} in the map.
+ * 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.
+ * It will return {@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;
+ }
+ }
+
+ final int rowOffset;
+ 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/2762c660/src/test/java/org/apache/commons/math3/ml/neuralnet/twod/NeuronSquareMesh2DTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math3/ml/neuralnet/twod/NeuronSquareMesh2DTest.java b/src/test/java/org/apache/commons/math3/ml/neuralnet/twod/NeuronSquareMesh2DTest.java
index 9d5f21c..1e4d3ea 100644
--- a/src/test/java/org/apache/commons/math3/ml/neuralnet/twod/NeuronSquareMesh2DTest.java
+++ b/src/test/java/org/apache/commons/math3/ml/neuralnet/twod/NeuronSquareMesh2DTest.java
@@ -26,6 +26,7 @@ import java.util.Collection;
import java.util.HashSet;
import org.apache.commons.math3.exception.NumberIsTooSmallException;
+import org.apache.commons.math3.exception.OutOfRangeException;
import org.apache.commons.math3.ml.neuralnet.FeatureInitializer;
import org.apache.commons.math3.ml.neuralnet.FeatureInitializerFactory;
import org.apache.commons.math3.ml.neuralnet.Network;
@@ -681,4 +682,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());
+ }
}