Exemplo n.º 1
0
        public void ClasGetHashCodeTest()
        {
            var p1 = new PointIdFloat(0, new List <float>()
            {
                1.0f
            });
            var p2 = new PointIdFloat(1, new List <float>()
            {
                2.0f, 3.0f
            });
            var p3 = new PointIdFloat(2, new List <float>()
            {
                2.0f, 3.0f, 4.0f
            });
            var p4 = new PointIdFloat(3, new List <float>()
            {
                2.0f, 3.0f, 4.0f
            });
            var p5 = new PointIdFloat(4, new List <float>()
            {
                2.0f, 3.0f, 5.0f
            });
            var p6 = new PointIdFloat(5, new List <float>()
            {
                2.0f, 3.00001f, 5.00001f
            });

            Assert.IsFalse(p1.GetHashCode() == p2.GetHashCode());
            Assert.IsTrue(p3.GetHashCode() == p4.GetHashCode());
            Assert.IsFalse(p4.GetHashCode() == p5.GetHashCode());
            Assert.IsFalse(p5.GetHashCode() == p6.GetHashCode());
        }
        public void UpdateTest()
        {
            Dictionary <long, float?> reachabilityDistances = new Dictionary <long, float?>();
            Dictionary <long, float?> coreDistancesCache    = new Dictionary <long, float?>();
            HashSet <long>            processed             = new HashSet <long>();

            var points3D = new List <IPointIdFloat>()
            {
                new PointIdFloat(new List <float>()
                {
                    1, 2, 55
                }),
                new PointIdFloat(new List <float>()
                {
                    0, 1, 0.1f
                }),
                new PointIdFloat(new List <float>()
                {
                    3, 3, 0.01f
                }),
                new PointIdFloat(new List <float>()
                {
                    1.5f, 2, -0.03f
                }),
                new PointIdFloat(new List <float>()
                {
                    5, -1, 44
                }),
                new PointIdFloat(new List <float>()
                {
                    15, -51, 73
                }),
                new PointIdFloat(new List <float>()
                {
                    0.5f, -21, 144
                })
            };

            PointIdFloat.SetIds(points3D);
            var p         = points3D[2];
            var epsilon   = 10;
            var minPoints = 3;

            Optics algo  = new Optics(points3D);
            var    seeds = new PriorityQueue <float, IPointIdFloat>();

            processed.Add(p.id);
            var coreDistance = algo.CoreDistance(algo.kdt, coreDistancesCache, p, epsilon, minPoints);

            algo.Update(ref seeds, processed, reachabilityDistances, coreDistancesCache, p, epsilon, minPoints);

            Assert.AreEqual(2, seeds.Count);
            KeyValuePair <float, IPointIdFloat> top;

            seeds.TryPeek(out top);
            Assert.AreEqual(top.Key, coreDistance);
            Assert.AreEqual(points3D[3], top.Value);
        }
