
org.numenta.nupic.util.SparseBinaryMatrix 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) 2014, 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 gnu.trove.TIntCollection;
import gnu.trove.iterator.TIntIterator;
import gnu.trove.list.TIntList;
import gnu.trove.map.TIntIntMap;
import gnu.trove.map.hash.TIntIntHashMap;
import java.lang.reflect.Array;
import java.util.Arrays;
@SuppressWarnings("rawtypes")
public class SparseBinaryMatrix extends SparseMatrix {
private TIntIntMap sparseMap = new TIntIntHashMap();
private int[] trueCounts;
private Object backingArray;
public SparseBinaryMatrix(int[] dimensions) {
this(dimensions, false);
}
public SparseBinaryMatrix(int[] dimensions, boolean useColumnMajorOrdering) {
super(dimensions, useColumnMajorOrdering);
this.backingArray = Array.newInstance(int.class, dimensions);
this.trueCounts = new int[dimensions[0]];
}
/**
* Called during mutation operations to simultaneously set the value
* on the backing array dynamically.
* @param val
* @param coordinates
*/
private void back(int val, int... coordinates) {
ArrayUtils.setValue(this.backingArray, val, coordinates);
//update true counts
trueCounts[coordinates[0]] = ArrayUtils.aggregateArray(((Object[])this.backingArray)[coordinates[0]]);
}
/**
* Returns the slice specified by the passed in coordinates.
* The array is returned as an object, therefore it is the caller's
* responsibility to cast the array to the appropriate dimensions.
*
* @param coordinates the coordinates which specify the returned array
* @return the array specified
* @throws IllegalArgumentException if the specified coordinates address
* an actual value instead of the array holding it.
*/
public Object getSlice(int... coordinates) {
Object slice = backingArray;
for(int i = 0;i < coordinates.length;i++) {
slice = Array.get(slice, coordinates[i]);;
}
//Ensure return value is of type Array
if(!slice.getClass().isArray()) {
throw new IllegalArgumentException(
"This method only returns the array holding the specified index: " +
Arrays.toString(coordinates));
}
return slice;
}
/**
* Fills the specified results array with the result of the
* matrix vector multiplication.
*
* @param inputVector the right side vector
* @param results the results array
*/
public void rightVecSumAtNZ(int[] inputVector, int[] results) {
for(int i = 0;i < dimensions[0];i++) {
int[] slice = (int[])(dimensions.length > 1 ? getSlice(i) : backingArray);
for(int j = 0;j < slice.length;j++) {
results[i] += (inputVector[j] * slice[j]);
}
}
}
/**
* Sets the value at the specified index.
*
* @param index the index the object will occupy
* @param object the object to be indexed.
*/
@Override
public SparseBinaryMatrix set(int index, int value) {
int[] coordinates = computeCoordinates(index);
return set(value, coordinates);
}
/**
* Sets the value to be indexed at the index
* computed from the specified coordinates.
* @param coordinates the row major coordinates [outer --> ,...,..., inner]
* @param object the object to be indexed.
*/
@Override
public SparseBinaryMatrix set(int value, int... coordinates) {
sparseMap.put(computeIndex(coordinates), value);
back(value, coordinates);
return this;
}
/**
* Sets the specified values at the specified indexes.
*
* @param indexes indexes of the values to be set
* @param values the values to be indexed.
*
* @return this {@code SparseMatrix} implementation
*/
public SparseBinaryMatrix set(int[] indexes, int[] values) {
for(int i = 0;i < indexes.length;i++) {
set(indexes[i], values[i]);
}
return this;
}
/**
* Sets the value at the specified index skipping the automatic
* truth statistic tallying of the real method.
*
* @param index the index the object will occupy
* @param object the object to be indexed.
*/
public SparseBinaryMatrix setForTest(int index, int value) {
sparseMap.put(index, value);
return this;
}
/**
* Call This for TEST METHODS ONLY
* Sets the specified values at the specified indexes.
*
* @param indexes indexes of the values to be set
* @param values the values to be indexed.
*
* @return this {@code SparseMatrix} implementation
*/
public SparseBinaryMatrix set(int[] indexes, int[] values, boolean isTest) {
for(int i = 0;i < indexes.length;i++) {
if(isTest) setForTest(indexes[i], values[i]);
else set(indexes[i], values[i]);
}
return this;
}
/**
* Returns the count of 1's set on the specified row.
* @param index
* @return
*/
public int getTrueCount(int index) {
return trueCounts[index];
}
/**
* Sets the count of 1's on the specified row.
* @param index
* @param count
*/
public void setTrueCount(int index, int count) {
this.trueCounts[index] = count;
}
/**
* Get the true counts for all outer indexes.
* @return
*/
public int[] getTrueCounts() {
return trueCounts;
}
/**
* Clears the true counts prior to a cycle where they're
* being set
*/
public void clearStatistics(int row) {
int[] slice = (int[])Array.get(backingArray, row);
Arrays.fill(slice, 0);
trueCounts[row] = 0;
sparseMap.put(row, 0);
}
/**
* Returns an outer array of T values.
* @return
*/
@Override
protected int[] values() {
return sparseMap.values();
}
/**
* Returns the int value at the index computed from the specified coordinates
* @param coordinates the coordinates from which to retrieve the indexed object
* @return the indexed object
*/
public int getIntValue(int... coordinates) {
return sparseMap.get(computeIndex(coordinates));
}
/**
* Returns the T at the specified index.
*
* @param index the index of the T to return
* @return the T at the specified index.
*/
@Override
public int getIntValue(int index) {
return sparseMap.get(index);
}
/**
* Returns a sorted array of occupied indexes.
* @return a sorted array of occupied indexes.
*/
@Override
public int[] getSparseIndices() {
return reverse(sparseMap.keys());
}
/**
* This {@code SparseBinaryMatrix} will contain the operation of or-ing
* the inputMatrix with the contents of this matrix; returning this matrix
* as the result.
*
* @param inputMatrix the matrix containing the "on" bits to or
* @return this matrix
*/
public SparseBinaryMatrix or(SparseBinaryMatrix inputMatrix) {
int[] mask = inputMatrix.getSparseIndices();
int[] ones = new int[mask.length];
Arrays.fill(ones, 1);
return set(mask, ones);
}
/**
* This {@code SparseBinaryMatrix} will contain the operation of or-ing
* the sparse list with the contents of this matrix; returning this matrix
* as the result.
*
* @param onBitIndexes the matrix containing the "on" bits to or
* @return this matrix
*/
public SparseBinaryMatrix or(TIntCollection onBitIndexes) {
int[] ones = new int[onBitIndexes.size()];
Arrays.fill(ones, 1);
return set(onBitIndexes.toArray(), ones);
}
/**
* This {@code SparseBinaryMatrix} will contain the operation of or-ing
* the sparse array with the contents of this matrix; returning this matrix
* as the result.
*
* @param onBitIndexes the int array containing the "on" bits to or
* @return this matrix
*/
public SparseBinaryMatrix or(int[] onBitIndexes) {
int[] ones = new int[onBitIndexes.length];
Arrays.fill(ones, 1);
return set(onBitIndexes, ones);
}
/**
* Returns true if the on bits of the specified matrix are
* matched by the on bits of this matrix. It is allowed that
* this matrix have more on bits than the specified matrix.
*
* @param matrix
* @return
*/
public boolean all(SparseBinaryMatrix matrix) {
return sparseMap.keySet().containsAll(matrix.sparseMap.keys());
}
/**
* Returns true if the on bits of the specified list are
* matched by the on bits of this matrix. It is allowed that
* this matrix have more on bits than the specified matrix.
*
* @param matrix
* @return
*/
public boolean all(TIntCollection onBits) {
return sparseMap.keySet().containsAll(onBits);
}
/**
* Returns true if the on bits of the specified array are
* matched by the on bits of this matrix. It is allowed that
* this matrix have more on bits than the specified matrix.
*
* @param matrix
* @return
*/
public boolean all(int[] onBits) {
return sparseMap.keySet().containsAll(onBits);
}
/**
* Returns true if any of the on bits of the specified matrix are
* matched by the on bits of this matrix. It is allowed that
* this matrix have more on bits than the specified matrix.
*
* @param matrix
* @return
*/
public boolean any(SparseBinaryMatrix matrix) {
for(int i : matrix.sparseMap.keys()) {
if(sparseMap.containsKey(i)) return true;
}
return false;
}
/**
* Returns true if any of the on bit indexes of the specified collection are
* matched by the on bits of this matrix. It is allowed that
* this matrix have more on bits than the specified matrix.
*
* @param matrix
* @return
*/
public boolean any(TIntList onBits) {
for(TIntIterator i = onBits.iterator();i.hasNext();) {
if(sparseMap.containsKey(i.next())) return true;
}
return false;
}
/**
* Returns true if any of the on bit indexes of the specified matrix are
* matched by the on bits of this matrix. It is allowed that
* this matrix have more on bits than the specified matrix.
*
* @param matrix
* @return
*/
public boolean any(int[] onBits) {
for(int i : onBits) {
if(sparseMap.containsKey(i)) return true;
}
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy