Provided by: pdl_2.085-1ubuntu1_amd64 bug

NAME

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

SYNOPSIS

         use PDL;
         $x = ones(3,3);
         $y = $x->slice('-1:0,(1)');
         $c = $x->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

        $x = zeroes(1000,1000);
        $x->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.

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

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

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

        $y = $x->slice("1:3")->sever;
        $y += 5;               # $x 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

        $y = $x->slice("1:3");
        $c = $y->sever;

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

FUNCTIONS

   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 broadcast slightly
       differently.

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

       •  "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 broadcasting sense.

       •  "index2d" works like "index" but uses separate ndarrays 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 = $x->index(pdl[0,5,8]);
        $c .= pdl [0,2,4];

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

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

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

       puts  a  single column from $x into $y, and puts a single element from each column of $x 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  broadcast  slightly
       differently.

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

       •  "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 broadcasting sense.

       •  "index2d" works like "index" but uses separate ndarrays 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 = $x->index(pdl[0,5,8]);
        $c .= pdl [0,2,4];

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

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

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

       puts  a  single column from $x into $y, and puts a single element from each column of $x 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  broadcast  slightly
       differently.

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

       •  "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 broadcasting sense.

       •  "index2d" works like "index" but uses separate ndarrays 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 = $x->index(pdl[0,5,8]);
        $c .= pdl [0,2,4];

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

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

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

       puts  a  single column from $x into $y, and puts a single element from each column of $x 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 ndarray, 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.

       SEE ALSO:

       "whichND"  in  PDL::Primitive  returns  N-D  indices into a multidimensional PDL, suitable for feeding to
       this.

   rangeb
         Signature: (P(); C(); pdl *ind_pdl; SV *size_sv; SV *boundary_sv)

       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 ndarray, with boundary conditions

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

       Returns elements or rectangular slices of the original ndarray, indexed by the $index  ndarray.   $source
       is  an  N-dimensional ndarray, and $index is an ndarray 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 ndarrays 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 ndarray 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 ndarray point instead to the nearest  allowed  value  within
          the ndarray.  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 ndarray 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 broadcasts over both $index and $source.  Because implicit broadcasting can happen in a couple
       of ways, a little thought is needed.  The returned dimension list is stacked up like this:

          (index broadcast dims), (index dims (size)), (source broadcast 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, broadcasted 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 broadcast dims, because adding more  dims  to  $source  just  tacks
       extra  dims on the end of the output.  Each source broadcast 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)  # Broadcast 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 = PDL::RandVar->new->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...
         $x =  $data->range($index, $sizes, $bound)->sever;
         $aa = $data->range($index, $sizes, $bound);
         $x($_ - 1) .= $_ for 1..$x->nelem;    # Lots of little ops
         $aa .= $x;

       "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 broadcast 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 ndarrays if the flag is set
       for any of the input ndarrays.

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

       Run-length decode a vector

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

        rld($x,$y,$c=null);

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

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

       Run-length encode a vector

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

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

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

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

        # the inverse of (chance of all 6 3d6 rolls being >= each possible sum)
        ($nrolls, $ndice, $dmax) = (6, 3, 6);
        ($x, $x1) = (allaxisvals(($dmax) x $ndice)+1)->sumover->flat->qsort->rle;
        $y = $x->cumusumover;
        $yprob1x = $y->slice('-1:0')->double / $y->slice('(-1)');
        $z = cat($x1, 1 / $yprob1x**$nrolls)->transpose;

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

   rlevec
         Signature: (c(M,N); indx [o]a(N); [o]b(M,N))

       Run-length encode a set of vectors.

       Higher-order rle(), for use with qsortvec().

       Given set of vectors $c, generate a vector $a with the number of occurrences of each  element  (where  an
       "element"  is  a  vector  of  length  $M  occurring in $c), and a set of vectors $b containing the unique
       values.  As for rle(), only the elements up to the first instance of 0 in $a should be considered.

       Can be used together with clump() to run-length encode "values" of arbitrary  dimensions.   Can  be  used
       together with rotate(), cat(), append(), and qsortvec() to count N-grams over a 1d PDL.

       See  also:  "rle",  "qsortvec"  in  PDL::Ufunc,  "uniqvec"  in PDL::Primitive Contributed by Bryan Jurish
       <moocow@cpan.org>.

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

   rldvec
         Signature: (indx a(N); b(M,N); [o]c(M,N))

       Run-length decode a set of vectors, akin to a higher-order rld().

       Given a vector $a() of the number of occurrences of each row, and a  set  $c()  of  row-vectors  each  of
       length $M, run-length decode to $c().

       Can be used together with clump() to run-length decode "values" of arbitrary dimensions.

       See also: "rld".  Contributed by Bryan Jurish <moocow@cpan.org>.

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

   rleseq
         Signature: (c(N); indx [o]a(N); [o]b(N))

       Run-length encode a vector of subsequences.

       Given  a  vector of $c() of concatenated variable-length, variable-offset subsequences, generate a vector
       $a containing the length of each subsequence and a vector $b containing the subsequence offsets.  As  for
       rle(), only the elements up to the first instance of 0 in $a should be considered.

       See also "rle".  Contributed by Bryan Jurish <moocow@cpan.org>.

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

   rldseq
         Signature: (indx a(N); b(N); [o]c(M))

       Run-length decode a subsequence vector.

       Given  a vector $a() of sequence lengths and a vector $b() of corresponding offsets, decode concatenation
       of subsequences to $c(), as for:

        $c = null;
        $c = $c->append($b($_)+sequence($a->type,$a($_))) foreach (0..($N-1));

       See also: "rld".  Contributed by Bryan Jurish <moocow@cpan.org>.

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

   rleND
         Signature: (data(@vdims,N); int [o]counts(N); [o]elts(@vdims,N))

       Run-length encode a set of (sorted) n-dimensional values.

       Generalization of rle() and vv_rlevec(): given set of values $data, generate a vector  $counts  with  the
       number of occurrences of each element (where an "element" is a matrix of dimensions @vdims occurring as a
       sequential  run  over  the  final dimension in $data), and a set of vectors $elts containing the elements
       which begin a run.  Really just a wrapper for clump() and rlevec().

       See also: "rle", "rlevec".  Contributed by Bryan Jurish <moocow@cpan.org>.

   rldND
         Signature: (int counts(N); elts(@vdims,N); [o]data(@vdims,N);)

       Run-length decode a set of (sorted) n-dimensional values.

       Generalization of rld() and rldvec(): given a vector $counts() of  the  number  of  occurrences  of  each
       @vdims-dimensioned  element,  and  a  set  $elts()  of  @vdims-dimensioned elements, run-length decode to
       $data().

       Really just a wrapper for clump() and rldvec().

       See also: "rld", "rldvec".  Contributed by Bryan Jurish <moocow@cpan.org>.

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

       exchange two dimensions

       Negative dimension indices count from the end.

       The command

        $y = $x->xchg(2,3);

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

        $y->at(5,3,2,8) == $x->at(5,3,8,2)

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

   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> $x = sequence(5,3,2);       # Create a 3-d Array
        pdl> p $x
        [
         [
          [ 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 $x->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 "$x->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(); PDL_Indx n1; PDL_Indx n2)

       move a dimension to another position

       The command

        $y = $x->mv(4,1);

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

        $y->at(1,2,3,4,5,6) == $x->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 ndarrays if the flag is set
       for any of the input ndarrays.

   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);

   diagonal
         Signature: (P(); C(); PDL_Indx whichdims[])

       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 $x has dimensions "(5,3,5,4,6,5)" then after

        $d = $x->diagonal(dim1, dim2,...)

        $y = $x->diagonal(0,2,5);

       the ndarray $y has dimensions "(5,3,4,6)" and "$y->at(2,1,0,1)" refers to "$x->at(2,1,2,0,1,2)".

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

        pdl> $x = zeroes(3,3,3);
        pdl> ($y = $x->diagonal(0,1))++;
        pdl> p $x
        [
         [
          [1 0 0]
          [0 1 0]
          [0 0 1]
         ]
         [
          [1 0 0]
          [0 1 0]
          [0 0 1]
         ]
         [
          [1 0 0]
          [0 1 0]
          [0 0 1]
         ]
        ]

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

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

       Returns an ndarray of lags to parent.

       Usage:

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

       I.e. if $x contains

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

       then

        $y = $x->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 ndarrays if the  flag  is
       set for any of the input ndarrays.

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

       Splits  a  dimension  in  the  parent ndarray (opposite of clump).  As of 2.076, throws exception if non-
       divisible "nsp" given, and can give negative "nthdim" which then counts backwards.

       After

        $y = $x->splitdim(2,3);

       the expression

        $y->at(6,4,m,n,3,6) == $x->at(6,4,m+3*n)

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

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

   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 ndarrays if the flag is
       set for any of the input ndarrays.

   broadcastI
         Signature: (P(); C(); PDL_Indx id; PDL_Indx whichdims[])

       internal

       Put some dimensions to a broadcastid.

        $y = $x->broadcastI(0,1,5); # broadcast over dims 1,5 in id 1

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

   unbroadcast
         Signature: (P(); C(); PDL_Indx atind)

       All broadcasted dimensions are made real again.

       See [TBD Doc] for details and examples.

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

   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> $x = sequence(10,4)
        pdl> p $x
        [
         [ 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 $x->dice([1,2],[0,3]) # Select columns 1,2 and rows 0,3
        [
         [ 1  2]
         [31 32]
        ]
        pdl> p $x->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 $x->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  will  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> $x = sequence(10,4)
        pdl> $idx = pdl(1,2)
        pdl> p $x->dice_axis(0,$idx) # Select columns
        [
         [ 1  2]
         [11 12]
         [21 22]
         [31 32]
        ]
        pdl> $t = $x->dice_axis(1,$idx) # Select rows
        pdl> $t.=0
        pdl> p $x
        [
         [ 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 will change the parent.

   slice
         Signature: (P(); C(); pdl_slice_args *arglist)

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

       Extract  rectangular  slices  of  an  ndarray,  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 the NiceSlice source prefilter that extends Perl syntax to 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  number  (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. "$x->slice( pdl(3,4,9))"
       gives you elements 3, 4, and 9 along the 0 dim of $x.

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

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

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

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

BUGS

       For the moment, you can't slice one of the zero-length dims of an empty ndarray.  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.38.2                                       2024-04-10                                        Slices(3pm)