// Path: src/main/java/pitt/search/semanticvectors/vectors/VectorFactory.java
// public class VectorFactory {
//   private static final BinaryVector binaryInstance = new BinaryVector(0);
//   private static final RealVector realInstance = new RealVector(0);
//   private static final ComplexVector complexInstance =
//     new ComplexVector(0, ComplexVector.Mode.POLAR_SPARSE);
//   private static final ComplexVector complexFlatInstance =
//       new ComplexVector(0, ComplexVector.Mode.CARTESIAN);
// 
//   /**
//    * createZeroVector returns a vector set to zero. It can be used externally, but
//    * be careful particularly with Complex Vectors to make sure that polar / cartesian / hermitian
//    * modes are set correctly especially if you try to set coordinates manually after that.
//    */
//   public static Vector createZeroVector(VectorType type, int dimension) {
//     switch (type) {
//       case BINARY:
//         return new BinaryVector(dimension);
//       case REAL:
//         return new RealVector(dimension);
//       case COMPLEX:
//         return new ComplexVector(dimension, Mode.POLAR_SPARSE);
//       case COMPLEXFLAT:
//         return new ComplexVector(dimension, Mode.POLAR_SPARSE);
//       case PERMUTATION:
//     	return new PermutationVector(dimension);
//       default:
//         throw new IllegalArgumentException("Unrecognized VectorType: " + type);
//     }
//   }
//   
//   /**
//    * Generates an appropriate random vector.
//    * 
//    * @param type one of the recognized vector types
//    * @param dimension number of dimensions in the generated vector
//    * @param numEntries total number of non-zero entries; must be no greater than half of dimension
//    * @param random random number generator; passed in to enable deterministic testing
//    * @return vector generated with appropriate type, dimension and number of nonzero entries
//    */
//   public static Vector generateRandomVector(
//       VectorType type, int dimension, int numEntries, Random random) {
// 	 
// 	  if (2 * numEntries > dimension && !type.equals(VectorType.COMPLEX) && !(numEntries == dimension)) {
//       throw new RuntimeException("Requested " + numEntries + " to be filled in sparse "
//           + "vector of dimension " + dimension + ". This is not sparse and may cause problems.");
//     }
//     switch (type) {
//     case BINARY:
//       return binaryInstance.generateRandomVector(dimension, numEntries, random);
//     case REAL:
//       return realInstance.generateRandomVector(dimension, numEntries, random);
//     case COMPLEX:
//       if (!ComplexVector.getDominantMode().equals(Mode.HERMITIAN)) 
//     	  ComplexVector.setDominantMode(Mode.POLAR_DENSE);
//       return complexInstance.generateRandomVector(dimension, numEntries, random);
//     case COMPLEXFLAT:
//       ComplexVector.setDominantMode(Mode.CARTESIAN);
//       return complexInstance.generateRandomVector(dimension, numEntries, random);
//     default:
//       throw new IllegalArgumentException("Unrecognized VectorType: " + type);
//     }
//   }
// 
//   /**
//    * Returns the size in bytes expected to be taken up by the serialization
//    * of this vector in Lucene format.
//    */
//   public static int getLuceneByteSize(VectorType vectorType, int dimension) {
//     switch (vectorType) {
//       case BINARY:
//         return 8 * ((dimension / 64) );
//       case REAL:
//         return 4 * dimension;
//       case COMPLEX:
//       case COMPLEXFLAT:
//         return 8 * dimension;
//       default:
//         throw new IllegalArgumentException("Unrecognized VectorType: " + vectorType);
//     }
//   }
// }


