Skip to content

Commit 7751368

Browse files
committed
Added SDR class
1 parent 2bfeac6 commit 7751368

File tree

2 files changed

+235
-0
lines changed

2 files changed

+235
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/* ---------------------------------------------------------------------
2+
* Numenta Platform for Intelligent Computing (NuPIC)
3+
* Copyright (C) 2014, Numenta, Inc. Unless you have an agreement
4+
* with Numenta, Inc., for a separate license for this software code, the
5+
* following terms and conditions apply:
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU Affero Public License version 3 as
9+
* published by the Free Software Foundation.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14+
* See the GNU Affero Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Affero Public License
17+
* along with this program. If not, see http://www.gnu.org/licenses.
18+
*
19+
* http://numenta.org/licenses/
20+
* ---------------------------------------------------------------------
21+
*/
22+
package org.numenta.nupic;
23+
24+
import java.util.Arrays;
25+
import java.util.Collection;
26+
import java.util.List;
27+
import java.util.Set;
28+
import java.util.stream.IntStream;
29+
30+
import org.numenta.nupic.model.Cell;
31+
import org.numenta.nupic.model.Column;
32+
33+
/**
34+
* <p>
35+
* For now, a utility class for convenience operations
36+
* on integer arrays understood to be algorithmic inputs
37+
* and outputs; and conversions to and from canonical objects.
38+
* </p><p>
39+
* Later, this may become the encapsulation of the vectors
40+
* representing SDRs and previously treated as integer arrays.
41+
* </p><p>
42+
* <b>NOTE:</b> <em>Eclipse is not up to date with its leakable resource inspection.
43+
* Streams not derived from channels (i.e. from arrays or lists) do not
44+
* need explicit closing.</em>
45+
* </p>
46+
* <p>
47+
* see here: http://stackoverflow.com/questions/25796118/java-8-streams-and-try-with-resources
48+
* </p>
49+
* @author cogmission
50+
*/
51+
public class SDR {
52+
53+
/**
54+
* Converts a vector of {@link Cell} indexes to {@link Column} indexes.
55+
*
56+
* @param cells the indexes of the cells to convert
57+
* @param cellsPerColumn the defined number of cells per column
58+
* false if not.
59+
* @return the column indexes of the specified cells.
60+
*/
61+
public static int[] asColumnIndices(int[] cells, int cellsPerColumn) {
62+
IntStream op = Arrays.stream(cells);
63+
return op.map(cell -> cell / cellsPerColumn).distinct().toArray();
64+
}
65+
66+
/**
67+
* Converts a vector of {@link Cell} indexes to {@link Column} indexes.
68+
*
69+
* @param cells the indexes of the cells to convert
70+
* @param cellsPerColumn the defined number of cells per column
71+
* false if not.
72+
* @return the column indexes of the specified cells.
73+
*/
74+
public static int[] asColumnIndices(List<Integer> cells, int cellsPerColumn) {
75+
IntStream op = cells.stream().mapToInt(c -> c);
76+
return op.map(cellIdx -> cellIdx / cellsPerColumn).distinct().toArray();
77+
}
78+
79+
/**
80+
* Converts a List of {@link Cell}s to {@link Column} indexes.
81+
*
82+
* @param cells the list of cells to convert
83+
* @param cellsPerColumn the defined number of cells per column
84+
* false if not.
85+
* @return the column indexes of the specified cells.
86+
*/
87+
public static int[] cellsToColumns(List<Cell> cells, int cellsPerColumn) {
88+
IntStream op = cells.stream().mapToInt(c -> c.getIndex());
89+
90+
return op.map(cellIdx -> cellIdx / cellsPerColumn).distinct().toArray();
91+
}
92+
93+
/**
94+
* Converts a Set of {@link Cell}s to {@link Column} indexes.
95+
*
96+
* @param cells the list of cells to convert
97+
* @param cellsPerColumn the defined number of cells per column
98+
*
99+
* @return the column indexes of the specified cells.
100+
*/
101+
public static int[] cellsAsColumnIndices(Set<Cell> cells, int cellsPerColumn) {
102+
return cells.stream().mapToInt(c -> c.getIndex())
103+
.sorted().map(cellIdx -> cellIdx / cellsPerColumn).distinct().toArray();
104+
}
105+
106+
/**
107+
* Converts a {@link Collection} of {@link Cell}s to a list
108+
* of cell indexes.
109+
*
110+
* @param cells
111+
* @return
112+
*/
113+
public static int[] asCellIndices(Collection<Cell> cells) {
114+
return cells.stream().mapToInt(cell -> cell.getIndex()).sorted().toArray();
115+
}
116+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package org.numenta.nupic;
2+
3+
import static org.junit.Assert.assertFalse;
4+
import static org.junit.Assert.assertTrue;
5+
6+
import java.util.ArrayList;
7+
import java.util.Arrays;
8+
import java.util.List;
9+
import java.util.Set;
10+
import java.util.stream.Collectors;
11+
12+
import org.junit.Test;
13+
import org.numenta.nupic.algorithms.TemporalMemory;
14+
import org.numenta.nupic.model.Cell;
15+
16+
17+
public class SDRTest {
18+
19+
@Test
20+
public void testAsCellIndices() {
21+
TemporalMemory tm = new TemporalMemory();
22+
Connections cn = new Connections();
23+
cn.setColumnDimensions(new int[] { 64, 64 });
24+
cn.setCellsPerColumn(4);
25+
tm.init(cn);
26+
27+
int[] expectedIndexes = { 0, 3, 4, 16383 };
28+
Set<Cell> cells = cn.getCellSet(expectedIndexes);
29+
30+
int[] cellIndices = SDR.asCellIndices(cells);
31+
32+
assertTrue(Arrays.equals(cellIndices, expectedIndexes));
33+
}
34+
35+
@Test
36+
public void testAsColumnIndices() {
37+
int cellsPerColumn = 4;
38+
39+
int[] expectedIndexes = { 0, 3, 4, 4095 };
40+
int[] inputIndexes = Arrays.stream(expectedIndexes).map(i -> i * cellsPerColumn).toArray();
41+
int[] result = SDR.asColumnIndices(inputIndexes, cellsPerColumn);
42+
assertTrue(Arrays.equals(expectedIndexes, result));
43+
44+
// Test failure
45+
expectedIndexes = new int[] { 0, 3, 4, 4, 4095 }; // Has duplicate ("4")
46+
inputIndexes = Arrays.stream(expectedIndexes).map(i -> i * cellsPerColumn).toArray();
47+
result = SDR.asColumnIndices(inputIndexes, cellsPerColumn); // "true" is Erroneous state
48+
assertFalse(Arrays.equals(expectedIndexes, result));
49+
50+
// Test correct state fixes above
51+
int[] arrInputIndexes = new int[] { 0, 3, 4, 4, 4095 }; // Has duplicate ("4")
52+
expectedIndexes = new int[] { 0, 3, 4, 4095 }; // Has duplicate ("4")
53+
inputIndexes = Arrays.stream(arrInputIndexes).map(i -> i * cellsPerColumn).toArray();
54+
result = SDR.asColumnIndices(inputIndexes, cellsPerColumn); // "false" is correct state
55+
assertTrue(Arrays.equals(expectedIndexes, result));
56+
}
57+
58+
@Test
59+
public void testAsColumnIndicesList() {
60+
int cellsPerColumn = 4;
61+
62+
int[] expectedIndexes = { 0, 3, 4, 4095 };
63+
int[] inputIndexes = Arrays.stream(expectedIndexes).map(i -> i * cellsPerColumn).toArray();
64+
int[] result = SDR.asColumnIndices(
65+
Arrays.stream(inputIndexes).boxed().collect(Collectors.toList()), cellsPerColumn);
66+
assertTrue(Arrays.equals(expectedIndexes, result));
67+
68+
// Test failure
69+
expectedIndexes = new int[] { 0, 3, 4, 4, 4095 }; // Has duplicate ("4")
70+
inputIndexes = Arrays.stream(expectedIndexes).map(i -> i * cellsPerColumn).toArray();
71+
result = SDR.asColumnIndices(
72+
Arrays.stream(inputIndexes).boxed().collect(Collectors.toList()), cellsPerColumn); // "true" is Erroneous state
73+
assertFalse(Arrays.equals(expectedIndexes, result));
74+
75+
// Test correct state fixes above
76+
int[] arrInputIndexes = new int[] { 0, 3, 4, 4, 4095 }; // Has duplicate ("4")
77+
expectedIndexes = new int[] { 0, 3, 4, 4095 }; // Has duplicate ("4")
78+
inputIndexes = Arrays.stream(arrInputIndexes).map(i -> i * cellsPerColumn).toArray();
79+
System.out.println("result = " + Arrays.toString(result));
80+
result = SDR.asColumnIndices(
81+
Arrays.stream(inputIndexes).boxed().collect(Collectors.toList()), cellsPerColumn); // "false" is correct state
82+
assertTrue(Arrays.equals(expectedIndexes, result));
83+
}
84+
85+
@Test
86+
public void testCellsAsColumnIndicesList() {
87+
TemporalMemory tm = new TemporalMemory();
88+
Connections cn = new Connections();
89+
cn.setColumnDimensions(new int[] { 64, 64 });
90+
cn.setCellsPerColumn(4);
91+
tm.init(cn);
92+
93+
int[] expectedIndexes = { 0, 3, 4, 4095 };
94+
int[] inputIndices = Arrays.stream(expectedIndexes).map(i -> i * cn.getCellsPerColumn()).toArray();
95+
List<Cell> cells = new ArrayList<Cell>(cn.getCellSet(inputIndices));
96+
97+
int[] result = SDR.cellsToColumns(cells, cn.getCellsPerColumn());
98+
99+
assertTrue(Arrays.equals(expectedIndexes, result));
100+
}
101+
102+
@Test
103+
public void testCellsAsColumnIndicesSet() {
104+
TemporalMemory tm = new TemporalMemory();
105+
Connections cn = new Connections();
106+
cn.setColumnDimensions(new int[] { 64, 64 });
107+
cn.setCellsPerColumn(4);
108+
tm.init(cn);
109+
110+
int[] expectedIndexes = { 0, 3, 4, 4095 };
111+
int[] inputIndices = Arrays.stream(expectedIndexes).map(i -> i * cn.getCellsPerColumn()).toArray();
112+
Set<Cell> cells = cn.getCellSet(inputIndices);
113+
114+
int[] result = SDR.cellsAsColumnIndices(cells, cn.getCellsPerColumn());
115+
116+
assertTrue(Arrays.equals(expectedIndexes, result));
117+
}
118+
119+
}

0 commit comments

Comments
 (0)