Apply the feature factory to the documents and then cluster the resulting array
using the provided distance metric and centroid factory.
342305
public function cluster(TrainingSet $documents, FeatureFactoryInterface $ff)
    {
        // transform the documents according to the FeatureFactory
        $docs = $this->getDocumentArray($documents,$ff);

        // choose N centroids at random
        $centroids = array();
        foreach (array_rand($docs,$this->n) as $key) {
            $centroids[] = $docs[$key];
        }

        // cache the distance and centroid factory functions for use
        // with closures
        $dist = array($this->dist,'dist');
        $cf = array($this->centroidF,'getCentroid');

        // looooooooop
        while (true) {
            // compute the distance each document has from our centroids
            // the array is MxN where M = count($docs) and N = count($centroids)
            $distances = array_map(
                function ($doc) use (&$centroids,$dist) {
                    return array_map(
                        function ($c) use ($dist,$doc) {
                            // it is passed with an array because dist expects references
                            // and it failed when run with phpunit.
                            // see http://php.net/manual/en/function.call-user-func.php
                            // for the solution used below
                            return call_user_func_array(
                                $dist,
                                array(
                                    &$c,
                                    &$doc
                                )
                            );
                        },
                        $centroids
                    );
                },
                $docs
            );

            // initialize the empty clusters
            $clusters = array_fill_keys(
                array_keys($centroids),
                array()
            );
            foreach ($distances as $idx=>$d) {
                // assign document idx to the closest centroid
                $clusters[array_search(min($d),$d)][] = $idx;
            }

            // compute the new centroids from the assigned documents
            // using the centroid factory function
            $new_centroids = array_map(
                function ($cluster) use (&$docs,$cf) {
                    return call_user_func_array(
                        $cf,
                        array(
                            &$docs,
                            $cluster
                        )
                    );
                },
                $clusters
            );

            // compute the change each centroid had from the previous one
            $changes = array_map(
                $dist,
                $new_centroids,
                $centroids
            );

            // if the largest change is small enough we are done
            if (max($changes)<$this->cutoff) {
                // return the clusters, the centroids and the distances
                return array($clusters,$centroids,$distances);
            }

            // update the centroids and loooooop again
            $centroids = $new_centroids;
        }
    }
1020947
@Override
	public void trainOnInstanceImpl(Instance inst) {
		double[] x = inst.toDoubleArray();
		if (this.numDimensions != x.length) {
			System.out.println("Line skipped because line dimension is "
					+ x.length + " instead of " + this.numDimensions);
			return;
		}
		// Starts with the buffer phase to calculate the starting threshold
		if (this.bufferPhase) {
			// Calculates the pairwise distance to all unequal point in the
			// buffer
			for (double[] point : this.buffer) {
				double d = Metric.distanceSquared(point, x);
				if (d > 0) {
					this.pairwiseDifferent++;
					if (d < minDistance) {
						minDistance = d;
					}
				}
			}
			this.buffer.add(x);

			// Checks if the buffer is large enough
			if (this.pairwiseDifferent >= this.maxNumClusterFeatures + 1) {
				// Calculates the starting threshold
				this.T = 16 * minDistance;
				this.root.setThreshold(calcRSquared(1));
				this.bufferPhase = false;
				// Adds all points to the ClusteringFeature tree
				for (double[] point : this.buffer) {
					bicoUpdate(point);
				}
				this.buffer.clear();
				this.buffer = null;
			}
		} else {
			// Adds the point directly to the ClusteringFeature tree
			bicoUpdate(x);
		}
	}
604617
public static int centroids(Relation<? extends NumberVector> rel, List<? extends Cluster<?>> clusters, NumberVector[] centroids, NoiseHandling noiseOption) {
    assert (centroids.length == clusters.size());
    int ignorednoise = 0;
    Iterator<? extends Cluster<?>> ci = clusters.iterator();
    for(int i = 0; ci.hasNext(); i++) {
      Cluster<?> cluster = ci.next();
      if(cluster.size() <= 1 || cluster.isNoise()) {
        switch(noiseOption){
        case IGNORE_NOISE:
          ignorednoise += cluster.size();
        case TREAT_NOISE_AS_SINGLETONS:
          centroids[i] = null;
          continue;
        case MERGE_NOISE:
          break; // Treat as cluster below
        }
      }
      centroids[i] = ModelUtil.getPrototypeOrCentroid(cluster.getModel(), rel, cluster.getIDs());
    }
    return ignorednoise;
  }
