// 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/vectors/VectorType.java
// public enum VectorType {
//   /**
//    * Uses binary-valued vectors. May be slower for some operations, but highly accurate.
//    */
//   BINARY,
//   /**
//    * "Standard" real-valued vectors. Performs well for many operations though bind and release
//    * are (in some cases) either lossy with respect to argument structure and binding, or
//    * inexact with respect to inverse.
//    */
//   REAL,
//   /**
//    * Complex-valued vectors, default "polar" version, normalized to coordinates on the unit circle,
//    * and compared using angular differences.
//    */
//   COMPLEX,
//   /**
//    * Complex-valued vectors, normalized and compared using a hermitian scalar product.
//    */
//   COMPLEXFLAT,
//   /**
//    * Vector of integer values, describing a permutation
//    */
//   PERMUTATION
// }


import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermsEnum;
import pitt.search.semanticvectors.utils.VerbatimLogger;
import pitt.search.semanticvectors.vectors.Vector;
import pitt.search.semanticvectors.vectors.VectorFactory;
import pitt.search.semanticvectors.vectors.VectorType;
import java.io.IOException;
import java.util.Enumeration;
import java.util.logging.Logger;
              while (terms.next() != null) {
                numTerms++;
              }
              fieldweight = (float) (1/Math.sqrt(numTerms));
            }

            docVector.superpose(
                termVector, localweight * globalweight * fieldweight, null);
          }
        }
      }
    }
    catch (IOException e) { // catches from indexReader.
      e.printStackTrace();
    }

    VerbatimLogger.info("\nNormalizing doc vectors ...\n");
    
    Enumeration<ObjectVector> docEnum = docVectors.getAllVectors();
    while (docEnum.hasMoreElements())
    	docEnum.nextElement().getVector().normalize();
  }

  /**
   * Allocate doc vectors to zero vectors.
   */
  private void initializeZeroDocVectors() throws IOException {
    VerbatimLogger.info("Initializing new document vector store ... \n");
    for (int i = 0; i < luceneUtils.getNumDocs(); ++i) {
      String externalDocId = luceneUtils.getExternalDocId(i);
// 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/vectors/VectorType.java
// public enum VectorType {
//   /**
//    * Uses binary-valued vectors. May be slower for some operations, but highly accurate.
//    */
//   BINARY,
//   /**
//    * "Standard" real-valued vectors. Performs well for many operations though bind and release
//    * are (in some cases) either lossy with respect to argument structure and binding, or
//    * inexact with respect to inverse.
//    */
//   REAL,
//   /**
//    * Complex-valued vectors, default "polar" version, normalized to coordinates on the unit circle,
//    * and compared using angular differences.
//    */
//   COMPLEX,
//   /**
//    * Complex-valued vectors, normalized and compared using a hermitian scalar product.
//    */
//   COMPLEXFLAT,
//   /**
//    * Vector of integer values, describing a permutation
//    */
//   PERMUTATION
// }


// Path: src/main/java/pitt/search/semanticvectors/DocVectors.java
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermsEnum;
import pitt.search.semanticvectors.utils.VerbatimLogger;
import pitt.search.semanticvectors.vectors.Vector;
import pitt.search.semanticvectors.vectors.VectorFactory;
import pitt.search.semanticvectors.vectors.VectorType;
import java.io.IOException;
import java.util.Enumeration;
import java.util.logging.Logger;

              while (terms.next() != null) {
                numTerms++;
              }
              fieldweight = (float) (1/Math.sqrt(numTerms));
            }

            docVector.superpose(
                termVector, localweight * globalweight * fieldweight, null);
          }
        }
      }
    }
    catch (IOException e) { // catches from indexReader.
      e.printStackTrace();
    }

    VerbatimLogger.info("\nNormalizing doc vectors ...\n");
    
    Enumeration<ObjectVector> docEnum = docVectors.getAllVectors();
    while (docEnum.hasMoreElements())
    	docEnum.nextElement().getVector().normalize();
  }

  /**
   * Allocate doc vectors to zero vectors.
   */
  private void initializeZeroDocVectors() throws IOException {
    VerbatimLogger.info("Initializing new document vector store ... \n");
    for (int i = 0; i < luceneUtils.getNumDocs(); ++i) {
      String externalDocId = luceneUtils.getExternalDocId(i);
      Vector docVector = VectorFactory.createZeroVector(flagConfig.vectortype(), flagConfig.dimension());