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