Package edu.ucla.sspace.vector

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

/*
* 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.DoubleEntry;
import edu.ucla.sspace.util.ObjectEntry;

import gnu.trove.iterator.TDoubleIterator;
import gnu.trove.map.TIntDoubleMap;
import gnu.trove.map.hash.TIntDoubleHashMap;

import java.io.Serializable;

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


/**
* A {@code SparseVector} implementation backed by a {@code Map}.  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 SparseHashDoubleVector
        extends AbstractDoubleVector
        implements SparseDoubleVector, Serializable { //Iterable<DoubleEntry>, Serializable {

    private static final long serialVersionUID = 1L;

    private final TIntDoubleHashMap vector;

    private int maxLength;

    private double magnitude;

    private int[] nonZeroIndices;

    /**
     * Creates a new {@link SparseHashDoubleVector} with an unbounded length.
     */
    public SparseHashDoubleVector() {
        this(Integer.MAX_VALUE);
    }

    /**
     * Creates a new vector of the specified length
     *
     * @param length the length of this vector
     */
    public SparseHashDoubleVector(int length) {
        maxLength = length;
        vector = new TIntDoubleHashMap();
    }

    /**
     * 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 SparseHashDoubleVector(double[] values) {
        maxLength = values.length;
        vector = new TIntDoubleHashMap();
        nonZeroIndices = null;
        magnitude = -1;
        for (int i = 0; i < values.length; ++i) {
            if (values[i] != 0) {
                vector.put(i, values[i]);
            }
        }
    }

    /**
     * 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 SparseHashDoubleVector(DoubleVector values) {
        maxLength = values.length();
        nonZeroIndices = null;
        magnitude = -1;
        if (values instanceof SparseHashDoubleVector) {
            SparseHashDoubleVector v = (SparseHashDoubleVector)values;
            vector = new TIntDoubleHashMap(v.vector);
        }
        else if (values instanceof SparseVector) {
            int[] nonZeros = ((SparseVector) values).getNonZeroIndices();
            vector = new TIntDoubleHashMap(nonZeros.length);
            for (int index : nonZeros)
                vector.put(index, values.get(index));
        } else {
            vector = new TIntDoubleHashMap();
            for (int index = 0; index < values.length(); ++index) {
                double value = values.get(index);
                if (value != 0d)
                    vector.put(index, value);
            }
        }
    }
   
    /**
     * {@inheritDoc}
     */
    public double add(int index, double delta) {
        double val = vector.get(index) + delta;
        if (val == 0)
            vector.remove(index);       
        else
            set(index, val);
        nonZeroIndices = null;
        magnitude = -1;
        return val;
    }

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

    /**
     * {@inheritDoc}
     */
    public Double getValue(int index) {
        return get(index);
    }

    /**
     * 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<DoubleEntry> iterator() {
        return new DoubleIterator();
    }
     */

    /**
     * {@inheritDoc}
     */
    public void set(int index, Number value) {
        set(index, value.doubleValue());
    }

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

    /**
     * {@inheritDoc}
     */
    public double[] toArray() {
        double[] array = new double[length()];
        for (int i : vector.keys())
            array[i] = vector.get(i);
        return array;
    }

    /**
     * {@inheritDoc}
     */
    public int length() {
        return maxLength;
    }

    /**
     * {@inheritDoc}
     */
    public double magnitude() {
        if (magnitude < 0) {
            magnitude = 0;
            TDoubleIterator iter = vector.valueCollection().iterator();
            while (iter.hasNext()) {
                double d = iter.next();
                magnitude += d*d;
            }
            magnitude = Math.sqrt(magnitude);
        }
        return magnitude;
    }

    /**
     * {@inheritDoc}
     */
    public int[] getNonZeroIndices() {
        if (nonZeroIndices == null) {
            nonZeroIndices = vector.keys();
            Arrays.sort(nonZeroIndices);
        }
        return nonZeroIndices;
    }

    /**
     * {@inheritDoc}
     */
    public SparseDoubleVector instanceCopy() {
        return new SparseHashDoubleVector(maxLength);
    }

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

    //     Iterator<ObjectEntry<Number>> it;

    //     public DoubleIterator() {
    //         it = vector.iterator();
    //     }

    //     public boolean hasNext() {
    //         return it.hasNext();
    //     }

    //     public DoubleEntry next() {
    //         final ObjectEntry<Number> e = it.next();
    //         return new DoubleEntry() {
    //             public int index() { return e.index(); }
    //             public double value() { return e.value().doubleValue(); }
    //         };
    //     }

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

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

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.