public MapVector sparsify(MapVector input, final int numNonZeroEntries) {
   Comparator<IntDoublePair> comparator =
       new Comparator<IntDoublePair>() {
         public int compare(IntDoublePair o1, IntDoublePair o2) {
           return Math.abs(o1.getDouble()) - Math.abs(o2.getDouble()) > 0 ? 1 : -1;
         }
       };
   Set<IntDoublePair> bestPairs =
       new FixedSizeSortedSet<IntDoublePair>(comparator, numNonZeroEntries);
   for (final IntDoublePair pair : input) bestPairs.add(new IntDoublePairImpl(pair));
   List<IntDoublePair> resortedPairs = new ArrayList<IntDoublePair>(bestPairs);
   Collections.sort(
       resortedPairs,
       new Comparator<IntDoublePair>() {
         public int compare(IntDoublePair o1, IntDoublePair o2) {
           if (o1.getInt() == o2.getInt()) return 0;
           return o1.getInt() - o2.getInt() > 0 ? 1 : -1;
         }
       });
   int[] indices = new int[numNonZeroEntries];
   double[] values = new double[numNonZeroEntries];
   int i = 0;
   for (IntDoublePair pair : resortedPairs) {
     indices[i] = pair.getInt();
     values[i] = pair.getDouble();
     i++;
     if (i >= numNonZeroEntries) break;
   }
   return new ImmutableSparseMapVector(indices, values);
 }
 public MapVector project(MapVector documentVector) {
   MapVector output = _eigenvectors.times(documentVector);
   for (IntDoublePair pair : output) {
     if (pair.getInt() >= _inverseSingularValues.length) break;
     pair.setDouble(pair.getDouble() * _inverseSingularValues[pair.getInt()]);
   }
   return output;
 }