// Return the distance from the nearest point from within the HR to the target point. internal double Distance(IKDTreeDomain target) { float closestPointN; float distance = 0; // first compute the closest point within hr to the target. if // this point is within reach of target, then there is an // intersection between the hypersphere around target with radius // 'dist' and this hyperrectangle. for (int n = 0; n < dim; ++n) { float tI = target.GetDimensionElement(n); float hrMin = leftTop[n]; float hrMax = rightBottom[n]; closestPointN = 0; if (tI <= hrMin) { closestPointN = hrMin; } else if (tI > hrMin && tI < hrMax) { closestPointN = tI; } else if (tI >= hrMax) { closestPointN = hrMax; } float dimDist = tI - closestPointN; distance += dimDist * dimDist; } return(Math.Sqrt((double)distance)); }
internal double Distance(IKDTreeDomain target) { int closestPointN; int distance = 0; for (int n = 0; n < dim; ++n) { int tI = target.GetDimensionElement(n); int hrMin = leftTop[n]; int hrMax = rightBottom[n]; closestPointN = 0; if (tI <= hrMin) { closestPointN = hrMin; } else if (tI > hrMin && tI < hrMax) { closestPointN = tI; } else if (tI >= hrMax) { closestPointN = hrMax; } int dimDist = tI - closestPointN; distance += dimDist * dimDist; } return(Math.Sqrt((double)distance)); }
public string predic(IKDTreeDomain input) { double r; IKDTreeDomain nb = NearestNeighbour(input, out r); return(pointsLabel[nb]); }
public IKDTreeDomain NearestNeighbourListBBF(IKDTreeDomain target, int searchSteps) { // Same as above but always return the NN only. ArrayList list = NearestNeighbourListBBF(target, 1, searchSteps); return(((BestEntry)list[0]).Neighbour); }
internal HREntry(HyperRectangle rect, KDTree tree, IKDTreeDomain pivot, double dist) { this.rect = rect; this.tree = tree; this.pivot = pivot; this.dist = dist; }
// Find the nearest neighbour to the hyperspace point 'target' within the // kd-tree. After return 'resDist' contains the absolute distance from the // target point. The nearest neighbour is returned. public IKDTreeDomain NearestNeighbour(IKDTreeDomain target, out double resDist) { HyperRectangle hr = HyperRectangle.CreateUniverseRectangle(target.DimensionCount); IKDTreeDomain nearest = NearestNeighbourI(target, hr, Double.PositiveInfinity, out resDist); resDist = Math.Sqrt(resDist); return(nearest); }
public static float DistanceSq(IKDTreeDomain t1, IKDTreeDomain t2) { float distance = 0; for (int n = 0; n < t1.DimensionCount; ++n) { float dimDist = t1.GetDimensionElement(n) - t2.GetDimensionElement(n); distance += dimDist * dimDist; } return(distance); }
// Limited Best-Bin-First k-d-tree nearest neighbour search. // // (Using the algorithm described in the paper "Shape indexing using // approximate nearest-neighbour search in high-dimensional spaces", // available at http://www.cs.ubc.ca/spider/lowe/papers/cvpr97-abs.html) // // Find the approximate nearest neighbour to the hyperspace point 'target' // within the kd-tree using 'searchSteps' tail recursions at most (each // recursion deciding about one neighbours' fitness). // // After return 'resDist' contains the absolute distance of the // approximate nearest neighbour from the target point. The approximate // nearest neighbour is returned. public ArrayList NearestNeighbourListBBF(IKDTreeDomain target, int q, int searchSteps) { HyperRectangle hr = HyperRectangle.CreateUniverseRectangle(target.DimensionCount); SortedLimitedList best = new SortedLimitedList(q); SortedLimitedList searchHr = new SortedLimitedList(searchSteps); float dummyDist; IKDTreeDomain nearest = NearestNeighbourListBBFI(best, q, target, hr, float.MaxValue, out dummyDist, searchHr, ref searchSteps); foreach (BestEntry be in best) { be.Distance = Math.Sqrt(be.DistanceSq); } return(best); }
internal bool IsIn(IKDTreeDomain target) { if (target.DimensionCount != dim) { throw (new ArgumentException("IsIn dimension mismatch")); } for (int n = 0; n < dim; ++n) { int targD = target.GetDimensionElement(n); if (targD < leftTop[n] || targD >= rightBottom[n]) { return(false); } } return(true); }
public ArrayList NearestNeighbourList(IKDTreeDomain target, out double resDist, int q) { HyperRectangle hr = HyperRectangle.CreateUniverseRectangle(target.DimensionCount); SortedLimitedList best = new SortedLimitedList(q); IKDTreeDomain nearest = NearestNeighbourListI(best, q, target, hr, Double.PositiveInfinity, out resDist); resDist = Math.Sqrt(resDist); foreach (BestEntry be in best) { be.Distance = Math.Sqrt(be.Distance); } return(best); }
internal bool IsInReach(IKDTreeDomain target, double distRad) { return(Distance(target) < distRad); }
internal BestEntry(IKDTreeDomain neighbour, double dist) { this.neighbour = neighbour; this.dist = dist; }
private IKDTreeDomain NearestNeighbourListBBFI(SortedLimitedList best, int q, IKDTreeDomain target, HyperRectangle hr, int maxDistSq, out int resDistSq, SortedLimitedList searchHr, ref int searchSteps) { resDistSq = Int32.MaxValue; IKDTreeDomain pivot = dr; best.Add(new BestEntry(dr, KDTree.DistanceSq(target, dr), true)); HyperRectangle leftHr = hr; HyperRectangle rightHr = leftHr.SplitAt(splitDim, pivot.GetDimensionElement(splitDim)); HyperRectangle nearerHr, furtherHr; KDTree nearerKd, furtherKd; if (target.GetDimensionElement(splitDim) <= pivot.GetDimensionElement(splitDim)) { nearerKd = left; nearerHr = leftHr; furtherKd = right; furtherHr = rightHr; } else { nearerKd = right; nearerHr = rightHr; furtherKd = left; furtherHr = leftHr; } IKDTreeDomain nearest = null; int distSq; searchHr.Add(new HREntry(furtherHr, furtherKd, pivot, furtherHr.Distance(target))); if (nearerKd == null) { distSq = Int32.MaxValue; } else { nearest = nearerKd.NearestNeighbourListBBFI(best, q, target, nearerHr, maxDistSq, out distSq, searchHr, ref searchSteps); } if (best.Count >= q) { maxDistSq = ((BestEntry)best[q - 1]).DistanceSq; } else { maxDistSq = Int32.MaxValue; } if (searchHr.Count > 0) { HREntry hre = (HREntry)searchHr[0]; searchHr.RemoveAt(0); furtherHr = hre.HR; furtherKd = hre.Tree; pivot = hre.Pivot; } searchSteps -= 1; if (searchSteps > 0 && furtherHr.IsInReach(target, Math.Sqrt(maxDistSq))) { int ptDistSq = KDTree.DistanceSq(pivot, target); if (ptDistSq < distSq) { nearest = pivot; distSq = ptDistSq; maxDistSq = distSq; } int tempDistSq; IKDTreeDomain tempNearest = null; if (furtherKd == null) { tempDistSq = Int32.MaxValue; } else { tempNearest = furtherKd.NearestNeighbourListBBFI(best, q, target, furtherHr, maxDistSq, out tempDistSq, searchHr, ref searchSteps); } if (tempDistSq < distSq) { nearest = tempNearest; distSq = tempDistSq; } } resDistSq = distSq; return(nearest); }
private IKDTreeDomain NearestNeighbourListI(SortedLimitedList best, int q, IKDTreeDomain target, HyperRectangle hr, double maxDistSq, out double resDistSq) { resDistSq = Double.PositiveInfinity; IKDTreeDomain pivot = dr; best.Add(new BestEntry(dr, KDTree.DistanceSq(target, dr))); HyperRectangle leftHr = hr; HyperRectangle rightHr = leftHr.SplitAt(splitDim, pivot.GetDimensionElement(splitDim)); HyperRectangle nearerHr, furtherHr; KDTree nearerKd, furtherKd; // step 5-7 if (target.GetDimensionElement(splitDim) <= pivot.GetDimensionElement(splitDim)) { nearerKd = left; nearerHr = leftHr; furtherKd = right; furtherHr = rightHr; } else { nearerKd = right; nearerHr = rightHr; furtherKd = left; furtherHr = leftHr; } // step 8 IKDTreeDomain nearest = null; double distSq; // No child, bottom reached! if (nearerKd == null) { distSq = Double.PositiveInfinity; } else { nearest = nearerKd.NearestNeighbourListI(best, q, target, nearerHr, maxDistSq, out distSq); } // step 9 //maxDistSq = Math.Min (maxDistSq, distSq); if (best.Count >= q) { maxDistSq = ((BestEntry)best[q - 1]).Distance; } else { maxDistSq = Double.PositiveInfinity; } // step 10 if (furtherHr.IsInReach(target, Math.Sqrt(maxDistSq))) { double ptDistSq = KDTree.DistanceSq(pivot, target); if (ptDistSq < distSq) { // steps 10.1.1 to 10.1.3 nearest = pivot; distSq = ptDistSq; // TODO: use k-element list /* * best.Add (new BestEntry (pivot, ptDistSq)); * best.Sort (); */ maxDistSq = distSq; } // step 10.2 double tempDistSq; IKDTreeDomain tempNearest = null; if (furtherKd == null) { tempDistSq = Double.PositiveInfinity; } else { tempNearest = furtherKd.NearestNeighbourListI(best, q, target, furtherHr, maxDistSq, out tempDistSq); } // step 10.3 if (tempDistSq < distSq) { nearest = tempNearest; distSq = tempDistSq; } } resDistSq = distSq; return(nearest); }
private IKDTreeDomain NearestNeighbourI(IKDTreeDomain target, HyperRectangle hr, double maxDistSq, out double resDistSq) { resDistSq = Double.PositiveInfinity; IKDTreeDomain pivot = dr; HyperRectangle leftHr = hr; HyperRectangle rightHr = leftHr.SplitAt(splitDim, pivot.GetDimensionElement(splitDim)); HyperRectangle nearerHr, furtherHr; KDTree nearerKd, furtherKd; if (target.GetDimensionElement(splitDim) <= pivot.GetDimensionElement(splitDim)) { nearerKd = left; nearerHr = leftHr; furtherKd = right; furtherHr = rightHr; } else { nearerKd = right; nearerHr = rightHr; furtherKd = left; furtherHr = leftHr; } IKDTreeDomain nearest = null; double distSq; if (nearerKd == null) { distSq = Double.PositiveInfinity; } else { nearest = nearerKd.NearestNeighbourI(target, nearerHr, maxDistSq, out distSq); } maxDistSq = Math.Min(maxDistSq, distSq); if (furtherHr.IsInReach(target, Math.Sqrt(maxDistSq))) { double ptDistSq = KDTree.DistanceSq(pivot, target); if (ptDistSq < distSq) { nearest = pivot; distSq = ptDistSq; maxDistSq = distSq; } double tempDistSq; IKDTreeDomain tempNearest = null; if (furtherKd == null) { tempDistSq = Double.PositiveInfinity; } else { tempNearest = furtherKd.NearestNeighbourI(target, furtherHr, maxDistSq, out tempDistSq); } if (tempDistSq < distSq) { nearest = tempNearest; distSq = tempDistSq; } } resDistSq = distSq; return(nearest); }
private IKDTreeDomain NearestNeighbourListI(SortedLimitedList best, int q, IKDTreeDomain target, HyperRectangle hr, double maxDistSq, out double resDistSq) { resDistSq = Double.PositiveInfinity; IKDTreeDomain pivot = dr; best.Add(new BestEntry(dr, KDTree.DistanceSq(target, dr))); HyperRectangle leftHr = hr; HyperRectangle rightHr = leftHr.SplitAt(splitDim, pivot.GetDimensionElement(splitDim)); HyperRectangle nearerHr, furtherHr; KDTree nearerKd, furtherKd; if (target.GetDimensionElement(splitDim) <= pivot.GetDimensionElement(splitDim)) { nearerKd = left; nearerHr = leftHr; furtherKd = right; furtherHr = rightHr; } else { nearerKd = right; nearerHr = rightHr; furtherKd = left; furtherHr = leftHr; } IKDTreeDomain nearest = null; double distSq; if (nearerKd == null) { distSq = Double.PositiveInfinity; } else { nearest = nearerKd.NearestNeighbourListI(best, q, target, nearerHr, maxDistSq, out distSq); } if (best.Count >= q) { maxDistSq = ((BestEntry)best[q - 1]).Distance; } else { maxDistSq = Double.PositiveInfinity; } if (furtherHr.IsInReach(target, Math.Sqrt(maxDistSq))) { double ptDistSq = KDTree.DistanceSq(pivot, target); if (ptDistSq < distSq) { nearest = pivot; distSq = ptDistSq; maxDistSq = distSq; } double tempDistSq; IKDTreeDomain tempNearest = null; if (furtherKd == null) { tempDistSq = Double.PositiveInfinity; } else { tempNearest = furtherKd.NearestNeighbourListI(best, q, target, furtherHr, maxDistSq, out tempDistSq); } if (tempDistSq < distSq) { nearest = tempNearest; distSq = tempDistSq; } } resDistSq = distSq; return(nearest); }
static private IKDTreeDomain GoodCandidate(ArrayList exset, out int splitDim) { IKDTreeDomain first = exset[0] as IKDTreeDomain; if (first == null) { Console.WriteLine("type: {0}", exset[0]); throw (new Exception("Not of type IKDTreeDomain (TODO: custom exception)")); } int dim = first.DimensionCount; // initialize temporary hr search min/max values double[] minHr = new double[dim]; double[] maxHr = new double[dim]; for (int k = 0; k < dim; ++k) { minHr[k] = Double.PositiveInfinity; maxHr[k] = Double.NegativeInfinity; } foreach (IKDTreeDomain dom in exset) { for (int k = 0; k < dim; ++k) { double dimE = dom.GetDimensionElement(k); if (dimE < minHr[k]) { minHr[k] = dimE; } if (dimE > maxHr[k]) { maxHr[k] = dimE; } } } // find the maximum range dimension double[] diffHr = new double[dim]; int maxDiffDim = 0; double maxDiff = 0.0; for (int k = 0; k < dim; ++k) { diffHr[k] = maxHr[k] - minHr[k]; if (diffHr[k] > maxDiff) { maxDiff = diffHr[k]; maxDiffDim = k; } } // the splitting dimension is maxDiffDim // now find a exemplar as close to the arithmetic middle as possible double middle = (maxDiff / 2.0) + minHr[maxDiffDim]; IKDTreeDomain exemplar = null; double exemMinDiff = Double.PositiveInfinity; foreach (IKDTreeDomain dom in exset) { double curDiff = Math.Abs(dom.GetDimensionElement(maxDiffDim) - middle); if (curDiff < exemMinDiff) { exemMinDiff = curDiff; exemplar = dom; } } // return the values splitDim = maxDiffDim; return(exemplar); }
static private IKDTreeDomain GoodCandidate(ArrayList exset, out int splitDim) { IKDTreeDomain first = exset[0] as IKDTreeDomain; if (first == null) { Console.WriteLine("type: {0}", exset[0]); throw (new Exception("Not of type IKDTreeDomain (TODO: custom exception)")); } int dim = first.DimensionCount; double[] minHr = new double[dim]; double[] maxHr = new double[dim]; for (int k = 0; k < dim; ++k) { minHr[k] = Double.PositiveInfinity; maxHr[k] = Double.NegativeInfinity; } foreach (IKDTreeDomain dom in exset) { for (int k = 0; k < dim; ++k) { double dimE = dom.GetDimensionElement(k); if (dimE < minHr[k]) { minHr[k] = dimE; } if (dimE > maxHr[k]) { maxHr[k] = dimE; } } } double[] diffHr = new double[dim]; int maxDiffDim = 0; double maxDiff = 0.0; for (int k = 0; k < dim; ++k) { diffHr[k] = maxHr[k] - minHr[k]; if (diffHr[k] > maxDiff) { maxDiff = diffHr[k]; maxDiffDim = k; } } double middle = (maxDiff / 2.0) + minHr[maxDiffDim]; IKDTreeDomain exemplar = null; double exemMinDiff = Double.PositiveInfinity; foreach (IKDTreeDomain dom in exset) { double curDiff = Math.Abs(dom.GetDimensionElement(maxDiffDim) - middle); if (curDiff < exemMinDiff) { exemMinDiff = curDiff; exemplar = dom; } } splitDim = maxDiffDim; return(exemplar); }
internal BestEntry(IKDTreeDomain neighbour, int distSq, bool squared) { this.neighbour = neighbour; this.distSq = distSq; }