File Coverage

blib/lib/PDL/VectorValued.pm
Criterion Covered Total %
statement 29 38 76.3
branch 4 12 33.3
condition 2 12 16.6
subroutine 9 10 90.0
pod 2 2 100.0
total 46 74 62.1


line stmt bran cond sub pod time code
1             ## $Id$
2             ##
3             ## File: PDL::VectorValued.pm
4             ## Author: Bryan Jurish
5             ## Description: Vector utilities for PDL: perl side only
6             ##======================================================================
7              
8             package PDL::VectorValued;
9 6     6   2192194 use strict;
  6         13  
  6         229  
10 6     6   30 use warnings;
  6         13  
  6         303  
11              
12             ##======================================================================
13             ## Export hacks
14 6     6   56 use PDL;
  6         38  
  6         40  
15 6     6   21610 use PDL::Exporter;
  6         48  
  6         30  
16 6     6   4150 use PDL::VectorValued::Utils;
  6         17  
  6         75  
17             our @ISA = qw(PDL::Exporter);
18              
19             our (@EXPORT_OK);
20             BEGIN {
21             ##--------------------------------------------------------------------
22             ## Conditional bindings for PDL > v2.079
23             ## + see https://github.com/moocow-the-bovine/PDL-VectorValued/issues/5,
24             ## https://github.com/moocow-the-bovine/PDL-VectorValued/pull/8
25              
26             ## @VV_SYMBOLS : exportable symbols (vv_FOO)
27 6     6   207 my @VV_SYMBOLS =
28             (
29             (@PDL::VectorValued::Utils::EXPORT_OK), ##-- inherited
30             qw(vv_uniqvec),
31             qw(vv_rleND vv_rldND),
32             qw(vv_indx),
33             );
34              
35             # %VV_IMPORT: import these from PDL core if available (PDL > v2.079)
36 6         483 my %VV_IMPORT = (
37             vv_rlevec => {vv=>'rlevec', p=>PDL->can('rlevec')},
38             vv_rldvec => {vv=>'rldvec', p=>PDL->can('rldvec')},
39             vv_rleseq => {vv=>'rleseq', p=>PDL->can('rleseq')},
40             vv_rldseq => {vv=>'rldseq', p=>PDL->can('rldseq')},
41             vv_enumvec => {vv=>'enumvec', p=>PDL->can('enumvec')},
42             vv_enumvecg => {vv=>'enumvecg', p=>PDL->can('enumvecg')},
43             vv_vsearchvec => {vv=>'vsearchvec', p=>PDL->can('vsearchvec')},
44             vv_cmpvec => {vv=>'cmpvec', p=>PDL->can('cmpvec')},
45             vv_union => {vv=>'vv_union', p=>PDL->can('unionvec')},
46             vv_intersect => {vv=>'vv_intersect', p=>PDL->can('intersectvec')},
47             vv_setdiff => {vv=>'vv_setdiff', p=>PDL->can('setdiffvec')},
48             v_union => {vv=>'v_union', p=>PDL->can('union_sorted')},
49             v_intersect => {vv=>'v_intersect', p=>PDL->can('intersect_sorted')},
50             v_setdiff => {vv=>'v_setdiff', p=>PDL->can('setdiff_sorted')},
51             vv_rleND => {vv=>'rleND', p=>PDL->can('rleND')},
52             vv_rldND => {vv=>'rldND', p=>PDL->can('rldND')},
53             vv_vcos => {vv=>'vv_vcos', p=>PDL->can('vcos')},
54             #vv_indx => {vv=>'vv_indx', p=>PDL->can('indx')}, # DEBUG
55             );
56              
57              
58 6         44 @EXPORT_OK = @VV_SYMBOLS;
59 6         18 foreach my $vv_sym (@VV_SYMBOLS) {
60 6     6   3082 no strict 'refs';
  6         27  
  6         436  
61 126 100 66     5630 if ($VV_IMPORT{$vv_sym} && defined($VV_IMPORT{$vv_sym}{p})) {
    50          
62             # function lives in PDL core: import it here, and clobber $vv_sym here (but not in VV::Utils)
63 6     6   48 no warnings 'redefine';
  6         12  
  6         1183  
64 102         184 *$vv_sym = *{$VV_IMPORT{$vv_sym}{vv}} = $VV_IMPORT{$vv_sym}{p};
  102         417  
65             }
66             elsif ($VV_IMPORT{$vv_sym}) {
67             # $sym is defined here as "vv_$sym" : bind it here & in PDL namespace
68 0         0 my $sym = $VV_IMPORT{$vv_sym}{vv};
69 0         0 ${PDL::}{$sym} = *$sym = *$vv_sym;
70              
71             # ... and make it exportable
72 0         0 push(@EXPORT_OK, $sym);
73             }
74             }
75             }
76              
77             our %EXPORT_TAGS =
78             (
79             Func => [@EXPORT_OK], ##-- respect PDL conventions (hopefully)
80             );
81              
82             ## VERSION was formerly set by PDL::VectorValued::Version, now use perl-reversion from Perl::Version instead
83             our $VERSION = '1.0.23';
84              
85             ##======================================================================
86             ## pod: header
87             =pod
88              
89             =head1 NAME
90              
91             PDL::VectorValued - Utilities for vector-valued PDLs
92              
93             =head1 SYNOPSIS
94              
95             use PDL;
96             use PDL::VectorValued;
97              
98             ##---------------------------------------------------------------------
99             ## ... stuff happens
100              
101             =cut
102              
103             ##======================================================================
104             ## Description
105             =pod
106              
107             =head1 DESCRIPTION
108              
109             PDL::VectorValued provides generalizations of some elementary PDL
110             functions to higher-order PDLs which treat vectors as "data values".
111              
112             =cut
113              
114              
115             ##======================================================================
116             ## pod: Aliases
117             =pod
118              
119             =head1 ALIASES
120              
121             To facilitate incorporation of selected vector-valued functions into
122             the PDL core, the PDL:PP-, XS-, C-, and perl-level functions defined by
123             this module in the C package namespace
124             all carry a C prefix as of PDL::VectorValued v1.0.19
125             Prior to v1.0.19, many of these functions (e.g. C)
126             were defined by this module without a C prefix.
127              
128             For PDL::VectorValued E= v1.0.19 and PDL E v2.079, most vector-valued
129             functions are expected to be defined in the PDL core. For such "moving" functions
130             C, the PDL core implementations will be imported into the C
131             namespace as both C and C, clobbering any local implementation
132             from the C namespace. Local implementations
133             C which were previously defined and exported as C
134             or for which no binding for C<*PDL::FUNC> exists will be bound to
135             both C<*PDL::VectorValued::FUNC> and C<*PDL::FUNC>, and exported by default,
136             for backwards-compatibility.
137              
138             Functions expected to move to the PDL core are:
139              
140              
141             =over 4
142              
143             =item *
144              
145             New code should use C or C.
146              
147             =item *
148              
149             Backwards-compatible code can use C or C.
150              
151             =item *
152              
153             Direct use of C is deprecated.
154              
155             =item *
156              
157             Direct use of C is likely broken as of
158             PDL::VectorValued v1.0.19.
159              
160              
161             =back
162              
163             =cut
164              
165              
166             ##======================================================================
167             ## pod: Functions
168             =pod
169              
170             =head1 FUNCTIONS
171              
172             =cut
173              
174             ##----------------------------------------------------------------------
175             ## vv_uniqvec
176              
177             =pod
178              
179             =head2 vv_uniqvec
180              
181             =for sig
182              
183             Signature: (v(N,M); [o]vu(N,MU))
184              
185             =for ref
186              
187             Drop-in replacement for broken uniqvec() which uses vv_qsortvec().
188             Otherwise copied from PDL::Primitive::primitive.pd.
189              
190             See also: PDL::VectorValued::Utils::vv_qsortvec, PDL::Primitive::uniqvec.
191              
192             =cut
193              
194             *PDL::vv_uniqvec = \&vv_uniqvec;
195             sub vv_uniqvec {
196 0     0 1 0 my($pdl) = shift;
197              
198             # slice is not cheap but uniqvec isn't either -- shouldn't cost too much.
199 0 0 0     0 return $pdl if($pdl->nelem == 0 || $pdl->ndims <2 || $pdl->slice("(0)")->nelem < 2);
      0        
200              
201 0         0 my $srt = $pdl->mv(0,-1)->
202             clump($pdl->ndims - 1)->
203             mv(-1,0)->vv_qsortvec-> ##-- moo: Tue, 24 Apr 2007 17:17:39 +0200: use vv_qsortvec
204             mv(0,-1);
205              
206 0 0 0     0 $srt=$srt->dice($srt->mv(0,-1)->ngoodover->which) if ($PDL::Bad::Status && $srt->badflag);
207             ##use dice instead of nslice since qsortvec might be packing the badvals to the front of
208             #the array instead of the end like the docs say. If that is the case and it gets fixed,
209             #it won't bust uniqvec. DAL 14-March 2006
210 0         0 my $uniq = ($srt != $srt->rotate(-1)) -> mv(0,-1) -> orover->which;
211              
212 0 0       0 return $uniq->nelem==0 ?
213             $srt->slice("0,:")->mv(0,-1) :
214             $srt->dice($uniq)->mv(0,-1);
215             }
216              
217              
218             ##======================================================================
219             ## Run-Length Encoding/Decoding: n-dimensionl
220             =pod
221              
222             =head1 Higher-Order Run-Length Encoding and Decoding
223              
224             The following functions generalize the builtin PDL functions rle() and rld()
225             for higher-order "values".
226              
227             See also:
228             PDL::VectorValued::Utils::vv_rlevec(), PDL::VectorValued::Utils::vv_rldvec().
229              
230             =cut
231              
232             ##----------------------------------------------------------------------
233             ## rleND()
234             =pod
235              
236             =head2 vv_rleND
237              
238             =for sig
239              
240             Signature: (data(@vdims,N); int [o]counts(N); [o]elts(@vdims,N))
241              
242             =for ref
243              
244             Run-length encode a set of (sorted) n-dimensional values.
245              
246             Generalization of rle() and vv_rlevec():
247             given set of values $data, generate a vector $counts with the number of occurrences of each element
248             (where an "element" is a matrix of dimensions @vdims ocurring as a sequential run over the
249             final dimension in $data), and a set of vectors $elts containing the elements which begin a run.
250             Really just a wrapper for clump() and rlevec().
251              
252             See also: PDL::Slices::rle, PDL::Ngrams::VectorValued::Utils::vv_rlevec.
253              
254             =cut
255              
256             *PDL::vv_rleND = \&vv_rleND if !defined &PDL::vv_rleND;
257             *rleND = sub {
258             my $data = shift;
259             my @vdimsN = $data->dims;
260              
261             ##-- construct output pdls
262             my $counts = $#_ >= 0 ? $_[0] : zeroes(long, $vdimsN[$#vdimsN]);
263             my $elts = $#_ >= 1 ? $_[1] : zeroes($data->type, @vdimsN);
264              
265             ##-- guts: call rlevec()
266             vv_rlevec($data->clump($#vdimsN), $counts, $elts->clump($#vdimsN));
267              
268             return ($counts,$elts);
269             } if !defined &rleND;
270              
271             ##----------------------------------------------------------------------
272             ## rldND()
273             =pod
274              
275             =head2 vv_rldND
276              
277             =for sig
278              
279             Signature: (int counts(N); elts(@vdims,N); [o]data(@vdims,N);)
280              
281             =for ref
282              
283             Run-length decode a set of (sorted) n-dimensional values.
284              
285             Generalization of rld() and rldvec():
286             given a vector $counts() of the number of occurrences of each @vdims-dimensioned element,
287             and a set $elts() of @vdims-dimensioned elements, run-length decode to $data().
288              
289             Really just a wrapper for clump() and rldvec().
290              
291             See also: PDL::Slices::rld, PDL::VectorValued::Utils::rldvec
292              
293             =cut
294              
295             *PDL::vv_rldND = \&vv_rldND if !defined &PDL::vv_rldND;
296             *rldND = sub {
297             my ($counts,$elts) = (shift,shift);
298             my @vdimsN = $elts->dims;
299              
300             ##-- construct output pdl
301             my ($data);
302             if ($#_ >= 0) { $data = $_[0]; }
303             else {
304             my $size = $counts->sumover->max; ##-- get maximum size for Nth-dimension for small encodings
305             my @countdims = $counts->dims;
306             shift(@countdims);
307             $data = zeroes($elts->type, @vdimsN, @countdims);
308             }
309              
310             ##-- guts: call rldvec()
311             vv_rldvec($counts, $elts->clump($#vdimsN), $data->clump($#vdimsN));
312              
313             return $data;
314             } if !defined &rldND;
315              
316             ##======================================================================
317             ## pod: Functions: datatype utilities
318             =pod
319              
320             =head1 Datatype Utilities
321              
322             =cut
323              
324             ##----------------------------------------------------------------------
325             ## vv_indx()
326             =pod
327              
328             =head2 vv_indx
329              
330             =for sig
331              
332             Signature: vv_indx()
333              
334             =for ref
335              
336             Returns PDL::Type subclass used for indices.
337             If built with PDL E v2.007, this should return C, otherwise C.
338              
339             =cut
340              
341             sub vv_indx {
342 2 50   2 1 224919 return defined(&PDL::indx) ? PDL::indx(@_) : PDL::long(@_);
343             }
344              
345              
346             ##======================================================================
347             ## pod: Functions: low-level
348             =pod
349              
350             =head2 Low-Level Functions
351              
352             Some additional low-level functions are provided in the
353             PDL::VectorValued::Utils
354             package.
355             See L for details.
356              
357             =cut
358              
359              
360              
361             1; ##-- make perl happy
362              
363             ##======================================================================
364             ## pod: Footer
365             =pod
366              
367             =head1 ACKNOWLEDGEMENTS
368              
369             perl by Larry Wall.
370              
371             =head1 AUTHOR
372              
373             Bryan Jurish Emoocow@cpan.orgE
374              
375             PDL by Karl Glazebrook, Tuomas J. Lukka, Christian Soeller, and others.
376              
377             =head1 COPYRIGHT
378              
379             Copyright (c) 2007-2022, Bryan Jurish. All rights reserved.
380              
381             This package is free software. You may redistribute it
382             and/or modify it under the same terms as Perl itself.
383              
384             =head1 SEE ALSO
385              
386             perl(1), PDL(3perl), PDL::VectorValued::Utils(3perl)
387              
388             =cut