View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.math4.neuralnet.twod;
19  
20  import java.util.Collection;
21  import java.util.Set;
22  import java.util.HashSet;
23  import java.util.List;
24  import java.util.stream.StreamSupport;
25  import java.util.stream.Collectors;
26  
27  import org.junit.Assert;
28  import org.junit.Test;
29  
30  import org.apache.commons.rng.UniformRandomProvider;
31  import org.apache.commons.rng.simple.RandomSource;
32  
33  import org.apache.commons.math4.neuralnet.FeatureInitializer;
34  import org.apache.commons.math4.neuralnet.FeatureInitializerFactory;
35  import org.apache.commons.math4.neuralnet.Network;
36  import org.apache.commons.math4.neuralnet.Neuron;
37  import org.apache.commons.math4.neuralnet.SquareNeighbourhood;
38  
39  import static org.junit.jupiter.api.Assertions.assertThrows;
40  
41  /**
42   * Tests for {@link NeuronSquareMesh2D} and {@link Network} functionality for
43   * a two-dimensional network.
44   */
45  public class NeuronSquareMesh2DTest {
46  
47      private final UniformRandomProvider rng = RandomSource.SPLIT_MIX_64.create();
48      private final FeatureInitializer init = FeatureInitializerFactory.uniform(rng, 0, 2);
49  
50      @Test
51      public void testMinimalNetworkSize1() {
52          final FeatureInitializer[] initArray = {init};
53  
54          assertThrows(IllegalArgumentException.class, () ->
55                  new NeuronSquareMesh2D(1, false,
56                                         2, false,
57                                         SquareNeighbourhood.VON_NEUMANN,
58                                         initArray));
59      }
60  
61      @Test
62      public void testMinimalNetworkSize2() {
63          final FeatureInitializer[] initArray = {init};
64  
65          assertThrows(IllegalArgumentException.class, () ->
66                  new NeuronSquareMesh2D(2, false,
67                                         0, false,
68                                         SquareNeighbourhood.VON_NEUMANN,
69                                         initArray));
70      }
71  
72      @Test
73      public void testGetFeaturesSize() {
74          final FeatureInitializer[] initArray = {init, init, init};
75  
76          final Network net = new NeuronSquareMesh2D(2, false,
77                                                     2, false,
78                                                     SquareNeighbourhood.VON_NEUMANN,
79                                                     initArray).getNetwork();
80          Assert.assertEquals(3, net.getFeaturesSize());
81      }
82  
83      @Test
84      public void testAccessors() {
85          final FeatureInitializer[] initArray = {init};
86          NeuronSquareMesh2D map;
87  
88          for (SquareNeighbourhood type : SquareNeighbourhood.values()) {
89              map = new NeuronSquareMesh2D(4, false, 2, true, type, initArray);
90              Assert.assertFalse(map.isWrappedRow());
91              Assert.assertTrue(map.isWrappedColumn());
92              Assert.assertEquals(type, map.getSquareNeighbourhood());
93  
94              map = new NeuronSquareMesh2D(3, true, 4, false, type, initArray);
95              Assert.assertTrue(map.isWrappedRow());
96              Assert.assertFalse(map.isWrappedColumn());
97              Assert.assertEquals(type, map.getSquareNeighbourhood());
98          }
99      }
100 
101     /*
102      * Test assumes that the network is
103      *
104      *  0-----1
105      *  |     |
106      *  |     |
107      *  2-----3
108      */
109     @Test
110     public void test2x2Network() {
111         final FeatureInitializer[] initArray = {init};
112         final Network net = new NeuronSquareMesh2D(2, false,
113                                                    2, false,
114                                                    SquareNeighbourhood.VON_NEUMANN,
115                                                    initArray).getNetwork();
116         Collection<Neuron> neighbours;
117 
118         // Neurons 0 and 3.
119         for (long id : new long[] {0, 3 }) {
120             neighbours = net.getNeighbours(net.getNeuron(id));
121             for (long nId : new long[] {1, 2 }) {
122                 Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
123             }
124             // Ensures that no other neurons is in the neighbourhood set.
125             Assert.assertEquals(2, neighbours.size());
126         }
127 
128         // Neurons 1 and 2.
129         for (long id : new long[] {1, 2 }) {
130             neighbours = net.getNeighbours(net.getNeuron(id));
131             for (long nId : new long[] {0, 3 }) {
132                 Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
133             }
134             // Ensures that no other neurons is in the neighbourhood set.
135             Assert.assertEquals(2, neighbours.size());
136         }
137     }
138 
139     /*
140      * Test assumes that the network is
141      *
142      *  0-----1
143      *  |     |
144      *  |     |
145      *  2-----3
146      */
147     @Test
148     public void test2x2Network2() {
149         final FeatureInitializer[] initArray = {init};
150         final Network net = new NeuronSquareMesh2D(2, false,
151                                                    2, false,
152                                                    SquareNeighbourhood.MOORE,
153                                                    initArray).getNetwork();
154         Collection<Neuron> neighbours;
155 
156         // All neurons
157         for (long id : new long[] {0, 1, 2, 3 }) {
158             neighbours = net.getNeighbours(net.getNeuron(id));
159             for (long nId : new long[] {0, 1, 2, 3 }) {
160                 if (id != nId) {
161                     Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
162                 }
163             }
164         }
165     }
166 
167     /*
168      * Test assumes that the network is
169      *
170      *  0-----1-----2
171      *  |     |     |
172      *  |     |     |
173      *  3-----4-----5
174      */
175     @Test
176     public void test3x2CylinderNetwork() {
177         final FeatureInitializer[] initArray = {init};
178         final Network net = new NeuronSquareMesh2D(2, false,
179                                                    3, true,
180                                                    SquareNeighbourhood.VON_NEUMANN,
181                                                    initArray).getNetwork();
182         Collection<Neuron> neighbours;
183 
184         // Neuron 0.
185         neighbours = net.getNeighbours(net.getNeuron(0));
186         for (long nId : new long[] {1, 2, 3 }) {
187             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
188         }
189         // Ensures that no other neurons is in the neighbourhood set.
190         Assert.assertEquals(3, neighbours.size());
191 
192         // Neuron 1.
193         neighbours = net.getNeighbours(net.getNeuron(1));
194         for (long nId : new long[] {0, 2, 4 }) {
195             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
196         }
197         // Ensures that no other neurons is in the neighbourhood set.
198         Assert.assertEquals(3, neighbours.size());
199 
200         // Neuron 2.
201         neighbours = net.getNeighbours(net.getNeuron(2));
202         for (long nId : new long[] {0, 1, 5 }) {
203             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
204         }
205         // Ensures that no other neurons is in the neighbourhood set.
206         Assert.assertEquals(3, neighbours.size());
207 
208         // Neuron 3.
209         neighbours = net.getNeighbours(net.getNeuron(3));
210         for (long nId : new long[] {0, 4, 5 }) {
211             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
212         }
213         // Ensures that no other neurons is in the neighbourhood set.
214         Assert.assertEquals(3, neighbours.size());
215 
216         // Neuron 4.
217         neighbours = net.getNeighbours(net.getNeuron(4));
218         for (long nId : new long[] {1, 3, 5 }) {
219             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
220         }
221         // Ensures that no other neurons is in the neighbourhood set.
222         Assert.assertEquals(3, neighbours.size());
223 
224         // Neuron 5.
225         neighbours = net.getNeighbours(net.getNeuron(5));
226         for (long nId : new long[] {2, 3, 4 }) {
227             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
228         }
229         // Ensures that no other neurons is in the neighbourhood set.
230         Assert.assertEquals(3, neighbours.size());
231     }
232 
233     /*
234      * Test assumes that the network is
235      *
236      *  0-----1-----2
237      *  |     |     |
238      *  |     |     |
239      *  3-----4-----5
240      */
241     @Test
242     public void test3x2CylinderNetwork2() {
243         final FeatureInitializer[] initArray = {init};
244         final Network net = new NeuronSquareMesh2D(2, false,
245                                                    3, true,
246                                                    SquareNeighbourhood.MOORE,
247                                                    initArray).getNetwork();
248         Collection<Neuron> neighbours;
249 
250         // All neurons.
251         for (long id : new long[] {0, 1, 2, 3, 4, 5 }) {
252             neighbours = net.getNeighbours(net.getNeuron(id));
253             for (long nId : new long[] {0, 1, 2, 3, 4, 5 }) {
254                 if (id != nId) {
255                     Assert.assertTrue("id=" + id + " nId=" + nId,
256                                       neighbours.contains(net.getNeuron(nId)));
257                 }
258             }
259         }
260     }
261 
262     /*
263      * Test assumes that the network is
264      *
265      *  0-----1-----2
266      *  |     |     |
267      *  |     |     |
268      *  3-----4-----5
269      *  |     |     |
270      *  |     |     |
271      *  6-----7-----8
272      */
273     @Test
274     public void test3x3TorusNetwork() {
275         final FeatureInitializer[] initArray = {init};
276         final Network net = new NeuronSquareMesh2D(3, true,
277                                                    3, true,
278                                                    SquareNeighbourhood.VON_NEUMANN,
279                                                    initArray).getNetwork();
280         Collection<Neuron> neighbours;
281 
282         // Neuron 0.
283         neighbours = net.getNeighbours(net.getNeuron(0));
284         for (long nId : new long[] {1, 2, 3, 6 }) {
285             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
286         }
287         // Ensures that no other neurons is in the neighbourhood set.
288         Assert.assertEquals(4, neighbours.size());
289 
290         // Neuron 1.
291         neighbours = net.getNeighbours(net.getNeuron(1));
292         for (long nId : new long[] {0, 2, 4, 7 }) {
293             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
294         }
295         // Ensures that no other neurons is in the neighbourhood set.
296         Assert.assertEquals(4, neighbours.size());
297 
298         // Neuron 2.
299         neighbours = net.getNeighbours(net.getNeuron(2));
300         for (long nId : new long[] {0, 1, 5, 8 }) {
301             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
302         }
303         // Ensures that no other neurons is in the neighbourhood set.
304         Assert.assertEquals(4, neighbours.size());
305 
306         // Neuron 3.
307         neighbours = net.getNeighbours(net.getNeuron(3));
308         for (long nId : new long[] {0, 4, 5, 6 }) {
309             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
310         }
311         // Ensures that no other neurons is in the neighbourhood set.
312         Assert.assertEquals(4, neighbours.size());
313 
314         // Neuron 4.
315         neighbours = net.getNeighbours(net.getNeuron(4));
316         for (long nId : new long[] {1, 3, 5, 7 }) {
317             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
318         }
319         // Ensures that no other neurons is in the neighbourhood set.
320         Assert.assertEquals(4, neighbours.size());
321 
322         // Neuron 5.
323         neighbours = net.getNeighbours(net.getNeuron(5));
324         for (long nId : new long[] {2, 3, 4, 8 }) {
325             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
326         }
327         // Ensures that no other neurons is in the neighbourhood set.
328         Assert.assertEquals(4, neighbours.size());
329 
330         // Neuron 6.
331         neighbours = net.getNeighbours(net.getNeuron(6));
332         for (long nId : new long[] {0, 3, 7, 8 }) {
333             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
334         }
335         // Ensures that no other neurons is in the neighbourhood set.
336         Assert.assertEquals(4, neighbours.size());
337 
338         // Neuron 7.
339         neighbours = net.getNeighbours(net.getNeuron(7));
340         for (long nId : new long[] {1, 4, 6, 8 }) {
341             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
342         }
343         // Ensures that no other neurons is in the neighbourhood set.
344         Assert.assertEquals(4, neighbours.size());
345 
346         // Neuron 8.
347         neighbours = net.getNeighbours(net.getNeuron(8));
348         for (long nId : new long[] {2, 5, 6, 7 }) {
349             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
350         }
351         // Ensures that no other neurons is in the neighbourhood set.
352         Assert.assertEquals(4, neighbours.size());
353     }
354 
355     /*
356      * Test assumes that the network is
357      *
358      *  0-----1-----2
359      *  |     |     |
360      *  |     |     |
361      *  3-----4-----5
362      *  |     |     |
363      *  |     |     |
364      *  6-----7-----8
365      */
366     @Test
367     public void test3x3TorusNetwork2() {
368         final FeatureInitializer[] initArray = {init};
369         final Network net = new NeuronSquareMesh2D(3, true,
370                                                    3, true,
371                                                    SquareNeighbourhood.MOORE,
372                                                    initArray).getNetwork();
373         Collection<Neuron> neighbours;
374 
375         // All neurons.
376         for (long id : new long[] {0, 1, 2, 3, 4, 5, 6, 7, 8 }) {
377             neighbours = net.getNeighbours(net.getNeuron(id));
378             for (long nId : new long[] {0, 1, 2, 3, 4, 5, 6, 7, 8 }) {
379                 if (id != nId) {
380                     Assert.assertTrue("id=" + id + " nId=" + nId,
381                                       neighbours.contains(net.getNeuron(nId)));
382                 }
383             }
384         }
385     }
386 
387     /*
388      * Test assumes that the network is
389      *
390      *  0-----1-----2
391      *  |     |     |
392      *  |     |     |
393      *  3-----4-----5
394      *  |     |     |
395      *  |     |     |
396      *  6-----7-----8
397      */
398     @Test
399     public void test3x3CylinderNetwork() {
400         final FeatureInitializer[] initArray = {init};
401         final Network net = new NeuronSquareMesh2D(3, false,
402                                                    3, true,
403                                                    SquareNeighbourhood.MOORE,
404                                                    initArray).getNetwork();
405         Collection<Neuron> neighbours;
406 
407         // Neuron 0.
408         neighbours = net.getNeighbours(net.getNeuron(0));
409         for (long nId : new long[] {1, 2, 3, 4, 5}) {
410             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
411         }
412         // Ensures that no other neurons is in the neighbourhood set.
413         Assert.assertEquals(5, neighbours.size());
414 
415         // Neuron 1.
416         neighbours = net.getNeighbours(net.getNeuron(1));
417         for (long nId : new long[] {0, 2, 3, 4, 5 }) {
418             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
419         }
420         // Ensures that no other neurons is in the neighbourhood set.
421         Assert.assertEquals(5, neighbours.size());
422 
423         // Neuron 2.
424         neighbours = net.getNeighbours(net.getNeuron(2));
425         for (long nId : new long[] {0, 1, 3, 4, 5 }) {
426             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
427         }
428         // Ensures that no other neurons is in the neighbourhood set.
429         Assert.assertEquals(5, neighbours.size());
430 
431         // Neuron 3.
432         neighbours = net.getNeighbours(net.getNeuron(3));
433         for (long nId : new long[] {0, 1, 2, 4, 5, 6, 7, 8 }) {
434             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
435         }
436         // Ensures that no other neurons is in the neighbourhood set.
437         Assert.assertEquals(8, neighbours.size());
438 
439         // Neuron 4.
440         neighbours = net.getNeighbours(net.getNeuron(4));
441         for (long nId : new long[] {0, 1, 2, 3, 5, 6, 7, 8 }) {
442             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
443         }
444         // Ensures that no other neurons is in the neighbourhood set.
445         Assert.assertEquals(8, neighbours.size());
446 
447         // Neuron 5.
448         neighbours = net.getNeighbours(net.getNeuron(5));
449         for (long nId : new long[] {0, 1, 2, 3, 4, 6, 7, 8 }) {
450             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
451         }
452         // Ensures that no other neurons is in the neighbourhood set.
453         Assert.assertEquals(8, neighbours.size());
454 
455         // Neuron 6.
456         neighbours = net.getNeighbours(net.getNeuron(6));
457         for (long nId : new long[] {3, 4, 5, 7, 8 }) {
458             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
459         }
460         // Ensures that no other neurons is in the neighbourhood set.
461         Assert.assertEquals(5, neighbours.size());
462 
463         // Neuron 7.
464         neighbours = net.getNeighbours(net.getNeuron(7));
465         for (long nId : new long[] {3, 4, 5, 6, 8 }) {
466             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
467         }
468         // Ensures that no other neurons is in the neighbourhood set.
469         Assert.assertEquals(5, neighbours.size());
470 
471         // Neuron 8.
472         neighbours = net.getNeighbours(net.getNeuron(8));
473         for (long nId : new long[] {3, 4, 5, 6, 7 }) {
474             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
475         }
476         // Ensures that no other neurons is in the neighbourhood set.
477         Assert.assertEquals(5, neighbours.size());
478     }
479 
480     /*
481      * Test assumes that the network is
482      *
483      *  0-----1-----2
484      *  |     |     |
485      *  |     |     |
486      *  3-----4-----5
487      *  |     |     |
488      *  |     |     |
489      *  6-----7-----8
490      */
491     @Test
492     public void test3x3CylinderNetwork2() {
493         final FeatureInitializer[] initArray = {init};
494         final Network net = new NeuronSquareMesh2D(3, false,
495                                                    3, false,
496                                                    SquareNeighbourhood.MOORE,
497                                                    initArray).getNetwork();
498         Collection<Neuron> neighbours;
499 
500         // Neuron 0.
501         neighbours = net.getNeighbours(net.getNeuron(0));
502         for (long nId : new long[] {1, 3, 4}) {
503             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
504         }
505         // Ensures that no other neurons is in the neighbourhood set.
506         Assert.assertEquals(3, neighbours.size());
507 
508         // Neuron 1.
509         neighbours = net.getNeighbours(net.getNeuron(1));
510         for (long nId : new long[] {0, 2, 3, 4, 5 }) {
511             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
512         }
513         // Ensures that no other neurons is in the neighbourhood set.
514         Assert.assertEquals(5, neighbours.size());
515 
516         // Neuron 2.
517         neighbours = net.getNeighbours(net.getNeuron(2));
518         for (long nId : new long[] {1, 4, 5 }) {
519             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
520         }
521         // Ensures that no other neurons is in the neighbourhood set.
522         Assert.assertEquals(3, neighbours.size());
523 
524         // Neuron 3.
525         neighbours = net.getNeighbours(net.getNeuron(3));
526         for (long nId : new long[] {0, 1, 4, 6, 7 }) {
527             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
528         }
529         // Ensures that no other neurons is in the neighbourhood set.
530         Assert.assertEquals(5, neighbours.size());
531 
532         // Neuron 4.
533         neighbours = net.getNeighbours(net.getNeuron(4));
534         for (long nId : new long[] {0, 1, 2, 3, 5, 6, 7, 8 }) {
535             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
536         }
537         // Ensures that no other neurons is in the neighbourhood set.
538         Assert.assertEquals(8, neighbours.size());
539 
540         // Neuron 5.
541         neighbours = net.getNeighbours(net.getNeuron(5));
542         for (long nId : new long[] {1, 2, 4, 7, 8 }) {
543             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
544         }
545         // Ensures that no other neurons is in the neighbourhood set.
546         Assert.assertEquals(5, neighbours.size());
547 
548         // Neuron 6.
549         neighbours = net.getNeighbours(net.getNeuron(6));
550         for (long nId : new long[] {3, 4, 7 }) {
551             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
552         }
553         // Ensures that no other neurons is in the neighbourhood set.
554         Assert.assertEquals(3, neighbours.size());
555 
556         // Neuron 7.
557         neighbours = net.getNeighbours(net.getNeuron(7));
558         for (long nId : new long[] {3, 4, 5, 6, 8 }) {
559             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
560         }
561         // Ensures that no other neurons is in the neighbourhood set.
562         Assert.assertEquals(5, neighbours.size());
563 
564         // Neuron 8.
565         neighbours = net.getNeighbours(net.getNeuron(8));
566         for (long nId : new long[] {4, 5, 7 }) {
567             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
568         }
569         // Ensures that no other neurons is in the neighbourhood set.
570         Assert.assertEquals(3, neighbours.size());
571     }
572 
573     /*
574      * Test assumes that the network is
575      *
576      *  0-----1-----2-----3-----4
577      *  |     |     |     |     |
578      *  |     |     |     |     |
579      *  5-----6-----7-----8-----9
580      *  |     |     |     |     |
581      *  |     |     |     |     |
582      *  10----11----12----13---14
583      *  |     |     |     |     |
584      *  |     |     |     |     |
585      *  15----16----17----18---19
586      *  |     |     |     |     |
587      *  |     |     |     |     |
588      *  20----21----22----23---24
589      */
590     @Test
591     public void testConcentricNeighbourhood() {
592         final FeatureInitializer[] initArray = {init};
593         final Network net = new NeuronSquareMesh2D(5, true,
594                                                    5, true,
595                                                    SquareNeighbourhood.VON_NEUMANN,
596                                                    initArray).getNetwork();
597 
598         Collection<Neuron> neighbours;
599         Collection<Neuron> exclude = new HashSet<>();
600 
601         // Level-1 neighbourhood.
602         neighbours = net.getNeighbours(net.getNeuron(12));
603         for (long nId : new long[] {7, 11, 13, 17 }) {
604             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
605         }
606         // Ensures that no other neurons is in the neighbourhood set.
607         Assert.assertEquals(4, neighbours.size());
608 
609         // 1. Add the neuron to the "exclude" list.
610         exclude.add(net.getNeuron(12));
611         // 2. Add all neurons from level-1 neighbourhood.
612         exclude.addAll(neighbours);
613         // 3. Retrieve level-2 neighbourhood.
614         neighbours = net.getNeighbours(neighbours, exclude);
615         for (long nId : new long[] {6, 8, 16, 18, 2, 10, 14, 22 }) {
616             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
617         }
618         // Ensures that no other neurons is in the neighbourhood set.
619         Assert.assertEquals(8, neighbours.size());
620     }
621 
622     /*
623      * Test assumes that the network is
624      *
625      *  0-----1-----2-----3-----4
626      *  |     |     |     |     |
627      *  |     |     |     |     |
628      *  5-----6-----7-----8-----9
629      *  |     |     |     |     |
630      *  |     |     |     |     |
631      *  10----11----12----13---14
632      *  |     |     |     |     |
633      *  |     |     |     |     |
634      *  15----16----17----18---19
635      *  |     |     |     |     |
636      *  |     |     |     |     |
637      *  20----21----22----23---24
638      */
639     @Test
640     public void testConcentricNeighbourhood2() {
641         final FeatureInitializer[] initArray = {init};
642         final Network net = new NeuronSquareMesh2D(5, true,
643                                                    5, true,
644                                                    SquareNeighbourhood.MOORE,
645                                                    initArray).getNetwork();
646 
647         Collection<Neuron> neighbours;
648         Collection<Neuron> exclude = new HashSet<>();
649 
650         // Level-1 neighbourhood.
651         neighbours = net.getNeighbours(net.getNeuron(8));
652         for (long nId : new long[] {2, 3, 4, 7, 9, 12, 13, 14}) {
653             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
654         }
655         // Ensures that no other neurons is in the neighbourhood set.
656         Assert.assertEquals(8, neighbours.size());
657 
658         // 1. Add the neuron to the "exclude" list.
659         exclude.add(net.getNeuron(8));
660         // 2. Add all neurons from level-1 neighbourhood.
661         exclude.addAll(neighbours);
662         // 3. Retrieve level-2 neighbourhood.
663         neighbours = net.getNeighbours(neighbours, exclude);
664         for (long nId : new long[] {1, 6, 11, 16, 17, 18, 19, 15, 10, 5, 0, 20, 24, 23, 22, 21}) {
665             Assert.assertTrue(neighbours.contains(net.getNeuron(nId)));
666         }
667         // Ensures that no other neurons is in the neighbourhood set.
668         Assert.assertEquals(16, neighbours.size());
669     }
670 
671     /*
672      * Test assumes that the network is
673      *
674      *  0-----1
675      *  |     |
676      *  |     |
677      *  2-----3
678      */
679     @Test
680     public void testGetNeuron() {
681         final FeatureInitializer[] initArray = {init};
682         final NeuronSquareMesh2D net = new NeuronSquareMesh2D(2, false,
683                                                               2, true,
684                                                               SquareNeighbourhood.VON_NEUMANN,
685                                                               initArray);
686         Assert.assertEquals(0, net.getNeuron(0, 0).getIdentifier());
687         Assert.assertEquals(1, net.getNeuron(0, 1).getIdentifier());
688         Assert.assertEquals(2, net.getNeuron(1, 0).getIdentifier());
689         Assert.assertEquals(3, net.getNeuron(1, 1).getIdentifier());
690 
691         try {
692             net.getNeuron(2, 0);
693             Assert.fail("exception expected");
694         } catch (IllegalArgumentException e) {
695             // Expected.
696         }
697         try {
698             net.getNeuron(0, 2);
699             Assert.fail("exception expected");
700         } catch (IllegalArgumentException e) {
701             // Expected.
702         }
703         try {
704             net.getNeuron(-1, 0);
705             Assert.fail("exception expected");
706         } catch (IllegalArgumentException e) {
707             // Expected.
708         }
709         try {
710             net.getNeuron(0, -1);
711             Assert.fail("exception expected");
712         } catch (IllegalArgumentException e) {
713             // Expected.
714         }
715     }
716 
717     /*
718      * Test assumes that the network is
719      *
720      *  0-----1-----2
721      *  |     |     |
722      *  |     |     |
723      *  3-----4-----5
724      *  |     |     |
725      *  |     |     |
726      *  6-----7-----8
727      */
728     @Test
729     public void testGetNeuronAlongDirection() {
730         final FeatureInitializer[] initArray = {init};
731         final NeuronSquareMesh2D net = new NeuronSquareMesh2D(3, false,
732                                                               3, false,
733                                                               SquareNeighbourhood.VON_NEUMANN,
734                                                               initArray);
735         Assert.assertEquals(0, net.getNeuron(1, 1,
736                                              NeuronSquareMesh2D.HorizontalDirection.LEFT,
737                                              NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
738         Assert.assertEquals(1, net.getNeuron(1, 1,
739                                              NeuronSquareMesh2D.HorizontalDirection.CENTER,
740                                              NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
741         Assert.assertEquals(2, net.getNeuron(1, 1,
742                                              NeuronSquareMesh2D.HorizontalDirection.RIGHT,
743                                              NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
744         Assert.assertEquals(3, net.getNeuron(1, 1,
745                                              NeuronSquareMesh2D.HorizontalDirection.LEFT,
746                                              NeuronSquareMesh2D.VerticalDirection.CENTER).getIdentifier());
747         Assert.assertEquals(4, net.getNeuron(1, 1,
748                                              NeuronSquareMesh2D.HorizontalDirection.CENTER,
749                                              NeuronSquareMesh2D.VerticalDirection.CENTER).getIdentifier());
750         Assert.assertEquals(5, net.getNeuron(1, 1,
751                                              NeuronSquareMesh2D.HorizontalDirection.RIGHT,
752                                              NeuronSquareMesh2D.VerticalDirection.CENTER).getIdentifier());
753         Assert.assertEquals(6, net.getNeuron(1, 1,
754                                              NeuronSquareMesh2D.HorizontalDirection.LEFT,
755                                              NeuronSquareMesh2D.VerticalDirection.DOWN).getIdentifier());
756         Assert.assertEquals(7, net.getNeuron(1, 1,
757                                              NeuronSquareMesh2D.HorizontalDirection.CENTER,
758                                              NeuronSquareMesh2D.VerticalDirection.DOWN).getIdentifier());
759         Assert.assertEquals(8, net.getNeuron(1, 1,
760                                              NeuronSquareMesh2D.HorizontalDirection.RIGHT,
761                                              NeuronSquareMesh2D.VerticalDirection.DOWN).getIdentifier());
762 
763         // Locations not in map.
764         Assert.assertNull(net.getNeuron(0, 1,
765                                         NeuronSquareMesh2D.HorizontalDirection.CENTER,
766                                         NeuronSquareMesh2D.VerticalDirection.UP));
767         Assert.assertNull(net.getNeuron(1, 0,
768                                         NeuronSquareMesh2D.HorizontalDirection.LEFT,
769                                         NeuronSquareMesh2D.VerticalDirection.CENTER));
770         Assert.assertNull(net.getNeuron(2, 1,
771                                         NeuronSquareMesh2D.HorizontalDirection.CENTER,
772                                         NeuronSquareMesh2D.VerticalDirection.DOWN));
773         Assert.assertNull(net.getNeuron(1, 2,
774                                         NeuronSquareMesh2D.HorizontalDirection.RIGHT,
775                                         NeuronSquareMesh2D.VerticalDirection.CENTER));
776     }
777 
778     /*
779      * Test assumes that the network is
780      *
781      *  0-----1-----2
782      *  |     |     |
783      *  |     |     |
784      *  3-----4-----5
785      *  |     |     |
786      *  |     |     |
787      *  6-----7-----8
788      */
789     @Test
790     public void testGetNeuronAlongDirectionWrappedMap() {
791         final FeatureInitializer[] initArray = {init};
792         final NeuronSquareMesh2D net = new NeuronSquareMesh2D(3, true,
793                                                               3, true,
794                                                               SquareNeighbourhood.VON_NEUMANN,
795                                                               initArray);
796         // No wrapping.
797         Assert.assertEquals(3, net.getNeuron(0, 0,
798                                              NeuronSquareMesh2D.HorizontalDirection.CENTER,
799                                              NeuronSquareMesh2D.VerticalDirection.DOWN).getIdentifier());
800         // With wrapping.
801         Assert.assertEquals(2, net.getNeuron(0, 0,
802                                              NeuronSquareMesh2D.HorizontalDirection.LEFT,
803                                              NeuronSquareMesh2D.VerticalDirection.CENTER).getIdentifier());
804         Assert.assertEquals(7, net.getNeuron(0, 0,
805                                              NeuronSquareMesh2D.HorizontalDirection.RIGHT,
806                                              NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
807         Assert.assertEquals(8, net.getNeuron(0, 0,
808                                              NeuronSquareMesh2D.HorizontalDirection.LEFT,
809                                              NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
810         Assert.assertEquals(6, net.getNeuron(0, 0,
811                                              NeuronSquareMesh2D.HorizontalDirection.CENTER,
812                                              NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
813         Assert.assertEquals(5, net.getNeuron(0, 0,
814                                              NeuronSquareMesh2D.HorizontalDirection.LEFT,
815                                              NeuronSquareMesh2D.VerticalDirection.DOWN).getIdentifier());
816 
817         // No wrapping.
818         Assert.assertEquals(1, net.getNeuron(1, 2,
819                                              NeuronSquareMesh2D.HorizontalDirection.LEFT,
820                                              NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
821         // With wrapping.
822         Assert.assertEquals(0, net.getNeuron(1, 2,
823                                              NeuronSquareMesh2D.HorizontalDirection.RIGHT,
824                                              NeuronSquareMesh2D.VerticalDirection.UP).getIdentifier());
825         Assert.assertEquals(3, net.getNeuron(1, 2,
826                                              NeuronSquareMesh2D.HorizontalDirection.RIGHT,
827                                              NeuronSquareMesh2D.VerticalDirection.CENTER).getIdentifier());
828         Assert.assertEquals(6, net.getNeuron(1, 2,
829                                              NeuronSquareMesh2D.HorizontalDirection.RIGHT,
830                                              NeuronSquareMesh2D.VerticalDirection.DOWN).getIdentifier());
831     }
832 
833     @Test
834     public void testIterator() {
835         final FeatureInitializer[] initArray = {init};
836         final NeuronSquareMesh2D map = new NeuronSquareMesh2D(3, true,
837                                                               3, true,
838                                                               SquareNeighbourhood.VON_NEUMANN,
839                                                               initArray);
840         final Set<Neuron> fromMap = new HashSet<>();
841         for (Neuron n : map) {
842             fromMap.add(n);
843         }
844 
845         final Network net = map.getNetwork();
846         final Set<Neuron> fromNet = new HashSet<>();
847         for (Neuron n : net) {
848             fromNet.add(n);
849         }
850 
851         for (Neuron n : fromMap) {
852             Assert.assertTrue(fromNet.contains(n));
853         }
854         for (Neuron n : fromNet) {
855             Assert.assertTrue(fromMap.contains(n));
856         }
857     }
858 
859     @Test
860     public void testDataVisualization() {
861         final FeatureInitializer[] initArray = {init};
862         final NeuronSquareMesh2D map = new NeuronSquareMesh2D(3, true,
863                                                               3, true,
864                                                               SquareNeighbourhood.VON_NEUMANN,
865                                                               initArray);
866 
867         // Trivial test: Use neurons' features as data.
868 
869         final List<double[]> data = StreamSupport.stream(map.spliterator(), false)
870             .map(n -> n.getFeatures())
871             .collect(Collectors.toList());
872         final NeuronSquareMesh2D.DataVisualization v = map.computeQualityIndicators(data);
873 
874         final int numRows = map.getNumberOfRows();
875         final int numCols = map.getNumberOfColumns();
876 
877         // Test hits.
878         final double[][] hits = v.getNormalizedHits();
879         final double expectedHits = 1d / (numRows * numCols);
880         for (int i = 0; i < numRows; i++) {
881             for (int j = 0; j < numCols; j++) {
882                 Assert.assertEquals(expectedHits, hits[i][j], 0d);
883             }
884         }
885 
886         // Test quantization error.
887         final double[][] qe = v.getQuantizationError();
888         final double expectedQE = 0;
889         for (int i = 0; i < numRows; i++) {
890             for (int j = 0; j < numCols; j++) {
891                 Assert.assertEquals(expectedQE, qe[i][j], 0d);
892             }
893         }
894     }
895 
896 }