/** * Compute the centroids of all the clusters. * * @param ids Array of cluster numbers which this call will fill in, defining which cluster each * point belongs to. The caller must leave the data here intact between iterations. * @param means Array of x,y values in which we will place the centroids of the clusters. * @return true iff none of the means moved by a significant amount. */ private boolean computeCentroids(int[] ids, double[][] means) { boolean dirty = false; for (int c = 0; c < numClusters; ++c) { // Compute the weighted sum of the data points. double tx = 0.0, ty = 0.0, tot = 0.0; for (int p = 0; p < numPoints; ++p) { Point point = dataPoints[p]; double str = Math.pow(clusterStrengths[p][c], M); tx += point.getX() * str; ty += point.getY() * str; tot += str; } // Calculate the mean, and see if it's different from // the previous one. final double nx = tx / tot; final double ny = ty / tot; if (!MathTools.eq(means[c][0], nx) || !MathTools.eq(means[c][1], ny)) { means[c][0] = nx; means[c][1] = ny; dirty = true; } } return !dirty; }
/** Computes the absolute squared Cartesian distance between two points. */ private static final double computeDistanceSquared(Point a, double[] b) { final double dx = a.getX() - b[0]; final double dy = a.getY() - b[1]; return dx * dx + dy * dy; }