
org.numenta.nupic.util.SparseBinaryMatrix Maven / Gradle / Ivy
/* ---------------------------------------------------------------------
* 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 Affero 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 Affero Public License for more details.
*
* You should have received a copy of the GNU Affero 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.lang.reflect.Array;
import java.util.Arrays;
import org.numenta.nupic.model.Persistable;
/**
* Implementation of a sparse matrix which contains binary integer
* values only.
*
* @author cogmission
*
*/
public class SparseBinaryMatrix extends AbstractSparseBinaryMatrix implements Persistable {
/** keep it simple */
private static final long serialVersionUID = 1L;
private Object backingArray;
/**
* Constructs a new {@code SparseBinaryMatrix} with the specified
* dimensions (defaults to row major ordering)
*
* @param dimensions each indexed value is a dimension size
*/
public SparseBinaryMatrix(int[] dimensions) {
this(dimensions, false);
}
/**
* Constructs a new {@code SparseBinaryMatrix} with the specified dimensions,
* allowing the specification of column major ordering if desired.
* (defaults to row major ordering)
*
* @param dimensions each indexed value is a dimension size
* @param useColumnMajorOrdering if true, indicates column first iteration, otherwise
* row first iteration is the default (if false).
*/
public SparseBinaryMatrix(int[] dimensions, boolean useColumnMajorOrdering) {
super(dimensions, useColumnMajorOrdering);
this.backingArray = Array.newInstance(int.class, dimensions);
}
/**
* 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
setTrueCount(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.
*/
@Override
public Object getSlice(int... coordinates) {
Object slice = ArrayUtils.getValue(this.backingArray, coordinates);
//Ensure return value is of type Array
if(!slice.getClass().isArray()) {
sliceError(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]);
}
}
}
/**
* 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, double stimulusThreshold) {
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]);
if(j==slice.length - 1) {
results[i] -= results[i] < stimulusThreshold ? results[i] : 0;
}
}
}
}
/**
* Sets the value at the specified index.
*
* @param index the index the object will occupy
* @param object the object to be indexed.
*/
@Override
public AbstractSparseBinaryMatrix 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 AbstractSparseBinaryMatrix set(int value, int... coordinates) {
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 AbstractSparseBinaryMatrix set(int[] indexes, int[] values) {
for(int i = 0;i < indexes.length;i++) {
set(indexes[i], values[i]);
}
return this;
}
/**
* Clears the true counts prior to a cycle where they're
* being set
*/
public void clearStatistics(int row) {
this.setTrueCount(row, 0);
int[] slice = (int[])Array.get(backingArray, row);
Arrays.fill(slice, 0);
}
@Override
public AbstractSparseBinaryMatrix set(int index, Object value) {
set(index, ((Integer) value).intValue());
return this;
}
@Override
public Integer get(int index) {
int[] coordinates = computeCoordinates(index);
if (coordinates.length == 1) {
return Array.getInt(this.backingArray, index);
}
else return (Integer) ArrayUtils.getValue(this.backingArray, coordinates);
}
@Override
public AbstractSparseBinaryMatrix setForTest(int index, int value) {
ArrayUtils.setValue(this.backingArray, value, computeCoordinates(index));
return this;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy