Example #1
0
        internal float?CoreDistance(KdTree kdt, Dictionary <long, float?> coreDistances,
                                    IPointIdFloat p, float eps, int minPoints)
        {
            float?distance;
            long  id = p.id;

            if (coreDistances.ContainsKey(id))
            {
                coreDistances.TryGetValue(id, out distance);
            }
            else
            {
                var nNeighbours = NNearestNeighbours(kdt, p, minPoints);
                //There will always be at least one element, i.e. p itself
                float nthDistance = nNeighbours.Last().DistanceTo(p);

                if (nNeighbours.Count < minPoints || nthDistance > eps)
                {
                    distance = null;
                }
                else
                {
                    distance = nthDistance;
                }
                coreDistances.Add(id, distance);
            }
            return(distance);
        }
            public IPointIdFloat NearestNeighbour(IPointIdFloat target, IPointIdFloat nn, ref float nnDist,
                                                  Func <VBuffer <float>, VBuffer <float>, float> distFunc)
            {
                float key       = KeyByDepth(point, depth);
                float targetKey = KeyByDepth(target, depth);

                float       d = distFunc(point.coordinates, target.coordinates);
                IKdTreeNode closestBranch, fartherBranch;

                if (d < nnDist)
                {
                    nnDist = d;
                    nn     = point;
                }

                if (targetKey <= key)
                {
                    closestBranch = left;
                    fartherBranch = right;
                }
                else
                {
                    closestBranch = right;
                    fartherBranch = left;
                }

                nn = closestBranch.NearestNeighbour(target, nn, ref nnDist, distFunc);

                if (Math.Abs(targetKey - key) <= nnDist)
                {
                    nn = fartherBranch.NearestNeighbour(target, nn, ref nnDist, distFunc);
                }
                return(nn);
            }
Example #3
0
        public float Score(IPointIdFloat p, float epsilon, Dictionary <long, int> mapClusters)
        {
            var res = RegionQuery(kdt, p, epsilon);

            if (res.Count() <= 1)
            {
                return(1f);
            }
            else
            {
                var sorted = res.Select(pe => new Tuple <float, int>((float)(1 / (epsilon + p.DistanceTo(pe))), mapClusters[pe.id]))
                             .OrderBy(c => c);
                float score = 0f;
                int   last  = mapClusters[p.id];
                float lastd = 0f;
                foreach (var el in sorted)
                {
                    if (el.Item2 != last)
                    {
                        score += el.Item1 - lastd;
                        lastd  = el.Item1;
                    }
                }
                return(score);
            }
        }
        /// <summary>
        /// Returns the N points in the tree which are closest to the target.
        /// </summary>
        public IList <IPointIdFloat> NearestNNeighbors(IPointIdFloat target, int N)
        {
            var nns = NearestNNeighborsAndDistance(target, N)
                      .ToList()
                      .OrderBy(kvp => - kvp.Key)
                      .Select(kvp => kvp.Value)
                      .ToList();

            Comparison <IPointIdFloat> comparePointsByDistanceToTarget = (a, b) =>
            {
                float dA = _distFunc(a.coordinates, target.coordinates);
                float dB = _distFunc(b.coordinates, target.coordinates);
                if (dA < dB)
                {
                    return(-1);
                }
                else if (dA > dB)
                {
                    return(1);
                }
                else
                {
                    return(0);
                }
            };

            nns.Sort(comparePointsByDistanceToTarget);
            return(nns);
        }
            public void PointsWithinDistance(IPointIdFloat center, float distance, ref IList <IPointIdFloat> results,
                                             Func <VBuffer <float>, VBuffer <float>, float> distFunc)
            {
                float key       = KeyByDepth(point, depth);
                float centerKey = KeyByDepth(center, depth);

                float       d = distFunc(point.coordinates, center.coordinates);
                IKdTreeNode closestBranch, fartherBranch;

                if (d <= distance)
                {
                    results.Add(point);
                }

                if (centerKey <= key)
                {
                    closestBranch = left;
                    fartherBranch = right;
                }
                else
                {
                    closestBranch = right;
                    fartherBranch = left;
                }

                closestBranch.PointsWithinDistance(center, distance, ref results, distFunc);

                if (Math.Abs(centerKey - key) <= distance)
                {
                    fartherBranch.PointsWithinDistance(center, distance, ref results, distFunc);
                }
            }
        public IPointIdFloat NearestNeighbour(IPointIdFloat p)
        {
            ValidatePoint(p);
            float tmp = float.MaxValue;

            return(root.NearestNeighbour(p, null, ref tmp, _distFunc));
        }
