Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
Slices(3)	      User Contributed Perl Documentation	     Slices(3)

NAME
       PDL::Slices -- Indexing,	slicing, and dicing

SYNOPSIS
	 use PDL;
	 $a = ones(3,3);
	 $b = $a->slice('-1:0,(1)');
	 $c = $a->dummy(2);

DESCRIPTION
       This package provides many of the powerful PerlDL core index
       manipulation routines.  These routines mostly allow two-way data	flow,
       so you can modify your data in the most convenient representation.  For
       example,	you can	make a 1000x1000 unit matrix with

	$a = zeroes(1000,1000);
	$a->diagonal(0,1) ++;

       which is	quite efficient. See PDL::Indexing and PDL::Tips for more
       examples.

       Slicing is so central to	the PDL	language that a	special	compile-time
       syntax has been introduced to handle it compactly; see PDL::NiceSlice
       for details.

       PDL indexing and	slicing	functions usually include two-way data flow,
       so that you can separate	the actions of reshaping your data structures
       and modifying the data themselves.  Two special methods,	copy and
       sever, help you control the data	flow connection	between	related
       variables.

	$b = $a->slice("1:3"); # Slice maintains a link	between	$a and $b.
	$b += 5;	       # $a is changed!

       If you want to force a physical copy and	no data	flow, you can copy or
       sever the slice expression:

	$b = $a->slice("1:3")->copy;
	$b += 5;	       # $a is not changed.

	$b = $a->slice("1:3")->sever;
	$b += 5;	       # $a is not changed.

       The difference between "sever" and "copy" is that sever acts on (and
       returns)	its argument, while copy produces a disconnected copy.	If you
       say

	$b = $a->slice("1:3");
	$c = $b->sever;

       then the	variables $b and $c point to the same object but with "->copy"
       they would not.