1081307
private Clustering<OPTICSModel> extractClusters(ClusterOrder clusterOrderResult, Relation<?> relation, double ixi, int minpts) {
    ArrayDBIDs clusterOrder = clusterOrderResult.ids;
    DoubleDataStore reach = clusterOrderResult.reachability;

    DBIDArrayIter tmp = clusterOrder.iter();
    DBIDVar tmp2 = DBIDUtil.newVar();
    double mib = 0.0;
    List<SteepArea> salist = keepsteep ? new ArrayList<SteepArea>() : null;
    List<SteepDownArea> sdaset = new ArrayList<>();
    final Clustering<OPTICSModel> clustering = new Clustering<>("OPTICS Xi-Clusters", "optics");
    HashSet<Cluster<OPTICSModel>> curclusters = new HashSet<>();
    HashSetModifiableDBIDs unclaimedids = DBIDUtil.newHashSet(relation.getDBIDs());

    FiniteProgress scanprog = LOG.isVerbose() ? new FiniteProgress("OPTICS Xi cluster extraction", clusterOrder.size(), LOG) : null;
    for(SteepScanPosition scan = new SteepScanPosition(clusterOrderResult); scan.hasNext();) {
      if(scanprog != null) {
        scanprog.setProcessed(scan.index, LOG);
      }
      // Update maximum-inbetween
      mib = MathUtil.max(mib, scan.getReachability());
      // The last point cannot be the start of a steep area.
      if(!scan.next.valid()) {
        break;
      }
      // Xi-steep down area
      if(scan.steepDown(ixi)) {
        // Update mib values with current mib and filter
        updateFilterSDASet(mib, sdaset, ixi);
        final double startval = scan.getReachability();
        mib = 0.;
        int startsteep = scan.index, endsteep = scan.index;
        for(scan.next(); scan.hasNext(); scan.next()) {
          // still steep - continue.
          if(scan.steepDown(ixi)) {
            endsteep = scan.index;
            continue;
          }
          // Not going downward at all - stop here.
          // Always stop looking after minpts "flat" steps.
          if(!scan.steepDown(1.0) || scan.index - endsteep > minpts) {
            break;
          }
        }
        final SteepDownArea sda = new SteepDownArea(startsteep, endsteep, startval, 0);
        if(LOG.isDebuggingFinest()) {
          LOG.debugFinest("New steep down area: " + sda.toString());
        }
        sdaset.add(sda);
        if(salist != null) {
          salist.add(sda);
        }
        continue;
      }
      // Xi-steep up area
      if(scan.steepUp(ixi)) {
        // Update mib values with current mib and filter
        updateFilterSDASet(mib, sdaset, ixi);
        final SteepUpArea sua;
        // Compute steep-up area
        {
          int startsteep = scan.index, endsteep = scan.index;
          mib = scan.getReachability();
          double esuccr = scan.getNextReachability();
          // Find end of steep-up-area, eventually updating mib again
          while(!Double.isInfinite(esuccr) && scan.hasNext()) {
            scan.next();
            // still steep - continue.
            if(scan.steepUp(ixi)) {
              endsteep = scan.index;
              mib = scan.getReachability();
              esuccr = scan.getNextReachability();
              continue;
            }
            // Not going upward - stop here.
            // Stop looking after minpts non-up steps.
            if(!scan.steepUp(1.0) || scan.index - endsteep > minpts) {
              break;
            }
          }
          if(Double.isInfinite(esuccr)) {
            scan.next();
          }
          sua = new SteepUpArea(startsteep, endsteep, esuccr);
          if(LOG.isDebuggingFinest()) {
            LOG.debugFinest("New steep up area: " + sua.toString());
          }
          if(salist != null) {
            salist.add(sua);
          }
        }
        // Validate and computer clusters
        // LOG.debug("SDA size:"+sdaset.size()+" "+sdaset);
        ListIterator<SteepDownArea> sdaiter = sdaset.listIterator(sdaset.size());
        // Iterate backwards for correct hierarchy generation.
        while(sdaiter.hasPrevious()) {
          SteepDownArea sda = sdaiter.previous();
          if(LOG.isDebuggingFinest()) {
            LOG.debugFinest("Comparing: eU=" + mib + " SDA: " + sda.toString());
          }
          // Condition 3b: end-of-steep-up > maximum-in-between lower
          if(mib * ixi < sda.getMib()) {
            if(LOG.isDebuggingFinest()) {
              LOG.debugFinest("mib * ixi = " + mib * ixi + " >= sda.getMib() = " + sda.getMib());
            }
            continue;
          }
          // By default, clusters cover both the steep up and steep down area
          int cstart = sda.getStartIndex(),
              cend = MathUtil.min(sua.getEndIndex(), clusterOrder.size() - 1);
          // However, we sometimes have to adjust this (Condition 4):
          {
            // Case b)
            if(sda.getMaximum() * ixi >= sua.getMaximum()) {
              while(cstart < cend && //
                  reach.doubleValue(tmp.seek(cstart + 1)) > sua.getMaximum()) {
                cstart++;
              }
            }
            // Case c)
            else if(sua.getMaximum() * ixi >= sda.getMaximum()) {
              while(cend > cstart && //
                  reach.doubleValue(tmp.seek(cend - 1)) > sda.getMaximum()) {
                cend--;
              }
            }
            // Case a) is the default
          }
          // MST-based filtering technique of Schubert:
          // ensure that the predecessor is in the current cluster.
          // This filter removes common artifacts from the Xi method
          if(!nocorrect) {
            double startval = clusterOrderResult.reachability.doubleValue(tmp.seek(cstart));
            simplify: while(cend > cstart) {
              tmp.seek(cend);
              // If the reachability is less than the first points', then there
              // must be some point inbetween that "reached" the current point.
              if(clusterOrderResult.reachability.doubleValue(tmp) < startval) {
                break simplify;
              }
              clusterOrderResult.predecessor.assignVar(tmp, tmp2);
              // "Slow" search for predecessor:
              for(int i = cstart; i < cend; i++) {
                if(DBIDUtil.equal(tmp2, tmp.seek(i))) {
                  break simplify;
                }
              }
              // Not found, prune the last point
              if(LOG.isDebuggingFinest()) {
                LOG.debugFinest("Pruned one point by predecessor rule.");
              }
              --cend;
            }
          }
          // Condition 3a: obey minpts
          if(cend - cstart + 1 < minpts) {
            if(LOG.isDebuggingFinest()) {
              LOG.debugFinest("MinPts not satisfied.");
            }
            continue;
          }
          // Build the cluster
          ModifiableDBIDs dbids = DBIDUtil.newArray();
          for(int idx = cstart; idx <= cend; idx++) {
            tmp.seek(idx);
            // Collect only unclaimed IDs.
            if(unclaimedids.remove(tmp)) {
              dbids.add(tmp);
            }
          }
          if(LOG.isDebuggingFine()) {
            LOG.debugFine("Found cluster with " + dbids.size() + " new objects, length " + (cend - cstart + 1));
          }
          OPTICSModel model = new OPTICSModel(cstart, cend);
          Cluster<OPTICSModel> cluster = new Cluster<>("Cluster_" + cstart + "_" + cend, dbids, model);
          // Build the hierarchy
          for(Iterator<Cluster<OPTICSModel>> iter = curclusters.iterator(); iter.hasNext();) {
            Cluster<OPTICSModel> clus = iter.next();
            OPTICSModel omodel = clus.getModel();
            if(model.getStartIndex() <= omodel.getStartIndex() && omodel.getEndIndex() <= model.getEndIndex()) {
              clustering.addChildCluster(cluster, clus);
              iter.remove(); // Not a top-level cluster
            }
          }
          curclusters.add(cluster);
        }
        continue;
      }
      // Flat - advance anyway.
      scan.next();
    }
    if(scanprog != null) {
      scanprog.setProcessed(clusterOrder.size(), LOG);
    }
    if(!unclaimedids.isEmpty()) {
      boolean noise = reach.doubleValue(tmp.seek(clusterOrder.size() - 1)) >= Double.POSITIVE_INFINITY;
      Cluster<OPTICSModel> allcluster = new Cluster<>(noise ? "Noise" : "Cluster", unclaimedids, noise, new OPTICSModel(0, clusterOrder.size() - 1));
      for(Cluster<OPTICSModel> cluster : curclusters) {
        clustering.addChildCluster(allcluster, cluster);
      }
      clustering.addToplevelCluster(allcluster);
    }
    else {
      for(Cluster<OPTICSModel> cluster : curclusters) {
        clustering.addToplevelCluster(cluster);
      }
    }
    clustering.addChildResult(clusterOrderResult);
    if(salist != null) {
      clusterOrderResult.addChildResult(new SteepAreaResult(salist));
    }
    return clustering;
  }
