PDL::Primitive
Primitive(e)   User Contributed Perl Documentation   Primitive(e)



NAME
       PDL::Primitive - primitive operations for pdl

DESCRIPTION
       This module provides some primitive and useful functions
       defined using PDL::PP and able to use the new indexing
       tricks.

       See PDL::Indexing for how to use indices creatively.  For
       explanation of the signature format, see PDL::PP.

SYNOPSIS
        use PDL::Primitive;


FUNCTIONS
       inner

         Signature: (a(a); b(b); [o]c())

       Inner product over one dimension

        c = sum_i a_i * b_i


       outer

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

       outer product over one dimension

       Naturally, it is possible to achieve the effects of outer
       product simply by threading over the ""*"" operator but
       this function is provided for convenience.

       matmult

        Signature: (a(x,y),b(y,z),[o]c(x,z))

       Matrix multiplication

       We peruse the inner product to define matrix multiplica-
       tion via a threaded inner product

       innerwt

         Signature: (a(a); b(b); c(c); [o]d())

       Weighted (i.e. triple) inner product

        d = sum_i a(a) b(b) c(c)


       inner2

         Signature: (a(a); b(n,m); c(c); [o]d())

       Inner product of two vectors and a matrix

        d = sum_ij a(a) b(i,j) c(c)

       Note that you should probably not thread over "a" and "c"
       since that would be very wasteful. Instead, you should use
       a temporary for "b*c".

       inner2d

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

       Inner product over 2 dimensions.

       Equivalent to

        $c = inner($a->clump(p), $b->clump(p))


       inner2t

         Signature: (a(j,n); b(n,m); c(m,k); [t]tmp(n,k); [o]d(j,k)))

       Efficient Triple matrix product "a*b*c"

       Efficiency comes from by using the temporary "tmp". This
       operation only scales as "N**3" whereas threading using
       inner2 would scale as "N**4".

       The reason for having this routine is that you do not need
       to have the same thread-dimensions for "tmp" as for the
       other arguments, which in case of large numbers of matri-
       ces makes this much more memory-efficient.

       It is hoped that things like this could be taken care of
       as a kind of closures at some point.

       crossp

         Signature: (a(tri=3); b(b); [o] c(c))

       Cross product of two 3D vectors

       After

        $c = crossp $a, $b

       the inner product "$c*$a" and "$c*$b" will be zero, i.e.
       $c is orthogonal to $a and $b

       norm

         Signature: (vec(c); [o] norm(m))

       Normalises a vector to unit Euclidean length

       indadd

         Signature: (a(); int ind(); [o] sum(m))

       Threaded Index Add: Add "a" to the "ind" element of "sum",
       i.e:

        sum(m) += a

       Simple Example:





         $a = 2;
         $ind = 3;
         $sum = zeroes(s);
         indadd($a,$ind, $sum);
         print $sum
         #Result: ( 2 added to element 3 of $sum)
         # [0 0 0 2 0 0 0 0 0 0]

       Threaded Example:

         $a = pdl( 1,2,3);
         $ind = pdl( 1,4,6);
         $sum = zeroes(s);
         indadd($a,$ind, $sum);
         print $sum."\n";
         #Result: ( 1, 2, and 3 added to elements 1,4,6 $sum)
         # [0 1 0 0 2 0 3 0 0 0]


       conv1d

         Signature: (a(a); kern(n); [o]b(b); int reflect)

       1d convolution along first dimension

         $con = conv1d sequence(e), pdl(-1,0,1), {Boundary => 'reflect'};

       By default, periodic boundary conditions are assumed (i.e.
       wrap around).  Alternatively, you can request reflective
       boundary conditions using the "Boundary" option:

         {Boundary => 'reflect'} # case in 'reflect' doesn't matter

       The convolution is performed along the first dimension. To
       apply it across another dimension use the slicing rou-
       tines, e.g.

         $b = $a->mv(2,0)->conv1d($kernel)->mv(0,2); # along third dim

       This function is useful for threaded filtering of 1D sig-
       nals.

       Compare also conv2d, convolve, fftconvolve, fftwconv,
       rfftwconv

       in

         Signature: (a(); b(b); [o] c())

       test if a is in the set of values b

          $goodmsk = $labels->in($goodlabels);
          print pdl(4,3,1)->in(pdl(2,3,3));
         [0 1 0]

       "in" is akin to the is an element of of set theory. In
       priciple, PDL threading could be used to achieve its func-
       tionality by using a construct like

          $msk = ($labels->dummy(y) == $goodlabels)->orover;

       However, "in" doesn't create a (potentially large) inter-
       mediate and is generally faster.




       uniq

       return all unique elements of a piddle

       The unique elements are returned in ascending order.

         print pdl(2,2,2,4,0,-1,6,6)->uniq;
        [-1 0 2 4 6]

       Note: The returned pdl is 1D; any structure of the input
       piddle is lost.

       hclip

         Signature: (a(); b(); [o] c())

       clip $a by $b ($b is upper bound)

       lclip

         Signature: (a(); b(); [o] c())

       clip $a by $b ($b is lower bound)

       clip

       Clip a piddle by (optional) upper or lower bounds.

        $b = $a->clip(0,3);
        $c = $a->clip(undef, $x);


       wtstat

         Signature: (a(a); wt(t); avg(); [o]b(); int deg)

       Weighted statistical moment of given degree

       This calculates a weighted statistic over the vector "a".
       The formula is

        b() = (sum_i wt_i * (a_i ** degree - avg)) / (sum_i wt_i)


       statsover

         Signature: (a(a); w(w); int+ [o]avg(); int+ [o]rms(); int+ [o]min(); int+ [o]max(); int+ [o]adev())

       Calculate useful statistics over a dimension of a piddle

         ($mean, $rms, $median, $min, $max, $adev) = statover($piddle, $weights);

       This utility function calculates various useful quantities
       of a piddle. These are the mean:

         MEAN = sum (x)/ N

       with "N" being the number of elements in x, the root mean
       square deviation from the mean, RMS, given as,

         RMS = sqrt(sum( (x-mean(n))^2 )/(N-1));

       Note the use of "N-1" which for almost all cases should be
       the right normalisation factor. The routine also returns
       the median, minimum and maximum of the piddle as well as
       the mean absolute deviation, defined as:

         ADEV = sqrt(sum( abs(x-mean(n)) )/N)

       note here that we use the mean and not the median. This
       could possibly be changed in future versions of the code.

       This operator is a projection operator so the calculation
       will take place over the final dimension. Thus if the
       input is N-dimensional each returned value will be N-1
       dimensional, to calculate the statistics for the entire
       piddle either use "clump(-1)" directly on the piddle or
       call "stats".

       stats

       Calculates useful statistics on a piddle

        ($mean,$rms,$median,$min,$max) = stats($piddle,[$weights]);

       This utility calculates all the most useful quantities in
       one call.

       Note: The RMS value that this function returns in the RMS
       deviation from the mean, also known as the population
       standard- deviation.

       histogram

         Signature: (in(n); int+[o] hist(t); double step; double min; int msize => m)

       Calculates a histogram for given stepsize and minimum.

        $h = histogram($data, $step, $min, $numbins);
        $hist = zeroes $numbins;  # Put histogram in existing piddle.
        histogram($data, $hist, $step, $min, $numbins);

       The histogram will contain $numbins bins starting from
       $min, each $step wide. The value in each bin is the number
       of values in $data that lie within the bin limits.

       Data below the lower limit is put in the first bin, and
       data above the upper limit is put in the last bin.

       The output is reset in a different threadloop so that you
       can take a histogram of "$a(10,12)" into "$b(b)" and get
       the result you want.

       Use hist instead for a high-level interface.

        perldl> p histogram(pdl(1,1,2),1,0,3)
        [0 2 1]


       whistogram

         Signature: (in(n); float+ wt(t);float+[o] hist(t); double step; double min; int msize => m)

       Calculates a histogram from weighted data for given step-
       size and minimum.

        $h = whistogram($data, $weights, $step, $min, $numbins);
        $hist = zeroes $numbins;  # Put histogram in existing piddle.
        whistogram($data, $weights, $hist, $step, $min, $numbins);

       The histogram will contain $numbins bins starting from
       $min, each $step wide. The value in each bin is the sum of
       the values in $weights that correspond to values in $data
       that lie within the bin limits.

       Data below the lower limit is put in the first bin, and
       data above the upper limit is put in the last bin.

       The output is reset in a different threadloop so that you
       can take a histogram of "$a(10,12)" into "$b(b)" and get
       the result you want.

        perldl> p whistogram(pdl(1,1,2), pdl(0.1,0.1,0.5), 1, 0, 4)
        [0 0.2 0.5 0]


       histogram2d

         Signature: (ina(a); inb(b); int+[o] hist(ma,mb); double stepa; double mina; int masize => ma;
                            double stepb; double minb; int mbsize => mb;)

       Calculates a 2d histogram.

        $h = histogram2d($datax, $datay,
              $stepx, $minx, $nbinx, $stepy, $miny, $nbiny);
        $hist = zeroes $nbinx, $nbiny;  # Put histogram in existing piddle.
        histogram2d($datax, $datay, $hist,
              $stepx, $minx, $nbinx, $stepy, $miny, $nbiny);

       The histogram will contain $nbinx x $nbiny bins, with the
       lower limits of the first one at "($minx, $miny)", and
       with bin size "($stepx, $stepy)".  The value in each bin
       is the number of values in $datax and $datay that lie
       within the bin limits.

       Data below the lower limit is put in the first bin, and
       data above the upper limit is put in the last bin.

        perldl> p histogram2d(pdl(1,1,1,2,2),pdl(2,1,1,1,1),1,0,3,1,0,3)
        [
         [0 0 0]
         [0 2 2]
         [0 1 0]
        ]


       whistogram2d

         Signature: (ina(a); inb(b); float+ wt(t);float+[o] hist(ma,mb); double stepa; double mina; int masize => ma;
                            double stepb; double minb; int mbsize => mb;)

       Calculates a 2d histogram from weighted data.

        $h = whistogram2d($datax, $datay, $weights,
              $stepx, $minx, $nbinx, $stepy, $miny, $nbiny);
        $hist = zeroes $nbinx, $nbiny;  # Put histogram in existing piddle.
        whistogram2d($datax, $datay, $weights, $hist,
              $stepx, $minx, $nbinx, $stepy, $miny, $nbiny);

       The histogram will contain $nbinx x $nbiny bins, with the
       lower limits of the first one at "($minx, $miny)", and
       with bin size "($stepx, $stepy)".  The value in each bin
       is the sum of the values in $weights that correspond to
       values in $datax and $datay that lie within the bin lim-
       its.

       Data below the lower limit is put in the first bin, and
       data above the upper limit is put in the last bin.

        perldl> p whistogram2d(pdl(1,1,1,2,2),pdl(2,1,1,1,1),pdl(0.1,0.2,0.3,0.4,0.5),1,0,3,1,0,3)
        [
         [  0   0   0]
         [  0 0.5 0.9]
         [  0 0.1   0]
        ]


       fibonacci

         Signature: ([o]x(x))

       Constructor - a vector with Fibonacci's sequence

       append

         Signature: (a(a); b(b); [o] c(c))

       append two piddles by concantening along their respective
       first dimensions

        $a = ones(2,4,7);
        $b = sequence 5;
        $c = $a->append($b);  # size of $c is now (7,4,7) (a jumbo-piddle ;)

       "append" appends two piddles along their first dims. Rest
       of the dimensions must be compatible in the threading
       sense. Resulting size of first dim is the sum of the sizes
       of the first dims of the two argument piddles - ie "n +
       m".

       axisvalues

         Signature: ([o,nc]a(a))

       Internal routine

       "axisvalues" is the internal primitive that implements
       axisvals and alters its argument.

       random

       Constructor which returns piddle of random numbers

        $a = random([type], $nx, $ny, $nz,...);
        $a = random $b;

       etc (see zeroes).

       This is the uniform distribution between 0 and 1
       (assumedly excluding 1 itself). The arguments are the same
       as "zeroes" (q.v.) - i.e. one can specify dimensions,
       types or give a template.

       You can use the perl function srand to seed the random
       generator. For further details consult Perl's  srand docu-
       mentation.

       randsym

       Constructor which returns piddle of random numbers

        $a = randsym([type], $nx, $ny, $nz,...);
        $a = randsym $b;

       etc (see zeroes).

       This is the uniform distribution between 0 and 1 (exclud-
       ing both 0 and 1, cf random). The arguments are the same
       as "zeroes" (q.v.) - i.e. one can specify dimensions,
       types or give a template.

       You can use the perl function srand to seed the random
       generator. For further details consult Perl's  srand docu-
       mentation.

       grandom

       Constructor which returns piddle of Gaussian random num-
       bers

        $a = grandom([type], $nx, $ny, $nz,...);
        $a = grandom $b;

       etc (see zeroes).

       This is generated using the math library routine "ndtri".

       Mean = 0, Stddev = 1

       You can use the perl function srand to seed the random
       generator. For further details consult Perl's  srand docu-
       mentation.

       vsearch

         Signature: (i(); x(x); int [o]ip())

       routine for searching 1D values i.e. step-function inter-
       polation.

        $inds = vsearch($vals, $xs);

       Returns for each value of $vals the index of the least
       larger member of $xs (which need to be in increasing
       order). If the value is larger than any member of $xs, the
       index to the last element of $xs is returned.

       This function is useful e.g. when you have a list of prob-
       abilities for events and want to generate indices to
       events:

        $a = pdl(.01,.86,.93,1); # Barnsley IFS probabilities cumulatively
        $b = random 20;
        $c = vsearch($b, $a); # Now, $c will have the appropriate distr.

       It is possible to use the cumusumover function to obtain
       cumulative probabilities from absolute probabilities.

       interpolate

         Signature: (xi(); x(x); y(y); [o] yi(); int [o] err())

       routine for 1D linear interpolation

        ( $yi, $err ) = interpolate($xi, $x, $y)

       Given a set of points "($x,$y)", use linear interpolation
       to find the values $yi at a set of points $xi.

       "interpolate" uses a binary search to find the suspects,
       er..., interpolation indices and therefore abscissas (ie
       $x) have to be strictly ordered (increasing or decreas-
       ing).  For interpolation at lots of closely spaced abscis-
       sas an approach that uses the last index found as a start
       for the next search can be faster (compare Numerical
       Recipes "hunt" routine). Feel free to implement that on
       top of the binary search if you like. For out of bounds
       values it just does a linear extrapolation and sets the
       corresponding element of $err to 1, which is otherwise 0.

       See also interpol, which uses the same routine, differing
       only in the handling of extrapolation - an error message
       is printed rather than returning an error piddle.

       interpol

        Signature: (xi(); x(x); y(y); [o] yi())

       routine for 1D linear interpolation

        $yi = interpol($xi, $x, $y)

       "interpol" uses the same search method as interpolate,
       hence $x must be strictly ordered (either increasing or
       decreasing).  The difference occurs in the handling of
       out-of-bounds values; here an error message is printed.

       one2nd

       Converts a one dimensional index piddle to a set of ND
       coordinates

        @coords=one2nd($a, $indices)

       returns an array of piddles containing the ND indexes cor-
       responding to the one dimensional list indices. The
       indices are assumed to correspond to array $a clumped
       using "clump(-1)". This routine is used in whichND, but is
       useful on its own occasionally.

        perldl> $a=pdl [[[1,2],[-1,1]], [[0,-3],[3,2]]]; $c=$a->clump(-1)
        perldl> $maxind=maximum_ind($c); p $maxind;
        6
        perldl> print one2nd($a, maximum_ind($c))
        0 1 1
        perldl> p $a->at(0,1,1)
        3


       which

         Signature: (mask(k); int [o] inds(s))

       Returns piddle of indices of non-zero values.

        $i = which($mask);

       returns a pdl with indices for all those elements that are
       nonzero in the mask. Note that the returned indices will
       be 1D. If you want to index into the original mask or a
       similar piddle remember to flatten it before calling
       index:



         $data = random 5, 5;
         $idx = which $data > 0.5; # $idx is now 1D
         $bigsum = $data->flat->index($idx)->sum;  # flatten before indexing

       Compare also where for similar functionality.

       If you want to return both the indices of non-zero values
       and the complement, use the function which_both.

        perldl> $x = sequence(e); p $x
        [0 1 2 3 4 5 6 7 8 9]
        perldl> $indx = which($x>6); p $indx
        [7 8 9]


       which_both

         Signature: (mask(k); int [o] inds(s); int [o]notinds(s))

       Returns piddle of indices of non-zero values and their
       complement

        ($i, $c_i) = which_both($mask);

       This works just as which, but the complement of $i will be
       in $c_i.

        perldl> $x = sequence(e); p $x
        [0 1 2 3 4 5 6 7 8 9]
        perldl> ($small, $big) = which_both ($x >= 5); p "$small\n $big"
        [5 6 7 8 9]
        [0 1 2 3 4]


       where

       Returns indices to non-zero values or those values from
       another piddle.

        $i = $x->where($x+5 > 0); # $i contains elements of $x
                                  # where mask ($x+5 > 0) is 1

       Note: $i is always 1-D, even if $x is >1-D. The first
       argument (the values) and the second argument (the mask)
       currently have to have the same initial dimensions (or
       horrible things happen).

       It is also possible to use the same mask for several pid-
       dles with the same call:

        ($i,$j,$k) = where($x,$y,$z, $x+5>0);


       whichND

       Returns the coordinates for non-zero values

        @coords=whichND($mask);

       returns an array of piddles containing the coordinates of
       the elements that are non-zero in $mask.





        perldl> $a=sequence(10,10,3,4)
        perldl> ($x, $y, $z, $w)=whichND($a == 203); p $x, $y, $z, $w
        [3] [0] [2] [0]
        perldl> print $a->at(list(cat($x,$y,$z,$w)))
        203


AUTHOR
       Copyright (C) Tuomas J. Lukka 1997 (lukka@husc.har-
       vard.edu). Contributions by Christian Soeller
       (c.soeller@auckland.ac.nz) and Karl Glazebrook
       (kgb@aaoepp.aao.gov.au).  All rights reserved. There is no
       warranty. You are allowed to redistribute this software /
       documentation under certain conditions. For details, see
       the file COPYING in the PDL distribution. If this file is
       separated from the PDL distribution, the copyright notice
       should be included in the file.



perl v5.6.1                 2002-04-08               Primitive(e)