1
package de.lmu.ifi.dbs.elki.database.query.knn;
4
This file is part of ELKI:
5
Environment for Developing KDD-Applications Supported by Index-Structures
8
Ludwig-Maximilians-Universität München
9
Lehr- und Forschungseinheit für Datenbanksysteme
12
This program is free software: you can redistribute it and/or modify
13
it under the terms of the GNU Affero General Public License as published by
14
the Free Software Foundation, either version 3 of the License, or
15
(at your option) any later version.
17
This program is distributed in the hope that it will be useful,
18
but WITHOUT ANY WARRANTY; without even the implied warranty of
19
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
GNU Affero General Public License for more details.
22
You should have received a copy of the GNU Affero General Public License
23
along with this program. If not, see <http://www.gnu.org/licenses/>.
26
import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory;
27
import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
28
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
29
import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
30
import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
31
import de.lmu.ifi.dbs.elki.database.query.LinearScanQuery;
32
import de.lmu.ifi.dbs.elki.database.query.distance.PrimitiveDistanceQuery;
33
import de.lmu.ifi.dbs.elki.database.relation.Relation;
34
import de.lmu.ifi.dbs.elki.distance.distancefunction.PrimitiveDoubleDistanceFunction;
35
import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
38
* Optimized linear scan query for {@link PrimitiveDoubleDistanceFunction}s.
40
* @author Erich Schubert
42
* @apiviz.uses PrimitiveDoubleDistanceFunction
44
* @param <O> Object type
46
public class DoubleOptimizedDistanceKNNQuery<O> extends AbstractDistanceKNNQuery<O, DoubleDistance> implements LinearScanQuery {
48
* Raw distance function.
50
PrimitiveDoubleDistanceFunction<O> rawdist;
53
* Constructor.newDoubleDistanceHeap
55
* @param distanceQuery Distance function to use
57
@SuppressWarnings("unchecked")
58
public DoubleOptimizedDistanceKNNQuery(PrimitiveDistanceQuery<O, DoubleDistance> distanceQuery) {
60
if(!(distanceQuery.getDistanceFunction() instanceof PrimitiveDoubleDistanceFunction)) {
61
throw new UnsupportedOperationException("DoubleOptimizedKNNQuery instantiated for non-PrimitiveDoubleDistanceFunction!");
63
rawdist = (PrimitiveDoubleDistanceFunction<O>) distanceQuery.getDistanceFunction();
67
public DoubleDistanceKNNList getKNNForDBID(DBIDRef id, int k) {
68
final Relation<? extends O> relation = this.relation;
69
DoubleDistanceKNNHeap heap = DBIDFactory.FACTORY.newDoubleDistanceHeap(k);
70
linearScan(relation, relation.iterDBIDs(), rawdist, relation.get(id), heap);
71
return heap.toKNNList();
75
public DoubleDistanceKNNList getKNNForObject(O obj, int k) {
76
DoubleDistanceKNNHeap heap = DBIDFactory.FACTORY.newDoubleDistanceHeap(k);
77
linearScan(relation, relation.iterDBIDs(), rawdist, obj, heap);
78
return heap.toKNNList();
81
private static <O> void linearScan(Relation<? extends O> relation, DBIDIter iter, PrimitiveDoubleDistanceFunction<? super O> rawdist, final O obj, DoubleDistanceKNNHeap heap) {
82
double kdist = Double.POSITIVE_INFINITY;
84
final double dist = rawdist.doubleDistance(obj, relation.get(iter));
86
kdist = heap.insert(dist, iter);