Package edu.ucla.sspace.vector

Source Code of edu.ucla.sspace.vector.SparseHashIntegerVector

/*
* Copyright 2009 David Jurgens
*
* This file is part of the S-Space package and is covered under the terms and
* conditions therein.
*
* The S-Space package is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation and distributed hereunder to you.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND NO REPRESENTATIONS OR WARRANTIES,
* EXPRESS OR IMPLIED ARE MADE.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, WE MAKE
* NO REPRESENTATIONS OR WARRANTIES OF MERCHANT- ABILITY OR FITNESS FOR ANY
* PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE OR DOCUMENTATION
* WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER
* RIGHTS.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package edu.ucla.sspace.vector;

import edu.ucla.sspace.util.IntegerEntry;
import edu.ucla.sspace.util.ObjectEntry;

import java.io.Serializable;

import java.util.Arrays;
import java.util.Iterator;

import gnu.trove.iterator.TIntIterator;
import gnu.trove.iterator.TIntIntIterator;
import gnu.trove.map.TIntIntMap;
import gnu.trove.map.hash.TIntIntHashMap;


/**
* A {@code SparseVector} implementation backed by a {@code HashMap}.  This
* provides amoritized constant time access to all get and set operations, while
* using more space than the {@link CompactSparseVector} or {@link
* AmortizedSparseVector} classes.
*
* <p> See {@see SparseHashArray} for implementation details.
*
* @author David Jurgens
*/
public class SparseHashIntegerVector extends AbstractIntegerVector
         implements SparseIntegerVector, Iterable<IntegerEntry>, Serializable {

    private static final long serialVersionUID = 1L;

    private final TIntIntMap map;
   
    private final int length;

    private double magnitude;

    /**
     * Creates a new vector of the specified length
     *
     * @param length the length of this vector
     */
    public SparseHashIntegerVector(int length) {
        this.length = length;
        map = new TIntIntHashMap();
        magnitude = -1;
    }

    /**
     * Creates a new vector using the non-zero values of the specified array.
     * The created vector contains no references to the provided array, so
     * changes to either will not be reflected in the other.
     *
     * @param values the intial values for this vector to have
     */
    public SparseHashIntegerVector(int[] values) {
        this(values.length);
        for (int i = 0; i < values.length; ++i)
            if (values[i] != 0)
                map.put(i, values[i]);
        magnitude = -1;
    }

    /**
     * Creates a new vector with a copy of the date in {@code values}.  This
     * method is preferable than individually adding elements as it can
     * preallocate the space required for the data and avoid rehashing.
     */
    public SparseHashIntegerVector(IntegerVector values) {
        length = values.length();
        magnitude = -1;
        if (values instanceof SparseHashIntegerVector) {
            SparseHashIntegerVector v = (SparseHashIntegerVector)values;
            map = new TIntIntHashMap(v.map);
        }
        else if (values instanceof SparseVector) {
            int[] nonZeros = ((SparseVector) values).getNonZeroIndices();
            map = new TIntIntHashMap(nonZeros.length);
            for (int index : nonZeros)
                map.put(index, values.get(index));
        } else {
            map = new TIntIntHashMap();
            for (int index = 0; index < values.length(); ++index) {
                int value = values.get(index);
                if (value != 0)
                    map.put(index, value);
            }
        }
    }


    /**
     * {@inheritDoc}
     */
    public int add(int index, int delta) {
        int val = map.get(index);
        int newVal = val + delta;
        if (newVal == 0)
            map.remove(index);
        else
            map.put(index, newVal);
        magnitude = -1;
        return newVal;
    }

    /**
     * {@inheritDoc}
     */
    public int get(int index) {
        return map.get(index);
    }

    /**
     * {@inheritDoc}
     */
    public int[] getNonZeroIndices() {
        int[] nz = map.keys();
        Arrays.sort(nz);
        return nz;
    }

    /**
     * Returns an iterator over the non-{@code 0} values in this vector.  This
     * method makes no guarantee about the order in which the indices are
     * returned.
     */
    public Iterator<IntegerEntry> iterator() {
        return new IntegerIterator();
    }
   
    /**
     * {@inheritDoc}
     */
    public int length() {
        return length;
    }   

    /**
     * {@inheritDoc} This value is cached and recomputed as needed when the
     * vector changes.
     */
    @Override public double magnitude() {
        if (magnitude < 0) {
            magnitude = 0;
            TIntIterator iter = map.valueCollection().iterator();
            while (iter.hasNext()) {
                int i = iter.next();
                magnitude += i*i;
            }
            magnitude = Math.sqrt(magnitude);
        }
        return magnitude;
    }

    /**
     * {@inheritDoc}
     */
    public void set(int index, int value) {
        int cur = map.get(index);
        if (value == 0) {
            if (cur != 0)
                map.remove(index);
        }
        else
            map.put(index, value);
        magnitude = -1;
    }

    /**
     * An iterator over the {@code int} values in the vector, wrapping the
     * backing {@code SparseHashArray}'s own iterator.
     */
    class IntegerIterator implements Iterator<IntegerEntry> {

        TIntIntIterator iter;

        public IntegerIterator() {
            iter = map.iterator();
        }

        public boolean hasNext() {
            return iter.hasNext();
        }

        public IntegerEntry next() {
            iter.advance();
            return new IntegerEntry() {
                public int index() { return iter.key(); }
                public int value() { return iter.value(); }
            };
        }

        public void remove() {
            throw new UnsupportedOperationException(
                "Cannot remove from vector");
        }
    }
}
TOP

Related Classes of edu.ucla.sspace.vector.SparseHashIntegerVector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.