code: public static <E> double dotProduct(Counter<E> c1, Counter<E> c2) {
      double dotProd = 0.0;
      if (c1.size() > c2.size()) {
        Counter<E> tmpCnt = c1;
        c1 = c2;
        c2 = tmpCnt;
      }
      for (E key : c1.keySet()) {
        double count1 = c1.getCount(key);
        if (Double.isNaN(count1) || Double.isInfinite(count1)) {
          throw new RuntimeException("Counters.dotProduct infinite or NaN value for key: " + key + '\t' + c1.getCount(key) + '\t' + c2.getCount(key));
        }
        if (count1 != 0.0) {
          double count2 = c2.getCount(key);
          if (Double.isNaN(count2) || Double.isInfinite(count2)) {
            throw new RuntimeException("Counters.dotProduct infinite or NaN value for key: " + key + '\t' + c1.getCount(key) + '\t' + c2.getCount(key));
          }
          if (count2 != 0.0) {
            // this is the inner product
            dotProd += (count1 * count2);
          }
        }
      }
      return dotProd;
    }
docs: Returns the product of c1 and c2.
  
  @return The product of c1 and c2.