1Slices(3)             User Contributed Perl Documentation            Slices(3)
2
3
4

NAME

6       PDL::Slices -- Indexing, slicing, and dicing
7

SYNOPSIS

9         use PDL;
10         $x = ones(3,3);
11         $y = $x->slice('-1:0,(1)');
12         $c = $x->dummy(2);
13

DESCRIPTION

15       This package provides many of the powerful PerlDL core index
16       manipulation routines.  These routines mostly allow two-way data flow,
17       so you can modify your data in the most convenient representation.  For
18       example, you can make a 1000x1000 unit matrix with
19
20        $x = zeroes(1000,1000);
21        $x->diagonal(0,1) ++;
22
23       which is quite efficient. See PDL::Indexing and PDL::Tips for more
24       examples.
25
26       Slicing is so central to the PDL language that a special compile-time
27       syntax has been introduced to handle it compactly; see PDL::NiceSlice
28       for details.
29
30       PDL indexing and slicing functions usually include two-way data flow,
31       so that you can separate the actions of reshaping your data structures
32       and modifying the data themselves.  Two special methods, "copy" and
33       "sever", help you control the data flow connection between related
34       variables.
35
36        $y = $x->slice("1:3"); # Slice maintains a link between $x and $y.
37        $y += 5;               # $x is changed!
38
39       If you want to force a physical copy and no data flow, you can copy or
40       sever the slice expression:
41
42        $y = $x->slice("1:3")->copy;
43        $y += 5;               # $x is not changed.
44
45        $y = $x->slice("1:3")->sever;
46        $y += 5;               # $x is not changed.
47
48       The difference between "sever" and "copy" is that sever acts on (and
49       returns) its argument, while copy produces a disconnected copy.  If you
50       say
51
52        $y = $x->slice("1:3");
53        $c = $y->sever;
54
55       then the variables $y and $c point to the same object but with "->copy"
56       they would not.
57

FUNCTIONS