FUNCTIONS
   s_identity
	 Signature: (P(); C())

       Internal	vaffine	identity function.

       s_identity processes bad	values.	 It will set the bad-value flag	of all
       output piddles if the flag is set for any of the	input piddles.

   index
	 Signature: (a(n); indx	ind(); [oca] c())

       "index",	"index1d", and "index2d" provide rudimentary index
       indirection.

	$c = index($source,$ind);
	$c = index1d($source,$ind);
	$c = index2d($source2,$ind1,$ind2);

       use the $ind variables as indices to look up values in $source.	The
       three routines thread slightly differently.

       o  "index" uses direct threading	for 1-D	indexing across	the 0 dim of
	  $source.  It can thread over source thread dims or index thread
	  dims,	but not	(easily) both: If $source has more than	1 dimension
	  and $ind has more than 0 dimensions, they must agree in a threading
	  sense.

       o  "index1d" uses a single active dim in	$ind to	produce	a list of
	  indexed values in the	0 dim of the output - it is useful for
	  collapsing $source by	indexing with a	single row of values along
	  $source's 0 dimension.  The output has the same number of dims as
	  $source.  The	0 dim of the output has	size 1 if $ind is a scalar,
	  and the same size as the 0 dim of $ind if it is not. If $ind and
	  $source both have more than 1	dim, then all dims higher than 0 must
	  agree	in a threading sense.

       o  "index2d" works like "index" but uses	separate piddles for X and Y
	  coordinates.	For more general N-dimensional indexing, see the
	  PDL::NiceSlice syntax	or PDL::Slices (in particular "slice",
	  "indexND", and "range").

       These functions are two-way, i.e. after

	$c = $a->index(pdl[0,5,8]);
	$c .= pdl [0,2,4];

       the changes in $c will flow back	to $a.

       "index" provids simple threading:  multiple-dimensioned arrays are
       treated as collections of 1-D arrays, so	that

	$a = xvals(10,10)+10*yvals(10,10);
	$b = $a->index(3);
	$c = $a->index(9-xvals(10));

       puts a single column from $a into $b, and puts a	single element from
       each column of $a into $c.  If you want to extract multiple columns
       from an array in	one operation, see dice	or indexND.

       index barfs if any of the index values are bad.

   index1d
	 Signature: (a(n); indx	ind(m);	[oca] c(m))

       "index",	"index1d", and "index2d" provide rudimentary index
       indirection.

	$c = index($source,$ind);
	$c = index1d($source,$ind);
	$c = index2d($source2,$ind1,$ind2);

       use the $ind variables as indices to look up values in $source.	The
       three routines thread slightly differently.

       o  "index" uses direct threading	for 1-D	indexing across	the 0 dim of
	  $source.  It can thread over source thread dims or index thread
	  dims,	but not	(easily) both: If $source has more than	1 dimension
	  and $ind has more than 0 dimensions, they must agree in a threading
	  sense.

       o  "index1d" uses a single active dim in	$ind to	produce	a list of
	  indexed values in the	0 dim of the output - it is useful for
	  collapsing $source by	indexing with a	single row of values along
	  $source's 0 dimension.  The output has the same number of dims as
	  $source.  The	0 dim of the output has	size 1 if $ind is a scalar,
	  and the same size as the 0 dim of $ind if it is not. If $ind and
	  $source both have more than 1	dim, then all dims higher than 0 must
	  agree	in a threading sense.

       o  "index2d" works like "index" but uses	separate piddles for X and Y
	  coordinates.	For more general N-dimensional indexing, see the
	  PDL::NiceSlice syntax	or PDL::Slices (in particular "slice",
	  "indexND", and "range").

       These functions are two-way, i.e. after

	$c = $a->index(pdl[0,5,8]);
	$c .= pdl [0,2,4];

       the changes in $c will flow back	to $a.

       "index" provids simple threading:  multiple-dimensioned arrays are
       treated as collections of 1-D arrays, so	that

	$a = xvals(10,10)+10*yvals(10,10);
	$b = $a->index(3);
	$c = $a->index(9-xvals(10));

       puts a single column from $a into $b, and puts a	single element from
       each column of $a into $c.  If you want to extract multiple columns
       from an array in	one operation, see dice	or indexND.

       index1d propagates BAD index elements to	the output variable.

   index2d
	 Signature: (a(na,nb); indx inda(); indx indb(); [oca] c())

       "index",	"index1d", and "index2d" provide rudimentary index
       indirection.

	$c = index($source,$ind);
	$c = index1d($source,$ind);
	$c = index2d($source2,$ind1,$ind2);

       use the $ind variables as indices to look up values in $source.	The
       three routines thread slightly differently.

       o  "index" uses direct threading	for 1-D	indexing across	the 0 dim of
	  $source.  It can thread over source thread dims or index thread
	  dims,	but not	(easily) both: If $source has more than	1 dimension
	  and $ind has more than 0 dimensions, they must agree in a threading
	  sense.

       o  "index1d" uses a single active dim in	$ind to	produce	a list of
	  indexed values in the	0 dim of the output - it is useful for
	  collapsing $source by	indexing with a	single row of values along
	  $source's 0 dimension.  The output has the same number of dims as
	  $source.  The	0 dim of the output has	size 1 if $ind is a scalar,
	  and the same size as the 0 dim of $ind if it is not. If $ind and
	  $source both have more than 1	dim, then all dims higher than 0 must
	  agree	in a threading sense.

       o  "index2d" works like "index" but uses	separate piddles for X and Y
	  coordinates.	For more general N-dimensional indexing, see the
	  PDL::NiceSlice syntax	or PDL::Slices (in particular "slice",
	  "indexND", and "range").

       These functions are two-way, i.e. after

	$c = $a->index(pdl[0,5,8]);
	$c .= pdl [0,2,4];

       the changes in $c will flow back	to $a.

       "index" provids simple threading:  multiple-dimensioned arrays are
       treated as collections of 1-D arrays, so	that

	$a = xvals(10,10)+10*yvals(10,10);
	$b = $a->index(3);
	$c = $a->index(9-xvals(10));

       puts a single column from $a into $b, and puts a	single element from
       each column of $a into $c.  If you want to extract multiple columns
       from an array in	one operation, see dice	or indexND.

       index2d barfs if	either of the index values are bad.

   indexNDb
	 Backwards-compatibility alias for indexND

   indexND
	 Find selected elements	in an N-D piddle, with optional	boundary handling

	 $out =	$source->indexND( $index, [$method] )

	 $source = 10*xvals(10,10) + yvals(10,10);
	 $index	 = pdl([[2,3],[4,5]],[[6,7],[8,9]]);
	 print $source->indexND( $index	);

	 [
	  [23 45]
	  [67 89]
	 ]

       IndexND collapses $index	by lookup into $source.	 The 0th dimension of
       $index is treated as coordinates	in $source, and	the return value has
       the same	dimensions as the rest of $index.  The returned	elements are
       looked up from $source.	Dataflow works -- propagated assignment	flows
       back into $source.

       IndexND and IndexNDb were originally separate routines but they are
       both now	implemented as a call to range,	and have identical syntax to
       one another.

   rangeb
	 Signature: (P(); C(); SV *index; SV *size; SV *boundary)

       Engine for range

       Same calling convention as range, but you must supply all parameters.
       "rangeb"	is marginally faster as	it makes a direct PP call, avoiding
       the perl	argument-parsing step.

   range
       Extract selected	chunks from a source piddle, with boundary conditions

	       $out = $source->range($index,[$size,[$boundary]])

       Returns elements	or rectangular slices of the original piddle, indexed
       by the $index piddle.  $source is an N-dimensional piddle, and $index
       is a piddle whose first dimension has size up to	N.  Each row of	$index
       is treated as coordinates of a single value or chunk from $source,
       specifying the location(s) to extract.

       If you specify a	single index location, then range is essentially an
       expensive slice,	with controllable boundary conditions.

       INPUTS

       $index and $size	can be piddles or array	refs such as you would feed to
       zeroes and its ilk.  If $index's	0th dimension has size higher than the
       number of dimensions in $source,	then $source is	treated	as though it
       had trivial dummy dimensions of size 1, up to the required size to be
       indexed by $index -- so if your source array is 1-D and your index
       array is	a list of 3-vectors, you get two dummy dimensions of size 1 on
       the end of your source array.

       You can extract single elements or N-D rectangular ranges from $source,
       by setting $size.  If $size is undef or zero, then you get a single
       sample for each row of $index.  This behavior is	similar	to indexNDb,
       which is	in fact	implemented as a call to range.

       If $size	is positive then you get a range of values from	$source	at
       each location, and the output has extra dimensions allocated for	them.
       $size can be a scalar, in which case it applies to all dimensions, or
       an N-vector, in which case each element is applied independently	to the
       corresponding dimension in $source.  See	below for details.

       $boundary is a number, string, or list ref indicating the type of
       boundary	conditions to use when ranges reach the	edge of	$source.  If
       you specify no boundary conditions the default is to forbid boundary
       violations on all axes.	If you specify exactly one boundary condition,
       it applies to all axes.	If you specify more (as	elements of a list
       ref, or as a packed string, see below), then they apply to dimensions
       in the order in which they appear, and the last one applies to all
       subsequent dimensions.  (This is	less difficult than it sounds; see the
       examples	below).

       0 (synonyms: 'f','forbid') (default)
	  Ranges are not allowed to cross the boundary of the original PDL.
	  Disallowed ranges throw an error.  The errors	are thrown at
	  evaluation time, not at the time of the range	call (this is the same
	  behavior as slice).

       1 (synonyms: 't','truncate')
	  Values outside the original piddle get BAD if	you've got bad value
	  support compiled into	your PDL and set the badflag for the source
	  PDL; or 0 if you haven't (you	must set the badflag if	you want BADs
	  for out of bound values, otherwise you get 0).  Reverse dataflow
	  works	OK for the portion of the child	that is	in-bounds.  The	out-
	  of-bounds part of the	child is reset to (BAD|0) during each dataflow
	  operation, but execution continues.

       2 (synonyms: 'e','x','extend')
	  Values that would be outside the original piddle point instead to
	  the nearest allowed value within the piddle.	See the	CAVEAT below
	  on mappings that are not single valued.

       3 (synonyms: 'p','periodic')
	  Periodic boundary conditions apply: the numbers in $index are
	  applied, strict-modulo the corresponding dimensions of $source.
	  This is equivalent to	duplicating the	$source	piddle throughout N-D
	  space.  See the CAVEAT below about mappings that are not single
	  valued.

       4 (synonyms: 'm','mirror')
	  Mirror-reflection periodic boundary conditions apply.	 See the
	  CAVEAT below about mappings that are not single valued.

       The boundary condition identifiers all begin with unique	characters, so
       you can feed in multiple	boundary conditions as either a	list ref or a
       packed string.  (The packed string is marginally	faster to run).	 For
       example,	the four expressions [0,1], ['forbid','truncate'], ['f','t'],
       and 'ft'	all specify that violating the boundary	in the 0th dimension
       throws an error,	and all	other dimensions get truncated.

       If you feed in a	single string, it is interpreted as a packed boundary
       array if	all of its characters are valid	boundary specifiers (e.g.
       'pet'), but as a	single word-style specifier if they are	not (e.g.
       'forbid').

       OUTPUT

       The output threads over both $index and $source.	 Because implicit
       threading can happen in a couple	of ways, a little thought is needed.
       The returned dimension list is stacked up like this:

	  (index thread	dims), (index dims (size)), (source thread dims)

       The first few dims of the output	correspond to the extra	dims of	$index
       (beyond the 0 dim). They	allow you to pick out individual ranges	from a
       large, threaded collection.

       The middle few dims of the output correspond to the size	dims specified
       in $size, and contain the range of values that is extracted at each
       location	in $source.  Every nonzero element of $size is copied to the
       dimension list here, so that if you feed	in (for	example) "$size	=
       [2,0,1]"	you get	an index dim list of "(2,1)".

       The last	few dims of the	output correspond to extra dims	of $source
       beyond the number of dims indexed by $index.  These dims	act like
       ordinary	thread dims, because adding more dims to $source just tacks
       extra dims on the end of	the output.  Each source thread	dim ranges
       over the	entire corresponding dim of $source.

       Dataflow: Dataflow is bidirectional.

       Examples: Here are basic	examples of "range" operation, showing how to
       get ranges out of a small matrix.  The first few	examples show
       extraction and selection	of individual chunks.  The last	example	shows
       how to mark loci	in the original	matrix (using dataflow).

	pdl> $src = 10*xvals(10,5)+yvals(10,5)
	pdl> print $src->range([2,3])	 # Cut out a single element
	23
	pdl> print $src->range([2,3],1)	 # Cut out a single 1x1	block
	[
	 [23]
	]
	pdl> print $src->range([2,3], [2,1]) # Cut a 2x1 chunk
	[
	 [23 33]
	]
	pdl> print $src->range([[2,3]],[2,1]) #	Trivial	list of	1 chunk
	[
	 [
	  [23]
	  [33]
	 ]
	]
	pdl> print $src->range([[2,3],[0,1]], [2,1])   # two 2x1 chunks
	[
	 [
	  [23  1]
	  [33 11]
	 ]
	]
	pdl> # A 2x2 collection	of 2x1 chunks
	pdl> print $src->range([[[1,1],[2,2]],[[2,3],[0,1]]],[2,1])
	[
	 [
	  [
	   [11 22]
	   [23	1]
	  ]
	  [
	   [21 32]
	   [33 11]
	  ]
	 ]
	]
	pdl> $src = xvals(5,3)*10+yvals(5,3)
	pdl> print $src->range(3,1)  # Thread over y dimension in $src
	[
	 [30]
	 [31]
	 [32]
	]

	pdl> $src = zeroes(5,4);
	pdl> $src->range(pdl([2,3],[0,1]),pdl(2,1)) .= xvals(2,2,1) + 1
	pdl> print $src
	[
	 [0 0 0	0 0]
	 [2 2 0	0 0]
	 [0 0 0	0 0]
	 [0 0 1	1 0]
	]

       CAVEAT: It's quite possible to select multiple ranges that intersect.
       In that case, modifying the ranges doesn't have a guaranteed result in
       the original PDL	-- the result is an arbitrary choice among the valid
       values.	For some things	that's OK; but for others it's not. In
       particular, this	doesn't	work:

	   pdl>	$photon_list = new PDL::RandVar->sample(500)->reshape(2,250)*10
	   pdl>	histogram = zeroes(10,10)
	   pdl>	histogram->range($photon_list,1)++;  #not what you wanted

       The reason is that if two photons land in the same bin, then that bin
       doesn't get incremented twice.  (That may get fixed in a	later
       version...)

       PERMISSIVE RANGING: If $index has too many dimensions compared to
       $source,	then $source is	treated	as though it had dummy dimensions of
       size 1, up to the required number of dimensions.	 These virtual dummy
       dimensions have the usual boundary conditions applied to	them.

       If the 0	dimension of $index is ludicrously large (if its size is more
       than 5 greater than the number of dims in the source PDL) then range
       will insist that	you specify a size in every dimension, to make sure
       that you	know what you're doing.	 That catches a	common error with
       range usage: confusing the initial dim (which is	usually	small) with
       another index dim (perhaps of size 1000).

       If the index variable is	Empty, then range() always returns the Empty
       PDL.  If	the index variable is not Empty, indexing it always yields a
       boundary	violation.  All	non-barfing conditions are treated as
       truncation, since there are no actual data to return.

       EFFICIENCY: Because "range" isn't an affine transformation (it involves
       lookup into a list of N-D indices), it is somewhat memory-inefficient
       for long	lists of ranges, and keeping dataflow open is much slower than
       for affine transformations (which don't have to copy data around).

       Doing operations	on small subfields of a	large range is inefficient
       because the engine must flow the	entire range back into the original
       PDL with	every atomic perl operation, even if you only touch a single
       element.	 One way to speed up such code is to sever your	range, so that
       PDL doesn't have	to copy	the data with each operation, then copy	the
       elements	explicitly at the end of your loop.  Here's an example that
       labels each region in a range sequentially, using many small operations
       rather than a single xvals assignment:

	 ### How to make a collection of small ops run fast with range...
	 $a =  $data->range($index, $sizes, $bound)->sever;
	 $aa = $data->range($index, $sizes, $bound);
	 map { $a($_ - 1) .= $_; } (1..$a->nelem);    #	Lots of	little ops
	 $aa .=	$a;

       "range" is a perl front-end to a	PP function, "rangeb".	Calling
       "rangeb"	is marginally faster but requires that you include all
       arguments.

       DEVEL NOTES

       * index thread dimensions are effectively clumped internally.  This
       makes it	easier to loop over the	index array but	a little more brain-
       bending to tease	out the	algorithm.

       rangeb processes	bad values.  It	will set the bad-value flag of all
       output piddles if the flag is set for any of the	input piddles.

   rld
	 Signature: (indx a(n);	b(n); [o]c(m))

       Run-length decode a vector

       Given a vector $a of the	numbers	of instances of	values $b, run-length
       decode to $c.

	rld($a,$b,$c=null);

       rld does	not process bad	values.	 It will set the bad-value flag	of all
       output piddles if the flag is set for any of the	input piddles.

   rle
	 Signature: (c(n); indx	[o]a(m); [o]b(m))

       Run-length encode a vector

       Given vector $c,	generate a vector $a with the number of	each element,
       and a vector $b of the unique values.  New in PDL 2.017,	only the
       elements	up to the first	instance of 0 in $a are	returned, which	makes
       the common use case of a	1-dimensional $c simpler.  For threaded
       operation, $a and $b will be large enough to hold the largest row of
       $a, and only the	elements up to the first instance of 0 in each row of
       $a should be considered.

	$c = floor(4*random(10));
	rle($c,$a=null,$b=null);
	#or
	($a,$b)	= rle($c);

	#for $c	of shape [10, 4]:
	$c = floor(4*random(10,4));
	($a,$b)	= rle($c);

	#to see	the results of each row	one at a time:
	foreach	(0..$c->dim(1)-1){
	 my ($as,$bs) =	($a(:,($_)),$b(:,($_)));
	 my ($ta,$tb) =	where($as,$bs,$as!=0); #only the non-zero elements of $a
	 print $c(:,($_)) . " rle==> " , ($ta,$tb) , "\trld==> " . rld($ta,$tb)	. "\n";
	}

       rle does	not process bad	values.	 It will set the bad-value flag	of all
       output piddles if the flag is set for any of the	input piddles.

   xchg
	 Signature: (P(); C(); int n1; int n2)

       exchange	two dimensions

       Negative	dimension indices count	from the end.

       The command

	$b = $a->xchg(2,3);

       creates $b to be	like $a	except that the	dimensions 2 and 3 are
       exchanged with each other i.e.

	$b->at(5,3,2,8)	== $a->at(5,3,8,2)

       xchg does not process bad values.  It will set the bad-value flag of
       all output piddles if the flag is set for any of	the input piddles.

   reorder
       Re-orders the dimensions	of a PDL based on the supplied list.

       Similar to the xchg method, this	method re-orders the dimensions	of a
       PDL. While the xchg method swaps	the position of	two dimensions,	the
       reorder method can change the positions of many dimensions at once.

	# Completely reverse the dimension order of a 6-Dim array.
	$reOrderedPDL =	$pdl->reorder(5,4,3,2,1,0);

       The argument to reorder is an array representing	where the current
       dimensions should go in the new array. In the above usage, the argument
       to reorder "(5,4,3,2,1,0)" indicates that the old dimensions ($pdl's
       dims) should be re-arranged to make the new pdl ($reOrderPDL) according
       to the following:

	  Old Position	 New Position
	  ------------	 ------------
	  5		 0
	  4		 1
	  3		 2
	  2		 3
	  1		 4
	  0		 5

       You do not need to specify all dimensions, only a complete set starting
       at position 0.  (Extra dimensions are left where	they are).  This
       means, for example, that	you can	reorder() the X	and Y dimensions of an
       image, and not care whether it is an RGB	image with a third dimension
       running across color plane.

       Example:

	pdl> $a	= sequence(5,3,2);	 # Create a 3-d	Array
	pdl> p $a
	[
	 [
	  [ 0  1  2  3	4]
	  [ 5  6  7  8	9]
	  [10 11 12 13 14]
	 ]
	 [
	  [15 16 17 18 19]
	  [20 21 22 23 24]
	  [25 26 27 28 29]
	 ]
	]
	pdl> p $a->reorder(2,1,0); # Reverse the order of the 3-D PDL
	[
	 [
	  [ 0 15]
	  [ 5 20]
	  [10 25]
	 ]
	 [
	  [ 1 16]
	  [ 6 21]
	  [11 26]
	 ]
	 [
	  [ 2 17]
	  [ 7 22]
	  [12 27]
	 ]
	 [
	  [ 3 18]
	  [ 8 23]
	  [13 28]
	 ]
	 [
	  [ 4 19]
	  [ 9 24]
	  [14 29]
	 ]
	]

       The above is a simple example that could	be duplicated by calling
       "$a->xchg(0,2)",	but it demonstrates the	basic functionality of
       reorder.

       As this is an index function, any modifications to the result PDL will
       change the parent.

   mv
	 Signature: (P(); C(); int n1; int n2)

       move a dimension	to another position

       The command

	$b = $a->mv(4,1);

       creates $b to be	like $a	except that the	dimension 4 is moved to	the
       place 1,	so:

	$b->at(1,2,3,4,5,6) == $a->at(1,5,2,3,4,6);

       The other dimensions are	moved accordingly.  Negative dimension indices
       count from the end.

       mv does not process bad values.	It will	set the	bad-value flag of all
       output piddles if the flag is set for any of the	input piddles.

   oslice
	 Signature: (P(); C(); char* str)

       DEPRECATED:  'oslice' is	the original 'slice' routine in	pre-2.006_006
       versions	of PDL.	 It is left here for reference but will	disappear in
       PDL 3.000

       Extract a rectangular slice of a	piddle,	from a string specifier.

       "slice" was the original	Swiss-army-knife PDL indexing routine, but is
       largely superseded by the NiceSlice source prefilter and	its associated
       nslice method.  It is still used	as the basic underlying	slicing	engine
       for nslice, and is especially useful in particular niche	applications.

	$a->slice('1:3');  #  return the second	to fourth elements of $a
	$a->slice('3:1');  #  reverse the above
	$a->slice('-2:1'); #  return last-but-one to second elements of	$a

       The argument string is a	comma-separated	list of	what to	do for each
       dimension. The current formats include the following, where a, b	and c
       are integers and	can take legal array index values (including -1	etc):

       :       takes the whole dimension intact.

       ''      (nothing) is a synonym for ":" (This means that
	       "$a->slice(':,3')" is equal to "$a->slice(',3')").

       a       slices only this	value out of the corresponding dimension.

       (a)     means the same as "a" by	itself except that the resulting
	       dimension of length one is deleted (so if $a has	dims "(3,4,5)"
	       then "$a->slice(':,(2),:')" has dimensions "(3,5)" whereas
	       "$a->slice(':,2,:')" has	dimensions "(3,1,5))".

       a:b     slices the range	a to b inclusive out of	the dimension.

       a:b:c   slices the range	a to b,	with step c (i.e. "3:7:2" gives	the
	       indices "(3,5,7)"). This	may be confusing to Matlab users but
	       several other packages already use this syntax.

       '*'     inserts an extra	dimension of width 1 and

       '*a'    inserts an extra	(dummy)	dimension of width a.

       An extension is planned for a later stage allowing
       "$a->slice('(=1),(=1|5:8),3:6(=1),4:6')"	to express a multidimensional
       diagonal	of $a.

       Trivial out-of-bounds slicing is	allowed: if you	slice a	source
       dimension that doesn't exist, but only index the	0th element, then
       "slice" treats the source as if there were a dummy dimension there.
       The following are all equivalent:

	       xvals(5)->dummy(1,1)->slice('(2),0')  # Add dummy dim, then slice
	       xvals(5)->slice('(2),0')		     # Out-of-bounds slice adds	dim.
	       xvals(5)->slice((2),0)		     # NiceSlice syntax
	       xvals(5)->((2))->dummy(0,1)	     # NiceSlice syntax

       This is an error:

	       xvals(5)->slice('(2),1')	       # nontrivial out-of-bounds slice	dies

       Because slicing doesn't directly	manipulate the source and destination
       pdl -- it just sets up a	transformation between them -- indexing	errors
       often aren't reported until later.  This	is either a bug	or a feature,
       depending on whether you	prefer error-reporting clarity or speed	of
       execution.

       oslice does not process bad values.  It will set	the bad-value flag of
       all output piddles if the flag is set for any of	the input piddles.

   using
       Returns array of	column numbers requested

	line $pdl->using(1,2);

       Plot, as	a line,	column 1 of $pdl vs. column 2

	pdl> $pdl = rcols("file");
	pdl> line $pdl->using(1,2);

   diagonalI
	 Signature: (P(); C(); SV *list)

       Returns the multidimensional diagonal over the specified	dimensions.

       The diagonal is placed at the first (by number) dimension that is
       diagonalized.  The other	diagonalized dimensions	are removed. So	if $a
       has dimensions "(5,3,5,4,6,5)" then after

	$b = $a->diagonal(0,2,5);

       the piddle $b has dimensions "(5,3,4,6)"	and "$b->at(2,1,0,1)" refers
       to "$a->at(2,1,2,0,1,2)".

       NOTE: diagonal doesn't handle threadids correctly. XXX FIX

       diagonalI does not process bad values.  It will set the bad-value flag
       of all output piddles if	the flag is set	for any	of the input piddles.

   lags
	 Signature: (P(); C(); int nthdim; int step; int n)

       Returns a piddle	of lags	to parent.

       Usage:

	 $lags = $a->lags($nthdim,$step,$nlags);

       I.e. if $a contains

	[0,1,2,3,4,5,6,7]

       then

	$b = $a->lags(0,2,2);

       is a (5,2) matrix

	[2,3,4,5,6,7]
	[0,1,2,3,4,5]

       This order of returned indices is kept because the function is called
       "lags" i.e. the nth lag is n steps behind the original.

       $step and $nlags	must be	positive. $nthdim can be negative and will
       then be counted from the	last dim backwards in the usual	way (-1	= last
       dim).

       lags does not process bad values.  It will set the bad-value flag of
       all output piddles if the flag is set for any of	the input piddles.

   splitdim
	 Signature: (P(); C(); int nthdim; int nsp)

       Splits a	dimension in the parent	piddle (opposite of clump)

       After

	$b = $a->splitdim(2,3);

       the expression

	$b->at(6,4,x,y,3,6) == $a->at(6,4,x+3*y)

       is always true ("x" has to be less than 3).

       splitdim	does not process bad values.  It will set the bad-value	flag
       of all output piddles if	the flag is set	for any	of the input piddles.

   rotate
	 Signature: (x(n); indx	shift(); [oca]y(n))

       Shift vector elements along with	wrap. Flows data back&forth.

       rotate does not process bad values.  It will set	the bad-value flag of
       all output piddles if the flag is set for any of	the input piddles.

   threadI
	 Signature: (P(); C(); int id; SV *list)

       internal

       Put some	dimensions to a	threadid.

	$b = $a->threadI(0,1,5); # thread over dims 1,5	in id 1

       threadI does not	process	bad values.  It	will set the bad-value flag of
       all output piddles if the flag is set for any of	the input piddles.

   identvaff
	 Signature: (P(); C())

       A vaffine identity transformation (includes thread_id copying).

       Mainly for internal use.

       identvaff does not process bad values.  It will set the bad-value flag
       of all output piddles if	the flag is set	for any	of the input piddles.

   unthread
	 Signature: (P(); C(); int atind)

       All threaded dimensions are made	real again.

       See [TBD	Doc] for details and examples.

       unthread	does not process bad values.  It will set the bad-value	flag
       of all output piddles if	the flag is set	for any	of the input piddles.

   dice
       Dice rows/columns/planes	out of a PDL using indexes for each dimension.

       This function can be used to extract irregular subsets along many
       dimension of a PDL, e.g.	only certain rows in an	image, or planes in a
       cube. This can of course	be done	with the usual dimension tricks	but
       this saves having to figure it out each time!

       This method is similar in functionality to the slice method, but	slice
       requires	that contiguous	ranges or ranges with constant offset be
       extracted. ( i.e. slice requires	ranges of the form "1,2,3,4,5" or
       "2,4,6,8,10"). Because of this restriction, slice is more memory
       efficient and slightly faster than dice

	$slice = $data->dice([0,2,6],[2,1,6]); # Dicing	a 2-D array

       The arguments to	dice are arrays	(or 1D PDLs) for each dimension	in the
       PDL. These arrays are used as indexes to	which rows/columns/cubes,etc
       to dice-out (or extract)	from the $data PDL.

       Use "X" to select all indices along a given dimension (compare also
       mslice).	As usual (in slicing methods) trailing dimensions can be
       omitted implying	"X"'es for those.

	pdl> $a	= sequence(10,4)
	pdl> p $a
	[
	 [ 0  1	 2  3  4  5  6	7  8  9]
	 [10 11	12 13 14 15 16 17 18 19]
	 [20 21	22 23 24 25 26 27 28 29]
	 [30 31	32 33 34 35 36 37 38 39]
	]
	pdl> p $a->dice([1,2],[0,3]) # Select columns 1,2 and rows 0,3
	[
	 [ 1  2]
	 [31 32]
	]
	pdl> p $a->dice(X,[0,3])
	[
	 [ 0  1	 2  3  4  5  6	7  8  9]
	 [30 31	32 33 34 35 36 37 38 39]
	]
	pdl> p $a->dice([0,2,5])
	[
	 [ 0  2	 5]
	 [10 12	15]
	 [20 22	25]
	 [30 32	35]
	]

       As this is an index function, any modifications to the slice change the
       parent (use the ".=" operator).

   dice_axis
       Dice rows/columns/planes	from a single PDL axis (dimension) using index
       along a specified axis

       This function can be used to extract irregular subsets along any
       dimension, e.g. only certain rows in an image, or planes	in a cube.
       This can	of course be done with the usual dimension tricks but this
       saves having to figure it out each time!

	$slice = $data->dice_axis($axis,$index);

	pdl> $a	= sequence(10,4)
	pdl> $idx = pdl(1,2)
	pdl> p $a->dice_axis(0,$idx) # Select columns
	[
	 [ 1  2]
	 [11 12]
	 [21 22]
	 [31 32]
	]
	pdl> $t	= $a->dice_axis(1,$idx)	# Select rows
	pdl> $t.=0
	pdl> p $a
	[
	 [ 0  1	 2  3  4  5  6	7  8  9]
	 [ 0  0	 0  0  0  0  0	0  0  0]
	 [ 0  0	 0  0  0  0  0	0  0  0]
	 [30 31	32 33 34 35 36 37 38 39]
	]

       The trick to using this is that the index selects elements along	the
       dimensions specified, so	if you have a 2D image "axis=0"	will select
       certain "X" values - i.e. extract columns

       As this is an index function, any modifications to the slice change the
       parent.

   slice
	 $slice	= $data->slice([2,3],'x',[2,2,0],"-1:1:-1", "*3");

       Extract rectangular slices of a piddle, from a string specifier,	an
       array ref specifier, or a combination.

       "slice" is the main method for extracting regions of PDLs and
       manipulating their dimensionality.  You can call	it directly or via he
       NiceSlice source	prefilter that extends Perl syntax o include array
       slicing.

       "slice" can extract regions along each dimension	of a source PDL,
       subsample or reverse those regions, dice	each dimension by selecting a
       list of locations along it, or basic PDL	indexing routine.  The
       selected	subfield remains connected to the original PDL via dataflow.
       In most cases this neither allocates more memory	nor slows down
       subsequent operations on	either of the two connected PDLs.

       You pass	in a list of arguments.	 Each term in the list controls	the
       disposition of one axis of the source PDL and/or	returned PDL.  Each
       term can	be a string-format cut specifier, a list ref that gives	the
       same information	without	recourse to string manipulation, or a PDL with
       up to 1 dimension giving	indices	along that axis	that should be
       selected.

       If you want to pass in a	single string specifier	for the	entire
       operation, you can pass in a comma-delimited list as the	first
       argument.  "slice" detects this condition and splits the	string into a
       regular argument	list.  This calling style is fully backwards
       compatible with "slice" calls from before PDL 2.006.

       STRING SYNTAX

       If a particular argument	to "slice" is a	string,	it is parsed as	a
       selection, an affine slice, or a	dummy dimension	depending on the form.
       Leading or trailing whitespace in any part of each specifier is ignored
       (though it is not ignored within	numbers).

       '', ":",	or "X" -- keep
	  The empty string, ":", or "X"	cause the entire corresponding
	  dimension to be kept unchanged.

       "<n>" --	selection
	  A single number alone	causes a single	index to be selected from the
	  corresponding	dimension.  The	dimension is kept (and reduced to size
	  1) in	the output.

       "(<n>)" -- selection and	collapse
	  A single number in parenthesis causes	a single index to be selected
	  from the corresponding dimension.  The dimension is discarded
	  (completely eliminated) in the output.

       "<n>:<m>" -- select an inclusive	range
	  Two numbers separated	by a colon selects a range of values from the
	  corresponding	axis, e.g. "3:4" selects elements 3 and	4 along	the
	  corresponding	axis, and reduces that axis to size 2 in the output.
	  Both numbers are regularized so that you can address the last
	  element of the axis with an index of " -1 ".	If, after
	  regularization, the two numbers are the same,	then exactly one
	  element gets selected	(just like the "<n>" case).  If, after
	  regulariation, the second number is lower than the first, then the
	  resulting slice counts down rather than up --	e.g. "-1:0" will
	  return the entire axis, in reversed order.

       "<n>:<m>:<s>" --	select a range with explicit step
	  If you include a third parameter, it is the stride of	the extracted
	  range.  For example, "0:-1:2"	will sample every other	element	across
	  the complete dimension.  Specifying a	stride of 1 prevents
	  autoreversal -- so to	ensure that your slice is *always* forward you
	  can specify, e.g., "2:$n:1".	In that	case, an "impossible" slice
	  gets an Empty	PDL (with 0 elements along the corresponding
	  dimension), so you can generate an Empty PDL with a slice of the
	  form "2:1:1".

       "*<n>" -- insert	a dummy	dimension
	  Dummy	dimensions aren't present in the original source and are
	  "mocked up" to match dimensional slots, by repeating the data	in the
	  original PDL some number of times.  An asterisk followed by a	number
	  produces a dummy dimension in	the output, for	example	*2 will
	  generate a dimension of size 2 at the	corresponding location in the
	  output dim list.  Omitting the numeber (and using just an asterisk)
	  inserts a dummy dimension of size 1.

       ARRAY REF SYNTAX

       If you feed in an ARRAY ref as a	slice term, then it can	have 0-3
       elements.  The first element is the start of the	slice along the
       corresponding dim; the second is	the end; and the third is the
       stepsize.  Different combinations of inputs give	the same flexibility
       as the string syntax.

       "[]" - keep dim intact
	  An empty ARRAY ref keeps the entire corresponding dim

       "[ 'X' ]" - keep	dim intact
       "[ '*',$n ]" - generate a dummy dim of size $n
	  If $n	is missing, you	get a dummy dim	of size	1.

       "[ $dex,	, 0 ]" - collapse and discard dim
	  $dex must be a single	value.	It is used to index the	source,	and
	  the corresponding dimension is discarded.

       "[ $start, $end ]" - collect inclusive slice
	  In the simple	two-number case, you get a slice that runs up or down
	  (as appropriate) to connect $start and $end.

       "[ $start, $end,	$inc ]"	- collect inclusive slice
	  The three-number case	works exactly like the three-number string
	  case above.

       PDL args	for dicing

       If you pass in a	0- or 1-D PDL as a slicing argument, the corresponding
       dimension is "diced" -- you get one position along the corresponding
       dim, per	element	of the indexing	PDL, e.g. "$a->slice( pdl(3,4,9))"
       gives you elements 3, 4,	and 9 along the	0 dim of $a.

       Because dicing is not an	affine transformation, it is slower than
       direct slicing even though the syntax is	convenient.

	$a->slice('1:3');  #  return the second	to fourth elements of $a
	$a->slice('3:1');  #  reverse the above
	$a->slice('-2:1'); #  return last-but-one to second elements of	$a

	$a->slice([1,3]);  # Same as above three calls,	but using array	ref syntax
	$a->slice([3,1]);
	$a->slice([-2,1]);

   sliceb
	 Signature: (P(); C(); SV *args)

       info not	available

       sliceb does not process bad values.  It will set	the bad-value flag of
       all output piddles if the flag is set for any of	the input piddles.

BUGS
       For the moment, you can't slice one of the zero-length dims of an empty
       piddle.	It is not clear	how to implement this in a way that makes
       sense.

       Many types of index errors are reported far from	the indexing operation
       that caused them.  This is caused by the	underlying architecture:
       slice() sets up a mapping between variables, but	that mapping isn't
       tested for correctness until it is used (potentially much later).

AUTHOR
       Copyright (C) 1997 Tuomas J. Lukka.  Contributions by Craig DeForest,
       deforest@boulder.swri.edu.  Documentation contributions by David
       Mertens.	 All rights reserved. There is no warranty. You	are allowed to
       redistribute this software / documentation under	certain	conditions.
       For details, see	the file COPYING in the	PDL distribution. If this file
       is separated from the PDL distribution, the copyright notice should be
       included	in the file.

perl v5.32.0			  2020-08-09			     Slices(3)

NAME | SYNOPSIS | DESCRIPTION | FUNCTIONS | BUGS | AUTHOR

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=PDL::Slices&sektion=3&manpath=FreeBSD+12.2-RELEASE+and+Ports>

home | help