From e9077643efd3f6db76f3c82ba1bcb19ecc8024a0 Mon Sep 17 00:00:00 2001 From: Tilmann Date: Sun, 11 Aug 2024 14:38:18 +0200 Subject: [PATCH] BallTree WIP --- .../org/tinspin/index/balltree/BTNode.java | 40 ++++------------ .../org/tinspin/index/balltree/BTUtil.java | 46 ------------------- 2 files changed, 10 insertions(+), 76 deletions(-) diff --git a/src/main/java/org/tinspin/index/balltree/BTNode.java b/src/main/java/org/tinspin/index/balltree/BTNode.java index 2de2dbb..28e003a 100644 --- a/src/main/java/org/tinspin/index/balltree/BTNode.java +++ b/src/main/java/org/tinspin/index/balltree/BTNode.java @@ -51,7 +51,6 @@ public class BTNode { this.values = values; } - @SuppressWarnings("unchecked") BTNode(double[] center, double radius, BTNode parent, BTNode left, BTNode right) { this.center = center; this.radius = radius; @@ -61,7 +60,7 @@ public class BTNode { this.right = right; } - @SuppressWarnings({ "unchecked", "unused" }) + @SuppressWarnings({"unused" }) BTNode tryPut(PointEntry e, int maxNodeSize, boolean enforceLeaf) { if (BallTree.DEBUG && !BTUtil.fitsIntoNode(e.point(), center, radius)) { throw new IllegalStateException("e=" + Arrays.toString(e.point()) + @@ -101,26 +100,26 @@ BTNode tryPut(PointEntry e, int maxNodeSize, boolean enforceLeaf) { splitDim = d; } } - double splitValue = ordered[splitDim][values.size() / 2]; + double splitValue = ordered[splitDim][vals.size() / 2]; - ArrayList> left = new ArrayList<>(); - ArrayList> right = new ArrayList<>(); + ArrayList> leftPoints = new ArrayList<>(); + ArrayList> rightPoints = new ArrayList<>(); for (int i = 0; i < vals.size(); i++) { PointEntry pe = vals.get(i); if (pe.point()[splitDim] >= splitValue) { - right.add(pe); + rightPoints.add(pe); } else { - left.add(pe); + leftPoints.add(pe); } } double[] centerLeft = new double[dims]; double[] centerRight = new double[dims]; - double radiusLeft = BTUtil.calcBoundingSphere(left, centerLeft); - double radiusRight = BTUtil.calcBoundingSphere(left, centerRight); + double radiusLeft = BTUtil.calcBoundingSphere(leftPoints, centerLeft); + double radiusRight = BTUtil.calcBoundingSphere(rightPoints, centerRight); - this.left = new BTNode<>(centerLeft, radiusLeft, this, left); - this.right = new BTNode<>(centerRight, radiusRight, this, right); + this.left = new BTNode<>(centerLeft, radiusLeft, this, leftPoints); + this.right = new BTNode<>(centerRight, radiusRight, this, rightPoints); return findBestChildForInsert(e); } @@ -155,25 +154,6 @@ private BTNode findBestChildForInsert(PointEntry e) { return resizeVolLeft > resizeVolRight ? this.right : this.left; } - - /** - * The subnode position has reverse ordering of the point's - * dimension ordering. Dimension 0 of a point is the highest - * ordered bit in the position. - * @param p point - * @return subnode position - */ - private int calcSubPosition(double[] p) { - int subNodePos = 0; - for (int d = 0; d < center.length; d++) { - subNodePos <<= 1; - if (p[d] >= center[d]) { - subNodePos |= 1; - } - } - return subNodePos; - } - PointEntry remove(BTNode parent, double[] key, int maxNodeSize, Predicate> pred) { if (!isLeaf()) { if (DIST.dist(left.center, key) <= left.radius) { diff --git a/src/main/java/org/tinspin/index/balltree/BTUtil.java b/src/main/java/org/tinspin/index/balltree/BTUtil.java index 6ec969f..7c3f784 100644 --- a/src/main/java/org/tinspin/index/balltree/BTUtil.java +++ b/src/main/java/org/tinspin/index/balltree/BTUtil.java @@ -57,27 +57,6 @@ public static boolean isPointEqual(double[] p1, double[] p2) { return true; } -// public static boolean isRectEqual(double[] p1L, double[] p1U, double[] p2L, double[] p2U) { -// return isPointEqual(p1L, p2L) && isPointEqual(p1U, p2U); -// } -// -// public static boolean isRectEqual(BoxEntry e, double[] keyL, double[] keyU) { -// return isRectEqual(e.min(), e.max(), keyL, keyU); -// } -// -// public static boolean isRectEqual(BoxEntry e, BoxEntry e2) { -// return isRectEqual(e.min(), e.max(), e2.min(), e2.max()); -// } -// -// public static boolean overlap(double[] min, double[] max, double[] min2, double[] max2) { -// for (int d = 0; d < min.length; d++) { -// if (max[d] < min2[d] || min[d] > max2[d]) { -// return false; -// } -// } -// return true; -// } - public static boolean overlap(double[] min, double[] max, double[] center, double radius) { double[] p = new double[min.length]; for (int d = 0; d < min.length; d++) { @@ -94,31 +73,6 @@ public static boolean overlap(double[] min, double[] max, double[] center, doubl return PointDistance.l2(p, center) <= radius; } -// public static boolean isRectEnclosed(double[] minEnclosed, double[] maxEnclosed, double[] minOuter, double[] maxOuter) { -// for (int d = 0; d < minOuter.length; d++) { -// if (maxOuter[d] < maxEnclosed[d] || minOuter[d] > minEnclosed[d]) { -// return false; -// } -// } -// return true; -// } -// -// /** -// * The tests for inclusion with UPPER BOUNDARY EXCLUSIVE! -// * I.e. it firs only if maxEnclosed is SMALLER than (center + radius). -// */ -// public static boolean fitsIntoNode(double[] minEnclosed, double[] maxEnclosed, double[] centerNode, double radiusNode) { -// double r2 = 0; -// for (int d = 0; d < centerNode.length; d++) { -// double r = centerNode[d] - -// r2 -// if ((centerNode[d] + radiusNode) <= maxEnclosed[d] || (centerNode[d] - radiusNode) > minEnclosed[d]) { -// return false; -// } -// } -// return true; -// } - public static boolean isNodeEnclosed(double[] centerEnclosed, double radiusEnclosed, double[] centerOuter, double radiusOuter) { return PointDistance.l2(centerEnclosed, centerOuter) + radiusEnclosed <= radiusOuter; }