Exemplo n.º 3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="epsilon"></param>
        /// <param name="minPoints"></param>
        /// <param name="shuffle"></param>
        /// <param name="seed"></param>
        /// <param name="onShuffle"></param>
        /// <param name="onPointProcessing"></param>
        /// <returns>A dictionary storing, for each point's id, the cluster it is assigned to.</returns>
        public Dictionary <long, int> Cluster(float epsilon, int minPoints, bool shuffle = false,
                                              int?seed = null, Action <string> onShuffle = null,
                                              Action <int> onPointProcessing = null)
        {
            onShuffle         = onShuffle ?? (s => { });
            onPointProcessing = onPointProcessing ?? (c => { });

            if (epsilon <= 0)
            {
                throw new ArgumentException(String.Format("Argument epsilon must be positive. Got {0}", epsilon));
            }

            if (minPoints <= 0)
            {
                throw new ArgumentException(String.Format("Argument minPoints must be positive. Got {0}", minPoints));
            }

            Dictionary <long, int> clusters  = new Dictionary <long, int>();
            HashSet <long>         processed = new HashSet <long>();
            int C = 0;

            IList <IPointIdFloat> pts;

            if (shuffle)
            {
                onShuffle("Shuffle");
                var rnd = seed.HasValue ? new Random(seed.Value) : new Random();
                pts = PointIdFloat.RandomShuffle(points, rnd);
            }
            else
            {
                pts = points.ToList();
            }

            int nbtotal = points.Count;

            foreach (var p in points)
            {
                onPointProcessing(C);

                if (!processed.Contains(p.id))
                {
                    processed.Add(p.id);
                    var neighbours = kdt.PointsWithinDistance(p, epsilon);
                    if (neighbours.Count() < minPoints)
                    {
                        clusters.Add(p.id, NOISE);
                    }
                    else
                    {
                        C += 1;
                        ExpandCluster(clusters, processed, pts, p, neighbours.ToList(), C, epsilon, minPoints);
                    }
                }
            }
            return(clusters);
        }
        public void ExpandRegionTest()
        {
            var points = new List <IPointIdFloat>()
            {
                new PointIdFloat(new List <float>()
                {
                    1.5f, 1.5f, 1.5f
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    2, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 2, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 1, 2
                }),
                new PointIdFloat(new List <float>()
                {
                    3, 3, 3
                }),
                new PointIdFloat(new List <float>()
                {
                    2, 2, 2
                })
            };

            PointIdFloat.SetIds(points);

            var   clusters = new Dictionary <long, int>();
            var   visited  = new HashSet <long>();
            var   p        = points[0];
            float epsilon  = 1f;

            var neighbours = DBScan.RegionQuery(points, p, epsilon);

            Assert.IsTrue(neighbours.Contains(p));

            DBScan.ExpandCluster(clusters, visited, points, p, neighbours.ToList(), 0, epsilon, 3);
            Assert.IsTrue(clusters.ContainsKey(p.id));
            foreach (var q in neighbours)
            {
                Assert.IsTrue(clusters.ContainsKey(q.id));
                Assert.IsTrue(clusters[q.id] == clusters[p.id]);
            }

            Assert.IsFalse(clusters.ContainsKey(points.Count() + 1));
        }
        public void ClusterTest()
        {
            var points3D = new List <IPointIdFloat>()
            {
                new PointIdFloat(new List <float>()
                {
                    1, 2, 55
                }),
                new PointIdFloat(new List <float>()
                {
                    0, 1, 0.1f
                }),
                new PointIdFloat(new List <float>()
                {
                    3, 3, 0.01f
                }),
                new PointIdFloat(new List <float>()
                {
                    1.5f, 2, -0.03f
                }),
                new PointIdFloat(new List <float>()
                {
                    5, -1, 44
                }),
                new PointIdFloat(new List <float>()
                {
                    15, -51, 73
                }),
                new PointIdFloat(new List <float>()
                {
                    0.5f, -21, 144
                })
            };

            PointIdFloat.SetIds(points3D);
            var ids = points3D.Select(p => p.id).ToList();

            ids.Sort();

            var epsilon      = 100;
            var epsilonPrime = 10;
            var minPoints    = 3;

            Optics algo  = new Optics(points3D);
            var    seeds = new PriorityQueue <float, IPointIdFloat>();

            OpticsOrdering oo      = algo.Ordering(epsilon, minPoints);
            var            results = oo.Cluster(epsilonPrime);

            Assert.AreEqual(points3D.Count, results.Count);
            var keys = results.Keys.ToList();

            keys.Sort();
            Assert.IsTrue(keys.SequenceEqual(ids));
        }
Exemplo n.º 6
0
        public void ClasdistanceToThrowTest()
        {
            var p1 = new PointIdFloat(0, new List <float>()
            {
                1.0f
            });
            var p2 = new PointIdFloat(1, new List <float>()
            {
                2.0f, 3.0f
            });

            VectorDistanceHelper.L2Norm(p1.coordinates, p2.coordinates);
        }
Exemplo n.º 7
0
        public void ClasdistanceIsSimmetricToTest()
        {
            var x = new PointIdFloat(0, new List <float>()
            {
                1.0f
            });
            var y = new PointIdFloat(1, new List <float>()
            {
                2.0f
            });

            Assert.AreEqual(VectorDistanceHelper.L2Norm(x.coordinates, y.coordinates),
                            VectorDistanceHelper.L2Norm(y.coordinates, x.coordinates));
        }
