CosineDistanceMeasure implements DistanceMeasure { public static double distance(double[] p1, double[] p2) { double dotProduct = 0.0; double lengthSquaredp1 = 0.0; double lengthSquaredp2 = 0.0; for (int i = 0; i < p1.length; i++) { lengthSquaredp1 += p1[i] * p1[i]; lengthSquaredp2 += p2[i] * p2[i]; dotProduct += p1[i] * p2[i]; } double denominator = Math.sqrt(lengthSquaredp1) * Math.sqrt(lengthSquaredp2); if (denominator < dotProduct) { denominator = dotProduct; } if (denominator == 0 && dotProduct == 0) { return 0; } return 1.0 - dotProduct / denominator; }  @Override void configure(Configuration job); @Override Collection<Parameter<?>> getParameters(); @Override void createParameters(String prefix, Configuration jobConf); static double distance(double[] p1, double[] p2); @Override double distance(Vector v1, Vector v2); @Override double distance(double centroidLengthSquare, Vector centroid, Vector v);  }
@Test public void testMeasure() { DistanceMeasure distanceMeasure = new CosineDistanceMeasure(); Vector[] vectors = { new DenseVector(new double[]{1, 0, 0, 0, 0, 0}), new DenseVector(new double[]{1, 1, 1, 0, 0, 0}), new DenseVector(new double[]{1, 1, 1, 1, 1, 1}) }; double[][] distanceMatrix = new double[3][3]; for (int a = 0; a < 3; a++) { for (int b = 0; b < 3; b++) { distanceMatrix[a][b] = distanceMeasure.distance(vectors[a], vectors[b]); } } assertEquals(0.0, distanceMatrix[0][0], EPSILON); assertTrue(distanceMatrix[0][0] < distanceMatrix[0][1]); assertTrue(distanceMatrix[0][1] < distanceMatrix[0][2]); assertEquals(0.0, distanceMatrix[1][1], EPSILON); assertTrue(distanceMatrix[1][0] > distanceMatrix[1][1]); assertTrue(distanceMatrix[1][2] < distanceMatrix[1][0]); assertEquals(0.0, distanceMatrix[2][2], EPSILON); assertTrue(distanceMatrix[2][0] > distanceMatrix[2][1]); assertTrue(distanceMatrix[2][1] > distanceMatrix[2][2]); assertEquals(0, distanceMeasure.distance(new SequentialAccessSparseVector(1), new SequentialAccessSparseVector(1)), EPSILON); }