1133448
function centroidOf(points, dimension) {
    var centroid = new Float32Array(dimension);
    for (var i = 0; i < centroid.length; i++) {
      var sum = 0;
      var count = 0;
      for (var pointIndex = 0; pointIndex < points.length; pointIndex++) {
        var p = points[pointIndex];
        var point = p.getPoint();
        var val = point.getValue(i);
        if (!isNaN(val)) {
          sum += val;
          count++;
        }
      }
      centroid[i] = (sum / count);
    }
    return new PointWrapper(morpheus.VectorUtil.arrayAsVector(centroid));
  }
894256
def _move_centroids(self):
        
        for k in range(self.n_clusters):
            if k in self.clusters:
                centroid = np.mean(self._X[self.clusters == k, :], axis=0)
                self.centroids[k] = centroid

            else:
                self.n_clusters-=1
                self.centroids = self.centroids[:self.n_clusters]
                self.clusters-=1
                k-=1
1135385
public double evaluateClustering(Database db, Relation<? extends NumberVector> rel, Clustering<?> c) {
    List<? extends Cluster<?>> clusters = c.getAllClusters();
    NumberVector[] centroids = new NumberVector[clusters.size()];
    int ignorednoise = centroids(rel, clusters, centroids, noiseOption);

    MeanVariance mssil = new MeanVariance();

    Iterator<? extends Cluster<?>> ci = clusters.iterator();
    for(int i = 0; ci.hasNext(); i++) {
      Cluster<?> cluster = ci.next();
      if(cluster.size() <= 1) {
        // As suggested in Rousseeuw, we use 0 for singletons.
        mssil.put(0., cluster.size());
        continue;
      }
      if(cluster.isNoise()) {
        switch(noiseOption){
        case IGNORE_NOISE:
          continue; // Ignore elements
        case TREAT_NOISE_AS_SINGLETONS:
          // As suggested in Rousseeuw, we use 0 for singletons.
          mssil.put(0., cluster.size());
          continue;
        case MERGE_NOISE:
          break; // Treat as cluster below
        }
      }

      // Cluster center:
      final NumberVector center = centroids[i];
      assert (center != null);
      for(DBIDIter it = cluster.getIDs().iter(); it.valid(); it.advance()) {
        NumberVector obj = rel.get(it);
        // a: Distance to own centroid
        double a = distance.distance(center, obj);

        // b: Distance to other clusters centroids:
        double min = Double.POSITIVE_INFINITY;
        Iterator<? extends Cluster<?>> cj = clusters.iterator();
        for(int j = 0; cj.hasNext(); j++) {
          Cluster<?> ocluster = cj.next();
          if(i == j) {
            continue;
          }
          NumberVector other = centroids[j];
          if(other == null) { // Noise!
            switch(noiseOption){
            case IGNORE_NOISE:
              continue;
            case TREAT_NOISE_AS_SINGLETONS:
              // Treat each object like a centroid!
              for(DBIDIter it2 = ocluster.getIDs().iter(); it2.valid(); it2.advance()) {
                double dist = distance.distance(rel.get(it2), obj);
                min = dist < min ? dist : min;
              }
              continue;
            case MERGE_NOISE:
              break; // Treat as cluster below, but should not be reachable.
            }
          }
          // Clusters: use centroid.
          double dist = distance.distance(other, obj);
          min = dist < min ? dist : min;
        }

        // One 'real' cluster only?
        min = min < Double.POSITIVE_INFINITY ? min : a;
        mssil.put((min - a) / (min > a ? min : a));
      }
    }

    double penalty = 1.;
    // Only if {@link NoiseHandling#IGNORE_NOISE}:
    if(penalize && ignorednoise > 0) {
      penalty = (rel.size() - ignorednoise) / (double) rel.size();
    }
    final double meanssil = penalty * mssil.getMean();
    final double stdssil = penalty * mssil.getSampleStddev();
    if(LOG.isStatistics()) {
      LOG.statistics(new StringStatistic(key + ".simplified-silhouette.noise-handling", noiseOption.toString()));
      if(ignorednoise > 0) {
        LOG.statistics(new LongStatistic(key + ".simplified-silhouette.ignored", ignorednoise));
      }
      LOG.statistics(new DoubleStatistic(key + ".simplified-silhouette.mean", meanssil));
      LOG.statistics(new DoubleStatistic(key + ".simplified-silhouette.stddev", stdssil));
    }

    EvaluationResult ev = EvaluationResult.findOrCreate(db.getHierarchy(), c, "Internal Clustering Evaluation", "internal evaluation");
    MeasurementGroup g = ev.findOrCreateGroup("Distance-based Evaluation");
    g.addMeasure("Simp. Silhouette +-" + FormatUtil.NF2.format(stdssil), meanssil, -1., 1., 0., false);
    db.getHierarchy().resultChanged(ev);
    return meanssil;
  }
