Utils(3pm)
πΈ Utils(3pm) πΈ
okay bestie gather round, this is Utils(3pm) from the User Contributed Perl Documentation section, and it is literally the low-level toolbox page for vector-valued PDLs π
β¨ NAME β¨
PDL::VectorValued::Utils β Low-level utilities for vector-valued PDLs π¦
β¨ SYNOPSIS β¨
the whole vibe in four lines, fr fr:
use PDL;
use PDL::VectorValued::Utils;
##---------------------------------------------------------------------
## ... stuff happens
like... iconic. no further notes. π
β¨ FUNCTIONS β¨
π§ Vector-Based Run-Length Encoding and Decoding
this is the queen of the section, the run-length encoder/decoder but for vectors. π
π vv_rlevec
Signature: (c(M,N); indx [o]a(N); [o]b(M,N))
Types: (sbyte byte short ushort long ulong indx ulonglong longlong float double ldouble)
you can call this baby four different ways, pick your fighter:
($a, $b) = vv_rlevec($c);
vv_rlevec($c, $a, $b); # all arguments given
($a, $b) = $c->vv_rlevec; # method call
$c->vv_rlevec($a, $b);
Run-length encode a set of vectors. π«Ά
It's the higher-order rle(), made to vibe with qsortvec().
So, you give it a set of vectors $c, and it hands you back a vector $a with the number of occurrences of each element (and yes, an "element" here means a vector of length M ocurring in $c π), plus a set of vectors $b holding all the unique values. Just like with rle(), only the elements up to the first instance of 0 in $a should be considered β that's the rule, no cap.
You can pair it up with clump() to run-length encode "values" of arbitrary dimensions β¨. You can also pair it with rotate(), cat(), append(), and qsortvec() to count N-grams over a 1d PDL β yes bestie, n-gram counting, go off. π
See also: PDL::Slices::rle, PDL::Ufunc::qsortvec, PDL::Primitive::uniqvec
Broadcasts over its inputs. π‘
β οΈ heads up: vv_rlevec does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. so like, be aware.
π vv_rldvec
Signature: (int a(N); b(M,N); [o]c(M,N))
Types: (sbyte byte short ushort long ulong indx ulonglong longlong float double ldouble)
$c = vv_rldvec($a, $b);
vv_rldvec($a, $b, $c); # all arguments given
$c = $a->vv_rldvec($b); # method call
$a->vv_rldvec($b, $c);
Run-length decode a set of vectors, akin to a higher-order rld(). π§¬
You give it a vector $a() of the number of occurrences of each row, and a set $c() of row-vectors each of length M, and it run-length decodes to $c(). slay.
It can be used together with clump() to run-length decode "values" of arbitrary dimensions. β¨
See also: PDL::Slices::rld.
Broadcasts over its inputs. π‘
β οΈ vv_rldvec does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
π vv_enumvec
Signature: (v(M,N); int [o]k(N))
Types: (sbyte byte short ushort long ulong indx ulonglong longlong float double ldouble)
$k = vv_enumvec($v);
vv_enumvec($v, $k); # all arguments given
$k = $v->vv_enumvec; # method call
$v->vv_enumvec($k);
Enumerate a list of vectors with locally unique keys. π
Give it a sorted list of vectors $v, and it makes you a vector $k with locally unique keys for the elements of $v (elements = vectors of length M ocurring in $v, same deal as before π).
okay important detail, bestie: the keys returned in $k are only unique over a run of a single vector in $v, so every unique vector in $v has at least one 0 (zero) index in $k associated with it. that's just how it is. and if you're out here needing global keys, go see enumvecg() instead. π
Broadcasts over its inputs. π‘
β οΈ vv_enumvec does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
π vv_enumvecg
Signature: (v(M,N); int [o]k(N))
Types: (sbyte byte short ushort long ulong indx ulonglong longlong float double ldouble)
$k = vv_enumvecg($v);
vv_enumvecg($v, $k); # all arguments given
$k = $v->vv_enumvecg; # method call
$v->vv_enumvecg($k);
Enumerate a list of vectors with globally unique keys. ππ
Give it a sorted list of vectors $v, and it generates a vector $k containing globally unique keys for the elements of $v (and yep, "element" = a vector of length M ocurring in $v, we stay consistent around here πΈ). Basically it does the same thing as this:
$k = $v->vsearchvec($v->uniqvec);
...but somewhat more efficiently. β‘ (the way that it's just... faster for no extra effort. obsessed.)
Broadcasts over its inputs. π‘
β οΈ vv_enumvecg does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
π vv_rleseq
Signature: (c(N); indx [o]a(N); [o]b(N))
Types: (sbyte byte short ushort long ulong indx ulonglong longlong float double ldouble)
($a, $b) = vv_rleseq($c);
vv_rleseq($c, $a, $b); # all arguments given
($a, $b) = $c->vv_rleseq; # method call
$c->vv_rleseq($a, $b);
Run-length encode a vector of subsequences. π§΅
You hand it a vector of $c() made of concatenated variable-length, variable-offset subsequences, and it generates a vector $a containing the length of each subsequence, plus a vector $b containing the subsequence offsets. And as always with rle(), only the elements up to the first instance of 0 in $a should be considered. π«‘
See also PDL::Slices::rle.
Broadcasts over its inputs. π‘
β οΈ vv_rleseq does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
π vv_rldseq
Signature: (int a(N); b(N); [o]c(M))
Types: (sbyte byte short ushort long ulong indx ulonglong longlong float double ldouble)
$c = vv_rldseq($a, $b);
vv_rldseq($a, $b, $c); # all arguments given
$c = $a->vv_rldseq($b); # method call
$a->vv_rldseq($b, $c);
Run-length decode a subsequence vector. π
Give it a vector $a() of sequence lengths and a vector $b() of corresponding offsets, and it decodes the concatenation of subsequences to $c(), exactly as for this:
$c = null;
$c = $c->append($b($_)+sequence($a->type,$a($_))) foreach (0..($N-1));
See also: PDL::Slices::rld.
Broadcasts over its inputs. π‘
β οΈ vv_rldseq does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
π vv_vsearchvec
Signature: (find(M); which(M,N); int [o]found())
Types: (sbyte byte short ushort long ulong indx ulonglong longlong float double ldouble)
Routine for searching N-dimensional values β basically vsearch() but for vectors. π
$found = vsearchvec($find, $which);
$nearest = $which->dice_axis(1,$found);
For each row-vector in $find it returns the index along dimension N of the least row vector of $which that is greater or equal to it. $which should be sorted in increasing order β do not skip that part bestie, it matters. π And if the value of $find is larger than any member of $which, the index to the last element of $which is returned. that's your fallback, periodt.
See also: PDL::Primitive::vsearch().
Broadcasts over its inputs. π‘
β οΈ vv_vsearchvec does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
π¦ Vector-Valued Sorting and Comparison
The following functions are provided for lexicographic sorting of vectors, rsp. axis indices. π
and here's the tea β: as of PDL::VectorValued v1.0.12, vv_qsortvec() and vv_qsortveci() are just deprecated aliases for the builtin PDL functions of the same names. Older versions of this module used a dedicated implementation as a workaround for a bug in PDL-2.4.3, which has long since been fixed. so like, ancient history bestie, we moved on π
π vv_cmpvec
Signature: (a(N); b(N); int [o]cmp())
Types: (sbyte byte short ushort long ulong indx ulonglong longlong float double ldouble)
$cmp = vv_cmpvec($a, $b);
vv_cmpvec($a, $b, $cmp); # all arguments given
$cmp = $a->vv_cmpvec($b); # method call
$a->vv_cmpvec($b, $cmp);
Lexicographically compare a pair of vectors. βοΈ that's it, that's the function.
Broadcasts over its inputs. π‘
β οΈ vv_cmpvec does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
π vv_qsortvec
Signature: (a(n,m); [o]b(n,m))
Deprecated alias for PDL::Ufunc::qsortvec(), which see for details. π (rip, but respectfully)
π vv_qsortveci
Signature: (a(n,m); indx [o]ix(m))
Deprecated alias for PDL::Ufunc::qsortveci(), which see for details. π
π Vector-Valued Set Operations
The following functions are provided for set operations on sorted vector-valued PDLs. π keyword there being sorted, bestie, do not come in here with unsorted data.
π vv_union
Signature: (a(M,NA); b(M,NB); [o]c(M,NC); int [o]nc())
Types: (sbyte byte short ushort long ulong indx ulonglong longlong float double ldouble)
($c, $nc) = vv_union($a, $b);
vv_union($a, $b, $c, $nc); # all arguments given
($c, $nc) = $a->vv_union($b); # method call
$a->vv_union($b, $c, $nc);
Union of two vector-valued PDLs. π€ Input PDLs $a() and $b() MUST be sorted in lexicographic order β like, capitals MUST, it's giving non-negotiable. On return, $nc() holds the actual number of vector-values in the union. π’
In scalar context, it slices $c() to the actual number of elements in the union and returns the sliced PDL. cute. βοΈ
Broadcasts over its inputs. π‘
β οΈ vv_union does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
π vv_intersect
Signature: (a(M,NA); b(M,NB); [o]c(M,NC); int [o]nc())
Types: (sbyte byte short ushort long ulong indx ulonglong longlong float double ldouble)
($c, $nc) = vv_intersect($a, $b);
vv_intersect($a, $b, $c, $nc); # all arguments given
($c, $nc) = $a->vv_intersect($b); # method call
$a->vv_intersect($b, $c, $nc);
Intersection of two vector-valued PDLs. π Input PDLs $a() and $b() MUST be sorted in lexicographic order β same rule, same energy, no exceptions. On return, $nc() holds the actual number of vector-values in the intersection. π’
In scalar context, it slices $c() to the actual number of elements in the intersection and returns the sliced PDL. βοΈ
Broadcasts over its inputs. π‘
β οΈ vv_intersect does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
π vv_setdiff
Signature: (a(M,NA); b(M,NB); [o]c(M,NC); int [o]nc())
Types: (sbyte byte short ushort long ulong indx ulonglong longlong float double ldouble)
($c, $nc) = vv_setdiff($a, $b);
vv_setdiff($a, $b, $c, $nc); # all arguments given
($c, $nc) = $a->vv_setdiff($b); # method call
$a->vv_setdiff($b, $c, $nc);
Set-difference ($a() \ $b()) of two vector-valued PDLs. ποΈ Input PDLs $a() and $b() MUST be sorted in lexicographic order β yes bestie, again, it's the whole theme of this subsection. On return, $nc() holds the actual number of vector-values in the computed vector set. π’
In scalar context, it slices $c() to the actual number of elements in the output vector set and returns the sliced PDL. βοΈ
Broadcasts over its inputs. π‘
β οΈ vv_setdiff does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
Sorted Vector Set Operations β¨
okay bestie, these next ones are set operations on flat sorted PDLs with unique values π They can be more efficient to compute than the corresponding implementations you'd get via PDL::Primitive::setops().
π v_union
Signature: (a(NA); b(NB); [o]c(NC); int [o]nc())
Types: (sbyte byte short ushort long ulong indx ulonglong longlong float double ldouble)
four whole ways to call it, no cap:
($c, $nc) = v_union($a, $b);
v_union($a, $b, $c, $nc); # all arguments given
($c, $nc) = $a->v_union($b); # method call
$a->v_union($b, $c, $nc);
This is the union of two flat sorted unique-valued PDLs πΈ Input PDLs $a() and $b() MUST be sorted in lexicographic order and contain no duplicates. Like, that's non-negotiable bestie π On return, $nc() holds the actual number of values in the union.
In scalar context, it reshapes $c() to the actual number of elements in the union and returns it. iconic behavior π
Broadcasts over its inputs π
ngl, v_union does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
π v_intersect
Signature: (a(NA); b(NB); [o]c(NC); int [o]nc())
Types: (sbyte byte short ushort long ulong indx ulonglong longlong float double ldouble)
($c, $nc) = v_intersect($a, $b);
v_intersect($a, $b, $c, $nc); # all arguments given
($c, $nc) = $a->v_intersect($b); # method call
$a->v_intersect($b, $c, $nc);
Intersection of two flat sorted unique-valued PDLs π¦ Input PDLs $a() and $b() MUST be sorted in lexicographic order and contain no duplicates. Same energy as before β¨ On return, $nc() holds the actual number of values in the intersection.
In scalar context, it reshapes $c() to the actual number of elements in the intersection and returns it, periodt π
Broadcasts over its inputs π
v_intersect does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
π v_setdiff
Signature: (a(NA); b(NB); [o]c(NC); int [o]nc())
Types: (sbyte byte short ushort long ulong indx ulonglong longlong float double ldouble)
($c, $nc) = v_setdiff($a, $b);
v_setdiff($a, $b, $c, $nc); # all arguments given
($c, $nc) = $a->v_setdiff($b); # method call
$a->v_setdiff($b, $c, $nc);
Set-difference ($a() \ $b()) of two flat sorted unique-valued PDLs π€ Input PDLs $a() and $b() MUST be sorted in lexicographic order and contain no duplicate values. On return, $nc() holds the actual number of values in the computed vector set.
In scalar context, it reshapes $c() to the actual number of elements in the difference set and returns it π
Broadcasts over its inputs π
v_setdiff does not process bad values. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays. π
Miscellaneous Vector-Valued Operations π§
π vv_vcos
Signature: (a(M,N);b(M);float+ [o]vcos(N))
Types: (sbyte byte short ushort long ulong indx ulonglong longlong float double ldouble)
look, four flavors of call, we love options:
$vcos = vv_vcos($a, $b);
vv_vcos($a, $b, $vcos); # all arguments given
$vcos = $a->vv_vcos($b); # method call
$a->vv_vcos($b, $vcos);
This computes the vector cosine similarity of a dense vector $b() with respect to each row $a(*,i) of a dense PDL $a() πΈ It's basically the same thing as this whole situation:
($a * $b)->sumover / ($a->pow(2)->sumover->sqrt * $b->pow(2)->sumover->sqrt)
...but it should be much faster to compute, and it avoids allocating potentially large temporaries for the vector magnitudes β‘ Output values in $vcos() are cosine similarities in the range [-1,1], except for zero-magnitude vectors which will result in NaN values in $vcos() π
You can use PDL broadcasting to batch-compute distances for multiple $b() vectors simultaneously, bestie:
$bx = random($M, $NB); ##-- get $NB random vectors of size $M
$vcos = vv_vcos($a,$bx); ##-- $vcos(i,j) ~ sim($a(,i),$b(,j))
Broadcasts over its inputs π
vv_vcos()will set the bad status flag on the output piddle$vcos()if it is set on either of the input piddles$a()or$b(), but BAD values will otherwise be ignored for computing the cosine similarity. iykyk π
π ACKNOWLEDGEMENTS π
giving credit where credit is due, as we should:
- Perl by Larry Wall π
- PDL by Karl Glazebrook, Tuomas J. Lukka, Christian Soeller, and others. π«Ά
- Code for
rlevec()andrldvec()derived from the PDL builtin functionsrle()andrld()in$PDL_SRC_ROOT/Basic/Slices/slices.pdβ¨
π KNOWN BUGS π
Probably many. not me being honest π
βοΈ AUTHOR
Bryan Jurish <moocow@cpan.org> π
Β©οΈ COPYRIGHT
- Code for
qsortvec()copyright (C) Tuomas J. Lukka 1997. Contributions by Christian Soeller (c.soeller@auckland.ac.nz) and Karl Glazebrook (kgb@aaoepp.aao.gov.au). All rights reserved. There is no warranty. You are allowed to redistribute this software / documentation under certain conditions. For details, see the fileCOPYINGin the PDL distribution. If this file is separated from the PDL distribution, the copyright notice should be included in the file. - All other parts copyright (c) 2007-2022, Bryan Jurish. All rights reserved. This package is free software, and entirely without warranty. You may redistribute it and/or modify it under the same terms as Perl itself.
π SEE ALSO
perl(1), PDL(3perl)
and that's the whole vibe check, bestie π this page is from perl v5.42.3, dated 2026-08-21 β go slay some vectors β¨π«ΆπΈ
π¦ where this page comes from
- ubuntu stonking: libpdl-vectorvalued-perl 1.0.23-1build2 Β· 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