import java.util.ArrayList;
import java.util.Random;
import pitt.search.semanticvectors.vectors.Vector;
import pitt.search.semanticvectors.vectors.VectorFactory;
	   * This implementation only works for string objects so far.
	   * 
	   * @param subsSample - if true, this method will return "null" instead of a vector for Strings that 
	   * 					 hash to keys that have been encountered with a frequency > .01*flagConfig.samplingthreshold()
	   * 					 In practice this means n-grams are subsampled more aggressively than terms
	   * 					 Subsampling follows the procedure described in Mikolov 2013, 1-sqrt(T/F), with F
	   * 					 being the cumulative count of the observations of the relevant hash code / total observed hash codes 
	   * 
	   * @param desiredObject - the string you're searching for
	   * @return vector from the VectorStore, or null if not found. 
	   */
	  public Vector getVector(String desiredObject, boolean subSample) {
		int hashedKey = getHashedKey(desiredObject);
		
		observationCounts[hashedKey]++;
		totalCounts++;
		
		//the hashed key has been seen before - a vector exists
		if (vectorTable[hashedKey] != null)	
		{
			if (subSample)
			{
			double frequency 	= observationCounts[hashedKey]/ (double) totalCounts;
			double subsamp 	= Math.sqrt(flagConfig.samplingthreshold() / frequency);
			if (subsamp > 0 && random.nextDouble() <= subsamp)
				return null;
			}
			return vectorTable[hashedKey];
		} //previously unseen hash (and therefore previously unseen key)
		else {
// Path: src/main/java/pitt/search/semanticvectors/vectors/VectorFactory.java
// public class VectorFactory {
//   private static final BinaryVector binaryInstance = new BinaryVector(0);
//   private static final RealVector realInstance = new RealVector(0);
//   private static final ComplexVector complexInstance =
//     new ComplexVector(0, ComplexVector.Mode.POLAR_SPARSE);
//   private static final ComplexVector complexFlatInstance =
//       new ComplexVector(0, ComplexVector.Mode.CARTESIAN);
// 
//   /**
//    * createZeroVector returns a vector set to zero. It can be used externally, but
//    * be careful particularly with Complex Vectors to make sure that polar / cartesian / hermitian
//    * modes are set correctly especially if you try to set coordinates manually after that.
//    */
//   public static Vector createZeroVector(VectorType type, int dimension) {
//     switch (type) {
//       case BINARY:
//         return new BinaryVector(dimension);
//       case REAL:
//         return new RealVector(dimension);
//       case COMPLEX:
//         return new ComplexVector(dimension, Mode.POLAR_SPARSE);
//       case COMPLEXFLAT:
//         return new ComplexVector(dimension, Mode.POLAR_SPARSE);
//       case PERMUTATION:
//     	return new PermutationVector(dimension);
//       default:
//         throw new IllegalArgumentException("Unrecognized VectorType: " + type);
//     }
//   }
//   
//   /**
//    * Generates an appropriate random vector.
//    * 
//    * @param type one of the recognized vector types
//    * @param dimension number of dimensions in the generated vector
//    * @param numEntries total number of non-zero entries; must be no greater than half of dimension
//    * @param random random number generator; passed in to enable deterministic testing
//    * @return vector generated with appropriate type, dimension and number of nonzero entries
//    */
//   public static Vector generateRandomVector(
//       VectorType type, int dimension, int numEntries, Random random) {
// 	 
// 	  if (2 * numEntries > dimension && !type.equals(VectorType.COMPLEX) && !(numEntries == dimension)) {
//       throw new RuntimeException("Requested " + numEntries + " to be filled in sparse "
//           + "vector of dimension " + dimension + ". This is not sparse and may cause problems.");
//     }
//     switch (type) {
//     case BINARY:
//       return binaryInstance.generateRandomVector(dimension, numEntries, random);
//     case REAL:
//       return realInstance.generateRandomVector(dimension, numEntries, random);
//     case COMPLEX:
//       if (!ComplexVector.getDominantMode().equals(Mode.HERMITIAN)) 
//     	  ComplexVector.setDominantMode(Mode.POLAR_DENSE);
//       return complexInstance.generateRandomVector(dimension, numEntries, random);
//     case COMPLEXFLAT:
//       ComplexVector.setDominantMode(Mode.CARTESIAN);
//       return complexInstance.generateRandomVector(dimension, numEntries, random);
//     default:
//       throw new IllegalArgumentException("Unrecognized VectorType: " + type);
//     }
//   }
// 
//   /**
//    * Returns the size in bytes expected to be taken up by the serialization
//    * of this vector in Lucene format.
//    */
//   public static int getLuceneByteSize(VectorType vectorType, int dimension) {
//     switch (vectorType) {
//       case BINARY:
//         return 8 * ((dimension / 64) );
//       case REAL:
//         return 4 * dimension;
//       case COMPLEX:
//       case COMPLEXFLAT:
//         return 8 * dimension;
//       default:
//         throw new IllegalArgumentException("Unrecognized VectorType: " + vectorType);
//     }
//   }
// }


// Path: src/main/java/pitt/search/semanticvectors/CompressedVectorStoreRAM.java
import java.util.ArrayList;
import java.util.Random;
import pitt.search.semanticvectors.vectors.Vector;
import pitt.search.semanticvectors.vectors.VectorFactory;

	   * This implementation only works for string objects so far.
	   * 
	   * @param subsSample - if true, this method will return "null" instead of a vector for Strings that 
	   * 					 hash to keys that have been encountered with a frequency > .01*flagConfig.samplingthreshold()
	   * 					 In practice this means n-grams are subsampled more aggressively than terms
	   * 					 Subsampling follows the procedure described in Mikolov 2013, 1-sqrt(T/F), with F
	   * 					 being the cumulative count of the observations of the relevant hash code / total observed hash codes 
	   * 
	   * @param desiredObject - the string you're searching for
	   * @return vector from the VectorStore, or null if not found. 
	   */
	  public Vector getVector(String desiredObject, boolean subSample) {
		int hashedKey = getHashedKey(desiredObject);
		
		observationCounts[hashedKey]++;
		totalCounts++;
		
		//the hashed key has been seen before - a vector exists
		if (vectorTable[hashedKey] != null)	
		{
			if (subSample)
			{
			double frequency 	= observationCounts[hashedKey]/ (double) totalCounts;
			double subsamp 	= Math.sqrt(flagConfig.samplingthreshold() / frequency);
			if (subsamp > 0 && random.nextDouble() <= subsamp)
				return null;
			}
			return vectorTable[hashedKey];
		} //previously unseen hash (and therefore previously unseen key)
		else {
	      Vector toBeAdded = VectorFactory.generateRandomVector(flagConfig.vectortype(), flagConfig.dimension(), flagConfig.seedlength, random);