@Override
          public void notify(final CentroidPairing<Object> pairing) {
            outputKeyWritable.set(pairing.getCentroid().getGroupID());
            final double extraFromItem[] = pairing.getPairedItem().getDimensionValues();
            final double extraCentroid[] = pairing.getCentroid().getDimensionValues();
            final Point p = centroidExtractor.getCentroid(pairing.getPairedItem().getWrappedItem());

            final Point centroid =
                centroidExtractor.getCentroid(pairing.getCentroid().getWrappedItem());

            // calculate error for dp
            // using identity matrix for the common covariance, therefore
            // E[(p - c)^-1 * cov * (p - c)] => (px - cx)^2 + (py - cy)^2
            double expectation = 0.0;
            for (int i = 0; i < extraCentroid.length; i++) {
              expectation += Math.pow(extraFromItem[i] - extraCentroid[i], 2);
            }
            expectation +=
                (Math.pow(p.getCoordinate().x - centroid.getCoordinate().x, 2)
                    + Math.pow(p.getCoordinate().y - centroid.getCoordinate().y, 2));
            // + Math.pow(
            // p.getCoordinate().z - centroid.getCoordinate().z,
            // 2));
            outputValWritable.set(expectation, 1);
          }
    @Override
    public void reduce(
        final Text key,
        final Iterable<CountofDoubleWritable> values,
        final Reducer<Text, CountofDoubleWritable, Text, CountofDoubleWritable>.Context context)
        throws IOException, InterruptedException {

      double expectation = 0;
      double ptCount = 0;
      for (final CountofDoubleWritable value : values) {
        expectation += value.getValue();
        ptCount += value.getCount();
      }
      outputValue.set(expectation, ptCount);
      context.write(key, outputValue);
    }
    @Override
    public void reduce(
        final Text key,
        final Iterable<CountofDoubleWritable> values,
        final Reducer<Text, CountofDoubleWritable, GeoWaveOutputKey, DistortionEntry>.Context
            context)
        throws IOException, InterruptedException {
      double expectation = 0.0;
      final List<AnalyticItemWrapper<Object>> centroids =
          centroidManager.getCentroidsForGroup(key.toString());
      // it is possible that the number of items in a group are smaller
      // than the cluster
      final Integer kCount;
      if (expectedK == null) {
        kCount = centroids.size();
      } else {
        kCount = expectedK;
      }
      if (centroids.size() == 0) {
        return;
      }
      final double numDimesions = 2 + centroids.get(0).getExtraDimensions().length;

      double ptCount = 0;
      for (final CountofDoubleWritable value : values) {
        expectation += value.getValue();
        ptCount += value.getCount();
      }

      if (ptCount > 0) {
        expectation /= ptCount;

        final Double distortion = Math.pow(expectation / numDimesions, -(numDimesions / 2));

        final DistortionEntry entry =
            new DistortionEntry(key.toString(), batchId, kCount, distortion);

        context.write(
            new GeoWaveOutputKey(
                DistortionDataAdapter.ADAPTER_ID, DistortionGroupManagement.DISTORTIONS_INDEX_LIST),
            entry);
      }
    }