public ulong knn(
            DenseColumnMajorMatrixStorage <float> query,
            DenseColumnMajorMatrixStorage <float> indices,//int
            DenseColumnMajorMatrixStorage <float> dists2,
            Vector <float> maxRadii,
            int k,
            float epsilon,
            SearchOptionFlags optionFlags)
        {
            checkSizesKnn(query, indices, dists2, k, optionFlags, maxRadii);

            bool allowSelfMatch = optionFlags.HasFlag(SearchOptionFlags.AllowSelfMatch);
            //bool sortResults = optionFlags.HasFlag(SearchOptionFlags.SortResults);
            float maxError2 = ((1 + epsilon) * (1 + epsilon));

            Debug.Assert(nodes.Count > 0);
            ulong leafTouchedCount = 0;

            var off = new float[this.dimensions];

            // TODO: Parallel.for?
            for (int i = 0; i < query.ColumnCount; ++i)
            {
                var   heap       = new ListPriorityQueue <BucketEntry>(k);
                float maxRadius  = maxRadii[i];
                float maxRadius2 = maxRadius * maxRadius;
                leafTouchedCount += onePointKnn(query, indices, dists2, i, heap, off, maxError2, maxRadius2, allowSelfMatch);
            }

            return(leafTouchedCount);
        }
예제 #2
0
        public ulong knn(
            DenseColumnMajorMatrixStorage <float> query,
            DenseColumnMajorMatrixStorage <int> indices,
            DenseColumnMajorMatrixStorage <float> dists2,
            Vector <float> maxRadii,
            int k,
            float epsilon,
            SearchOptionFlags optionFlags)
        {
            for (int i = 0; i < query.ColumnCount; i++)
            {
                onePointKnn(query, i, indices, dists2, maxRadii, k, epsilon, optionFlags);
            }

            return(0);
        }
예제 #3
0
        private ulong onePointKnn(
            DenseColumnMajorMatrixStorage <float> query,
            int i,
            DenseColumnMajorMatrixStorage <int> indices,
            DenseColumnMajorMatrixStorage <float> dists2,
            Vector <float> maxRadii,
            int k,
            float epsilon,
            SearchOptionFlags optionFlags)
        {
            var results = new ListPriorityQueue <int>(maxSize: k);

            var queryMatrix = new MathNet.Numerics.LinearAlgebra.Single.DenseMatrix(query);
            var q           = queryMatrix.Column(i);

            for (int j = 0; j < cloud.ColumnCount; j++)
            {
                var c = cloud.Column(j);

                var   diff = (c - q);
                float l2   = diff * diff;

                results.Enqueue(j, l2);
            }

            int kIdx = 0;

            foreach (var j in results.Items)
            {
                indices.At(kIdx, i, j);
                kIdx++;
            }

            kIdx = 0;
            foreach (var d2 in results.Priorities)
            {
                dists2.At(kIdx, i, d2);
            }

            return(0);
        }
 private void checkSizesKnn(
     DenseColumnMajorMatrixStorage <float> query,
     DenseColumnMajorMatrixStorage <float> indices, //int
     DenseColumnMajorMatrixStorage <float> dists2,
     int k,
     SearchOptionFlags optionFlags,
     Vector <float> maxRadii)
 {
     if (k > cloud.ColumnCount)
     {
         throw new ArgumentException(string.Format("Requesting more points (%1%) than available in cloud (%2%)", k, cloud.ColumnCount));
     }
     if (query.RowCount < this.dimensions)
     {
         throw new ArgumentException(string.Format("Query has less dimensions (%1%) than requested for cloud (%2%)", query.RowCount, this.dimensions));
     }
     if (indices.RowCount != k)
     {
         throw new ArgumentException(string.Format("Index matrix has a different number of rows (%1%) than k (%2%)", indices.RowCount, k));
     }
     if (indices.ColumnCount != query.ColumnCount)
     {
         throw new ArgumentException(string.Format("Index matrix has a different number of columns (%1%) than query (%2%)", indices.ColumnCount, query.ColumnCount));
     }
     if (dists2.RowCount != k)
     {
         throw new ArgumentException(string.Format("Distance matrix has a different number of rows (%1%) than k (%2%)", dists2.RowCount, k));
     }
     if (dists2.ColumnCount != query.ColumnCount)
     {
         throw new ArgumentException(string.Format("Distance matrix has a different number of columns (%1%) than query (%2%)", dists2.RowCount, query.ColumnCount));
     }
     if (maxRadii != null && (maxRadii.Count != query.ColumnCount))
     {
         throw new ArgumentException(string.Format("Maximum radii vector has not the same length (%1%) than query has columns (%2%)", maxRadii.Count, k));
     }
 }