"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "GENERATED/PDL/Slices.pm" between
PDL-2.074.tar.gz and PDL-2.075.tar.gz

About: PDL (Perl Data Language) aims to turn perl into an efficient numerical language for scientific computing (similar to IDL and MatLab).

Slices.pm  (PDL-2.074):Slices.pm  (PDL-2.075)
# #
# GENERATED WITH PDL::PP! Don't modify! # GENERATED WITH PDL::PP! Don't modify!
# #
package PDL::Slices; package PDL::Slices;
our @EXPORT_OK = qw(index index1d index2d indexND indexNDb rangeb rld rle _clump _int xchg mv using diagonal lags splitdim rotate threadI unthread dice dice_axis slice ); our @EXPORT_OK = qw(index index1d index2d indexND indexNDb rangeb rld rle _clump _int xchg mv using diagonal lags splitdim rotate broadcastI unbroadcast dice dic e_axis slice );
our %EXPORT_TAGS = (Func=>\@EXPORT_OK); our %EXPORT_TAGS = (Func=>\@EXPORT_OK);
use PDL::Core; use PDL::Core;
use PDL::Exporter; use PDL::Exporter;
use DynaLoader; use DynaLoader;
our @ISA = ( 'PDL::Exporter','DynaLoader' ); our @ISA = ( 'PDL::Exporter','DynaLoader' );
push @PDL::Core::PP, __PACKAGE__; push @PDL::Core::PP, __PACKAGE__;
bootstrap PDL::Slices ; bootstrap PDL::Slices ;
#line 6 "slices.pd" #line 5 "slices.pd"
=head1 NAME =head1 NAME
PDL::Slices -- Indexing, slicing, and dicing PDL::Slices -- Indexing, slicing, and dicing
=head1 SYNOPSIS =head1 SYNOPSIS
use PDL; use PDL;
$x = ones(3,3); $x = ones(3,3);
$y = $x->slice('-1:0,(1)'); $y = $x->slice('-1:0,(1)');
skipping to change at line 81 skipping to change at line 81
then the variables C<$y> and C<$c> point to the same object but with then the variables C<$y> and C<$c> point to the same object but with
C<-E<gt>copy> they would not. C<-E<gt>copy> they would not.
=cut =cut
use strict; use strict;
use warnings; use warnings;
use PDL::Core ':Internal'; use PDL::Core ':Internal';
use Scalar::Util 'blessed'; use Scalar::Util 'blessed';
#line 90 "Slices.pm" #line 91 "Slices.pm"
=head1 FUNCTIONS =head1 FUNCTIONS
=cut =cut
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 index =head2 index
=for sig =for sig
Signature: (a(n); indx ind(); [oca] c()) Signature: (a(n); indx ind(); [oca] c())
=for ref =for ref
C<index>, C<index1d>, and C<index2d> provide rudimentary index indirection. C<index>, C<index1d>, and C<index2d> provide rudimentary index indirection.
=for example =for example
$c = index($source,$ind); $c = index($source,$ind);
$c = index1d($source,$ind); $c = index1d($source,$ind);
$c = index2d($source2,$ind1,$ind2); $c = index2d($source2,$ind1,$ind2);
use the C<$ind> variables as indices to look up values in C<$source>. use the C<$ind> variables as indices to look up values in C<$source>.
The three routines thread slightly differently. The three routines broadcast slightly differently.
=over 3 =over 3
=item * =item *
C<index> uses direct threading for 1-D indexing across the 0 dim C<index> uses direct broadcasting for 1-D indexing across the 0 dim
of C<$source>. It can thread over source thread dims or index thread of C<$source>. It can broadcast over source broadcast dims or index broadcast
dims, but not (easily) both: If C<$source> has more than 1 dims, but not (easily) both: If C<$source> has more than 1
dimension and C<$ind> has more than 0 dimensions, they must agree in dimension and C<$ind> has more than 0 dimensions, they must agree in
a threading sense. a broadcasting sense.
=item * =item *
C<index1d> uses a single active dim in C<$ind> to produce a list of C<index1d> uses a single active dim in C<$ind> to produce a list of
indexed values in the 0 dim of the output - it is useful for indexed values in the 0 dim of the output - it is useful for
collapsing C<$source> by indexing with a single row of values along collapsing C<$source> by indexing with a single row of values along
C<$source>'s 0 dimension. The output has the same number of dims as C<$source>'s 0 dimension. The output has the same number of dims as
C<$source>. The 0 dim of the output has size 1 if C<$ind> is a C<$source>. The 0 dim of the output has size 1 if C<$ind> is a
scalar, and the same size as the 0 dim of C<$ind> if it is not. If scalar, and the same size as the 0 dim of C<$ind> if it is not. If
C<$ind> and C<$source> both have more than 1 dim, then all dims higher C<$ind> and C<$source> both have more than 1 dim, then all dims higher
than 0 must agree in a threading sense. than 0 must agree in a broadcasting sense.
=item * =item *
C<index2d> works like C<index> but uses separate ndarrays for X and Y C<index2d> works like C<index> but uses separate ndarrays for X and Y
coordinates. For more general N-dimensional indexing, see the coordinates. For more general N-dimensional indexing, see the
L<PDL::NiceSlice> syntax or L<PDL::Slices> (in particular C<slice>, L<PDL::NiceSlice> syntax or L<PDL::Slices> (in particular C<slice>,
C<indexND>, and C<range>). C<indexND>, and C<range>).
=back =back
These functions are two-way, i.e. after These functions are two-way, i.e. after
$c = $x->index(pdl[0,5,8]); $c = $x->index(pdl[0,5,8]);
$c .= pdl [0,2,4]; $c .= pdl [0,2,4];
the changes in C<$c> will flow back to C<$x>. the changes in C<$c> will flow back to C<$x>.
C<index> provids simple threading: multiple-dimensioned arrays are treated C<index> provids simple broadcasting: multiple-dimensioned arrays are treated
as collections of 1-D arrays, so that as collections of 1-D arrays, so that
$x = xvals(10,10)+10*yvals(10,10); $x = xvals(10,10)+10*yvals(10,10);
$y = $x->index(3); $y = $x->index(3);
$c = $x->index(9-xvals(10)); $c = $x->index(9-xvals(10));
puts a single column from C<$x> into C<$y>, and puts a single element puts a single column from C<$x> into C<$y>, and puts a single element
from each column of C<$x> into C<$c>. If you want to extract multiple from each column of C<$x> into C<$c>. If you want to extract multiple
columns from an array in one operation, see L</dice> or columns from an array in one operation, see L</dice> or
L</indexND>. L</indexND>.
=for bad =for bad
index barfs if any of the index values are bad. index barfs if any of the index values are bad.
=cut =cut
#line 182 "Slices.pm" #line 184 "Slices.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*index = \&PDL::index; *index = \&PDL::index;
#line 188 "Slices.pm" #line 191 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 index1d =head2 index1d
=for sig =for sig
Signature: (a(n); indx ind(m); [oca] c(m)) Signature: (a(n); indx ind(m); [oca] c(m))
=for ref =for ref
C<index>, C<index1d>, and C<index2d> provide rudimentary index indirection. C<index>, C<index1d>, and C<index2d> provide rudimentary index indirection.
=for example =for example
$c = index($source,$ind); $c = index($source,$ind);
$c = index1d($source,$ind); $c = index1d($source,$ind);
$c = index2d($source2,$ind1,$ind2); $c = index2d($source2,$ind1,$ind2);
use the C<$ind> variables as indices to look up values in C<$source>. use the C<$ind> variables as indices to look up values in C<$source>.
The three routines thread slightly differently. The three routines broadcast slightly differently.
=over 3 =over 3
=item * =item *
C<index> uses direct threading for 1-D indexing across the 0 dim C<index> uses direct broadcasting for 1-D indexing across the 0 dim
of C<$source>. It can thread over source thread dims or index thread of C<$source>. It can broadcast over source broadcast dims or index broadcast
dims, but not (easily) both: If C<$source> has more than 1 dims, but not (easily) both: If C<$source> has more than 1
dimension and C<$ind> has more than 0 dimensions, they must agree in dimension and C<$ind> has more than 0 dimensions, they must agree in
a threading sense. a broadcasting sense.
=item * =item *
C<index1d> uses a single active dim in C<$ind> to produce a list of C<index1d> uses a single active dim in C<$ind> to produce a list of
indexed values in the 0 dim of the output - it is useful for indexed values in the 0 dim of the output - it is useful for
collapsing C<$source> by indexing with a single row of values along collapsing C<$source> by indexing with a single row of values along
C<$source>'s 0 dimension. The output has the same number of dims as C<$source>'s 0 dimension. The output has the same number of dims as
C<$source>. The 0 dim of the output has size 1 if C<$ind> is a C<$source>. The 0 dim of the output has size 1 if C<$ind> is a
scalar, and the same size as the 0 dim of C<$ind> if it is not. If scalar, and the same size as the 0 dim of C<$ind> if it is not. If
C<$ind> and C<$source> both have more than 1 dim, then all dims higher C<$ind> and C<$source> both have more than 1 dim, then all dims higher
than 0 must agree in a threading sense. than 0 must agree in a broadcasting sense.
=item * =item *
C<index2d> works like C<index> but uses separate ndarrays for X and Y C<index2d> works like C<index> but uses separate ndarrays for X and Y
coordinates. For more general N-dimensional indexing, see the coordinates. For more general N-dimensional indexing, see the
L<PDL::NiceSlice> syntax or L<PDL::Slices> (in particular C<slice>, L<PDL::NiceSlice> syntax or L<PDL::Slices> (in particular C<slice>,
C<indexND>, and C<range>). C<indexND>, and C<range>).
=back =back
These functions are two-way, i.e. after These functions are two-way, i.e. after
$c = $x->index(pdl[0,5,8]); $c = $x->index(pdl[0,5,8]);
$c .= pdl [0,2,4]; $c .= pdl [0,2,4];
the changes in C<$c> will flow back to C<$x>. the changes in C<$c> will flow back to C<$x>.
C<index> provids simple threading: multiple-dimensioned arrays are treated C<index> provids simple broadcasting: multiple-dimensioned arrays are treated
as collections of 1-D arrays, so that as collections of 1-D arrays, so that
$x = xvals(10,10)+10*yvals(10,10); $x = xvals(10,10)+10*yvals(10,10);
$y = $x->index(3); $y = $x->index(3);
$c = $x->index(9-xvals(10)); $c = $x->index(9-xvals(10));
puts a single column from C<$x> into C<$y>, and puts a single element puts a single column from C<$x> into C<$y>, and puts a single element
from each column of C<$x> into C<$c>. If you want to extract multiple from each column of C<$x> into C<$c>. If you want to extract multiple
columns from an array in one operation, see L</dice> or columns from an array in one operation, see L</dice> or
L</indexND>. L</indexND>.
=for bad =for bad
index1d propagates BAD index elements to the output variable. index1d propagates BAD index elements to the output variable.
=cut =cut
#line 270 "Slices.pm" #line 274 "Slices.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*index1d = \&PDL::index1d; *index1d = \&PDL::index1d;
#line 276 "Slices.pm" #line 281 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 index2d =head2 index2d
=for sig =for sig
Signature: (a(na,nb); indx inda(); indx indb(); [oca] c()) Signature: (a(na,nb); indx inda(); indx indb(); [oca] c())
=for ref =for ref
C<index>, C<index1d>, and C<index2d> provide rudimentary index indirection. C<index>, C<index1d>, and C<index2d> provide rudimentary index indirection.
=for example =for example
$c = index($source,$ind); $c = index($source,$ind);
$c = index1d($source,$ind); $c = index1d($source,$ind);
$c = index2d($source2,$ind1,$ind2); $c = index2d($source2,$ind1,$ind2);
use the C<$ind> variables as indices to look up values in C<$source>. use the C<$ind> variables as indices to look up values in C<$source>.
The three routines thread slightly differently. The three routines broadcast slightly differently.
=over 3 =over 3
=item * =item *
C<index> uses direct threading for 1-D indexing across the 0 dim C<index> uses direct broadcasting for 1-D indexing across the 0 dim
of C<$source>. It can thread over source thread dims or index thread of C<$source>. It can broadcast over source broadcast dims or index broadcast
dims, but not (easily) both: If C<$source> has more than 1 dims, but not (easily) both: If C<$source> has more than 1
dimension and C<$ind> has more than 0 dimensions, they must agree in dimension and C<$ind> has more than 0 dimensions, they must agree in
a threading sense. a broadcasting sense.
=item * =item *
C<index1d> uses a single active dim in C<$ind> to produce a list of C<index1d> uses a single active dim in C<$ind> to produce a list of
indexed values in the 0 dim of the output - it is useful for indexed values in the 0 dim of the output - it is useful for
collapsing C<$source> by indexing with a single row of values along collapsing C<$source> by indexing with a single row of values along
C<$source>'s 0 dimension. The output has the same number of dims as C<$source>'s 0 dimension. The output has the same number of dims as
C<$source>. The 0 dim of the output has size 1 if C<$ind> is a C<$source>. The 0 dim of the output has size 1 if C<$ind> is a
scalar, and the same size as the 0 dim of C<$ind> if it is not. If scalar, and the same size as the 0 dim of C<$ind> if it is not. If
C<$ind> and C<$source> both have more than 1 dim, then all dims higher C<$ind> and C<$source> both have more than 1 dim, then all dims higher
than 0 must agree in a threading sense. than 0 must agree in a broadcasting sense.
=item * =item *
C<index2d> works like C<index> but uses separate ndarrays for X and Y C<index2d> works like C<index> but uses separate ndarrays for X and Y
coordinates. For more general N-dimensional indexing, see the coordinates. For more general N-dimensional indexing, see the
L<PDL::NiceSlice> syntax or L<PDL::Slices> (in particular C<slice>, L<PDL::NiceSlice> syntax or L<PDL::Slices> (in particular C<slice>,
C<indexND>, and C<range>). C<indexND>, and C<range>).
=back =back
These functions are two-way, i.e. after These functions are two-way, i.e. after
$c = $x->index(pdl[0,5,8]); $c = $x->index(pdl[0,5,8]);
$c .= pdl [0,2,4]; $c .= pdl [0,2,4];
the changes in C<$c> will flow back to C<$x>. the changes in C<$c> will flow back to C<$x>.
C<index> provids simple threading: multiple-dimensioned arrays are treated C<index> provids simple broadcasting: multiple-dimensioned arrays are treated
as collections of 1-D arrays, so that as collections of 1-D arrays, so that
$x = xvals(10,10)+10*yvals(10,10); $x = xvals(10,10)+10*yvals(10,10);
$y = $x->index(3); $y = $x->index(3);
$c = $x->index(9-xvals(10)); $c = $x->index(9-xvals(10));
puts a single column from C<$x> into C<$y>, and puts a single element puts a single column from C<$x> into C<$y>, and puts a single element
from each column of C<$x> into C<$c>. If you want to extract multiple from each column of C<$x> into C<$c>. If you want to extract multiple
columns from an array in one operation, see L</dice> or columns from an array in one operation, see L</dice> or
L</indexND>. L</indexND>.
=for bad =for bad
index2d barfs if either of the index values are bad. index2d barfs if either of the index values are bad.
=cut =cut
#line 358 "Slices.pm" #line 364 "Slices.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*index2d = \&PDL::index2d; *index2d = \&PDL::index2d;
#line 364 "Slices.pm" #line 371 "Slices.pm"
#line 300 "slices.pd" #line 299 "slices.pd"
=head2 indexNDb =head2 indexNDb
=for ref =for ref
Backwards-compatibility alias for indexND Backwards-compatibility alias for indexND
=head2 indexND =head2 indexND
=for ref =for ref
skipping to change at line 380 skipping to change at line 383
PDL, suitable for feeding to this. PDL, suitable for feeding to this.
=cut =cut
sub PDL::indexND { sub PDL::indexND {
my($source,$index, $boundary) = @_; my($source,$index, $boundary) = @_;
return PDL::range($source,$index,undef,$boundary); return PDL::range($source,$index,undef,$boundary);
} }
*PDL::indexNDb = \&PDL::indexND; *PDL::indexNDb = \&PDL::indexND;
#line 418 "Slices.pm" #line 426 "Slices.pm"
#line 353 "slices.pd" #line 352 "slices.pd"
sub PDL::range { sub PDL::range {
my($source,$ind,$sz,$bound) = @_; my($source,$ind,$sz,$bound) = @_;
# Convert to indx type up front (also handled in rangeb if necessary) # Convert to indx type up front (also handled in rangeb if necessary)
my $index = (ref $ind && UNIVERSAL::isa($ind,'PDL') && $ind->type eq 'indx') ? $ind : indx($ind); my $index = (ref $ind && UNIVERSAL::isa($ind,'PDL') && $ind->type eq 'indx') ? $ind : indx($ind);
my $size = defined($sz) ? PDL->pdl($sz) : undef; my $size = defined($sz) ? PDL->pdl($sz) : undef;
# Handle empty PDL case: return a properly constructed Empty. # Handle empty PDL case: return a properly constructed Empty.
if($index->isempty) { if($index->isempty) {
skipping to change at line 420 skipping to change at line 423
$bound = $s; $bound = $s;
} }
elsif($bound !~ m/^[0123ftepx]+$/ && $bound =~ m/^([0123ftepx])/i ) { elsif($bound !~ m/^[0123ftepx]+$/ && $bound =~ m/^([0123ftepx])/i ) {
$bound = $1; $bound = $1;
} }
} }
no warnings; # shut up about passing undef into rangeb no warnings; # shut up about passing undef into rangeb
$source->rangeb($index,$size,$bound); $source->rangeb($index,$size,$bound);
} }
#line 463 "Slices.pm" #line 472 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 rangeb =head2 rangeb
=for sig =for sig
Signature: (P(); C(); pdl *ind_pdl; SV *size; SV *boundary_sv) Signature: (P(); C(); pdl *ind_pdl; SV *size; SV *boundary_sv)
=for ref =for ref
Engine for L</range> Engine for L</range>
skipping to change at line 540 skipping to change at line 543
example, the four expressions [0,1], ['forbid','truncate'], ['f','t'], example, the four expressions [0,1], ['forbid','truncate'], ['f','t'],
and 'ft' all specify that violating the boundary in the 0th dimension and 'ft' all specify that violating the boundary in the 0th dimension
throws an error, and all other dimensions get truncated. throws an error, and all other dimensions get truncated.
If you feed in a single string, it is interpreted as a packed boundary 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'), 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'). but as a single word-style specifier if they are not (e.g. 'forbid').
B<OUTPUT> B<OUTPUT>
The output threads over both C<$index> and C<$source>. Because implicit The output broadcasts over both C<$index> and C<$source>. Because implicit
threading can happen in a couple of ways, a little thought is needed. The broadcasting can happen in a couple of ways, a little thought is needed. The
returned dimension list is stacked up like this: returned dimension list is stacked up like this:
(index thread dims), (index dims (size)), (source thread dims) (index broadcast dims), (index dims (size)), (source broadcast dims)
The first few dims of the output correspond to the extra dims of The first few dims of the output correspond to the extra dims of
C<$index> (beyond the 0 dim). They allow you to pick out individual C<$index> (beyond the 0 dim). They allow you to pick out individual
ranges from a large, threaded collection. ranges from a large, broadcasted collection.
The middle few dims of the output correspond to the size dims The middle few dims of the output correspond to the size dims
specified in C<$size>, and contain the range of values that is extracted specified in C<$size>, and contain the range of values that is extracted
at each location in C<$source>. Every nonzero element of C<$size> is copied to at each location in C<$source>. Every nonzero element of C<$size> is copied to
the dimension list here, so that if you feed in (for example) C<$size the dimension list here, so that if you feed in (for example) C<$size
= [2,0,1]> you get an index dim list of C<(2,1)>. = [2,0,1]> you get an index dim list of C<(2,1)>.
The last few dims of the output correspond to extra dims of C<$source> beyond The last few dims of the output correspond to extra dims of C<$source> beyond
the number of dims indexed by C<$index>. These dims act like ordinary the number of dims indexed by C<$index>. These dims act like ordinary
thread dims, because adding more dims to C<$source> just tacks extra dims broadcast dims, because adding more dims to C<$source> just tacks extra dims
on the end of the output. Each source thread dim ranges over the entire on the end of the output. Each source broadcast dim ranges over the entire
corresponding dim of C<$source>. corresponding dim of C<$source>.
B<Dataflow>: Dataflow is bidirectional. B<Dataflow>: Dataflow is bidirectional.
B<Examples>: B<Examples>:
Here are basic examples of C<range> operation, showing how to get Here are basic examples of C<range> operation, showing how to get
ranges out of a small matrix. The first few examples show extraction ranges out of a small matrix. The first few examples show extraction
and selection of individual chunks. The last example shows and selection of individual chunks. The last example shows
how to mark loci in the original matrix (using dataflow). how to mark loci in the original matrix (using dataflow).
skipping to change at line 610 skipping to change at line 613
[11 22] [11 22]
[23 1] [23 1]
] ]
[ [
[21 32] [21 32]
[33 11] [33 11]
] ]
] ]
] ]
pdl> $src = xvals(5,3)*10+yvals(5,3) pdl> $src = xvals(5,3)*10+yvals(5,3)
pdl> print $src->range(3,1) # Thread over y dimension in $src pdl> print $src->range(3,1) # Broadcast over y dimension in $src
[ [
[30] [30]
[31] [31]
[32] [32]
] ]
pdl> $src = zeroes(5,4); pdl> $src = zeroes(5,4);
pdl> $src->range(pdl([2,3],[0,1]),pdl(2,1)) .= xvals(2,2,1) + 1 pdl> $src->range(pdl([2,3],[0,1]),pdl(2,1)) .= xvals(2,2,1) + 1
pdl> print $src pdl> print $src
[ [
skipping to change at line 684 skipping to change at line 687
$x = $data->range($index, $sizes, $bound)->sever; $x = $data->range($index, $sizes, $bound)->sever;
$aa = $data->range($index, $sizes, $bound); $aa = $data->range($index, $sizes, $bound);
map { $x($_ - 1) .= $_; } (1..$x->nelem); # Lots of little ops map { $x($_ - 1) .= $_; } (1..$x->nelem); # Lots of little ops
$aa .= $x; $aa .= $x;
C<range> is a perl front-end to a PP function, C<rangeb>. Calling C<range> is a perl front-end to a PP function, C<rangeb>. Calling
C<rangeb> is marginally faster but requires that you include all arguments. C<rangeb> is marginally faster but requires that you include all arguments.
DEVEL NOTES DEVEL NOTES
* index thread dimensions are effectively clumped internally. This * index broadcast dimensions are effectively clumped internally. This
makes it easier to loop over the index array but a little more brain-bending makes it easier to loop over the index array but a little more brain-bending
to tease out the algorithm. to tease out the algorithm.
=cut =cut
=for bad =for bad
rangeb processes bad values. 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. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
=cut =cut
#line 746 "Slices.pm" #line 756 "Slices.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*rangeb = \&PDL::rangeb; *rangeb = \&PDL::rangeb;
#line 752 "Slices.pm" #line 763 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 rld =head2 rld
=for sig =for sig
Signature: (indx a(n); b(n); [o]c(m)) Signature: (indx a(n); b(n); [o]c(m))
=for ref =for ref
Run-length decode a vector Run-length decode a vector
skipping to change at line 727 skipping to change at line 731
=for example =for example
rld($x,$y,$c=null); rld($x,$y,$c=null);
=for bad =for bad
rld does not process bad values. 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. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
=cut =cut
#line 785 "Slices.pm" #line 797 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
sub PDL::rld { sub PDL::rld {
my ($x,$y) = @_; my ($x,$y) = @_;
my ($c); my ($c);
if ($#_ == 2) { if ($#_ == 2) {
$c = $_[2]; $c = $_[2];
} else { } else {
# XXX Need to improve emulation of threading in auto-generating c # XXX Need to improve emulation of broadcasting in auto-generating c
my ($size) = $x->sumover->max->sclr; my ($size) = $x->sumover->max->sclr;
my (@dims) = $x->dims; my (@dims) = $x->dims;
shift @dims; shift @dims;
$c = $y->zeroes($size,@dims); $c = $y->zeroes($size,@dims);
} }
&PDL::_rld_int($x,$y,$c); &PDL::_rld_int($x,$y,$c);
$c; $c;
} }
#line 805 "Slices.pm" #line 818 "Slices.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*rld = \&PDL::rld; *rld = \&PDL::rld;
#line 811 "Slices.pm" #line 825 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 rle =head2 rle
=for sig =for sig
Signature: (c(n); indx [o]a(m); [o]b(m)) Signature: (c(n); indx [o]a(m); [o]b(m))
=for ref =for ref
Run-length encode a vector Run-length encode a vector
Given vector C<$c>, generate a vector C<$x> with the number of each Given vector C<$c>, generate a vector C<$x> with the number of each
element, and a vector C<$y> of the unique values. New in PDL 2.017, element, and a vector C<$y> of the unique values. New in PDL 2.017,
only the elements up to the first instance of C<0> in C<$x> are only the elements up to the first instance of C<0> in C<$x> are
returned, which makes the common use case of a 1-dimensional C<$c> simpler. returned, which makes the common use case of a 1-dimensional C<$c> simpler.
For threaded operation, C<$x> and C<$y> will be large enough For broadcast operation, C<$x> and C<$y> will be large enough
to hold the largest row of C<$y>, and only the elements up to the to hold the largest row of C<$y>, and only the elements up to the
first instance of C<0> in each row of C<$x> should be considered. first instance of C<0> in each row of C<$x> should be considered.
=for example =for example
$c = floor(4*random(10)); $c = floor(4*random(10));
rle($c,$x=null,$y=null); rle($c,$x=null,$y=null);
#or #or
($x,$y) = rle($c); ($x,$y) = rle($c);
skipping to change at line 802 skipping to change at line 808
$y = $x->cumusumover; $y = $x->cumusumover;
$yprob1x = $y->slice('-1:0')->double / $y->slice('(-1)'); $yprob1x = $y->slice('-1:0')->double / $y->slice('(-1)');
$z = cat($x1, 1 / $yprob1x**$nrolls)->transpose; $z = cat($x1, 1 / $yprob1x**$nrolls)->transpose;
=for bad =for bad
rle does not process bad values. 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. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
=cut =cut
#line 870 "Slices.pm" #line 885 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
sub PDL::rle { sub PDL::rle {
my $c = shift; my $c = shift;
my ($x,$y) = @_==2 ? @_ : (null,null); my ($x,$y) = @_==2 ? @_ : (null,null);
PDL::_rle_int($c,$x,$y); PDL::_rle_int($c,$x,$y);
my $max_ind = ($c->ndims<2) ? ($x!=0)->sumover-1 : my $max_ind = ($c->ndims<2) ? ($x!=0)->sumover-1 :
($x!=0)->clump(1..$x->ndims-1)->sumover->max->sc lr-1; ($x!=0)->clump(1..$x->ndims-1)->sumover->max->sc lr-1;
return ($x->slice("0:$max_ind"),$y->slice("0:$max_ind")); return ($x->slice("0:$max_ind"),$y->slice("0:$max_ind"));
} }
#line 883 "Slices.pm" #line 899 "Slices.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*rle = \&PDL::rle; *rle = \&PDL::rle;
#line 889 "Slices.pm" #line 906 "Slices.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*_clump_int = \&PDL::_clump_int; *_clump_int = \&PDL::_clump_int;
#line 895 "Slices.pm" #line 913 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 xchg =head2 xchg
=for sig =for sig
Signature: (P(); C(); PDL_Indx n1; PDL_Indx n2) Signature: (P(); C(); PDL_Indx n1; PDL_Indx n2)
=for ref =for ref
exchange two dimensions exchange two dimensions
skipping to change at line 854 skipping to change at line 863
are exchanged with each other i.e. are exchanged with each other i.e.
$y->at(5,3,2,8) == $x->at(5,3,8,2) $y->at(5,3,2,8) == $x->at(5,3,8,2)
=for bad =for bad
xchg does not process bad values. 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. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
=cut =cut
#line 934 "Slices.pm" #line 953 "Slices.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*xchg = \&PDL::xchg; *xchg = \&PDL::xchg;
#line 940 "Slices.pm" #line 960 "Slices.pm"
#line 1320 "slices.pd" #line 1319 "slices.pd"
=head2 reorder =head2 reorder
=for ref =for ref
Re-orders the dimensions of a PDL based on the supplied list. Re-orders the dimensions of a PDL based on the supplied list.
Similar to the L</xchg> method, this method re-orders the dimensions Similar to the L</xchg> method, this method re-orders the dimensions
of a PDL. While the L</xchg> method swaps the position of two dimensions, of a PDL. While the L</xchg> method swaps the position of two dimensions,
the reorder method can change the positions of many dimensions at the reorder method can change the positions of many dimensions at
skipping to change at line 975 skipping to change at line 985
# Check to make sure all the dims are within bounds # Check to make sure all the dims are within bounds
for my $i(0..$#newDimOrder) { for my $i(0..$#newDimOrder) {
my $dim = $newDimOrder[$i]; my $dim = $newDimOrder[$i];
if($dim < 0 || $dim > $#newDimOrder) { if($dim < 0 || $dim > $#newDimOrder) {
my $errString = "PDL::reorder: Dim index $newDimOrder[$i] out of r ange in position $i\n(range is 0-$#newDimOrder)"; my $errString = "PDL::reorder: Dim index $newDimOrder[$i] out of r ange in position $i\n(range is 0-$#newDimOrder)";
barf($errString); barf($errString);
} }
} }
# Checking that they are all present and also not duplicated is done by thread() [I think] # Checking that they are all present and also not duplicated is done by broadcast() [I think]
# a quicker way to do the reorder # a quicker way to do the reorder
return $pdl->thread(@newDimOrder)->unthread(0); return $pdl->broadcast(@newDimOrder)->unbroadcast(0);
} }
#line 1064 "Slices.pm" #line 1085 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 mv =head2 mv
=for sig =for sig
Signature: (P(); C(); PDL_Indx n1; PDL_Indx n2) Signature: (P(); C(); PDL_Indx n1; PDL_Indx n2)
=for ref =for ref
move a dimension to another position move a dimension to another position
skipping to change at line 1014 skipping to change at line 1024
The other dimensions are moved accordingly. The other dimensions are moved accordingly.
Negative dimension indices count from the end. Negative dimension indices count from the end.
=for bad =for bad
mv does not process bad values. 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. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
=cut =cut
#line 1103 "Slices.pm" #line 1125 "Slices.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*mv = \&PDL::mv; *mv = \&PDL::mv;
#line 1109 "Slices.pm" #line 1132 "Slices.pm"
#line 1496 "slices.pd" #line 1495 "slices.pd"
=head2 using =head2 using
=for ref =for ref
Returns array of column numbers requested Returns array of column numbers requested
=for usage =for usage
line $pdl->using(1,2); line $pdl->using(1,2);
skipping to change at line 1050 skipping to change at line 1061
*using = \&PDL::using; *using = \&PDL::using;
sub PDL::using { sub PDL::using {
my ($x,@ind)=@_; my ($x,@ind)=@_;
@ind = list $ind[0] if (blessed($ind[0]) && $ind[0]->isa('PDL')); @ind = list $ind[0] if (blessed($ind[0]) && $ind[0]->isa('PDL'));
foreach (@ind) { foreach (@ind) {
$_ = $x->slice("($_)"); $_ = $x->slice("($_)");
} }
@ind; @ind;
} }
#line 1143 "Slices.pm" #line 1167 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 diagonal =head2 diagonal
=for sig =for sig
Signature: (P(); C(); PDL_Indx whichdims[]) Signature: (P(); C(); PDL_Indx whichdims[])
=for ref =for ref
Returns the multidimensional diagonal over the specified dimensions. Returns the multidimensional diagonal over the specified dimensions.
skipping to change at line 1081 skipping to change at line 1092
$d = $x->diagonal(dim1, dim2,...) $d = $x->diagonal(dim1, dim2,...)
=for example =for example
$y = $x->diagonal(0,2,5); $y = $x->diagonal(0,2,5);
the ndarray C<$y> has dimensions C<(5,3,4,6)> and the ndarray C<$y> has dimensions C<(5,3,4,6)> and
C<$y-E<gt>at(2,1,0,1)> refers C<$y-E<gt>at(2,1,0,1)> refers
to C<$x-E<gt>at(2,1,2,0,1,2)>. to C<$x-E<gt>at(2,1,2,0,1,2)>.
NOTE: diagonal doesn't handle threadids correctly. XXX FIX NOTE: diagonal doesn't handle broadcastids correctly. XXX FIX
pdl> $x = zeroes(3,3,3); pdl> $x = zeroes(3,3,3);
pdl> ($y = $x->diagonal(0,1))++; pdl> ($y = $x->diagonal(0,1))++;
pdl> p $x pdl> p $x
[ [
[ [
[1 0 0] [1 0 0]
[0 1 0] [0 1 0]
[0 0 1] [0 0 1]
] ]
skipping to change at line 1110 skipping to change at line 1121
[0 0 1] [0 0 1]
] ]
] ]
=for bad =for bad
diagonal does not process bad values. 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. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
=cut =cut
#line 1208 "Slices.pm" #line 1233 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
sub PDL::diagonal { shift->_diagonal_int(my $o=PDL->null, \@_); $o } sub PDL::diagonal { shift->_diagonal_int(my $o=PDL->null, \@_); $o }
#line 1214 "Slices.pm" #line 1240 "Slices.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*diagonal = \&PDL::diagonal; *diagonal = \&PDL::diagonal;
#line 1220 "Slices.pm" #line 1247 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 lags =head2 lags
=for sig =for sig
Signature: (P(); C(); PDL_Indx nthdim;PDL_Indx step;PDL_Indx n) Signature: (P(); C(); PDL_Indx nthdim;PDL_Indx step;PDL_Indx n)
=for ref =for ref
Returns an ndarray of lags to parent. Returns an ndarray of lags to parent.
skipping to change at line 1166 skipping to change at line 1179
C<$step> and C<$nlags> must be positive. C<$nthdim> can be C<$step> and C<$nlags> must be positive. C<$nthdim> can be
negative and will then be counted from the last dim backwards negative and will then be counted from the last dim backwards
in the usual way (-1 = last dim). in the usual way (-1 = last dim).
=for bad =for bad
lags does not process bad values. 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. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
=cut =cut
#line 1273 "Slices.pm" #line 1301 "Slices.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*lags = \&PDL::lags; *lags = \&PDL::lags;
#line 1279 "Slices.pm" #line 1308 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 splitdim =head2 splitdim
=for sig =for sig
Signature: (P(); C(); PDL_Indx nthdim;PDL_Indx nsp) Signature: (P(); C(); PDL_Indx nthdim;PDL_Indx nsp)
=for ref =for ref
Splits a dimension in the parent ndarray (opposite of L<clump|PDL::Core/clump>) Splits a dimension in the parent ndarray (opposite of L<clump|PDL::Core/clump>)
skipping to change at line 1202 skipping to change at line 1216
$y->at(6,4,m,n,3,6) == $x->at(6,4,m+3*n) $y->at(6,4,m,n,3,6) == $x->at(6,4,m+3*n)
is always true (C<m> has to be less than 3). is always true (C<m> has to be less than 3).
=for bad =for bad
splitdim does not process bad values. 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. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
=cut =cut
#line 1316 "Slices.pm" #line 1346 "Slices.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*splitdim = \&PDL::splitdim; *splitdim = \&PDL::splitdim;
#line 1322 "Slices.pm" #line 1353 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 rotate =head2 rotate
=for sig =for sig
Signature: (x(n); indx shift(); [oca]y(n)) Signature: (x(n); indx shift(); [oca]y(n))
=for ref =for ref
Shift vector elements along with wrap. Flows data back&forth. Shift vector elements along with wrap. Flows data back&forth.
=for bad =for bad
rotate does not process bad values. 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. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
=cut =cut
#line 1347 "Slices.pm" #line 1379 "Slices.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*rotate = \&PDL::rotate; *rotate = \&PDL::rotate;
#line 1353 "Slices.pm" #line 1386 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 threadI =head2 broadcastI
=for sig =for sig
Signature: (P(); C(); PDL_Indx id; PDL_Indx whichdims[]) Signature: (P(); C(); PDL_Indx id; PDL_Indx whichdims[])
=for ref =for ref
internal internal
Put some dimensions to a threadid. Put some dimensions to a broadcastid.
=for example =for example
$y = $x->threadI(0,1,5); # thread over dims 1,5 in id 1 $y = $x->broadcastI(0,1,5); # broadcast over dims 1,5 in id 1
=for bad =for bad
threadI does not process bad values. 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. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
=cut =cut
#line 1385 "Slices.pm" #line 1419 "Slices.pm"
#line 1061 "../../blib/lib/PDL/PP.pm" #line 1060 "../../blib/lib/PDL/PP.pm"
*threadI = \&PDL::threadI;
#line 1391 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" *broadcastI = \&PDL::broadcastI;
#line 1426 "Slices.pm"
=head2 unthread #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 unbroadcast
=for sig =for sig
Signature: (P(); C(); int atind) Signature: (P(); C(); int atind)
=for ref =for ref
All threaded dimensions are made real again. All broadcasted dimensions are made real again.
See [TBD Doc] for details and examples. See [TBD Doc] for details and examples.
=for bad =for bad
unthread does not process bad values. 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. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
=cut =cut
#line 1418 "Slices.pm" #line 1454 "Slices.pm"
#line 1061 "../../blib/lib/PDL/PP.pm" #line 1060 "../../blib/lib/PDL/PP.pm"
*unthread = \&PDL::unthread;
#line 1424 "Slices.pm"
#line 1936 "slices.pd" *unbroadcast = \&PDL::unbroadcast;
#line 1461 "Slices.pm"
#line 1935 "slices.pd"
=head2 dice =head2 dice
=for ref =for ref
Dice rows/columns/planes out of a PDL using indexes for Dice rows/columns/planes out of a PDL using indexes for
each dimension. each dimension.
This function can be used to extract irregular subsets This function can be used to extract irregular subsets
along many dimension of a PDL, e.g. only certain rows in an image, along many dimension of a PDL, e.g. only certain rows in an image,
skipping to change at line 1438 skipping to change at line 1456
=cut =cut
sub PDL::dice_axis { sub PDL::dice_axis {
my($self,$axis,$idx) = @_; my($self,$axis,$idx) = @_;
my $ix = ref($self)->topdl($idx); my $ix = ref($self)->topdl($idx);
barf("dice_axis: index must be <=1D") if $ix->getndims > 1; barf("dice_axis: index must be <=1D") if $ix->getndims > 1;
return $self->mv($axis,0)->index1d($ix)->mv(0,$axis); return $self->mv($axis,0)->index1d($ix)->mv(0,$axis);
} }
*dice_axis = \&PDL::dice_axis; *dice_axis = \&PDL::dice_axis;
#line 1579 "Slices.pm" #line 1617 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 slice =head2 slice
=for sig =for sig
Signature: (P(); C(); pdl_slice_args *arglist) Signature: (P(); C(); pdl_slice_args *arglist)
=for usage =for usage
$slice = $data->slice([2,3],'x',[2,2,0],"-1:1:-1", "*3"); $slice = $data->slice([2,3],'x',[2,2,0],"-1:1:-1", "*3");
skipping to change at line 1609 skipping to change at line 1627
$x->slice([1,3]); # Same as above three calls, but using array ref syntax $x->slice([1,3]); # Same as above three calls, but using array ref syntax
$x->slice([3,1]); $x->slice([3,1]);
$x->slice([-2,1]); $x->slice([-2,1]);
=for bad =for bad
slice does not process bad values. 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. It will set the bad-value flag of all output ndarrays if the flag is set for any of the input ndarrays.
=cut =cut
#line 1756 "Slices.pm" #line 1795 "Slices.pm"
#line 1059 "../../blib/lib/PDL/PP.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
sub PDL::slice { sub PDL::slice {
my ($source, @others) = @_; my ($source, @others) = @_;
for my $i(0..$#others) { for my $i(0..$#others) {
my $idx = $others[$i]; my $idx = $others[$i];
if (ref $idx eq 'ARRAY') { if (ref $idx eq 'ARRAY') {
my @arr = map UNIVERSAL::isa($_, 'PDL') ? $_->flat->at(0) : $_, @{$other s[$i]}; my @arr = map UNIVERSAL::isa($_, 'PDL') ? $_->flat->at(0) : $_, @{$other s[$i]};
$others[$i] = \@arr; $others[$i] = \@arr;
next; next;
} }
next if !( blessed($idx) && $idx->isa('PDL') ); next if !( blessed($idx) && $idx->isa('PDL') );
skipping to change at line 1648 skipping to change at line 1667
$others[$i] = $idx->flat->at(0); $others[$i] = $idx->flat->at(0);
} }
else { else {
#### Zero elements -- force an extended empty. #### Zero elements -- force an extended empty.
$others[$i] = "1:0:1"; $others[$i] = "1:0:1";
} }
} }
PDL::_slice_int($source,my $o=$source->initialize,\@others); PDL::_slice_int($source,my $o=$source->initialize,\@others);
$o; $o;
} }
#line 1797 "Slices.pm" #line 1837 "Slices.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*slice = \&PDL::slice; *slice = \&PDL::slice;
#line 1803 "Slices.pm" #line 1844 "Slices.pm"
#line 2427 "slices.pd" #line 2426 "slices.pd"
=head1 BUGS =head1 BUGS
For the moment, you can't slice one of the zero-length dims of an 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 empty ndarray. It is not clear how to implement this in a way that makes
sense. sense.
Many types of index errors are reported far from the indexing Many types of index errors are reported far from the indexing
operation that caused them. This is caused by the underlying architecture: operation that caused them. This is caused by the underlying architecture:
slice() sets up a mapping between variables, but that mapping isn't slice() sets up a mapping between variables, but that mapping isn't
skipping to change at line 1679 skipping to change at line 1699
Copyright (C) 1997 Tuomas J. Lukka. Contributions by Copyright (C) 1997 Tuomas J. Lukka. Contributions by
Craig DeForest, deforest@boulder.swri.edu. Craig DeForest, deforest@boulder.swri.edu.
Documentation contributions by David Mertens. Documentation contributions by David Mertens.
All rights reserved. There is no warranty. You are allowed All rights reserved. There is no warranty. You are allowed
to redistribute this software / documentation under certain to redistribute this software / documentation under certain
conditions. For details, see the file COPYING in the PDL conditions. For details, see the file COPYING in the PDL
distribution. If this file is separated from the PDL distribution, distribution. If this file is separated from the PDL distribution,
the copyright notice should be included in the file. the copyright notice should be included in the file.
=cut =cut
#line 1834 "Slices.pm" #line 1876 "Slices.pm"
# Exit with OK status # Exit with OK status
1; 1;
 End of changes. 116 change blocks. 
125 lines changed or deleted 145 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)