Пример #1
0
        // 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));
        }
Пример #2
0
        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));
        }
Пример #3
0
        public string predic(IKDTreeDomain input)
        {
            double        r;
            IKDTreeDomain nb = NearestNeighbour(input, out r);

            return(pointsLabel[nb]);
        }
Пример #4
0
    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);
    }
Пример #5
0
 internal HREntry(HyperRectangle rect, KDTree tree, IKDTreeDomain pivot,
                  double dist)
 {
     this.rect  = rect;
     this.tree  = tree;
     this.pivot = pivot;
     this.dist  = dist;
 }
Пример #6
0
    // 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);
    }
Пример #7
0
    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);
    }
Пример #8
0
    // 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);
    }
Пример #9
0
        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);
        }
Пример #10
0
    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);
    }
Пример #11
0
 internal bool IsInReach(IKDTreeDomain target, double distRad)
 {
     return(Distance(target) < distRad);
 }
Пример #12
0
 internal BestEntry(IKDTreeDomain neighbour, double dist)
 {
     this.neighbour = neighbour;
     this.dist      = dist;
 }
Пример #13
0
    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);
    }
Пример #14
0
    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);
    }
Пример #15
0
    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);
    }
Пример #16
0
    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);
    }
Пример #17
0
    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);
    }
Пример #18
0
    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);
    }
Пример #19
0
 internal BestEntry(IKDTreeDomain neighbour, int distSq, bool squared)
 {
     this.neighbour = neighbour;
     this.distSq    = distSq;
 }