1Slices(3) User Contributed Perl Documentation Slices(3)
2
3
4
6 PDL::Slices -- Indexing, slicing, and dicing
7
9 use PDL;
10 $a = ones(3,3);
11 $b = $a->slice('-1:0,(1)');
12 $c = $a->dummy(2);
13
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 $a = zeroes(1000,1000);
21 $a->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 $b = $a->slice("1:3"); # Slice maintains a link between $a and $b.
37 $b += 5; # $a 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 $b = $a->slice("1:3")->copy;
43 $b += 5; # $a is not changed.
44
45 $b = $a->slice("1:3")->sever;
46 $b += 5; # $a 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 $b = $a->slice("1:3");
53 $c = $b->sever;
54
55 then the variables $b and $c point to the same object but with "->copy"
56 they would not.
57
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 = $a->index(pdl[0,5,8]);
103 $c .= pdl [0,2,4];
104
105 the changes in $c will flow back to $a.
106
107 "index" provids simple threading: multiple-dimensioned arrays are
108 treated as collections of 1-D arrays, so that
109
110 $a = xvals(10,10)+10*yvals(10,10);
111 $b = $a->index(3);
112 $c = $a->index(9-xvals(10));
113
114 puts a single column from $a into $b, and puts a single element from
115 each column of $a 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 = $a->index(pdl[0,5,8]);
156 $c .= pdl [0,2,4];
157
158 the changes in $c will flow back to $a.
159
160 "index" provids simple threading: multiple-dimensioned arrays are
161 treated as collections of 1-D arrays, so that
162
163 $a = xvals(10,10)+10*yvals(10,10);
164 $b = $a->index(3);
165 $c = $a->index(9-xvals(10));
166
167 puts a single column from $a into $b, and puts a single element from
168 each column of $a 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 = $a->index(pdl[0,5,8]);
209 $c .= pdl [0,2,4];
210
211 the changes in $c will flow back to $a.
212
213 "index" provids simple threading: multiple-dimensioned arrays are
214 treated as collections of 1-D arrays, so that
215
216 $a = xvals(10,10)+10*yvals(10,10);
217 $b = $a->index(3);
218 $c = $a->index(9-xvals(10));
219
220 puts a single column from $a into $b, and puts a single element from
221 each column of $a 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 $a = $data->range($index, $sizes, $bound)->sever;
485 $aa = $data->range($index, $sizes, $bound);
486 map { $a($_ - 1) .= $_; } (1..$a->nelem); # Lots of little ops
487 $aa .= $a;
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 $a of the numbers of instances of values $b, run-length
508 decode to $c.
509
510 rld($a,$b,$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 $a with the number of each element,
521 and a vector $b of the unique values. New in PDL 2.017, only the
522 elements up to the first instance of 0 in $a are returned, which makes
523 the common use case of a 1-dimensional $c simpler. For threaded
524 operation, $a and $b will be large enough to hold the largest row of
525 $a, and only the elements up to the first instance of 0 in each row of
526 $a should be considered.
527
528 $c = floor(4*random(10));
529 rle($c,$a=null,$b=null);
530 #or
531 ($a,$b) = rle($c);
532
533 #for $c of shape [10, 4]:
534 $c = floor(4*random(10,4));
535 ($a,$b) = 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) = ($a(:,($_)),$b(:,($_)));
540 my ($ta,$tb) = where($as,$bs,$as!=0); #only the non-zero elements of $a
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 $b = $a->xchg(2,3);
557
558 creates $b to be like $a except that the dimensions 2 and 3 are
559 exchanged with each other i.e.
560
561 $b->at(5,3,2,8) == $a->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> $a = sequence(5,3,2); # Create a 3-d Array
600 pdl> p $a
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 $a->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 "$a->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 $b = $a->mv(4,1);
657
658 creates $b to be like $a except that the dimension 4 is moved to the
659 place 1, so:
660
661 $b->at(1,2,3,4,5,6) == $a->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 $a->slice('1:3'); # return the second to fourth elements of $a
684 $a->slice('3:1'); # reverse the above
685 $a->slice('-2:1'); # return last-but-one to second elements of $a
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 "$a->slice(':,3')" is equal to "$a->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 $a has dims "(3,4,5)"
700 then "$a->slice(':,(2),:')" has dimensions "(3,5)" whereas
701 "$a->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 "$a->slice('(=1),(=1|5:8),3:6(=1),4:6')" to express a multidimensional
715 diagonal of $a.
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 $a
757 has dimensions "(5,3,5,4,6,5)" then after
758
759 $b = $a->diagonal(0,2,5);
760
761 the piddle $b has dimensions "(5,3,4,6)" and "$b->at(2,1,0,1)" refers
762 to "$a->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 = $a->lags($nthdim,$step,$nlags);
777
778 I.e. if $a contains
779
780 [0,1,2,3,4,5,6,7]
781
782 then
783
784 $b = $a->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 $b = $a->splitdim(2,3);
809
810 the expression
811
812 $b->at(6,4,x,y,3,6) == $a->at(6,4,x+3*y)
813
814 is always true ("x" 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 $b = $a->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 slice
868 requires that contiguous ranges or ranges with constant offset be
869 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> $a = sequence(10,4)
884 pdl> p $a
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 $a->dice([1,2],[0,3]) # Select columns 1,2 and rows 0,3
892 [
893 [ 1 2]
894 [31 32]
895 ]
896 pdl> p $a->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 $a->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 change the
910 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> $a = sequence(10,4)
924 pdl> $idx = pdl(1,2)
925 pdl> p $a->dice_axis(0,$idx) # Select columns
926 [
927 [ 1 2]
928 [11 12]
929 [21 22]
930 [31 32]
931 ]
932 pdl> $t = $a->dice_axis(1,$idx) # Select rows
933 pdl> $t.=0
934 pdl> p $a
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 change the
947 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 o 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 numeber (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. "$a->slice( pdl(3,4,9))"
1064 gives you elements 3, 4, and 9 along the 0 dim of $a.
1065
1066 Because dicing is not an affine transformation, it is slower than
1067 direct slicing even though the syntax is convenient.
1068
1069 $a->slice('1:3'); # return the second to fourth elements of $a
1070 $a->slice('3:1'); # reverse the above
1071 $a->slice('-2:1'); # return last-but-one to second elements of $a
1072
1073 $a->slice([1,3]); # Same as above three calls, but using array ref syntax
1074 $a->slice([3,1]);
1075 $a->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
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
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.28.1 2019-02-14 Slices(3)