Example #1
0
        /// <summary>
        /// Search for closest elements to the given query in increasing order of distance (L2)
        /// </summary>
        public IEnumerable <T> Find(IVector x)
        {
            // Setup the priority queue for the search
            _pq      = new PriorityQueue <PQEntry, PQEntry>();
            _closest = new Vector(x.Dimensions);

            // Search is started at root
            this.Tree.InternalBounds.Closest(x, ref _closest);
            double dist2 = VectorReductions.SquaredL2NormDistance(x, _closest);

            if (dist2 <= this.SquaredDistanceLimit)
            {
                PQEntry root_entry = PQEntry.CreateNodeEntry(dist2, this.Tree);
                _pq.Push(root_entry, root_entry);
            }

            int found = 0;

            while (found < this.CountLimit && _pq.Count > 0)
            {
                PQEntry entry = _pq.Pop();
                if (entry.NodeEntry)
                {
                    this.ProcessNodeEntry(entry, x);
                }
                else
                {
                    yield return(entry.Element);

                    found += 1;
                }
            }
        }
Example #2
0
        /// <summary>
        /// Process a node
        /// </summary>
        private void ProcessNodeEntry(PQEntry entry, IVector x)
        {
            KdNode <T> node = entry.Node;
            double     dist2;

            if (node.Leaf)
            {
                foreach (T t in node.Vectors)
                {
                    dist2 = VectorReductions.SquaredL2NormDistance(x, t);
                    if (dist2 <= this.SquaredDistanceLimit)
                    {
                        PQEntry e = PQEntry.CreateElementEntry(dist2, t);
                        _pq.Push(e, e);
                    }
                }
            }
            else
            {
                node.Left.InternalBounds.Closest(x, ref _closest);
                dist2 = VectorReductions.SquaredL2NormDistance(x, _closest);
                if (dist2 <= this.SquaredDistanceLimit)
                {
                    PQEntry left = PQEntry.CreateNodeEntry(dist2, node.Left);
                    _pq.Push(left, left);
                }

                node.Right.InternalBounds.Closest(x, ref _closest);
                dist2 = VectorReductions.SquaredL2NormDistance(x, _closest);
                if (dist2 <= this.SquaredDistanceLimit)
                {
                    PQEntry right = PQEntry.CreateNodeEntry(dist2, node.Right);
                    _pq.Push(right, right);
                }
            }
        }