WIP: v1 recursive
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
function [N, D] = mergeReducedResultsWithMink(N_sub, D_sub, C_sub, k, ~)
|
||||
% Merge reduced results for one subset of queries using mink
|
||||
numQueries = size(N_sub, 1); % Number of queries
|
||||
|
||||
% Find the k smallest distances and their indices using mink
|
||||
[D, idx] = mink(D_sub, k, 2);
|
||||
|
||||
% Select the corresponding neighbors based on the indices
|
||||
N = N_sub(sub2ind(size(N_sub), ...
|
||||
repmat((1:numQueries)', 1, k), idx));
|
||||
end
|
||||
@@ -0,0 +1,19 @@
|
||||
function [N, D] = mergeResults(N1, D1, N2, D2, C1, C2, k, ~)
|
||||
% Merge neighbors from two sources for a specific subset of queries
|
||||
numQueries = size(N1, 1); % Queries corresponding to N1 (or N2)
|
||||
N_combined = [N1, N2 + size(C1, 1)]; % Adjust indices for C2
|
||||
D_combined = [D1, D2];
|
||||
|
||||
% Sort distances and select top-k for each query
|
||||
[D_sorted, idx] = sort(D_combined, 2); % Sort by distance for each query
|
||||
idx = idx(:, 1:k); % Top-k indices
|
||||
|
||||
% Select corresponding neighbors
|
||||
N = zeros(numQueries, k);
|
||||
for i = 1:numQueries
|
||||
N(i, :) = N_combined(i, idx(i, :));
|
||||
end
|
||||
|
||||
% Select corresponding distances
|
||||
D = D_sorted(:, 1:k);
|
||||
end
|
||||
@@ -0,0 +1,46 @@
|
||||
function [N, D] = mergeResultsWithM(N1, D1, N2, D2, C1, C2, k, m)
|
||||
% Merge neighbors from two sources with a limit on candidate neighbors (m)
|
||||
|
||||
numQueries = size(N1, 1); % Number of queries in this subset
|
||||
maxCandidates = min(m, size(N1, 2) + size(N2, 2)); % Maximum candidates to consider
|
||||
|
||||
% Combine distances and neighbors
|
||||
N_combined = [N1, N2 + size(C1, 1)]; % Adjust indices for C2
|
||||
D_combined = [D1, D2];
|
||||
|
||||
% Sort distances and keep only top-m candidates for each query
|
||||
[D_sorted, idx] = sort(D_combined, 2, 'ascend');
|
||||
D_sorted = D_sorted(:, 1:maxCandidates); % Keep only top-m distances
|
||||
idx = idx(:, 1:maxCandidates); % Keep indices corresponding to top-m distances
|
||||
|
||||
% Select the corresponding neighbors
|
||||
%N_sorted = N_combined(sub2ind(size(N_combined), ...
|
||||
% repmat((1:numQueries)', 1, maxCandidates), idx));
|
||||
N_sorted = zeros(numQueries, maxCandidates); % Initialize output
|
||||
for i = 1:numQueries
|
||||
for j = 1:maxCandidates
|
||||
N_sorted(i, j) = N_combined(i, idx(i, j));
|
||||
end
|
||||
end
|
||||
|
||||
% Handle cases where m < k
|
||||
if maxCandidates < k
|
||||
% Pad with Inf distances and invalid indices
|
||||
D_sorted = [D_sorted, Inf(numQueries, k - maxCandidates)];
|
||||
N_sorted = [N_sorted, zeros(numQueries, k - maxCandidates)];
|
||||
end
|
||||
|
||||
% Extract top-k from the reduced set of candidates
|
||||
[D, idx_final] = sort(D_sorted, 2, 'ascend');
|
||||
D = D(:, 1:k); % Final top-k distances
|
||||
%N = N_sorted(sub2ind(size(N_sorted), ...
|
||||
% repmat((1:numQueries)', 1, k), idx_final(:, 1:k)));
|
||||
% Extract top-k neighbors using a loop
|
||||
N = zeros(numQueries, k); % Initialize output
|
||||
for i = 1:numQueries
|
||||
for j = 1:k
|
||||
N(i, j) = N_sorted(i, idx_final(i, j));
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
function [neighbors, distances] = recursiveKNN(C, Q, k, m)
|
||||
% Recursive break, call knnsearch
|
||||
if size(C, 1) <= 1000 || size(Q, 1) <= 500 % Adjastable limit
|
||||
[neighbors, distances] = knnsearch(C, Q, 'K', k);
|
||||
return;
|
||||
end
|
||||
|
||||
% Divide into subsets
|
||||
midC = floor(size(C, 1) / 2);
|
||||
midQ = floor(size(Q, 1) / 2);
|
||||
C1 = C(1:midC, :);
|
||||
C2 = C(midC+1:end, :);
|
||||
Q1 = Q(1:midQ, :);
|
||||
Q2 = Q(midQ+1:end, :);
|
||||
|
||||
% Recursive calls
|
||||
[N1_1, D1_1] = recursiveKNN(C1, Q1, k, m);
|
||||
[N1_2, D1_2] = recursiveKNN(C2, Q1, k, m);
|
||||
[N2_1, D2_1] = recursiveKNN(C1, Q2, k, m);
|
||||
[N2_2, D2_2] = recursiveKNN(C2, Q2, k, m);
|
||||
|
||||
% Merge
|
||||
[N1, D1] = mergeResultsWithM(N1_1, D1_1, N1_2, D1_2, C1, C2, k, m);
|
||||
[N2, D2] = mergeResultsWithM(N2_1, D2_1, N2_2, D2_2, C1, C2, k, m);
|
||||
|
||||
% Combine results for Q1 and Q2
|
||||
neighbors = [N1; N2];
|
||||
distances = [D1; D2];
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
%
|
||||
%
|
||||
%
|
||||
|
||||
%C = rand(10000, 2); % Corpus
|
||||
%Q = rand(10000, 2); % Queries
|
||||
C = rand(20000, 2); % Δύο clusters
|
||||
Q = C;
|
||||
%Q = rand(10000, 2); % Queries κοντά στο μέσο
|
||||
k = 100; % Number of neighbors
|
||||
m = 100; % Max candidates per query
|
||||
global count;
|
||||
|
||||
count =0;
|
||||
tic; [pi, pd] = recursiveKNN(C, Q, k, m); toc
|
||||
count
|
||||
tic; [si, sd] = knnsearch(C, Q, 'k', k); toc
|
||||
|
||||
[a,b] = size(si);
|
||||
all_neighbors = a*b
|
||||
accuracy = 1 - nnz(si-pi)/all_neighbors
|
||||
false_neighbors = nnz(sd-pd)
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
%
|
||||
%
|
||||
%
|
||||
|
||||
C = rand(40000,4);
|
||||
Q = rand(4000,4);
|
||||
|
||||
disp ('C-Q');
|
||||
disp ('build-in')
|
||||
tic; [i1, d1] = knnsearch(C, Q, 'k', 4); toc
|
||||
disp ('mine')
|
||||
tic; [i2, d2] = knnsearch2(C, Q, 4); toc
|
||||
sum(i1-i2)
|
||||
sum(d1-d2)
|
||||
|
||||
disp (' ');
|
||||
disp (' ');
|
||||
disp ('C-C');
|
||||
disp ('build-in')
|
||||
tic; [i1, d1] = knnsearch(C, C, 'k', 4); toc
|
||||
disp ('mine')
|
||||
tic; [i2, d2] = knnsearch2(C, C, 4); toc
|
||||
sum(i1-i2)
|
||||
sum(d1-d2)
|
||||
Reference in New Issue
Block a user