summaryrefslogtreecommitdiff
path: root/src/main/java/org/apache/commons/math3/ml/neuralnet/oned/NeuronString.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/apache/commons/math3/ml/neuralnet/oned/NeuronString.java')
-rw-r--r--src/main/java/org/apache/commons/math3/ml/neuralnet/oned/NeuronString.java238
1 files changed, 238 insertions, 0 deletions
diff --git a/src/main/java/org/apache/commons/math3/ml/neuralnet/oned/NeuronString.java b/src/main/java/org/apache/commons/math3/ml/neuralnet/oned/NeuronString.java
new file mode 100644
index 0000000..fad6042
--- /dev/null
+++ b/src/main/java/org/apache/commons/math3/ml/neuralnet/oned/NeuronString.java
@@ -0,0 +1,238 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math3.ml.neuralnet.oned;
+
+import java.io.Serializable;
+import java.io.ObjectInputStream;
+import org.apache.commons.math3.ml.neuralnet.Network;
+import org.apache.commons.math3.ml.neuralnet.FeatureInitializer;
+import org.apache.commons.math3.exception.NumberIsTooSmallException;
+import org.apache.commons.math3.exception.OutOfRangeException;
+
+/**
+ * Neural network with the topology of a one-dimensional line.
+ * Each neuron defines one point on the line.
+ *
+ * @since 3.3
+ */
+public class NeuronString implements Serializable {
+ /** Serial version ID */
+ private static final long serialVersionUID = 1L;
+ /** Underlying network. */
+ private final Network network;
+ /** Number of neurons. */
+ private final int size;
+ /** Wrap. */
+ private final boolean wrap;
+
+ /**
+ * Mapping of the 1D coordinate to the neuron identifiers
+ * (attributed by the {@link #network} instance).
+ */
+ private final long[] identifiers;
+
+ /**
+ * Constructor with restricted access, solely used for deserialization.
+ *
+ * @param wrap Whether to wrap the dimension (i.e the first and last
+ * neurons will be linked together).
+ * @param featuresList Arrays that will initialize the features sets of
+ * the network's neurons.
+ * @throws NumberIsTooSmallException if {@code num < 2}.
+ */
+ NeuronString(boolean wrap,
+ double[][] featuresList) {
+ size = featuresList.length;
+
+ if (size < 2) {
+ throw new NumberIsTooSmallException(size, 2, true);
+ }
+
+ this.wrap = wrap;
+
+ final int fLen = featuresList[0].length;
+ network = new Network(0, fLen);
+ identifiers = new long[size];
+
+ // Add neurons.
+ for (int i = 0; i < size; i++) {
+ identifiers[i] = network.createNeuron(featuresList[i]);
+ }
+
+ // Add links.
+ createLinks();
+ }
+
+ /**
+ * Creates a one-dimensional network:
+ * Each neuron not located on the border of the mesh has two
+ * neurons linked to it.
+ * <br/>
+ * The links are bi-directional.
+ * Neurons created successively are neighbours (i.e. there are
+ * links between them).
+ * <br/>
+ * The topology of the network can also be a circle (if the
+ * dimension is wrapped).
+ *
+ * @param num Number of neurons.
+ * @param wrap Whether to wrap the dimension (i.e the first and last
+ * neurons will be linked together).
+ * @param featureInit Arrays that will initialize the features sets of
+ * the network's neurons.
+ * @throws NumberIsTooSmallException if {@code num < 2}.
+ */
+ public NeuronString(int num,
+ boolean wrap,
+ FeatureInitializer[] featureInit) {
+ if (num < 2) {
+ throw new NumberIsTooSmallException(num, 2, true);
+ }
+
+ size = num;
+ this.wrap = wrap;
+ identifiers = new long[num];
+
+ final int fLen = featureInit.length;
+ network = new Network(0, fLen);
+
+ // Add neurons.
+ for (int i = 0; i < num; i++) {
+ final double[] features = new double[fLen];
+ for (int fIndex = 0; fIndex < fLen; fIndex++) {
+ features[fIndex] = featureInit[fIndex].value();
+ }
+ identifiers[i] = network.createNeuron(features);
+ }
+
+ // Add links.
+ createLinks();
+ }
+
+ /**
+ * Retrieves the underlying network.
+ * A reference is returned (enabling, for example, the network to be
+ * trained).
+ * This also implies that calling methods that modify the {@link Network}
+ * topology may cause this class to become inconsistent.
+ *
+ * @return the network.
+ */
+ public Network getNetwork() {
+ return network;
+ }
+
+ /**
+ * Gets the number of neurons.
+ *
+ * @return the number of neurons.
+ */
+ public int getSize() {
+ return size;
+ }
+
+ /**
+ * Retrieves the features set from the neuron at location
+ * {@code i} in the map.
+ *
+ * @param i Neuron index.
+ * @return the features of the neuron at index {@code i}.
+ * @throws OutOfRangeException if {@code i} is out of range.
+ */
+ public double[] getFeatures(int i) {
+ if (i < 0 ||
+ i >= size) {
+ throw new OutOfRangeException(i, 0, size - 1);
+ }
+
+ return network.getNeuron(identifiers[i]).getFeatures();
+ }
+
+ /**
+ * Creates the neighbour relationships between neurons.
+ */
+ private void createLinks() {
+ for (int i = 0; i < size - 1; i++) {
+ network.addLink(network.getNeuron(i), network.getNeuron(i + 1));
+ }
+ for (int i = size - 1; i > 0; i--) {
+ network.addLink(network.getNeuron(i), network.getNeuron(i - 1));
+ }
+ if (wrap) {
+ network.addLink(network.getNeuron(0), network.getNeuron(size - 1));
+ network.addLink(network.getNeuron(size - 1), network.getNeuron(0));
+ }
+ }
+
+ /**
+ * Prevents proxy bypass.
+ *
+ * @param in Input stream.
+ */
+ private void readObject(ObjectInputStream in) {
+ throw new IllegalStateException();
+ }
+
+ /**
+ * Custom serialization.
+ *
+ * @return the proxy instance that will be actually serialized.
+ */
+ private Object writeReplace() {
+ final double[][] featuresList = new double[size][];
+ for (int i = 0; i < size; i++) {
+ featuresList[i] = getFeatures(i);
+ }
+
+ return new SerializationProxy(wrap,
+ featuresList);
+ }
+
+ /**
+ * Serialization.
+ */
+ private static class SerializationProxy implements Serializable {
+ /** Serializable. */
+ private static final long serialVersionUID = 20130226L;
+ /** Wrap. */
+ private final boolean wrap;
+ /** Neurons' features. */
+ private final double[][] featuresList;
+
+ /**
+ * @param wrap Whether the dimension is wrapped.
+ * @param featuresList List of neurons features.
+ * {@code neuronList}.
+ */
+ SerializationProxy(boolean wrap,
+ double[][] featuresList) {
+ this.wrap = wrap;
+ this.featuresList = featuresList;
+ }
+
+ /**
+ * Custom serialization.
+ *
+ * @return the {@link Neuron} for which this instance is the proxy.
+ */
+ private Object readResolve() {
+ return new NeuronString(wrap,
+ featuresList);
+ }
+ }
+}