Exemplo n.º 8
0
        public void ClasAddTest()
        {
            IPointIdFloat p1  = new PointIdFloat(0, 1f, 2f);
            IPointIdFloat p2  = new PointIdFloat(1, -1f, 2f);
            IPointIdFloat p3  = new PointIdFloat(2, 1f, -2f);
            IPointIdFloat p1B = new PointIdFloat(3, 1f, 2f);
            IPointIdFloat p2B = new PointIdFloat(4, -1f, 2f);
            IPointIdFloat p2C = new PointIdFloat(5, -1f, 2f);
            IPointIdFloat p3B = new PointIdFloat(6, 1f, -2f);
            IPointIdFloat p4  = new PointIdFloat(7, 0f, 0f);

            KdTree kdt = new KdTree(new List <IPointIdFloat>()
            {
                p1
            });

            Assert.AreEqual(1, kdt.Count());

            kdt.Add(p2);
            Assert.AreEqual(2, kdt.Count());
            Assert.IsTrue(kdt.Contains(p1));
            Assert.IsTrue(kdt.Contains(p2));

            kdt.Add(p3);
            Assert.AreEqual(3, kdt.Count());
            Assert.IsTrue(kdt.Contains(p1));
            Assert.IsTrue(kdt.Contains(p2));
            Assert.IsTrue(kdt.Contains(p3));

            kdt.Add(p1B);
            Assert.AreEqual(4, kdt.Count());
            Assert.IsTrue(kdt.Contains(p1));
            Assert.IsTrue(kdt.Contains(p1B));
            Assert.IsTrue(kdt.Contains(p2));
            Assert.IsTrue(kdt.Contains(p3));

            kdt.Add(p2B);
            kdt.Add(p3B);
            kdt.Add(p2C);
            Assert.AreEqual(7, kdt.Count());
            Assert.IsTrue(kdt.Contains(p1));
            Assert.IsTrue(kdt.Contains(p1B));
            Assert.IsTrue(kdt.Contains(p2));
            Assert.IsTrue(kdt.Contains(p2B));
            Assert.IsTrue(kdt.Contains(p2C));
            Assert.IsTrue(kdt.Contains(p3));
            Assert.IsTrue(kdt.Contains(p3B));
        }
Exemplo n.º 9
0
        public void ClasToStringTest()
        {
            var p = new PointIdFloat(0, new List <float>()
            {
                1.0f
            });
            var s1 = p.ToString();

            Assert.AreEqual("PointIdFloat1D(1.000)", s1);

            p = new PointIdFloat(1, new List <float>()
            {
                -1.0f, 0.55f
            });
            s1 = p.ToString();
            Assert.AreEqual("PointIdFloat2D(-1.000,0.550)", s1);
        }
Exemplo n.º 10
0
        public void ClasEqualsTest()
        {
            var p1 = new PointIdFloat(0, new List <float>()
            {
                1.0f
            });
            var p2 = new PointIdFloat(1, new List <float>()
            {
                2.0f, 3.0f
            });
            var p3 = new PointIdFloat(2, new List <float>()
            {
                2.0f, 3.0f, 4.0f
            });
            var p4 = new PointIdFloat(3, new List <float>()
            {
                2.0f, 3.0f, 4.0f
            });
            var p5 = new PointIdFloat(4, new List <float>()
            {
                2.0f, 3.0f, 5.0f
            });
            var p6 = new PointIdFloat(5, new List <float>()
            {
                2.0f, 3.00001f, 5.00001f
            });

            Assert.IsTrue(p1.Equals(p1));
            Assert.IsTrue(p2.Equals(p2));
            Assert.IsTrue(p3.Equals(p3));
            Assert.IsTrue(p4.Equals(p4));
            Assert.IsTrue(p5.Equals(p5));

            Assert.IsFalse(p1.Equals(p2));
            Assert.IsTrue(p3.Equals(p4));
            Assert.IsTrue(p4.Equals(p3));
            Assert.IsFalse(p4.Equals(p5));
            Assert.IsFalse(p6.Equals(p5));
        }
Exemplo n.º 11
0
        public void ClasdistanceToTest()
        {
            PointIdFloat x = new PointIdFloat(0, new List <float>()
            {
                1.0f
            });
            PointIdFloat y = new PointIdFloat(1, new List <float>()
            {
                2.0f
            });

            Assert.AreEqual(0.0f, VectorDistanceHelper.L2Norm(x.coordinates, x.coordinates));
            Assert.AreEqual(1.0f, VectorDistanceHelper.L2Norm(x.coordinates, y.coordinates));

            x = new PointIdFloat(2, new List <float>()
            {
                1.0f, 2.2f
            });
            y = new PointIdFloat(3, new List <float>()
            {
                4.0f, 6.2f
            });
            Assert.AreEqual(0.0f, VectorDistanceHelper.L2Norm(y.coordinates, y.coordinates));
            Assert.IsTrue(Math.Abs(3.535534f - VectorDistanceHelper.L2Norm(x.coordinates, y.coordinates)) < 1e-5);

            x = new PointIdFloat(5, new List <float>()
            {
                1.0f, 2.5f, 3.0f
            });
            y = new PointIdFloat(6, new List <float>()
            {
                2.0f, 3.0f, 3.0f
            });
            var d1 = 0.6454972f;
            var d2 = VectorDistanceHelper.L2Norm(x.coordinates, y.coordinates);

            Assert.IsTrue(Math.Abs(d1 - d2) < 1e-5);
        }
        public void StartTest()
        {
            var points = new List <IPointIdFloat>()
            {
                new PointIdFloat(new List <float>()
                {
                    1, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    2, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 2, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 1, 2
                }),
                new PointIdFloat(new List <float>()
                {
                    3, 3, 3
                }),
                new PointIdFloat(new List <float>()
                {
                    2, 2, 2
                })
            };

            PointIdFloat.SetIds(points);

            var dbscan = new DBScan(points);
            var result = dbscan.Cluster(0.5f, 2);

            Assert.IsTrue(result.Count == points.Count);
            Assert.IsTrue(result.Values.Max() <= points.Count);
        }
