![JAR search and dependency download from the Maven repository](/logo.png)
org.numenta.nupic.util.Topology Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of htm.java Show documentation
Show all versions of htm.java Show documentation
The Java version of Numenta's HTM technology
/* ---------------------------------------------------------------------
* Numenta Platform for Intelligent Computing (NuPIC)
* Copyright (C) 2016, Numenta, Inc. Unless you have an agreement
* with Numenta, Inc., for a separate license for this software code, the
* following terms and conditions apply:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses.
*
* http://numenta.org/licenses/
* ---------------------------------------------------------------------
*/
package org.numenta.nupic.util;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
import gnu.trove.list.TIntList;
import gnu.trove.list.array.TIntArrayList;
public class Topology extends Coordinator implements Serializable {
/** keep it simple */
private static final long serialVersionUID = 1L;
private IntGenerator[] igs;
private int[] centerPosition;
/**
* Constructs a new {@link AbstractFlatMatrix} object to be configured with specified
* dimensions and major ordering.
* @param shape the dimensions of this matrix
*/
public Topology(int... shape) {
super(shape, false);
}
/**
* Translate an index into coordinates, using the given coordinate system.
*
* @param index The index of the point. The coordinates are expressed as a single index by
* using the dimensions as a mixed radix definition. For example, in dimensions
* 42x10, the point [1, 4] is index 1*420 + 4*10 = 460.
* @return A array of coordinates of length len(dimensions).
*/
public int[] coordinatesFromIndex(int index) {
return computeCoordinates(index);
}
/**
* Translate coordinates into an index, using the given coordinate system.
*
* @param coordinates A array of coordinates of length dimensions.size().
* @param shape The coordinate system.
* @return The index of the point. The coordinates are expressed as a single index by
* using the dimensions as a mixed radix definition. For example, in dimensions
* 42x10, the point [1, 4] is index 1*420 + 4*10 = 460.
*/
public int indexFromCoordinates(int... coordinates) {
return computeIndex(coordinates);
}
/**
* Get the points in the neighborhood of a point.
*
* A point's neighborhood is the n-dimensional hypercube with sides ranging
* [center - radius, center + radius], inclusive. For example, if there are two
* dimensions and the radius is 3, the neighborhood is 6x6. Neighborhoods are
* truncated when they are near an edge.
*
* @param centerIndex The index of the point. The coordinates are expressed as a single index by
* using the dimensions as a mixed radix definition. For example, in dimensions
* 42x10, the point [1, 4] is index 1*420 + 4*10 = 460.
* @param radius The radius of this neighborhood about the centerIndex.
* @return The points in the neighborhood, including centerIndex.
*/
public int[] neighborhood(int centerIndex, int radius) {
centerPosition = coordinatesFromIndex(centerIndex);
igs = IntStream.range(0, dimensions.length)
.mapToObj(i ->
IntGenerator.of(Math.max(0, centerPosition[i] - radius),
Math.min(dimensions[i] - 1, centerPosition[i] + radius) + 1))
.toArray(IntGenerator[]::new);
List result = new ArrayList<>();
result.add(new TIntArrayList());
List interim = new ArrayList<>();
for(IntGenerator pool : igs) {
int size = result.size();
interim.clear();
interim.addAll(result);
result.clear();
for(int x = 0;x < size;x++) {
TIntList lx = interim.get(x);
pool.reset();
for(int y = 0;y < pool.size();y++) {
int py = pool.next();
TIntArrayList tl = new TIntArrayList();
tl.addAll(lx);
tl.add(py);
result.add(tl);
}
}
}
return result.stream().mapToInt(tl -> indexFromCoordinates(tl.toArray())).toArray();
}
/**
* Like {@link #neighborhood(int, int)}, except that the neighborhood isn't truncated when it's
* near an edge. It wraps around to the other side.
*
* @param centerIndex The index of the point. The coordinates are expressed as a single index by
* using the dimensions as a mixed radix definition. For example, in dimensions
* 42x10, the point [1, 4] is index 1*420 + 4*10 = 460.
* @param radius The radius of this neighborhood about the centerIndex.
* @return The points in the neighborhood, including centerIndex.
*/
public int[] wrappingNeighborhood(int centerIndex, int radius) {
int[] cp = coordinatesFromIndex(centerIndex);
IntGenerator[] igs = IntStream.range(0, dimensions.length)
.mapToObj(i ->
new IntGenerator(cp[i] - radius,
Math.min((cp[i] - radius) + dimensions[i] - 1, cp[i] + radius) + 1))
.toArray(IntGenerator[]::new);
List result = new ArrayList<>();
result.add(new TIntArrayList());
List interim = new ArrayList<>();
for(int i = 0;i < igs.length;i++) {
IntGenerator pool = igs[i];
int size = result.size();
interim.clear();
interim.addAll(result);
result.clear();
for(int x = 0;x < size;x++) {
TIntList lx = interim.get(x);
pool.reset();
for(int y = 0;y < pool.size();y++) {
int py = ArrayUtils.modulo(pool.next(), dimensions[i]);
TIntArrayList tl = new TIntArrayList();
tl.addAll(lx);
tl.add(py);
result.add(tl);
}
}
}
return result.stream().mapToInt(tl -> indexFromCoordinates(tl.toArray())).toArray();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy