diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java')
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java | 211 |
1 files changed, 108 insertions, 103 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java index b98d6821..126013b1 100644 --- a/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java +++ b/src/de/lmu/ifi/dbs/elki/index/tree/metrical/mtreevariants/mktrees/mkcop/MkCoPTree.java @@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.mkcop; This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures - Copyright (C) 2013 + Copyright (C) 2014 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team @@ -31,21 +31,20 @@ import de.lmu.ifi.dbs.elki.database.ids.DBID; import de.lmu.ifi.dbs.elki.database.ids.DBIDIter; import de.lmu.ifi.dbs.elki.database.ids.DBIDRef; import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.DoubleDBIDListIter; +import de.lmu.ifi.dbs.elki.database.ids.KNNList; import de.lmu.ifi.dbs.elki.database.ids.ModifiableDBIDs; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDList; -import de.lmu.ifi.dbs.elki.database.ids.distance.DistanceDBIDListIter; -import de.lmu.ifi.dbs.elki.database.ids.distance.KNNList; -import de.lmu.ifi.dbs.elki.database.ids.generic.GenericDistanceDBIDList; +import de.lmu.ifi.dbs.elki.database.ids.ModifiableDoubleDBIDList; import de.lmu.ifi.dbs.elki.database.relation.Relation; -import de.lmu.ifi.dbs.elki.distance.distancevalue.NumberDistance; import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.AbstractMkTree; import de.lmu.ifi.dbs.elki.index.tree.metrical.mtreevariants.mktrees.MkTreeSettings; import de.lmu.ifi.dbs.elki.index.tree.query.GenericMTreeDistanceSearchCandidate; import de.lmu.ifi.dbs.elki.logging.Logging; -import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil; import de.lmu.ifi.dbs.elki.persistent.PageFile; import de.lmu.ifi.dbs.elki.utilities.FormatUtil; import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMinHeap; +import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil; /** * MkCopTree is a metrical index structure based on the concepts of the M-Tree @@ -58,9 +57,8 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.heap.ComparableMinHeap; * @apiviz.has ConvexHull * * @param <O> Object type - * @param <D> Distance type */ -public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree<O, D, MkCoPTreeNode<O, D>, MkCoPEntry, MkTreeSettings<O, D, MkCoPTreeNode<O, D>, MkCoPEntry>> { +public class MkCoPTree<O> extends AbstractMkTree<O, MkCoPTreeNode<O>, MkCoPEntry, MkTreeSettings<O, MkCoPTreeNode<O>, MkCoPEntry>> { /** * The logger for this class. */ @@ -78,11 +76,11 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree * @param pagefile Page file * @param settings Tree settings */ - public MkCoPTree(Relation<O> relation, PageFile<MkCoPTreeNode<O, D>> pagefile, MkTreeSettings<O, D, MkCoPTreeNode<O, D>, MkCoPEntry> settings) { + public MkCoPTree(Relation<O> relation, PageFile<MkCoPTreeNode<O>> pagefile, MkTreeSettings<O, MkCoPTreeNode<O>, MkCoPEntry> settings) { super(relation, pagefile, settings); // init log k log_k = new double[settings.k_max]; - for (int k = 1; k <= settings.k_max; k++) { + for(int k = 1; k <= settings.k_max; k++) { log_k[k - 1] = Math.log(k); } } @@ -105,34 +103,34 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree @Override public void insertAll(List<MkCoPEntry> entries) { - if (entries.isEmpty()) { + if(entries.isEmpty()) { return; } - if (LOG.isDebugging()) { + if(LOG.isDebugging()) { LOG.debugFine("insert " + entries + "\n"); } - if (!initialized) { + if(!initialized) { initialize(entries.get(0)); } ModifiableDBIDs ids = DBIDUtil.newArray(entries.size()); // insert - for (MkCoPEntry entry : entries) { + for(MkCoPEntry entry : entries) { ids.add(entry.getRoutingObjectID()); // insert the object super.insert(entry, false); } // perform nearest neighbor queries - Map<DBID, KNNList<D>> knnLists = batchNN(getRoot(), ids, settings.k_max); + Map<DBID, KNNList> knnLists = batchNN(getRoot(), ids, settings.k_max); // adjust the knn distances adjustApproximatedKNNDistances(getRootEntry(), knnLists); - if (EXTRA_INTEGRITY_CHECKS) { + if(EXTRA_INTEGRITY_CHECKS) { getRoot().integrityCheck(this, getRootEntry()); } } @@ -146,17 +144,17 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree * @return a List of the query results */ @Override - public DistanceDBIDList<D> reverseKNNQuery(DBIDRef id, int k) { - if (k > settings.k_max) { + public DoubleDBIDList reverseKNNQuery(DBIDRef id, int k) { + if(k > settings.k_max) { throw new IllegalArgumentException("Parameter k has to be less or equal than " + "parameter kmax of the MCop-Tree!"); } - GenericDistanceDBIDList<D> result = new GenericDistanceDBIDList<>(); + ModifiableDoubleDBIDList result = DBIDUtil.newDistanceDBIDList(); ModifiableDBIDs candidates = DBIDUtil.newArray(); doReverseKNNQuery(k, id, result, candidates); // refinement of candidates - Map<DBID, KNNList<D>> knnLists = batchNN(getRoot(), candidates, k); + Map<DBID, KNNList> knnLists = batchNN(getRoot(), candidates, k); result.sort(); // Collections.sort(candidates); @@ -165,12 +163,12 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree // rkNNStatistics.addCandidates(candidates.size()); // rkNNStatistics.addTrueHits(result.size()); - for (DBIDIter iter = candidates.iter(); iter.valid(); iter.advance()) { + for(DBIDIter iter = candidates.iter(); iter.valid(); iter.advance()) { DBID cid = DBIDUtil.deref(iter); - KNNList<D> cands = knnLists.get(cid); - for (DistanceDBIDListIter<D> iter2 = cands.iter(); iter2.valid(); iter2.advance()) { - if (DBIDUtil.equal(id, iter2)) { - result.add(iter2.getDistance(), cid); + KNNList cands = knnLists.get(cid); + for(DoubleDBIDListIter iter2 = cands.iter(); iter2.valid(); iter2.advance()) { + if(DBIDUtil.equal(id, iter2)) { + result.add(iter2.doubleValue(), cid); break; } } @@ -200,7 +198,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree // overhead = index(4), numEntries(4), id(4), isLeaf(0.125) double overhead = 12.125; - if (getPageSize() - overhead < 0) { + if(getPageSize() - overhead < 0) { throw new RuntimeException("Node size of " + getPageSize() + " Bytes is chosen too small!"); } @@ -208,11 +206,11 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree // coveringRadius + parentDistance + consApprox) + 1 dirCapacity = (int) (getPageSize() - overhead) / (4 + 4 + distanceSize + distanceSize + 10) + 1; - if (dirCapacity <= 1) { + if(dirCapacity <= 1) { throw new RuntimeException("Node size of " + getPageSize() + " Bytes is chosen too small!"); } - if (dirCapacity < 10) { + if(dirCapacity < 10) { LOG.warning("Page size is choosen too small! Maximum number of entries " + "in a directory node = " + (dirCapacity - 1)); } @@ -221,17 +219,17 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree // consApprox + progrApprox) + 1 leafCapacity = (int) (getPageSize() - overhead) / (4 + distanceSize + 2 * 10) + 1; - if (leafCapacity <= 1) { + if(leafCapacity <= 1) { throw new RuntimeException("Node size of " + getPageSize() + " Bytes is chosen too small!"); } - if (leafCapacity < 10) { + if(leafCapacity < 10) { LOG.warning("Page size is choosen too small! Maximum number of entries " + "in a leaf node = " + (leafCapacity - 1)); } initialized = true; - if (LOG.isVerbose()) { + if(LOG.isVerbose()) { LOG.verbose("Directory Capacity: " + (dirCapacity - 1) + "\nLeaf Capacity: " + (leafCapacity - 1)); } } @@ -245,45 +243,46 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree * @param candidates holds possible candidates for the result (they need a * refinement) */ - private void doReverseKNNQuery(int k, DBIDRef q, GenericDistanceDBIDList<D> result, ModifiableDBIDs candidates) { + private void doReverseKNNQuery(int k, DBIDRef q, ModifiableDoubleDBIDList result, ModifiableDBIDs candidates) { final ComparableMinHeap<GenericMTreeDistanceSearchCandidate> pq = new ComparableMinHeap<>(); // push root pq.add(new GenericMTreeDistanceSearchCandidate(0., getRootID(), null)); // search in tree - while (!pq.isEmpty()) { + while(!pq.isEmpty()) { GenericMTreeDistanceSearchCandidate pqNode = pq.poll(); // FIXME: cache the distance to the routing object in the queue node! - MkCoPTreeNode<O, D> node = getNode(pqNode.nodeID); + MkCoPTreeNode<O> node = getNode(pqNode.nodeID); // directory node - if (!node.isLeaf()) { - for (int i = 0; i < node.getNumEntries(); i++) { + if(!node.isLeaf()) { + for(int i = 0; i < node.getNumEntries(); i++) { MkCoPEntry entry = node.getEntry(i); - double distance = distance(entry.getRoutingObjectID(), q).doubleValue(); + double distance = distance(entry.getRoutingObjectID(), q); double minDist = entry.getCoveringRadius() > distance ? 0. : distance - entry.getCoveringRadius(); double approximatedKnnDist_cons = entry.approximateConservativeKnnDistance(k); - if (minDist <= approximatedKnnDist_cons) { + if(minDist <= approximatedKnnDist_cons) { pq.add(new GenericMTreeDistanceSearchCandidate(minDist, getPageID(entry), entry.getRoutingObjectID())); } } } // data node else { - for (int i = 0; i < node.getNumEntries(); i++) { + for(int i = 0; i < node.getNumEntries(); i++) { MkCoPLeafEntry entry = (MkCoPLeafEntry) node.getEntry(i); - D distance = distance(entry.getRoutingObjectID(), q); + double distance = distance(entry.getRoutingObjectID(), q); double approximatedKnnDist_prog = entry.approximateProgressiveKnnDistance(k); - if (distance.doubleValue() <= approximatedKnnDist_prog) { + if(distance <= approximatedKnnDist_prog) { result.add(distance, entry.getRoutingObjectID()); - } else { + } + else { double approximatedKnnDist_cons = entry.approximateConservativeKnnDistance(k); - double diff = distance.doubleValue() - approximatedKnnDist_cons; - if (diff <= 1E-10) { + double diff = distance - approximatedKnnDist_cons; + if(diff <= 1E-10) { candidates.add(entry.getRoutingObjectID()); } } @@ -298,16 +297,17 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree * @param entry the root entry of the current subtree * @param knnLists a map of knn lists for each leaf entry */ - private void adjustApproximatedKNNDistances(MkCoPEntry entry, Map<DBID, KNNList<D>> knnLists) { - MkCoPTreeNode<O, D> node = getNode(entry); + private void adjustApproximatedKNNDistances(MkCoPEntry entry, Map<DBID, KNNList> knnLists) { + MkCoPTreeNode<O> node = getNode(entry); - if (node.isLeaf()) { - for (int i = 0; i < node.getNumEntries(); i++) { + if(node.isLeaf()) { + for(int i = 0; i < node.getNumEntries(); i++) { MkCoPLeafEntry leafEntry = (MkCoPLeafEntry) node.getEntry(i); approximateKnnDistances(leafEntry, knnLists.get(leafEntry.getRoutingObjectID())); } - } else { - for (int i = 0; i < node.getNumEntries(); i++) { + } + else { + for(int i = 0; i < node.getNumEntries(); i++) { MkCoPEntry dirEntry = node.getEntry(i); adjustApproximatedKNNDistances(dirEntry, knnLists); } @@ -323,7 +323,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree private double ssqerr(int k0, int kmax, double[] logk, double[] log_kDist, double m, double t) { int k = kmax - k0; double result = 0; - for (int i = 0; i < k; i++) { + for(int i = 0; i < k; i++) { // double h = log_kDist[i] - (m * (logk[i] - logk[0]) + t); ??? double h = log_kDist[i] - m * logk[i] - t; result += h * h; @@ -349,19 +349,20 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree * @param knnDistances TODO: Spezialbehandlung fuer identische Punkte in DB * (insbes. Distanz 0) */ - private void approximateKnnDistances(MkCoPLeafEntry entry, KNNList<D> knnDistances) { + private void approximateKnnDistances(MkCoPLeafEntry entry, KNNList knnDistances) { StringBuilder msg = LOG.isDebugging() ? new StringBuilder() : null; - if (msg != null) { + if(msg != null) { msg.append("\nknnDistances ").append(knnDistances); } // count the zero distances int k_0 = 0; - for (int i = 0; i < settings.k_max; i++) { - double dist = knnDistances.get(i).getDistance().doubleValue(); - if (dist == 0) { + for(int i = 0; i < settings.k_max; i++) { + double dist = knnDistances.get(i).doubleValue(); + if(dist == 0) { k_0++; - } else { + } + else { break; } } @@ -374,8 +375,8 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree double sum_log_k_kDist = 0; double[] log_kDist = new double[settings.k_max - k_0]; - for (int i = 0; i < settings.k_max - k_0; i++) { - double dist = knnDistances.get(i + k_0).getDistance().doubleValue(); + for(int i = 0; i < settings.k_max - k_0; i++) { + double dist = knnDistances.get(i + k_0).doubleValue(); log_kDist[i] = Math.log(dist); sum_log_kDist += log_kDist[i]; sum_log_k_kDist += log_kDist[i] * log_k[i]; @@ -384,12 +385,12 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree double sum_log_k = 0; double sum_log_k2 = 0; // noinspection ForLoopReplaceableByForEach - for (int i = 0; i < log_k.length; i++) { + for(int i = 0; i < log_k.length; i++) { sum_log_k += log_k[i]; sum_log_k2 += (log_k[i] * log_k[i]); } - if (msg != null) { + if(msg != null) { msg.append("\nk_0 ").append(k_0); msg.append("\nk_max ").append(settings.k_max); msg.append("\nlog_k(").append(log_k.length).append(") ").append(FormatUtil.format(log_k)); @@ -412,12 +413,12 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree double err1 = ssqerr(k_0, settings.k_max, log_k, log_kDist, conservative.getM(), conservative.getT()); double err2 = ssqerr(k_0, settings.k_max, log_k, log_kDist, c2.getM(), c2.getT()); - if (msg != null) { + if(msg != null) { msg.append("err1 ").append(err1); msg.append("err2 ").append(err2); } - if (err1 > err2 && err1 - err2 > 0.000000001) { + if(err1 > err2 && err1 - err2 > 0.000000001) { // if (err1 > err2) { StringBuilder warning = new StringBuilder(); @@ -431,7 +432,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree warning.append("\nconservative1 ").append(conservative); warning.append("\nconservative2 ").append(c2); - for (int i = 0; i < u; i++) { + for(int i = 0; i < u; i++) { warning.append("\nlog_k[").append(upperHull[i]).append("] = ").append(log_k[upperHull[i]]); warning.append("\nlog_kDist[").append(upperHull[i]).append("] = ").append(log_kDist[upperHull[i]]); } @@ -444,7 +445,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree entry.setConservativeKnnDistanceApproximation(conservative); entry.setProgressiveKnnDistanceApproximation(progressive); - if (msg != null) { + if(msg != null) { LOG.debugFine(msg.toString()); } } @@ -470,12 +471,12 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree double low_m = 0.0; double low_t = 0.0; - for (int i = 1; i < l; i++) { + for(int i = 1; i < l; i++) { double cur_m = (log_kDist[lowerHull[i]] - log_kDist[lowerHull[i - 1]]) / (log_k[lowerHull[i]] - log_k[lowerHull[i - 1]]); double cur_t = log_kDist[lowerHull[i]] - cur_m * log_k[lowerHull[i]]; double cur_error = ssqerr(k_0, settings.k_max, log_k, log_kDist, cur_m, cur_t); msg.append(" Segment = ").append(i).append(" m = ").append(cur_m).append(" t = ").append(cur_t).append(" lowerror = ").append(cur_error).append("\n"); - if (cur_error < low_error) { + if(cur_error < low_error) { low_error = cur_error; low_m = cur_m; low_t = cur_t; @@ -484,13 +485,13 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree // linear search on all points of the lower convex hull boolean is_right = true; // NEEDED FOR PROOF CHECK - for (int i = 0; i < l; i++) { + for(int i = 0; i < l; i++) { double cur_m = optimize(k_0, settings.k_max, sum_log_k, sum_log_k2, log_k[lowerHull[i]], log_kDist[lowerHull[i]], sum_log_k_kDist, sum_log_kDist); double cur_t = log_kDist[lowerHull[i]] - cur_m * log_k[lowerHull[i]]; // only valid if both neighboring points are underneath y=mx+t - if ((i == 0 || log_kDist[lowerHull[i - 1]] >= log_kDist[lowerHull[i]] - cur_m * (log_k[lowerHull[i]] - log_k[lowerHull[i - 1]])) && (i == l - 1 || log_kDist[lowerHull[i + 1]] >= log_kDist[lowerHull[i]] + cur_m * (log_k[lowerHull[i + 1]] - log_k[lowerHull[i]]))) { + if((i == 0 || log_kDist[lowerHull[i - 1]] >= log_kDist[lowerHull[i]] - cur_m * (log_k[lowerHull[i]] - log_k[lowerHull[i - 1]])) && (i == l - 1 || log_kDist[lowerHull[i + 1]] >= log_kDist[lowerHull[i]] + cur_m * (log_k[lowerHull[i + 1]] - log_k[lowerHull[i]]))) { double cur_error = ssqerr(k_0, settings.k_max, log_k, log_kDist, cur_m, cur_t); - if (cur_error < low_error) { + if(cur_error < low_error) { low_error = cur_error; low_m = cur_m; low_t = cur_t; @@ -498,9 +499,9 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree } // check proof of bisection search - if (!(i > 0 && log_kDist[lowerHull[i - 1]] < log_kDist[lowerHull[i]] - cur_m * (log_k[lowerHull[i]] - log_k[lowerHull[i - 1]])) && !is_right) { + if(!(i > 0 && log_kDist[lowerHull[i - 1]] < log_kDist[lowerHull[i]] - cur_m * (log_k[lowerHull[i]] - log_k[lowerHull[i - 1]])) && !is_right) { // warning("ERROR lower: The bisection search will not work properly !"); - if (!(i < l - 1 && log_kDist[lowerHull[i + 1]] < log_kDist[lowerHull[i]] + cur_m * (log_k[lowerHull[i + 1]] - log_k[lowerHull[i]]))) { + if(!(i < l - 1 && log_kDist[lowerHull[i + 1]] < log_kDist[lowerHull[i]] + cur_m * (log_k[lowerHull[i + 1]] - log_k[lowerHull[i]]))) { is_right = false; } } @@ -519,14 +520,14 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree ApproximationLine approx = null; double error = Double.POSITIVE_INFINITY; - for (int i = 0; i < u - 1; i++) { + for(int i = 0; i < u - 1; i++) { int ii = upperHull[i]; int jj = upperHull[i + 1]; double current_m = (log_kDist[jj] - log_kDist[ii]) / (log_k[jj] - log_k[ii]); double current_t = log_kDist[ii] - current_m * log_k[ii]; ApproximationLine current_approx = new ApproximationLine(k_0, current_m, current_t); - if (LOG.isDebugging()) { + if(LOG.isDebugging()) { msg.append("\nlog_kDist[").append(jj).append("] ").append(log_kDist[jj]); msg.append("\nlog_kDist[").append(ii).append("] ").append(log_kDist[ii]); msg.append("\nlog_k[").append(jj).append("] ").append(log_k[jj]); @@ -537,22 +538,22 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree boolean ok = true; double currentError = 0; - for (int k = k_0; k <= settings.k_max; k++) { + for(int k = k_0; k <= settings.k_max; k++) { double appDist = current_approx.getValueAt(k); - if (appDist < log_kDist[k - k_0] && log_kDist[k - k_0] - appDist > 0.000000001) { + if(appDist < log_kDist[k - k_0] && log_kDist[k - k_0] - appDist > 0.000000001) { ok = false; break; } currentError += (appDist - log_kDist[k - k_0]); } - if (ok && currentError < error) { + if(ok && currentError < error) { approx = current_approx; error = currentError; } } - if (LOG.isDebugging()) { + if(LOG.isDebugging()) { msg.append("\nupper Approx ").append(approx); LOG.debugFine(msg.toString()); } @@ -570,7 +571,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree int k_0 = settings.k_max - upperHull.length + 1; int a = u / 2; - while (marked.size() != u) { + while(marked.size() != u) { marked.add(a); double x_a = log_k[upperHull[a]]; double y_a = log_kDist[upperHull[a]]; @@ -578,7 +579,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree double m_a = optimize(k_0, settings.k_max, sum_log_k, sum_log_k2, x_a, y_a, sum_log_k_kDist, sum_log_kDist); double t_a = y_a - m_a * x_a; - if (msg != null) { + if(msg != null) { msg.append("\na=").append(a).append(" m_a=").append(m_a).append(", t_a=").append(t_a); msg.append("\n err ").append(ssqerr(k_0, settings.k_max, log_k, log_kDist, m_a, m_a)); } @@ -591,23 +592,24 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree boolean lessThanPre = a == 0 || y_p <= m_a * x_p + t_a; boolean lessThanSuc = a == u || y_s <= m_a * x_s + t_a; - if (lessThanPre && lessThanSuc) { + if(lessThanPre && lessThanSuc) { ApproximationLine appr = new ApproximationLine(k_0, m_a, t_a); - if (msg != null) { + if(msg != null) { msg.append("\n1 anchor = ").append(a); LOG.debugFine(msg.toString()); } return appr; - } else if (!lessThanPre) { - if (marked.contains(a - 1)) { + } + else if(!lessThanPre) { + if(marked.contains(a - 1)) { m_a = (y_a - y_p) / (x_a - x_p); - if (y_a == y_p) { + if(y_a == y_p) { m_a = 0; } t_a = y_a - m_a * x_a; ApproximationLine appr = new ApproximationLine(k_0, m_a, t_a); - if (msg != null) { + if(msg != null) { msg.append("2 anchor = ").append(a); msg.append(" appr1 ").append(appr); msg.append(" x_a ").append(x_a).append(", y_a ").append(y_a); @@ -617,25 +619,28 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree LOG.debugFine(msg.toString()); } return appr; - } else { + } + else { a = a - 1; } - } else { - if (marked.contains(a + 1)) { + } + else { + if(marked.contains(a + 1)) { m_a = (y_a - y_s) / (x_a - x_s); - if (y_a == y_p) { + if(y_a == y_p) { m_a = 0; } t_a = y_a - m_a * x_a; ApproximationLine appr = new ApproximationLine(k_0, m_a, t_a); - if (msg != null) { + if(msg != null) { msg.append("3 anchor = ").append(a).append(" -- ").append((a + 1)); msg.append(" appr2 ").append(appr); LOG.debugFine(msg.toString()); } return appr; - } else { + } + else { a = a + 1; } } @@ -657,11 +662,11 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree double upp_error = Double.MAX_VALUE; double upp_m = 0.0; double upp_t = 0.0; - for (int i = 1; i < u; i++) { + for(int i = 1; i < u; i++) { double cur_m = (log_kDist[upperHull[i]] - log_kDist[upperHull[i - 1]]) / (log_k[upperHull[i]] - log_k[upperHull[i - 1]]); double cur_t = log_kDist[upperHull[i]] - cur_m * log_k[upperHull[i]]; double cur_error = ssqerr(k_0, settings.k_max, log_k, log_kDist, cur_m, cur_t); - if (cur_error < upp_error) { + if(cur_error < upp_error) { upp_error = cur_error; upp_m = cur_m; upp_t = cur_t; @@ -669,13 +674,13 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree } // linear search on all points of the upper convex hull boolean is_left = true; // NEEDED FOR PROOF CHECK - for (int i = 0; i < u; i++) { + for(int i = 0; i < u; i++) { double cur_m = optimize(k_0, settings.k_max, sum_log_k, sum_log_k2, log_k[upperHull[i]], log_kDist[upperHull[i]], sum_log_k_kDist, sum_log_kDist); double cur_t = log_kDist[upperHull[i]] - cur_m * log_k[upperHull[i]]; // only valid if both neighboring points are underneath y=mx+t - if ((i == 0 || log_kDist[upperHull[i - 1]] <= log_kDist[upperHull[i]] - cur_m * (log_k[upperHull[i]] - log_k[upperHull[i - 1]])) && (i == u - 1 || log_kDist[upperHull[i + 1]] <= log_kDist[upperHull[i]] + cur_m * (log_k[upperHull[i + 1]] - log_k[upperHull[i]]))) { + if((i == 0 || log_kDist[upperHull[i - 1]] <= log_kDist[upperHull[i]] - cur_m * (log_k[upperHull[i]] - log_k[upperHull[i - 1]])) && (i == u - 1 || log_kDist[upperHull[i + 1]] <= log_kDist[upperHull[i]] + cur_m * (log_k[upperHull[i + 1]] - log_k[upperHull[i]]))) { double cur_error = ssqerr(k_0, settings.k_max, log_k, log_kDist, cur_m, cur_t); - if (cur_error < upp_error) { + if(cur_error < upp_error) { upp_error = cur_error; upp_m = cur_m; upp_t = cur_t; @@ -683,12 +688,12 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree } // check proof of bisection search - if (!(i > 0 && log_kDist[upperHull[i - 1]] > log_kDist[upperHull[i]] - cur_m * (log_k[upperHull[i]] - log_k[upperHull[i - 1]])) && !is_left) { + if(!(i > 0 && log_kDist[upperHull[i - 1]] > log_kDist[upperHull[i]] - cur_m * (log_k[upperHull[i]] - log_k[upperHull[i - 1]])) && !is_left) { // warning("ERROR upper: The bisection search will not work properly !" // + // "\n" + Util.format(log_kDist)); } - if (!(i < u - 1 && log_kDist[upperHull[i + 1]] > log_kDist[upperHull[i]] + cur_m * (log_k[upperHull[i + 1]] - log_k[upperHull[i]]))) { + if(!(i < u - 1 && log_kDist[upperHull[i + 1]] > log_kDist[upperHull[i]] + cur_m * (log_k[upperHull[i + 1]] - log_k[upperHull[i]]))) { is_left = false; } } @@ -703,7 +708,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree * @return a new leaf node */ @Override - protected MkCoPTreeNode<O, D> createNewLeafNode() { + protected MkCoPTreeNode<O> createNewLeafNode() { return new MkCoPTreeNode<>(leafCapacity, true); } @@ -713,7 +718,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree * @return a new directory node */ @Override - protected MkCoPTreeNode<O, D> createNewDirectoryNode() { + protected MkCoPTreeNode<O> createNewDirectoryNode() { return new MkCoPTreeNode<>(dirCapacity, false); } @@ -726,7 +731,7 @@ public class MkCoPTree<O, D extends NumberDistance<D, ?>> extends AbstractMkTree * the routing object of the parent node */ @Override - protected MkCoPEntry createNewDirectoryEntry(MkCoPTreeNode<O, D> node, DBID routingObjectID, double parentDistance) { + protected MkCoPEntry createNewDirectoryEntry(MkCoPTreeNode<O> node, DBID routingObjectID, double parentDistance) { return new MkCoPDirectoryEntry(routingObjectID, parentDistance, node.getPageID(), node.coveringRadius(routingObjectID, this), null); // node.conservativeKnnDistanceApproximation(k_max)); } |