NeuronString.java
- /*
- * 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.math4.neuralnet.oned;
- import org.apache.commons.math4.neuralnet.internal.NeuralNetException;
- import org.apache.commons.math4.neuralnet.FeatureInitializer;
- import org.apache.commons.math4.neuralnet.Network;
- /**
- * Neural network with the topology of a one-dimensional line.
- * Each neuron defines one point on the line.
- *
- * @since 3.3
- */
- public class NeuronString {
- /** Minimal number of neurons. */
- private static final int MIN_NEURONS = 2;
- /** 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 IllegalArgumentException if {@code num < 2}.
- */
- NeuronString(boolean wrap,
- double[][] featuresList) {
- size = featuresList.length;
- if (size < MIN_NEURONS) {
- throw new NeuralNetException(NeuralNetException.TOO_SMALL, size, MIN_NEURONS);
- }
- 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 IllegalArgumentException if {@code num < 2}.
- */
- public NeuronString(int num,
- boolean wrap,
- FeatureInitializer[] featureInit) {
- if (num < MIN_NEURONS) {
- throw new NeuralNetException(NeuralNetException.TOO_SMALL, num, MIN_NEURONS);
- }
- 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;
- }
- /**
- * Indicates whether the line of neurons is wrapped.
- *
- * @return {@code true} if the last neuron is linked to the first neuron.
- */
- public boolean isWrapped() {
- return wrap;
- }
- /**
- * 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 IllegalArgumentException if {@code i} is out of range.
- */
- public double[] getFeatures(int i) {
- if (i < 0 ||
- i >= size) {
- throw new NeuralNetException(NeuralNetException.OUT_OF_RANGE, 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));
- }
- }
- }