DistanceQuery<V, D> distFunc = relation.getDatabase().getDistanceQuery(relation, distanceFunction);
Collection<V> refPoints = refp.getReferencePoints(relation);
DBIDs ids = relation.getDBIDs();
// storage of distance/score values.
WritableDoubleDataStore rbod_score = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_STATIC | DataStoreFactory.HINT_HOT);
// Compute density estimation:
{
// compute density for one reference point, to initialize the first
// density
// value for each object, then update
final Iterator<V> iter = refPoints.iterator();
if(!iter.hasNext()) {
throw new AbortException("Cannot compute ROS without reference points!");
}
V firstRef = iter.next();
// compute distance vector for the first reference point
List<DistanceResultPair<D>> firstReferenceDists = computeDistanceVector(firstRef, relation, distFunc);
for(int l = 0; l < firstReferenceDists.size(); l++) {
double density = computeDensity(firstReferenceDists, l);
// Initial value
rbod_score.putDouble(firstReferenceDists.get(l).getDBID(), density);
}
// compute density values for all remaining reference points
while(iter.hasNext()) {
V refPoint = iter.next();
List<DistanceResultPair<D>> referenceDists = computeDistanceVector(refPoint, relation, distFunc);
// compute density value for each object
for(int l = 0; l < referenceDists.size(); l++) {
double density = computeDensity(referenceDists, l);
// Update minimum
if(density < rbod_score.doubleValue(referenceDists.get(l).getDBID())) {
rbod_score.putDouble(referenceDists.get(l).getDBID(), density);
}
}
}
}
// compute maximum density
double maxDensity = 0.0;
for(DBID id : relation.iterDBIDs()) {
double dens = rbod_score.doubleValue(id);
if(dens > maxDensity) {
maxDensity = dens;
}
}
// compute ROS
for(DBID id : relation.iterDBIDs()) {
double score = 1 - (rbod_score.doubleValue(id) / maxDensity);
rbod_score.putDouble(id, score);
}
// adds reference points to the result. header information for the
// visualizer to find the reference points in the result
ReferencePointsResult<V> refp = new ReferencePointsResult<V>("Reference points", "reference-points", refPoints);