Math::...kdTree(3pm)
π¦ NAME π¦
Math::Vector::Real::kdTree β bestie, it's a kd-Tree implementation built right on top of Math::Vector::Real. That's the whole vibe. π
(And yes, you're reading the Math::...kdTree(3pm) page from the User Contributed Perl Documentation. Iconic.)
β¨ SYNOPSIS β¨
use Math::Vector::Real::kdTree;
use Math::Vector::Real;
use Math::Vector::Real::Random;
my @v = map Math::Vector::Real->random_normal(4), 1..1000;
my $tree = Math::Vector::Real::kdTree->new(@v);
my $ix = $tree->find_nearest_vector(V(0, 0, 0, 0));
say "nearest vector is $ix, $v[$ix]";
πΈ DESCRIPTION πΈ
This module implements a kd-Tree data structure in Perl and common algorithms on top of it. Like, the whole tree, in Perl. Obsessed. β¨
π Methods π
The following methods are provided:
$t = Math::Vector::Real::kdTree->new(@points)β creates a brand new kd-Tree holding all the points you hand it. π«Ά$t2 = $t->cloneβ makes a duplicate of the tree. The two trees share internal read only data, so this is way more efficient memory-wise than other methods that do a deep copy. Lowkey a steal.my $ix = $t->insert($p0, $p1, ...)β inserts the given points into the kd-Tree.
Returns the index assigned to the first point inserted.
$s = $t->sizeβ returns the number of points inside the tree.$p = $t->at($ix)β returns the point at the given index inside the tree.$t->move($ix, $p)β moves the point at index$ixto the new given position, readjusting the tree structure accordingly. π($ix, $d) = $t->find_nearest_vector($p, $max_d, @but_ix)or($ix, $d) = $t->find_nearest_vector($p, $max_d, \%but_ix)β finds the nearest vector for the given point$pand returns its index plus the distance between the two points. In scalar context, you just get the index back. π
If $max_d is defined, the search is limited to the points within that distance.
Optionally, a list of point indexes to be excluded from the search can be passed, or alternatively a reference to a hash containing the indexes of the points to be excluded.
@ix = $t->find_nearest_vector_all_internalβ returns the index of the nearest vector from the tree.
It is equivalent to the following code (though, it uses a better algorithm):
@ix = map {
scalar $t->nearest_vector($t->at($_), undef, $_)
} 0..($t->size - 1);
$ix = $t->find_nearest_vector_in_box($p, $a, $b, $max_d, @but_ix)or$ix = $t->find_nearest_vector_in_box($p, $a, $b, $max_d, \%but_ix)β returns the nearest vector for the given point, but only from those that are also inside the box defined by$aand$b.
The other arguments have the same meaning as for the method find_nearest_vector.
$ix = $t->find_nearest_vector_in_box_chebyshev($p, $a, $b, $max_d, @but_ix)or$ix = $t->find_nearest_vector_in_box_chebyshev($p, $a, $b, $max_d, \%but_ix)β same energy asfind_nearest_vector_in_box, except it's using the Chebyshev metric. π$ix = $t->find_farthest_vector($p, $min_d, @but_ix)β finds the point from the tree farthest from the given$p.
The optional argument $min_d specifies a minimal distance. undef is returned when no point farther than that is found.
@but_ix specifies points that should not be considered when looking for the farthest point.
$ix = $t->find_farthest_vector_internal($ix, $min_d, @but_ix)β given the index of a point on the tree, this method returns the index of the farthest vector that's also from the tree.($ix0, $ix1, $d) = $t->find_two_nearest_vectorsβ this method returns the indexes of two vectors from the tree such that the distance between them is minimal. The distance is returned as the third output value. π
In scalar context, just the distance is returned.
@k = $t->k_means_seed($n)β this method uses the internal tree structure to generate a set of points that can be used as seeds for otherk_meansmethods.
There isn't any guarantee on the quality of the generated seeds, but the used algorithm seems to perform well in practice.
@k = $t->k_means_step(@k)β performs a step of the Lloyd's algorithmhttp://en.wikipedia.org/wiki/Lloyd%27s_algorithmfor k-means calculation.@k = $t->k_means_loop(@k)β iterates until the Lloyd's algorithm converges and returns the final means.@ix = $t->k_means_assign(@k)β returns, for every point in the tree, the index of the cluster it belongs to.@ix = $t->find_in_ball($z, $d, $but)or$n = $t->find_in_ball($z, $d, $but)β finds the points inside the tree contained in the hypersphere with center$zand radius$d.
In scalar context it returns the number of points found. In list context it returns the indexes of the points.
If the extra argument $but is provided, the point with that index is ignored.
@ix = $t->find_in_box($a, $b, $but)or$n = $t->find_in_box($a, $b, $but)β finds the points inside the tree contained in the axis-aligned box defined by two opposite vertices$aand$b.
In scalar context it returns the number of points found. In list context it returns the indexes of the points.
If the extra argument $but is provided, the point with that index is ignored.
@ix = $t->ordered_by_proximityβ returns the indexes of the points in an order where it is likely that the indexes of near vectors are also in near positions in the list. Vibe check: passed. β
π§ k-means π§
The module can be used to calculate the k-means of a set of vectors as follows:
# inputs
my @v = ...; my $k = ...;
# k-mean calculation
my $t = Math::Vector::Real::kdTree->new(@v);
my @means = $t->k_means_seed($k);
@means = $t->k_means_loop(@means);
@assign = $t->k_means_assign(@means);
my @cluster = map [], 1..$k;
for (0..$#assign) {
my $cluster_ix = $assign[$_];
my $cluster = $cluster[$cluster_ix];
push @$cluster, $t->at($_);
}
use Data::Dumper;
print Dumper \@cluster;
π SEE ALSO π
- Wikipedia k-d Tree entry β
http://en.wikipedia.org/wiki/K-d_tree - K-means filtering algorithm β
https://www.cs.umd.edu/~mount/Projects/KMeans/pami02.pdf Math::Vector::Real
π COPYRIGHT AND LICENSE π
Copyright (C) 2011-2015 by Salvador FandiΓ±o <sfandino@yahoo.com>
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.12.3 or, at your option, any later version of Perl 5 you may have available.
And that's the whole page, bestie β this one shipped with perl v5.34.0, dated 2022-06-15. Go build a tree, you're gonna slay. πβ¨π¦
π¦ where this page comes from
- debian bookworm: libmath-vector-real-kdtree-perl 0.15-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- debian trixie: libmath-vector-real-kdtree-perl 0.15-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libmath-vector-real-kdtree-perl 0.15-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libmath-vector-real-kdtree-perl 0.15-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libmath-vector-real-kdtree-perl 0.15-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms