test_pointkdtree.m

Back to PointKdTree (Matlab)

matlab/+pastelgeometry/

% Description: A test for PointKdTree Matlab interface
% DocumentationOf: PointKdTree.m

function test_pointkdtree()

clear all;
close all;

eval(import_pastel);

d = 2;
n = 200;
kNearest = 8;

% Generate a point-set.
pointSet = randn(d, n);

% Construct a kd-tree.
kdTree = PointKdTree(d);

% Insert the points into the kd-tree.
idSet = kdTree.insert(pointSet);

% Compute the correct nearest neighbors by brute-force.
correctSet = int32(zeros(n, kNearest));
for i = 1 : n
    distanceSet = zeros(1, n);
    for j = 1 : n
        distanceSet(j) = sum((pointSet(:, i) - pointSet(:, j)).^2);
    end
    distanceSet(i) = Inf;
    [Y, I] = sort(distanceSet);
    correctSet(i, :) = idSet(I(1 : kNearest));
end

% Refine the subdivision of the kd-tree.
kdTree.refine();

% Print out some statistics.
disp(['Points = ', int2str(kdTree.points())]);
disp(['Leaf nodes = ', int2str(kdTree.leaves())]);
disp(['Nodes = ', int2str(kdTree.nodes())]);

% Make a copy of the tree.
copyTree = kdTree.copy();

% Destruct the copy.
clear copyTree;

% Use all of the points as query points.
querySet = idSet;

% Search for k nearest neighbors.
neighborSet = kdTree.search_nearest(querySet, ...
    'kNearest', kNearest);

if ~isequal(correctSet, neighborSet)
    error('Kd-tree did not find the same points as brute-force.');
end

nearestSet = kdTree.as_points(neighborSet(:, 1));

% Draw a picture.
figure;
axis equal;
scatter(pointSet(1, :), pointSet(2, :), 'bx');
hold on;
for i = 1 : numel(querySet)
    line([pointSet(1, i), nearestSet(1, i)], ...
        [pointSet(2, i), nearestSet(2, i)]);
end
hold off

% Search using queries in component form.
querySet = randn(d, 100);
neighborSet = kdTree.search_nearest(querySet, ...
    'kNearest', kNearest);
nearestSet = kdTree.as_points(neighborSet(:, 1));

% Draw a picture.
figure;
axis equal;
scatter(pointSet(1, :), pointSet(2, :), 'bx');
hold on;
scatter(querySet(1, :), querySet(2, :), 'r+');
for i = 1 : size(querySet, 2)
    line([querySet(1, i), nearestSet(1, i)], ...
        [querySet(2, i), nearestSet(2, i)]);
end
hold off

% Hide some of the points.
kdTree.hide(idSet(101 : 200));

% Test range counting.
for i = 1 : 100
    [nearest, distance] = kdTree.search_nearest(idSet(i), ...
        'kNearest', 10);
    count = kdTree.count_nearest(idSet(i), max(distance));
    if count < 10
        error('Range counting finds less points than nn-searching.')
    end
end

% Test range counting some more.
kdTree.count_nearest(idSet(1 : 10), 0^2);
kdTree.count_nearest(idSet(1 : 10), 0.1^2);
kdTree.count_nearest(idSet(1 : 10), 1^2);
kdTree.count_nearest(idSet(1 : 10), 2^2, 'norm', 'euclidean');
kdTree.count_nearest(idSet(1 : 10), 2, 'norm', 'maximum');
kdTree.count_nearest(idSet(1 : 10), 10^2);
kdTree.count_nearest(idSet(1 : 10), Inf);

disp(['Points after hiding 100 of them = ', ...
    int2str(kdTree.points())]);

% Bring back the hided points.
kdTree.show(idSet(101 : 200));

disp(['Points after showing the 100 hided points = ', ...
    int2str(kdTree.points())]);

% Remove some of the points completely.
kdTree.erase(idSet(1 : 100));

disp(['Points after erasing 100 of them = ', ...
    int2str(kdTree.points())]);

% Hide all points.
kdTree.hide();

% Show all points.
kdTree.show();

% Flatten the kd-tree.
kdTree.merge();

% Remove all points, but not the subdivision.
kdTree.erase();

% Remove everything.
kdTree.clear();

% Destruct the kd-tree.
clear kdTree;