use of de.lmu.ifi.dbs.elki.database.ids.DBIDVar in project elki by elki-project.
the class DiSH method extractClusters.
/**
* Extracts the clusters from the cluster order.
*
* @param relation the database storing the objects
* @param clusterOrder the cluster order to extract the clusters from
* @return the extracted clusters
*/
private Object2ObjectOpenCustomHashMap<long[], List<ArrayModifiableDBIDs>> extractClusters(Relation<V> relation, DiSHClusterOrder clusterOrder) {
FiniteProgress progress = LOG.isVerbose() ? new FiniteProgress("Extract Clusters", relation.size(), LOG) : null;
Object2ObjectOpenCustomHashMap<long[], List<ArrayModifiableDBIDs>> clustersMap = new Object2ObjectOpenCustomHashMap<>(BitsUtil.FASTUTIL_HASH_STRATEGY);
// Note clusterOrder currently contains DBID objects anyway.
WritableDataStore<Pair<long[], ArrayModifiableDBIDs>> entryToClusterMap = DataStoreUtil.makeStorage(relation.getDBIDs(), DataStoreFactory.HINT_TEMP | DataStoreFactory.HINT_HOT, Pair.class);
for (DBIDIter iter = clusterOrder.iter(); iter.valid(); iter.advance()) {
V object = relation.get(iter);
long[] preferenceVector = clusterOrder.getCommonPreferenceVector(iter);
// get the list of (parallel) clusters for the preference vector
List<ArrayModifiableDBIDs> parallelClusters = clustersMap.get(preferenceVector);
if (parallelClusters == null) {
parallelClusters = new ArrayList<>();
clustersMap.put(preferenceVector, parallelClusters);
}
// look for the proper cluster
ArrayModifiableDBIDs cluster = null;
for (ArrayModifiableDBIDs c : parallelClusters) {
NumberVector c_centroid = ProjectedCentroid.make(preferenceVector, relation, c);
long[] commonPreferenceVector = BitsUtil.andCMin(preferenceVector, preferenceVector);
int subspaceDim = subspaceDimensionality(object, c_centroid, preferenceVector, preferenceVector, commonPreferenceVector);
if (subspaceDim == clusterOrder.getCorrelationValue(iter)) {
double d = weightedDistance(object, c_centroid, commonPreferenceVector);
if (d <= 2 * epsilon) {
cluster = c;
break;
}
}
}
if (cluster == null) {
cluster = DBIDUtil.newArray();
parallelClusters.add(cluster);
}
cluster.add(iter);
entryToClusterMap.put(iter, new Pair<>(preferenceVector, cluster));
LOG.incrementProcessed(progress);
}
LOG.ensureCompleted(progress);
if (LOG.isDebuggingFiner()) {
int dim = RelationUtil.dimensionality(relation);
StringBuilder msg = new StringBuilder("Step 0");
for (Map.Entry<long[], List<ArrayModifiableDBIDs>> clusterList : clustersMap.entrySet()) {
for (ArrayModifiableDBIDs c : clusterList.getValue()) {
msg.append('\n').append(BitsUtil.toStringLow(clusterList.getKey(), dim)).append(" ids ").append(c.size());
}
}
LOG.debugFiner(msg.toString());
}
// add the predecessor to the cluster
DBIDVar cur = DBIDUtil.newVar(), pre = DBIDUtil.newVar();
for (long[] pv : clustersMap.keySet()) {
List<ArrayModifiableDBIDs> parallelClusters = clustersMap.get(pv);
for (ArrayModifiableDBIDs cluster : parallelClusters) {
if (cluster.isEmpty()) {
continue;
}
cluster.assignVar(0, cur);
clusterOrder.getPredecessor(cur, pre);
if (!pre.isSet() || DBIDUtil.equal(pre, cur)) {
continue;
}
// parallel cluster
if (BitsUtil.equal(clusterOrder.getCommonPreferenceVector(pre), clusterOrder.getCommonPreferenceVector(cur))) {
continue;
}
if (//
clusterOrder.getCorrelationValue(pre) < clusterOrder.getCorrelationValue(cur) || clusterOrder.getReachability(pre) < clusterOrder.getReachability(cur)) {
continue;
}
Pair<long[], ArrayModifiableDBIDs> oldCluster = entryToClusterMap.get(pre);
oldCluster.second.remove(pre);
cluster.add(pre);
entryToClusterMap.put(pre, new Pair<>(pv, cluster));
}
}
return clustersMap;
}
use of de.lmu.ifi.dbs.elki.database.ids.DBIDVar in project elki by elki-project.
the class HashmapDatabase method insert.
@Override
public DBIDs insert(ObjectBundle objpackages) {
if (objpackages.dataLength() == 0) {
return DBIDUtil.EMPTYDBIDS;
}
// insert into db
ArrayModifiableDBIDs newids = DBIDUtil.newArray(objpackages.dataLength());
Relation<?>[] targets = alignColumns(objpackages);
DBIDVar var = DBIDUtil.newVar();
for (int j = 0; j < objpackages.dataLength(); j++) {
// insert object
if (!objpackages.assignDBID(j, var)) {
var.set(DBIDUtil.generateSingleDBID());
}
if (ids.contains(var)) {
throw new AbortException("Duplicate DBID conflict.");
}
ids.add(var);
for (int i = 0; i < targets.length; i++) {
if (!(targets[i] instanceof ModifiableRelation)) {
throw new AbortException("Non-modifiable relations have been added to the database.");
}
@SuppressWarnings("unchecked") final ModifiableRelation<Object> relation = (ModifiableRelation<Object>) targets[i];
relation.insert(var, objpackages.data(j, i));
}
newids.add(var);
}
// fire insertion event
eventManager.fireObjectsInserted(newids);
return newids;
}
use of de.lmu.ifi.dbs.elki.database.ids.DBIDVar in project elki by elki-project.
the class PointerPrototypeHierarchyRepresentationResult method findPrototype.
/**
* Extract the prototype of a given cluster. When the argument is not a valid
* cluster of this Pointer Hierarchy, the return value is unspecified.
*
* @param members Cluster members
* @return The prototype of the cluster
*/
public DBID findPrototype(DBIDs members) {
// Find the last merge within the cluster.
// The object with maximum priority will merge outside of the cluster,
// So we need the second largest priority.
DBIDIter it = members.iter();
DBIDVar proto = DBIDUtil.newVar(it), last = DBIDUtil.newVar(it);
int maxprio = Integer.MIN_VALUE, secprio = Integer.MIN_VALUE;
for (; it.valid(); it.advance()) {
int prio = mergeOrder.intValue(it);
if (prio > maxprio) {
secprio = maxprio;
proto.set(last);
maxprio = prio;
last.set(it);
} else if (prio > secprio) {
secprio = prio;
proto.set(it);
}
}
return DBIDUtil.deref(prototypes.assignVar(proto, proto));
}
use of de.lmu.ifi.dbs.elki.database.ids.DBIDVar in project elki by elki-project.
the class SLINKHDBSCANLinearMemory method step4.
/**
* Fourth step: Actualize the clusters if necessary
*
* @param id the id of the current object
* @param pi Pi data store
* @param lambda Lambda data store
* @param processedIDs the already processed ids
*/
private void step4(DBIDRef id, WritableDBIDDataStore pi, WritableDoubleDataStore lambda, DBIDs processedIDs) {
DBIDVar p_i = DBIDUtil.newVar();
// for i = 1..n
for (DBIDIter it = processedIDs.iter(); it.valid(); it.advance()) {
double l_i = lambda.doubleValue(it);
// p_i = pi(it)
pi.assignVar(it, p_i);
double lp_i = lambda.doubleValue(p_i);
// if L(i) >= L(P(i))
if (l_i >= lp_i) {
// P(i) = n+1
pi.put(it, id);
}
}
}
use of de.lmu.ifi.dbs.elki.database.ids.DBIDVar in project elki by elki-project.
the class SLINKHDBSCANLinearMemory method step3.
/**
* Third step: Determine the values for P and L
*
* @param id the id of the object to be inserted into the pointer
* representation
* @param pi Pi data store
* @param lambda Lambda data store
* @param processedIDs the already processed ids
* @param m Data store
*/
private void step3(DBIDRef id, WritableDBIDDataStore pi, WritableDoubleDataStore lambda, DBIDs processedIDs, WritableDoubleDataStore m) {
DBIDVar p_i = DBIDUtil.newVar();
// for i = 1..n
for (DBIDIter it = processedIDs.iter(); it.valid(); it.advance()) {
double l_i = lambda.doubleValue(it);
double m_i = m.doubleValue(it);
// p_i = pi(it)
pi.assignVar(it, p_i);
double mp_i = m.doubleValue(p_i);
// if L(i) >= M(i)
if (l_i >= m_i) {
// M(P(i)) = min { M(P(i)), L(i) }
if (l_i < mp_i) {
m.putDouble(p_i, l_i);
}
// L(i) = M(i)
lambda.putDouble(it, m_i);
// P(i) = n+1;
pi.put(it, id);
} else {
// M(P(i)) = min { M(P(i)), M(i) }
if (m_i < mp_i) {
m.putDouble(p_i, m_i);
}
}
}
}
Aggregations