All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.numenta.nupic.util.SparseBinaryMatrix Maven / Gradle / Ivy

The newest version!
/* ---------------------------------------------------------------------
 * 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