835829
public static Assignments cluster(Matrix matrix,
                                      int numClusters,
                                      int numRepetitions,
                                      KMeansSeed seedType,
                                      CriterionFunction criterion) {
        int[] bestAssignment = null;
        double bestScore = (criterion.isMaximize()) ? 0 : Double.MAX_VALUE;
        for (int i = 0; i < numRepetitions; ++i) {
            clusterIteration(matrix, numClusters, seedType, criterion);
            if (criterion.isMaximize()) {
                if (criterion.score() > bestScore) {
                    bestScore = criterion.score();
                    bestAssignment = criterion.assignments();
                }
            } else {
                if (criterion.score() < bestScore) {
                    bestScore = criterion.score();
                    bestAssignment = criterion.assignments();
                }
            }
        }

        // Convert the array of assignments to an Assignments object.
        Assignment[] assignments = new Assignment[matrix.rows()];
        for (int i = 0; i < bestAssignment.length; ++i)
            assignments[i] = new HardAssignment(bestAssignment[i]);

        return new Assignments(numClusters, assignments, matrix);
    }
786485
public Clustering<MedoidModel> run(Database database, Relation<V> relation) {
    DistanceQuery<V> distQ = DatabaseUtil.precomputedDistanceQuery(database, relation, getDistanceFunction(), LOG);
    // Choose initial medoids
    if(LOG.isStatistics()) {
      LOG.statistics(new StringStatistic(KEY + ".initialization", initializer.toString()));
    }
    ArrayModifiableDBIDs medoids = DBIDUtil.newArray(initializer.chooseInitialMedoids(k, relation.getDBIDs(), distQ));
    DBIDArrayMIter miter = medoids.iter();
    double[] mdists = new double[k];
    // Setup cluster assignment store
    List<ModifiableDBIDs> clusters = new ArrayList<>();
    for(int i = 0; i < k; i++) {
      HashSetModifiableDBIDs set = DBIDUtil.newHashSet(relation.size() / k);
      set.add(miter.seek(i)); // Add medoids.
      clusters.add(set);
    }

    // Initial assignment to nearest medoids
    // TODO: reuse this information, from the build phase, when possible?
    double tc = assignToNearestCluster(miter, mdists, clusters, distQ);
    if(LOG.isStatistics()) {
      LOG.statistics(new DoubleStatistic(KEY + ".iteration-" + 0 + ".cost", tc));
    }

    IndefiniteProgress prog = LOG.isVerbose() ? new IndefiniteProgress("K-Medoids EM iteration", LOG) : null;
    // Swap phase
    int iteration = 0;
    DBIDVar best = DBIDUtil.newVar();
    while(true) {
      boolean changed = false;
      // Try to swap the medoid with a better cluster member:
      int i = 0;
      for(miter.seek(0); miter.valid(); miter.advance(), i++) {
        best.unset();
        double bestm = mdists[i];
        for(DBIDIter iter = clusters.get(i).iter(); iter.valid(); iter.advance()) {
          if(DBIDUtil.equal(miter, iter)) {
            continue;
          }
          double sum = 0;
          for(DBIDIter iter2 = clusters.get(i).iter(); iter2.valid(); iter2.advance()) {
            if(DBIDUtil.equal(iter, iter2)) {
              continue;
            }
            sum += distQ.distance(iter, iter2);
          }
          if(sum < bestm) {
            best.set(iter);
            bestm = sum;
          }
        }
        if(best.isSet() && !DBIDUtil.equal(miter, best)) {
          changed = true;
          assert (clusters.get(i).contains(best));
          medoids.set(i, best);
          mdists[i] = bestm;
        }
      }
      if(!changed) {
        break; // Converged
      }
      // Reassign
      double nc = assignToNearestCluster(miter, mdists, clusters, distQ);
      ++iteration;
      if(LOG.isStatistics()) {
        LOG.statistics(new DoubleStatistic(KEY + ".iteration-" + iteration + ".cost", nc));
      }
      LOG.incrementProcessed(prog);
    }
    LOG.setCompleted(prog);
    if(LOG.isStatistics()) {
      LOG.statistics(new LongStatistic(KEY + ".iterations", iteration));
    }

    // Wrap result
    Clustering<MedoidModel> result = new Clustering<>("k-Medoids Clustering", "kmedoids-clustering");
    for(DBIDArrayIter it = medoids.iter(); it.valid(); it.advance()) {
      result.addToplevelCluster(new Cluster<>(clusters.get(it.getOffset()), new MedoidModel(DBIDUtil.deref(it))));
    }
    return result;
  }