Exemplo n.º 13
0
        public void ClasPointContructorEnumerableTest()
        {
            IPointIdFloat p = new PointIdFloat(0, new List <float>()
            {
                1.0f
            });

            Assert.AreEqual(1, p.dimension);
            Assert.IsTrue(p.coordinates.Values.SequenceEqual(new List <float>()
            {
                1.0f
            }));

            p = new PointIdFloat(0, new List <float>()
            {
                1.0f, -0.000031f, (float)Math.PI, (float)-Math.E
            });
            Assert.AreEqual(4, p.dimension);
            Assert.IsTrue(p.coordinates.Values.SequenceEqual(new List <float>()
            {
                1.0f, -0.000031f, (float)Math.PI, (float)-Math.E
            }));
        }
Exemplo n.º 14
0
        public void ClasRandomShuffleTest()
        {
            IList <IPointIdFloat> points = new List <IPointIdFloat>()
            {
                new PointIdFloat(0, new List <float>()
                {
                    1, 1, 1
                }),
                new PointIdFloat(1, new List <float>()
                {
                    2, 1, 1
                }),
                new PointIdFloat(2, new List <float>()
                {
                    1, 2, 1
                }),
                new PointIdFloat(3, new List <float>()
                {
                    1, 1, 2
                }),
                new PointIdFloat(4, new List <float>()
                {
                    3, 3, 3
                }),
                new PointIdFloat(5, new List <float>()
                {
                    2, 2, 2
                })
            };
            IList <IPointIdFloat> pointsCopy = new List <IPointIdFloat>(points);

            IList <IPointIdFloat> shuffledPoints = PointIdFloat.RandomShuffle(points.ToList().AsReadOnly(), new Random());

            Assert.IsTrue(SequenceEquivalent(shuffledPoints.ToList(), points.ToList(), PointIdFloat.PointsComparison), "shuffled list should have the same elements and multiplicity");
            Assert.IsFalse(points.SequenceEqual(shuffledPoints), "shuffled list should have a different order");
            Assert.IsTrue(points.SequenceEqual(pointsCopy), "Original list must not be changed");
        }
Exemplo n.º 15
0
        public void ClasMedianTest()
        {
            IPointIdFloat p0 = new PointIdFloat(0, 0f);
            IPointIdFloat p1 = new PointIdFloat(1, 1f);
            IPointIdFloat p2 = new PointIdFloat(2, 2f);
            IPointIdFloat p3 = new PointIdFloat(3, 3f);
            IPointIdFloat p4 = new PointIdFloat(4, 4f);

            IPointIdFloat p2D0 = new PointIdFloat(5, 0f, 2f);
            IPointIdFloat p2D1 = new PointIdFloat(6, 1f, 3f);
            IPointIdFloat p2D2 = new PointIdFloat(7, 2f, 4f);
            IPointIdFloat p2D3 = new PointIdFloat(8, 3f, 1f);
            IPointIdFloat p2D4 = new PointIdFloat(0, 4f, 0f);

            testMedian(new List <IPointIdFloat>()
            {
                p1
            }, p1, new List <IPointIdFloat>(), new List <IPointIdFloat>());
            testMedian(new List <IPointIdFloat>()
            {
                p2, p1
            }, p1, new List <IPointIdFloat>(), new List <IPointIdFloat>()
            {
                p2
            });
            testMedian(new List <IPointIdFloat>()
            {
                p1, p2
            }, p1, new List <IPointIdFloat>(), new List <IPointIdFloat>()
            {
                p2
            });
            testMedian(new List <IPointIdFloat>()
            {
                p1, p2, p0
            }, p1, new List <IPointIdFloat>()
            {
                p0
            }, new List <IPointIdFloat>()
            {
                p2
            });
            testMedian(new List <IPointIdFloat>()
            {
                p2, p1, p0, p1, p1
            }, p1, new List <IPointIdFloat>()
            {
                p0, p1, p1
            }, new List <IPointIdFloat>()
            {
                p2
            });
            testMedian(new List <IPointIdFloat>()
            {
                p2D2, p2D1, p2D0, p2D3, p2D4
            }, p2D2, new List <IPointIdFloat>()
            {
                p2D1, p2D0
            }, new List <IPointIdFloat>()
            {
                p2D3, p2D4
            });
            testMedian(new List <IPointIdFloat>()
            {
                p2D2, p2D1, p2D0, p2D3, p2D4
            }, p2D0, new List <IPointIdFloat>()
            {
                p2D3, p2D4
            }, new List <IPointIdFloat>()
            {
                p2D1, p2D2
            }, 1);
        }
