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

edu.ucla.sspace.vector.Vectors Maven / Gradle / Ivy

Go to download

The S-Space Package is a collection of algorithms for building Semantic Spaces as well as a highly-scalable library for designing new distributional semantics algorithms. Distributional algorithms process text corpora and represent the semantic for words as high dimensional feature vectors. This package also includes matrices, vectors, and numerous clustering algorithms. These approaches are known by many names, such as word spaces, semantic spaces, or distributed semantics and rest upon the Distributional Hypothesis: words that appear in similar contexts have similar meanings.

The newest version!
/*
 * Copyright 2009 Keith Stevens 
 *
 * 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 .
 */

package edu.ucla.sspace.vector;

import java.util.Arrays;

import java.lang.reflect.Constructor;


/**
 * A collection of static methods that operate on or return {@link Vector}
 * instances, following a format similar to that of {@link
 * java.util.Collections}.  

* *

Unless otherwise noted, all returned {@link Vector} instances implement * {@code Serializable}. * * @author Keith Stevens * @author David Jurgens */ public class Vectors { /** * A private constructor to make this class uninstantiable. */ private Vectors() { } /** * Returns a view over the given {@code Vector} as a {@code DoubleVector}. * The returned vector is mutable but any changes will be converted into its * internal data-type, e.g. {@code int}, which may result in information * loss. * * @param v The {@code Vector} to return as a {@code DoubleVector}. * * @return a mutable {@code DoubleVector} view of {@code v} */ public static DoubleVector asDouble(Vector v) { if (v == null) throw new NullPointerException("Cannot re-type a null vector"); // NOTE: Special case the the sparse classes first to becase the // base interfaces of DoubleVectors and IntegerVectors matches as well. if (v instanceof SparseIntegerVector) return new IntAsSparseDoubleVector((SparseIntegerVector)v); if (v instanceof SparseDoubleVector) return (SparseDoubleVector) v; else if (v instanceof IntegerVector) return new IntAsDoubleVector((IntegerVector)v); else if (v instanceof DoubleVector) return (DoubleVector)v; // Base case: the vector is either of some unknown type or only // implements Vector. Therefore, wrap its contents using Vector's API. else return new ViewVectorAsDoubleVector(v); } public static SparseDoubleVector asDouble(SparseIntegerVector v) { if (v == null) throw new NullPointerException("Cannot re-type a null vector"); return new IntAsSparseDoubleVector(v); } /** * Returns a vector backed by the specified array. Any changes to the * vector are written through to the array. This method acts a bridge * between array-based and {@code Vector}-based computation. * * @param array the array backing the vector * * @return a {@code Vector} view of the array */ public static DoubleVector asVector(double[] array) { if (array == null) throw new NullPointerException("Cannot wrap a null array"); return new DoubleArrayAsVector(array); } /** * Returns a vector backed by the specified array. Any changes to the * vector are written through to the array. This method acts a bridge * between array-based and {@code Vector}-based computation. * * @param array the array backing the vector * * @return a {@code Vector} view of the array */ public static IntegerVector asVector(int[] array) { if (array == null) throw new NullPointerException("Cannot wrap a null array"); return new IntArrayAsVector(array); } /** * Returns {@code true} if the two vectors are equal to one another. Two * {@code Vector} insances are considered equal if they contain the same * number of elements and all corresponding pairs of {@code double} values * are equal. */ public static boolean equals(DoubleVector v1, DoubleVector v2) { if (v1.length() == v2.length()) { int length = v1.length(); for (int i = 0; i < length; ++i) { if (v1.get(i) != v2.get(i)) return false; } return true; } return false; } /** * Returns {@code true} if the two integer vectors are equal to one another. * Two {@code Vector} insances are considered equal if they contain the same * number of elements and all corresponding pairs of {@code int} values * are equal. */ public static boolean equals(IntegerVector v1, IntegerVector v2) { if (v1.length() == v2.length()) { int length = v1.length(); for (int i = 0; i < length; ++i) { if (v1.get(i) != v2.get(i)) return false; } return true; } return false; } /** * Returns {@code true} if the two vectors are equal to one another. Two * {@code Vector} insances are considered equal if they contain the same * number of elements and all corresponding pairs of {@code Number} values * are equal. Two values {@code n1} and {@code n2} are considered equal if * {@code n1.equals(n2)}. */ public static boolean equals(Vector v1, Vector v2) { if (v1.length() == v2.length()) { int length = v1.length(); for (int i = 0; i < length; ++i) { Number n1 = v1.getValue(i); Number n2 = v2.getValue(i); if (!n1.equals(n2)) return false; } return true; } return false; } /** * Returns an immutable view of the given {@code DoubleVector}. * * @param vector The {@code DoubleVector} to decorate as immutable. * @return An immutable version of {@code vector}. */ public static DoubleVector immutable(DoubleVector vector) { if (vector == null) throw new NullPointerException("Cannot create an immutable " + "null vector"); return new DoubleVectorView(vector, true); } /** * Returns an immutable view of the given {@code SparseDoubleVector}. * * @param vector The {@code DoubleVector} to decorate as immutable. * @return An immutable version of {@code vector}. */ public static SparseDoubleVector immutable(SparseDoubleVector vector) { if (vector == null) throw new NullPointerException("Cannot create an immutable " + "null vector"); return new ViewDoubleAsDoubleSparseVector(vector, true); } /** * Returns an immutable view of the given {@code IntegerVector}. * * @param vector The {@code IntegerVector} to decorate as immutable. * @return An immutable version of {@code vector}. */ public static IntegerVector immutable(IntegerVector vector) { if (vector == null) throw new NullPointerException("Cannot create an immutable " + "null vector"); return new IntegerVectorView(vector, true); } /** * Returns an immutable view of the given {@code SparseIntegerVector}. * * @param vector The {@code IntegerVector} to decorate as immutable. * @return An immutable version of {@code vector}. */ public static SparseIntegerVector immutable(SparseIntegerVector vector) { if (vector == null) throw new NullPointerException("Cannot create an immutable " + "null vector"); return new ViewIntegerAsIntegerSparseVector(vector, true); } /** * Returns an immutable view of the given {@code Vector}. * * @param vector The {@code DoubleVector} to decorate as immutable. * @return An immutable version of {@code vector}. */ public static Vector immutable(Vector vector) { if (vector == null) throw new NullPointerException("Cannot create an immutable " + "null vector"); return new VectorView(vector, true); } /** * Returns a thread-safe version of a {@code DoubleVector} that guarantees * atomic access to all operations. The returned vector allows concurrent * read access. * * @param vector The {@code DoubleVector} to decorate as atomic. * @return An atomic version of {@code vector}. */ public static DoubleVector atomic(DoubleVector vector) { if (vector == null) throw new NullPointerException("Cannot create an atomic " + "null vector"); return new AtomicVector(vector); } /** * Returns a syncrhonized view of a given {@code DoubleVector}. This may * show slightly better performance than using an {@code AtomicVector} in * some use cases. * * @param vector The {@code DoubleVector} to decorate as synchronized. * @return An atomic version of {@code vector}. */ public static DoubleVector synchronizedVector(DoubleVector vector) { if (vector == null) throw new NullPointerException("Cannot create an synchronized " + "null vector"); return new SynchronizedVector(vector); } public static DoubleVector scale(DoubleVector vector, double scale) { if (vector instanceof SparseDoubleVector) return scaleSparse((SparseDoubleVector) vector, scale); return new ScaledDoubleVector(vector, scale); } public static SparseDoubleVector scaleSparse(SparseDoubleVector vector, double scale) { return new ScaledSparseDoubleVector(vector, scale); } public static DoubleVector scaleByMagnitude(DoubleVector vector) { if (vector instanceof SparseDoubleVector) return scaleByMagnitude((SparseDoubleVector) vector); return new ScaledDoubleVector(vector, 1d/vector.magnitude()); } public static DoubleVector scaleByMagnitude(SparseDoubleVector vector) { return new ScaledSparseDoubleVector(vector, 1d/vector.magnitude()); } /** * Returns a subview for the given {@code DoubleVector} with a specified * offset and length. * * @param vector the {@code Vector} whose values will be shown in the view * @param offset the index of {@code v} at which the first index of this * view starts * @param length the length of this view. * * @throws IllegalArgumentException if

  • {@code offset} is * negative
  • {@code length} is less than zero
  • the sum of {@code * offset} plus {@code length} is greater than the length of {@code * vector}
*/ public static DoubleVector subview(DoubleVector vector, int offset, int length) { if (vector == null) throw new NullPointerException("Cannot create view of a " + "null vector"); return new DoubleVectorView(vector, offset, length); } /** * Returns a subview for the given {@code SparseDoubleVector} with a * specified offset and length. * * @param vector the {@code Vector} whose values will be shown in the view * @param offset the index of {@code v} at which the first index of this * view starts * @param length the length of this view. * * @throws IllegalArgumentException if
  • {@code offset} is * negative
  • {@code length} is less than zero
  • the sum of {@code * offset} plus {@code length} is greater than the length of {@code * vector}
*/ public static SparseDoubleVector subview(SparseDoubleVector vector, int offset, int length) { if (vector == null) throw new NullPointerException("Cannot create view of a " + "null vector"); return new ViewDoubleAsDoubleSparseVector(vector, offset, length); } /** * Returns a subview for the given {@code IntegerVector} with a specified * offset and length. * * @param vector the {@code Vector} whose values will be shown in the view * @param offset the index of {@code v} at which the first index of this * view starts * @param length the length of this view. * * @throws IllegalArgumentException if
  • {@code offset} is * negative
  • {@code length} is less than zero
  • the sum of {@code * offset} plus {@code length} is greater than the length of {@code * vector}
*/ public static IntegerVector subview(IntegerVector vector, int offset, int length) { if (vector == null) throw new NullPointerException("Cannot create view of a " + "null vector"); return new IntegerVectorView(vector, offset, length); } /** * Returns a subview for the given {@code IntegerVector} with a specified * offset and length. * * @param vector the {@code Vector} whose values will be shown in the view * @param offset the index of {@code v} at which the first index of this * view starts * @param length the length of this view. * * @throws IllegalArgumentException if
  • {@code offset} is * negative
  • {@code length} is less than zero
  • the sum of {@code * offset} plus {@code length} is greater than the length of {@code * vector}
*/ public static SparseIntegerVector subview(SparseIntegerVector vector, int offset, int length) { if (vector == null) throw new NullPointerException("Cannot create view of a " + "null vector"); return new SparseIntegerVectorView(vector, offset, length); } /** * Copies all of the values from one {@code Vector} into another. After the * operation, all of the values in {@code dest} will be the same as that of * {@code source}. The legnth of {@code dest} must be as long as the length * of {@code source}. Once completed {@code dest} is returned. * * @param dest The {@code Vector} to copy values into. * @param source The {@code Vector} to copy values from. * * @return {@code dest} after being copied from {@code source}. * * @throws IllegalArgumentException if the length of {@code dest} is less * than that of {@code source}. */ public static Vector copy(Vector dest, Vector source) { for (int i = 0; i < source.length(); ++i) dest.set(i, source.getValue(i).doubleValue()); return dest; } /** * Creates a copy of a given {@code DoubleVector} with the same type as the * original. * * @param source The {@code Vector} to copy. * * @return A copy of {@code source} with the same type. */ public static DoubleVector copyOf(DoubleVector source) { if (source == null) return null; DoubleVector result = null; if (source instanceof SparseDoubleVector) { result = new CompactSparseVector(source.length()); copyFromSparseVector(result, source); } else if (source instanceof DenseVector || source instanceof ScaledDoubleVector) { result = new DenseVector(source.length()); for (int i = 0; i < source.length(); ++i) result.set(i, source.get(i)); } else if (source instanceof AmortizedSparseVector) { result = new AmortizedSparseVector(source.length()); copyFromSparseVector(result, source); } else if (source instanceof DoubleVectorView) { DoubleVectorView view = (DoubleVectorView) source; return copyOf(view.getOriginalVector()); } else { // Create a copy of the given class using reflection. // First check whether we can find a copy contructor that accepts an // instance of Vector Class sourceClazz = source.getClass(); try { Constructor constructor = sourceClazz.getConstructor(DoubleVector.class); result = (DoubleVector) constructor.newInstance(source); } // If there wasn't a copy constructor, see if there's one that // accepts the length and then we'll copy the data over manually catch (NoSuchMethodException nsme) { try { Constructor constructor = sourceClazz.getConstructor(Integer.TYPE); int length = source.length(); result = (DoubleVector) constructor.newInstance( Integer.valueOf(length)); // Copy the data over for (int i = 0; i < length; ++i) result.set(i, source.get(i)); } catch (Exception e) { throw new UnsupportedOperationException( "Could not find applicalble way to copy a vector " + "of type " + source.getClass(), e); } } catch (Exception e) { throw new UnsupportedOperationException( "Could not find applicalble way to copy a vector " + "of type " + source.getClass(), e); } } return result; } /** * Creates a copy of a given {@code Vector}. * * @param source The {@code Vector} to copy. * * @return A copy of {@code source} with the same type. */ public static Vector copyOf(Vector source) { if (source instanceof DoubleVector) return copyOf((DoubleVector) source); if (source instanceof IntegerVector) return copyOf((IntegerVector) source); Vector result = new DenseVector(source.length()); for (int i = 0; i < source.length(); ++i) result.set(i, source.getValue(i)); return result; } /** * Creates a copy of a given {@code IntegerVector} with the same type as the * original. * * @param source The {@code Vector} to copy. * * @return A copy of {@code source} with the same type. */ public static IntegerVector copyOf(IntegerVector source) { IntegerVector result = null; if (source instanceof TernaryVector) { TernaryVector v = (TernaryVector) source; int[] pos = v.positiveDimensions(); int[] neg = v.negativeDimensions(); result = new TernaryVector(source.length(), Arrays.copyOf(pos, pos.length), Arrays.copyOf(neg, neg.length)); } else if (source instanceof SparseVector) { result = new SparseHashIntegerVector(source.length()); copyFromSparseVector(result, source); } else { result = new DenseIntVector(source.length()); for (int i = 0; i < source.length(); ++i) result.set(i, source.get(i)); } return result; } /** * Creates a {@code Vector} instance of the same type and length of the * provided vector. * * @param vector a vector whose type and length should be used when creating * a new vector with the same properties * * @return a vector with the same type and length as the provided vector * * @throw IllegalArgumentException if
  • the class of the provided * vector does not have a constructor that takes in an {@code int} to * specify the length
  • the class of the provided vector cannot be * instantiated
*/ @SuppressWarnings("unchecked") public static T instanceOf(T vector) { // Check for known vector types to avoid reflection overhead if (vector instanceof CompactSparseIntegerVector) { return (T)(new CompactSparseIntegerVector(vector.length())); } // Remaining cases of vector types is being left unfinished until the // vector name refactoring is finished. -jurgens 12/7/09 else { try { Class clazz = (Class)vector.getClass(); Constructor c = clazz.getConstructor(Integer.TYPE); T copy = c.newInstance(new Object[] { vector.length() }); return copy; } catch (Exception e) { throw new IllegalArgumentException("Cannot instantiate a vector" + " of type " + vector.getClass(), e); } } } /** * Copies values from a {@code SparseVector} into another vector * * @param destination The {@code Vector to copy values into. * @param source The {@code @SparseVector} to copy values from. */ private static void copyFromSparseVector(DoubleVector destination, DoubleVector source) { int[] nonZeroIndices = ((SparseVector) source).getNonZeroIndices(); for (int index : nonZeroIndices) destination.set(index, source.get(index)); } /** * Copies values from a {@code SparseVector} into another vector * * @param destination The {@code Vector to copy values into. * @param source The {@code @SparseVector} to copy values from. */ private static void copyFromSparseVector(IntegerVector destination, IntegerVector source) { int[] nonZeroIndices = ((SparseVector) source).getNonZeroIndices(); for (int index : nonZeroIndices) destination.set(index, source.get(index)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy