
org.numenta.nupic.util.Topology Maven / Gradle / Ivy
/* ---------------------------------------------------------------------
* 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