ModifiableDBIDs unclustered = DBIDUtil.newHashSet(relation.getDBIDs());
final int maxdim = Math.min(maxLMDim, DatabaseUtil.dimensionality(relation));
int cnum = 0;
while(unclustered.size() > minsize) {
DBIDs current = unclustered;
int lmDim = 1;
for(int k = 1; k <= maxdim; k++) {
// Implementation note: this while loop is from the original publication
// and the published LMCLUS source code. It doesn't make sense to me -
// it is lacking a stop criterion other than "cluster is too small" and
// "cluster is inseparable"! Additionally, there is good criterion for
// stopping at the appropriate dimensionality either.
while(true) {
Separation separation = findSeparation(relation, current, k);
// logger.verbose("k: " + k + " goodness: " + separation.goodness +
// " threshold: " + separation.threshold);
if(separation.goodness <= sensitivityThreshold) {
break;
}
ModifiableDBIDs subset = DBIDUtil.newArray(current.size());
for(DBID id : current) {
if(deviation(relation.get(id).getColumnVector().minusEquals(separation.originV), separation.basis) < separation.threshold) {
subset.add(id);
}
}
// logger.verbose("size:"+subset.size());
if(subset.size() < minsize) {
break;
}
current = subset;
lmDim = k;
// System.out.println("Partition: " + subset.size());
}
}
// No more clusters found
if(current.size() < minsize || current == unclustered) {
break;
}
// New cluster found
// TODO: annotate cluster with dimensionality
final Cluster<Model> cluster = new Cluster<Model>(current);