"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "GENERATED/PDL/Primitive.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).

Primitive.pm  (PDL-2.074):Primitive.pm  (PDL-2.075)
skipping to change at line 17 skipping to change at line 17
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::Primitive ; bootstrap PDL::Primitive ;
#line 7 "primitive.pd" #line 6 "primitive.pd"
use strict; use strict;
use warnings; use warnings;
use PDL::Slices; use PDL::Slices;
use Carp; use Carp;
{ package PDL; { package PDL;
use overload ( use overload (
'x' => sub { 'x' => sub {
PDL::Primitive::matmult(@_[0,1], my $foo=$_[0]->null()); PDL::Primitive::matmult(@_[0,1], my $foo=$_[0]->null());
$foo; $foo;
skipping to change at line 53 skipping to change at line 54
=head1 SYNOPSIS =head1 SYNOPSIS
# Pulls in PDL::Primitive, among other modules. # Pulls in PDL::Primitive, among other modules.
use PDL; use PDL;
# Only pull in PDL::Primitive: # Only pull in PDL::Primitive:
use PDL::Primitive; use PDL::Primitive;
=cut =cut
#line 61 "Primitive.pm" #line 62 "Primitive.pm"
=head1 FUNCTIONS =head1 FUNCTIONS
=cut =cut
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 inner =head2 inner
=for sig =for sig
Signature: (a(n); b(n); [o]c()) Signature: (a(n); b(n); [o]c())
=for ref =for ref
Inner product over one dimension Inner product over one dimension
skipping to change at line 82 skipping to change at line 83
=for bad =for bad
=for bad =for bad
If C<a() * b()> contains only bad data, If C<a() * b()> contains only bad data,
C<c()> is set bad. Otherwise C<c()> will have its bad flag cleared, C<c()> is set bad. Otherwise C<c()> will have its bad flag cleared,
as it will not contain any bad values. as it will not contain any bad values.
=cut =cut
#line 105 "Primitive.pm" #line 107 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*inner = \&PDL::inner; *inner = \&PDL::inner;
#line 111 "Primitive.pm" #line 114 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 outer =head2 outer
=for sig =for sig
Signature: (a(n); b(m); [o]c(n,m)) Signature: (a(n); b(m); [o]c(n,m))
=for ref =for ref
outer product over one dimension outer product over one dimension
Naturally, it is possible to achieve the effects of outer Naturally, it is possible to achieve the effects of outer
product simply by threading over the "C<*>" product simply by broadcasting over the "C<*>"
operator but this function is provided for convenience. operator but this function is provided for convenience.
=for bad =for bad
outer processes bad values. outer 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 141 "Primitive.pm" #line 145 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*outer = \&PDL::outer; *outer = \&PDL::outer;
#line 147 "Primitive.pm" #line 152 "Primitive.pm"
#line 120 "primitive.pd"
#line 121 "primitive.pd"
=head2 x =head2 x
=for sig =for sig
Signature: (a(i,z), b(x,i),[o]c(x,z)) Signature: (a(i,z), b(x,i),[o]c(x,z))
=for ref =for ref
Matrix multiplication Matrix multiplication
skipping to change at line 138 skipping to change at line 142
matrix multiplication. The number of columns (size of the 0 matrix multiplication. The number of columns (size of the 0
dimension) in the left-hand argument must normally equal the number of dimension) in the left-hand argument must normally equal the number of
rows (size of the 1 dimension) in the right-hand argument. rows (size of the 1 dimension) in the right-hand argument.
Row vectors are represented as (N x 1) two-dimensional PDLs, or you Row vectors are represented as (N x 1) two-dimensional PDLs, or you
may be sloppy and use a one-dimensional PDL. Column vectors are may be sloppy and use a one-dimensional PDL. Column vectors are
represented as (1 x N) two-dimensional PDLs. represented as (1 x N) two-dimensional PDLs.
Threading occurs in the usual way, but as both the 0 and 1 dimension Threading occurs in the usual way, but as both the 0 and 1 dimension
(if present) are included in the operation, you must be sure that (if present) are included in the operation, you must be sure that
you don't try to thread over either of those dims. you don't try to broadcast over either of those dims.
Of note, due to how Perl v5.14.0 and above implement operator overloading of Of note, due to how Perl v5.14.0 and above implement operator overloading of
the C<x> operator, the use of parentheses for the left operand creates a list the C<x> operator, the use of parentheses for the left operand creates a list
context, that is context, that is
pdl> ( $x * $y ) x $z pdl> ( $x * $y ) x $z
ERROR: Argument "..." isn't numeric in repeat (x) ... ERROR: Argument "..." isn't numeric in repeat (x) ...
treats C<$z> as a numeric count for the list repeat operation and does not call treats C<$z> as a numeric count for the list repeat operation and does not call
the scalar form of the overloaded operator. To use the operator in this case, the scalar form of the overloaded operator. To use the operator in this case,
skipping to change at line 206 skipping to change at line 210
[3 6] [3 6]
[4 8] [4 8]
] ]
INTERNALS INTERNALS
The mechanics of the multiplication are carried out by the The mechanics of the multiplication are carried out by the
L</matmult> method. L</matmult> method.
=cut =cut
#line 242 "Primitive.pm" #line 248 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 matmult =head2 matmult
=for sig =for sig
Signature: (a(t,h); b(w,t); [o]c(w,h)) Signature: (a(t,h); b(w,t); [o]c(w,h))
=for ref =for ref
Matrix multiplication Matrix multiplication
Notionally, matrix multiplication $x x $y is equivalent to the Notionally, matrix multiplication $x x $y is equivalent to the
threading expression broadcasting expression
$x->dummy(1)->inner($y->xchg(0,1)->dummy(2),$c); $x->dummy(1)->inner($y->xchg(0,1)->dummy(2),$c);
but for large matrices that breaks CPU cache and is slow. Instead, but for large matrices that breaks CPU cache and is slow. Instead,
matmult calculates its result in 32x32x32 tiles, to keep the memory matmult calculates its result in 32x32x32 tiles, to keep the memory
footprint within cache as long as possible on most modern CPUs. footprint within cache as long as possible on most modern CPUs.
For usage, see L</x>, a description of the overloaded 'x' operator For usage, see L</x>, a description of the overloaded 'x' operator
=for bad =for bad
matmult ignores the bad-value flag of the input ndarrays. matmult ignores the bad-value flag 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. 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 279 "Primitive.pm" #line 286 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
sub PDL::matmult { sub PDL::matmult {
my ($x,$y,$c) = @_; my ($x,$y,$c) = @_;
$y = pdl($y) unless eval { $y->isa('PDL') }; $y = pdl($y) unless eval { $y->isa('PDL') };
$c = PDL->null unless eval { $c->isa('PDL') }; $c = PDL->null unless eval { $c->isa('PDL') };
while($x->getndims < 2) {$x = $x->dummy(-1)} while($x->getndims < 2) {$x = $x->dummy(-1)}
while($y->getndims < 2) {$y = $y->dummy(-1)} while($y->getndims < 2) {$y = $y->dummy(-1)}
return ($c .= $x * $y) if( ($x->dim(0)==1 && $x->dim(1)==1) || return ($c .= $x * $y) if( ($x->dim(0)==1 && $x->dim(1)==1) ||
($y->dim(0)==1 && $y->dim(1)==1) ); ($y->dim(0)==1 && $y->dim(1)==1) );
if($y->dim(1) != $x->dim(0)) { if($y->dim(1) != $x->dim(0)) {
barf(sprintf("Dim mismatch in matmult of [%dx%d] x [%dx%d]: %d != %d",$x ->dim(0),$x->dim(1),$y->dim(0),$y->dim(1),$x->dim(0),$y->dim(1))); barf(sprintf("Dim mismatch in matmult of [%dx%d] x [%dx%d]: %d != %d",$x ->dim(0),$x->dim(1),$y->dim(0),$y->dim(1),$x->dim(0),$y->dim(1)));
} }
PDL::_matmult_int($x,$y,$c); PDL::_matmult_int($x,$y,$c);
$c; $c;
} }
#line 301 "Primitive.pm" #line 309 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*matmult = \&PDL::matmult; *matmult = \&PDL::matmult;
#line 307 "Primitive.pm" #line 316 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 innerwt =head2 innerwt
=for sig =for sig
Signature: (a(n); b(n); c(n); [o]d()) Signature: (a(n); b(n); c(n); [o]d())
=for ref =for ref
Weighted (i.e. triple) inner product Weighted (i.e. triple) inner product
d = sum_i a(i) b(i) c(i) d = sum_i a(i) b(i) c(i)
=for bad =for bad
innerwt processes bad values. innerwt 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 337 "Primitive.pm" #line 347 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*innerwt = \&PDL::innerwt; *innerwt = \&PDL::innerwt;
#line 343 "Primitive.pm" #line 354 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 inner2 =head2 inner2
=for sig =for sig
Signature: (a(n); b(n,m); c(m); [o]d()) Signature: (a(n); b(n,m); c(m); [o]d())
=for ref =for ref
Inner product of two vectors and a matrix Inner product of two vectors and a matrix
d = sum_ij a(i) b(i,j) c(j) d = sum_ij a(i) b(i,j) c(j)
Note that you should probably not thread over C<a> and C<c> since that would be Note that you should probably not broadcast over C<a> and C<c> since that would be
very wasteful. Instead, you should use a temporary for C<b*c>. very wasteful. Instead, you should use a temporary for C<b*c>.
=for bad =for bad
inner2 processes bad values. inner2 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 374 "Primitive.pm" #line 386 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*inner2 = \&PDL::inner2; *inner2 = \&PDL::inner2;
#line 380 "Primitive.pm" #line 393 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 inner2d =head2 inner2d
=for sig =for sig
Signature: (a(n,m); b(n,m); [o]c()) Signature: (a(n,m); b(n,m); [o]c())
=for ref =for ref
Inner product over 2 dimensions. Inner product over 2 dimensions.
skipping to change at line 340 skipping to change at line 348
Equivalent to Equivalent to
$c = inner($x->clump(2), $y->clump(2)) $c = inner($x->clump(2), $y->clump(2))
=for bad =for bad
inner2d processes bad values. inner2d 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 412 "Primitive.pm" #line 426 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*inner2d = \&PDL::inner2d; *inner2d = \&PDL::inner2d;
#line 418 "Primitive.pm" #line 433 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 inner2t =head2 inner2t
=for sig =for sig
Signature: (a(j,n); b(n,m); c(m,k); [t]tmp(n,k); [o]d(j,k))) Signature: (a(j,n); b(n,m); c(m,k); [t]tmp(n,k); [o]d(j,k)))
=for ref =for ref
Efficient Triple matrix product C<a*b*c> Efficient Triple matrix product C<a*b*c>
Efficiency comes from by using the temporary C<tmp>. This operation only Efficiency comes from by using the temporary C<tmp>. This operation only
scales as C<N**3> whereas threading using L</inner2> would scale scales as C<N**3> whereas broadcasting using L</inner2> would scale
as C<N**4>. as C<N**4>.
The reason for having this routine is that you do not need to The reason for having this routine is that you do not need to
have the same thread-dimensions for C<tmp> as for the other arguments, have the same broadcast-dimensions for C<tmp> as for the other arguments,
which in case of large numbers of matrices makes this much more which in case of large numbers of matrices makes this much more
memory-efficient. memory-efficient.
It is hoped that things like this could be taken care of as a kind of It is hoped that things like this could be taken care of as a kind of
closures at some point. closures at some point.
=for bad =for bad
inner2t processes bad values. inner2t 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 458 "Primitive.pm" #line 474 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*inner2t = \&PDL::inner2t; *inner2t = \&PDL::inner2t;
#line 464 "Primitive.pm" #line 481 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 crossp =head2 crossp
=for sig =for sig
Signature: (a(tri=3); b(tri); [o] c(tri)) Signature: (a(tri=3); b(tri); [o] c(tri))
=for ref =for ref
Cross product of two 3D vectors Cross product of two 3D vectors
skipping to change at line 409 skipping to change at line 419
the inner product C<$c*$x> and C<$c*$y> will be zero, i.e. C<$c> is the inner product C<$c*$x> and C<$c*$y> will be zero, i.e. C<$c> is
orthogonal to C<$x> and C<$y> orthogonal to C<$x> and C<$y>
=for bad =for bad
crossp does not process bad values. crossp 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 500 "Primitive.pm" #line 518 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*crossp = \&PDL::crossp; *crossp = \&PDL::crossp;
#line 506 "Primitive.pm" #line 525 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 norm =head2 norm
=for sig =for sig
Signature: (vec(n); [o] norm(n)) Signature: (vec(n); [o] norm(n))
=for ref =for ref
Normalises a vector to unit Euclidean length Normalises a vector to unit Euclidean length
=for bad =for bad
norm processes bad values. norm 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 530 "Primitive.pm" #line 550 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*norm = \&PDL::norm; *norm = \&PDL::norm;
#line 536 "Primitive.pm" #line 557 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 indadd =head2 indadd
=for sig =for sig
Signature: (a(n); indx ind(n); [o] sum(m)) Signature: (a(n); indx ind(n); [o] sum(m))
=for ref =for ref
Threaded Index Add: Add C<a> to the C<ind> element of C<sum>, i.e: Threaded Index Add: Add C<a> to the C<ind> element of C<sum>, i.e:
skipping to change at line 482 skipping to change at line 494
#Result: ( 1, 2, and 3 added to elements 1,4,6 $sum) #Result: ( 1, 2, and 3 added to elements 1,4,6 $sum)
# [0 1 0 0 2 0 3 0 0 0] # [0 1 0 0 2 0 3 0 0 0]
=for bad =for bad
=for bad =for bad
The routine barfs if any of the indices are bad. The routine barfs if any of the indices are bad.
=cut =cut
#line 590 "Primitive.pm" #line 612 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*indadd = \&PDL::indadd; *indadd = \&PDL::indadd;
#line 596 "Primitive.pm" #line 619 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 conv1d =head2 conv1d
=for sig =for sig
Signature: (a(m); kern(p); [o]b(m); int reflect) Signature: (a(m); kern(p); [o]b(m); int reflect)
=for ref =for ref
1D convolution along first dimension 1D convolution along first dimension
skipping to change at line 533 skipping to change at line 546
Alternatively, you can request reflective boundary conditions using Alternatively, you can request reflective boundary conditions using
the C<Boundary> option: the C<Boundary> option:
{Boundary => 'reflect'} # case in 'reflect' doesn't matter {Boundary => 'reflect'} # case in 'reflect' doesn't matter
The convolution is performed along the first dimension. To apply it across The convolution is performed along the first dimension. To apply it across
another dimension use the slicing routines, e.g. another dimension use the slicing routines, e.g.
$y = $x->mv(2,0)->conv1d($kernel)->mv(0,2); # along third dim $y = $x->mv(2,0)->conv1d($kernel)->mv(0,2); # along third dim
This function is useful for threaded filtering of 1D signals. This function is useful for broadcasted filtering of 1D signals.
Compare also L<conv2d|PDL::Image2D/conv2d>, L<convolve|PDL::ImageND/convolve>, Compare also L<conv2d|PDL::Image2D/conv2d>, L<convolve|PDL::ImageND/convolve>,
L<fftconvolve|PDL::FFT/fftconvolve()>, L<fftwconv|PDL::FFTW/fftwconv>, L<fftconvolve|PDL::FFT/fftconvolve()>, L<fftwconv|PDL::FFTW/fftwconv>,
L<rfftwconv|PDL::FFTW/rfftwconv> L<rfftwconv|PDL::FFTW/rfftwconv>
=for bad =for bad
WARNING: C<conv1d> processes bad values in its inputs as WARNING: C<conv1d> processes bad values in its inputs as
the numeric value of C<< $pdl->badvalue >> so it is not the numeric value of C<< $pdl->badvalue >> so it is not
recommended for processing pdls with bad values in them recommended for processing pdls with bad values in them
unless special care is taken. unless special care is taken.
=for bad =for bad
conv1d ignores the bad-value flag of the input ndarrays. conv1d ignores the bad-value flag 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. 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 670 "Primitive.pm" #line 694 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm" #line 1059 "../../blib/lib/PDL/PP.pm"
sub PDL::conv1d { sub PDL::conv1d {
my $opt = pop @_ if ref($_[$#_]) eq 'HASH'; my $opt = pop @_ if ref($_[$#_]) eq 'HASH';
die 'Usage: conv1d( a(m), kern(p), [o]b(m), {Options} )' die 'Usage: conv1d( a(m), kern(p), [o]b(m), {Options} )'
if $#_<1 || $#_>2; if $#_<1 || $#_>2;
my($x,$kern) = @_; my($x,$kern) = @_;
my $c = $#_ == 2 ? $_[2] : PDL->null; my $c = $#_ == 2 ? $_[2] : PDL->null;
PDL::_conv1d_int($x,$kern,$c, PDL::_conv1d_int($x,$kern,$c,
!(defined $opt && exists $$opt{Boundary}) ? 0 : !(defined $opt && exists $$opt{Boundary}) ? 0 :
lc $$opt{Boundary} eq "reflect"); lc $$opt{Boundary} eq "reflect");
return $c; return $c;
} }
#line 688 "Primitive.pm" #line 713 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*conv1d = \&PDL::conv1d; *conv1d = \&PDL::conv1d;
#line 694 "Primitive.pm" #line 720 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 in =head2 in
=for sig =for sig
Signature: (a(); b(n); [o] c()) Signature: (a(); b(n); [o] c())
=for ref =for ref
test if a is in the set of values b test if a is in the set of values b
=for example =for example
$goodmsk = $labels->in($goodlabels); $goodmsk = $labels->in($goodlabels);
print pdl(3,1,4,6,2)->in(pdl(2,3,3)); print pdl(3,1,4,6,2)->in(pdl(2,3,3));
[1 0 0 0 1] [1 0 0 0 1]
C<in> is akin to the I<is an element of> of set theory. In principle, C<in> is akin to the I<is an element of> of set theory. In principle,
PDL threading could be used to achieve its functionality by using a PDL broadcasting could be used to achieve its functionality by using a
construct like construct like
$msk = ($labels->dummy(0) == $goodlabels)->orover; $msk = ($labels->dummy(0) == $goodlabels)->orover;
However, C<in> doesn't create a (potentially large) intermediate However, C<in> doesn't create a (potentially large) intermediate
and is generally faster. and is generally faster.
=for bad =for bad
in does not process bad values. in 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 736 "Primitive.pm" #line 763 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*in = \&PDL::in; *in = \&PDL::in;
#line 742 "Primitive.pm" #line 770 "Primitive.pm"
#line 784 "primitive.pd"
#line 788 "primitive.pd"
=head2 uniq =head2 uniq
=for ref =for ref
return all unique elements of an ndarray return all unique elements of an ndarray
The unique elements are returned in ascending order. The unique elements are returned in ascending order.
=for example =for example
skipping to change at line 669 skipping to change at line 685
my $uniq = ($srt->nelem > 0) ? $srt->where($srt != $srt->rotate(-1)) : $srt; my $uniq = ($srt->nelem > 0) ? $srt->where($srt != $srt->rotate(-1)) : $srt;
# make sure we return something if there is only one value # make sure we return something if there is only one value
my $answ = $nans; # NaN values always uniq my $answ = $nans; # NaN values always uniq
if ( $uniq->nelem > 0 ) { if ( $uniq->nelem > 0 ) {
$answ = $uniq->append($answ); $answ = $uniq->append($answ);
} else { } else {
$answ = ( ($srt->nelem == 0) ? $srt : PDL::pdl( ref($srt), [$srt->index(0 )] ) )->append($answ); $answ = ( ($srt->nelem == 0) ? $srt : PDL::pdl( ref($srt), [$srt->index(0 )] ) )->append($answ);
} }
return $answ; return $answ;
} }
#line 803 "Primitive.pm" #line 832 "Primitive.pm"
#line 844 "primitive.pd"
#line 848 "primitive.pd"
=head2 uniqind =head2 uniqind
=for ref =for ref
Return the indices of all unique elements of an ndarray Return the indices of all unique elements of an ndarray
The order is in the order of the values to be consistent The order is in the order of the values to be consistent
with uniq. C<NaN> values never compare equal with any with uniq. C<NaN> values never compare equal with any
other value and so are always unique. This follows the other value and so are always unique. This follows the
Matlab usage. Matlab usage.
skipping to change at line 732 skipping to change at line 749
} }
# Now map back to the original space # Now map back to the original space
my $ansind = $nanind; my $ansind = $nanind;
if ( $uniqind->nelem > 0 ) { if ( $uniqind->nelem > 0 ) {
$ansind = ($good->index($i_srt->index($uniqind)))->append($ansind); $ansind = ($good->index($i_srt->index($uniqind)))->append($ansind);
} else { } else {
$ansind = $uniqind->append($ansind); $ansind = $uniqind->append($ansind);
} }
return $ansind; return $ansind;
} }
#line 869 "Primitive.pm" #line 899 "Primitive.pm"
#line 910 "primitive.pd"
#line 914 "primitive.pd"
=head2 uniqvec =head2 uniqvec
=for ref =for ref
Return all unique vectors out of a collection Return all unique vectors out of a collection
NOTE: If any vectors in the input ndarray have NaN values NOTE: If any vectors in the input ndarray have NaN values
they are returned at the end of the non-NaN ones. This is they are returned at the end of the non-NaN ones. This is
because, by definition, NaN values never compare equal with because, by definition, NaN values never compare equal with
any other value. any other value.
skipping to change at line 807 skipping to change at line 825
my $uniq = $srtdice->nelem > 0 my $uniq = $srtdice->nelem > 0
? ($srtdice != $srtdice->rotate(-1))->mv(0,-1)->orover->which ? ($srtdice != $srtdice->rotate(-1))->mv(0,-1)->orover->which
: $srtdice->orover->which; : $srtdice->orover->which;
my $ans = $uniq->nelem > 0 ? $srtdice->dice($uniq) : my $ans = $uniq->nelem > 0 ? $srtdice->dice($uniq) :
($srtdice->nelem > 0) ? $srtdice->slice("0,:") : ($srtdice->nelem > 0) ? $srtdice->slice("0,:") :
$srtdice; $srtdice;
return $ans->append($somebad)->append($nanvec->mv(0,-1))->mv(0,-1); return $ans->append($somebad)->append($nanvec->mv(0,-1))->mv(0,-1);
} }
#line 946 "Primitive.pm" #line 977 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 hclip =head2 hclip
=for sig =for sig
Signature: (a(); b(); [o] c()) Signature: (a(); b(); [o] c())
=for ref =for ref
clip (threshold) C<$a> by C<$b> (C<$b> is upper bound) clip (threshold) C<$a> by C<$b> (C<$b> is upper bound)
=for bad =for bad
hclip processes bad values. hclip 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 970 "Primitive.pm" #line 1002 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
sub PDL::hclip { sub PDL::hclip {
my ($x,$y) = @_; my ($x,$y) = @_;
my $c; my $c;
if ($x->is_inplace) { if ($x->is_inplace) {
$x->set_inplace(0); $c = $x; $x->set_inplace(0); $c = $x;
} elsif ($#_ > 1) {$c=$_[2]} else {$c=PDL->nullcreate($x)} } elsif ($#_ > 1) {$c=$_[2]} else {$c=PDL->nullcreate($x)}
PDL::_hclip_int($x,$y,$c); PDL::_hclip_int($x,$y,$c);
return $c; return $c;
} }
#line 984 "Primitive.pm" #line 1017 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*hclip = \&PDL::hclip; *hclip = \&PDL::hclip;
#line 990 "Primitive.pm" #line 1024 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 lclip =head2 lclip
=for sig =for sig
Signature: (a(); b(); [o] c()) Signature: (a(); b(); [o] c())
=for ref =for ref
clip (threshold) C<$a> by C<$b> (C<$b> is lower bound) clip (threshold) C<$a> by C<$b> (C<$b> is lower bound)
=for bad =for bad
lclip processes bad values. lclip 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 1014 "Primitive.pm" #line 1049 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
sub PDL::lclip { sub PDL::lclip {
my ($x,$y) = @_; my ($x,$y) = @_;
my $c; my $c;
if ($x->is_inplace) { if ($x->is_inplace) {
$x->set_inplace(0); $c = $x; $x->set_inplace(0); $c = $x;
} elsif ($#_ > 1) {$c=$_[2]} else {$c=PDL->nullcreate($x)} } elsif ($#_ > 1) {$c=$_[2]} else {$c=PDL->nullcreate($x)}
PDL::_lclip_int($x,$y,$c); PDL::_lclip_int($x,$y,$c);
return $c; return $c;
} }
#line 1028 "Primitive.pm" #line 1064 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*lclip = \&PDL::lclip; *lclip = \&PDL::lclip;
#line 1034 "Primitive.pm" #line 1071 "Primitive.pm"
#line 1027 "primitive.pd"
#line 1031 "primitive.pd"
=head2 clip =head2 clip
=for ref =for ref
Clip (threshold) an ndarray by (optional) upper or lower bounds. Clip (threshold) an ndarray by (optional) upper or lower bounds.
=for usage =for usage
$y = $x->clip(0,3); $y = $x->clip(0,3);
$c = $x->clip(undef, $x); $c = $x->clip(undef, $x);
=for bad =for bad
clip handles bad values since it is just a clip handles bad values since it is just a
wrapper around L</hclip> and wrapper around L</hclip> and
L</lclip>. L</lclip>.
=cut =cut
#line 1057 "Primitive.pm" #line 1095 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 clip =head2 clip
=for sig =for sig
Signature: (a(); l(); h(); [o] c()) Signature: (a(); l(); h(); [o] c())
=for ref =for ref
info not available info not available
=for bad =for bad
clip processes bad values. clip 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 1083 "Primitive.pm" #line 1122 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
*clip = \&PDL::clip; *clip = \&PDL::clip;
sub PDL::clip { sub PDL::clip {
my($x, $l, $h) = @_; my($x, $l, $h) = @_;
my $d; my $d;
unless(defined($l) || defined($h)) { unless(defined($l) || defined($h)) {
# Deal with pathological case # Deal with pathological case
if($x->is_inplace) { if($x->is_inplace) {
$x->set_inplace(0); $x->set_inplace(0);
return $x; return $x;
} else { } else {
skipping to change at line 956 skipping to change at line 980
} elsif( defined($l) ) { } elsif( defined($l) ) {
PDL::_lclip_int($x,$l,$d); PDL::_lclip_int($x,$l,$d);
} elsif( defined($h) ) { } elsif( defined($h) ) {
PDL::_hclip_int($x,$h,$d); PDL::_hclip_int($x,$h,$d);
} else { } else {
die "This can't happen (clip contingency) - file a bug"; die "This can't happen (clip contingency) - file a bug";
} }
return $d; return $d;
} }
#line 1121 "Primitive.pm" #line 1161 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*clip = \&PDL::clip; *clip = \&PDL::clip;
#line 1127 "Primitive.pm" #line 1168 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 wtstat =head2 wtstat
=for sig =for sig
Signature: (a(n); wt(n); avg(); [o]b(); int deg) Signature: (a(n); wt(n); avg(); [o]b(); int deg)
=for ref =for ref
Weighted statistical moment of given degree Weighted statistical moment of given degree
skipping to change at line 987 skipping to change at line 1012
b() = (sum_i wt_i * (a_i ** degree - avg)) / (sum_i wt_i) b() = (sum_i wt_i * (a_i ** degree - avg)) / (sum_i wt_i)
=for bad =for bad
=for bad =for bad
Bad values are ignored in any calculation; C<$b> will only Bad values are ignored in any calculation; C<$b> will only
have its bad flag set if the output contains any bad data. have its bad flag set if the output contains any bad data.
=cut =cut
#line 1160 "Primitive.pm" #line 1202 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*wtstat = \&PDL::wtstat; *wtstat = \&PDL::wtstat;
#line 1166 "Primitive.pm" #line 1209 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 statsover =head2 statsover
=for sig =for sig
Signature: (a(n); w(n); float+ [o]avg(); float+ [o]prms(); int+ [o]median(); i nt+ [o]min(); int+ [o]max(); float+ [o]adev(); float+ [o]rms()) Signature: (a(n); w(n); float+ [o]avg(); float+ [o]prms(); int+ [o]median(); i nt+ [o]min(); int+ [o]max(); float+ [o]adev(); float+ [o]rms())
=for ref =for ref
Calculate useful statistics over a dimension of an ndarray Calculate useful statistics over a dimension of an ndarray
skipping to change at line 1063 skipping to change at line 1089
use C<clump(-1)> directly on the ndarray or call C<stats>. use C<clump(-1)> directly on the ndarray or call C<stats>.
=for bad =for bad
=for bad =for bad
Bad values are simply ignored in the calculation, effectively reducing Bad values are simply ignored in the calculation, effectively reducing
the sample size. If all data are bad then the output data are marked bad. the sample size. If all data are bad then the output data are marked bad.
=cut =cut
#line 1247 "Primitive.pm" #line 1291 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm" #line 1059 "../../blib/lib/PDL/PP.pm"
sub PDL::statsover { sub PDL::statsover {
barf('Usage: ($mean,[$prms, $median, $min, $max, $adev, $rms]) = statsover($d ata,[$weights])') if $#_>1; barf('Usage: ($mean,[$prms, $median, $min, $max, $adev, $rms]) = statsover($d ata,[$weights])') if $#_>1;
my ($data, $weights) = @_; my ($data, $weights) = @_;
$weights = $data->ones() if !defined($weights); $weights = $data->ones() if !defined($weights);
my $median = $data->medover(); my $median = $data->medover();
my $mean = PDL->nullcreate($data); my $mean = PDL->nullcreate($data);
my $rms = PDL->nullcreate($data); my $rms = PDL->nullcreate($data);
my $min = PDL->nullcreate($data); my $min = PDL->nullcreate($data);
my $max = PDL->nullcreate($data); my $max = PDL->nullcreate($data);
my $adev = PDL->nullcreate($data); my $adev = PDL->nullcreate($data);
my $prms = PDL->nullcreate($data); my $prms = PDL->nullcreate($data);
PDL::_statsover_int($data, $weights, $mean, $prms, $median, $min, $max, $adev , $rms); PDL::_statsover_int($data, $weights, $mean, $prms, $median, $min, $max, $adev , $rms);
return $mean unless wantarray; return $mean unless wantarray;
return ($mean, $prms, $median, $min, $max, $adev, $rms); return ($mean, $prms, $median, $min, $max, $adev, $rms);
} }
#line 1271 "Primitive.pm" #line 1316 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*statsover = \&PDL::statsover; *statsover = \&PDL::statsover;
#line 1277 "Primitive.pm" #line 1323 "Primitive.pm"
#line 1335 "primitive.pd"
#line 1339 "primitive.pd"
=head2 stats =head2 stats
=for ref =for ref
Calculates useful statistics on an ndarray Calculates useful statistics on an ndarray
=for usage =for usage
($mean,$prms,$median,$min,$max,$adev,$rms) = stats($ndarray,[$weights]); ($mean,$prms,$median,$min,$max,$adev,$rms) = stats($ndarray,[$weights]);
skipping to change at line 1119 skipping to change at line 1147
Bad values are handled; if all input values are bad, then all of the output Bad values are handled; if all input values are bad, then all of the output
values are flagged bad. values are flagged bad.
=cut =cut
*stats = \&PDL::stats; *stats = \&PDL::stats;
sub PDL::stats { sub PDL::stats {
barf('Usage: ($mean,[$rms]) = stats($data,[$weights])') if $#_>1; barf('Usage: ($mean,[$rms]) = stats($data,[$weights])') if $#_>1;
my ($data,$weights) = @_; my ($data,$weights) = @_;
# Ensure that $weights is properly threaded over; this could be # Ensure that $weights is properly broadcasted over; this could be
# done rather more efficiently... # done rather more efficiently...
if(defined $weights) { if(defined $weights) {
$weights = pdl($weights) unless UNIVERSAL::isa($weights,'PDL'); $weights = pdl($weights) unless UNIVERSAL::isa($weights,'PDL');
if( ($weights->ndims != $data->ndims) or if( ($weights->ndims != $data->ndims) or
(pdl($weights->dims) != pdl($data->dims))->or (pdl($weights->dims) != pdl($data->dims))->or
) { ) {
$weights = $weights + zeroes($data) $weights = $weights + zeroes($data)
} }
$weights = $weights->flat; $weights = $weights->flat;
} }
return PDL::statsover($data->flat,$weights); return PDL::statsover($data->flat,$weights);
} }
#line 1324 "Primitive.pm" #line 1371 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 histogram =head2 histogram
=for sig =for sig
Signature: (in(n); int+[o] hist(m); double step; double min; int msize => m) Signature: (in(n); int+[o] hist(m); double step; double min; int msize => m)
=for ref =for ref
Calculates a histogram for given stepsize and minimum. Calculates a histogram for given stepsize and minimum.
skipping to change at line 1160 skipping to change at line 1188
$hist = zeroes $numbins; # Put histogram in existing ndarray. $hist = zeroes $numbins; # Put histogram in existing ndarray.
histogram($data, $hist, $step, $min, $numbins); histogram($data, $hist, $step, $min, $numbins);
The histogram will contain C<$numbins> bins starting from C<$min>, each The histogram will contain C<$numbins> bins starting from C<$min>, each
C<$step> wide. The value in each bin is the number of C<$step> wide. The value in each bin is the number of
values in C<$data> that lie within the bin limits. values in C<$data> that lie within the bin limits.
Data below the lower limit is put in the first bin, and data above the Data below the lower limit is put in the first bin, and data above the
upper limit is put in the last bin. upper limit is put in the last bin.
The output is reset in a different threadloop so that you The output is reset in a different broadcastloop so that you
can take a histogram of C<$a(10,12)> into C<$b(15)> and get the result can take a histogram of C<$a(10,12)> into C<$b(15)> and get the result
you want. you want.
For a higher-level interface, see L<hist|PDL::Basic/hist>. For a higher-level interface, see L<hist|PDL::Basic/hist>.
=for example =for example
pdl> p histogram(pdl(1,1,2),1,0,3) pdl> p histogram(pdl(1,1,2),1,0,3)
[0 2 1] [0 2 1]
=for bad =for bad
histogram processes bad values. histogram 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 1375 "Primitive.pm" #line 1423 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*histogram = \&PDL::histogram; *histogram = \&PDL::histogram;
#line 1381 "Primitive.pm" #line 1430 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 whistogram =head2 whistogram
=for sig =for sig
Signature: (in(n); float+ wt(n);float+[o] hist(m); double step; double min; in t msize => m) Signature: (in(n); float+ wt(n);float+[o] hist(m); double step; double min; in t msize => m)
=for ref =for ref
Calculates a histogram from weighted data for given stepsize and minimum. Calculates a histogram from weighted data for given stepsize and minimum.
skipping to change at line 1208 skipping to change at line 1237
$hist = zeroes $numbins; # Put histogram in existing ndarray. $hist = zeroes $numbins; # Put histogram in existing ndarray.
whistogram($data, $weights, $hist, $step, $min, $numbins); whistogram($data, $weights, $hist, $step, $min, $numbins);
The histogram will contain C<$numbins> bins starting from C<$min>, each The histogram will contain C<$numbins> bins starting from C<$min>, each
C<$step> wide. The value in each bin is the sum of the values in C<$weights> C<$step> wide. The value in each bin is the sum of the values in C<$weights>
that correspond to values in C<$data> that lie within the bin limits. that correspond to values in C<$data> that lie within the bin limits.
Data below the lower limit is put in the first bin, and data above the Data below the lower limit is put in the first bin, and data above the
upper limit is put in the last bin. upper limit is put in the last bin.
The output is reset in a different threadloop so that you The output is reset in a different broadcastloop so that you
can take a histogram of C<$a(10,12)> into C<$b(15)> and get the result can take a histogram of C<$a(10,12)> into C<$b(15)> and get the result
you want. you want.
=for example =for example
pdl> p whistogram(pdl(1,1,2), pdl(0.1,0.1,0.5), 1, 0, 4) pdl> p whistogram(pdl(1,1,2), pdl(0.1,0.1,0.5), 1, 0, 4)
[0 0.2 0.5 0] [0 0.2 0.5 0]
=for bad =for bad
whistogram processes bad values. whistogram 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 1429 "Primitive.pm" #line 1479 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*whistogram = \&PDL::whistogram; *whistogram = \&PDL::whistogram;
#line 1435 "Primitive.pm" #line 1486 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 histogram2d =head2 histogram2d
=for sig =for sig
Signature: (ina(n); inb(n); int+[o] hist(ma,mb); double stepa; double mina; in t masize => ma; Signature: (ina(n); inb(n); int+[o] hist(ma,mb); double stepa; double mina; in t masize => ma;
double stepb; double minb; int mbsize => mb;) double stepb; double minb; int mbsize => mb;)
=for ref =for ref
skipping to change at line 1274 skipping to change at line 1304
[0 2 2] [0 2 2]
[0 1 0] [0 1 0]
] ]
=for bad =for bad
histogram2d processes bad values. histogram2d 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 1488 "Primitive.pm" #line 1540 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*histogram2d = \&PDL::histogram2d; *histogram2d = \&PDL::histogram2d;
#line 1494 "Primitive.pm" #line 1547 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 whistogram2d =head2 whistogram2d
=for sig =for sig
Signature: (ina(n); inb(n); float+ wt(n);float+[o] hist(ma,mb); double stepa; double mina; int masize => ma; Signature: (ina(n); inb(n); float+ wt(n);float+[o] hist(ma,mb); double stepa; double mina; int masize => ma;
double stepb; double minb; int mbsize => mb;) double stepb; double minb; int mbsize => mb;)
=for ref =for ref
skipping to change at line 1325 skipping to change at line 1356
[ 0 0.5 0.9] [ 0 0.5 0.9]
[ 0 0.1 0] [ 0 0.1 0]
] ]
=for bad =for bad
whistogram2d processes bad values. whistogram2d 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 1547 "Primitive.pm" #line 1601 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*whistogram2d = \&PDL::whistogram2d; *whistogram2d = \&PDL::whistogram2d;
#line 1553 "Primitive.pm" #line 1608 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 fibonacci =head2 fibonacci
=for sig =for sig
Signature: (i(n); indx [o]x(n)) Signature: (i(n); indx [o]x(n))
=for ref =for ref
Constructor - a vector with Fibonacci's sequence Constructor - a vector with Fibonacci's sequence
=for bad =for bad
fibonacci does not process bad values. fibonacci 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 1577 "Primitive.pm" #line 1633 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
sub fibonacci { ref($_[0]) && ref($_[0]) ne 'PDL::Type' ? $_[0]->fibonacci : PDL ->fibonacci(@_) } sub fibonacci { ref($_[0]) && ref($_[0]) ne 'PDL::Type' ? $_[0]->fibonacci : PDL ->fibonacci(@_) }
sub PDL::fibonacci{ sub PDL::fibonacci{
my $x = &PDL::Core::_construct; my $x = &PDL::Core::_construct;
my $is_inplace = $x->is_inplace; my $is_inplace = $x->is_inplace;
my ($in, $out) = $x->clump(-1); my ($in, $out) = $x->clump(-1);
$out = $is_inplace ? $in->inplace : PDL->null; $out = $is_inplace ? $in->inplace : PDL->null;
PDL::_fibonacci_int($in, $out); PDL::_fibonacci_int($in, $out);
$out; $out;
} }
#line 1591 "Primitive.pm" #line 1648 "Primitive.pm"
#line 1061 "../../blib/lib/PDL/PP.pm" #line 1060 "../../blib/lib/PDL/PP.pm"
#line 1596 "Primitive.pm" #line 1653 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 append =head2 append
=for sig =for sig
Signature: (a(n); b(m); [o] c(mn)) Signature: (a(n); b(m); [o] c(mn))
=for ref =for ref
append two ndarrays by concatenating along their first dimensions append two ndarrays by concatenating along their first dimensions
=for example =for example
$x = ones(2,4,7); $x = ones(2,4,7);
$y = sequence 5; $y = sequence 5;
$c = $x->append($y); # size of $c is now (7,4,7) (a jumbo-ndarray ;) $c = $x->append($y); # size of $c is now (7,4,7) (a jumbo-ndarray ;)
C<append> appends two ndarrays along their first dimensions. The rest of the C<append> appends two ndarrays along their first dimensions. The rest of the
dimensions must be compatible in the threading sense. The resulting dimensions must be compatible in the broadcasting sense. The resulting
size of the first dimension is the sum of the sizes of the first dimensions size of the first dimension is the sum of the sizes of the first dimensions
of the two argument ndarrays - i.e. C<n + m>. of the two argument ndarrays - i.e. C<n + m>.
Similar functions include L</glue> (below), which can append more Similar functions include L</glue> (below), which can append more
than two ndarrays along an arbitrary dimension, and than two ndarrays along an arbitrary dimension, and
L<cat|PDL::Core/cat>, which can append more than two ndarrays that all L<cat|PDL::Core/cat>, which can append more than two ndarrays that all
have the same sized dimensions. have the same sized dimensions.
=for bad =for bad
append does not process bad values. append 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 1638 "Primitive.pm" #line 1696 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm" #line 1059 "../../blib/lib/PDL/PP.pm"
#line 1652 "primitive.pd" #line 1649 "primitive.pd"
sub PDL::append { sub PDL::append {
my ($i1, $i2, $o) = map PDL->topdl($_), @_; my ($i1, $i2, $o) = map PDL->topdl($_), @_;
if (grep $_->isempty, $i1, $i2) { if (grep $_->isempty, $i1, $i2) {
if (!defined $o) { if (!defined $o) {
return $i2->copy if $i1->isempty; return $i2->isnull ? PDL->zeroes(0) : $i2->copy if $i1->isempty;
return $i1->isnull ? PDL->zeroes(0) : $i1->copy; return $i1->isnull ? PDL->zeroes(0) : $i1->copy;
} else { } else {
$o .= $i2->isnull ? PDL->zeroes(0) : $i2, return $o if $i1->isempty; $o .= $i2->isnull ? PDL->zeroes(0) : $i2, return $o if $i1->isempty;
$o .= $i1->isnull ? PDL->zeroes(0) : $i1, return $o; $o .= $i1->isnull ? PDL->zeroes(0) : $i1, return $o;
} }
} }
$o //= PDL->null; $o //= PDL->null;
PDL::_append_int($i1, $i2, $o); PDL::_append_int($i1, $i2->convert($i1->type), $o);
$o; $o;
} }
#line 1079 "../../blib/lib/PDL/PP.pm" #line 1079 "../../blib/lib/PDL/PP.pm"
#line 1663 "Primitive.pm" #line 1722 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*append = \&PDL::append; *append = \&PDL::append;
#line 1669 "Primitive.pm" #line 1729 "Primitive.pm"
#line 1701 "primitive.pd"
#line 1705 "primitive.pd"
=head2 glue =head2 glue
=for usage =for usage
$c = $x->glue(<dim>,$y,...) $c = $x->glue(<dim>,$y,...)
=for ref =for ref
Glue two or more PDLs together along an arbitrary dimension Glue two or more PDLs together along an arbitrary dimension
(N-D L</append>). (N-D L</append>).
Sticks $x, $y, and all following arguments together along the Sticks $x, $y, and all following arguments together along the
specified dimension. All other dimensions must be compatible in the specified dimension. All other dimensions must be compatible in the
threading sense. broadcasting sense.
Glue is permissive, in the sense that every PDL is treated as having an Glue is permissive, in the sense that every PDL is treated as having an
infinite number of trivial dimensions of order 1 -- so C<< $x->glue(3,$y) >> infinite number of trivial dimensions of order 1 -- so C<< $x->glue(3,$y) >>
works, even if $x and $y are only one dimensional. works, even if $x and $y are only one dimensional.
If one of the PDLs has no elements, it is ignored. Likewise, if one If one of the PDLs has no elements, it is ignored. Likewise, if one
of them is actually the undefined value, it is treated as if it had no of them is actually the undefined value, it is treated as if it had no
elements. elements.
If the first parameter is a defined perl scalar rather than a pdl, If the first parameter is a defined perl scalar rather than a pdl,
skipping to change at line 1505 skipping to change at line 1540
next unless(defined $y && $y->nelem); next unless(defined $y && $y->nelem);
while($dim >= $y->ndims) { while($dim >= $y->ndims) {
$y = $y->dummy(-1,1); $y = $y->dummy(-1,1);
} }
$y = $y->xchg(0,$dim); $y = $y->xchg(0,$dim);
$x = $x->append($y); $x = $x->append($y);
} }
$x->xchg(0,$dim); $x->xchg(0,$dim);
} }
#line 1749 "Primitive.pm" #line 1810 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*axisvalues = \&PDL::axisvalues; *axisvalues = \&PDL::axisvalues;
#line 1755 "Primitive.pm" #line 1817 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 srand =head2 srand
=for sig =for sig
Signature: (a()) Signature: (a())
=for ref =for ref
Seed random-number generator with a 64-bit int. Will generate seed data Seed random-number generator with a 64-bit int. Will generate seed data
skipping to change at line 1536 skipping to change at line 1572
srand(); # uses current time srand(); # uses current time
srand(5); # fixed number e.g. for testing srand(5); # fixed number e.g. for testing
=for bad =for bad
srand does not process bad values. srand 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 1788 "Primitive.pm" #line 1851 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
*srand = \&PDL::srand; *srand = \&PDL::srand;
sub PDL::srand { PDL::_srand_int($_[0] // PDL::Core::seed()) } sub PDL::srand { PDL::_srand_int($_[0] // PDL::Core::seed()) }
#line 1795 "Primitive.pm" #line 1859 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*srand = \&PDL::srand; *srand = \&PDL::srand;
#line 1801 "Primitive.pm" #line 1866 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 random =head2 random
=for sig =for sig
Signature: (a()) Signature: (a())
=for ref =for ref
Constructor which returns ndarray of random numbers Constructor which returns ndarray of random numbers
skipping to change at line 1580 skipping to change at line 1618
You can use the PDL function L</srand> to seed the random generator. You can use the PDL function L</srand> to seed the random generator.
If it has not been called yet, it will be with the current time. If it has not been called yet, it will be with the current time.
=for bad =for bad
random does not process bad values. random 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 1841 "Primitive.pm" #line 1907 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
sub random { ref($_[0]) && ref($_[0]) ne 'PDL::Type' ? $_[0]->random : PDL->rand om(@_) } sub random { ref($_[0]) && ref($_[0]) ne 'PDL::Type' ? $_[0]->random : PDL->rand om(@_) }
sub PDL::random { sub PDL::random {
my $class = shift; my $class = shift;
my $x = scalar(@_)? $class->new_from_specification(@_) : $class->new_or_inpla ce; my $x = scalar(@_)? $class->new_from_specification(@_) : $class->new_or_inpla ce;
PDL::_random_int($x); PDL::_random_int($x);
return $x; return $x;
} }
#line 1853 "Primitive.pm" #line 1920 "Primitive.pm"
#line 1061 "../../blib/lib/PDL/PP.pm" #line 1060 "../../blib/lib/PDL/PP.pm"
#line 1858 "Primitive.pm" #line 1925 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 randsym =head2 randsym
=for sig =for sig
Signature: (a()) Signature: (a())
=for ref =for ref
Constructor which returns ndarray of random numbers Constructor which returns ndarray of random numbers
skipping to change at line 1627 skipping to change at line 1666
You can use the PDL function L</srand> to seed the random generator. You can use the PDL function L</srand> to seed the random generator.
If it has not been called yet, it will be with the current time. If it has not been called yet, it will be with the current time.
=for bad =for bad
randsym does not process bad values. randsym 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 1897 "Primitive.pm" #line 1965 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
sub randsym { ref($_[0]) && ref($_[0]) ne 'PDL::Type' ? $_[0]->randsym : PDL->ra ndsym(@_) } sub randsym { ref($_[0]) && ref($_[0]) ne 'PDL::Type' ? $_[0]->randsym : PDL->ra ndsym(@_) }
sub PDL::randsym { sub PDL::randsym {
my $class = shift; my $class = shift;
my $x = scalar(@_)? $class->new_from_specification(@_) : $class->new_or_inpla ce; my $x = scalar(@_)? $class->new_from_specification(@_) : $class->new_or_inpla ce;
PDL::_randsym_int($x); PDL::_randsym_int($x);
return $x; return $x;
} }
#line 1909 "Primitive.pm" #line 1978 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1983 "Primitive.pm"
#line 1061 "../../blib/lib/PDL/PP.pm" #line 1925 "primitive.pd"
#line 1914 "Primitive.pm"
#line 1929 "primitive.pd"
=head2 grandom =head2 grandom
=for ref =for ref
Constructor which returns ndarray of Gaussian random numbers Constructor which returns ndarray of Gaussian random numbers
=for usage =for usage
$x = grandom([type], $nx, $ny, $nz,...); $x = grandom([type], $nx, $ny, $nz,...);
$x = grandom $y; $x = grandom $y;
skipping to change at line 1673 skipping to change at line 1714
=cut =cut
sub grandom { ref($_[0]) && ref($_[0]) ne 'PDL::Type' ? $_[0]->grandom : PDL->gr andom(@_) } sub grandom { ref($_[0]) && ref($_[0]) ne 'PDL::Type' ? $_[0]->grandom : PDL->gr andom(@_) }
sub PDL::grandom { sub PDL::grandom {
my $class = shift; my $class = shift;
my $x = scalar(@_)? $class->new_from_specification(@_) : $class->new_or_inpla ce; my $x = scalar(@_)? $class->new_from_specification(@_) : $class->new_or_inpla ce;
use PDL::Math 'ndtri'; use PDL::Math 'ndtri';
$x .= ndtri(randsym($x)); $x .= ndtri(randsym($x));
return $x; return $x;
} }
#line 1949 "Primitive.pm" #line 2019 "Primitive.pm"
#line 1969 "primitive.pd"
#line 1973 "primitive.pd"
=head2 vsearch =head2 vsearch
=for sig =for sig
Signature: ( vals(); xs(n); [o] indx(); [\%options] ) Signature: ( vals(); xs(n); [o] indx(); [\%options] )
=for ref =for ref
Efficiently search for values in a sorted ndarray, returning indices. Efficiently search for values in a sorted ndarray, returning indices.
skipping to change at line 1820 skipping to change at line 1862
$mode eq 'sample' ? \&vsearch_sample $mode eq 'sample' ? \&vsearch_sample
: $mode eq 'insert_leftmost' ? \&vsearch_insert_leftmost : $mode eq 'insert_leftmost' ? \&vsearch_insert_leftmost
: $mode eq 'insert_rightmost' ? \&vsearch_insert_rightmost : $mode eq 'insert_rightmost' ? \&vsearch_insert_rightmost
: $mode eq 'match' ? \&vsearch_match : $mode eq 'match' ? \&vsearch_match
: $mode eq 'bin_inclusive' ? \&vsearch_bin_inclusive : $mode eq 'bin_inclusive' ? \&vsearch_bin_inclusive
: $mode eq 'bin_exclusive' ? \&vsearch_bin_exclusive : $mode eq 'bin_exclusive' ? \&vsearch_bin_exclusive
: croak( "unknown vsearch mode: $mode\n" ); : croak( "unknown vsearch mode: $mode\n" );
} }
*PDL::vsearch = \&vsearch; *PDL::vsearch = \&vsearch;
#line 2099 "Primitive.pm" #line 2170 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 vsearch_sample =head2 vsearch_sample
=for sig =for sig
Signature: (vals(); x(n); indx [o]idx()) Signature: (vals(); x(n); indx [o]idx())
=for ref =for ref
Search for values in a sorted array, return index appropriate for sampling from a distribution Search for values in a sorted array, return index appropriate for sampling from a distribution
skipping to change at line 1888 skipping to change at line 1930
$c = vsearch_sample($y, $x); # Now, $c will have the appropriate distr. $c = vsearch_sample($y, $x); # Now, $c will have the appropriate distr.
It is possible to use the L<cumusumover|PDL::Ufunc/cumusumover> It is possible to use the L<cumusumover|PDL::Ufunc/cumusumover>
function to obtain cumulative probabilities from absolute probabilities. function to obtain cumulative probabilities from absolute probabilities.
=for bad =for bad
needs major (?) work to handles bad values needs major (?) work to handles bad values
=cut =cut
#line 2192 "Primitive.pm" #line 2264 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*vsearch_sample = \&PDL::vsearch_sample; *vsearch_sample = \&PDL::vsearch_sample;
#line 2198 "Primitive.pm" #line 2271 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 vsearch_insert_leftmost =head2 vsearch_insert_leftmost
=for sig =for sig
Signature: (vals(); x(n); indx [o]idx()) Signature: (vals(); x(n); indx [o]idx())
=for ref =for ref
Determine the insertion point for values in a sorted array, inserting before dup licates. Determine the insertion point for values in a sorted array, inserting before dup licates.
skipping to change at line 1956 skipping to change at line 1999
i = 0 i = 0
If C<$x> contains duplicated elements, I<I> is the index of the If C<$x> contains duplicated elements, I<I> is the index of the
leftmost (by index in array) duplicate if I<V> matches. leftmost (by index in array) duplicate if I<V> matches.
=for bad =for bad
needs major (?) work to handles bad values needs major (?) work to handles bad values
=cut =cut
#line 2287 "Primitive.pm" #line 2361 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*vsearch_insert_leftmost = \&PDL::vsearch_insert_leftmost; *vsearch_insert_leftmost = \&PDL::vsearch_insert_leftmost;
#line 2293 "Primitive.pm" #line 2368 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 vsearch_insert_rightmost =head2 vsearch_insert_rightmost
=for sig =for sig
Signature: (vals(); x(n); indx [o]idx()) Signature: (vals(); x(n); indx [o]idx())
=for ref =for ref
Determine the insertion point for values in a sorted array, inserting after dupl icates. Determine the insertion point for values in a sorted array, inserting after dupl icates.
skipping to change at line 2024 skipping to change at line 2068
i = $x->nelem - 1 i = $x->nelem - 1
If C<$x> contains duplicated elements, I<I> is the index of the If C<$x> contains duplicated elements, I<I> is the index of the
leftmost (by index in array) duplicate if I<V> matches. leftmost (by index in array) duplicate if I<V> matches.
=for bad =for bad
needs major (?) work to handles bad values needs major (?) work to handles bad values
=cut =cut
#line 2382 "Primitive.pm" #line 2458 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*vsearch_insert_rightmost = \&PDL::vsearch_insert_rightmost; *vsearch_insert_rightmost = \&PDL::vsearch_insert_rightmost;
#line 2388 "Primitive.pm" #line 2465 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 vsearch_match =head2 vsearch_match
=for sig =for sig
Signature: (vals(); x(n); indx [o]idx()) Signature: (vals(); x(n); indx [o]idx())
=for ref =for ref
Match values against a sorted array. Match values against a sorted array.
skipping to change at line 2061 skipping to change at line 2106
index of that element, otherwise it is I<-( insertion_point + 1 )>, index of that element, otherwise it is I<-( insertion_point + 1 )>,
where I<insertion_point> is an index in C<$x> where I<V> may be where I<insertion_point> is an index in C<$x> where I<V> may be
inserted while maintaining the order in C<$x>. If C<$x> has inserted while maintaining the order in C<$x>. If C<$x> has
duplicated values, I<I> may refer to any of them. duplicated values, I<I> may refer to any of them.
=for bad =for bad
needs major (?) work to handles bad values needs major (?) work to handles bad values
=cut =cut
#line 2435 "Primitive.pm" #line 2513 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*vsearch_match = \&PDL::vsearch_match; *vsearch_match = \&PDL::vsearch_match;
#line 2441 "Primitive.pm" #line 2520 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 vsearch_bin_inclusive =head2 vsearch_bin_inclusive
=for sig =for sig
Signature: (vals(); x(n); indx [o]idx()) Signature: (vals(); x(n); indx [o]idx())
=for ref =for ref
Determine the index for values in a sorted array of bins, lower bound inclusive. Determine the index for values in a sorted array of bins, lower bound inclusive.
skipping to change at line 2127 skipping to change at line 2173
i = $x->nelem - 1 i = $x->nelem - 1
If C<$x> contains duplicated elements, I<I> is the index of the If C<$x> contains duplicated elements, I<I> is the index of the
righmost (by index in array) duplicate if I<V> matches. righmost (by index in array) duplicate if I<V> matches.
=for bad =for bad
needs major (?) work to handles bad values needs major (?) work to handles bad values
=cut =cut
#line 2528 "Primitive.pm" #line 2608 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*vsearch_bin_inclusive = \&PDL::vsearch_bin_inclusive; *vsearch_bin_inclusive = \&PDL::vsearch_bin_inclusive;
#line 2534 "Primitive.pm" #line 2615 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 vsearch_bin_exclusive =head2 vsearch_bin_exclusive
=for sig =for sig
Signature: (vals(); x(n); indx [o]idx()) Signature: (vals(); x(n); indx [o]idx())
=for ref =for ref
Determine the index for values in a sorted array of bins, lower bound exclusive. Determine the index for values in a sorted array of bins, lower bound exclusive.
skipping to change at line 2193 skipping to change at line 2240
i = $x->nelem - 1 i = $x->nelem - 1
If C<$x> contains duplicated elements, I<I> is the index of the If C<$x> contains duplicated elements, I<I> is the index of the
righmost (by index in array) duplicate if I<V> matches. righmost (by index in array) duplicate if I<V> matches.
=for bad =for bad
needs major (?) work to handles bad values needs major (?) work to handles bad values
=cut =cut
#line 2621 "Primitive.pm" #line 2703 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*vsearch_bin_exclusive = \&PDL::vsearch_bin_exclusive; *vsearch_bin_exclusive = \&PDL::vsearch_bin_exclusive;
#line 2627 "Primitive.pm" #line 2710 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 interpolate =head2 interpolate
=for sig =for sig
Signature: (xi(); x(n); y(n); [o] yi(); int [o] err()) Signature: (xi(); x(n); y(n); [o] yi(); int [o] err())
=for ref =for ref
routine for 1D linear interpolation routine for 1D linear interpolation
skipping to change at line 2238 skipping to change at line 2286
See also L</interpol>, which uses the same routine, See also L</interpol>, which uses the same routine,
differing only in the handling of extrapolation - an error message differing only in the handling of extrapolation - an error message
is printed rather than returning an error ndarray. is printed rather than returning an error ndarray.
=for bad =for bad
needs major (?) work to handles bad values needs major (?) work to handles bad values
=cut =cut
#line 2674 "Primitive.pm" #line 2758 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*interpolate = \&PDL::interpolate; *interpolate = \&PDL::interpolate;
#line 2680 "Primitive.pm" #line 2765 "Primitive.pm"
#line 2645 "primitive.pd"
#line 2649 "primitive.pd"
=head2 interpol =head2 interpol
=for sig =for sig
Signature: (xi(); x(n); y(n); [o] yi()) Signature: (xi(); x(n); y(n); [o] yi())
=for ref =for ref
routine for 1D linear interpolation routine for 1D linear interpolation
skipping to change at line 2284 skipping to change at line 2334
else { $yi = PDL->null; } else { $yi = PDL->null; }
interpolate( $xi, $x, $y, $yi, my $err = PDL->null ); interpolate( $xi, $x, $y, $yi, my $err = PDL->null );
print "some values had to be extrapolated\n" print "some values had to be extrapolated\n"
if any $err; if any $err;
return $yi if $#_ == -1; return $yi if $#_ == -1;
} # sub: interpol() } # sub: interpol()
*PDL::interpol = \&interpol; *PDL::interpol = \&interpol;
#line 2724 "Primitive.pm" #line 2810 "Primitive.pm"
#line 2689 "primitive.pd"
#line 2693 "primitive.pd"
=head2 interpND =head2 interpND
=for ref =for ref
Interpolate values from an N-D ndarray, with switchable method Interpolate values from an N-D ndarray, with switchable method
=for example =for example
$source = 10*xvals(10,10) + yvals(10,10); $source = 10*xvals(10,10) + yvals(10,10);
$index = pdl([[2.2,3.5],[4.1,5.0]],[[6.0,7.4],[8,9]]); $index = pdl([[2.2,3.5],[4.1,5.0]],[[6.0,7.4],[8,9]]);
skipping to change at line 2399 skipping to change at line 2450
$method //= $source->type->integer ? 'sample' : 'linear'; $method //= $source->type->integer ? 'sample' : 'linear';
my($boundary) = $opt->{b} || $opt->{boundary} || $opt->{Boundary} || $opt->{bo und} || $opt->{Bound} || 'extend'; my($boundary) = $opt->{b} || $opt->{boundary} || $opt->{Boundary} || $opt->{bo und} || $opt->{Bound} || 'extend';
my($bad) = $opt->{bad} || $opt->{Bad} || 0.0; my($bad) = $opt->{bad} || $opt->{Bad} || 0.0;
if($method =~ m/^s(am(p(le)?)?)?/i) { if($method =~ m/^s(am(p(le)?)?)?/i) {
return $source->range(PDL::Math::floor($index+0.5),0,$boundary); return $source->range(PDL::Math::floor($index+0.5),0,$boundary);
} }
elsif (($method eq 1) || $method =~ m/^l(in(ear)?)?/i) { elsif (($method eq 1) || $method =~ m/^l(in(ear)?)?/i) {
## key: (ith = index thread; cth = cube thread; sth = source thread) ## key: (ith = index broadcast; cth = cube broadcast; sth = source broadcast )
my $d = $index->dim(0); my $d = $index->dim(0);
my $di = $index->ndims - 1; my $di = $index->ndims - 1;
# Grab a 2-on-a-side n-cube around each desired pixel # Grab a 2-on-a-side n-cube around each desired pixel
my $samp = $source->range($index->floor,2,$boundary); # (ith, cth, sth) my $samp = $source->range($index->floor,2,$boundary); # (ith, cth, sth)
# Reorder to put the cube dimensions in front and convert to a list # Reorder to put the cube dimensions in front and convert to a list
$samp = $samp->reorder( $di .. $di+$d-1, $samp = $samp->reorder( $di .. $di+$d-1,
0 .. $di-1, 0 .. $di-1,
$di+$d .. $samp->ndims-1) # (cth, ith, sth) $di+$d .. $samp->ndims-1) # (cth, ith, sth)
skipping to change at line 2526 skipping to change at line 2577
$mag = $mag->dummy(-1,$index->dim($i)); $mag = $mag->dummy(-1,$index->dim($i));
} }
my $out = cos($phase + $phref ) * $mag; my $out = cos($phase + $phref ) * $mag;
$out = $out->clump($source->ndims)->sumover; $out = $out->clump($source->ndims)->sumover;
return $out; return $out;
} else { } else {
barf("interpND: unknown method '$method'; valid ones are 'linear' and 'samp le'.\n"); barf("interpND: unknown method '$method'; valid ones are 'linear' and 'samp le'.\n");
} }
} }
#line 2969 "Primitive.pm" #line 3056 "Primitive.pm"
#line 2938 "primitive.pd"
#line 2942 "primitive.pd"
=head2 one2nd =head2 one2nd
=for ref =for ref
Converts a one dimensional index ndarray to a set of ND coordinates Converts a one dimensional index ndarray to a set of ND coordinates
=for usage =for usage
@coords=one2nd($x, $indices) @coords=one2nd($x, $indices)
skipping to change at line 2575 skipping to change at line 2627
my @dimension=$x->dims; my @dimension=$x->dims;
$ind = indx($ind); $ind = indx($ind);
my(@index); my(@index);
my $count=0; my $count=0;
foreach (@dimension) { foreach (@dimension) {
$index[$count++]=$ind % $_; $index[$count++]=$ind % $_;
$ind /= $_; $ind /= $_;
} }
return @index; return @index;
} }
#line 3020 "Primitive.pm" #line 3108 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 which =head2 which
=for sig =for sig
Signature: (mask(n); indx [o] inds(m)) Signature: (mask(n); indx [o] inds(m))
=for ref =for ref
Returns indices of non-zero values from a 1-D PDL Returns indices of non-zero values from a 1-D PDL
skipping to change at line 2630 skipping to change at line 2682
[0 1 2 3 4 5 6 7 8 9] [0 1 2 3 4 5 6 7 8 9]
pdl> $indx = which($x>6); p $indx pdl> $indx = which($x>6); p $indx
[7 8 9] [7 8 9]
=for bad =for bad
which processes bad values. which 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 3082 "Primitive.pm" #line 3171 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
sub which { my ($this,$out) = @_; sub which { my ($this,$out) = @_;
$this = $this->flat; $this = $this->flat;
$out = $this->nullcreate unless defined $out; $out = $this->nullcreate unless defined $out;
PDL::_which_int($this,$out); PDL::_which_int($this,$out);
return $out; return $out;
} }
*PDL::which = \&which; *PDL::which = \&which;
#line 3094 "Primitive.pm" #line 3184 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*which = \&PDL::which; *which = \&PDL::which;
#line 3100 "Primitive.pm" #line 3191 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm" #line 1058 "../../blib/lib/PDL/PP.pm"
=head2 which_both =head2 which_both
=for sig =for sig
Signature: (mask(n); indx [o] inds(m); indx [o]notinds(q)) Signature: (mask(n); indx [o] inds(m); indx [o]notinds(q))
=for ref =for ref
Returns indices of zero and nonzero values in a mask PDL Returns indices of zero and nonzero values in a mask PDL
skipping to change at line 2679 skipping to change at line 2733
pdl> ($small, $big) = which_both ($x >= 5); p "$small\n $big" pdl> ($small, $big) = which_both ($x >= 5); p "$small\n $big"
[5 6 7 8 9] [5 6 7 8 9]
[0 1 2 3 4] [0 1 2 3 4]
=for bad =for bad
which_both processes bad values. which_both 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 3142 "Primitive.pm" #line 3234 "Primitive.pm"
#line 1059 "../../blib/lib/PDL/PP.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
sub which_both { my ($this,$outi,$outni) = @_; sub which_both { my ($this,$outi,$outni) = @_;
$this = $this->flat; $this = $this->flat;
$outi = $this->nullcreate unless defined $outi; $outi = $this->nullcreate unless defined $outi;
$outni = $this->nullcreate unless defined $outni; $outni = $this->nullcreate unless defined $outni;
PDL::_which_both_int($this,$outi,$outni); PDL::_which_both_int($this,$outi,$outni);
return wantarray ? ($outi,$outni) : $outi; return wantarray ? ($outi,$outni) : $outi;
} }
*PDL::which_both = \&which_both; *PDL::which_both = \&which_both;
#line 3155 "Primitive.pm" #line 3248 "Primitive.pm"
#line 1060 "../../blib/lib/PDL/PP.pm"
#line 1061 "../../blib/lib/PDL/PP.pm"
*which_both = \&PDL::which_both; *which_both = \&PDL::which_both;
#line 3161 "Primitive.pm" #line 3255 "Primitive.pm"
#line 3142 "primitive.pd"
#line 3146 "primitive.pd"
=head2 where =head2 where
=for ref =for ref
Use a mask to select values from one or more data PDLs Use a mask to select values from one or more data PDLs
C<where> accepts one or more data ndarrays and a mask ndarray. It C<where> accepts one or more data ndarrays and a mask ndarray. It
returns a list of output ndarrays, corresponding to the input data returns a list of output ndarrays, corresponding to the input data
ndarrays. Each output ndarray is a 1-dimensional list of values in its ndarrays. Each output ndarray is a 1-dimensional list of values in its
corresponding data ndarray. The values are drawn from locations where corresponding data ndarray. The values are drawn from locations where
skipping to change at line 2718 skipping to change at line 2775
The output PDLs are still connected to the original data PDLs, for the The output PDLs are still connected to the original data PDLs, for the
purpose of dataflow. purpose of dataflow.
C<where> combines the functionality of L</which> and L<index|PDL::Slices/index> C<where> combines the functionality of L</which> and L<index|PDL::Slices/index>
into a single operation. into a single operation.
BUGS: BUGS:
While C<where> works OK for most N-dimensional cases, it does not While C<where> works OK for most N-dimensional cases, it does not
thread properly over (for example) the (N+1)th dimension in data broadcast properly over (for example) the (N+1)th dimension in data
that is compared to an N-dimensional mask. Use C<whereND> for that. that is compared to an N-dimensional mask. Use C<whereND> for that.
=for usage =for usage
$i = $x->where($x+5 > 0); # $i contains those elements of $x $i = $x->where($x+5 > 0); # $i contains those elements of $x
# where mask ($x+5 > 0) is 1 # where mask ($x+5 > 0) is 1
$i .= -5; # Set those elements (of $x) to -5. Together, these $i .= -5; # Set those elements (of $x) to -5. Together, these
# commands clamp $x to a maximum of -5. # commands clamp $x to a maximum of -5.
It is also possible to use the same mask for several ndarrays with It is also possible to use the same mask for several ndarrays with
the same call: the same call:
($i,$j,$k) = where($x,$y,$z, $x+5>0); ($i,$j,$k) = where($x,$y,$z, $x+5>0);
Note: C<$i> is always 1-D, even if C<$x> is E<gt>1-D. Note: C<$i> is always 1-D, even if C<$x> is E<gt>1-D.
WARNING: The first argument WARNING: The first argument
(the values) and the second argument (the mask) currently have to have (the values) and the second argument (the mask) currently have to have
the exact same dimensions (or horrible things happen). You *cannot* the exact same dimensions (or horrible things happen). You *cannot*
thread over a smaller mask, for example. broadcast over a smaller mask, for example.
=cut =cut
sub PDL::where { sub PDL::where {
barf "Usage: where( \$pdl1, ..., \$pdlN, \$mask )\n" if $#_ == 0; barf "Usage: where( \$pdl1, ..., \$pdlN, \$mask )\n" if $#_ == 0;
if($#_ == 1) { if($#_ == 1) {
my($data,$mask) = @_; my($data,$mask) = @_;
$data = $_[0]->clump(-1) if $_[0]->getndims>1; $data = $_[0]->clump(-1) if $_[0]->getndims>1;
$mask = $_[1]->clump(-1) if $_[0]->getndims>1; $mask = $_[1]->clump(-1) if $_[0]->getndims>1;
skipping to change at line 2761 skipping to change at line 2818
if($_[-1]->getndims > 1) { if($_[-1]->getndims > 1) {
my $mask = $_[-1]->clump(-1)->which; my $mask = $_[-1]->clump(-1)->which;
return map {$_->clump(-1)->index($mask)} @_[0..$#_-1]; return map {$_->clump(-1)->index($mask)} @_[0..$#_-1];
} else { } else {
my $mask = $_[-1]->which; my $mask = $_[-1]->which;
return map {$_->index($mask)} @_[0..$#_-1]; return map {$_->index($mask)} @_[0..$#_-1];
} }
} }
} }
*where = \&PDL::where; *where = \&PDL::where;
#line 3230 "Primitive.pm" #line 3325 "Primitive.pm"
#line 3212 "primitive.pd"
#line 3216 "primitive.pd"
=head2 whereND =head2 whereND
=for ref =for ref
C<where> with support for ND masks and threading C<where> with support for ND masks and broadcasting
C<whereND> accepts one or more data ndarrays and a C<whereND> accepts one or more data ndarrays and a
mask ndarray. It returns a list of output ndarrays, mask ndarray. It returns a list of output ndarrays,
corresponding to the input data ndarrays. The values corresponding to the input data ndarrays. The values
are drawn from locations where the mask is nonzero. are drawn from locations where the mask is nonzero.
C<whereND> differs from C<where> in that the mask C<whereND> differs from C<where> in that the mask
dimensionality is preserved which allows for dimensionality is preserved which allows for
proper threading of the selection operation over proper broadcasting of the selection operation over
higher dimensions. higher dimensions.
As with C<where> the output PDLs are still connected As with C<where> the output PDLs are still connected
to the original data PDLs, for the purpose of dataflow. to the original data PDLs, for the purpose of dataflow.
=for usage =for usage
$sdata = whereND $data, $mask $sdata = whereND $data, $mask
($s1, $s2, ..., $sn) = whereND $d1, $d2, ..., $dn, $mask ($s1, $s2, ..., $sn) = whereND $d1, $d2, ..., $dn, $mask
where where
$data is M dimensional $data is M dimensional
$mask is N < M dimensional $mask is N < M dimensional
dims($data) 1..N == dims($mask) 1..N dims($data) 1..N == dims($mask) 1..N
with threading over N+1 to M dimensions with broadcasting over N+1 to M dimensions
=for example =for example
$data = sequence(4,3,2); # example data array $data = sequence(4,3,2); # example data array
$mask4 = (random(4)>0.5); # example 1-D mask array, has $n4 true values $mask4 = (random(4)>0.5); # example 1-D mask array, has $n4 true values
$mask43 = (random(4,3)>0.5); # example 2-D mask array, has $n43 true values $mask43 = (random(4,3)>0.5); # example 2-D mask array, has $n43 true values
$sdat4 = whereND $data, $mask4; # $sdat4 is a [$n4,3,2] pdl $sdat4 = whereND $data, $mask4; # $sdat4 is a [$n4,3,2] pdl
$sdat43 = whereND $data, $mask43; # $sdat43 is a [$n43,2] pdl $sdat43 = whereND $data, $mask43; # $sdat43 is a [$n43,2] pdl
Just as with C<where>, you can use the returned value in an Just as with C<where>, you can use the returned value in an
skipping to change at line 2849 skipping to change at line 2907
foreach my $id ($n, @idims[0..($#idims-1)]) { foreach my $id ($n, @idims[0..($#idims-1)]) {
$where_sub_i = $where_sub_i->splitdim($ndim++,$id) if $n>0; $where_sub_i = $where_sub_i->splitdim($ndim++,$id) if $n>0;
} }
push @to_return, $where_sub_i; push @to_return, $where_sub_i;
} }
return (@to_return == 1) ? $to_return[0] : @to_return; return (@to_return == 1) ? $to_return[0] : @to_return;
} }
*whereND = \&PDL::whereND; *whereND = \&PDL::whereND;
#line 3320 "Primitive.pm" #line 3416 "Primitive.pm"
#line 3303 "primitive.pd"
#line 3307 "primitive.pd"
=head2 whichND =head2 whichND
=for ref =for ref
Return the coordinates of non-zero values in a mask. Return the coordinates of non-zero values in a mask.
=for usage =for usage
WhichND returns the N-dimensional coordinates of each nonzero value in WhichND returns the N-dimensional coordinates of each nonzero value in
a mask PDL with any number of dimensions. The returned values arrive a mask PDL with any number of dimensions. The returned values arrive
skipping to change at line 2874 skipping to change at line 2933
$coords = whichND($mask); $coords = whichND($mask);
returns a PDL containing the coordinates of the elements that are non-zero returns a PDL containing the coordinates of the elements that are non-zero
in C<$mask>, suitable for use in L<PDL::Slices/indexND>. The 0th dimension conta ins the in C<$mask>, suitable for use in L<PDL::Slices/indexND>. The 0th dimension conta ins the
full coordinate listing of each point; the 1st dimension lists all the points. full coordinate listing of each point; the 1st dimension lists all the points.
For example, if $mask has rank 4 and 100 matching elements, then $coords has For example, if $mask has rank 4 and 100 matching elements, then $coords has
dimension 4x100. dimension 4x100.
If no such elements exist, then whichND returns a structured empty PDL: If no such elements exist, then whichND returns a structured empty PDL:
an Nx0 PDL that contains no values (but matches, threading-wise, with an Nx0 PDL that contains no values (but matches, broadcasting-wise, with
the vectors that would be produced if such elements existed). the vectors that would be produced if such elements existed).
DEPRECATED BEHAVIOR IN LIST CONTEXT: DEPRECATED BEHAVIOR IN LIST CONTEXT:
whichND once delivered different values in list context than in scalar whichND once delivered different values in list context than in scalar
context, for historical reasons. In list context, it returned the context, for historical reasons. In list context, it returned the
coordinates transposed, as a collection of 1-PDLs (one per dimension) coordinates transposed, as a collection of 1-PDLs (one per dimension)
in a list. This usage is deprecated in PDL 2.4.10, and will cause a in a list. This usage is deprecated in PDL 2.4.10, and will cause a
warning to be issued every time it is encountered. To avoid the warning to be issued every time it is encountered. To avoid the
warning, you can set the global variable "$PDL::whichND" to 's' to warning, you can set the global variable "$PDL::whichND" to 's' to
skipping to change at line 2953 skipping to change at line 3012
} }
for my $i (0..$#mdims) { for my $i (0..$#mdims) {
my($s) = $ind->index($i); my($s) = $ind->index($i);
$s /= $mult->index($i); $s /= $mult->index($i);
$s %= $mdims[$i]; $s %= $mdims[$i];
} }
return $ind; return $ind;
} }
#line 3427 "Primitive.pm" #line 3524 "Primitive.pm"
#line 3416 "primitive.pd"
#line 3420 "primitive.pd"
=head2 setops =head2 setops
=for ref =for ref
Implements simple set operations like union and intersection Implements simple set operations like union and intersection
=for usage =for usage
Usage: $set = setops($x, <OPERATOR>, $y); Usage: $set = setops($x, <OPERATOR>, $y);
skipping to change at line 3134 skipping to change at line 3194
# Make ordered list of set union. # Make ordered list of set union.
my $union = append($x, $y)->qsort; my $union = append($x, $y)->qsort;
return $union->where($union == rotate($union, -1)); return $union->where($union == rotate($union, -1));
} else { } else {
print "The operation $op is not known!"; print "The operation $op is not known!";
return -1; return -1;
} }
} }
#line 3611 "Primitive.pm" #line 3709 "Primitive.pm"
#line 3600 "primitive.pd"
#line 3604 "primitive.pd"
=head2 intersect =head2 intersect
=for ref =for ref
Calculate the intersection of two ndarrays Calculate the intersection of two ndarrays
=for usage =for usage
Usage: $set = intersect($x, $y); Usage: $set = intersect($x, $y);
skipping to change at line 3170 skipping to change at line 3231
=cut =cut
*intersect = \&PDL::intersect; *intersect = \&PDL::intersect;
sub PDL::intersect { sub PDL::intersect {
return setops($_[0], 'AND', $_[1]); return setops($_[0], 'AND', $_[1]);
} }
#line 3649 "Primitive.pm" #line 3748 "Primitive.pm"
#line 3643 "primitive.pd" #line 3639 "primitive.pd"
=head1 AUTHOR =head1 AUTHOR
Copyright (C) Tuomas J. Lukka 1997 (lukka@husc.harvard.edu). Contributions Copyright (C) Tuomas J. Lukka 1997 (lukka@husc.harvard.edu). Contributions
by Christian Soeller (c.soeller@auckland.ac.nz), Karl Glazebrook by Christian Soeller (c.soeller@auckland.ac.nz), Karl Glazebrook
(kgb@aaoepp.aao.gov.au), Craig DeForest (deforest@boulder.swri.edu) (kgb@aaoepp.aao.gov.au), Craig DeForest (deforest@boulder.swri.edu)
and Jarle Brinchmann (jarle@astro.up.pt) and Jarle Brinchmann (jarle@astro.up.pt)
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.
Updated for CPAN viewing compatibility by David Mertens. Updated for CPAN viewing compatibility by David Mertens.
=cut =cut
#line 3672 "Primitive.pm" #line 3772 "Primitive.pm"
# Exit with OK status # Exit with OK status
1; 1;
 End of changes. 226 change blocks. 
229 lines changed or deleted 290 lines changed or added

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