public final void plusEqualsSparse(SparseVector v) {
   if (indices.length == 0) return;
   if (index2location == null) setIndex2Location();
   for (int i = 0; i < v.numLocations(); i++) {
     int index = v.indexAtLocation(i);
     if (index >= index2location.length) break;
     int location = index2location[index];
     if (location >= 0) values[location] += v.valueAtLocation(i);
   }
 }
 public final double dotProduct(SparseVector v) {
   if (indices.length == 0) return 0;
   if (index2location == null) setIndex2Location();
   double ret = 0;
   int vNumLocs = v.numLocations();
   if (isBinary()) {
     // this vector is binary
     for (int i = 0; i < vNumLocs; i++) {
       int index = v.indexAtLocation(i);
       if (index >= index2location.length) break;
       if (index2location[index] >= 0) ret += v.valueAtLocation(i);
     }
   } else if (v.isBinary()) {
     // the other vector is binary
     for (int i = 0; i < vNumLocs; i++) {
       int index = v.indexAtLocation(i);
       if (index >= index2location.length) break;
       int location = index2location[index];
       if (location >= 0) ret += values[location];
     }
   } else {
     for (int i = 0; i < vNumLocs; i++) {
       int index = v.indexAtLocation(i);
       if (index >= index2location.length) break;
       int location = index2location[index];
       if (location >= 0) ret += values[location] * v.valueAtLocation(i);
     }
   }
   return ret;
 }