"Fossies" - the Fresh Open Source Software Archive

Member "PDL-2.080/GENERATED/PDL/Slices.pm" (28 May 2022, 52951 Bytes) of package /linux/misc/PDL-2.080.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Perl source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Slices.pm" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.079_vs_2.080.

    1 #
    2 # GENERATED WITH PDL::PP! Don't modify!
    3 #
    4 package PDL::Slices;
    5 
    6 our @EXPORT_OK = qw(index index1d index2d indexND indexNDb rangeb rld rle rlevec rldvec rleseq rldseq rleND rldND _clump_int xchg mv using diagonal lags splitdim rotate broadcastI unbroadcast dice dice_axis slice );
    7 our %EXPORT_TAGS = (Func=>\@EXPORT_OK);
    8 
    9 use PDL::Core;
   10 use PDL::Exporter;
   11 use DynaLoader;
   12 
   13 
   14    
   15    our @ISA = ( 'PDL::Exporter','DynaLoader' );
   16    push @PDL::Core::PP, __PACKAGE__;
   17    bootstrap PDL::Slices ;
   18 
   19 
   20 
   21 
   22 
   23 
   24 #line 5 "slices.pd"
   25 
   26 
   27 =head1 NAME
   28 
   29 PDL::Slices -- Indexing, slicing, and dicing
   30 
   31 =head1 SYNOPSIS
   32 
   33   use PDL;
   34   $x = ones(3,3);
   35   $y = $x->slice('-1:0,(1)');
   36   $c = $x->dummy(2);
   37 
   38 
   39 =head1 DESCRIPTION
   40 
   41 This package provides many of the powerful PerlDL core index
   42 manipulation routines.  These routines mostly allow two-way data flow,
   43 so you can modify your data in the most convenient representation.
   44 For example, you can make a 1000x1000 unit matrix with
   45 
   46  $x = zeroes(1000,1000);
   47  $x->diagonal(0,1) ++;
   48 
   49 which is quite efficient. See L<PDL::Indexing> and L<PDL::Tips> for
   50 more examples.
   51 
   52 Slicing is so central to the PDL language that a special compile-time
   53 syntax has been introduced to handle it compactly; see L<PDL::NiceSlice>
   54 for details.
   55 
   56 PDL indexing and slicing functions usually include two-way data flow,
   57 so that you can separate the actions of reshaping your data structures
   58 and modifying the data themselves.  Two special methods, L</copy> and
   59 L</sever>, help you control the data flow connection between related
   60 variables.
   61 
   62  $y = $x->slice("1:3"); # Slice maintains a link between $x and $y.
   63  $y += 5;               # $x is changed!
   64 
   65 If you want to force a physical copy and no data flow, you can copy or
   66 sever the slice expression:
   67 
   68  $y = $x->slice("1:3")->copy;
   69  $y += 5;               # $x is not changed.
   70 
   71  $y = $x->slice("1:3")->sever;
   72  $y += 5;               # $x is not changed.
   73 
   74 The difference between C<sever> and C<copy> is that sever acts on (and
   75 returns) its argument, while copy produces a disconnected copy.  If you
   76 say
   77 
   78  $y = $x->slice("1:3");
   79  $c = $y->sever;
   80 
   81 then the variables C<$y> and C<$c> point to the same object but with
   82 C<-E<gt>copy> they would not.
   83 
   84 =cut
   85 
   86 use strict;
   87 use warnings;
   88 use PDL::Core ':Internal';
   89 use Scalar::Util 'blessed';
   90 #line 91 "Slices.pm"
   91 
   92 
   93 
   94 
   95 
   96 
   97 =head1 FUNCTIONS
   98 
   99 =cut
  100 
  101 
  102 
  103 
  104 #line 948 "../../blib/lib/PDL/PP.pm"
  105 
  106 
  107 
  108 =head2 index
  109 
  110 =for sig
  111 
  112   Signature: (a(n); indx ind(); [oca] c())
  113 
  114 =for ref
  115 
  116 C<index>, C<index1d>, and C<index2d> provide rudimentary index indirection.
  117 
  118 =for example
  119 
  120  $c = index($source,$ind);
  121  $c = index1d($source,$ind);
  122  $c = index2d($source2,$ind1,$ind2);
  123 
  124 use the C<$ind> variables as indices to look up values in C<$source>.
  125 The three routines broadcast slightly differently.
  126 
  127 =over 3
  128 
  129 =item *
  130 
  131 C<index> uses direct broadcasting for 1-D indexing across the 0 dim
  132 of C<$source>.  It can broadcast over source broadcast dims or index broadcast
  133 dims, but not (easily) both: If C<$source> has more than 1
  134 dimension and C<$ind> has more than 0 dimensions, they must agree in
  135 a broadcasting sense.
  136 
  137 =item * 
  138 
  139 C<index1d> uses a single active dim in C<$ind> to produce a list of
  140 indexed values in the 0 dim of the output - it is useful for
  141 collapsing C<$source> by indexing with a single row of values along
  142 C<$source>'s 0 dimension.  The output has the same number of dims as
  143 C<$source>.  The 0 dim of the output has size 1 if C<$ind> is a
  144 scalar, and the same size as the 0 dim of C<$ind> if it is not. If
  145 C<$ind> and C<$source> both have more than 1 dim, then all dims higher
  146 than 0 must agree in a broadcasting sense.
  147 
  148 =item * 
  149 
  150 C<index2d> works like C<index> but uses separate ndarrays for X and Y
  151 coordinates.  For more general N-dimensional indexing, see the
  152 L<PDL::NiceSlice> syntax or L<PDL::Slices> (in particular C<slice>,
  153 C<indexND>, and C<range>).
  154 
  155 =back 
  156 
  157 These functions are two-way, i.e. after
  158 
  159  $c = $x->index(pdl[0,5,8]);
  160  $c .= pdl [0,2,4];
  161 
  162 the changes in C<$c> will flow back to C<$x>.
  163 
  164 C<index> provids simple broadcasting:  multiple-dimensioned arrays are treated
  165 as collections of 1-D arrays, so that
  166 
  167  $x = xvals(10,10)+10*yvals(10,10);
  168  $y = $x->index(3);
  169  $c = $x->index(9-xvals(10));
  170 
  171 puts a single column from C<$x> into C<$y>, and puts a single element
  172 from each column of C<$x> into C<$c>.  If you want to extract multiple
  173 columns from an array in one operation, see L</dice> or
  174 L</indexND>.
  175 
  176 
  177 
  178 =for bad
  179 
  180 index barfs if any of the index values are bad.
  181 
  182 =cut
  183 #line 184 "Slices.pm"
  184 
  185 
  186 
  187 #line 950 "../../blib/lib/PDL/PP.pm"
  188 
  189 *index = \&PDL::index;
  190 #line 191 "Slices.pm"
  191 
  192 
  193 
  194 #line 948 "../../blib/lib/PDL/PP.pm"
  195 
  196 
  197 
  198 =head2 index1d
  199 
  200 =for sig
  201 
  202   Signature: (a(n); indx ind(m); [oca] c(m))
  203 
  204 =for ref
  205 
  206 C<index>, C<index1d>, and C<index2d> provide rudimentary index indirection.
  207 
  208 =for example
  209 
  210  $c = index($source,$ind);
  211  $c = index1d($source,$ind);
  212  $c = index2d($source2,$ind1,$ind2);
  213 
  214 use the C<$ind> variables as indices to look up values in C<$source>.
  215 The three routines broadcast slightly differently.
  216 
  217 =over 3
  218 
  219 =item *
  220 
  221 C<index> uses direct broadcasting for 1-D indexing across the 0 dim
  222 of C<$source>.  It can broadcast over source broadcast dims or index broadcast
  223 dims, but not (easily) both: If C<$source> has more than 1
  224 dimension and C<$ind> has more than 0 dimensions, they must agree in
  225 a broadcasting sense.
  226 
  227 =item * 
  228 
  229 C<index1d> uses a single active dim in C<$ind> to produce a list of
  230 indexed values in the 0 dim of the output - it is useful for
  231 collapsing C<$source> by indexing with a single row of values along
  232 C<$source>'s 0 dimension.  The output has the same number of dims as
  233 C<$source>.  The 0 dim of the output has size 1 if C<$ind> is a
  234 scalar, and the same size as the 0 dim of C<$ind> if it is not. If
  235 C<$ind> and C<$source> both have more than 1 dim, then all dims higher
  236 than 0 must agree in a broadcasting sense.
  237 
  238 =item * 
  239 
  240 C<index2d> works like C<index> but uses separate ndarrays for X and Y
  241 coordinates.  For more general N-dimensional indexing, see the
  242 L<PDL::NiceSlice> syntax or L<PDL::Slices> (in particular C<slice>,
  243 C<indexND>, and C<range>).
  244 
  245 =back 
  246 
  247 These functions are two-way, i.e. after
  248 
  249  $c = $x->index(pdl[0,5,8]);
  250  $c .= pdl [0,2,4];
  251 
  252 the changes in C<$c> will flow back to C<$x>.
  253 
  254 C<index> provids simple broadcasting:  multiple-dimensioned arrays are treated
  255 as collections of 1-D arrays, so that
  256 
  257  $x = xvals(10,10)+10*yvals(10,10);
  258  $y = $x->index(3);
  259  $c = $x->index(9-xvals(10));
  260 
  261 puts a single column from C<$x> into C<$y>, and puts a single element
  262 from each column of C<$x> into C<$c>.  If you want to extract multiple
  263 columns from an array in one operation, see L</dice> or
  264 L</indexND>.
  265 
  266 
  267 
  268 =for bad
  269 
  270 index1d propagates BAD index elements to the output variable.
  271 
  272 =cut
  273 #line 274 "Slices.pm"
  274 
  275 
  276 
  277 #line 950 "../../blib/lib/PDL/PP.pm"
  278 
  279 *index1d = \&PDL::index1d;
  280 #line 281 "Slices.pm"
  281 
  282 
  283 
  284 #line 948 "../../blib/lib/PDL/PP.pm"
  285 
  286 
  287 
  288 =head2 index2d
  289 
  290 =for sig
  291 
  292   Signature: (a(na,nb); indx inda(); indx indb(); [oca] c())
  293 
  294 =for ref
  295 
  296 C<index>, C<index1d>, and C<index2d> provide rudimentary index indirection.
  297 
  298 =for example
  299 
  300  $c = index($source,$ind);
  301  $c = index1d($source,$ind);
  302  $c = index2d($source2,$ind1,$ind2);
  303 
  304 use the C<$ind> variables as indices to look up values in C<$source>.
  305 The three routines broadcast slightly differently.
  306 
  307 =over 3
  308 
  309 =item *
  310 
  311 C<index> uses direct broadcasting for 1-D indexing across the 0 dim
  312 of C<$source>.  It can broadcast over source broadcast dims or index broadcast
  313 dims, but not (easily) both: If C<$source> has more than 1
  314 dimension and C<$ind> has more than 0 dimensions, they must agree in
  315 a broadcasting sense.
  316 
  317 =item * 
  318 
  319 C<index1d> uses a single active dim in C<$ind> to produce a list of
  320 indexed values in the 0 dim of the output - it is useful for
  321 collapsing C<$source> by indexing with a single row of values along
  322 C<$source>'s 0 dimension.  The output has the same number of dims as
  323 C<$source>.  The 0 dim of the output has size 1 if C<$ind> is a
  324 scalar, and the same size as the 0 dim of C<$ind> if it is not. If
  325 C<$ind> and C<$source> both have more than 1 dim, then all dims higher
  326 than 0 must agree in a broadcasting sense.
  327 
  328 =item * 
  329 
  330 C<index2d> works like C<index> but uses separate ndarrays for X and Y
  331 coordinates.  For more general N-dimensional indexing, see the
  332 L<PDL::NiceSlice> syntax or L<PDL::Slices> (in particular C<slice>,
  333 C<indexND>, and C<range>).
  334 
  335 =back 
  336 
  337 These functions are two-way, i.e. after
  338 
  339  $c = $x->index(pdl[0,5,8]);
  340  $c .= pdl [0,2,4];
  341 
  342 the changes in C<$c> will flow back to C<$x>.
  343 
  344 C<index> provids simple broadcasting:  multiple-dimensioned arrays are treated
  345 as collections of 1-D arrays, so that
  346 
  347  $x = xvals(10,10)+10*yvals(10,10);
  348  $y = $x->index(3);
  349  $c = $x->index(9-xvals(10));
  350 
  351 puts a single column from C<$x> into C<$y>, and puts a single element
  352 from each column of C<$x> into C<$c>.  If you want to extract multiple
  353 columns from an array in one operation, see L</dice> or
  354 L</indexND>.
  355 
  356 
  357 
  358 =for bad
  359 
  360 index2d barfs if either of the index values are bad.
  361 
  362 =cut
  363 #line 364 "Slices.pm"
  364 
  365 
  366 
  367 #line 950 "../../blib/lib/PDL/PP.pm"
  368 
  369 *index2d = \&PDL::index2d;
  370 #line 371 "Slices.pm"
  371 
  372 
  373 
  374 #line 241 "slices.pd"
  375 
  376 =head2 indexNDb
  377 
  378 =for ref
  379 
  380   Backwards-compatibility alias for indexND
  381 
  382 =head2 indexND
  383 
  384 =for ref
  385 
  386   Find selected elements in an N-D ndarray, with optional boundary handling
  387 
  388 =for example
  389 
  390   $out = $source->indexND( $index, [$method] )
  391 
  392   $source = 10*xvals(10,10) + yvals(10,10);
  393   $index  = pdl([[2,3],[4,5]],[[6,7],[8,9]]);
  394   print $source->indexND( $index );
  395 
  396   [
  397    [23 45]
  398    [67 89]
  399   ]
  400 
  401 IndexND collapses C<$index> by lookup into C<$source>.  The
  402 0th dimension of C<$index> is treated as coordinates in C<$source>, and
  403 the return value has the same dimensions as the rest of C<$index>.
  404 The returned elements are looked up from C<$source>.  Dataflow
  405 works -- propagated assignment flows back into C<$source>.
  406 
  407 IndexND and IndexNDb were originally separate routines but they are both
  408 now implemented as a call to L</range>, and have identical syntax to
  409 one another.
  410 
  411 SEE ALSO:
  412 
  413 L<PDL::Primitive/whichND> returns N-D indices into a multidimensional
  414 PDL, suitable for feeding to this.
  415 
  416 =cut
  417 
  418 sub PDL::indexND {
  419         my($source,$index, $boundary) = @_;
  420         return PDL::range($source,$index,undef,$boundary);
  421 }
  422 
  423 *PDL::indexNDb = \&PDL::indexND;
  424 #line 425 "Slices.pm"
  425 
  426 
  427 
  428 #line 293 "slices.pd"
  429 
  430 
  431 sub PDL::range {
  432   my($source,$ind,$sz,$bound) = @_;
  433 
  434 # Convert to indx type up front (also handled in rangeb if necessary)
  435   my $index = (ref $ind && UNIVERSAL::isa($ind,'PDL') && $ind->type eq 'indx') ? $ind : indx($ind);
  436   my $size = defined($sz) ? PDL->pdl($sz) : undef;
  437 
  438 
  439   # Handle empty PDL case: return a properly constructed Empty.
  440   if($index->isempty) {
  441       my @sdims= $source->dims;
  442       splice(@sdims, 0, $index->dim(0) + ($index->dim(0)==0)); # added term is to treat Empty[0] like a single empty coordinate
  443       unshift(@sdims, $size->list) if(defined($size));
  444       return PDL->new_from_specification(0 x ($index->ndims-1), @sdims);
  445   }
  446 
  447 
  448   $index = $index->dummy(0,1) unless $index->ndims;
  449 
  450 
  451   # Pack boundary string if necessary
  452   if(defined $bound) {
  453     if(ref $bound eq 'ARRAY') {
  454       my ($s,$el);
  455       foreach $el(@$bound) {
  456         barf "Illegal boundary value '$el' in range"
  457           unless( $el =~ m/^([0123fFtTeEpPmM])/ );
  458         $s .= $1;
  459       }
  460       $bound = $s;
  461     }
  462     elsif($bound !~ m/^[0123ftepx]+$/  && $bound =~ m/^([0123ftepx])/i ) {
  463       $bound = $1;
  464     }
  465   }
  466 
  467   no warnings; # shut up about passing undef into rangeb
  468   $source->rangeb($index,$size,$bound);
  469 }
  470 #line 471 "Slices.pm"
  471 
  472 
  473 
  474 #line 948 "../../blib/lib/PDL/PP.pm"
  475 
  476 
  477 
  478 =head2 rangeb
  479 
  480 =for sig
  481 
  482   Signature: (P(); C(); pdl *ind_pdl; SV *size; SV *boundary_sv)
  483 
  484 =for ref
  485 
  486 Engine for L</range>
  487 
  488 =for example
  489 
  490 Same calling convention as L</range>, but you must supply all
  491 parameters.  C<rangeb> is marginally faster as it makes a direct PP call,
  492 avoiding the perl argument-parsing step.
  493 
  494 =head2 range
  495 
  496 =for ref
  497 
  498 Extract selected chunks from a source ndarray, with boundary conditions
  499 
  500 =for example
  501 
  502         $out = $source->range($index,[$size,[$boundary]])
  503 
  504 Returns elements or rectangular slices of the original ndarray, indexed by
  505 the C<$index> ndarray.  C<$source> is an N-dimensional ndarray, and C<$index> is
  506 an ndarray whose first dimension has size up to N.  Each row of C<$index> is
  507 treated as coordinates of a single value or chunk from C<$source>, specifying
  508 the location(s) to extract.
  509 
  510 If you specify a single index location, then range is essentially an expensive
  511 slice, with controllable boundary conditions.
  512 
  513 B<INPUTS>
  514 
  515 C<$index> and C<$size> can be ndarrays or array refs such as you would
  516 feed to L<zeroes|PDL::Core/zeroes> and its ilk.  If C<$index>'s 0th dimension
  517 has size higher than the number of dimensions in C<$source>, then
  518 C<$source> is treated as though it had trivial dummy dimensions of
  519 size 1, up to the required size to be indexed by C<$index> -- so if
  520 your source array is 1-D and your index array is a list of 3-vectors,
  521 you get two dummy dimensions of size 1 on the end of your source array.
  522 
  523 You can extract single elements or N-D rectangular ranges from C<$source>,
  524 by setting C<$size>.  If C<$size> is undef or zero, then you get a single
  525 sample for each row of C<$index>.  This behavior is similar to
  526 L</indexNDb>, which is in fact implemented as a call to L</range>.
  527 
  528 If C<$size> is positive then you get a range of values from C<$source> at
  529 each location, and the output has extra dimensions allocated for them.
  530 C<$size> can be a scalar, in which case it applies to all dimensions, or an
  531 N-vector, in which case each element is applied independently to the
  532 corresponding dimension in C<$source>.  See below for details.
  533 
  534 C<$boundary> is a number, string, or list ref indicating the type of
  535 boundary conditions to use when ranges reach the edge of C<$source>.  If you
  536 specify no boundary conditions the default is to forbid boundary violations
  537 on all axes.  If you specify exactly one boundary condition, it applies to
  538 all axes.  If you specify more (as elements of a list ref, or as a packed
  539 string, see below), then they apply to dimensions in the order in which they
  540 appear, and the last one applies to all subsequent dimensions.  (This is
  541 less difficult than it sounds; see the examples below).
  542 
  543 =over 3
  544 
  545 =item 0 (synonyms: 'f','forbid') B<(default)>
  546 
  547 Ranges are not allowed to cross the boundary of the original PDL.  Disallowed
  548 ranges throw an error.  The errors are thrown at evaluation time, not
  549 at the time of the range call (this is the same behavior as L</slice>).
  550 
  551 =item 1 (synonyms: 't','truncate')
  552 
  553 Values outside the original ndarray get BAD if you've got bad value
  554 support compiled into your PDL and set the badflag for the source PDL;
  555 or 0 if you haven't (you must set the badflag if you want BADs for out
  556 of bound values, otherwise you get 0).  Reverse dataflow works OK for
  557 the portion of the child that is in-bounds.  The out-of-bounds part of
  558 the child is reset to (BAD|0) during each dataflow operation, but
  559 execution continues.
  560 
  561 =item 2 (synonyms: 'e','x','extend')
  562 
  563 Values that would be outside the original ndarray point instead to the
  564 nearest allowed value within the ndarray.  See the CAVEAT below on
  565 mappings that are not single valued.
  566 
  567 =item 3 (synonyms: 'p','periodic')
  568 
  569 Periodic boundary conditions apply: the numbers in $index are applied,
  570 strict-modulo the corresponding dimensions of $source.  This is equivalent to
  571 duplicating the $source ndarray throughout N-D space.  See the CAVEAT below
  572 about mappings that are not single valued.
  573 
  574 =item 4 (synonyms: 'm','mirror')
  575 
  576 Mirror-reflection periodic boundary conditions apply.  See the CAVEAT
  577 below about mappings that are not single valued.
  578 
  579 =back
  580 
  581 The boundary condition identifiers all begin with unique characters, so
  582 you can feed in multiple boundary conditions as either a list ref or a
  583 packed string.  (The packed string is marginally faster to run).  For
  584 example, the four expressions [0,1], ['forbid','truncate'], ['f','t'],
  585 and 'ft' all specify that violating the boundary in the 0th dimension
  586 throws an error, and all other dimensions get truncated.
  587 
  588 If you feed in a single string, it is interpreted as a packed boundary
  589 array if all of its characters are valid boundary specifiers (e.g. 'pet'),
  590 but as a single word-style specifier if they are not (e.g. 'forbid').
  591 
  592 B<OUTPUT>
  593 
  594 The output broadcasts over both C<$index> and C<$source>.  Because implicit
  595 broadcasting can happen in a couple of ways, a little thought is needed.  The
  596 returned dimension list is stacked up like this:
  597 
  598    (index broadcast dims), (index dims (size)), (source broadcast dims)
  599 
  600 The first few dims of the output correspond to the extra dims of
  601 C<$index> (beyond the 0 dim). They allow you to pick out individual
  602 ranges from a large, broadcasted collection.
  603 
  604 The middle few dims of the output correspond to the size dims
  605 specified in C<$size>, and contain the range of values that is extracted
  606 at each location in C<$source>.  Every nonzero element of C<$size> is copied to
  607 the dimension list here, so that if you feed in (for example) C<$size
  608 = [2,0,1]> you get an index dim list of C<(2,1)>.
  609 
  610 The last few dims of the output correspond to extra dims of C<$source> beyond
  611 the number of dims indexed by C<$index>.  These dims act like ordinary
  612 broadcast dims, because adding more dims to C<$source> just tacks extra dims
  613 on the end of the output.  Each source broadcast dim ranges over the entire
  614 corresponding dim of C<$source>.
  615 
  616 B<Dataflow>: Dataflow is bidirectional.
  617 
  618 B<Examples>:
  619 Here are basic examples of C<range> operation, showing how to get
  620 ranges out of a small matrix.  The first few examples show extraction
  621 and selection of individual chunks.  The last example shows
  622 how to mark loci in the original matrix (using dataflow).
  623 
  624  pdl> $src = 10*xvals(10,5)+yvals(10,5)
  625  pdl> print $src->range([2,3])    # Cut out a single element
  626  23
  627  pdl> print $src->range([2,3],1)  # Cut out a single 1x1 block
  628  [
  629   [23]
  630  ]
  631  pdl> print $src->range([2,3], [2,1]) # Cut a 2x1 chunk
  632  [
  633   [23 33]
  634  ]
  635  pdl> print $src->range([[2,3]],[2,1]) # Trivial list of 1 chunk
  636  [
  637   [
  638    [23]
  639    [33]
  640   ]
  641  ]
  642  pdl> print $src->range([[2,3],[0,1]], [2,1])   # two 2x1 chunks
  643  [
  644   [
  645    [23  1]
  646    [33 11]
  647   ]
  648  ]
  649  pdl> # A 2x2 collection of 2x1 chunks
  650  pdl> print $src->range([[[1,1],[2,2]],[[2,3],[0,1]]],[2,1])
  651  [
  652   [
  653    [
  654     [11 22]
  655     [23  1]
  656    ]
  657    [
  658     [21 32]
  659     [33 11]
  660    ]
  661   ]
  662  ]
  663  pdl> $src = xvals(5,3)*10+yvals(5,3)
  664  pdl> print $src->range(3,1)  # Broadcast over y dimension in $src
  665  [
  666   [30]
  667   [31]
  668   [32]
  669  ]
  670 
  671  pdl> $src = zeroes(5,4);
  672  pdl> $src->range(pdl([2,3],[0,1]),pdl(2,1)) .= xvals(2,2,1) + 1
  673  pdl> print $src
  674  [
  675   [0 0 0 0 0]
  676   [2 2 0 0 0]
  677   [0 0 0 0 0]
  678   [0 0 1 1 0]
  679  ]
  680 
  681 B<CAVEAT>: It's quite possible to select multiple ranges that
  682 intersect.  In that case, modifying the ranges doesn't have a
  683 guaranteed result in the original PDL -- the result is an arbitrary
  684 choice among the valid values.  For some things that's OK; but for
  685 others it's not. In particular, this doesn't work:
  686 
  687     pdl> $photon_list = new PDL::RandVar->sample(500)->reshape(2,250)*10
  688     pdl> $histogram = zeroes(10,10)
  689     pdl> $histogram->range($photon_list,1)++;  #not what you wanted
  690 
  691 The reason is that if two photons land in the same bin, then that bin
  692 doesn't get incremented twice.  (That may get fixed in a later version...)
  693 
  694 B<PERMISSIVE RANGING>: If C<$index> has too many dimensions compared
  695 to C<$source>, then $source is treated as though it had dummy
  696 dimensions of size 1, up to the required number of dimensions.  These
  697 virtual dummy dimensions have the usual boundary conditions applied to
  698 them.
  699 
  700 If the 0 dimension of C<$index> is ludicrously large (if its size is
  701 more than 5 greater than the number of dims in the source PDL) then
  702 range will insist that you specify a size in every dimension, to make
  703 sure that you know what you're doing.  That catches a common error with
  704 range usage: confusing the initial dim (which is usually small) with another
  705 index dim (perhaps of size 1000).
  706 
  707 If the index variable is Empty, then range() always returns the Empty PDL.
  708 If the index variable is not Empty, indexing it always yields a boundary
  709 violation.  All non-barfing conditions are treated as truncation, since
  710 there are no actual data to return.
  711 
  712 B<EFFICIENCY>: Because C<range> isn't an affine transformation (it
  713 involves lookup into a list of N-D indices), it is somewhat
  714 memory-inefficient for long lists of ranges, and keeping dataflow open
  715 is much slower than for affine transformations (which don't have to copy
  716 data around).
  717 
  718 Doing operations on small subfields of a large range is inefficient
  719 because the engine must flow the entire range back into the original
  720 PDL with every atomic perl operation, even if you only touch a single element.
  721 One way to speed up such code is to sever your range, so that PDL
  722 doesn't have to copy the data with each operation, then copy the
  723 elements explicitly at the end of your loop.  Here's an example that
  724 labels each region in a range sequentially, using many small
  725 operations rather than a single xvals assignment:
  726 
  727   ### How to make a collection of small ops run fast with range...
  728   $x =  $data->range($index, $sizes, $bound)->sever;
  729   $aa = $data->range($index, $sizes, $bound);
  730   $x($_ - 1) .= $_ for 1..$x->nelem;    # Lots of little ops
  731   $aa .= $x;
  732 
  733 C<range> is a perl front-end to a PP function, C<rangeb>.  Calling
  734 C<rangeb> is marginally faster but requires that you include all arguments.
  735 
  736 DEVEL NOTES
  737 
  738 * index broadcast dimensions are effectively clumped internally.  This
  739 makes it easier to loop over the index array but a little more brain-bending
  740 to tease out the algorithm.
  741 
  742 
  743 
  744 =for bad
  745 
  746 rangeb processes bad values.
  747 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  748 
  749 
  750 =cut
  751 #line 752 "Slices.pm"
  752 
  753 
  754 
  755 #line 950 "../../blib/lib/PDL/PP.pm"
  756 
  757 *rangeb = \&PDL::rangeb;
  758 #line 759 "Slices.pm"
  759 
  760 
  761 
  762 #line 948 "../../blib/lib/PDL/PP.pm"
  763 
  764 
  765 
  766 =head2 rld
  767 
  768 =for sig
  769 
  770   Signature: (indx a(n); b(n); [o]c(m))
  771 
  772 =for ref
  773 
  774 Run-length decode a vector
  775 
  776 Given a vector C<$x> of the numbers of instances of values C<$y>, run-length
  777 decode to C<$c>.
  778 
  779 =for example
  780 
  781  rld($x,$y,$c=null);
  782 
  783 
  784 
  785 =for bad
  786 
  787 rld does not process bad values.
  788 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  789 
  790 
  791 =cut
  792 #line 793 "Slices.pm"
  793 
  794 
  795 
  796 #line 949 "../../blib/lib/PDL/PP.pm"
  797 
  798 sub PDL::rld {
  799   my ($x,$y) = @_;
  800   my ($c);
  801   if ($#_ == 2) {
  802     $c = $_[2];
  803   } else {
  804 # XXX Need to improve emulation of broadcasting in auto-generating c
  805     my ($size) = $x->sumover->max->sclr;
  806     my (@dims) = $x->dims;
  807     shift @dims;
  808     $c = $y->zeroes($size,@dims);
  809   }
  810   &PDL::_rld_int($x,$y,$c);
  811   $c;
  812 }
  813 #line 814 "Slices.pm"
  814 
  815 
  816 
  817 #line 950 "../../blib/lib/PDL/PP.pm"
  818 
  819 *rld = \&PDL::rld;
  820 #line 821 "Slices.pm"
  821 
  822 
  823 
  824 #line 948 "../../blib/lib/PDL/PP.pm"
  825 
  826 
  827 
  828 =head2 rle
  829 
  830 =for sig
  831 
  832   Signature: (c(n); indx [o]a(m); [o]b(m))
  833 
  834 =for ref
  835 
  836 Run-length encode a vector
  837 
  838 Given vector C<$c>, generate a vector C<$x> with the number of each
  839 element, and a vector C<$y> of the unique values.  New in PDL 2.017,
  840 only the elements up to the first instance of C<0> in C<$x> are
  841 returned, which makes the common use case of a 1-dimensional C<$c> simpler.
  842 For broadcast operation, C<$x> and C<$y> will be large enough
  843 to hold the largest row of C<$y>, and only the elements up to the
  844 first instance of C<0> in each row of C<$x> should be considered.
  845 
  846 =for example
  847 
  848  $c = floor(4*random(10));
  849  rle($c,$x=null,$y=null);
  850  #or
  851  ($x,$y) = rle($c);
  852 
  853  #for $c of shape [10, 4]:
  854  $c = floor(4*random(10,4));
  855  ($x,$y) = rle($c);
  856 
  857  #to see the results of each row one at a time:
  858  foreach (0..$c->dim(1)-1){
  859   my ($as,$bs) = ($x(:,($_)),$y(:,($_)));
  860   my ($ta,$tb) = where($as,$bs,$as!=0); #only the non-zero elements of $x
  861   print $c(:,($_)) . " rle==> " , ($ta,$tb) , "\trld==> " . rld($ta,$tb) . "\n";
  862  }
  863 
  864  # the inverse of (chance of all 6 3d6 rolls being >= each possible sum)
  865  ($nrolls, $ndice, $dmax) = (6, 3, 6);
  866  ($x, $x1) = (allaxisvals(($dmax) x $ndice)+1)->sumover->flat->qsort->rle;
  867  $y = $x->cumusumover;
  868  $yprob1x = $y->slice('-1:0')->double / $y->slice('(-1)');
  869  $z = cat($x1, 1 / $yprob1x**$nrolls)->transpose;
  870 
  871 
  872 
  873 =for bad
  874 
  875 rle does not process bad values.
  876 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  877 
  878 
  879 =cut
  880 #line 881 "Slices.pm"
  881 
  882 
  883 
  884 #line 949 "../../blib/lib/PDL/PP.pm"
  885 
  886 sub PDL::rle {
  887   my $c = shift;
  888   my ($x,$y) = @_==2 ? @_ : (null,null);
  889   PDL::_rle_int($c,$x,$y);
  890   my $max_ind = ($c->ndims<2) ? ($x!=0)->sumover-1 :
  891                                 ($x!=0)->clump(1..$x->ndims-1)->sumover->max->sclr-1;
  892   return ($x->slice("0:$max_ind"),$y->slice("0:$max_ind"));
  893 }
  894 #line 895 "Slices.pm"
  895 
  896 
  897 
  898 #line 950 "../../blib/lib/PDL/PP.pm"
  899 
  900 *rle = \&PDL::rle;
  901 #line 902 "Slices.pm"
  902 
  903 
  904 
  905 #line 948 "../../blib/lib/PDL/PP.pm"
  906 
  907 
  908 
  909 =head2 rlevec
  910 
  911 =for sig
  912 
  913   Signature: (c(M,N); indx [o]a(N); [o]b(M,N))
  914 
  915 =for ref
  916 
  917 Run-length encode a set of vectors.
  918 
  919 Higher-order rle(), for use with qsortvec().
  920 
  921 Given set of vectors $c, generate a vector $a with the number of occurrences of each element
  922 (where an "element" is a vector of length $M ocurring in $c),
  923 and a set of vectors $b containing the unique values.
  924 As for rle(), only the elements up to the first instance of 0 in $a should be considered.
  925 
  926 Can be used together with clump() to run-length encode "values" of arbitrary dimensions.
  927 Can be used together with rotate(), cat(), append(), and qsortvec() to count N-grams
  928 over a 1d PDL.
  929 
  930 See also: L</rle>, L<PDL::Ufunc/qsortvec>, L<PDL::Primitive/uniqvec>
  931 Contributed by Bryan Jurish E<lt>moocow@cpan.orgE<gt>.
  932 
  933 
  934 
  935 =for bad
  936 
  937 rlevec does not process bad values.
  938 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  939 
  940 
  941 =cut
  942 #line 943 "Slices.pm"
  943 
  944 
  945 
  946 #line 950 "../../blib/lib/PDL/PP.pm"
  947 
  948 *rlevec = \&PDL::rlevec;
  949 #line 950 "Slices.pm"
  950 
  951 
  952 
  953 #line 948 "../../blib/lib/PDL/PP.pm"
  954 
  955 
  956 
  957 =head2 rldvec
  958 
  959 =for sig
  960 
  961   Signature: (indx a(N); b(M,N); [o]c(M,N))
  962 
  963 =for ref
  964 
  965 Run-length decode a set of vectors, akin to a higher-order rld().
  966 
  967 Given a vector $a() of the number of occurrences of each row, and a set $c()
  968 of row-vectors each of length $M, run-length decode to $c().
  969 
  970 Can be used together with clump() to run-length decode "values" of arbitrary dimensions.
  971 
  972 See also: L</rld>.
  973 Contributed by Bryan Jurish E<lt>moocow@cpan.orgE<gt>.
  974 
  975 
  976 =for bad
  977 
  978 rldvec does not process bad values.
  979 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
  980 
  981 
  982 =cut
  983 #line 984 "Slices.pm"
  984 
  985 
  986 
  987 #line 949 "../../blib/lib/PDL/PP.pm"
  988 
  989 sub PDL::rldvec {
  990   my ($a,$b,$c) = @_;
  991   if (!defined($c)) {
  992 # XXX Need to improve emulation of threading in auto-generating c
  993     my ($rowlen) = $b->dim(0);
  994     my ($size) = $a->sumover->max;
  995     my (@dims) = $a->dims;
  996     shift(@dims);
  997     $c = $b->zeroes($b->type,$rowlen,$size,@dims);
  998   }
  999   &PDL::_rldvec_int($a,$b,$c);
 1000   return $c;
 1001 }
 1002 #line 1003 "Slices.pm"
 1003 
 1004 
 1005 
 1006 #line 950 "../../blib/lib/PDL/PP.pm"
 1007 
 1008 *rldvec = \&PDL::rldvec;
 1009 #line 1010 "Slices.pm"
 1010 
 1011 
 1012 
 1013 #line 948 "../../blib/lib/PDL/PP.pm"
 1014 
 1015 
 1016 
 1017 =head2 rleseq
 1018 
 1019 =for sig
 1020 
 1021   Signature: (c(N); indx [o]a(N); [o]b(N))
 1022 
 1023 =for ref
 1024 
 1025 Run-length encode a vector of subsequences.
 1026 
 1027 Given a vector of $c() of concatenated variable-length, variable-offset subsequences,
 1028 generate a vector $a containing the length of each subsequence
 1029 and a vector $b containing the subsequence offsets.
 1030 As for rle(), only the elements up to the first instance of 0 in $a should be considered.
 1031 
 1032 See also L</rle>.
 1033 Contributed by Bryan Jurish E<lt>moocow@cpan.orgE<gt>.
 1034 
 1035 
 1036 =for bad
 1037 
 1038 rleseq does not process bad values.
 1039 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1040 
 1041 
 1042 =cut
 1043 #line 1044 "Slices.pm"
 1044 
 1045 
 1046 
 1047 #line 950 "../../blib/lib/PDL/PP.pm"
 1048 
 1049 *rleseq = \&PDL::rleseq;
 1050 #line 1051 "Slices.pm"
 1051 
 1052 
 1053 
 1054 #line 948 "../../blib/lib/PDL/PP.pm"
 1055 
 1056 
 1057 
 1058 =head2 rldseq
 1059 
 1060 =for sig
 1061 
 1062   Signature: (indx a(N); b(N); [o]c(M))
 1063 
 1064 =for ref
 1065 
 1066 Run-length decode a subsequence vector.
 1067 
 1068 Given a vector $a() of sequence lengths
 1069 and a vector $b() of corresponding offsets,
 1070 decode concatenation of subsequences to $c(),
 1071 as for:
 1072 
 1073  $c = null;
 1074  $c = $c->append($b($_)+sequence($a->type,$a($_))) foreach (0..($N-1));
 1075 
 1076 See also: L</rld>.
 1077 Contributed by Bryan Jurish E<lt>moocow@cpan.orgE<gt>.
 1078 
 1079 
 1080 =for bad
 1081 
 1082 rldseq does not process bad values.
 1083 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1084 
 1085 
 1086 =cut
 1087 #line 1088 "Slices.pm"
 1088 
 1089 
 1090 
 1091 #line 949 "../../blib/lib/PDL/PP.pm"
 1092 
 1093 sub PDL::rldseq {
 1094   my ($a,$b,$c) = @_;
 1095   if (!defined($c)) {
 1096     my $size   = $a->sumover->max;
 1097     my (@dims) = $a->dims;
 1098     shift(@dims);
 1099     $c = $b->zeroes($b->type,$size,@dims);
 1100   }
 1101   &PDL::_rldseq_int($a,$b,$c);
 1102   return $c;
 1103 }
 1104 #line 1105 "Slices.pm"
 1105 
 1106 
 1107 
 1108 #line 950 "../../blib/lib/PDL/PP.pm"
 1109 
 1110 *rldseq = \&PDL::rldseq;
 1111 #line 1112 "Slices.pm"
 1112 
 1113 
 1114 
 1115 #line 1346 "slices.pd"
 1116 
 1117 =head2 rleND
 1118 
 1119 =for sig
 1120 
 1121   Signature: (data(@vdims,N); int [o]counts(N); [o]elts(@vdims,N))
 1122 
 1123 =for ref
 1124 
 1125 Run-length encode a set of (sorted) n-dimensional values.
 1126 
 1127 Generalization of rle() and vv_rlevec():
 1128 given set of values $data, generate a vector $counts with the number of occurrences of each element
 1129 (where an "element" is a matrix of dimensions @vdims ocurring as a sequential run over the
 1130 final dimension in $data), and a set of vectors $elts containing the elements which begin a run.
 1131 Really just a wrapper for clump() and rlevec().
 1132 
 1133 See also: L</rle>, L</rlevec>.
 1134 Contributed by Bryan Jurish E<lt>moocow@cpan.orgE<gt>.
 1135 
 1136 =cut
 1137 
 1138 *PDL::rleND = \&rleND;
 1139 sub rleND {
 1140   my $data   = shift;
 1141   my @vdimsN = $data->dims;
 1142 
 1143   ##-- construct output pdls
 1144   my $counts = $#_ >= 0 ? $_[0] : zeroes(long, $vdimsN[$#vdimsN]);
 1145   my $elts   = $#_ >= 1 ? $_[1] : zeroes($data->type, @vdimsN);
 1146 
 1147   ##-- guts: call rlevec()
 1148   rlevec($data->clump($#vdimsN), $counts, $elts->clump($#vdimsN));
 1149 
 1150   return ($counts,$elts);
 1151 }
 1152 
 1153 =head2 rldND
 1154 
 1155 =for sig
 1156 
 1157   Signature: (int counts(N); elts(@vdims,N); [o]data(@vdims,N);)
 1158 
 1159 =for ref
 1160 
 1161 Run-length decode a set of (sorted) n-dimensional values.
 1162 
 1163 Generalization of rld() and rldvec():
 1164 given a vector $counts() of the number of occurrences of each @vdims-dimensioned element,
 1165 and a set $elts() of @vdims-dimensioned elements, run-length decode to $data().
 1166 
 1167 Really just a wrapper for clump() and rldvec().
 1168 
 1169 See also: L</rld>, L</rldvec>.
 1170 Contributed by Bryan Jurish E<lt>moocow@cpan.orgE<gt>.
 1171 
 1172 =cut
 1173 
 1174 *PDL::rldND = \&rldND;
 1175 sub rldND {
 1176   my ($counts,$elts) = (shift,shift);
 1177   my @vdimsN        = $elts->dims;
 1178 
 1179   ##-- construct output pdl
 1180   my ($data);
 1181   if ($#_ >= 0) { $data = $_[0]; }
 1182   else {
 1183     my $size      = $counts->sumover->max; ##-- get maximum size for Nth-dimension for small encodings
 1184     my @countdims = $counts->dims;
 1185     shift(@countdims);
 1186     $data         = zeroes($elts->type, @vdimsN, @countdims);
 1187   }
 1188 
 1189   ##-- guts: call rldvec()
 1190   rldvec($counts, $elts->clump($#vdimsN), $data->clump($#vdimsN));
 1191 
 1192   return $data;
 1193 }
 1194 #line 1195 "Slices.pm"
 1195 
 1196 
 1197 
 1198 #line 950 "../../blib/lib/PDL/PP.pm"
 1199 
 1200 *_clump_int = \&PDL::_clump_int;
 1201 #line 1202 "Slices.pm"
 1202 
 1203 
 1204 
 1205 #line 948 "../../blib/lib/PDL/PP.pm"
 1206 
 1207 
 1208 
 1209 =head2 xchg
 1210 
 1211 =for sig
 1212 
 1213   Signature: (P(); C(); PDL_Indx n1; PDL_Indx n2)
 1214 
 1215 =for ref
 1216 
 1217 exchange two dimensions
 1218 
 1219 Negative dimension indices count from the end.
 1220 
 1221 The command
 1222 
 1223 =for example
 1224 
 1225  $y = $x->xchg(2,3);
 1226 
 1227 creates C<$y> to be like C<$x> except that the dimensions 2 and 3
 1228 are exchanged with each other i.e.
 1229 
 1230  $y->at(5,3,2,8) == $x->at(5,3,8,2)
 1231 
 1232 
 1233 
 1234 =for bad
 1235 
 1236 xchg does not process bad values.
 1237 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1238 
 1239 
 1240 =cut
 1241 #line 1242 "Slices.pm"
 1242 
 1243 
 1244 
 1245 #line 950 "../../blib/lib/PDL/PP.pm"
 1246 
 1247 *xchg = \&PDL::xchg;
 1248 #line 1249 "Slices.pm"
 1249 
 1250 
 1251 
 1252 #line 1502 "slices.pd"
 1253 
 1254 
 1255 =head2 reorder
 1256 
 1257 =for ref
 1258 
 1259 Re-orders the dimensions of a PDL based on the supplied list.
 1260 
 1261 Similar to the L</xchg> method, this method re-orders the dimensions
 1262 of a PDL. While the L</xchg> method swaps the position of two dimensions,
 1263 the reorder method can change the positions of many dimensions at
 1264 once.
 1265 
 1266 =for usage
 1267 
 1268  # Completely reverse the dimension order of a 6-Dim array.
 1269  $reOrderedPDL = $pdl->reorder(5,4,3,2,1,0);
 1270 
 1271 The argument to reorder is an array representing where the current dimensions
 1272 should go in the new array. In the above usage, the argument to reorder
 1273 C<(5,4,3,2,1,0)>
 1274 indicates that the old dimensions (C<$pdl>'s dims) should be re-arranged to make the
 1275 new pdl (C<$reOrderPDL>) according to the following:
 1276 
 1277    Old Position   New Position
 1278    ------------   ------------
 1279    5              0
 1280    4              1
 1281    3              2
 1282    2              3
 1283    1              4
 1284    0              5
 1285 
 1286 You do not need to specify all dimensions, only a complete set
 1287 starting at position 0.  (Extra dimensions are left where they are).
 1288 This means, for example, that you can reorder() the X and Y dimensions of
 1289 an image, and not care whether it is an RGB image with a third dimension running
 1290 across color plane.
 1291 
 1292 =for example
 1293 
 1294 Example:
 1295 
 1296  pdl> $x = sequence(5,3,2);       # Create a 3-d Array
 1297  pdl> p $x
 1298  [
 1299   [
 1300    [ 0  1  2  3  4]
 1301    [ 5  6  7  8  9]
 1302    [10 11 12 13 14]
 1303   ]
 1304   [
 1305    [15 16 17 18 19]
 1306    [20 21 22 23 24]
 1307    [25 26 27 28 29]
 1308   ]
 1309  ]
 1310  pdl> p $x->reorder(2,1,0); # Reverse the order of the 3-D PDL
 1311  [
 1312   [
 1313    [ 0 15]
 1314    [ 5 20]
 1315    [10 25]
 1316   ]
 1317   [
 1318    [ 1 16]
 1319    [ 6 21]
 1320    [11 26]
 1321   ]
 1322   [
 1323    [ 2 17]
 1324    [ 7 22]
 1325    [12 27]
 1326   ]
 1327   [
 1328    [ 3 18]
 1329    [ 8 23]
 1330    [13 28]
 1331   ]
 1332   [
 1333    [ 4 19]
 1334    [ 9 24]
 1335    [14 29]
 1336   ]
 1337  ]
 1338 
 1339 The above is a simple example that could be duplicated by calling
 1340 C<$x-E<gt>xchg(0,2)>, but it demonstrates the basic functionality of reorder.
 1341 
 1342 As this is an index function, any modifications to the
 1343 result PDL will change the parent.
 1344 
 1345 =cut
 1346 
 1347 sub PDL::reorder {
 1348         my ($pdl,@newDimOrder) = @_;
 1349 
 1350         my $arrayMax = $#newDimOrder;
 1351 
 1352         #Error Checking:
 1353         if( $pdl->getndims < scalar(@newDimOrder) ){
 1354                 my $errString = "PDL::reorder: Number of elements (".scalar(@newDimOrder).") in newDimOrder array exceeds\n";
 1355                 $errString .= "the number of dims in the supplied PDL (".$pdl->getndims.")";
 1356                 barf($errString);
 1357         }
 1358 
 1359         # Check to make sure all the dims are within bounds
 1360         for my $i(0..$#newDimOrder) {
 1361           my $dim = $newDimOrder[$i];
 1362           if($dim < 0 || $dim > $#newDimOrder) {
 1363               my $errString = "PDL::reorder: Dim index $newDimOrder[$i] out of range in position $i\n(range is 0-$#newDimOrder)";
 1364               barf($errString);
 1365           }
 1366         }
 1367 
 1368         # Checking that they are all present and also not duplicated is done by broadcast() [I think]
 1369 
 1370         # a quicker way to do the reorder
 1371         return $pdl->broadcast(@newDimOrder)->unbroadcast(0);
 1372 }
 1373 #line 1374 "Slices.pm"
 1374 
 1375 
 1376 
 1377 #line 948 "../../blib/lib/PDL/PP.pm"
 1378 
 1379 
 1380 
 1381 =head2 mv
 1382 
 1383 =for sig
 1384 
 1385   Signature: (P(); C(); PDL_Indx n1; PDL_Indx n2)
 1386 
 1387 =for ref
 1388 
 1389 move a dimension to another position
 1390 
 1391 The command
 1392 
 1393 =for example
 1394 
 1395  $y = $x->mv(4,1);
 1396 
 1397 creates C<$y> to be like C<$x> except that the dimension 4 is moved to the
 1398 place 1, so:
 1399 
 1400  $y->at(1,2,3,4,5,6) == $x->at(1,5,2,3,4,6);
 1401 
 1402 The other dimensions are moved accordingly.
 1403 Negative dimension indices count from the end.
 1404 
 1405 
 1406 =for bad
 1407 
 1408 mv does not process bad values.
 1409 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1410 
 1411 
 1412 =cut
 1413 #line 1414 "Slices.pm"
 1414 
 1415 
 1416 
 1417 #line 950 "../../blib/lib/PDL/PP.pm"
 1418 
 1419 *mv = \&PDL::mv;
 1420 #line 1421 "Slices.pm"
 1421 
 1422 
 1423 
 1424 #line 1675 "slices.pd"
 1425 
 1426 
 1427 =head2 using
 1428 
 1429 =for ref
 1430 
 1431 Returns array of column numbers requested
 1432 
 1433 =for usage
 1434 
 1435  line $pdl->using(1,2);
 1436 
 1437 Plot, as a line, column 1 of C<$pdl> vs. column 2
 1438 
 1439 =for example
 1440 
 1441  pdl> $pdl = rcols("file");
 1442  pdl> line $pdl->using(1,2);
 1443 
 1444 =cut
 1445 
 1446 *using = \&PDL::using;
 1447 sub PDL::using {
 1448   my ($x,@ind)=@_;
 1449   @ind = list $ind[0] if (blessed($ind[0]) && $ind[0]->isa('PDL'));
 1450   foreach (@ind) {
 1451     $_ = $x->slice("($_)");
 1452   }
 1453   @ind;
 1454 }
 1455 #line 1456 "Slices.pm"
 1456 
 1457 
 1458 
 1459 #line 948 "../../blib/lib/PDL/PP.pm"
 1460 
 1461 
 1462 
 1463 =head2 diagonal
 1464 
 1465 =for sig
 1466 
 1467   Signature: (P(); C(); PDL_Indx whichdims[])
 1468 
 1469 =for ref
 1470 
 1471 Returns the multidimensional diagonal over the specified dimensions.
 1472 
 1473 The diagonal is placed at the first (by number) dimension that is
 1474 diagonalized.
 1475 The other diagonalized dimensions are removed. So if C<$x> has dimensions
 1476 C<(5,3,5,4,6,5)> then after
 1477 
 1478 =for usage
 1479 
 1480  $d = $x->diagonal(dim1, dim2,...)
 1481 
 1482 =for example
 1483 
 1484  $y = $x->diagonal(0,2,5);
 1485 
 1486 the ndarray C<$y> has dimensions C<(5,3,4,6)> and
 1487 C<$y-E<gt>at(2,1,0,1)> refers
 1488 to C<$x-E<gt>at(2,1,2,0,1,2)>.
 1489 
 1490 NOTE: diagonal doesn't handle broadcastids correctly. XXX FIX
 1491 
 1492  pdl> $x = zeroes(3,3,3);
 1493  pdl> ($y = $x->diagonal(0,1))++;
 1494  pdl> p $x
 1495  [
 1496   [
 1497    [1 0 0]
 1498    [0 1 0]
 1499    [0 0 1]
 1500   ]
 1501   [
 1502    [1 0 0]
 1503    [0 1 0]
 1504    [0 0 1]
 1505   ]
 1506   [
 1507    [1 0 0]
 1508    [0 1 0]
 1509    [0 0 1]
 1510   ]
 1511  ]
 1512 
 1513 
 1514 =for bad
 1515 
 1516 diagonal does not process bad values.
 1517 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1518 
 1519 
 1520 =cut
 1521 #line 1522 "Slices.pm"
 1522 
 1523 
 1524 
 1525 #line 949 "../../blib/lib/PDL/PP.pm"
 1526 
 1527 sub PDL::diagonal { shift->_diagonal_int(my $o=PDL->null, \@_); $o }
 1528 #line 1529 "Slices.pm"
 1529 
 1530 
 1531 
 1532 #line 950 "../../blib/lib/PDL/PP.pm"
 1533 
 1534 *diagonal = \&PDL::diagonal;
 1535 #line 1536 "Slices.pm"
 1536 
 1537 
 1538 
 1539 #line 948 "../../blib/lib/PDL/PP.pm"
 1540 
 1541 
 1542 
 1543 =head2 lags
 1544 
 1545 =for sig
 1546 
 1547   Signature: (P(); C(); PDL_Indx nthdim;PDL_Indx step;PDL_Indx n)
 1548 
 1549 =for ref
 1550 
 1551 Returns an ndarray of lags to parent.
 1552 
 1553 Usage:
 1554 
 1555 =for usage
 1556 
 1557   $lags = $x->lags($nthdim,$step,$nlags);
 1558 
 1559 I.e. if C<$x> contains
 1560 
 1561  [0,1,2,3,4,5,6,7]
 1562 
 1563 then
 1564 
 1565 =for example
 1566 
 1567  $y = $x->lags(0,2,2);
 1568 
 1569 is a (5,2) matrix
 1570 
 1571  [2,3,4,5,6,7]
 1572  [0,1,2,3,4,5]
 1573 
 1574 This order of returned indices is kept because the function is
 1575 called "lags" i.e. the nth lag is n steps behind the original.
 1576 
 1577 C<$step> and C<$nlags> must be positive. C<$nthdim> can be
 1578 negative and will then be counted from the last dim backwards
 1579 in the usual way (-1 = last dim).
 1580 
 1581 
 1582 =for bad
 1583 
 1584 lags does not process bad values.
 1585 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1586 
 1587 
 1588 =cut
 1589 #line 1590 "Slices.pm"
 1590 
 1591 
 1592 
 1593 #line 950 "../../blib/lib/PDL/PP.pm"
 1594 
 1595 *lags = \&PDL::lags;
 1596 #line 1597 "Slices.pm"
 1597 
 1598 
 1599 
 1600 #line 948 "../../blib/lib/PDL/PP.pm"
 1601 
 1602 
 1603 
 1604 =head2 splitdim
 1605 
 1606 =for sig
 1607 
 1608   Signature: (P(); C(); PDL_Indx nthdim;PDL_Indx nsp)
 1609 
 1610 =for ref
 1611 
 1612 Splits a dimension in the parent ndarray (opposite of L<clump|PDL::Core/clump>).
 1613 As of 2.076, throws exception if non-divisible C<nsp> given, and can
 1614 give negative C<nthdim> which then counts backwards.
 1615 
 1616 =for example
 1617 
 1618 After
 1619 
 1620  $y = $x->splitdim(2,3);
 1621 
 1622 the expression
 1623 
 1624  $y->at(6,4,m,n,3,6) == $x->at(6,4,m+3*n)
 1625 
 1626 is always true (C<m> has to be less than 3).
 1627 
 1628 
 1629 =for bad
 1630 
 1631 splitdim does not process bad values.
 1632 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1633 
 1634 
 1635 =cut
 1636 #line 1637 "Slices.pm"
 1637 
 1638 
 1639 
 1640 #line 950 "../../blib/lib/PDL/PP.pm"
 1641 
 1642 *splitdim = \&PDL::splitdim;
 1643 #line 1644 "Slices.pm"
 1644 
 1645 
 1646 
 1647 #line 948 "../../blib/lib/PDL/PP.pm"
 1648 
 1649 
 1650 
 1651 =head2 rotate
 1652 
 1653 =for sig
 1654 
 1655   Signature: (x(n); indx shift(); [oca]y(n))
 1656 
 1657 =for ref
 1658 
 1659 Shift vector elements along with wrap. Flows data back&forth.
 1660 
 1661 
 1662 =for bad
 1663 
 1664 rotate does not process bad values.
 1665 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1666 
 1667 
 1668 =cut
 1669 #line 1670 "Slices.pm"
 1670 
 1671 
 1672 
 1673 #line 950 "../../blib/lib/PDL/PP.pm"
 1674 
 1675 *rotate = \&PDL::rotate;
 1676 #line 1677 "Slices.pm"
 1677 
 1678 
 1679 
 1680 #line 948 "../../blib/lib/PDL/PP.pm"
 1681 
 1682 
 1683 
 1684 =head2 broadcastI
 1685 
 1686 =for sig
 1687 
 1688   Signature: (P(); C(); PDL_Indx id; PDL_Indx whichdims[])
 1689 
 1690 =for ref
 1691 
 1692 internal
 1693 
 1694 Put some dimensions to a broadcastid.
 1695 
 1696 =for example
 1697 
 1698  $y = $x->broadcastI(0,1,5); # broadcast over dims 1,5 in id 1
 1699 
 1700 
 1701 
 1702 =for bad
 1703 
 1704 broadcastI does not process bad values.
 1705 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1706 
 1707 
 1708 =cut
 1709 #line 1710 "Slices.pm"
 1710 
 1711 
 1712 
 1713 #line 950 "../../blib/lib/PDL/PP.pm"
 1714 
 1715 *broadcastI = \&PDL::broadcastI;
 1716 #line 1717 "Slices.pm"
 1717 
 1718 
 1719 
 1720 #line 948 "../../blib/lib/PDL/PP.pm"
 1721 
 1722 
 1723 
 1724 =head2 unbroadcast
 1725 
 1726 =for sig
 1727 
 1728   Signature: (P(); C(); PDL_Indx atind)
 1729 
 1730 =for ref
 1731 
 1732 All broadcasted dimensions are made real again.
 1733 
 1734 See [TBD Doc] for details and examples.
 1735 
 1736 
 1737 =for bad
 1738 
 1739 unbroadcast does not process bad values.
 1740 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 1741 
 1742 
 1743 =cut
 1744 #line 1745 "Slices.pm"
 1745 
 1746 
 1747 
 1748 #line 950 "../../blib/lib/PDL/PP.pm"
 1749 
 1750 *unbroadcast = \&PDL::unbroadcast;
 1751 #line 1752 "Slices.pm"
 1752 
 1753 
 1754 
 1755 #line 2110 "slices.pd"
 1756 
 1757 
 1758 =head2 dice
 1759 
 1760 =for ref
 1761 
 1762 Dice rows/columns/planes out of a PDL using indexes for
 1763 each dimension.
 1764 
 1765 This function can be used to extract irregular subsets
 1766 along many dimension of a PDL, e.g. only certain rows in an image,
 1767 or planes in a cube. This can of course be done with
 1768 the usual dimension tricks but this saves having to
 1769 figure it out each time!
 1770 
 1771 This method is similar in functionality to the L</slice>
 1772 method, but L</slice> requires that contiguous ranges or ranges
 1773 with constant offset be extracted. ( i.e. L</slice> requires
 1774 ranges of the form C<1,2,3,4,5> or C<2,4,6,8,10>). Because of this
 1775 restriction, L</slice> is more memory efficient and slightly faster
 1776 than dice
 1777 
 1778 =for usage
 1779 
 1780  $slice = $data->dice([0,2,6],[2,1,6]); # Dicing a 2-D array
 1781 
 1782 The arguments to dice are arrays (or 1D PDLs) for each dimension
 1783 in the PDL. These arrays are used as indexes to which rows/columns/cubes,etc
 1784 to dice-out (or extract) from the C<$data> PDL.
 1785 
 1786 Use C<X> to select all indices along a given dimension (compare also
 1787 L<mslice|PDL::Core/mslice>). As usual (in slicing methods) trailing
 1788 dimensions can be omitted implying C<X>'es for those.
 1789 
 1790 =for example
 1791 
 1792  pdl> $x = sequence(10,4)
 1793  pdl> p $x
 1794  [
 1795   [ 0  1  2  3  4  5  6  7  8  9]
 1796   [10 11 12 13 14 15 16 17 18 19]
 1797   [20 21 22 23 24 25 26 27 28 29]
 1798   [30 31 32 33 34 35 36 37 38 39]
 1799  ]
 1800  pdl> p $x->dice([1,2],[0,3]) # Select columns 1,2 and rows 0,3
 1801  [
 1802   [ 1  2]
 1803   [31 32]
 1804  ]
 1805  pdl> p $x->dice(X,[0,3])
 1806  [
 1807   [ 0  1  2  3  4  5  6  7  8  9]
 1808   [30 31 32 33 34 35 36 37 38 39]
 1809  ]
 1810  pdl> p $x->dice([0,2,5])
 1811  [
 1812   [ 0  2  5]
 1813   [10 12 15]
 1814   [20 22 25]
 1815   [30 32 35]
 1816  ]
 1817 
 1818 As this is an index function, any modifications to the
 1819 slice will change the parent (use the C<.=> operator).
 1820 
 1821 =cut
 1822 
 1823 sub PDL::dice {
 1824 
 1825         my $self = shift;
 1826         my @dim_indexes = @_;  # array of dimension indexes
 1827 
 1828         # Check that the number of dim indexes <=
 1829         #    number of dimensions in the PDL
 1830         my $no_indexes = scalar(@dim_indexes);
 1831         my $noDims = $self->getndims;
 1832         barf("PDL::dice: Number of index arrays ($no_indexes) not equal to the dimensions of the PDL ($noDims")
 1833                          if $no_indexes > $noDims;
 1834         my $index;
 1835         my $pdlIndex;
 1836         my $outputPDL=$self;
 1837         my $indexNo = 0;
 1838 
 1839         # Go thru each index array and dice the input PDL:
 1840         foreach $index(@dim_indexes){
 1841                 $outputPDL = $outputPDL->dice_axis($indexNo,$index)
 1842                         unless !ref $index && $index eq 'X';
 1843 
 1844                 $indexNo++;
 1845         }
 1846 
 1847         return $outputPDL;
 1848 }
 1849 *dice = \&PDL::dice;
 1850 
 1851 =head2 dice_axis
 1852 
 1853 =for ref
 1854 
 1855 Dice rows/columns/planes from a single PDL axis (dimension)
 1856 using index along a specified axis
 1857 
 1858 This function can be used to extract irregular subsets
 1859 along any dimension, e.g. only certain rows in an image,
 1860 or planes in a cube. This can of course be done with
 1861 the usual dimension tricks but this saves having to
 1862 figure it out each time!
 1863 
 1864 =for usage
 1865 
 1866  $slice = $data->dice_axis($axis,$index);
 1867 
 1868 =for example
 1869 
 1870  pdl> $x = sequence(10,4)
 1871  pdl> $idx = pdl(1,2)
 1872  pdl> p $x->dice_axis(0,$idx) # Select columns
 1873  [
 1874   [ 1  2]
 1875   [11 12]
 1876   [21 22]
 1877   [31 32]
 1878  ]
 1879  pdl> $t = $x->dice_axis(1,$idx) # Select rows
 1880  pdl> $t.=0
 1881  pdl> p $x
 1882  [
 1883   [ 0  1  2  3  4  5  6  7  8  9]
 1884   [ 0  0  0  0  0  0  0  0  0  0]
 1885   [ 0  0  0  0  0  0  0  0  0  0]
 1886   [30 31 32 33 34 35 36 37 38 39]
 1887  ]
 1888 
 1889 The trick to using this is that the index selects
 1890 elements along the dimensions specified, so if you
 1891 have a 2D image C<axis=0> will select certain C<X> values
 1892 - i.e. extract columns
 1893 
 1894 As this is an index function, any modifications to the
 1895 slice will change the parent.
 1896 
 1897 =cut
 1898 
 1899 sub PDL::dice_axis {
 1900   my($self,$axis,$idx) = @_;
 1901   my $ix = PDL->topdl($idx);
 1902   barf("dice_axis: index must be <=1D") if $ix->getndims > 1;
 1903   return $self->mv($axis,0)->index1d($ix)->mv(0,$axis);
 1904 }
 1905 *dice_axis = \&PDL::dice_axis;
 1906 #line 1907 "Slices.pm"
 1907 
 1908 
 1909 
 1910 #line 948 "../../blib/lib/PDL/PP.pm"
 1911 
 1912 
 1913 
 1914 =head2 slice
 1915 
 1916 =for sig
 1917 
 1918   Signature: (P(); C(); pdl_slice_args *arglist)
 1919 
 1920 =for usage
 1921 
 1922   $slice = $data->slice([2,3],'x',[2,2,0],"-1:1:-1", "*3");
 1923 
 1924 =for ref
 1925 
 1926 Extract rectangular slices of an ndarray, from a string specifier,
 1927 an array ref specifier, or a combination.
 1928 
 1929 C<slice> is the main method for extracting regions of PDLs and
 1930 manipulating their dimensionality.  You can call it directly or
 1931 via the L<NiceSlice|PDL::NiceSlice> source prefilter that extends
 1932 Perl syntax to include array slicing.
 1933 
 1934 C<slice> can extract regions along each dimension of a source PDL,
 1935 subsample or reverse those regions, dice each dimension by selecting a
 1936 list of locations along it, or basic PDL indexing routine.  The
 1937 selected subfield remains connected to the original PDL via dataflow.
 1938 In most cases this neither allocates more memory nor slows down
 1939 subsequent operations on either of the two connected PDLs.
 1940 
 1941 You pass in a list of arguments.  Each term in the list controls
 1942 the disposition of one axis of the source PDL and/or returned PDL.
 1943 Each term can be a string-format cut specifier, a list ref that
 1944 gives the same information without recourse to string manipulation,
 1945 or a PDL with up to 1 dimension giving indices along that axis that
 1946 should be selected.
 1947 
 1948 If you want to pass in a single string specifier for the entire
 1949 operation, you can pass in a comma-delimited list as the first
 1950 argument.  C<slice> detects this condition and splits the string
 1951 into a regular argument list.  This calling style is fully
 1952 backwards compatible with C<slice> calls from before PDL 2.006.
 1953 
 1954 B<STRING SYNTAX>
 1955 
 1956 If a particular argument to C<slice> is a string, it is parsed as a
 1957 selection, an affine slice, or a dummy dimension depending on the
 1958 form.  Leading or trailing whitespace in any part of each specifier is
 1959 ignored (though it is not ignored within numbers).
 1960 
 1961 =over 3
 1962 
 1963 =item C<< '' >>, C<< : >>, or C<< X >> -- keep
 1964 
 1965 The empty string, C<:>, or C<X> cause the entire corresponding
 1966 dimension to be kept unchanged.
 1967 
 1968 
 1969 =item C<< <n> >> -- selection
 1970 
 1971 A single number alone causes a single index to be selected from the
 1972 corresponding dimension.  The dimension is kept (and reduced to size
 1973 1) in the output.
 1974 
 1975 =item C<< (<n>) >> -- selection and collapse
 1976 
 1977 A single number in parenthesis causes a single index to be selected
 1978 from the corresponding dimension.  The dimension is discarded
 1979 (completely eliminated) in the output.
 1980 
 1981 =item C<< <n>:<m> >> -- select an inclusive range
 1982 
 1983 Two numbers separated by a colon selects a range of values from the
 1984 corresponding axis, e.g. C<< 3:4 >> selects elements 3 and 4 along the
 1985 corresponding axis, and reduces that axis to size 2 in the output.
 1986 Both numbers are regularized so that you can address the last element
 1987 of the axis with an index of C< -1 >.  If, after regularization, the
 1988 two numbers are the same, then exactly one element gets selected (just
 1989 like the C<< <n> >> case).  If, after regulariation, the second number
 1990 is lower than the first, then the resulting slice counts down rather
 1991 than up -- e.g. C<-1:0> will return the entire axis, in reversed
 1992 order.
 1993 
 1994 =item C<< <n>:<m>:<s> >> -- select a range with explicit step
 1995 
 1996 If you include a third parameter, it is the stride of the extracted
 1997 range.  For example, C<< 0:-1:2 >> will sample every other element
 1998 across the complete dimension.  Specifying a stride of 1 prevents
 1999 autoreversal -- so to ensure that your slice is *always* forward
 2000 you can specify, e.g., C<< 2:$n:1 >>.  In that case, an "impossible"
 2001 slice gets an Empty PDL (with 0 elements along the corresponding
 2002 dimension), so you can generate an Empty PDL with a slice of the
 2003 form C<< 2:1:1 >>.
 2004 
 2005 =item C<< *<n> >> -- insert a dummy dimension
 2006 
 2007 Dummy dimensions aren't present in the original source and are
 2008 "mocked up" to match dimensional slots, by repeating the data
 2009 in the original PDL some number of times.  An asterisk followed
 2010 by a number produces a dummy dimension in the output, for
 2011 example C<< *2 >> will generate a dimension of size 2 at
 2012 the corresponding location in the output dim list.  Omitting
 2013 the number (and using just an asterisk) inserts a dummy dimension
 2014 of size 1.
 2015 
 2016 =back
 2017 
 2018 B<ARRAY REF SYNTAX>
 2019 
 2020 If you feed in an ARRAY ref as a slice term, then it can have
 2021 0-3 elements.  The first element is the start of the slice along
 2022 the corresponding dim; the second is the end; and the third is
 2023 the stepsize.  Different combinations of inputs give the same
 2024 flexibility as the string syntax.
 2025 
 2026 =over 3
 2027 
 2028 =item C<< [] >> - keep dim intact
 2029 
 2030 An empty ARRAY ref keeps the entire corresponding dim
 2031 
 2032 =item C<< [ 'X' ] >> - keep dim intact
 2033 
 2034 =item C<< [ '*',$n ] >> - generate a dummy dim of size $n
 2035 
 2036 If $n is missing, you get a dummy dim of size 1.
 2037 
 2038 =item C<< [ $dex, , 0 ] >> - collapse and discard dim
 2039 
 2040 C<$dex> must be a single value.  It is used to index
 2041 the source, and the corresponding dimension is discarded.
 2042 
 2043 =item C<< [ $start, $end ] >> - collect inclusive slice
 2044 
 2045 In the simple two-number case, you get a slice that runs
 2046 up or down (as appropriate) to connect $start and $end.
 2047 
 2048 =item C<< [ $start, $end, $inc ] >> - collect inclusive slice
 2049 
 2050 The three-number case works exactly like the three-number
 2051 string case above.
 2052 
 2053 =back
 2054 
 2055 B<PDL args for dicing>
 2056 
 2057 If you pass in a 0- or 1-D PDL as a slicing argument, the
 2058 corresponding dimension is "diced" -- you get one position
 2059 along the corresponding dim, per element of the indexing PDL,
 2060 e.g. C<< $x->slice( pdl(3,4,9)) >> gives you elements 3, 4, and
 2061 9 along the 0 dim of C<< $x >>.
 2062 
 2063 Because dicing is not an affine transformation, it is slower than
 2064 direct slicing even though the syntax is convenient.
 2065 
 2066 =for example
 2067 
 2068  $x->slice('1:3');  #  return the second to fourth elements of $x
 2069  $x->slice('3:1');  #  reverse the above
 2070  $x->slice('-2:1'); #  return last-but-one to second elements of $x
 2071 
 2072  $x->slice([1,3]);  # Same as above three calls, but using array ref syntax
 2073  $x->slice([3,1]);
 2074  $x->slice([-2,1]);
 2075 
 2076 
 2077 =for bad
 2078 
 2079 slice does not process bad values.
 2080 It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
 2081 
 2082 
 2083 =cut
 2084 #line 2085 "Slices.pm"
 2085 
 2086 
 2087 
 2088 #line 949 "../../blib/lib/PDL/PP.pm"
 2089 
 2090 sub PDL::slice {
 2091     my ($source, @others) = @_;
 2092     for my $i(0..$#others) {
 2093       my $idx = $others[$i];
 2094       if (ref $idx eq 'ARRAY') {
 2095         my @arr = map UNIVERSAL::isa($_, 'PDL') ? $_->flat->at(0) : $_, @{$others[$i]};
 2096         $others[$i] = \@arr;
 2097         next;
 2098       }
 2099       next if !( blessed($idx) && $idx->isa('PDL') );
 2100       # Deal with dicing.  This is lame and slow compared to the
 2101       # faster slicing, but works okay.  We loop over each argument,
 2102       # and if it's a PDL we dispatch it in the most straightforward
 2103       # way.  Single-element and zero-element PDLs are trivial and get
 2104       # converted into slices for faster handling later.
 2105       barf("slice: dicing parameters must be at most 1D (arg $i)\n")
 2106         if $idx->ndims > 1;
 2107       my $nlm = $idx->nelem;
 2108       if($nlm > 1) {
 2109          #### More than one element - we have to dice (darn it).
 2110          my $n = $source->getndims;
 2111          $source = $source->mv($i,0)->index1d($idx)->mv(0,$i);
 2112          $others[$i] = '';
 2113       }
 2114       elsif($nlm) {
 2115          #### One element - convert to a regular slice.
 2116          $others[$i] = $idx->flat->at(0);
 2117       }
 2118       else {
 2119          #### Zero elements -- force an extended empty.
 2120          $others[$i] = "1:0:1";
 2121       }
 2122     }
 2123     PDL::_slice_int($source,my $o=$source->initialize,\@others);
 2124     $o;
 2125 }
 2126 #line 2127 "Slices.pm"
 2127 
 2128 
 2129 
 2130 #line 950 "../../blib/lib/PDL/PP.pm"
 2131 
 2132 *slice = \&PDL::slice;
 2133 #line 2134 "Slices.pm"
 2134 
 2135 
 2136 
 2137 
 2138 
 2139 #line 2599 "slices.pd"
 2140 
 2141 
 2142 =head1 BUGS
 2143 
 2144 For the moment, you can't slice one of the zero-length dims of an
 2145 empty ndarray.  It is not clear how to implement this in a way that makes
 2146 sense.
 2147 
 2148 Many types of index errors are reported far from the indexing
 2149 operation that caused them.  This is caused by the underlying architecture:
 2150 slice() sets up a mapping between variables, but that mapping isn't
 2151 tested for correctness until it is used (potentially much later).
 2152 
 2153 =head1 AUTHOR
 2154 
 2155 Copyright (C) 1997 Tuomas J. Lukka.  Contributions by
 2156 Craig DeForest, deforest@boulder.swri.edu.
 2157 Documentation contributions by David Mertens.
 2158 All rights reserved. There is no warranty. You are allowed
 2159 to redistribute this software / documentation under certain
 2160 conditions. For details, see the file COPYING in the PDL
 2161 distribution. If this file is separated from the PDL distribution,
 2162 the copyright notice should be included in the file.
 2163 
 2164 =cut
 2165 #line 2166 "Slices.pm"
 2166 
 2167 
 2168 
 2169 
 2170 # Exit with OK status
 2171 
 2172 1;