protected void computeAverageChainingDistances(KNNQuery<O> knnq, DistanceQuery<O> dq, DBIDs ids, WritableDoubleDataStore acds) {
    FiniteProgress lrdsProgress = LOG.isVerbose() ? new FiniteProgress("Computing average chaining distances", ids.size(), LOG) : null;
    // Compute the chaining distances.
    // We do <i>not</i> bother to materialize the chaining order.
    for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
      final KNNList neighbors = knnq.getKNNForDBID(iter, k);
      final int r = neighbors.size();
      DoubleDBIDListIter it1 = neighbors.iter(), it2 = neighbors.iter();
      // Store the current lowest reachability.
      final double[] mindists = new double[r];
      for(int i = 0; it1.valid(); it1.advance(), ++i) {
        mindists[i] = DBIDUtil.equal(it1, iter) ? Double.NaN : it1.doubleValue();
      }
      double acsum = 0.;
      for(int j = ((r < k) ? r : k) - 1; j > 0; --j) {
        // Find the minimum:
        int minpos = -1;
        double mindist = Double.NaN;
        for(int i = 0; i < mindists.length; ++i) {
          double curdist = mindists[i];
          // Both values could be NaN, deliberately.
          if(curdist == curdist && !(curdist > mindist)) {
            minpos = i;
            mindist = curdist;
          }
        }
        acsum += mindist * j; // Weighted sum, decreasing weights
        mindists[minpos] = Double.NaN;
        it1.seek(minpos);
        // Update distances
        it2.seek(0);
        for(int i = 0; it2.valid(); it2.advance(), ++i) {
          final double curdist = mindists[i];
          if(curdist != curdist) {
            continue; // NaN = processed!
          }
          double newdist = dq.distance(it1, it2);
          if(newdist < curdist) {
            mindists[i] = newdist;
          }
        }
      }
      acds.putDouble(iter, acsum / (r * 0.5 * (r - 1.)));
      LOG.incrementProcessed(lrdsProgress);
    }
    LOG.ensureCompleted(lrdsProgress);
  }
protected void computeAverageChainingDistances(KNNQuery<O> knnq, DistanceQuery<O> dq, DBIDs ids, WritableDoubleDataStore acds) {
    FiniteProgress lrdsProgress = LOG.isVerbose() ? new FiniteProgress("Computing average chaining distances", ids.size(), LOG) : null;
   
   
    for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
      final KNNList neighbors = knnq.getKNNForDBID(iter, k);
      final int r = neighbors.size();
      DoubleDBIDListIter it1 = neighbors.iter(), it2 = neighbors.iter();
     
      final double[] mindists = new double[r];
      for(int i = 0; it1.valid(); it1.advance(), ++i) {
        mindists[i] = DBIDUtil.equal(it1, iter) ? Double.NaN : it1.doubleValue();
      }
      double acsum = 0.;
      for(int j = ((r < k) ? r : k) - 1; j > 0; --j) {
       
        int minpos = -1;
        double mindist = Double.NaN;
        for(int i = 0; i < mindists.length; ++i) {
          double curdist = mindists[i];
         
          if(curdist == curdist && !(curdist > mindist)) {
            minpos = i;
            mindist = curdist;
          }
        }
        acsum += mindist * j;
        mindists[minpos] = Double.NaN;
        it1.seek(minpos);
       
        it2.seek(0);
        for(int i = 0; it2.valid(); it2.advance(), ++i) {
          final double curdist = mindists[i];
          if(curdist != curdist) {
            continue;
          }
          double newdist = dq.distance(it1, it2);
          if(newdist < curdist) {
            mindists[i] = newdist;
          }
        }
      }
      acds.putDouble(iter, acsum / (r * 0.5 * (r - 1.)));
      LOG.incrementProcessed(lrdsProgress);
    }
    LOG.ensureCompleted(lrdsProgress);
  }
protected void computeaveragechainingdistances(knnquery<o> knnq, distancequery<o> dq, dbids ids, writabledoubledatastore acds) { finiteprogress lrdsprogress = log.isverbose() ? new finiteprogress("computing average chaining distances", ids.size(), log) : null; for(dbiditer iter = ids.iter(); iter.valid(); iter.advance()) { final knnlist neighbors = knnq.getknnfordbid(iter, k); final int r = neighbors.size(); doubledbidlistiter it1 = neighbors.iter(), it2 = neighbors.iter(); final double[] mindists = new double[r]; for(int i = 0; it1.valid(); it1.advance(), ++i) { mindists[i] = dbidutil.equal(it1, iter) ? double.nan : it1.doublevalue(); } double acsum = 0.; for(int j = ((r < k) ? r : k) - 1; j > 0; --j) { int minpos = -1; double mindist = double.nan; for(int i = 0; i < mindists.length; ++i) { double curdist = mindists[i]; if(curdist == curdist && !(curdist > mindist)) { minpos = i; mindist = curdist; } } acsum += mindist * j; mindists[minpos] = double.nan; it1.seek(minpos); it2.seek(0); for(int i = 0; it2.valid(); it2.advance(), ++i) { final double curdist = mindists[i]; if(curdist != curdist) { continue; } double newdist = dq.distance(it1, it2); if(newdist < curdist) { mindists[i] = newdist; } } } acds.putdouble(iter, acsum / (r * 0.5 * (r - 1.))); log.incrementprocessed(lrdsprogress); } log.ensurecompleted(lrdsprogress); }