184750
private Clustering<Model> generateDefaultClustering() {
    final Database db = ResultUtil.findDatabase(hier);
    Clustering<Model> c = null;
    try {
      // Try to cluster by labels
      ByLabelHierarchicalClustering split = new ByLabelHierarchicalClustering();
      c = split.run(db);
    }
    catch(NoSupportedDataTypeException e) {
      // Put everything into one
      c = new TrivialAllInOne().run(db);
    }
    return c;
  }
1010582
double refine_clusters(List<Cluster<K>> clusters)
    {
        double[] norms = new double[clusters.size()];
        int offset = 0;
        for (Cluster cluster : clusters)
        {
            norms[offset++] = cluster.composite_vector().norm();
        }

        double eval_cluster = 0.0;
        int loop_count = 0;
        while (loop_count++ < NUM_REFINE_LOOP)
        {
            List<int[]> items = new ArrayList<int[]>(documents_.size());
            for (int i = 0; i < clusters.size(); i++)
            {
                for (int j = 0; j < clusters.get(i).documents().size(); j++)
                {
                    items.add(new int[]{i, j});
                }
            }
            Collections.shuffle(items);

            boolean changed = false;
            for (int[] item : items)
            {
                int cluster_id = item[0];
                int item_id = item[1];
                Cluster<K> cluster = clusters.get(cluster_id);
                Document<K> doc = cluster.documents().get(item_id);
                double value_base = refined_vector_value(cluster.composite_vector(), doc.feature(), -1);
                double norm_base_moved = Math.pow(norms[cluster_id], 2) + value_base;
                norm_base_moved = norm_base_moved > 0 ? Math.sqrt(norm_base_moved) : 0.0;

                double eval_max = -1.0;
                double norm_max = 0.0;
                int max_index = 0;
                for (int j = 0; j < clusters.size(); j++)
                {
                    if (cluster_id == j)
                        continue;
                    Cluster<K> other = clusters.get(j);
                    double value_target = refined_vector_value(other.composite_vector(), doc.feature(), 1);
                    double norm_target_moved = Math.pow(norms[j], 2) + value_target;
                    norm_target_moved = norm_target_moved > 0 ? Math.sqrt(norm_target_moved) : 0.0;
                    double eval_moved = norm_base_moved + norm_target_moved - norms[cluster_id] - norms[j];
                    if (eval_max < eval_moved)
                    {
                        eval_max = eval_moved;
                        norm_max = norm_target_moved;
                        max_index = j;
                    }
                }
                if (eval_max > 0)
                {
                    eval_cluster += eval_max;
                    clusters.get(max_index).add_document(doc);
                    clusters.get(cluster_id).remove_document(item_id);
                    norms[cluster_id] = norm_base_moved;
                    norms[max_index] = norm_max;
                    changed = true;
                }
            }
            if (!changed)
                break;
            for (Cluster<K> cluster : clusters)
            {
                cluster.refresh();
            }
        }
        return eval_cluster;
    }
