private int assignToNearestCluster(Relation<V> relation,double[][] means,double[][] sums,List<ModifiableDBIDs> clusters,WritableIntegerDataStore assignment,double[] sep,double[][] cdist,WritableDoubleDataStore upper,WritableDataStore<double[]> lower){
  assert (k == means.length);
  final NumberVectorDistanceFunction<? super V> df=getDistanceFunction();
  final boolean issquared=(df instanceof SquaredEuclideanDistanceFunction);
  int changed=0;
  for (DBIDIter it=relation.iterDBIDs(); it.valid(); it.advance()) {
    final int orig=assignment.intValue(it);
    double u=upper.doubleValue(it);
    if (u <= sep[orig]) {
      continue;
    }
    boolean recompute_u=true;
    V fv=relation.get(it);
    double[] l=lower.get(it);
    int cur=orig;
    for (int j=0; j < k; j++) {
      if (orig == j || u <= l[j] || u <= cdist[cur][j]) {
        continue;
      }
      if (recompute_u) {
        u=df.distance(fv,DoubleVector.wrap(means[cur]));
        u=issquared ? Math.sqrt(u) : u;
        upper.putDouble(it,u);
        recompute_u=false;
        if (u <= l[j] || u <= cdist[cur][j]) {
          continue;
        }
      }
      double dist=df.distance(fv,DoubleVector.wrap(means[j]));
      dist=issquared ? Math.sqrt(dist) : dist;
      l[j]=dist;
      if (dist < u) {
        cur=j;
        u=dist;
      }
    }
    if (cur != orig) {
      upper.putDouble(it,u);
      ModifiableDBIDs newc=clusters.get(cur);
      newc.add(it);
      assignment.putInt(it,cur);
      double[] newmean=sums[cur];
      ModifiableDBIDs oldc=clusters.get(orig);
      oldc.remove(it);
      double[] oldmean=sums[orig];
      for (int d=0; d < fv.getDimensionality(); d++) {
        final double v=fv.doubleValue(d);
        newmean[d]+=v;
        oldmean[d]-=v;
      }
      ++changed;
    }
  }
  return changed;
}

private int assignToNearestCluster ( Relation < V > relation , double [ ] [ ] means , double [ ] [ ] sums , List < ModifiableDBIDs > clusters , WritableIntegerDataStore assignment , double [ ] sep , double [ ] [ ] cdist , WritableDoubleDataStore upper , WritableDataStore < double [ ] > lower ) { assert ( k == means . length ) ; final NumberVectorDistanceFunction < ? super V > df = getDistanceFunction ( ) ; final boolean issquared = ( df instanceof SquaredEuclideanDistanceFunction ) ; int changed = 0 ; for ( DBIDIter it = relation . iterDBIDs ( ) ; it . valid ( ) ; it . advance ( ) ) { final int orig = assignment . intValue ( it ) ; double u = upper . doubleValue ( it ) ; if ( u <= sep [ orig ] ) { continue ; } boolean recompute_u = true ; V fv = relation . get ( it ) ; double [ ] l = lower . get ( it ) ; int cur = orig ; for ( int j = 0 ; j < k ; j ++ ) { if ( orig == j || u <= l [ j ] || u <= cdist [ cur ] [ j ] ) { continue ; } if ( recompute_u ) { u = df . distance ( fv , DoubleVector . wrap ( means [ cur ] ) ) ; u = issquared ? Math . sqrt ( u ) : u ; upper . putDouble ( it , u ) ; recompute_u = false ; if ( u <= l [ j ] || u <= cdist [ cur ] [ j ] ) { continue ; } } double dist = df . distance ( fv , DoubleVector . wrap ( means [ j ] ) ) ; dist = issquared ? Math . sqrt ( dist ) : dist ; l [ j ] = dist ; if ( dist < u ) { cur = j ; u = dist ; } } if ( cur != orig ) { upper . putDouble ( it , u ) ; ModifiableDBIDs newc = clusters . get ( cur ) ; newc . add ( it ) ; assignment . putInt ( it , cur ) ; double [ ] newmean = sums [ cur ] ; ModifiableDBIDs oldc = clusters . get ( orig ) ; oldc . remove ( it ) ; double [ ] oldmean = sums [ orig ] ; for ( int d = 0 ; d < fv . getDimensionality ( ) ; d ++ ) { final double v = fv . doubleValue ( d ) ; newmean [ d ] += v ; oldmean [ d ] -= v ; } ++ changed ; } } return changed ; }
reassign objects , but only if their bounds indicate it is necessary to do so .
