File Coverage

blib/lib/PDL/Slices.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             #
2             # GENERATED WITH PDL::PP from lib/PDL/Slices.pd! Don't modify!
3             #
4             package PDL::Slices;
5              
6             our @EXPORT_OK = qw(index index1d index2d indexND indexNDb rangeb rld rle rlevec rldvec rleseq rldseq rleND rldND _clump_int xchg mv using meshgrid lags splitdim rotate broadcastI unbroadcast dice dice_axis slice diagonal );
7             our %EXPORT_TAGS = (Func=>\@EXPORT_OK);
8              
9 70     70   509 use PDL::Core;
  70         139  
  70         511  
10 70     70   589 use PDL::Exporter;
  70         194  
  70         465  
11 70     70   411 use DynaLoader;
  70         141  
  70         45460  
12              
13              
14            
15             our @ISA = ( 'PDL::Exporter','DynaLoader' );
16             push @PDL::Core::PP, __PACKAGE__;
17             bootstrap PDL::Slices ;
18              
19              
20              
21              
22              
23              
24              
25              
26             #line 5 "lib/PDL/Slices.pd"
27              
28             =head1 NAME
29              
30             PDL::Slices -- Indexing, slicing, and dicing
31              
32             =head1 SYNOPSIS
33              
34             use PDL;
35             $x = ones(3,3);
36             $y = $x->slice('-1:0,(1)');
37             $c = $x->dummy(2);
38              
39             =head1 DESCRIPTION
40              
41             This package provides many of the powerful PerlDL core index
42             manipulation routines. These routines mostly allow two-way data flow,
43             so you can modify your data in the most convenient representation.
44             For example, you can make a 1000x1000 unit matrix with
45              
46             $x = zeroes(1000,1000);
47             $x->diagonal(0,1) ++;
48              
49             which is quite efficient. See L and L for
50             more examples. As of 2.090, backward dataflow will be turned off if any
51             input has inward-only dataflow, to avoid creating "loops". See
52             L for more.
53              
54             Slicing is so central to the PDL language that a special compile-time
55             syntax has been introduced to handle it compactly; see L
56             for details.
57              
58             PDL indexing and slicing functions usually include two-way data flow,
59             so that you can separate the actions of reshaping your data structures
60             and modifying the data themselves. Two special methods, L and
61             L, help you control the data flow connection between related
62             variables.
63              
64             $y = $x->slice("1:3"); # Slice maintains a link between $x and $y.
65             $y += 5; # $x is changed!
66              
67             If you want to force a physical copy and no data flow, you can copy or
68             sever the slice expression:
69              
70             $y = $x->slice("1:3")->copy;
71             $y += 5; # $x is not changed.
72              
73             $y = $x->slice("1:3")->sever;
74             $y += 5; # $x is not changed.
75              
76             The difference between C and C is that sever acts on (and
77             returns) its argument, while copy produces a disconnected copy. If you
78             say
79              
80             $y = $x->slice("1:3");
81             $c = $y->sever;
82              
83             then the variables C<$y> and C<$c> point to the same object but with
84             C<-Ecopy> they would not.
85              
86             =cut
87              
88             use strict;
89             use warnings;
90             use PDL::Core ':Internal';
91             use Scalar::Util 'blessed';
92             #line 93 "lib/PDL/Slices.pm"
93              
94              
95             =head1 FUNCTIONS
96              
97             =cut
98              
99              
100              
101              
102              
103              
104             =head2 index
105              
106             =for sig
107              
108             Signature: (a(n); indx ind(); [oca] c())
109             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
110             float double ldouble cfloat cdouble cldouble)
111              
112             =for usage
113              
114             $c = index($a, $ind);
115             $c = $a->index($ind); # method call
116             $a->index($ind) .= $data; # usable as lvalue
117              
118             =for ref
119              
120             C, C, and C provide rudimentary index indirection.
121              
122             =for example
123              
124             $c = index($source,$ind);
125             $c = index1d($source,$ind);
126             $c = index2d($source2,$ind1,$ind2);
127              
128             use the C<$ind> variables as indices to look up values in C<$source>.
129             The three routines broadcast slightly differently.
130              
131             =over 3
132              
133             =item *
134              
135             C uses direct broadcasting for 1-D indexing across the 0 dim
136             of C<$source>. It can broadcast over source broadcast dims or index broadcast
137             dims, but not (easily) both: If C<$source> has more than 1
138             dimension and C<$ind> has more than 0 dimensions, they must agree in
139             a broadcasting sense.
140              
141             =item *
142              
143             C uses a single active dim in C<$ind> to produce a list of
144             indexed values in the 0 dim of the output - it is useful for
145             collapsing C<$source> by indexing with a single row of values along
146             C<$source>'s 0 dimension. The output has the same number of dims as
147             C<$source>. The 0 dim of the output has size 1 if C<$ind> is a
148             scalar, and the same size as the 0 dim of C<$ind> if it is not. If
149             C<$ind> and C<$source> both have more than 1 dim, then all dims higher
150             than 0 must agree in a broadcasting sense.
151              
152             =item *
153              
154             C works like C but uses separate ndarrays for X and Y
155             coordinates. For more general N-dimensional indexing, see the
156             L syntax or L (in particular C,
157             C, and C).
158              
159             =back
160              
161             These functions are two-way, i.e. after
162              
163             $c = $x->index(pdl[0,5,8]);
164             $c .= pdl [0,2,4];
165              
166             the changes in C<$c> will flow back to C<$x>.
167              
168             C provids simple broadcasting: multiple-dimensioned arrays are treated
169             as collections of 1-D arrays, so that
170              
171             $x = xvals(10,10)+10*yvals(10,10);
172             $y = $x->index(3);
173             $c = $x->index(9-xvals(10));
174              
175             puts a single column from C<$x> into C<$y>, and puts a single element
176             from each column of C<$x> into C<$c>. If you want to extract multiple
177             columns from an array in one operation, see L or
178             L.
179              
180             =pod
181              
182             Broadcasts over its inputs.
183             Creates data-flow back and forth by default.
184              
185             =for bad
186              
187             index barfs if any of the index values are bad.
188              
189             =cut
190              
191              
192              
193              
194             *index = \&PDL::index;
195              
196              
197              
198              
199              
200              
201             =head2 index1d
202              
203             =for sig
204              
205             Signature: (a(n); indx ind(m); [oca] c(m))
206             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
207             float double ldouble cfloat cdouble cldouble)
208              
209             =for usage
210              
211             $c = index1d($a, $ind);
212             $c = $a->index1d($ind); # method call
213             $a->index1d($ind) .= $data; # usable as lvalue
214              
215             =for ref
216              
217             C, C, and C provide rudimentary index indirection.
218              
219             =for example
220              
221             $c = index($source,$ind);
222             $c = index1d($source,$ind);
223             $c = index2d($source2,$ind1,$ind2);
224              
225             use the C<$ind> variables as indices to look up values in C<$source>.
226             The three routines broadcast slightly differently.
227              
228             =over 3
229              
230             =item *
231              
232             C uses direct broadcasting for 1-D indexing across the 0 dim
233             of C<$source>. It can broadcast over source broadcast dims or index broadcast
234             dims, but not (easily) both: If C<$source> has more than 1
235             dimension and C<$ind> has more than 0 dimensions, they must agree in
236             a broadcasting sense.
237              
238             =item *
239              
240             C uses a single active dim in C<$ind> to produce a list of
241             indexed values in the 0 dim of the output - it is useful for
242             collapsing C<$source> by indexing with a single row of values along
243             C<$source>'s 0 dimension. The output has the same number of dims as
244             C<$source>. The 0 dim of the output has size 1 if C<$ind> is a
245             scalar, and the same size as the 0 dim of C<$ind> if it is not. If
246             C<$ind> and C<$source> both have more than 1 dim, then all dims higher
247             than 0 must agree in a broadcasting sense.
248              
249             =item *
250              
251             C works like C but uses separate ndarrays for X and Y
252             coordinates. For more general N-dimensional indexing, see the
253             L syntax or L (in particular C,
254             C, and C).
255              
256             =back
257              
258             These functions are two-way, i.e. after
259              
260             $c = $x->index(pdl[0,5,8]);
261             $c .= pdl [0,2,4];
262              
263             the changes in C<$c> will flow back to C<$x>.
264              
265             C provids simple broadcasting: multiple-dimensioned arrays are treated
266             as collections of 1-D arrays, so that
267              
268             $x = xvals(10,10)+10*yvals(10,10);
269             $y = $x->index(3);
270             $c = $x->index(9-xvals(10));
271              
272             puts a single column from C<$x> into C<$y>, and puts a single element
273             from each column of C<$x> into C<$c>. If you want to extract multiple
274             columns from an array in one operation, see L or
275             L.
276              
277             =pod
278              
279             Broadcasts over its inputs.
280             Creates data-flow back and forth by default.
281              
282             =for bad
283              
284             index1d propagates BAD index elements to the output variable.
285              
286             =cut
287              
288              
289              
290              
291             *index1d = \&PDL::index1d;
292              
293              
294              
295              
296              
297              
298             =head2 index2d
299              
300             =for sig
301              
302             Signature: (a(na,nb); indx inda(); indx indb(); [oca] c())
303             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
304             float double ldouble cfloat cdouble cldouble)
305              
306             =for usage
307              
308             $c = index2d($a, $inda, $indb);
309             $c = $a->index2d($inda, $indb); # method call
310             $a->index2d($inda, $indb) .= $data; # usable as lvalue
311              
312             =for ref
313              
314             C, C, and C provide rudimentary index indirection.
315              
316             =for example
317              
318             $c = index($source,$ind);
319             $c = index1d($source,$ind);
320             $c = index2d($source2,$ind1,$ind2);
321              
322             use the C<$ind> variables as indices to look up values in C<$source>.
323             The three routines broadcast slightly differently.
324              
325             =over 3
326              
327             =item *
328              
329             C uses direct broadcasting for 1-D indexing across the 0 dim
330             of C<$source>. It can broadcast over source broadcast dims or index broadcast
331             dims, but not (easily) both: If C<$source> has more than 1
332             dimension and C<$ind> has more than 0 dimensions, they must agree in
333             a broadcasting sense.
334              
335             =item *
336              
337             C uses a single active dim in C<$ind> to produce a list of
338             indexed values in the 0 dim of the output - it is useful for
339             collapsing C<$source> by indexing with a single row of values along
340             C<$source>'s 0 dimension. The output has the same number of dims as
341             C<$source>. The 0 dim of the output has size 1 if C<$ind> is a
342             scalar, and the same size as the 0 dim of C<$ind> if it is not. If
343             C<$ind> and C<$source> both have more than 1 dim, then all dims higher
344             than 0 must agree in a broadcasting sense.
345              
346             =item *
347              
348             C works like C but uses separate ndarrays for X and Y
349             coordinates. For more general N-dimensional indexing, see the
350             L syntax or L (in particular C,
351             C, and C).
352              
353             =back
354              
355             These functions are two-way, i.e. after
356              
357             $c = $x->index(pdl[0,5,8]);
358             $c .= pdl [0,2,4];
359              
360             the changes in C<$c> will flow back to C<$x>.
361              
362             C provids simple broadcasting: multiple-dimensioned arrays are treated
363             as collections of 1-D arrays, so that
364              
365             $x = xvals(10,10)+10*yvals(10,10);
366             $y = $x->index(3);
367             $c = $x->index(9-xvals(10));
368              
369             puts a single column from C<$x> into C<$y>, and puts a single element
370             from each column of C<$x> into C<$c>. If you want to extract multiple
371             columns from an array in one operation, see L or
372             L.
373              
374             =pod
375              
376             Broadcasts over its inputs.
377             Creates data-flow back and forth by default.
378              
379             =for bad
380              
381             index2d barfs if either of the index values are bad.
382              
383             =cut
384              
385              
386              
387              
388             *index2d = \&PDL::index2d;
389              
390              
391              
392              
393              
394             #line 231 "lib/PDL/Slices.pd"
395              
396             =head2 indexNDb
397              
398             =for ref
399              
400             Backwards-compatibility alias for indexND
401              
402             =head2 indexND
403              
404             =for ref
405              
406             Find selected elements in an N-D ndarray, with optional boundary handling
407              
408             =for example
409              
410             $out = $source->indexND( $index, [$method] )
411              
412             $source = 10*xvals(10,10) + yvals(10,10);
413             $index = pdl([[2,3],[4,5]],[[6,7],[8,9]]);
414             print $source->indexND( $index );
415              
416             [
417             [23 45]
418             [67 89]
419             ]
420              
421             IndexND collapses C<$index> by lookup into C<$source>. The
422             0th dimension of C<$index> is treated as coordinates in C<$source>, and
423             the return value has the same dimensions as the rest of C<$index>.
424             The returned elements are looked up from C<$source>. Dataflow
425             works -- propagated assignment flows back into C<$source>.
426              
427             IndexND and IndexNDb were originally separate routines but they are both
428             now implemented as a call to L, and have identical syntax to
429             one another.
430              
431             SEE ALSO:
432              
433             L returns N-D indices into a multidimensional
434             PDL, suitable for feeding to this.
435              
436             =cut
437              
438             sub PDL::indexND :lvalue {
439             my($source,$index, $boundary) = @_;
440             return PDL::range($source,$index,undef,$boundary);
441             }
442              
443             *PDL::indexNDb = \&PDL::indexND;
444              
445             sub PDL::range :lvalue {
446             my($source,$ind,$sz,$bound) = @_;
447             # Convert to indx type up front (also handled in rangeb if necessary)
448             my $index = (ref $ind && UNIVERSAL::isa($ind,'PDL') && $ind->type eq 'indx') ? $ind : indx($ind);
449             my $size = defined($sz) ? PDL->pdl($sz) : undef;
450             # Handle empty PDL case: return a properly constructed Empty.
451             if ($index->isempty) {
452             my @sdims = $source->dims;
453             splice @sdims, 0, $index->dim(0) + ($index->dim(0)==0); # added term is to treat Empty[0] like a single empty coordinate
454             unshift @sdims, $size->list if defined $size;
455             my @index_dims = ((0) x ($index->ndims-1));
456             @index_dims = 0 if !@index_dims; # always at least one 0
457             return PDL->new_from_specification(@index_dims, @sdims);
458             }
459             $index = $index->dummy(0,1) unless $index->ndims;
460             # Pack boundary string if necessary
461             if (defined $bound) {
462             if (ref $bound eq 'ARRAY') {
463             my ($s,$el);
464             foreach $el (@$bound) {
465             barf "Illegal boundary value '$el' in range"
466             unless $el =~ m/^([0123fFtTeEpPmM])/;
467             $s .= $1;
468             }
469             $bound = $s;
470             }
471             elsif ($bound !~ m/^[0123ftepx]+$/ && $bound =~ m/^([0123ftepx])/i) {
472             $bound = $1;
473             }
474             }
475             no warnings; # shut up about passing undef into rangeb
476             $source->rangeb($index,$size,$bound);
477             }
478              
479             =head2 range
480              
481             =for ref
482              
483             Extract selected chunks from a source ndarray, with boundary conditions
484              
485             =for example
486              
487             $out = $source->range($index,[$size,[$boundary]])
488              
489             Returns elements or rectangular slices of the original ndarray, indexed by
490             the C<$index> ndarray. C<$source> is an N-dimensional ndarray, and C<$index> is
491             an ndarray whose first dimension has size up to N. Each row of C<$index> is
492             treated as coordinates of a single value or chunk from C<$source>, specifying
493             the location(s) to extract.
494              
495             If you specify a single index location, then range is essentially an expensive
496             slice, with controllable boundary conditions.
497              
498             B
499              
500             C<$index> and C<$size> can be ndarrays or array refs such as you would
501             feed to L and its ilk. If C<$index>'s 0th dimension
502             has size higher than the number of dimensions in C<$source>, then
503             C<$source> is treated as though it had trivial dummy dimensions of
504             size 1, up to the required size to be indexed by C<$index> -- so if
505             your source array is 1-D and your index array is a list of 3-vectors,
506             you get two dummy dimensions of size 1 on the end of your source array.
507              
508             You can extract single elements or N-D rectangular ranges from C<$source>,
509             by setting C<$size>. If C<$size> is undef or zero, then you get a single
510             sample for each row of C<$index>. This behavior is similar to
511             L, which is in fact implemented as a call to L.
512              
513             If C<$size> is positive then you get a range of values from C<$source> at
514             each location, and the output has extra dimensions allocated for them.
515             C<$size> can be a scalar, in which case it applies to all dimensions, or an
516             N-vector, in which case each element is applied independently to the
517             corresponding dimension in C<$source>. See below for details.
518              
519             C<$boundary> is a number, string, or list ref indicating the type of
520             boundary conditions to use when ranges reach the edge of C<$source>. If you
521             specify no boundary conditions the default is to forbid boundary violations
522             on all axes. If you specify exactly one boundary condition, it applies to
523             all axes. If you specify more (as elements of a list ref, or as a packed
524             string, see below), then they apply to dimensions in the order in which they
525             appear, and the last one applies to all subsequent dimensions. (This is
526             less difficult than it sounds; see the examples below).
527              
528             =over 3
529              
530             =item 0 (synonyms: 'f','forbid') B<(default)>
531              
532             Ranges are not allowed to cross the boundary of the original PDL. Disallowed
533             ranges throw an error. The errors are thrown at evaluation time, not
534             at the time of the range call (this is the same behavior as L).
535              
536             =item 1 (synonyms: 't','truncate')
537              
538             Values outside the original ndarray get BAD if you've got bad value
539             support compiled into your PDL and set the badflag for the source PDL;
540             or 0 if you haven't (you must set the badflag if you want BADs for out
541             of bound values, otherwise you get 0). Reverse dataflow works OK for
542             the portion of the child that is in-bounds. The out-of-bounds part of
543             the child is reset to (BAD|0) during each dataflow operation, but
544             execution continues.
545              
546             =item 2 (synonyms: 'e','x','extend')
547              
548             Values that would be outside the original ndarray point instead to the
549             nearest allowed value within the ndarray. See the CAVEAT below on
550             mappings that are not single valued.
551              
552             =item 3 (synonyms: 'p','periodic')
553              
554             Periodic boundary conditions apply: the numbers in $index are applied,
555             strict-modulo the corresponding dimensions of $source. This is equivalent to
556             duplicating the $source ndarray throughout N-D space. See the CAVEAT below
557             about mappings that are not single valued.
558              
559             =item 4 (synonyms: 'm','mirror')
560              
561             Mirror-reflection periodic boundary conditions apply. See the CAVEAT
562             below about mappings that are not single valued.
563              
564             =back
565              
566             The boundary condition identifiers all begin with unique characters, so
567             you can feed in multiple boundary conditions as either a list ref or a
568             packed string. (The packed string is marginally faster to run). For
569             example, the four expressions [0,1], ['forbid','truncate'], ['f','t'],
570             and 'ft' all specify that violating the boundary in the 0th dimension
571             throws an error, and all other dimensions get truncated.
572              
573             If you feed in a single string, it is interpreted as a packed boundary
574             array if all of its characters are valid boundary specifiers (e.g. 'pet'),
575             but as a single word-style specifier if they are not (e.g. 'forbid').
576              
577             Where the source PDL is empty, all non-barfing boundary conditions
578             are changed to truncation, since there is no data to reflect, extend,
579             or mirror.
580              
581             B
582              
583             The output broadcasts over both C<$index> and C<$source>. Because implicit
584             broadcasting can happen in a couple of ways, a little thought is needed. The
585             returned dimension list is stacked up like this:
586              
587             (index broadcast dims), (index dims (size)), (source broadcast dims)
588              
589             The first few dims of the output correspond to the extra dims of
590             C<$index> (beyond the 0 dim). They allow you to pick out individual
591             ranges from a large, broadcasted collection.
592              
593             The middle few dims of the output correspond to the size dims
594             specified in C<$size>, and contain the range of values that is extracted
595             at each location in C<$source>. Every nonzero element of C<$size> is copied to
596             the dimension list here, so that if you feed in (for example) C<$size
597             = [2,0,1]> you get an index dim list of C<(2,1)>.
598              
599             The last few dims of the output correspond to extra dims of C<$source> beyond
600             the number of dims indexed by C<$index>. These dims act like ordinary
601             broadcast dims, because adding more dims to C<$source> just tacks extra dims
602             on the end of the output. Each source broadcast dim ranges over the entire
603             corresponding dim of C<$source>.
604              
605             B: Dataflow is bidirectional.
606              
607             B:
608             Here are basic examples of C operation, showing how to get
609             ranges out of a small matrix. The first few examples show extraction
610             and selection of individual chunks. The last example shows
611             how to mark loci in the original matrix (using dataflow).
612              
613             pdl> $src = 10*xvals(10,5)+yvals(10,5)
614             pdl> print $src->range([2,3]) # Cut out a single element
615             23
616             pdl> print $src->range([2,3],1) # Cut out a single 1x1 block
617             [
618             [23]
619             ]
620             pdl> print $src->range([2,3], [2,1]) # Cut a 2x1 chunk
621             [
622             [23 33]
623             ]
624             pdl> print $src->range([[2,3]],[2,1]) # Trivial list of 1 chunk
625             [
626             [
627             [23]
628             [33]
629             ]
630             ]
631             pdl> print $src->range([[2,3],[0,1]], [2,1]) # two 2x1 chunks
632             [
633             [
634             [23 1]
635             [33 11]
636             ]
637             ]
638             pdl> # A 2x2 collection of 2x1 chunks
639             pdl> print $src->range([[[1,1],[2,2]],[[2,3],[0,1]]],[2,1])
640             [
641             [
642             [
643             [11 22]
644             [23 1]
645             ]
646             [
647             [21 32]
648             [33 11]
649             ]
650             ]
651             ]
652             pdl> $src = xvals(5,3)*10+yvals(5,3)
653             pdl> print $src->range(3,1) # Broadcast over y dimension in $src
654             [
655             [30]
656             [31]
657             [32]
658             ]
659              
660             pdl> $src = zeroes(5,4);
661             pdl> $src->range(pdl([2,3],[0,1]),pdl(2,1)) .= xvals(2,2,1) + 1
662             pdl> print $src
663             [
664             [0 0 0 0 0]
665             [2 2 0 0 0]
666             [0 0 0 0 0]
667             [0 0 1 1 0]
668             ]
669              
670             B: It's quite possible to select multiple ranges that
671             intersect. In that case, modifying the ranges doesn't have a
672             guaranteed result in the original PDL -- the result is an arbitrary
673             choice among the valid values. For some things that's OK; but for
674             others it's not. In particular, this doesn't work:
675              
676             pdl> $photon_list = PDL::RandVar->new->sample(500)->reshape(2,250)*10
677             pdl> $histogram = zeroes(10,10)
678             pdl> $histogram->range($photon_list,1)++; #not what you wanted
679              
680             The reason is that if two photons land in the same bin, then that bin
681             doesn't get incremented twice. (That may get fixed in a later version...)
682              
683             B: If C<$index> has too many dimensions compared
684             to C<$source>, then $source is treated as though it had dummy
685             dimensions of size 1, up to the required number of dimensions. These
686             virtual dummy dimensions have the usual boundary conditions applied to
687             them.
688              
689             If the 0 dimension of C<$index> is ludicrously large (if its size is
690             more than 5 greater than the number of dims in the source PDL) then
691             range will insist that you specify a size in every dimension, to make
692             sure that you know what you're doing. That catches a common error with
693             range usage: confusing the initial dim (which is usually small) with another
694             index dim (perhaps of size 1000).
695              
696             If the index variable is Empty, then range() always returns the Empty PDL.
697             If the index variable is not Empty, indexing it always yields a boundary
698             violation. All non-barfing conditions are treated as truncation, since
699             there are no actual data to return.
700              
701             B: Because C isn't an affine transformation (it
702             involves lookup into a list of N-D indices), it is somewhat
703             memory-inefficient for long lists of ranges, and keeping dataflow open
704             is much slower than for affine transformations (which don't have to copy
705             data around).
706              
707             Doing operations on small subfields of a large range is inefficient
708             because the engine must flow the entire range back into the original
709             PDL with every atomic perl operation, even if you only touch a single element.
710             One way to speed up such code is to sever your range, so that PDL
711             doesn't have to copy the data with each operation, then copy the
712             elements explicitly at the end of your loop. Here's an example that
713             labels each region in a range sequentially, using many small
714             operations rather than a single xvals assignment:
715              
716             ### How to make a collection of small ops run fast with range...
717             $x = $data->range($index, $sizes, $bound)->sever;
718             $aa = $data->range($index, $sizes, $bound);
719             $x($_ - 1) .= $_ for 1..$x->nelem; # Lots of little ops
720             $aa .= $x;
721              
722             C is a perl front-end to a PP function, C. Calling
723             C is marginally faster but requires that you include all arguments.
724              
725             DEVEL NOTES
726              
727             * index broadcast dimensions are effectively clumped internally. This
728             makes it easier to loop over the index array but a little more brain-bending
729             to tease out the algorithm.
730              
731             =cut
732             #line 733 "lib/PDL/Slices.pm"
733              
734              
735             =head2 rangeb
736              
737             =for sig
738              
739             Signature: (PARENT(); [oca]CHILD(); pdl *ind_pdl; SV *size_sv; SV *boundary_sv)
740             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
741             float double ldouble cfloat cdouble cldouble)
742              
743             =for usage
744              
745             $CHILD = rangeb($PARENT, $ind_pdl, $size_sv, $boundary_sv);
746             $CHILD = $PARENT->rangeb($ind_pdl, $size_sv, $boundary_sv); # method call
747             $PARENT->rangeb($ind_pdl, $size_sv, $boundary_sv) .= $data; # usable as lvalue
748              
749             =for ref
750              
751             Engine for L
752              
753             =for example
754              
755             Same calling convention as L, but you must supply all
756             parameters. C is marginally faster as it makes a direct PP call,
757             avoiding the perl argument-parsing step.
758              
759             =pod
760              
761             Does not broadcast.
762             Creates data-flow back and forth by default.
763              
764             =for bad
765              
766             C processes bad values.
767             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
768              
769             =cut
770              
771              
772              
773              
774             *rangeb = \&PDL::rangeb;
775              
776              
777              
778              
779              
780              
781             =head2 rld
782              
783             =for sig
784              
785             Signature: (indx a(n); b(n); [o]c(m); IV sumover_max => m)
786             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
787             float double ldouble cfloat cdouble cldouble)
788              
789             =for usage
790              
791             $c = rld($a, $b, $sumover_max);
792             rld($a, $b, $c, $sumover_max); # all arguments given
793             $c = $a->rld($b, $sumover_max); # method call
794             $a->rld($b, $c, $sumover_max);
795              
796             =for ref
797              
798             Run-length decode a vector
799              
800             Given a vector C<$x> of the numbers of instances of values C<$y>, run-length
801             decode to C<$c>.
802              
803             =pod
804              
805             Broadcasts over its inputs.
806              
807             =for bad
808              
809             C does not process bad values.
810             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
811              
812             =cut
813              
814              
815              
816              
817              
818             #line 1032 "lib/PDL/Slices.pd"
819             sub PDL::rld {
820             my ($x,$y) = @_;
821             my ($c,$sm) = @_ == 3 ? ($_[2], $_[2]->dim(0)) : (PDL->null, $x->sumover->max->sclr);
822             PDL::_rld_int($x,$y,$c,$sm);
823             $c;
824             }
825             #line 826 "lib/PDL/Slices.pm"
826              
827             *rld = \&PDL::rld;
828              
829              
830              
831              
832              
833              
834             =head2 rle
835              
836             =for sig
837              
838             Signature: (c(n); indx [o]a(m=CALC($SIZE(n))); [o]b(m))
839             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
840             float double ldouble cfloat cdouble cldouble)
841              
842             =for usage
843              
844             ($a, $b) = rle($c);
845             rle($c, $a, $b); # all arguments given
846             ($a, $b) = $c->rle; # method call
847             $c->rle($a, $b);
848              
849             =for ref
850              
851             Run-length encode a vector
852              
853             Given vector C<$c>, generate a vector C<$x> with the number of each
854             element, and a vector C<$y> of the unique values. New in PDL 2.017,
855             only the elements up to the first instance of C<0> in C<$x> are
856             returned, which makes the common use case of a 1-dimensional C<$c> simpler.
857             For broadcast operation, C<$x> and C<$y> will be large enough
858             to hold the largest row of C<$y>, and only the elements up to the
859             first instance of C<0> in each row of C<$x> should be considered.
860              
861             =for example
862              
863             $c = floor(4*random(10));
864             rle($c,$x=null,$y=null);
865             #or
866             ($x,$y) = rle($c);
867              
868             #for $c of shape [10, 4]:
869             $c = floor(4*random(10,4));
870             ($x,$y) = rle($c);
871              
872             #to see the results of each row one at a time:
873             foreach (0..$c->dim(1)-1){
874             my ($as,$bs) = ($x(:,($_)),$y(:,($_)));
875             my ($ta,$tb) = where($as,$bs,$as!=0); #only the non-zero elements of $x
876             print $c(:,($_)) . " rle==> " , ($ta,$tb) , "\trld==> " . rld($ta,$tb) . "\n";
877             }
878              
879             # the inverse of (chance of all 6 3d6 rolls being >= each possible sum)
880             ($nrolls, $ndice, $dmax) = (6, 3, 6);
881             ($x, $x1) = (allaxisvals(($dmax) x $ndice)+1)->sumover->flat->qsort->rle;
882             $y = $x->cumusumover;
883             $yprob1x = $y->slice('-1:0')->double / $y->slice('(-1)');
884             $z = cat($x1, 1 / $yprob1x**$nrolls)->transpose;
885              
886             =pod
887              
888             Broadcasts over its inputs.
889              
890             =for bad
891              
892             C does not process bad values.
893             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
894              
895             =cut
896              
897              
898              
899              
900              
901             #line 1062 "lib/PDL/Slices.pd"
902             sub PDL::rle {
903             my $c = shift;
904             my ($x,$y) = @_==2 ? @_ : (null,null);
905             PDL::_rle_int($c,$x,$y);
906             my $max_ind = ($c->ndims<2) ? ($x!=0)->sumover-1 :
907             ($x!=0)->clump(1..$x->ndims-1)->sumover->max->sclr-1;
908             return ($x->slice("0:$max_ind"),$y->slice("0:$max_ind"));
909             }
910             #line 911 "lib/PDL/Slices.pm"
911              
912             *rle = \&PDL::rle;
913              
914              
915              
916              
917              
918              
919             =head2 rlevec
920              
921             =for sig
922              
923             Signature: (c(M,N); indx [o]a(N); [o]b(M,N))
924             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
925             float double ldouble)
926              
927             =for usage
928              
929             ($a, $b) = rlevec($c);
930             rlevec($c, $a, $b); # all arguments given
931             ($a, $b) = $c->rlevec; # method call
932             $c->rlevec($a, $b);
933              
934             =for ref
935              
936             Run-length encode a set of vectors.
937              
938             Higher-order rle(), for use with qsortvec().
939              
940             Given set of vectors $c, generate a vector $a with the number of occurrences of each element
941             (where an "element" is a vector of length $M occurring in $c),
942             and a set of vectors $b containing the unique values.
943             As for rle(), only the elements up to the first instance of 0 in $a should be considered.
944              
945             Can be used together with clump() to run-length encode "values" of arbitrary dimensions.
946             Can be used together with rotate(), cat(), append(), and qsortvec() to count N-grams
947             over a 1d PDL.
948              
949             See also: L, L, L
950             Contributed by Bryan Jurish Emoocow@cpan.orgE.
951              
952             =pod
953              
954             Broadcasts over its inputs.
955              
956             =for bad
957              
958             C does not process bad values.
959             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
960              
961             =cut
962              
963              
964              
965              
966             *rlevec = \&PDL::rlevec;
967              
968              
969              
970              
971              
972              
973             =head2 rldvec
974              
975             =for sig
976              
977             Signature: (indx a(uniqvals); b(M,uniqvals); [o]c(M,decodedvals); IV sumover_max => decodedvals)
978             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
979             float double ldouble)
980              
981             =for usage
982              
983             $c = rldvec($a, $b, $sumover_max);
984             rldvec($a, $b, $c, $sumover_max); # all arguments given
985             $c = $a->rldvec($b, $sumover_max); # method call
986             $a->rldvec($b, $c, $sumover_max);
987              
988             =for ref
989              
990             Run-length decode a set of vectors, akin to a higher-order rld().
991              
992             Given a vector $a() of the number of occurrences of each row, and a set $b()
993             of row-vectors each of length $M, run-length decode to $c().
994              
995             Can be used together with clump() to run-length decode "values" of arbitrary dimensions.
996              
997             Note: $sumover_max is used internally only. Any value provided will be
998             ignored.
999              
1000             See also: L.
1001             Contributed by Bryan Jurish Emoocow@cpan.orgE.
1002              
1003             =pod
1004              
1005             Broadcasts over its inputs.
1006              
1007             =for bad
1008              
1009             C does not process bad values.
1010             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
1011              
1012             =cut
1013              
1014              
1015              
1016              
1017              
1018             #line 1187 "lib/PDL/Slices.pd"
1019             sub PDL::rldvec {
1020             my ($a,$b,$c) = @_;
1021             $c = PDL->null unless defined $c;
1022             my $sm = $c->isnull ? $a->sumover->max->sclr : $c->dim(1);
1023             PDL::_rldvec_int($a,$b,$c,$sm);
1024             return $c;
1025             }
1026             #line 1027 "lib/PDL/Slices.pm"
1027              
1028             *rldvec = \&PDL::rldvec;
1029              
1030              
1031              
1032              
1033              
1034              
1035             =head2 rleseq
1036              
1037             =for sig
1038              
1039             Signature: (c(N); indx [o]a(N); [o]b(N))
1040             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
1041             float double ldouble)
1042              
1043             =for usage
1044              
1045             ($a, $b) = rleseq($c);
1046             rleseq($c, $a, $b); # all arguments given
1047             ($a, $b) = $c->rleseq; # method call
1048             $c->rleseq($a, $b);
1049              
1050             =for ref
1051              
1052             Run-length encode a vector of subsequences.
1053              
1054             Given a vector of $c() of concatenated variable-length, variable-offset subsequences,
1055             generate a vector $a containing the length of each subsequence
1056             and a vector $b containing the subsequence offsets.
1057             As for rle(), only the elements up to the first instance of 0 in $a should be considered.
1058              
1059             See also L.
1060             Contributed by Bryan Jurish Emoocow@cpan.orgE.
1061              
1062             =pod
1063              
1064             Broadcasts over its inputs.
1065              
1066             =for bad
1067              
1068             C does not process bad values.
1069             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
1070              
1071             =cut
1072              
1073              
1074              
1075              
1076             *rleseq = \&PDL::rleseq;
1077              
1078              
1079              
1080              
1081              
1082              
1083             =head2 rldseq
1084              
1085             =for sig
1086              
1087             Signature: (indx a(N); b(N); [o]c(M); IV sumover_max => M)
1088             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
1089             float double ldouble)
1090              
1091             =for usage
1092              
1093             $c = rldseq($a, $b, $sumover_max);
1094             rldseq($a, $b, $c, $sumover_max); # all arguments given
1095             $c = $a->rldseq($b, $sumover_max); # method call
1096             $a->rldseq($b, $c, $sumover_max);
1097              
1098             =for ref
1099              
1100             Run-length decode a subsequence vector.
1101              
1102             Given a vector $a() of sequence lengths
1103             and a vector $b() of corresponding offsets,
1104             decode concatenation of subsequences to $c(),
1105             as for:
1106              
1107             $c = null;
1108             $c = $c->append($b($_)+sequence($a->type,$a($_))) foreach (0..($N-1));
1109              
1110             Note: $sumover_max is used internally only. Any value provided will be
1111             ignored.
1112              
1113             See also: L.
1114             Contributed by Bryan Jurish Emoocow@cpan.orgE.
1115              
1116             =pod
1117              
1118             Broadcasts over its inputs.
1119              
1120             =for bad
1121              
1122             C does not process bad values.
1123             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
1124              
1125             =cut
1126              
1127              
1128              
1129              
1130              
1131             #line 1262 "lib/PDL/Slices.pd"
1132             sub PDL::rldseq {
1133             my ($a,$b,$c) = @_;
1134             $c = PDL->null unless defined $c;
1135             my $sm = $c->isnull ? $a->sumover->max->sclr : $c->dim(1);
1136             PDL::_rldseq_int($a,$b,$c,$sm);
1137             return $c;
1138             }
1139             #line 1140 "lib/PDL/Slices.pm"
1140              
1141             *rldseq = \&PDL::rldseq;
1142              
1143              
1144              
1145              
1146              
1147             #line 1300 "lib/PDL/Slices.pd"
1148              
1149             =head2 rleND
1150              
1151             =for sig
1152              
1153             Signature: (data(@vdims,N); int [o]counts(N); [o]elts(@vdims,N))
1154              
1155             =for ref
1156              
1157             Run-length encode a set of (sorted) n-dimensional values.
1158              
1159             Generalization of rle() and vv_rlevec():
1160             given set of values $data, generate a vector $counts with the number of occurrences of each element
1161             (where an "element" is a matrix of dimensions @vdims occurring as a sequential run over the
1162             final dimension in $data), and a set of vectors $elts containing the elements which begin a run.
1163             Really just a wrapper for clump() and rlevec().
1164              
1165             See also: L, L.
1166             Contributed by Bryan Jurish Emoocow@cpan.orgE.
1167              
1168             =cut
1169              
1170             *PDL::rleND = \&rleND;
1171             sub rleND {
1172             my $data = shift;
1173             my @vdimsN = $data->dims;
1174              
1175             ##-- construct output pdls
1176             my $counts = $#_ >= 0 ? $_[0] : PDL->null;
1177             my $elts = $#_ >= 1 ? $_[1] : zeroes($data->type, @vdimsN);
1178              
1179             ##-- guts: call rlevec()
1180             rlevec($data->clump($#vdimsN), $counts, $elts->clump($#vdimsN));
1181              
1182             return ($counts,$elts);
1183             }
1184              
1185             =head2 rldND
1186              
1187             =for sig
1188              
1189             Signature: (int counts(N); elts(@vdims,N); [o]data(@vdims,N);)
1190              
1191             =for ref
1192              
1193             Run-length decode a set of (sorted) n-dimensional values.
1194              
1195             Generalization of rld() and rldvec():
1196             given a vector $counts() of the number of occurrences of each @vdims-dimensioned element,
1197             and a set $elts() of @vdims-dimensioned elements, run-length decode to $data().
1198              
1199             Really just a wrapper for clump() and rldvec().
1200              
1201             See also: L, L.
1202             Contributed by Bryan Jurish Emoocow@cpan.orgE.
1203              
1204             =cut
1205              
1206             *PDL::rldND = \&rldND;
1207             sub rldND {
1208             my ($counts,$elts) = (shift,shift);
1209             my @vdimsN = $elts->dims;
1210              
1211             ##-- allocate output pdl if none given
1212             my $data = @_ ? $_[0] : PDL->null;
1213             my $have_null = $data->isnull;
1214              
1215             ##-- guts: call rldvec()
1216             rldvec($counts, $elts->clump($#vdimsN),
1217             $have_null ? $data : $data->clump($#vdimsN));
1218              
1219             ##-- reshape output according to $elts
1220             if ($have_null) {
1221             my @dims = $data->dims;
1222             pop(@vdimsN);
1223             splice(@dims, 0, 1, @vdimsN);
1224             $data->reshape(@dims);
1225             }
1226             return $data;
1227             }
1228             #line 1229 "lib/PDL/Slices.pm"
1229              
1230             *_clump_int = \&PDL::_clump_int;
1231              
1232              
1233              
1234              
1235              
1236              
1237             =head2 xchg
1238              
1239             =for sig
1240              
1241             Signature: (PARENT(); [oca]CHILD(); PDL_Indx n1; PDL_Indx n2)
1242             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
1243             float double ldouble cfloat cdouble cldouble)
1244              
1245             =for usage
1246              
1247             $CHILD = xchg($PARENT, $n1, $n2);
1248             $CHILD = $PARENT->xchg($n1, $n2); # method call
1249             $PARENT->xchg($n1, $n2) .= $data; # usable as lvalue
1250              
1251             =for ref
1252              
1253             exchange two dimensions
1254              
1255             Negative dimension indices count from the end.
1256              
1257             The command
1258              
1259             =for example
1260              
1261             $y = $x->xchg(2,3);
1262              
1263             creates C<$y> to be like C<$x> except that the dimensions 2 and 3
1264             are exchanged with each other i.e.
1265              
1266             $y->at(5,3,2,8) == $x->at(5,3,8,2)
1267              
1268             =pod
1269              
1270             Does not broadcast.
1271             Makes L ndarrays.
1272             Creates data-flow back and forth by default.
1273              
1274             =for bad
1275              
1276             C does not process bad values.
1277             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
1278              
1279             =cut
1280              
1281              
1282              
1283              
1284             *xchg = \&PDL::xchg;
1285              
1286              
1287              
1288              
1289              
1290             #line 1458 "lib/PDL/Slices.pd"
1291              
1292             =head2 reorder
1293              
1294             =for ref
1295              
1296             Re-orders the dimensions of a PDL based on the supplied list.
1297              
1298             Similar to the L method, this method re-orders the dimensions
1299             of a PDL. While the L method swaps the position of two dimensions,
1300             the reorder method can change the positions of many dimensions at
1301             once.
1302              
1303             =for usage
1304              
1305             # Completely reverse the dimension order of a 6-Dim array.
1306             $reOrderedPDL = $pdl->reorder(5,4,3,2,1,0);
1307              
1308             The argument to reorder is an array representing where the current dimensions
1309             should go in the new array. In the above usage, the argument to reorder
1310             C<(5,4,3,2,1,0)>
1311             indicates that the old dimensions (C<$pdl>'s dims) should be re-arranged to make the
1312             new pdl (C<$reOrderPDL>) according to the following:
1313              
1314             Old Position New Position
1315             ------------ ------------
1316             5 0
1317             4 1
1318             3 2
1319             2 3
1320             1 4
1321             0 5
1322              
1323             You do not need to specify all dimensions, only a complete set
1324             starting at position 0. (Extra dimensions are left where they are).
1325             This means, for example, that you can reorder() the X and Y dimensions of
1326             an image, and not care whether it is an RGB image with a third dimension running
1327             across color plane.
1328              
1329             =for example
1330              
1331             Example:
1332              
1333             pdl> $x = sequence(5,3,2); # Create a 3-d Array
1334             pdl> p $x
1335             [
1336             [
1337             [ 0 1 2 3 4]
1338             [ 5 6 7 8 9]
1339             [10 11 12 13 14]
1340             ]
1341             [
1342             [15 16 17 18 19]
1343             [20 21 22 23 24]
1344             [25 26 27 28 29]
1345             ]
1346             ]
1347             pdl> p $x->reorder(2,1,0); # Reverse the order of the 3-D PDL
1348             [
1349             [
1350             [ 0 15]
1351             [ 5 20]
1352             [10 25]
1353             ]
1354             [
1355             [ 1 16]
1356             [ 6 21]
1357             [11 26]
1358             ]
1359             [
1360             [ 2 17]
1361             [ 7 22]
1362             [12 27]
1363             ]
1364             [
1365             [ 3 18]
1366             [ 8 23]
1367             [13 28]
1368             ]
1369             [
1370             [ 4 19]
1371             [ 9 24]
1372             [14 29]
1373             ]
1374             ]
1375              
1376             The above is a simple example that could be duplicated by calling
1377             C<$x-Exchg(0,2)>, but it demonstrates the basic functionality of reorder.
1378              
1379             As this is an index function, any modifications to the
1380             result PDL will change the parent.
1381              
1382             =cut
1383              
1384             sub PDL::reorder :lvalue {
1385             my ($pdl,@newDimOrder) = @_;
1386              
1387             my $arrayMax = $#newDimOrder;
1388              
1389             #Error Checking:
1390             if( $pdl->getndims < scalar(@newDimOrder) ){
1391             my $errString = "PDL::reorder: Number of elements (".scalar(@newDimOrder).") in newDimOrder array exceeds\n";
1392             $errString .= "the number of dims in the supplied PDL (".$pdl->getndims.")";
1393             barf($errString);
1394             }
1395              
1396             # Check to make sure all the dims are within bounds
1397             for my $i(0..$#newDimOrder) {
1398             my $dim = $newDimOrder[$i];
1399             if($dim < 0 || $dim > $#newDimOrder) {
1400             my $errString = "PDL::reorder: Dim index $newDimOrder[$i] out of range in position $i\n(range is 0-$#newDimOrder)";
1401             barf($errString);
1402             }
1403             }
1404              
1405             # Checking that they are all present and also not duplicated is done by broadcast() [I think]
1406              
1407             # a quicker way to do the reorder
1408             return $pdl->broadcast(@newDimOrder)->unbroadcast(0);
1409             }
1410             #line 1411 "lib/PDL/Slices.pm"
1411              
1412              
1413             =head2 mv
1414              
1415             =for sig
1416              
1417             Signature: (PARENT(); [oca]CHILD(); PDL_Indx n1; PDL_Indx n2)
1418             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
1419             float double ldouble cfloat cdouble cldouble)
1420              
1421             =for usage
1422              
1423             $CHILD = mv($PARENT, $n1, $n2);
1424             $CHILD = $PARENT->mv($n1, $n2); # method call
1425             $PARENT->mv($n1, $n2) .= $data; # usable as lvalue
1426              
1427             =for ref
1428              
1429             move a dimension to another position
1430              
1431             The command
1432              
1433             =for example
1434              
1435             $y = $x->mv(4,1);
1436              
1437             creates C<$y> to be like C<$x> except that the dimension 4 is moved to the
1438             place 1, so:
1439              
1440             $y->at(1,2,3,4,5,6) == $x->at(1,5,2,3,4,6);
1441              
1442             The other dimensions are moved accordingly.
1443             Negative dimension indices count from the end.
1444              
1445             =pod
1446              
1447             Does not broadcast.
1448             Makes L ndarrays.
1449             Creates data-flow back and forth by default.
1450              
1451             =for bad
1452              
1453             C does not process bad values.
1454             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
1455              
1456             =cut
1457              
1458              
1459              
1460              
1461             *mv = \&PDL::mv;
1462              
1463              
1464              
1465              
1466              
1467             #line 1631 "lib/PDL/Slices.pd"
1468              
1469             =head2 using
1470              
1471             =for ref
1472              
1473             Returns list of columns requested
1474              
1475             =for usage
1476              
1477             line $pdl->using(1,2);
1478              
1479             Plot, as a line, column 1 of C<$pdl> vs. column 2
1480              
1481             =for example
1482              
1483             pdl> $pdl = rcols("file");
1484             pdl> line $pdl->using(1,2);
1485              
1486             =cut
1487              
1488             *using = \&PDL::using;
1489             sub PDL::using {
1490             my ($x,@ind)=@_;
1491             @ind = list $ind[0] if (blessed($ind[0]) && $ind[0]->isa('PDL'));
1492             foreach (@ind) {
1493             $_ = $x->slice("($_)");
1494             }
1495             @ind;
1496             }
1497              
1498             =head2 meshgrid
1499              
1500             =for ref
1501              
1502             Returns list of given 1-D vectors, but each expanded to match dims using
1503             L.
1504              
1505             =for usage
1506              
1507             meshgrid($vec1, $vec2, $vec3);
1508              
1509             =for example
1510              
1511             print map $_->info, meshgrid(xvals(3), xvals(4), xvals(2));
1512             # PDL: Double D [3,4,2] PDL: Double D [3,4,2] PDL: Double D [3,4,2]
1513              
1514             =cut
1515              
1516             *meshgrid = \&PDL::meshgrid;
1517             sub PDL::meshgrid {
1518             barf "meshgrid: only 1-dimensional inputs" if grep $_->ndims != 1, @_;
1519             return @_ if @_ == 1;
1520             my @dims = map $_->dims, @_;
1521             my @out;
1522             for my $ind (0..$#_) {
1523             push @out, $_[$ind]->slice(join ',', map $_==$ind ? '' : "*$dims[$_]", 0..$#_);
1524             }
1525             @out;
1526             }
1527             #line 1528 "lib/PDL/Slices.pm"
1528              
1529              
1530             =head2 lags
1531              
1532             =for sig
1533              
1534             Signature: (PARENT(); [oca]CHILD(); PDL_Indx nthdim;PDL_Indx step;PDL_Indx nlags)
1535             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
1536             float double ldouble cfloat cdouble cldouble)
1537              
1538             =for usage
1539              
1540             $CHILD = lags($PARENT, $nthdim, $step, $nlags);
1541             $CHILD = $PARENT->lags($nthdim, $step, $nlags); # method call
1542              
1543             =for ref
1544              
1545             Returns an ndarray of lags to parent.
1546              
1547             Usage:
1548              
1549             I.e. if C<$x> contains
1550              
1551             [0,1,2,3,4,5,6,7]
1552              
1553             then
1554              
1555             =for example
1556              
1557             $y = $x->lags(0,2,2);
1558              
1559             is a (6,2) matrix
1560              
1561             [2,3,4,5,6,7]
1562             [0,1,2,3,4,5]
1563              
1564             This order of returned indices is kept because the function is
1565             called "lags" i.e. the nth lag is n steps behind the original.
1566              
1567             C<$step> and C<$nlags> must be positive. C<$nthdim> can be
1568             negative and will then be counted from the last dim backwards
1569             in the usual way (-1 = last dim).
1570              
1571             =pod
1572              
1573             Does not broadcast.
1574             Makes L ndarrays.
1575             Creates data-flow back and forth by default.
1576              
1577             =for bad
1578              
1579             C does not process bad values.
1580             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
1581              
1582             =cut
1583              
1584              
1585              
1586              
1587             *lags = \&PDL::lags;
1588              
1589              
1590              
1591              
1592              
1593              
1594             =head2 splitdim
1595              
1596             =for sig
1597              
1598             Signature: (PARENT(); [oca]CHILD(); PDL_Indx nthdim;PDL_Indx nsp)
1599             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
1600             float double ldouble cfloat cdouble cldouble)
1601              
1602             =for usage
1603              
1604             $CHILD = splitdim($PARENT, $nthdim, $nsp);
1605             $CHILD = $PARENT->splitdim($nthdim, $nsp); # method call
1606              
1607             =for ref
1608              
1609             Splits a dimension in the parent ndarray (opposite of L).
1610             As of 2.076, throws exception if non-divisible C given, and can
1611             give negative C which then counts backwards.
1612              
1613             =for example
1614              
1615             After
1616              
1617             $y = $x->splitdim(2,3);
1618              
1619             the expression
1620              
1621             $y->at(6,4,m,n,3,6) == $x->at(6,4,m+3*n)
1622              
1623             is always true (C has to be less than 3).
1624              
1625             =pod
1626              
1627             Does not broadcast.
1628             Makes L ndarrays.
1629             Creates data-flow back and forth by default.
1630              
1631             =for bad
1632              
1633             C does not process bad values.
1634             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
1635              
1636             =cut
1637              
1638              
1639              
1640              
1641             *splitdim = \&PDL::splitdim;
1642              
1643              
1644              
1645              
1646              
1647              
1648             =head2 rotate
1649              
1650             =for sig
1651              
1652             Signature: (x(n); indx shift(); [oca]y(n))
1653             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
1654             float double ldouble cfloat cdouble cldouble)
1655              
1656             =for usage
1657              
1658             $y = rotate($x, $shift);
1659             $y = $x->rotate($shift); # method call
1660              
1661             =for ref
1662              
1663             Shift vector elements along with wrap.
1664              
1665             =pod
1666              
1667             Broadcasts over its inputs.
1668             Creates data-flow back and forth by default.
1669              
1670             =for bad
1671              
1672             C does not process bad values.
1673             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
1674              
1675             =cut
1676              
1677              
1678              
1679              
1680             *rotate = \&PDL::rotate;
1681              
1682              
1683              
1684              
1685              
1686              
1687             =head2 broadcastI
1688              
1689             =for sig
1690              
1691             Signature: (PARENT(); [oca]CHILD(); PDL_Indx id; PDL_Indx whichdims[])
1692             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
1693             float double ldouble cfloat cdouble cldouble)
1694              
1695             =for usage
1696              
1697             $CHILD = broadcastI($PARENT, $id, $whichdims);
1698             $CHILD = $PARENT->broadcastI($id, $whichdims); # method call
1699             $PARENT->broadcastI($id, $whichdims) .= $data; # usable as lvalue
1700              
1701             =for ref
1702              
1703             internal
1704              
1705             Put some dimensions to a broadcastid.
1706              
1707             =for example
1708              
1709             $y = $x->broadcastI(0,1,5); # broadcast over dims 1,5 in id 1
1710              
1711             =pod
1712              
1713             Does not broadcast.
1714             Makes L ndarrays.
1715             Creates data-flow back and forth by default.
1716              
1717             =for bad
1718              
1719             C does not process bad values.
1720             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
1721              
1722             =cut
1723              
1724              
1725              
1726              
1727             *broadcastI = \&PDL::broadcastI;
1728              
1729              
1730              
1731              
1732              
1733              
1734             =head2 unbroadcast
1735              
1736             =for sig
1737              
1738             Signature: (PARENT(); [oca]CHILD(); PDL_Indx atind)
1739             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
1740             float double ldouble cfloat cdouble cldouble)
1741              
1742             =for usage
1743              
1744             $CHILD = unbroadcast($PARENT, $atind);
1745             $CHILD = $PARENT->unbroadcast($atind); # method call
1746             $PARENT->unbroadcast($atind) .= $data; # usable as lvalue
1747              
1748             =for ref
1749              
1750             All broadcasted dimensions are made real again.
1751              
1752             See [TBD Doc] for details and examples.
1753              
1754             =pod
1755              
1756             Does not broadcast.
1757             Makes L ndarrays.
1758             Creates data-flow back and forth by default.
1759              
1760             =for bad
1761              
1762             C does not process bad values.
1763             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
1764              
1765             =cut
1766              
1767              
1768              
1769              
1770             *unbroadcast = \&PDL::unbroadcast;
1771              
1772              
1773              
1774              
1775              
1776             #line 1967 "lib/PDL/Slices.pd"
1777              
1778             =head2 dice
1779              
1780             =for ref
1781              
1782             Dice rows/columns/planes out of a PDL using indexes for
1783             each dimension.
1784              
1785             This function can be used to extract irregular subsets
1786             along many dimension of a PDL, e.g. only certain rows in an image,
1787             or planes in a cube. This can of course be done with
1788             the usual dimension tricks but this saves having to
1789             figure it out each time!
1790              
1791             This method is similar in functionality to the L
1792             method, but L requires that contiguous ranges or ranges
1793             with constant offset be extracted. ( i.e. L requires
1794             ranges of the form C<1,2,3,4,5> or C<2,4,6,8,10>). Because of this
1795             restriction, L is more memory efficient and slightly faster
1796             than dice
1797              
1798             =for usage
1799              
1800             $slice = $data->dice([0,2,6],[2,1,6]); # Dicing a 2-D array
1801              
1802             The arguments to dice are arrays (or 1D PDLs) for each dimension
1803             in the PDL. These arrays are used as indexes to which rows/columns/cubes,etc
1804             to dice-out (or extract) from the C<$data> PDL.
1805              
1806             Use C to select all indices along a given dimension (compare also
1807             L). As usual (in slicing methods) trailing
1808             dimensions can be omitted implying C'es for those.
1809              
1810             =for example
1811              
1812             pdl> $x = sequence(10,4)
1813             pdl> p $x
1814             [
1815             [ 0 1 2 3 4 5 6 7 8 9]
1816             [10 11 12 13 14 15 16 17 18 19]
1817             [20 21 22 23 24 25 26 27 28 29]
1818             [30 31 32 33 34 35 36 37 38 39]
1819             ]
1820             pdl> p $x->dice([1,2],[0,3]) # Select columns 1,2 and rows 0,3
1821             [
1822             [ 1 2]
1823             [31 32]
1824             ]
1825             pdl> p $x->dice(X,[0,3])
1826             [
1827             [ 0 1 2 3 4 5 6 7 8 9]
1828             [30 31 32 33 34 35 36 37 38 39]
1829             ]
1830             pdl> p $x->dice([0,2,5])
1831             [
1832             [ 0 2 5]
1833             [10 12 15]
1834             [20 22 25]
1835             [30 32 35]
1836             ]
1837              
1838             As this is an index function, any modifications to the
1839             slice will change the parent (use the C<.=> operator).
1840              
1841             =cut
1842              
1843             sub PDL::dice :lvalue {
1844              
1845             my $self = shift;
1846             my @dim_indexes = @_; # array of dimension indexes
1847              
1848             # Check that the number of dim indexes <=
1849             # number of dimensions in the PDL
1850             my $no_indexes = scalar(@dim_indexes);
1851             my $noDims = $self->getndims;
1852             barf("PDL::dice: Number of index arrays ($no_indexes) not equal to the dimensions of the PDL ($noDims")
1853             if $no_indexes > $noDims;
1854             my $index;
1855             my $pdlIndex;
1856             my $outputPDL=$self;
1857             my $indexNo = 0;
1858              
1859             # Go thru each index array and dice the input PDL:
1860             foreach $index(@dim_indexes){
1861             $outputPDL = $outputPDL->dice_axis($indexNo,$index)
1862             unless !ref $index && $index eq 'X';
1863              
1864             $indexNo++;
1865             }
1866              
1867             return $outputPDL;
1868             }
1869             *dice = \&PDL::dice;
1870              
1871             =head2 dice_axis
1872              
1873             =for ref
1874              
1875             Dice rows/columns/planes from a single PDL axis (dimension)
1876             using index along a specified axis
1877              
1878             This function can be used to extract irregular subsets
1879             along any dimension, e.g. only certain rows in an image,
1880             or planes in a cube. This can of course be done with
1881             the usual dimension tricks but this saves having to
1882             figure it out each time!
1883              
1884             =for usage
1885              
1886             $slice = $data->dice_axis($axis,$index);
1887              
1888             =for example
1889              
1890             pdl> $x = sequence(10,4)
1891             pdl> $idx = pdl(1,2)
1892             pdl> p $x->dice_axis(0,$idx) # Select columns
1893             [
1894             [ 1 2]
1895             [11 12]
1896             [21 22]
1897             [31 32]
1898             ]
1899             pdl> $t = $x->dice_axis(1,$idx) # Select rows
1900             pdl> $t.=0
1901             pdl> p $x
1902             [
1903             [ 0 1 2 3 4 5 6 7 8 9]
1904             [ 0 0 0 0 0 0 0 0 0 0]
1905             [ 0 0 0 0 0 0 0 0 0 0]
1906             [30 31 32 33 34 35 36 37 38 39]
1907             ]
1908              
1909             The trick to using this is that the index selects
1910             elements along the dimensions specified, so if you
1911             have a 2D image C will select certain C values
1912             - i.e. extract columns
1913              
1914             As this is an index function, any modifications to the
1915             slice will change the parent.
1916              
1917             =cut
1918              
1919             sub PDL::dice_axis :lvalue {
1920             my($self,$axis,$idx) = @_;
1921             my $ix = PDL->topdl($idx);
1922             barf("dice_axis: index must be <=1D") if $ix->getndims > 1;
1923             return $self->mv($axis,0)->index1d($ix)->mv(0,$axis);
1924             }
1925             *dice_axis = \&PDL::dice_axis;
1926             #line 1927 "lib/PDL/Slices.pm"
1927              
1928              
1929             =head2 slice
1930              
1931             =for sig
1932              
1933             Signature: (PARENT(); [oca]CHILD(); pdl_slice_args *arglist)
1934             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
1935             float double ldouble cfloat cdouble cldouble)
1936              
1937             =for usage
1938              
1939             $CHILD = slice($PARENT, $arglist);
1940             $CHILD = $PARENT->slice($arglist); # method call
1941              
1942             =for example
1943              
1944             $slice = $data->slice([2,3],'x',[2,2,0],"-1:1:-1", "*3");
1945              
1946             =for ref
1947              
1948             Extract rectangular slices of an ndarray, from a string specifier,
1949             an array ref specifier, or a combination.
1950              
1951             C is the main method for extracting regions of PDLs and
1952             manipulating their dimensionality. You can call it directly or
1953             via the L source prefilter that extends
1954             Perl syntax to include array slicing.
1955              
1956             C can extract regions along each dimension of a source PDL,
1957             subsample or reverse those regions, dice each dimension by selecting a
1958             list of locations along it, or basic PDL indexing routine. The
1959             selected subfield remains connected to the original PDL via dataflow.
1960             In most cases this neither allocates more memory nor slows down
1961             subsequent operations on either of the two connected PDLs.
1962              
1963             You pass in a list of arguments. Each term in the list controls
1964             the disposition of one axis of the source PDL and/or returned PDL.
1965             Each term can be a string-format cut specifier, a list ref that
1966             gives the same information without recourse to string manipulation,
1967             or a PDL with up to 1 dimension giving indices along that axis that
1968             should be selected.
1969              
1970             If you want to pass in a single string specifier for the entire
1971             operation, you can pass in a comma-delimited list as the first
1972             argument. C detects this condition and splits the string
1973             into a regular argument list. This calling style is fully
1974             backwards compatible with C calls from before PDL 2.006.
1975              
1976             B
1977              
1978             If a particular argument to C is a string, it is parsed as a
1979             selection, an affine slice, or a dummy dimension depending on the
1980             form. Leading or trailing whitespace in any part of each specifier is
1981             ignored (though it is not ignored within numbers).
1982              
1983             =over 3
1984              
1985             =item C<< '' >>, C<< : >>, or C<< X >> -- keep
1986              
1987             The empty string, C<:>, or C cause the entire corresponding
1988             dimension to be kept unchanged.
1989              
1990             =item C<< >> -- selection
1991              
1992             A single number alone causes a single index to be selected from the
1993             corresponding dimension. The dimension is kept (and reduced to size
1994             1) in the output.
1995              
1996             =item C<< () >> -- selection and collapse
1997              
1998             A single number in parenthesis causes a single index to be selected
1999             from the corresponding dimension. The dimension is discarded
2000             (completely eliminated) in the output.
2001              
2002             =item C<< : >> -- select an inclusive range
2003              
2004             Two numbers separated by a colon selects a range of values from the
2005             corresponding axis, e.g. C<< 3:4 >> selects elements 3 and 4 along the
2006             corresponding axis, and reduces that axis to size 2 in the output.
2007             Both numbers are regularized so that you can address the last element
2008             of the axis with an index of C< -1 >. If, after regularization, the
2009             two numbers are the same, then exactly one element gets selected (just
2010             like the C<< >> case). If, after regulariation, the second number
2011             is lower than the first, then the resulting slice counts down rather
2012             than up -- e.g. C<-1:0> will return the entire axis, in reversed
2013             order.
2014              
2015             =item C<< :: >> -- select a range with explicit step
2016              
2017             If you include a third parameter, it is the stride of the extracted
2018             range. For example, C<< 0:-1:2 >> will sample every other element
2019             across the complete dimension. Specifying a stride of 1 prevents
2020             autoreversal -- so to ensure that your slice is *always* forward
2021             you can specify, e.g., C<< 2:$n:1 >>. In that case, an "impossible"
2022             slice gets an Empty PDL (with 0 elements along the corresponding
2023             dimension), so you can generate an Empty PDL with a slice of the
2024             form C<< 2:1:1 >>.
2025              
2026             =item C<< * >> -- insert a dummy dimension
2027              
2028             Dummy dimensions aren't present in the original source and are
2029             "mocked up" to match dimensional slots, by repeating the data
2030             in the original PDL some number of times. An asterisk followed
2031             by a number produces a dummy dimension in the output, for
2032             example C<< *2 >> will generate a dimension of size 2 at
2033             the corresponding location in the output dim list. Omitting
2034             the number (and using just an asterisk) inserts a dummy dimension
2035             of size 1.
2036              
2037             =back
2038              
2039             B
2040              
2041             If you feed in an ARRAY ref as a slice term, then it can have
2042             0-3 elements. The first element is the start of the slice along
2043             the corresponding dim; the second is the end; and the third is
2044             the stepsize. Different combinations of inputs give the same
2045             flexibility as the string syntax.
2046              
2047             =over 3
2048              
2049             =item C<< [] >> - keep dim intact
2050              
2051             An empty ARRAY ref keeps the entire corresponding dim
2052              
2053             =item C<< [ 'X' ] >> - keep dim intact
2054              
2055             =item C<< [ '*',$n ] >> - generate a dummy dim of size $n
2056              
2057             If $n is missing, you get a dummy dim of size 1.
2058              
2059             =item C<< [ $dex, 0, 0 ] >> - collapse and discard dim
2060              
2061             C<$dex> must be a single value. It is used to index
2062             the source, and the corresponding dimension is discarded.
2063              
2064             =item C<< [ $start, $end ] >> - collect inclusive slice
2065              
2066             In the simple two-number case, you get a slice that runs
2067             up or down (as appropriate) to connect $start and $end.
2068              
2069             =item C<< [ $start, $end, $inc ] >> - collect inclusive slice
2070              
2071             The three-number case works exactly like the three-number
2072             string case above.
2073              
2074             =back
2075              
2076             B
2077              
2078             If you pass in a 0- or 1-D PDL as a slicing argument, the
2079             corresponding dimension is "diced" -- you get one position
2080             along the corresponding dim, per element of the indexing PDL,
2081             e.g. C<< $x->slice( pdl(3,4,9)) >> gives you elements 3, 4, and
2082             9 along the 0 dim of C<< $x >>.
2083              
2084             Because dicing is not an affine transformation, it is slower than
2085             direct slicing even though the syntax is convenient.
2086              
2087             =for example
2088              
2089             $x->slice('1:3'); # return the second to fourth elements of $x
2090             $x->slice('3:1'); # reverse the above
2091             $x->slice('-2:1'); # return last-but-one to second elements of $x
2092              
2093             $x->slice([1,3]); # Same as above three calls, but using array ref syntax
2094             $x->slice([3,1]);
2095             $x->slice([-2,1]);
2096              
2097             =pod
2098              
2099             Does not broadcast.
2100             Makes L ndarrays.
2101             Creates data-flow back and forth by default.
2102              
2103             =for bad
2104              
2105             C does not process bad values.
2106             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
2107              
2108             =cut
2109              
2110              
2111              
2112              
2113              
2114             #line 2285 "lib/PDL/Slices.pd"
2115             sub PDL::slice :lvalue {
2116             my ($source, @others) = @_;
2117             for my $i(0..$#others) {
2118             my $idx = $others[$i];
2119             if (ref $idx eq 'ARRAY') {
2120             my @arr = map UNIVERSAL::isa($_, 'PDL') ? $_->flat->at(0) : $_, @{$others[$i]};
2121             $others[$i] = \@arr;
2122             next;
2123             }
2124             next if !( blessed($idx) && $idx->isa('PDL') );
2125             # Deal with dicing. This is lame and slow compared to the
2126             # faster slicing, but works okay. We loop over each argument,
2127             # and if it's a PDL we dispatch it in the most straightforward
2128             # way. Single-element and zero-element PDLs are trivial and get
2129             # converted into slices for faster handling later.
2130             barf("slice: dicing parameters must be at most 1D (arg $i)\n")
2131             if $idx->ndims > 1;
2132             my $nlm = $idx->nelem;
2133             if($nlm > 1) {
2134             #### More than one element - we have to dice (darn it).
2135             $source = $source->mv($i,0)->index1d($idx)->mv(0,$i);
2136             $others[$i] = '';
2137             }
2138             elsif($nlm) {
2139             #### One element - convert to a regular slice.
2140             $others[$i] = $idx->flat->at(0);
2141             }
2142             else {
2143             #### Zero elements -- force an extended empty.
2144             $others[$i] = "1:0:1";
2145             }
2146             }
2147             PDL::_slice_int($source,my $o=$source->initialize,\@others);
2148             $o;
2149             }
2150             #line 2151 "lib/PDL/Slices.pm"
2151              
2152             *slice = \&PDL::slice;
2153              
2154              
2155              
2156              
2157              
2158              
2159             =head2 diagonal
2160              
2161             =for sig
2162              
2163             Signature: (PARENT(); [oca]CHILD(); PDL_Indx whichdims[])
2164             Types: (sbyte byte short ushort long ulong indx ulonglong longlong
2165             float double ldouble cfloat cdouble cldouble)
2166              
2167             =for ref
2168              
2169             Returns the multidimensional diagonal over the specified dimensions.
2170              
2171             The diagonal is placed at the first (by number) dimension that is
2172             diagonalized.
2173             The other diagonalized dimensions are removed. So if C<$x> has dimensions
2174             C<(5,3,5,4,6,5)> then after
2175              
2176             =for usage
2177              
2178             $d = $x->diagonal(dim1, dim2,...)
2179              
2180             =for example
2181              
2182             $y = $x->diagonal(0,2,5);
2183              
2184             the ndarray C<$y> has dimensions C<(5,3,4,6)> and
2185             C<$y-Eat(2,1,0,1)> refers
2186             to C<$x-Eat(2,1,2,0,1,2)>.
2187              
2188             NOTE: diagonal doesn't handle broadcastids correctly. XXX FIX
2189              
2190             pdl> $x = zeroes(3,3,3);
2191             pdl> ($y = $x->diagonal(0,1))++;
2192             pdl> p $x
2193             [
2194             [
2195             [1 0 0]
2196             [0 1 0]
2197             [0 0 1]
2198             ]
2199             [
2200             [1 0 0]
2201             [0 1 0]
2202             [0 0 1]
2203             ]
2204             [
2205             [1 0 0]
2206             [0 1 0]
2207             [0 0 1]
2208             ]
2209             ]
2210              
2211             =pod
2212              
2213             Does not broadcast.
2214             Makes L ndarrays.
2215             Creates data-flow back and forth by default.
2216              
2217             =for bad
2218              
2219             C does not process bad values.
2220             It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
2221              
2222             =cut
2223              
2224              
2225              
2226              
2227              
2228             #line 2500 "lib/PDL/Slices.pd"
2229             sub PDL::diagonal :lvalue { shift->_diagonal_int(my $o=PDL->null, \@_); $o }
2230             #line 2231 "lib/PDL/Slices.pm"
2231              
2232             *diagonal = \&PDL::diagonal;
2233              
2234              
2235              
2236              
2237              
2238              
2239              
2240             #line 2550 "lib/PDL/Slices.pd"
2241              
2242             =head1 BUGS
2243              
2244             For the moment, you can't slice one of the zero-length dims of an
2245             empty ndarray. It is not clear how to implement this in a way that makes
2246             sense.
2247              
2248             Many types of index errors are reported far from the indexing
2249             operation that caused them. This is caused by the underlying architecture:
2250             slice() sets up a mapping between variables, but that mapping isn't
2251             tested for correctness until it is used (potentially much later).
2252              
2253             =head1 AUTHOR
2254              
2255             Copyright (C) 1997 Tuomas J. Lukka. Contributions by
2256             Craig DeForest, deforest@boulder.swri.edu.
2257             Documentation contributions by David Mertens.
2258             All rights reserved. There is no warranty. You are allowed
2259             to redistribute this software / documentation under certain
2260             conditions. For details, see the file COPYING in the PDL
2261             distribution. If this file is separated from the PDL distribution,
2262             the copyright notice should be included in the file.
2263              
2264             =cut
2265             #line 2266 "lib/PDL/Slices.pm"
2266              
2267             # Exit with OK status
2268              
2269             1;