107911
SparseVector centroid_vector()
    {
        if (documents_.size() > 0 && composite_.size() == 0)
            set_composite_vector();
        centroid_ = (SparseVector) composite_vector().clone();
        centroid_.normalize();
        return centroid_;
    }
90508
public static void main(String[] args) throws Exception {
		
		if(!parseParameters(args)) {
			return;
		}
	
		// set up execution environment
		ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
		
		// get input data
		DataSet<Point> points = getPointDataSet(env);
		DataSet<Centroid> centroids = getCentroidDataSet(env);
		
		// set number of bulk iterations for KMeans algorithm
		IterativeDataSet<Centroid> loop = centroids.iterate(numIterations);
		
		DataSet<Centroid> newCentroids = points
			// compute closest centroid for each point
			.map(new SelectNearestCenter()).withBroadcastSet(loop, "centroids")
			// count and sum point coordinates for each centroid
			.map(new CountAppender())
			.groupBy(0).reduce(new CentroidAccumulator())
			// compute new centroids from point counts and coordinate sums
			.map(new CentroidAverager());
		
		// feed new centroids back into next iteration
		DataSet<Centroid> finalCentroids = loop.closeWith(newCentroids);
		
		DataSet<Tuple2<Integer, Point>> clusteredPoints = points
				// assign points to final clusters
				.map(new SelectNearestCenter()).withBroadcastSet(finalCentroids, "centroids");
		
		// emit result
		if(fileOutput) {
			clusteredPoints.writeAsCsv(outputPath, "\n", " ");
		} else {
			clusteredPoints.print();
		}

		// execute program
		env.execute("KMeans Example");
		
	}
