use of de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction in project elki by elki-project.
the class PAMInitialMeans method chooseInitialMeans.
@Override
public <T extends NumberVector> double[][] chooseInitialMeans(Database database, Relation<T> relation, int k, NumberVectorDistanceFunction<? super T> distanceFunction) {
if (relation.size() < k) {
throw new AbortException("Database has less than k objects.");
}
// Ugly cast; but better than code duplication.
@SuppressWarnings("unchecked") Relation<O> rel = (Relation<O>) relation;
// Get a distance query
@SuppressWarnings("unchecked") final PrimitiveDistanceFunction<? super O> distF = (PrimitiveDistanceFunction<? super O>) distanceFunction;
final DistanceQuery<O> distQ = database.getDistanceQuery(rel, distF);
DBIDs medids = chooseInitialMedoids(k, rel.getDBIDs(), distQ);
double[][] medoids = new double[k][];
DBIDIter iter = medids.iter();
for (int i = 0; i < k; i++, iter.advance()) {
medoids[i] = relation.get(iter).toArray();
}
return medoids;
}
use of de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction in project elki by elki-project.
the class SLINK method run.
/**
* Performs the SLINK algorithm on the given database.
*
* @param database Database to process
* @param relation Data relation to use
*/
public PointerHierarchyRepresentationResult run(Database database, Relation<O> relation) {
DBIDs ids = relation.getDBIDs();
WritableDBIDDataStore pi = DataStoreUtil.makeDBIDStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_STATIC);
WritableDoubleDataStore lambda = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_STATIC, Double.POSITIVE_INFINITY);
// Temporary storage for m.
WritableDoubleDataStore m = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
// To allow CLINK logger override
final Logging log = getLogger();
FiniteProgress progress = log.isVerbose() ? new FiniteProgress("Running SLINK", ids.size(), log) : null;
ArrayDBIDs aids = DBIDUtil.ensureArray(ids);
// First element is trivial/special:
DBIDArrayIter id = aids.iter(), it = aids.iter();
// Step 1: initialize
for (; id.valid(); id.advance()) {
// P(n+1) = n+1:
pi.put(id, id);
// L(n+1) = infinity already.
}
// First element is finished already (start at seek(1) below!)
log.incrementProcessed(progress);
// Optimized branch
if (getDistanceFunction() instanceof PrimitiveDistanceFunction) {
PrimitiveDistanceFunction<? super O> distf = (PrimitiveDistanceFunction<? super O>) getDistanceFunction();
for (id.seek(1); id.valid(); id.advance()) {
step2primitive(id, it, id.getOffset(), relation, distf, m);
// SLINK or CLINK
process(id, aids, it, id.getOffset(), pi, lambda, m);
log.incrementProcessed(progress);
}
} else {
// Fallback branch
DistanceQuery<O> distQ = database.getDistanceQuery(relation, getDistanceFunction());
for (id.seek(1); id.valid(); id.advance()) {
step2(id, it, id.getOffset(), distQ, m);
// SLINK or CLINK
process(id, aids, it, id.getOffset(), pi, lambda, m);
log.incrementProcessed(progress);
}
}
log.ensureCompleted(progress);
// We don't need m anymore.
m.destroy();
m = null;
return new PointerHierarchyRepresentationResult(ids, pi, lambda, getDistanceFunction().isSquared());
}
use of de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDistanceFunction in project elki by elki-project.
the class BestOfMultipleKMeans method run.
@Override
public Clustering<M> run(Database database, Relation<V> relation) {
if (!(innerkMeans.getDistanceFunction() instanceof PrimitiveDistanceFunction)) {
throw new AbortException("K-Means results can only be evaluated for primitive distance functions, got: " + innerkMeans.getDistanceFunction().getClass());
}
@SuppressWarnings("unchecked") final NumberVectorDistanceFunction<? super NumberVector> df = (NumberVectorDistanceFunction<? super NumberVector>) innerkMeans.getDistanceFunction();
Clustering<M> bestResult = null;
double bestCost = Double.NaN;
FiniteProgress prog = LOG.isVerbose() ? new FiniteProgress("K-means iterations", trials, LOG) : null;
for (int i = 0; i < trials; i++) {
Clustering<M> currentCandidate = innerkMeans.run(database, relation);
double currentCost = qualityMeasure.quality(currentCandidate, df, relation);
if (LOG.isVerbose()) {
LOG.verbose("Cost of candidate " + i + ": " + currentCost);
}
if (qualityMeasure.isBetter(currentCost, bestCost)) {
bestResult = currentCandidate;
bestCost = currentCost;
}
LOG.incrementProcessed(prog);
}
LOG.ensureCompleted(prog);
return bestResult;
}
Aggregations