59   s_identity
60         Signature: (P(); C())
61
62       Internal vaffine identity function.
63
64       s_identity processes bad values.  It will set the bad-value flag of all
65       output piddles if the flag is set for any of the input piddles.
66
67   index
68         Signature: (a(n); indx ind(); [oca] c())
69
70       "index", "index1d", and "index2d" provide rudimentary index
71       indirection.
72
73        $c = index($source,$ind);
74        $c = index1d($source,$ind);
75        $c = index2d($source2,$ind1,$ind2);
76
77       use the $ind variables as indices to look up values in $source.  The
78       three routines thread slightly differently.
79
80       •  "index" uses direct threading for 1-D indexing across the 0 dim of
81          $source.  It can thread over source thread dims or index thread
82          dims, but not (easily) both: If $source has more than 1 dimension
83          and $ind has more than 0 dimensions, they must agree in a threading
84          sense.
85
86       •  "index1d" uses a single active dim in $ind to produce a list of
87          indexed values in the 0 dim of the output - it is useful for
88          collapsing $source by indexing with a single row of values along
89          $source's 0 dimension.  The output has the same number of dims as
90          $source.  The 0 dim of the output has size 1 if $ind is a scalar,
91          and the same size as the 0 dim of $ind if it is not. If $ind and
92          $source both have more than 1 dim, then all dims higher than 0 must
93          agree in a threading sense.
94
95       •  "index2d" works like "index" but uses separate piddles for X and Y
96          coordinates.  For more general N-dimensional indexing, see the
97          PDL::NiceSlice syntax or PDL::Slices (in particular "slice",
98          "indexND", and "range").
99
100       These functions are two-way, i.e. after
101
102        $c = $x->index(pdl[0,5,8]);
103        $c .= pdl [0,2,4];
104
105       the changes in $c will flow back to $x.
106
107       "index" provids simple threading:  multiple-dimensioned arrays are
108       treated as collections of 1-D arrays, so that
109
110        $x = xvals(10,10)+10*yvals(10,10);
111        $y = $x->index(3);
112        $c = $x->index(9-xvals(10));
113
114       puts a single column from $x into $y, and puts a single element from
115       each column of $x into $c.  If you want to extract multiple columns
116       from an array in one operation, see "dice" or "indexND".
117
118       index barfs if any of the index values are bad.
119
120   index1d
121         Signature: (a(n); indx ind(m); [oca] c(m))
122
123       "index", "index1d", and "index2d" provide rudimentary index
124       indirection.
125
126        $c = index($source,$ind);
127        $c = index1d($source,$ind);
128        $c = index2d($source2,$ind1,$ind2);
129
130       use the $ind variables as indices to look up values in $source.  The
131       three routines thread slightly differently.
132
133       •  "index" uses direct threading for 1-D indexing across the 0 dim of
134          $source.  It can thread over source thread dims or index thread
135          dims, but not (easily) both: If $source has more than 1 dimension
136          and $ind has more than 0 dimensions, they must agree in a threading
137          sense.
138
139       •  "index1d" uses a single active dim in $ind to produce a list of
140          indexed values in the 0 dim of the output - it is useful for
141          collapsing $source by indexing with a single row of values along
142          $source's 0 dimension.  The output has the same number of dims as
143          $source.  The 0 dim of the output has size 1 if $ind is a scalar,
144          and the same size as the 0 dim of $ind if it is not. If $ind and
145          $source both have more than 1 dim, then all dims higher than 0 must
146          agree in a threading sense.
147
148       •  "index2d" works like "index" but uses separate piddles for X and Y
149          coordinates.  For more general N-dimensional indexing, see the
150          PDL::NiceSlice syntax or PDL::Slices (in particular "slice",
151          "indexND", and "range").
152
153       These functions are two-way, i.e. after
154
155        $c = $x->index(pdl[0,5,8]);
156        $c .= pdl [0,2,4];
157
158       the changes in $c will flow back to $x.
159
160       "index" provids simple threading:  multiple-dimensioned arrays are
161       treated as collections of 1-D arrays, so that
162
163        $x = xvals(10,10)+10*yvals(10,10);
164        $y = $x->index(3);
165        $c = $x->index(9-xvals(10));
166
167       puts a single column from $x into $y, and puts a single element from
168       each column of $x into $c.  If you want to extract multiple columns
169       from an array in one operation, see "dice" or "indexND".
170
171       index1d propagates BAD index elements to the output variable.
172
173   index2d
174         Signature: (a(na,nb); indx inda(); indx indb(); [oca] c())
175
176       "index", "index1d", and "index2d" provide rudimentary index
177       indirection.
178
179        $c = index($source,$ind);
180        $c = index1d($source,$ind);
181        $c = index2d($source2,$ind1,$ind2);
182
183       use the $ind variables as indices to look up values in $source.  The
184       three routines thread slightly differently.
185
186       •  "index" uses direct threading for 1-D indexing across the 0 dim of
187          $source.  It can thread over source thread dims or index thread
188          dims, but not (easily) both: If $source has more than 1 dimension
189          and $ind has more than 0 dimensions, they must agree in a threading
190          sense.
191
192       •  "index1d" uses a single active dim in $ind to produce a list of
193          indexed values in the 0 dim of the output - it is useful for
194          collapsing $source by indexing with a single row of values along
195          $source's 0 dimension.  The output has the same number of dims as
196          $source.  The 0 dim of the output has size 1 if $ind is a scalar,
197          and the same size as the 0 dim of $ind if it is not. If $ind and
198          $source both have more than 1 dim, then all dims higher than 0 must
199          agree in a threading sense.
200
201       •  "index2d" works like "index" but uses separate piddles for X and Y
202          coordinates.  For more general N-dimensional indexing, see the
203          PDL::NiceSlice syntax or PDL::Slices (in particular "slice",
204          "indexND", and "range").
205
206       These functions are two-way, i.e. after
207
208        $c = $x->index(pdl[0,5,8]);
209        $c .= pdl [0,2,4];
210
211       the changes in $c will flow back to $x.
212
213       "index" provids simple threading:  multiple-dimensioned arrays are
214       treated as collections of 1-D arrays, so that
215
216        $x = xvals(10,10)+10*yvals(10,10);
217        $y = $x->index(3);
218        $c = $x->index(9-xvals(10));
219
220       puts a single column from $x into $y, and puts a single element from
221       each column of $x into $c.  If you want to extract multiple columns
222       from an array in one operation, see "dice" or "indexND".
223
224       index2d barfs if either of the index values are bad.
225
226   indexNDb
227         Backwards-compatibility alias for indexND
228
229   indexND
230         Find selected elements in an N-D piddle, with optional boundary handling
231
232         $out = $source->indexND( $index, [$method] )
233
234         $source = 10*xvals(10,10) + yvals(10,10);
235         $index  = pdl([[2,3],[4,5]],[[6,7],[8,9]]);
236         print $source->indexND( $index );
237
238         [
239          [23 45]
240          [67 89]
241         ]
242
243       IndexND collapses $index by lookup into $source.  The 0th dimension of
244       $index is treated as coordinates in $source, and the return value has
245       the same dimensions as the rest of $index.  The returned elements are
246       looked up from $source.  Dataflow works -- propagated assignment flows
247       back into $source.
248
249       IndexND and IndexNDb were originally separate routines but they are
250       both now implemented as a call to "range", and have identical syntax to
251       one another.
252
253   rangeb
254         Signature: (P(); C(); SV *index; SV *size; SV *boundary)
255
256       Engine for "range"
257
258       Same calling convention as "range", but you must supply all parameters.
259       "rangeb" is marginally faster as it makes a direct PP call, avoiding
260       the perl argument-parsing step.
261
262   range
263       Extract selected chunks from a source piddle, with boundary conditions
264
265               $out = $source->range($index,[$size,[$boundary]])
266
267       Returns elements or rectangular slices of the original piddle, indexed
268       by the $index piddle.  $source is an N-dimensional piddle, and $index
269       is a piddle whose first dimension has size up to N.  Each row of $index
270       is treated as coordinates of a single value or chunk from $source,
271       specifying the location(s) to extract.
272
273       If you specify a single index location, then range is essentially an
274       expensive slice, with controllable boundary conditions.
275
276       INPUTS
277
278       $index and $size can be piddles or array refs such as you would feed to
279       zeroes and its ilk.  If $index's 0th dimension has size higher than the
280       number of dimensions in $source, then $source is treated as though it
281       had trivial dummy dimensions of size 1, up to the required size to be
282       indexed by $index -- so if your source array is 1-D and your index
283       array is a list of 3-vectors, you get two dummy dimensions of size 1 on
284       the end of your source array.
285
286       You can extract single elements or N-D rectangular ranges from $source,
287       by setting $size.  If $size is undef or zero, then you get a single
288       sample for each row of $index.  This behavior is similar to "indexNDb",
289       which is in fact implemented as a call to "range".
290
291       If $size is positive then you get a range of values from $source at
292       each location, and the output has extra dimensions allocated for them.
293       $size can be a scalar, in which case it applies to all dimensions, or
294       an N-vector, in which case each element is applied independently to the
295       corresponding dimension in $source.  See below for details.
296
297       $boundary is a number, string, or list ref indicating the type of
298       boundary conditions to use when ranges reach the edge of $source.  If
299       you specify no boundary conditions the default is to forbid boundary
300       violations on all axes.  If you specify exactly one boundary condition,
301       it applies to all axes.  If you specify more (as elements of a list
302       ref, or as a packed string, see below), then they apply to dimensions
303       in the order in which they appear, and the last one applies to all
304       subsequent dimensions.  (This is less difficult than it sounds; see the
305       examples below).
306
307       0 (synonyms: 'f','forbid') (default)
308          Ranges are not allowed to cross the boundary of the original PDL.
309          Disallowed ranges throw an error.  The errors are thrown at
310          evaluation time, not at the time of the range call (this is the same
311          behavior as "slice").
312
313       1 (synonyms: 't','truncate')
314          Values outside the original piddle get BAD if you've got bad value
315          support compiled into your PDL and set the badflag for the source
316          PDL; or 0 if you haven't (you must set the badflag if you want BADs
317          for out of bound values, otherwise you get 0).  Reverse dataflow
318          works OK for the portion of the child that is in-bounds.  The out-
319          of-bounds part of the child is reset to (BAD|0) during each dataflow
320          operation, but execution continues.
321
322       2 (synonyms: 'e','x','extend')
323          Values that would be outside the original piddle point instead to
324          the nearest allowed value within the piddle.  See the CAVEAT below
325          on mappings that are not single valued.
326
327       3 (synonyms: 'p','periodic')
328          Periodic boundary conditions apply: the numbers in $index are
329          applied, strict-modulo the corresponding dimensions of $source.
330          This is equivalent to duplicating the $source piddle throughout N-D
331          space.  See the CAVEAT below about mappings that are not single
332          valued.
333
334       4 (synonyms: 'm','mirror')
335          Mirror-reflection periodic boundary conditions apply.  See the
336          CAVEAT below about mappings that are not single valued.
337
338       The boundary condition identifiers all begin with unique characters, so
339       you can feed in multiple boundary conditions as either a list ref or a
340       packed string.  (The packed string is marginally faster to run).  For
341       example, the four expressions [0,1], ['forbid','truncate'], ['f','t'],
342       and 'ft' all specify that violating the boundary in the 0th dimension
343       throws an error, and all other dimensions get truncated.
344
345       If you feed in a single string, it is interpreted as a packed boundary
346       array if all of its characters are valid boundary specifiers (e.g.
347       'pet'), but as a single word-style specifier if they are not (e.g.
348       'forbid').
349
350       OUTPUT
351
352       The output threads over both $index and $source.  Because implicit
353       threading can happen in a couple of ways, a little thought is needed.
354       The returned dimension list is stacked up like this:
355
356          (index thread dims), (index dims (size)), (source thread dims)
357
358       The first few dims of the output correspond to the extra dims of $index
359       (beyond the 0 dim). They allow you to pick out individual ranges from a
360       large, threaded collection.
361
362       The middle few dims of the output correspond to the size dims specified
363       in $size, and contain the range of values that is extracted at each
364       location in $source.  Every nonzero element of $size is copied to the
365       dimension list here, so that if you feed in (for example) "$size =
366       [2,0,1]" you get an index dim list of "(2,1)".
367
368       The last few dims of the output correspond to extra dims of $source
369       beyond the number of dims indexed by $index.  These dims act like
370       ordinary thread dims, because adding more dims to $source just tacks
371       extra dims on the end of the output.  Each source thread dim ranges
372       over the entire corresponding dim of $source.
373
374       Dataflow: Dataflow is bidirectional.
375
376       Examples: Here are basic examples of "range" operation, showing how to
377       get ranges out of a small matrix.  The first few examples show
378       extraction and selection of individual chunks.  The last example shows
379       how to mark loci in the original matrix (using dataflow).
380
381        pdl> $src = 10*xvals(10,5)+yvals(10,5)
382        pdl> print $src->range([2,3])    # Cut out a single element
383        23
384        pdl> print $src->range([2,3],1)  # Cut out a single 1x1 block
385        [
386         [23]
387        ]
388        pdl> print $src->range([2,3], [2,1]) # Cut a 2x1 chunk
389        [
390         [23 33]
391        ]
392        pdl> print $src->range([[2,3]],[2,1]) # Trivial list of 1 chunk
393        [
394         [
395          [23]
396          [33]
397         ]
398        ]
399        pdl> print $src->range([[2,3],[0,1]], [2,1])   # two 2x1 chunks
400        [
401         [
402          [23  1]
403          [33 11]
404         ]
405        ]
406        pdl> # A 2x2 collection of 2x1 chunks
407        pdl> print $src->range([[[1,1],[2,2]],[[2,3],[0,1]]],[2,1])
408        [
409         [
410          [
411           [11 22]
412           [23  1]
413          ]
414          [
415           [21 32]
416           [33 11]
417          ]
418         ]
419        ]
420        pdl> $src = xvals(5,3)*10+yvals(5,3)
421        pdl> print $src->range(3,1)  # Thread over y dimension in $src
422        [
423         [30]
424         [31]
425         [32]
426        ]
427
428        pdl> $src = zeroes(5,4);
429        pdl> $src->range(pdl([2,3],[0,1]),pdl(2,1)) .= xvals(2,2,1) + 1
430        pdl> print $src
431        [
432         [0 0 0 0 0]
433         [2 2 0 0 0]
434         [0 0 0 0 0]
435         [0 0 1 1 0]
436        ]
437
438       CAVEAT: It's quite possible to select multiple ranges that intersect.
439       In that case, modifying the ranges doesn't have a guaranteed result in
440       the original PDL -- the result is an arbitrary choice among the valid
441       values.  For some things that's OK; but for others it's not. In
442       particular, this doesn't work:
443
444           pdl> $photon_list = new PDL::RandVar->sample(500)->reshape(2,250)*10
445           pdl> histogram = zeroes(10,10)
446           pdl> histogram->range($photon_list,1)++;  #not what you wanted
447
448       The reason is that if two photons land in the same bin, then that bin
449       doesn't get incremented twice.  (That may get fixed in a later
450       version...)
451
452       PERMISSIVE RANGING: If $index has too many dimensions compared to
453       $source, then $source is treated as though it had dummy dimensions of
454       size 1, up to the required number of dimensions.  These virtual dummy
455       dimensions have the usual boundary conditions applied to them.
456
457       If the 0 dimension of $index is ludicrously large (if its size is more
458       than 5 greater than the number of dims in the source PDL) then range
459       will insist that you specify a size in every dimension, to make sure
460       that you know what you're doing.  That catches a common error with
461       range usage: confusing the initial dim (which is usually small) with
462       another index dim (perhaps of size 1000).
463
464       If the index variable is Empty, then range() always returns the Empty
465       PDL.  If the index variable is not Empty, indexing it always yields a
466       boundary violation.  All non-barfing conditions are treated as
467       truncation, since there are no actual data to return.
468
469       EFFICIENCY: Because "range" isn't an affine transformation (it involves
470       lookup into a list of N-D indices), it is somewhat memory-inefficient
471       for long lists of ranges, and keeping dataflow open is much slower than
472       for affine transformations (which don't have to copy data around).
473
474       Doing operations on small subfields of a large range is inefficient
475       because the engine must flow the entire range back into the original
476       PDL with every atomic perl operation, even if you only touch a single
477       element.  One way to speed up such code is to sever your range, so that
478       PDL doesn't have to copy the data with each operation, then copy the
479       elements explicitly at the end of your loop.  Here's an example that
480       labels each region in a range sequentially, using many small operations
481       rather than a single xvals assignment:
482
483         ### How to make a collection of small ops run fast with range...
484         $x =  $data->range($index, $sizes, $bound)->sever;
485         $aa = $data->range($index, $sizes, $bound);
486         map { $x($_ - 1) .= $_; } (1..$x->nelem);    # Lots of little ops
487         $aa .= $x;
488
489       "range" is a perl front-end to a PP function, "rangeb".  Calling
490       "rangeb" is marginally faster but requires that you include all
491       arguments.
492
493       DEVEL NOTES
494
495       * index thread dimensions are effectively clumped internally.  This
496       makes it easier to loop over the index array but a little more brain-
497       bending to tease out the algorithm.
498
499       rangeb processes bad values.  It will set the bad-value flag of all
500       output piddles if the flag is set for any of the input piddles.
501
502   rld
503         Signature: (indx a(n); b(n); [o]c(m))
504
505       Run-length decode a vector
506
507       Given a vector $x of the numbers of instances of values $y, run-length
508       decode to $c.
509
510        rld($x,$y,$c=null);
511
512       rld does not process bad values.  It will set the bad-value flag of all
513       output piddles if the flag is set for any of the input piddles.
514
515   rle
516         Signature: (c(n); indx [o]a(m); [o]b(m))
517
518       Run-length encode a vector
519
520       Given vector $c, generate a vector $x with the number of each element,
521       and a vector $y of the unique values.  New in PDL 2.017, only the
522       elements up to the first instance of 0 in $x are returned, which makes
523       the common use case of a 1-dimensional $c simpler.  For threaded
524       operation, $x and $y will be large enough to hold the largest row of
525       $y, and only the elements up to the first instance of 0 in each row of
526       $x should be considered.
527
528        $c = floor(4*random(10));
529        rle($c,$x=null,$y=null);
530        #or
531        ($x,$y) = rle($c);
532
533        #for $c of shape [10, 4]:
534        $c = floor(4*random(10,4));
535        ($x,$y) = rle($c);
536
537        #to see the results of each row one at a time:
538        foreach (0..$c->dim(1)-1){
539         my ($as,$bs) = ($x(:,($_)),$y(:,($_)));
540         my ($ta,$tb) = where($as,$bs,$as!=0); #only the non-zero elements of $x
541         print $c(:,($_)) . " rle==> " , ($ta,$tb) , "\trld==> " . rld($ta,$tb) . "\n";
542        }
543
544       rle does not process bad values.  It will set the bad-value flag of all
545       output piddles if the flag is set for any of the input piddles.
546
547   xchg
548         Signature: (P(); C(); int n1; int n2)
549
550       exchange two dimensions
551
552       Negative dimension indices count from the end.
553
554       The command
555
556        $y = $x->xchg(2,3);
557
558       creates $y to be like $x except that the dimensions 2 and 3 are
559       exchanged with each other i.e.
560
561        $y->at(5,3,2,8) == $x->at(5,3,8,2)
562
563       xchg does not process bad values.  It will set the bad-value flag of
564       all output piddles if the flag is set for any of the input piddles.
565
566   reorder
567       Re-orders the dimensions of a PDL based on the supplied list.
568
569       Similar to the "xchg" method, this method re-orders the dimensions of a
570       PDL. While the "xchg" method swaps the position of two dimensions, the
571       reorder method can change the positions of many dimensions at once.
572
573        # Completely reverse the dimension order of a 6-Dim array.
574        $reOrderedPDL = $pdl->reorder(5,4,3,2,1,0);
575
576       The argument to reorder is an array representing where the current
577       dimensions should go in the new array. In the above usage, the argument
578       to reorder "(5,4,3,2,1,0)" indicates that the old dimensions ($pdl's
579       dims) should be re-arranged to make the new pdl ($reOrderPDL) according
580       to the following:
581
582          Old Position   New Position
583          ------------   ------------
584          5              0
585          4              1
586          3              2
587          2              3
588          1              4
589          0              5
590
591       You do not need to specify all dimensions, only a complete set starting
592       at position 0.  (Extra dimensions are left where they are).  This
593       means, for example, that you can reorder() the X and Y dimensions of an
594       image, and not care whether it is an RGB image with a third dimension
595       running across color plane.
596
597       Example:
598
599        pdl> $x = sequence(5,3,2);       # Create a 3-d Array
600        pdl> p $x
601        [
602         [
603          [ 0  1  2  3  4]
604          [ 5  6  7  8  9]
605          [10 11 12 13 14]
606         ]
607         [
608          [15 16 17 18 19]
609          [20 21 22 23 24]
610          [25 26 27 28 29]
611         ]
612        ]
613        pdl> p $x->reorder(2,1,0); # Reverse the order of the 3-D PDL
614        [
615         [
616          [ 0 15]
617          [ 5 20]
618          [10 25]
619         ]
620         [
621          [ 1 16]
622          [ 6 21]
623          [11 26]
624         ]
625         [
626          [ 2 17]
627          [ 7 22]
628          [12 27]
629         ]
630         [
631          [ 3 18]
632          [ 8 23]
633          [13 28]
634         ]
635         [
636          [ 4 19]
637          [ 9 24]
638          [14 29]
639         ]
640        ]
641
642       The above is a simple example that could be duplicated by calling
643       "$x->xchg(0,2)", but it demonstrates the basic functionality of
644       reorder.
645
646       As this is an index function, any modifications to the result PDL will
647       change the parent.
648
649   mv
650         Signature: (P(); C(); int n1; int n2)
651
652       move a dimension to another position
653
654       The command
655
656        $y = $x->mv(4,1);
657
658       creates $y to be like $x except that the dimension 4 is moved to the
659       place 1, so:
660
661        $y->at(1,2,3,4,5,6) == $x->at(1,5,2,3,4,6);
662
663       The other dimensions are moved accordingly.  Negative dimension indices
664       count from the end.
665
666       mv does not process bad values.  It will set the bad-value flag of all
667       output piddles if the flag is set for any of the input piddles.
668
669   oslice
670         Signature: (P(); C(); char* str)
671
672       DEPRECATED:  'oslice' is the original 'slice' routine in pre-2.006_006
673       versions of PDL.  It is left here for reference but will disappear in
674       PDL 3.000
675
676       Extract a rectangular slice of a piddle, from a string specifier.
677
678       "slice" was the original Swiss-army-knife PDL indexing routine, but is
679       largely superseded by the NiceSlice source prefilter and its associated
680       nslice method.  It is still used as the basic underlying slicing engine
681       for nslice, and is especially useful in particular niche applications.
682
683        $x->slice('1:3');  #  return the second to fourth elements of $x
684        $x->slice('3:1');  #  reverse the above
685        $x->slice('-2:1'); #  return last-but-one to second elements of $x
686
687       The argument string is a comma-separated list of what to do for each
688       dimension. The current formats include the following, where a, b and c
689       are integers and can take legal array index values (including -1 etc):
690
691       :       takes the whole dimension intact.
692
693       ''      (nothing) is a synonym for ":" (This means that
694               "$x->slice(':,3')" is equal to "$x->slice(',3')").
695
696       a       slices only this value out of the corresponding dimension.
697
698       (a)     means the same as "a" by itself except that the resulting
699               dimension of length one is deleted (so if $x has dims "(3,4,5)"
700               then "$x->slice(':,(2),:')" has dimensions "(3,5)" whereas
701               "$x->slice(':,2,:')" has dimensions "(3,1,5))".
702
703       a:b     slices the range a to b inclusive out of the dimension.
704
705       a:b:c   slices the range a to b, with step c (i.e. "3:7:2" gives the
706               indices "(3,5,7)"). This may be confusing to Matlab users but
707               several other packages already use this syntax.
708
709       '*'     inserts an extra dimension of width 1 and
710
711       '*a'    inserts an extra (dummy) dimension of width a.
712
713       An extension is planned for a later stage allowing
714       "$x->slice('(=1),(=1|5:8),3:6(=1),4:6')" to express a multidimensional
715       diagonal of $x.
716
717       Trivial out-of-bounds slicing is allowed: if you slice a source
718       dimension that doesn't exist, but only index the 0th element, then
719       "slice" treats the source as if there were a dummy dimension there.
720       The following are all equivalent:
721
722               xvals(5)->dummy(1,1)->slice('(2),0')  # Add dummy dim, then slice
723               xvals(5)->slice('(2),0')              # Out-of-bounds slice adds dim.
724               xvals(5)->slice((2),0)                # NiceSlice syntax
725               xvals(5)->((2))->dummy(0,1)           # NiceSlice syntax
726
727       This is an error:
728
729               xvals(5)->slice('(2),1')        # nontrivial out-of-bounds slice dies
730
731       Because slicing doesn't directly manipulate the source and destination
732       pdl -- it just sets up a transformation between them -- indexing errors
733       often aren't reported until later.  This is either a bug or a feature,
734       depending on whether you prefer error-reporting clarity or speed of
735       execution.
736
737       oslice does not process bad values.  It will set the bad-value flag of
738       all output piddles if the flag is set for any of the input piddles.
739
740   using
741       Returns array of column numbers requested
742
743        line $pdl->using(1,2);
744
745       Plot, as a line, column 1 of $pdl vs. column 2
746
747        pdl> $pdl = rcols("file");
748        pdl> line $pdl->using(1,2);
749
750   diagonalI
751         Signature: (P(); C(); SV *list)
752
753       Returns the multidimensional diagonal over the specified dimensions.
754
755       The diagonal is placed at the first (by number) dimension that is
756       diagonalized.  The other diagonalized dimensions are removed. So if $x
757       has dimensions "(5,3,5,4,6,5)" then after
758
759        $y = $x->diagonal(0,2,5);
760
761       the piddle $y has dimensions "(5,3,4,6)" and "$y->at(2,1,0,1)" refers
762       to "$x->at(2,1,2,0,1,2)".
763
764       NOTE: diagonal doesn't handle threadids correctly. XXX FIX
765
766       diagonalI does not process bad values.  It will set the bad-value flag
767       of all output piddles if the flag is set for any of the input piddles.
768
769   lags
770         Signature: (P(); C(); int nthdim; int step; int n)
771
772       Returns a piddle of lags to parent.
773
774       Usage:
775
776         $lags = $x->lags($nthdim,$step,$nlags);
777
778       I.e. if $x contains
779
780        [0,1,2,3,4,5,6,7]
781
782       then
783
784        $y = $x->lags(0,2,2);
785
786       is a (5,2) matrix
787
788        [2,3,4,5,6,7]
789        [0,1,2,3,4,5]
790
791       This order of returned indices is kept because the function is called
792       "lags" i.e. the nth lag is n steps behind the original.
793
794       $step and $nlags must be positive. $nthdim can be negative and will
795       then be counted from the last dim backwards in the usual way (-1 = last
796       dim).
797
798       lags does not process bad values.  It will set the bad-value flag of
799       all output piddles if the flag is set for any of the input piddles.
800
801   splitdim
802         Signature: (P(); C(); int nthdim; int nsp)
803
804       Splits a dimension in the parent piddle (opposite of clump)
805
806       After
807
808        $y = $x->splitdim(2,3);
809
810       the expression
811
812        $y->at(6,4,m,n,3,6) == $x->at(6,4,m+3*n)
813
814       is always true ("m" has to be less than 3).
815
816       splitdim does not process bad values.  It will set the bad-value flag
817       of all output piddles if the flag is set for any of the input piddles.
818
819   rotate
820         Signature: (x(n); indx shift(); [oca]y(n))
821
822       Shift vector elements along with wrap. Flows data back&forth.
823
824       rotate does not process bad values.  It will set the bad-value flag of
825       all output piddles if the flag is set for any of the input piddles.
826
827   threadI
828         Signature: (P(); C(); int id; SV *list)
829
830       internal
831
832       Put some dimensions to a threadid.
833
834        $y = $x->threadI(0,1,5); # thread over dims 1,5 in id 1
835
836       threadI does not process bad values.  It will set the bad-value flag of
837       all output piddles if the flag is set for any of the input piddles.
838
839   identvaff
840         Signature: (P(); C())
841
842       A vaffine identity transformation (includes thread_id copying).
843
844       Mainly for internal use.
845
846       identvaff does not process bad values.  It will set the bad-value flag
847       of all output piddles if the flag is set for any of the input piddles.
848
849   unthread
850         Signature: (P(); C(); int atind)
851
852       All threaded dimensions are made real again.
853
854       See [TBD Doc] for details and examples.
855
856       unthread does not process bad values.  It will set the bad-value flag
857       of all output piddles if the flag is set for any of the input piddles.
858
859   dice
860       Dice rows/columns/planes out of a PDL using indexes for each dimension.
861
862       This function can be used to extract irregular subsets along many
863       dimension of a PDL, e.g. only certain rows in an image, or planes in a
864       cube. This can of course be done with the usual dimension tricks but
865       this saves having to figure it out each time!
866
867       This method is similar in functionality to the "slice" method, but
868       "slice" requires that contiguous ranges or ranges with constant offset
869       be extracted. ( i.e. "slice" requires ranges of the form "1,2,3,4,5" or
870       "2,4,6,8,10"). Because of this restriction, "slice" is more memory
871       efficient and slightly faster than dice
872
873        $slice = $data->dice([0,2,6],[2,1,6]); # Dicing a 2-D array
874
875       The arguments to dice are arrays (or 1D PDLs) for each dimension in the
876       PDL. These arrays are used as indexes to which rows/columns/cubes,etc
877       to dice-out (or extract) from the $data PDL.
878
879       Use "X" to select all indices along a given dimension (compare also
880       mslice). As usual (in slicing methods) trailing dimensions can be
881       omitted implying "X"'es for those.
882
883        pdl> $x = sequence(10,4)
884        pdl> p $x
885        [
886         [ 0  1  2  3  4  5  6  7  8  9]
887         [10 11 12 13 14 15 16 17 18 19]
888         [20 21 22 23 24 25 26 27 28 29]
889         [30 31 32 33 34 35 36 37 38 39]
890        ]
891        pdl> p $x->dice([1,2],[0,3]) # Select columns 1,2 and rows 0,3
892        [
893         [ 1  2]
894         [31 32]
895        ]
896        pdl> p $x->dice(X,[0,3])
897        [
898         [ 0  1  2  3  4  5  6  7  8  9]
899         [30 31 32 33 34 35 36 37 38 39]
900        ]
901        pdl> p $x->dice([0,2,5])
902        [
903         [ 0  2  5]
904         [10 12 15]
905         [20 22 25]
906         [30 32 35]
907        ]
908
909       As this is an index function, any modifications to the slice will
910       change the parent (use the ".=" operator).
911
912   dice_axis
913       Dice rows/columns/planes from a single PDL axis (dimension) using index
914       along a specified axis
915
916       This function can be used to extract irregular subsets along any
917       dimension, e.g. only certain rows in an image, or planes in a cube.
918       This can of course be done with the usual dimension tricks but this
919       saves having to figure it out each time!
920
921        $slice = $data->dice_axis($axis,$index);
922
923        pdl> $x = sequence(10,4)
924        pdl> $idx = pdl(1,2)
925        pdl> p $x->dice_axis(0,$idx) # Select columns
926        [
927         [ 1  2]
928         [11 12]
929         [21 22]
930         [31 32]
931        ]
932        pdl> $t = $x->dice_axis(1,$idx) # Select rows
933        pdl> $t.=0
934        pdl> p $x
935        [
936         [ 0  1  2  3  4  5  6  7  8  9]
937         [ 0  0  0  0  0  0  0  0  0  0]
938         [ 0  0  0  0  0  0  0  0  0  0]
939         [30 31 32 33 34 35 36 37 38 39]
940        ]
941
942       The trick to using this is that the index selects elements along the
943       dimensions specified, so if you have a 2D image "axis=0" will select
944       certain "X" values - i.e. extract columns
945
946       As this is an index function, any modifications to the slice will
947       change the parent.
948
949   slice
950         $slice = $data->slice([2,3],'x',[2,2,0],"-1:1:-1", "*3");
951
952       Extract rectangular slices of a piddle, from a string specifier, an
953       array ref specifier, or a combination.
954
955       "slice" is the main method for extracting regions of PDLs and
956       manipulating their dimensionality.  You can call it directly or via he
957       NiceSlice source prefilter that extends Perl syntax to include array
958       slicing.
959
960       "slice" can extract regions along each dimension of a source PDL,
961       subsample or reverse those regions, dice each dimension by selecting a
962       list of locations along it, or basic PDL indexing routine.  The
963       selected subfield remains connected to the original PDL via dataflow.
964       In most cases this neither allocates more memory nor slows down
965       subsequent operations on either of the two connected PDLs.
966
967       You pass in a list of arguments.  Each term in the list controls the
968       disposition of one axis of the source PDL and/or returned PDL.  Each
969       term can be a string-format cut specifier, a list ref that gives the
970       same information without recourse to string manipulation, or a PDL with
971       up to 1 dimension giving indices along that axis that should be
972       selected.
973
974       If you want to pass in a single string specifier for the entire
975       operation, you can pass in a comma-delimited list as the first
976       argument.  "slice" detects this condition and splits the string into a
977       regular argument list.  This calling style is fully backwards
978       compatible with "slice" calls from before PDL 2.006.
979
980       STRING SYNTAX
981
982       If a particular argument to "slice" is a string, it is parsed as a
983       selection, an affine slice, or a dummy dimension depending on the form.
984       Leading or trailing whitespace in any part of each specifier is ignored
985       (though it is not ignored within numbers).
986
987       '', ":", or "X" -- keep
988          The empty string, ":", or "X" cause the entire corresponding
989          dimension to be kept unchanged.
990
991       "<n>" -- selection
992          A single number alone causes a single index to be selected from the
993          corresponding dimension.  The dimension is kept (and reduced to size
994          1) in the output.
995
996       "(<n>)" -- selection and collapse
997          A single number in parenthesis causes a single index to be selected
998          from the corresponding dimension.  The dimension is discarded
999          (completely eliminated) in the output.
1000
1001       "<n>:<m>" -- select an inclusive range
1002          Two numbers separated by a colon selects a range of values from the
1003          corresponding axis, e.g. "3:4" selects elements 3 and 4 along the
1004          corresponding axis, and reduces that axis to size 2 in the output.
1005          Both numbers are regularized so that you can address the last
1006          element of the axis with an index of " -1 ".  If, after
1007          regularization, the two numbers are the same, then exactly one
1008          element gets selected (just like the "<n>" case).  If, after
1009          regulariation, the second number is lower than the first, then the
1010          resulting slice counts down rather than up -- e.g. "-1:0" will
1011          return the entire axis, in reversed order.
1012
1013       "<n>:<m>:<s>" -- select a range with explicit step
1014          If you include a third parameter, it is the stride of the extracted
1015          range.  For example, "0:-1:2" will sample every other element across
1016          the complete dimension.  Specifying a stride of 1 prevents
1017          autoreversal -- so to ensure that your slice is *always* forward you
1018          can specify, e.g., "2:$n:1".  In that case, an "impossible" slice
1019          gets an Empty PDL (with 0 elements along the corresponding
1020          dimension), so you can generate an Empty PDL with a slice of the
1021          form "2:1:1".
1022
1023       "*<n>" -- insert a dummy dimension
1024          Dummy dimensions aren't present in the original source and are
1025          "mocked up" to match dimensional slots, by repeating the data in the
1026          original PDL some number of times.  An asterisk followed by a number
1027          produces a dummy dimension in the output, for example *2 will
1028          generate a dimension of size 2 at the corresponding location in the
1029          output dim list.  Omitting the number (and using just an asterisk)
1030          inserts a dummy dimension of size 1.
1031
1032       ARRAY REF SYNTAX
1033
1034       If you feed in an ARRAY ref as a slice term, then it can have 0-3
1035       elements.  The first element is the start of the slice along the
1036       corresponding dim; the second is the end; and the third is the
1037       stepsize.  Different combinations of inputs give the same flexibility
1038       as the string syntax.
1039
1040       "[]" - keep dim intact
1041          An empty ARRAY ref keeps the entire corresponding dim
1042
1043       "[ 'X' ]" - keep dim intact
1044       "[ '*',$n ]" - generate a dummy dim of size $n
1045          If $n is missing, you get a dummy dim of size 1.
1046
1047       "[ $dex, , 0 ]" - collapse and discard dim
1048          $dex must be a single value.  It is used to index the source, and
1049          the corresponding dimension is discarded.
1050
1051       "[ $start, $end ]" - collect inclusive slice
1052          In the simple two-number case, you get a slice that runs up or down
1053          (as appropriate) to connect $start and $end.
1054
1055       "[ $start, $end, $inc ]" - collect inclusive slice
1056          The three-number case works exactly like the three-number string
1057          case above.
1058
1059       PDL args for dicing
1060
1061       If you pass in a 0- or 1-D PDL as a slicing argument, the corresponding
1062       dimension is "diced" -- you get one position along the corresponding
1063       dim, per element of the indexing PDL, e.g. "$x->slice( pdl(3,4,9))"
1064       gives you elements 3, 4, and 9 along the 0 dim of $x.
1065
1066       Because dicing is not an affine transformation, it is slower than
1067       direct slicing even though the syntax is convenient.
1068
1069        $x->slice('1:3');  #  return the second to fourth elements of $x
1070        $x->slice('3:1');  #  reverse the above
1071        $x->slice('-2:1'); #  return last-but-one to second elements of $x
1072
1073        $x->slice([1,3]);  # Same as above three calls, but using array ref syntax
1074        $x->slice([3,1]);
1075        $x->slice([-2,1]);
1076
1077   sliceb
1078         Signature: (P(); C(); SV *args)
1079
1080       info not available
1081
1082       sliceb does not process bad values.  It will set the bad-value flag of
1083       all output piddles if the flag is set for any of the input piddles.
1084

BUGS

1086       For the moment, you can't slice one of the zero-length dims of an empty
1087       piddle.  It is not clear how to implement this in a way that makes
1088       sense.
1089
1090       Many types of index errors are reported far from the indexing operation
1091       that caused them.  This is caused by the underlying architecture:
1092       slice() sets up a mapping between variables, but that mapping isn't
1093       tested for correctness until it is used (potentially much later).
1094

AUTHOR

1096       Copyright (C) 1997 Tuomas J. Lukka.  Contributions by Craig DeForest,
1097       deforest@boulder.swri.edu.  Documentation contributions by David
1098       Mertens.  All rights reserved. There is no warranty. You are allowed to
1099       redistribute this software / documentation under certain conditions.
1100       For details, see the file COPYING in the PDL distribution. If this file
1101       is separated from the PDL distribution, the copyright notice should be
1102       included in the file.
1103
1104
1105
1106perl v5.32.1                      2021-02-15                         Slices(3)
Impressum