3265
def _calculate_cluster_distance(end_iter):
    
    out = []
    sizes = []
    for x in end_iter:
        out.append(x)
        sizes.append(x.end1 - x.start1)
        sizes.append(x.end2 - x.start2)
    distance = sum(sizes) // len(sizes)
    return distance, out
847742
def generateFeatureGroups(fgiContainer, linkageGroups, matchArr, timeKey,
                          massKey, logMassKey, massScalingFactor):
    
    #Generate feature groups from the linked features
    newFgiIds = list()
    for linkageGroup in viewvalues(linkageGroups):
        fgiId = fgiContainer._getNextFgiId()
        fgi = fiGroupFromLinkageGroup(matchArr, linkageGroup, fgiId,
                                      timeKey, massKey
                                      )
        fgiContainer.container[fgiId] = fgi
        fgi.metrics = clusterMetrics(matchArr[timeKey][linkageGroup],
                                     matchArr[logMassKey][linkageGroup],
                                     massScalingFactor=massScalingFactor
                                     )
        fgi.rt = fgi.metrics['meanTime']
        fgi.mz = fgi.metrics['meanMass']
        newFgiIds.append(fgiId)
    return newFgiIds
1343327
function cluster(points) {
    // number of clusters has to be smaller or equal the number of data points
    if (points.length < k) {
      throw 'Too many clusters';
    }

    // create the initial clusters
    var clusters = chooseInitialCenters(points);

    // create an array containing the latest assignment of a point to a cluster
    // no need to initialize the array, as it will be filled with the first assignment
    var assignments = new Int32Array(points.length);
    assignPointsToClusters(clusters, points, assignments);
    // iterate through updating the centers until we're done
    var max = (maxIterations < 0) ? Number.MAX_VALUE : maxIterations;
    for (var count = 0; count < max; count++) {
      var emptyCluster = false;
      var newClusters = [];
      for (var clusterIndex = 0; clusterIndex < clusters.length; clusterIndex++) {
        var cluster = clusters[clusterIndex];
        var newCenter;
        if (cluster.getPoints().length === 0) {
          newCenter = getPointFromLargestVarianceCluster(clusters);
          emptyCluster = true;
        } else {
          newCenter = centroidOf(cluster.getPoints(), cluster.getCenter().getPoint().size());
        }
        newClusters.push(new CentroidCluster(newCenter));
      }
      var changes = assignPointsToClusters(newClusters, points, assignments);
      clusters = newClusters;

      // if there were no more changes in the point-to-cluster assignment
      // and there are no empty clusters left, return the current clusters
      if (changes === 0 && !emptyCluster) {
        return clusters;
      }
    }
    return clusters;
  }
1180216
function clusterByNeighbor(points) {
    const sorted = points.slice().sort((a, b) => {
        if (a.y < b.y) {
            return -1;
        } else if (a.y > b.y) {
            return 1;
        } else {
            if (a.x < b.x) {
                return -1;
            } else if (a.x > b.x) {
                return 1;
            } else {
                return 0;
            }
        }
    });

    const cluster = sorted.reduce((sets, point) => {
        const setContainingNeighbors = sets.find(set => set.some((setPoint) => {
            return getNeighbors(setPoint).some(spn => areEqual(spn, point));
        }));

        if (setContainingNeighbors) {
            setContainingNeighbors.push(point);
        } else {
            sets.push([point]);
        }

        return sets;
    }, []);

    return cluster;
}