Exemplo n.º 16
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="epsilon"></param>
        /// <param name="minPoints"></param>
        /// <param name="shuffle"></param>
        /// <param name="seed"></param>
        /// <param name="onShuffle"></param>
        /// <param name="onPointProcessing"></param>
        /// <returns>A total ordering of the points according to their density distribution.</returns>
        public OpticsOrdering Ordering(float epsilon, int minPoints, bool shuffle = false,
                                       int?seed = null, Action <string> onShuffle = null, Action onPointProcessing = null)
        {
            onShuffle         = onShuffle ?? (s => { });
            onPointProcessing = onPointProcessing ?? (() => { });

            if (epsilon <= 0)
            {
                throw new ArgumentException(String.Format("Argument epsilon must be positive. Got {0}", epsilon));
            }
            if (minPoints <= 0)
            {
                throw new ArgumentException(String.Format("Argument minPoints must be positive. Got {0}", minPoints));
            }

            var ordering              = new List <IPointIdFloat>();
            var orderingMapping       = new Dictionary <long, long>();
            var reachabilityDistances = new Dictionary <long, float?>();
            var coreDistancesCache    = new Dictionary <long, float?>();

            HashSet <long> processed    = new HashSet <long>();
            int            currentIndex = 0;

            Action <IPointIdFloat> ProcessPoint = p => MarkProcessed(p, orderingMapping, ordering, processed, ref currentIndex);

            IList <IPointIdFloat> pts;

            if (shuffle)
            {
                onShuffle("Shuffle");

                var rnd = seed.HasValue ? new Random(seed.Value) : new Random();
                pts = PointIdFloat.RandomShuffle(points, rnd);
            }
            else
            {
                pts = points.ToList();
            }

            foreach (var p in points)
            {
                onPointProcessing();

                long pId = p.id;
                if (!processed.Contains(pId))
                {
                    ProcessPoint(p);

                    double?coreDistance = CoreDistance(kdt, coreDistancesCache, p, epsilon, minPoints);

                    if (coreDistance != null)
                    {
                        var seeds = new PriorityQueue <float, IPointIdFloat>();
                        Update(ref seeds, processed, reachabilityDistances, coreDistancesCache, p, epsilon, minPoints);

                        while (!seeds.IsEmpty)
                        {
                            KeyValuePair <float, IPointIdFloat> kvp;
                            seeds.TryDequeue(out kvp);
                            var q = kvp.Value;
                            ProcessPoint(q);
                            coreDistance = CoreDistance(kdt, coreDistancesCache, q, epsilon, minPoints);
                            if (coreDistance != null)
                            {
                                Update(ref seeds, processed, reachabilityDistances,
                                       coreDistancesCache, q, epsilon, minPoints);
                            }
                        }
                    }
                }
            }
            return(new OpticsOrdering(kdt, ordering, orderingMapping,
                                      reachabilityDistances, coreDistancesCache, epsilon, minPoints));
        }
        public void RegionQueryPointsListTest()
        {
            var points = new List <IPointIdFloat>()
            {
                new PointIdFloat(new List <float>()
                {
                    1, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    2, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 2, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 1, 2
                }),
                new PointIdFloat(new List <float>()
                {
                    3, 3, 3
                }),
                new PointIdFloat(new List <float>()
                {
                    2, 2, 2
                })
            };

            PointIdFloat.SetIds(points);
            var p = new PointIdFloat(new List <float>()
            {
                1.5f, 1.5f, 1.5f
            });
            Func <IPointIdFloat, Tuple <float, float, float> > keySelector = t => Tuple.Create(
                KdTree.KdTreeNode.KeyByDepth(t, 0), 0.0f, 0.0f);

            var result = DBScan.RegionQuery(points, p, 0.16f);

            Assert.IsTrue(result.Count() == 0);

            result = DBScan.RegionQuery(points, p, 1);
            var expectedResult = new List <IPointIdFloat>()
            {
                new PointIdFloat(new List <float>()
                {
                    1, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    2, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 2, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 1, 2
                }),
                new PointIdFloat(new List <float>()
                {
                    2, 2, 2
                })
            };

            PointIdFloat.SetIds(expectedResult);

            Assert.IsTrue(SequenceEquivalent(result.ToList(), expectedResult, PointIdFloat.PointsComparison));

            p = new PointIdFloat(new List <float>()
            {
                0.75f, 0.75f, 0.75f
            });
            result         = DBScan.RegionQuery(points, p, (float)Math.Sqrt(2f / 3f));
            expectedResult = new List <IPointIdFloat>()
            {
                new PointIdFloat(new List <float>()
                {
                    1, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    2, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 2, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 1, 2
                }),
            };
            PointIdFloat.SetIds(expectedResult);

            Assert.IsTrue(SequenceEquivalent(result.ToList(), expectedResult, PointIdFloat.PointsComparison));
        }
        public void CoreDistanceTest()
        {
            var points3D = new List <IPointIdFloat>()
            {
                new PointIdFloat(new List <float>()
                {
                    1, 2, 55
                }),
                new PointIdFloat(new List <float>()
                {
                    0, 1, 0.1f
                }),
                new PointIdFloat(new List <float>()
                {
                    3, 3, 0.01f
                }),
                new PointIdFloat(new List <float>()
                {
                    1.5f, 2, -0.03f
                }),
                new PointIdFloat(new List <float>()
                {
                    5, -1, 44
                }),
                new PointIdFloat(new List <float>()
                {
                    15, -51, 73
                }),
                new PointIdFloat(new List <float>()
                {
                    0.5f, -21, 144
                })
            };

            PointIdFloat.SetIds(points3D);

            var p = new PointIdFloat(new List <float>()
            {
                1, 2, 3
            });

            Optics algo = new Optics(points3D);
            Dictionary <long, float?> coreDist = new Dictionary <long, float?>();

            // - Tests with no cache -

            //Not enough points in the tree
            Assert.IsNull(algo.CoreDistance(algo.kdt, new Dictionary <long, float?>(), p, 1000, 40));
            Assert.IsNull(algo.CoreDistance(algo.kdt, new Dictionary <long, float?>(), p, 1000, points3D.Count + 1));

            //Not enough points in the epsilon-neighbourhood
            Assert.IsNull(algo.CoreDistance(algo.kdt, new Dictionary <long, float?>(), p, 1, 2));
            Assert.IsNull(algo.CoreDistance(algo.kdt, new Dictionary <long, float?>(), p, 10, 6));

            var result = algo.CoreDistance(algo.kdt, new Dictionary <long, float?>(), p, 1000, points3D.Count);

            Assert.AreEqual(p.DistanceTo(points3D[6]), result);

            points3D.ForEach(point =>
            {
                result = algo.CoreDistance(algo.kdt, new Dictionary <long, float?>(), point, 0.00001f, 1);
                Assert.AreEqual(0, result);
            });

            Assert.IsNull(algo.CoreDistance(algo.kdt, new Dictionary <long, float?>(), p, 1, 1));
            Assert.AreEqual(p.DistanceTo(points3D[3]), algo.CoreDistance(algo.kdt, new Dictionary <long, float?>(), p, 5, 1));

            //Tests - using cache -
            Assert.AreEqual(0, coreDist.Count);
            float?tmp;

            Assert.IsNull(algo.CoreDistance(algo.kdt, coreDist, p, 1000, 40));
            Assert.IsTrue(coreDist.ContainsKey(p.id));
            coreDist.TryGetValue(p.id, out tmp);
            Assert.IsNull(tmp);

            coreDist.Clear();

            result = algo.CoreDistance(algo.kdt, coreDist, p, 1000, points3D.Count);
            Assert.AreEqual(p.DistanceTo(points3D[6]), result);

            Assert.IsTrue(coreDist.ContainsKey(p.id));
            coreDist.TryGetValue(p.id, out tmp);
            Assert.AreEqual(result, tmp);
        }
