/** * The average number of columns per input, taking into account the topology of the inputs and * columns. This value is used to calculate the inhibition radius. This function supports an * arbitrary number of dimensions. If the number of column dimensions does not match the number of * input dimensions, we treat the missing, or phantom dimensions as 'ones'. * * @param c the {@link Connections} (spatial pooler memory) * @return */ public double avgColumnsPerInput(Connections c) { int[] colDim = Arrays.copyOf(c.getColumnDimensions(), c.getColumnDimensions().length); int[] inputDim = Arrays.copyOf(c.getInputDimensions(), c.getInputDimensions().length); double[] columnsPerInput = ArrayUtils.divide( ArrayUtils.toDoubleArray(colDim), ArrayUtils.toDoubleArray(inputDim), 0, 0); return ArrayUtils.average(columnsPerInput); }
/** * Called to initialize the structural anatomy with configured values and prepare the anatomical * entities for activation. * * @param c */ public void initMatrices(final Connections c) { SparseObjectMatrix<Column> mem = c.getMemory(); c.setMemory(mem == null ? mem = new SparseObjectMatrix<>(c.getColumnDimensions()) : mem); c.setInputMatrix(new SparseBinaryMatrix(c.getInputDimensions())); // Calculate numInputs and numColumns int numInputs = c.getInputMatrix().getMaxIndex() + 1; int numColumns = c.getMemory().getMaxIndex() + 1; if (numColumns <= 0) { throw new InvalidSPParamValueException("Invalid number of columns: " + numColumns); } if (numInputs <= 0) { throw new InvalidSPParamValueException("Invalid number of inputs: " + numInputs); } c.setNumInputs(numInputs); c.setNumColumns(numColumns); // Fill the sparse matrix with column objects for (int i = 0; i < numColumns; i++) { mem.set(i, new Column(c.getCellsPerColumn(), i)); } c.setPotentialPools(new SparseObjectMatrix<Pool>(c.getMemory().getDimensions())); c.setConnectedMatrix(new SparseBinaryMatrix(new int[] {numColumns, numInputs})); // Initialize state meta-management statistics c.setOverlapDutyCycles(new double[numColumns]); c.setActiveDutyCycles(new double[numColumns]); c.setMinOverlapDutyCycles(new double[numColumns]); c.setMinActiveDutyCycles(new double[numColumns]); c.setBoostFactors(new double[numColumns]); Arrays.fill(c.getBoostFactors(), 1); }
/** * The range of connectedSynapses per column, averaged for each dimension. This value is used to * calculate the inhibition radius. This variation of the function supports arbitrary column * dimensions. * * @param c the {@link Connections} (spatial pooler memory) * @param columnIndex the current column for which to avg. * @return */ public double avgConnectedSpanForColumnND(Connections c, int columnIndex) { int[] dimensions = c.getInputDimensions(); int[] connected = c.getColumn(columnIndex).getProximalDendrite().getConnectedSynapsesSparse(c); if (connected == null || connected.length == 0) return 0; int[] maxCoord = new int[c.getInputDimensions().length]; int[] minCoord = new int[c.getInputDimensions().length]; Arrays.fill(maxCoord, -1); Arrays.fill(minCoord, ArrayUtils.max(dimensions)); SparseMatrix<?> inputMatrix = c.getInputMatrix(); for (int i = 0; i < connected.length; i++) { maxCoord = ArrayUtils.maxBetween(maxCoord, inputMatrix.computeCoordinates(connected[i])); minCoord = ArrayUtils.minBetween(minCoord, inputMatrix.computeCoordinates(connected[i])); } return ArrayUtils.average(ArrayUtils.add(ArrayUtils.subtract(maxCoord, minCoord), 1)); }
/** * Maps a column to its respective input index, keeping to the topology of the region. It takes * the index of the column as an argument and determines what is the index of the flattened input * vector that is to be the center of the column's potential pool. It distributes the columns over * the inputs uniformly. The return value is an integer representing the index of the input bit. * Examples of the expected output of this method: * If the topology is one dimensional, and the * column index is 0, this method will return the input index 0. If the column index is 1, and * there are 3 columns over 7 inputs, this method will return the input index 3. * If the topology * is two dimensional, with column dimensions [3, 5] and input dimensions [7, 11], and the column * index is 3, the method returns input index 8. * * @param columnIndex The index identifying a column in the permanence, potential and connectivity * matrices. * @return A boolean value indicating that boundaries should be ignored. */ public int mapColumn(Connections c, int columnIndex) { int[] columnCoords = c.getMemory().computeCoordinates(columnIndex); double[] colCoords = ArrayUtils.toDoubleArray(columnCoords); double[] ratios = ArrayUtils.divide(colCoords, ArrayUtils.toDoubleArray(c.getColumnDimensions()), 0, 0); double[] inputCoords = ArrayUtils.multiply(ArrayUtils.toDoubleArray(c.getInputDimensions()), ratios, 0, 0); inputCoords = ArrayUtils.d_add( inputCoords, ArrayUtils.multiply( ArrayUtils.divide( ArrayUtils.toDoubleArray(c.getInputDimensions()), ArrayUtils.toDoubleArray(c.getColumnDimensions()), 0, 0), 0.5)); int[] inputCoordInts = ArrayUtils.clip(ArrayUtils.toIntArray(inputCoords), c.getInputDimensions(), -1); return c.getInputMatrix().computeIndex(inputCoordInts); }