private double computeCompactness()

in samoa-api/src/main/java/org/apache/samoa/evaluation/measures/General.java [142:190]


  private double computeCompactness() {
    if (numFClusters == 0)
      return 0;
    for (int c = 0; c < numFClusters; c++) {
      if (!(clustering.get(c) instanceof SphereCluster)) {
        System.out.println("Compactness only supports Sphere Cluster. Found: " + clustering.get(c).getClass());
        return Double.NaN;
      }
    }

    // TODO weight radius by number of dimensions
    double totalCompactness = 0;
    for (int c = 0; c < numFClusters; c++) {
      ArrayList<Instance> containedPoints = new ArrayList<Instance>();
      for (int p = 0; p < numPoints; p++) {
        // p in c
        if (clustering.get(c).getInclusionProbability(points.get(p)) >= pointInclusionProbThreshold) {
          containedPoints.add(points.get(p));
        }
      }
      double compactness = 0;
      if (containedPoints.size() > 1) {
        // cluster not empty
        SphereCluster minEnclosingCluster = new SphereCluster(containedPoints, numDims);
        double minRadius = minEnclosingCluster.getRadius();
        double cfRadius = ((SphereCluster) clustering.get(c)).getRadius();
        if (Math.abs(minRadius - cfRadius) < 0.1e-10) {
          compactness = 1;
        }
        else if (minRadius < cfRadius)
          compactness = minRadius / cfRadius;
        else {
          System.out.println("Optimal radius bigger then real one (" + (cfRadius - minRadius)
              + "), this is really wrong");
          compactness = 1;
        }
      }
      else {
        double cfRadius = ((SphereCluster) clustering.get(c)).getRadius();
        if (cfRadius == 0)
          compactness = 1;
      }

      // weight by weight of cluster???
      totalCompactness += compactness;
      clustering.get(c).setMeasureValue("Compactness", Double.toString(compactness));
    }
    return (totalCompactness / numFClusters);
  }