KohonenUpdateAction implements UpdateAction { public void update(Network net, double[] features) { final long numCalls = numberOfCalls.incrementAndGet(); final double currentLearning = learningFactor.value(numCalls); final Neuron best = findAndUpdateBestNeuron(net, features, currentLearning); final int currentNeighbourhood = neighbourhoodSize.value(numCalls); final Gaussian neighbourhoodDecay = new Gaussian(currentLearning, 0, 1d / currentNeighbourhood); if (currentNeighbourhood > 0) { Collection<Neuron> neighbours = new HashSet<Neuron>(); neighbours.add(best); final HashSet<Neuron> exclude = new HashSet<Neuron>(); exclude.add(best); int radius = 1; do { neighbours = net.getNeighbours(neighbours, exclude); for (Neuron n : neighbours) { updateNeighbouringNeuron(n, features, neighbourhoodDecay.value(radius)); } exclude.addAll(neighbours); ++radius; } while (radius <= currentNeighbourhood); } } KohonenUpdateAction(DistanceMeasure distance,
                               LearningFactorFunction learningFactor,
                               NeighbourhoodSizeFunction neighbourhoodSize); void update(Network net,
                       double[] features); long getNumberOfCalls();  }
@Test public void testUpdate() { final FeatureInitializer init = new OffsetFeatureInitializer(FeatureInitializerFactory.uniform(0, 0.1)); final FeatureInitializer[] initArray = { init }; final int netSize = 3; final Network net = new NeuronString(netSize, false, initArray).getNetwork(); final DistanceMeasure dist = new EuclideanDistance(); final LearningFactorFunction learning = LearningFactorFunctionFactory.exponentialDecay(1, 0.1, 100); final NeighbourhoodSizeFunction neighbourhood = NeighbourhoodSizeFunctionFactory.exponentialDecay(3, 1, 100); final UpdateAction update = new KohonenUpdateAction(dist, learning, neighbourhood); final double[] features = new double[] { 0.3 }; final double[] distancesBefore = new double[netSize]; int count = 0; for (Neuron n : net) { distancesBefore[count++] = dist.compute(n.getFeatures(), features); } final Neuron bestBefore = MapUtils.findBest(features, net, dist); Assert.assertTrue(dist.compute(bestBefore.getFeatures(), features) >= 0.2); update.update(net, features); final double[] distancesAfter = new double[netSize]; count = 0; for (Neuron n : net) { distancesAfter[count++] = dist.compute(n.getFeatures(), features); } final Neuron bestAfter = MapUtils.findBest(features, net, dist); Assert.assertEquals(bestBefore, bestAfter); Assert.assertEquals(0, dist.compute(bestAfter.getFeatures(), features), 0d); for (int i = 0; i < netSize; i++) { Assert.assertTrue(distancesAfter[i] < distancesBefore[i]); } }