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