/// <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; } } }
public void TestNormalize() { Vector a = Vector.Create(1.0, 2.0); Vector na = new Vector(2); double old_len = VectorOperations.Normalize(a, ref na); Assert.AreEqual((double)Math.Sqrt(5.0), old_len, FloatComparison.DefaultEps); double new_len = VectorReductions.L2Norm(na); Assert.AreEqual(1.0, new_len, FloatComparison.DefaultEps); }
public void TestBallContainsAll() { // Ball encapsulating entire region IVector diag = _tree.Root.InternalBounds.Diagonal; IVector center = _tree.Root.InternalBounds.Center; double len_half = VectorReductions.L2Norm(diag) * 0.5; Ball b = new Ball(center, len_half); BoundingVolumeSearch <Vector> s = new BoundingVolumeSearch <Vector>(_tree.Root); List <Vector> result = new List <Vector>(s.FindInsideBoundingVolume(b)); Assert.AreEqual(7, result.Count); }
/// <summary> /// Select axis of maximum spread and test for degenerate data sets. /// </summary> public int Select <T> (KdNode <T> target) where T : IVector { // Use the internal bounds to detect degenerate data sets. IVector diagonal = target.InternalBounds.Diagonal; int max_spread_id = VectorReductions.IndexNormInf(diagonal); // Sanity check for degenerate data-sets if (FloatComparison.CloseZero(diagonal[max_spread_id], FloatComparison.DefaultEps)) { throw new DegenerateDatasetException(); } return(max_spread_id); }
/// <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); } } }
public void TestIndexNormInf() { Vector a = Vector.Create(1.0, 2.0); Assert.AreEqual(1, VectorReductions.IndexNormInf(a)); }
public void TestL2Norm() { Vector a = Vector.Create(1.0, 2.0); Assert.IsTrue(FloatComparison.Close(VectorReductions.L2Norm(a), (double)Math.Sqrt(5.0), FloatComparison.DefaultEps)); }
public void TestSquaredL2Norm() { Vector a = Vector.Create(1.0, 2.0); Assert.IsTrue(FloatComparison.Close(VectorReductions.SquaredL2Norm(a), 5.0, FloatComparison.DefaultEps)); }