use of de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException in project elki by elki-project.
the class KMeansPlusPlusInitialMeans method chooseInitialMeans.
@Override
public <T extends NumberVector> double[][] chooseInitialMeans(Database database, Relation<T> relation, int k, NumberVectorDistanceFunction<? super T> distanceFunction) {
DistanceQuery<T> distQ = database.getDistanceQuery(relation, distanceFunction);
DBIDs ids = relation.getDBIDs();
WritableDoubleDataStore weights = DataStoreUtil.makeDoubleStorage(ids, DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP, 0.);
// Chose first mean
List<NumberVector> means = new ArrayList<>(k);
if (ids.size() <= k) {
throw new AbortException("Don't use k-means with k >= data set size.");
}
Random random = rnd.getSingleThreadedRandom();
DBIDRef first = DBIDUtil.randomSample(ids, random);
T firstvec = relation.get(first);
means.add(firstvec);
// Initialize weights
double weightsum = initialWeights(weights, ids, firstvec, distQ);
while (true) {
if (weightsum > Double.MAX_VALUE) {
LoggingUtil.warning("Could not choose a reasonable mean for k-means++ - too many data points, too large squared distances?");
}
if (weightsum < Double.MIN_NORMAL) {
LoggingUtil.warning("Could not choose a reasonable mean for k-means++ - to few data points?");
}
double r = random.nextDouble() * weightsum, s = 0.;
DBIDIter it = ids.iter();
for (; s < r && it.valid(); it.advance()) {
s += weights.doubleValue(it);
}
if (!it.valid()) {
// Rare case, but happens due to floating math
// Decrease
weightsum -= (r - s);
// Retry
continue;
}
// Add new mean:
final T newmean = relation.get(it);
means.add(newmean);
if (means.size() >= k) {
break;
}
// Update weights:
weights.putDouble(it, 0.);
// Choose optimized version for double distances, if applicable.
weightsum = updateWeights(weights, ids, newmean, distQ);
}
// Explicitly destroy temporary data.
weights.destroy();
return unboxVectors(means);
}
use of de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException 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.utilities.exceptions.AbortException in project elki by elki-project.
the class BundleWriter method writeBundleStream.
/**
* Write a bundle stream to a file output channel.
*
* @param source Data source
* @param output Output channel
* @throws IOException on IO errors
*/
public void writeBundleStream(BundleStreamSource source, WritableByteChannel output) throws IOException {
ByteBuffer buffer = ByteBuffer.allocateDirect(INITIAL_BUFFER);
DBIDVar var = DBIDUtil.newVar();
ByteBufferSerializer<?>[] serializers = null;
loop: while (true) {
BundleStreamSource.Event ev = source.nextEvent();
switch(ev) {
case NEXT_OBJECT:
if (serializers == null) {
serializers = writeHeader(source, buffer, output);
}
if (serializers[0] != null) {
if (!source.assignDBID(var)) {
throw new AbortException("An object did not have an DBID assigned.");
}
DBID id = DBIDUtil.deref(var);
@SuppressWarnings("unchecked") ByteBufferSerializer<DBID> ser = (ByteBufferSerializer<DBID>) serializers[0];
int size = ser.getByteSize(id);
buffer = ensureBuffer(size, buffer, output);
ser.toByteBuffer(buffer, id);
}
for (int i = 1, j = 0; i < serializers.length; ++i, ++j) {
@SuppressWarnings("unchecked") ByteBufferSerializer<Object> ser = (ByteBufferSerializer<Object>) serializers[i];
int size = ser.getByteSize(source.data(j));
buffer = ensureBuffer(size, buffer, output);
ser.toByteBuffer(buffer, source.data(j));
}
// switch
break;
case META_CHANGED:
if (serializers != null) {
throw new AbortException("Meta changes are not supported, once the block header has been written.");
}
// switch
break;
case END_OF_STREAM:
break loop;
default:
LOG.warning("Unknown bundle stream event. API inconsistent? " + ev);
// switch
break;
}
}
if (buffer.position() > 0) {
flushBuffer(buffer, output);
}
}
use of de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException in project elki by elki-project.
the class TrivialDBIDFactory method generateSingleDBID.
@Override
public DBID generateSingleDBID() {
final int id = next.getAndIncrement();
if (id == Integer.MAX_VALUE) {
throw new AbortException("DBID allocation error - too many objects allocated!");
}
DBID ret = new IntegerDBID(id);
return ret;
}
use of de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException in project elki by elki-project.
the class SimpleDBIDFactory method generateStaticDBIDRange.
@Override
public synchronized DBIDRange generateStaticDBIDRange(int size) {
if (rangestart >= Integer.MAX_VALUE - size) {
throw new AbortException("DBID range allocation error - too many objects allocated!");
}
DBIDRange alloc = new IntegerDBIDRange(rangestart, size);
rangestart += size;
return alloc;
}
Aggregations