Example #7
0
        /**
         *
         */
        internal static void ExpandCluster(Dictionary <long, int> clusters, HashSet <long> processed,
                                           IList <IPointIdFloat> points, IPointIdFloat pAdd, List <IPointIdFloat> pNeighbours,
                                           int clusterId, float epsilon, int minPoints)
        {
            if (!clusters.ContainsKey(pAdd.id))
            {
                // Some points might have been added as neighbours even though they were not visited.
                // Line A below.
                clusters.Add(pAdd.id, clusterId);
            }

            for (int i = 0; i < pNeighbours.Count; i++)
            {
                IPointIdFloat q = pNeighbours[i];
                if (!processed.Contains(q.id))
                {
                    processed.Add(q.id);
                    var qNeighbours = RegionQuery(points, q, epsilon);
                    if (qNeighbours.Count() > minPoints)
                    {
                        pNeighbours.AddRange(qNeighbours);
                    }
                }
                if (!clusters.ContainsKey(q.id))
                {
                    clusters.Add(q.id, clusterId);
                }
            }
        }
        public IList <IPointIdFloat> PointsWithinDistance(IPointIdFloat center, float distance)
        {
            ValidatePoint(center);
            IList <IPointIdFloat> results = new List <IPointIdFloat>();

            root.PointsWithinDistance(center, distance, ref results, _distFunc);
            return(results);
        }
Example #9
0
 internal static void MarkProcessed(IPointIdFloat p, Dictionary <long, long> orderingMapping,
                                    List <IPointIdFloat> ordering, HashSet <long> processed, ref int currentIndex)
 {
     processed.Add(p.id);
     orderingMapping.Add(p.id, currentIndex);
     ordering.Add(p);
     currentIndex += 1;
 }
 internal void ValidatePoint(IPointIdFloat p)
 {
     if (p == null)
     {
         throw new ArgumentNullException();
     }
     else if (p.dimension != dimension)
     {
         throw new ArgumentException(string.Format("Wrong Point dimension: expected {0}, got {1}", dimension, p.dimension));
     }
 }
 public KdTreeNode(IPointIdFloat point, IKdTreeNode left, IKdTreeNode right, int depth)
 {
     this.point = point;
     this.left  = left;
     this.right = right;
     this.depth = depth;
     size       = 1 + left.size + right.size;
     if (depth > MaxDepth)
     {
         throw Contracts.Except("The k-d tree depth is too high (> {0}). This probably means the datasets is too sparse to be effective. You should reduce the number of dimensions (PCA for example).", MaxDepth);
     }
 }
 public void Add(IPointIdFloat p)
 {
     if (root == null)
     {
         var points = new IPointIdFloat[] { p };
         ValidatePointsArray(points);
         root = CreateTree(points.ToList(), _rnd);
     }
     else
     {
         ValidatePoint(p);
         root.Add(p);
     }
 }
 public bool Contains(IPointIdFloat p)
 {
     if (point == p)
     {
         return(true);
     }
     else if (KeyByDepth(p, depth) <= KeyByDepth(point, depth))
     {
         return(left.Contains(p));
     }
     else
     {
         return(right.Contains(p));
     }
 }
            public IKdTreeNode Add(IPointIdFloat p)
            {
                float key  = this.Key();
                float pKey = KeyByDepth(p, depth);

                if (pKey <= key)
                {
                    left = left.Add(p);
                    size = 1 + left.size + right.size;
                }
                else
                {
                    right = right.Add(p);
                    size  = 1 + left.size + right.size;
                }
                return(this);
            }
Example #15
0
        private void testMedian(
            IList <IPointIdFloat> points,
            IPointIdFloat expectedMedian,
            IList <IPointIdFloat> expectedLeft,
            IList <IPointIdFloat> expectedRight,
            int depth = 0)
        {
            IList <IPointIdFloat>       left        = null;
            IList <IPointIdFloat>       right       = null;
            Func <IPointIdFloat, float> keySelector = t => KdTree.KdTreeNode.KeyByDepth(t, depth);

            IPointIdFloat median = KdTree.MedianPoint(points, ref left, ref right, depth, rnd);

            Assert.AreEqual(expectedMedian, median);
            Assert.IsTrue(SequenceEquivalent(expectedLeft, left, keySelector));
            Assert.IsTrue(SequenceEquivalent(expectedRight, right, keySelector));
        }
