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