use of de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair in project elki by elki-project.
the class XSplitter method removeFromMBR.
/**
* Update operation for maintaining the second entry distribution. Removes the
* entries associated with indices <code>≤ index</code> from the
* dimensions' lower and upper bound priority queues (<code>pqLB</code> and
* <code>pqUB</code>). Whenever this causes a change in a dimension's lower or
* upper bound, <code>mbr</code> is updated accordingly.
*
* @param pqUB One priority queue for each dimension. They are sorted by upper
* bound in descending order and consist of entry indices for the
* entries belonging to <code>mbr</code> (and possibly others, which
* may first have to be removed).
* @param pqLB One priority queue for each dimension. They are sorted by lower
* bound in ascending order and consist of entry indices for the
* entries belonging to <code>mbr</code> (and possibly others, which
* may first have to be removed).
* @param index All indices <code>≤ index</code> must no longer be part of
* <code>mbr</code>.
* @param mbr The MBR to be adapted to a smaller entry list.
*/
private void removeFromMBR(List<Heap<DoubleIntPair>> pqUB, List<Heap<DoubleIntPair>> pqLB, int index, ModifiableHyperBoundingBox mbr) {
boolean change = false;
DoubleIntPair pqPair;
for (int d = 0; d < mbr.getDimensionality(); d++) {
// remove all relevant upper bound entries belonging to the first set
pqPair = pqUB.get(d).peek();
while (pqPair.second <= index) {
change = true;
pqUB.get(d).poll();
pqPair = pqUB.get(d).peek();
}
if (change) {
// there probably was a change, as an entry has been removed
mbr.setMax(d, pqPair.first);
}
change = false;
// remove all relevant lower bound entries belonging to the first set
pqPair = pqLB.get(d).peek();
while (pqPair.second <= index) {
change = true;
pqLB.get(d).poll();
pqPair = pqLB.get(d).peek();
}
if (change) {
// there probably was a change, as an entry has been removed
mbr.setMin(d, pqPair.first);
}
change = false;
}
}
use of de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair in project elki by elki-project.
the class XSplitter method add2MBR.
/**
* Adds the minimum and maximum bounds of the MBR of entry
* <code>entrySorting[index]</code> in {@link #entries} to the dimension-wise
* upper and lower bound priority queues <code>pqUBFirst</code> and
* <code>pqLBFirst</code>.
*
* @param entrySorting a sorting providing the mapping of <code>index</code>
* to the entry in {@link #entries} to be added
* @param pqUB One priority queue for each dimension. They are sorted by upper
* bound in descending order and consist of entry indices in
* <code>entrySorting</code> for the entries belonging to
* <code>mbr</code>.
* @param pqLB One priority queue for each dimension. They are sorted by lower
* bound in ascending order and consist of entry indices in
* <code>entrySorting</code> for the entries belonging to
* <code>mbr</code>.
* @param index the index in the sorting referencing the entry to be added
*/
private void add2MBR(int[] entrySorting, List<Heap<DoubleIntPair>> pqUB, List<Heap<DoubleIntPair>> pqLB, int index) {
SpatialComparable currMBR = node.getEntry(entrySorting[index]);
for (int d = 0; d < currMBR.getDimensionality(); d++) {
double max = currMBR.getMax(d);
pqUB.get(d).add(new DoubleIntPair(max, index));
double min = currMBR.getMin(d);
pqLB.get(d).add(new DoubleIntPair(min, index));
}
}
use of de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair in project elki by elki-project.
the class InMemoryIDistanceIndex method rankReferencePoints.
/**
* Sort the reference points by distance to the query object
*
* @param distanceQuery Distance query
* @param obj Query object
* @param referencepoints Iterator for reference points
* @return Sorted array.
*/
protected static <O> DoubleIntPair[] rankReferencePoints(DistanceQuery<O> distanceQuery, O obj, ArrayDBIDs referencepoints) {
DoubleIntPair[] priority = new DoubleIntPair[referencepoints.size()];
// Compute distances to reference points.
for (DBIDArrayIter iter = referencepoints.iter(); iter.valid(); iter.advance()) {
final int i = iter.getOffset();
final double dist = distanceQuery.distance(obj, iter);
priority[i] = new DoubleIntPair(dist, i);
}
Arrays.sort(priority);
return priority;
}
use of de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair in project elki by elki-project.
the class AbstractMTree method getSortedEntries.
/**
* Sorts the entries of the specified node according to their minimum distance
* to the specified object.
*
* @param node the node
* @param q the id of the object
* @return a list of the sorted entries
*/
protected final List<DoubleIntPair> getSortedEntries(N node, DBID q) {
List<DoubleIntPair> result = new ArrayList<>();
for (int i = 0; i < node.getNumEntries(); i++) {
E entry = node.getEntry(i);
double distance = distance(entry.getRoutingObjectID(), q);
double radius = entry.getCoveringRadius();
double minDist = (radius > distance) ? 0.0 : distance - radius;
result.add(new DoubleIntPair(minDist, i));
}
Collections.sort(result);
return result;
}
use of de.lmu.ifi.dbs.elki.utilities.pairs.DoubleIntPair in project elki by elki-project.
the class XSplitter method getSurfaceSums4Sorting.
/**
* Compute the surfaces of the <code>2 * (maxEntries - minEntries + 1)</code>
* split MBRs resulting for the sorting <code>entrySorting</code>.
*
* @param minEntries minimally allowed subgroup size
* @param maxEntries maximally allowed subgroup size for the first entry set
* @param entrySorting a permutation of the indices of {@link #entries}
* @param dim the dimension of the tree
* @return the sum of all first and second MBRs' surfaces for the tested entry
* distributions
*/
private double getSurfaceSums4Sorting(int minEntries, int maxEntries, int[] entrySorting, int dim) {
// avoid multiple MBR calculations by updating min/max-logs for the two
// collections' bounds:
// the first entries' maximum upper bounds
double[] pqUBFirst = new double[dim];
Arrays.fill(pqUBFirst, Double.NEGATIVE_INFINITY);
// maintain the second entries' upper bounds
List<Heap<DoubleIntPair>> pqUBSecond = new ArrayList<>(dim);
for (int i = 0; i < dim; i++) {
// Descending heap
pqUBSecond.add(new TopBoundedHeap<DoubleIntPair>(maxEntries, Collections.reverseOrder()));
}
// the first entries' minimum lower bounds
double[] pqLBFirst = new double[dim];
Arrays.fill(pqLBFirst, Double.POSITIVE_INFINITY);
// maintain the second entries' minimum lower bounds
List<Heap<DoubleIntPair>> pqLBSecond = new ArrayList<>(dim);
for (int i = 0; i < dim; i++) {
// Ascending heap
pqLBSecond.add(new TopBoundedHeap<DoubleIntPair>(maxEntries));
}
// initialize bounds for first entry collection
for (int index = 0; index < minEntries; index++) {
add2MBR(entrySorting, pqUBFirst, pqLBFirst, index);
}
HyperBoundingBox mbr1 = new HyperBoundingBox(pqLBFirst, pqUBFirst);
// fill bounding queues for the second entry collection
double[] minSecond = new double[dim];
double[] maxSecond = new double[dim];
Arrays.fill(maxSecond, Double.NEGATIVE_INFINITY);
Arrays.fill(minSecond, Double.POSITIVE_INFINITY);
assert entrySorting.length - maxEntries == minEntries;
// initialize min/max entries of the second collections' tail
for (int index = maxEntries; index < entrySorting.length; index++) {
add2MBR(entrySorting, maxSecond, minSecond, index);
}
for (int i = 0; i < dim; i++) {
// with index entrySorting.length => never to be removed
pqLBSecond.get(i).add(new DoubleIntPair(minSecond[i], entrySorting.length));
pqUBSecond.get(i).add(new DoubleIntPair(maxSecond[i], entrySorting.length));
}
// add the entries to be removed later on
for (int index = minEntries; index < maxEntries; index++) {
add2MBR(entrySorting, pqUBSecond, pqLBSecond, index);
}
for (int i = 0; i < minSecond.length; i++) {
minSecond[i] = pqLBSecond.get(i).peek().first;
maxSecond[i] = pqUBSecond.get(i).peek().first;
}
ModifiableHyperBoundingBox mbr2 = new ModifiableHyperBoundingBox(minSecond, maxSecond);
double surfaceSum = SpatialUtil.perimeter(mbr1) + SpatialUtil.perimeter(mbr2);
// generate the other distributions and file the surface sums
for (int limit = minEntries; limit < maxEntries; limit++) {
// extend first MBR by entry at position entrySorting[limit]:
add2MBR(entrySorting, pqUBFirst, pqLBFirst, limit);
// shrink entry at position entrySorting[limit] from second MBR:
removeFromMBR(pqUBSecond, pqLBSecond, limit, mbr2);
surfaceSum += SpatialUtil.perimeter(mbr1) + SpatialUtil.perimeter(mbr2);
}
return surfaceSum;
}
Aggregations