Exemplo n.º 19
0
        public void ClasPointsWithinDistanceTest()
        {
            IPointIdFloat p1 = new PointIdFloat(0, 1f, 2f);
            IPointIdFloat p2 = new PointIdFloat(1, 2f, 1f);
            IPointIdFloat p3 = new PointIdFloat(2, 200f, -100f);
            IPointIdFloat p4 = new PointIdFloat(3, 150f, -50f);

            List <IPointIdFloat> points2D = new List <IPointIdFloat>()
            {
                new PointIdFloat(0, 1f, 2f),
                new PointIdFloat(4, 0f, 1f), new PointIdFloat(3, 3f, 3f),
                new PointIdFloat(5, 1.5f, 2f), new PointIdFloat(6, 5f, -1f)
            };
            List <IPointIdFloat> points3D = new List <IPointIdFloat>()
            {
                new PointIdFloat(0, 0f, 0f, 0f),
                new PointIdFloat(1, -1f, 2f, 3.5f), new PointIdFloat(3, 0.55f, 30f, -10f),
                new PointIdFloat(2, 1f, 1.2f, 1.5f), new PointIdFloat(4, 4.25f, 0.37f, 0f)
            };

            Func <IPointIdFloat, float> keySelector = t => KdTree.KdTreeNode.KeyByDepth(t, 0);

            //should return an empty Set if all the points are not within distance
            var kdt = new KdTree(null, p1);

            Func <IPointIdFloat, float, List <IPointIdFloat>, bool> AssertResult = (target, maxDistance, expectedResults) =>
            {
                var results = kdt.PointsWithinDistance(target, maxDistance);
                if (!SequenceEquivalent(expectedResults, results, keySelector))
                {
                    var distance = results.Select(c => VectorDistanceHelper.L2(c.coordinates, target.coordinates)).ToArray();
                    results = kdt.PointsWithinDistance(target, maxDistance);
                    Assert.IsTrue(SequenceEquivalent(expectedResults, results, keySelector));
                }
                results.ToList().ForEach(p =>
                {
                    //Console.WriteLine(string.Format("{0}, {1}", p.ToString(),
                    //                    VectorDistanceHelper.L2(p.coordinates, target.coordinates)));
                    Assert.IsTrue(VectorDistanceHelper.L2(p.coordinates, target.coordinates) <= maxDistance);
                });
                return(true);
            };

            var result = kdt.PointsWithinDistance(p3, 100);

            Assert.AreEqual(0, result.Count());

            kdt    = new KdTree(null, p1, p2);
            result = kdt.PointsWithinDistance(p3, 100);
            Assert.AreEqual(0, result.Count());

            kdt = new KdTree(null, p1);
            AssertResult(p2, 10, new List <IPointIdFloat>()
            {
                p1
            });

            AssertResult(p1, 1, new List <IPointIdFloat>()
            {
                p1
            });

            //should include the points itself, if in the tree
            kdt = new KdTree(null, p1, p2);

            AssertResult(p2, 2, new List <IPointIdFloat>()
            {
                p1, p2
            });

            AssertResult(p2, 0, new List <IPointIdFloat>()
            {
                p2
            });

            IPointIdFloat p3D = points3D.First();

            kdt = new KdTree(null, p3D);

            AssertResult(p3D, 2, new List <IPointIdFloat>()
            {
                p3D
            });

            //should return all the points within distance
            kdt = new KdTree(points3D);

            AssertResult(new PointIdFloat(0, 0.5f, 0.6f, 0.7f), 2f, new List <IPointIdFloat>()
            {
                points3D[0], points3D[3]
            });
            AssertResult(new PointIdFloat(1, -5f, -5f, -5f), 1f, new List <IPointIdFloat>()
            {
            });
            AssertResult(new PointIdFloat(2, -5f, -5.5f, -6f), 12.5f, new List <IPointIdFloat>()
            {
                points3D[0], points3D[3], points3D[4]
            });
            AssertResult(new PointIdFloat(3, -0.95f, 2.05f, 3.45f), 0.1f, new List <IPointIdFloat>()
            {
                points3D[1]
            });
            AssertResult(new PointIdFloat(4, -0.9f, 2.05f, 3.45f), 4f, new List <IPointIdFloat>()
            {
                points3D[1], points3D[3]
            });
            kdt = new KdTree(points2D);
            AssertResult(new PointIdFloat(5, 1.1f, 1.9f), 1, new List <IPointIdFloat>()
            {
                points2D[0], points2D[3]
            });
            AssertResult(new PointIdFloat(6, 1.1f, 1.9f), 10, points2D);
            AssertResult(new PointIdFloat(7, -5f, 5f), 1, new List <IPointIdFloat>()
            {
            });
            AssertResult(new PointIdFloat(8, -5f, 5f), 8, new List <IPointIdFloat>()
            {
                points2D[0], points2D[1], points2D[3]
            });
            AssertResult(new PointIdFloat(9, -5f, 5f), 10, new List <IPointIdFloat>()
            {
                points2D[0], points2D[1], points2D[2], points2D[3]
            });
            AssertResult(new PointIdFloat(10, 3.01f, 2.9999f), 0.1f, new List <IPointIdFloat>()
            {
                points2D[2]
            });
            AssertResult(new PointIdFloat(11, 3.01f, 2.9999f), 2, new List <IPointIdFloat>()
            {
                points2D[2], points2D[3]
            });
            AssertResult(new PointIdFloat(12, 1.6f, 2f), 10, points2D);
            AssertResult(new PointIdFloat(13, 160f, 2f), 160, new List <IPointIdFloat>()
            {
                points2D[0], points2D[2], points2D[3], points2D[4]
            });
        }
        public void OrderingTest()
        {
            IReadOnlyDictionary <long, long>    orderingMapping;
            IReadOnlyCollection <IPointIdFloat> ordering;

            var points3D = new List <IPointIdFloat>()
            {
                new PointIdFloat(new List <float>()
                {
                    1, 2, 55
                }),
                new PointIdFloat(new List <float>()
                {
                    0, 1, 0.1f
                }),
                new PointIdFloat(new List <float>()
                {
                    3, 3, 0.01f
                }),
                new PointIdFloat(new List <float>()
                {
                    1.5f, 2, -0.03f
                }),
                new PointIdFloat(new List <float>()
                {
                    5, -1, 44
                }),
                new PointIdFloat(new List <float>()
                {
                    15, -51, 73
                }),
                new PointIdFloat(new List <float>()
                {
                    0.5f, -21, 144
                })
            };

            PointIdFloat.SetIds(points3D);
            var epsilon   = 10;
            var minPoints = 3;

            Optics algo  = new Optics(points3D);
            var    seeds = new PriorityQueue <float, IPointIdFloat>();

            OpticsOrdering oo = algo.Ordering(epsilon, minPoints);

            ordering        = oo.ordering;
            orderingMapping = oo.orderingMapping;

            Assert.AreEqual(points3D.Count, ordering.Count);
            Assert.IsTrue(SequenceEquivalent(points3D, ordering.ToList(), PointIdFloat.PointsComparison));
            Assert.AreEqual(points3D.Count, orderingMapping.Count);

            for (long i = 0; i < orderingMapping.Count; i++)
            {
                Assert.IsTrue(orderingMapping.Values.Contains(i));
            }
            foreach (var p in points3D)
            {
                Assert.IsTrue(orderingMapping.ContainsKey(p.id));
            }
            Assert.IsTrue(oo.reachabilityDistances.Count > 0);
            foreach (var p in points3D)
            {
                Assert.IsTrue(oo.coreDistancesCache.ContainsKey(p.id));
            }
        }
        public void RegionQueryKdTreeTest()
        {
            var points = new List <IPointIdFloat>()
            {
                new PointIdFloat(new List <float>()
                {
                    1, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    2, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 2, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 1, 2
                }),
                new PointIdFloat(new List <float>()
                {
                    3, 3, 3
                }),
                new PointIdFloat(new List <float>()
                {
                    2, 2, 2
                })
            };

            PointIdFloat.SetIds(points);

            var p = new PointIdFloat(new List <float>()
            {
                1.5f, 1.5f, 1.5f
            });
            KdTree kdt = new KdTree(points);

            var result = kdt.PointsWithinDistance(p, 0.5f);

            Assert.IsTrue(result.Count == 0);

            result = DBScan.RegionQuery(kdt, p, 1);
            var expectedResult = new List <IPointIdFloat>()
            {
                new PointIdFloat(new List <float>()
                {
                    1, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    2, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 2, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 1, 2
                }),
                new PointIdFloat(new List <float>()
                {
                    2, 2, 2
                })
            };

            PointIdFloat.SetIds(expectedResult);

            Assert.IsTrue(SequenceEquivalent(result.ToList(), expectedResult, PointIdFloat.PointsComparison));

            p = new PointIdFloat(new List <float>()
            {
                0.75f, 0.75f, 0.75f
            });
            result         = kdt.PointsWithinDistance(p, (float)Math.Sqrt(2));
            expectedResult = new List <IPointIdFloat>()
            {
                new PointIdFloat(new List <float>()
                {
                    1, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    2, 1, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 2, 1
                }),
                new PointIdFloat(new List <float>()
                {
                    1, 1, 2
                }),
            };
            PointIdFloat.SetIds(expectedResult);

            Assert.IsTrue(SequenceEquivalent(result.ToList(), expectedResult, PointIdFloat.PointsComparison));
        }