Пример #1
0
 internal HREntry(HyperRectangle rect, KDTree tree, IKDTreeDomain pivot,
                  double dist)
 {
     this.rect  = rect;
     this.tree  = tree;
     this.pivot = pivot;
     this.dist  = dist;
 }
        private bool Intersects(HyperRectangleBuilder builder, HyperRectangle rect, int dimensionIndex)
        {
            return(Dataset.GetFeatureType(dimensionIndex) switch
            {
                FeatureType.Continuous => IntersectsContinuous(builder, rect, dimensionIndex),

                _ => throw CommonExceptions.UnknownFeatureType
            });
Пример #3
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);
    }
Пример #4
0
        static internal HyperRectangle CreateUniverseRectangle(int dim)
        {
            HyperRectangle rec = new HyperRectangle(dim);

            for (int n = 0; n < dim; ++n)
            {
                rec.leftTop[n]     = Int32.MinValue;
                rec.rightBottom[n] = Int32.MaxValue;
            }

            return(rec);
        }
Пример #5
0
        public object Clone()
        {
            HyperRectangle rec = new HyperRectangle(dim);

            for (int n = 0; n < dim; ++n)
            {
                rec.leftTop[n]     = leftTop[n];
                rec.rightBottom[n] = rightBottom[n];
            }

            return(rec);
        }
Пример #6
0
        public HyperRectangle[] FromRules(ReadOnlySpan <Rule> rules)
        {
            var boxes = new HyperRectangle[rules.Length];

            for (int i = 0; i < boxes.Length; i++)
            {
                var rule = rules[i];
                var box  = FromRule(rule);
                boxes[i] = box;
            }

            return(boxes);
        }
Пример #7
0
        public IFeatureTest[] FromHyperRectangle(HyperRectangle hyperRectangle)
        {
            var tests = new IFeatureTest[hyperRectangle.DimensionCount];

            for (int i = 0; i < tests.Length; i++)
            {
                var interval = hyperRectangle.GetDimensionInterval(i);
                var test     = _testIntervalConverter.FromDimensionInterval(interval);
                tests[i] = test;
            }

            return(tests);
        }
Пример #8
0
        internal HyperRectangle SplitAt(int splitDim, int splitVal)
        {
            if (leftTop[splitDim] >= splitVal || rightBottom[splitDim] < splitVal)
            {
                throw (new ArgumentException("SplitAt with splitpoint outside rec"));
            }

            HyperRectangle r2 = (HyperRectangle)this.Clone();

            rightBottom[splitDim] = splitVal;
            r2.leftTop[splitDim]  = splitVal;

            return(r2);
        }
Пример #9
0
        public DatasetCoverage ComputeCoverage(HyperRectangle hyperRectangle)
        {
            var instanceCount    = Dataset.InstanceCount;
            var instaceIsCovered = new bool[instanceCount];

            for (int i = 0; i < instaceIsCovered.Length; i++)
            {
                var instanceData = Dataset.GetInstanceData(i);
                instaceIsCovered[i] = hyperRectangle.Contains(instanceData);
            }

            return(new DatasetCoverage(
                       dataset: Dataset,
                       instancesCovered: instaceIsCovered));
        }
Пример #10
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);
    }
Пример #11
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);
    }
        public bool IntersectsInAllButOneDimension(HyperRectangleBuilder builder, HyperRectangle rect, int dimensionToSkip)
        {
            var dimensionCount = Dataset.FeatureCount;

            for (int i = 0; i < dimensionCount; i++)
            {
                if (i == dimensionToSkip)
                {
                    continue;
                }

                var intersects = Intersects(
                    builder: builder,
                    rect: rect,
                    dimensionIndex: i);

                if (!intersects)
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #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;

        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);
    }
Пример #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;

        // 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);
    }