Example #16
0
        internal float?CoreDistance(KdTree kdt, IPointIdFloat p, float eps, int minPoints)
        {
            float?distance;
            long  id          = p.id;
            var   nNeighbours = NNearestNeighbours(kdt, p, minPoints);
            //There will always be at least one element, i.e. p itself
            var nthDistance = nNeighbours.Last().DistanceTo(p);

            if (nNeighbours.Count < minPoints || nthDistance > eps)
            {
                distance = null;
            }
            else
            {
                distance = nthDistance;
            }
            return(distance);
        }
        internal static IKdTreeNode CreateTree(IList <IPointIdFloat> points, Random rnd, int depth = 0)
        {
            switch (points.Count())
            {
            case 0:
                return(new KdTreeLeaf(depth));

            case 1:
                return(new KdTreeNode(points.First(), new KdTreeLeaf(depth + 1), new KdTreeLeaf(depth + 1), depth));

            default:
                IList <IPointIdFloat> leftPoints  = null;
                IList <IPointIdFloat> rightPoints = null;
                IPointIdFloat         median      = MedianPoint(points, ref leftPoints, ref rightPoints, depth, rnd);
                IKdTreeNode           left        = CreateTree(leftPoints, rnd, depth + 1);
                IKdTreeNode           right       = CreateTree(rightPoints, rnd, depth + 1);
                return(new KdTreeNode(median, left, right, depth));
            }
        }
            public FixedSizePriorityQueue <float, IPointIdFloat> NearestNNeighbors(IPointIdFloat target,
                                                                                   FixedSizePriorityQueue <float, IPointIdFloat> nns,
                                                                                   Func <VBuffer <float>, VBuffer <float>, float> distFunc)
            {
                float key       = KeyByDepth(point, depth);
                float targetKey = KeyByDepth(target, depth);

                float       d = distFunc(point.coordinates, target.coordinates);
                IKdTreeNode closestBranch, fartherBranch;
                float       nthNnDist = -nns.Peek().GetValueOrDefault(InfinitePoint).Key;

                if (!nns.IsFull || d < nthNnDist)
                {
                    nns.Enqueue(-d, point);
                }

                if (targetKey <= key)
                {
                    closestBranch = left;
                    fartherBranch = right;
                }
                else
                {
                    closestBranch = right;
                    fartherBranch = left;
                }

                nns = closestBranch.NearestNNeighbors(target, nns, distFunc);

                nthNnDist = -nns.Peek().GetValueOrDefault(InfinitePoint).Key;
                if (Math.Abs(targetKey - key) <= nthNnDist)
                {
                    nns = fartherBranch.NearestNNeighbors(target, nns, distFunc);
                }
                return(nns);
            }
Example #19
0
        internal void Update(
            ref PriorityQueue <float, IPointIdFloat> seeds,
            HashSet <long> processed,
            Dictionary <long, float?> reachabilityDistances,
            Dictionary <long, float?> coreDistancesCache,
            IPointIdFloat p,
            float eps,
            int minPoints)
        {
            IList <IPointIdFloat> neighbours = EpsilonNeighbourhood(kdt, p, eps);

            foreach (var o in neighbours)
            {
                long oId = o.id;
                if (!processed.Contains(oId))
                {
                    float?coreDistance;
                    coreDistancesCache.TryGetValue(p.id, out coreDistance);

                    float?reachDist;
                    // INVARIANT: coreDistance != null
                    float newReachDist = Math.Max(coreDistance.Value, o.DistanceTo(p));

                    reachabilityDistances.TryGetValue(oId, out reachDist);
                    if (reachDist == null || newReachDist < reachDist)
                    {   // reachDist == null => o is not in Seeds
                        // newReachDist < reachDist => o in Seeds, check for improvement
                        reachabilityDistances[oId] = newReachDist;
                        if (reachDist == null)
                        {
                            seeds.Enqueue(newReachDist, o);
                        }
                    }
                }
            }
        }
 public void PointsWithinDistance(IPointIdFloat center, float distance, ref IList <IPointIdFloat> results, Func <VBuffer <float>, VBuffer <float>, float> distFunc)
 {
     //Nothing to do
 }
Example #21
0
 /**
  *
  */
 internal static IList <IPointIdFloat> RegionQuery(KdTree points, IPointIdFloat p, float epsilon)
 {
     return(points.PointsWithinDistance(p, epsilon));
 }
Example #22
0
 /**
  *
  */
 internal static IList <IPointIdFloat> RegionQuery(IList <IPointIdFloat> points, IPointIdFloat p, float epsilon)
 {
     return(points.Where(x => p.DistanceTo(x) <= epsilon).ToList());
 }
Example #23
0
 public IList <IPointIdFloat> RegionQuery(IPointIdFloat p, float epsilon)
 {
     return(RegionQuery(kdt, p, epsilon));
 }
Example #24
0
 internal void expandClusterOrder(IPointIdFloat p)
 {
     throw new NotImplementedException();
 }
 public bool Delete(IPointIdFloat point)
 {
     throw new NotImplementedException();
 }
Example #26
0
 internal static IList <IPointIdFloat> NNearestNeighbours(KdTree kdt, IPointIdFloat p, int minPoints)
 {
     return(kdt.NearestNNeighbors(p, minPoints));
 }
Example #27
0
 internal static IList <IPointIdFloat> EpsilonNeighbourhood(KdTree kdt, IPointIdFloat p, float epsilon)
 {
     return(kdt.PointsWithinDistance(p, epsilon));
 }
 public bool Contains(IPointIdFloat p)
 {
     return(false);
 }
 public FixedSizePriorityQueue <float, IPointIdFloat> NearestNNeighbors(IPointIdFloat target, FixedSizePriorityQueue <float, IPointIdFloat> nns, Func <VBuffer <float>, VBuffer <float>, float> distFunc)
 {
     return(nns);
 }
 public IPointIdFloat NearestNeighbour(IPointIdFloat target, IPointIdFloat nn, ref float nnDist, Func <VBuffer <float>, VBuffer <float>, float> distFunc)
 {
     return(nn);
 }