PDL::Slices
Slices(s)      User Contributed Perl Documentation      Slices(s)



NAME
       PDL::Slices -- Stupid index tricks

SYNOPSIS
         use PDL;
         $a = ones(3,3);
         $b = $a->slice('-1:0,(1)');
         $c = $a->dummy(y);


DESCRIPTION
       This package provides many of the powerful PerlDL core
       index manipulation routines. These routines are usually
       two-way so you can get a unit matrix by

        $a = zeroes(1000,1000);
        $a->diagonal(0,1) ++;

       which is usually fairly efficient. See PDL::Indexing and
       PDL::Tips for more examples.

       These functions are usually two-way:

        $b = $a->slice("1:3");
        $b += 5;               # $a is changed!

       If you want to force a copy and no "flow" backwards, you
       need

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

       alternatively, you can use

        $b = $a->slice("1:3")->sever;

       which does not copy the struct but beware that after

        $b = $a->slice("1:3");
        $c = $b->sever;

       the variables $b and $c point to the same object but with
       "->copy" they do not.

       The fact that there is this kind of flow makes PDL a very
       powerful language in many ways: since you can alter the
       original data by altering some easier-to-use representa-
       tion of it, many things are much easier to accomplish,
       just like making the above unit matrix.

FUNCTIONS
       index

         Signature: (a(a); int ind(); [oca] c())

       These functions provide rudimentary index indirection.

        $c = a(ind());
        $c = a(ind1(),ind2());

       It would be useful to have a more complete function for
       this at some point, or at least a perl wrapper, that
       allows

        $c = $a->islice("1:2",$ind1,"3:4",$ind2);

       with many dimensions.

       This function is two-way, i.e. after

        $c = $a->index(pdl[0,5,8]);
        $c .= pdl [0,2,4];

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

       index2d

         Signature: (a(na,nb); int inda(); int indb(); [oca] c())

       These functions provide rudimentary index indirection.

        $c = a(ind());
        $c = a(ind1(),ind2());

       It would be useful to have a more complete function for
       this at some point, or at least a perl wrapper, that
       allows

        $c = $a->islice("1:2",$ind1,"3:4",$ind2);

       with many dimensions.

       This function is two-way, i.e. after

        $c = $a->index(pdl[0,5,8]);
        $c .= pdl [0,2,4];

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

       rld

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

       Run-length decode a vector

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

        rld($a,$b,$c=null);


       rle

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

       Run-length encode a vector

       Given vector $c, generate a vector $a with the number of
       each element, and a vector $b of the unique values.  Only
       the elements up to the first instance of `0' in $a should
       be considered.

        rle($c,$a=null,$b=null);






       xchg

         Signature: (P(); C(); int n1; int n2)

       exchange two dimensions

       Negative dimension indices count from the end.

       The command

        $b = $a->xchg(2,3);

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

        $b->at(5,3,2,8) == $a->at(5,3,8,2)


       reorder

       Re-orders the dimensions of a PDL based on the supplied
       list.

       Similar to the xchg method, this method re-orders the
       dimensions of a PDL. While the xchg method swaps the posi-
       tion of two dimensions, the reorder method can change the
       positions of many dimensions at once.

        # Completely reverse the dimension order of a 6-Dim array.
        $reOrderedPDL = $pdl->reorder(5,4,3,2,1,0);

       The argument to reorder is an array representing where the
       current dimensions should go in the new array. In the
       above usage, the argument to reorder "(5,4,3,2,1,0)" indi-
       cates that the old dimensions ($pdl's dims) should be re-
       arranged to make the new pdl ($reOrderPDL) according to
       the following:

          Old Position   New Position
          ------------   ------------
          5              0
          4              1
          3              2
          2              3
          1              4
          0              5

       Example:

















        perldl> $a = sequence(5,3,2);    # Create a 3-d Array
        perldl> p $a
        [
         [
          [ 0  1  2  3  4]
          [ 5  6  7  8  9]
          [10 11 12 13 14]
         ]
         [
          [15 16 17 18 19]
          [20 21 22 23 24]
          [25 26 27 28 29]
         ]
        ]
        perldl> p $a->reorder(2,1,0); # Reverse the order of the 3-D PDL
        [
         [
          [ 0 15]
          [ 5 20]
          [10 25]
         ]
         [
          [ 1 16]
          [ 6 21]
          [11 26]
         ]
         [
          [ 2 17]
          [ 7 22]
          [12 27]
         ]
         [
          [ 3 18]
          [ 8 23]
          [13 28]
         ]
         [
          [ 4 19]
          [ 9 24]
          [14 29]
         ]
        ]

       The above is a simple example that could be duplicated by
       calling "$a->xchg(0,2)", but it demonstrates the basic
       functionality of reorder.

       As this is an index function, any modifications to the
       result PDL will change the parent.

       mv

         Signature: (P(); C(); int n1; int n2)

       move a dimension to another position

       The command

        $b = $a->mv(4,1);

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

        $b->at(1,2,3,4,5,6) == $a->at(1,5,2,3,4,6);

       The other dimensions are moved accordingly.  Negative
       dimension indices count from the end.

       oneslice

         Signature: (P(); C(); int nth; int from; int step; int nsteps)

       experimental function - not for public use

        $a = oneslice();

       This is not for public use currently. See the source if
       you have to.  This function can be used to accomplish run-
       time changing of transformations i.e. changing the size of
       some piddle at run-time.

       However, the mechanism is not yet finalized and this is
       just a demonstration.

       slice

         Signature: (P(); C(); char* str)

       Returns a rectangular slice of the original piddle

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

       The argument string is a comma-separated list of what to
       do for each dimension. The current formats include the
       following, where a, b and c are integers and can take
       legal array index values (including -1 etc):

       :       takes the whole dimension intact.

       ''      (nothing) is a synonym for ":" (This means that
               "$a->slice(':,3')" is equal to "$a->slice(',3')").

       a       slices only this value out of the corresponding
               dimension.

       (a)     means the same as "a" by itself except that the
               resulting dimension of length one is deleted (so
               if $a has dims "(3,4,5)" then
               "$a->slice(':,(2),:')" has dimensions "(3,5)"
               whereas "$a->slice(':,2,:')" has dimensions
               "(3,1,5))".

       a:b     slices the range a to b inclusive out of the
               dimension.

       a:b:c   slices the range a to b, with step c (i.e. "3:7:2"
               gives the indices "(3,5,7)"). This may be confus-
               ing to Matlab users but several other packages
               already use this syntax.

       '*'     inserts an extra dimension of width 1 and

       '*a'    inserts an extra (dummy) dimension of width a.

       An extension is planned for a later stage allowing
       "$a->slice('(=1),(=1|5:8),3:6(=1),4:6')" to express a mul-
       tidimensional diagonal of $a.




       using

       Returns array of column numbers requested

        line $pdl->using(1,2);

       Plot, as a line, column 1 of $pdl vs. column 2

        perldl> $pdl = rcols("file");
        perldl> line $pdl->using(1,2);


       diagonalI

         Signature: (P(); C(); SV *list)

       Returns the multidimensional diagonal over the specified
       dimensions.

       The diagonal is placed at the first (by number) dimension
       that is diagonalized.  The other diagonalized dimensions
       are removed. So if $a has dimensions "(5,3,5,4,6,5)" then
       after

        $b = $a->diagonal(0,2,5);

       the piddle $b has dimensions "(5,3,4,6)" and
       "$b->at(2,1,0,1)" refers to "$a->at(2,1,2,0,1,2)".

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

       lags

         Signature: (P(); C(); int nthdim; int step; int n)

       Returns a piddle of lags to parent.

       Usage:

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

       I.e. if $a contains

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

       then

        $b = $a->lags(0,2,2);

       is a (5,2) matrix

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

       This order of returned indices is kept because the func-
       tion is called "lags" i.e. the nth lag is n steps behind
       the original.

       $step and $nlags must be positive. $nthdim can be negative
       and will then be counted from the last dim backwards in
       the usual way (-1 = last dim).





       splitdim

         Signature: (P(); C(); int nthdim; int nsp)

       Splits a dimension in the parent piddle (opposite of
       clump)

       After

        $b = $a->splitdim(2,3);

       the expression

        $b->at(6,4,x,y,3,6) == $a->at(6,4,x+3*y)

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

       rotate

         Signature: (x(x); int shift(); [oca]y(y))

       Shift vector elements along with wrap. Flows data
       back&forth.

       threadI

         Signature: (P(); C(); int id; SV *list)

       internal

       Put some dimensions to a threadid.

        $b = $a->threadI(0,1,5); # thread over dims 1,5 in id 1


       identvaff

         Signature: (P(); C())

       A vaffine identity transformation (includes thread_id
       copying).

       Mainly for internal use.

       unthread

         Signature: (P(); C(); int atind)

       All threaded dimensions are made real again.

       See [TBD Doc] for details and examples.

       dice

       Dice rows/columns/planes out of a PDL using indexes for
       each dimension.

       This function can be used to extract irregular subsets
       along many dimension of a PDL, e.g. only certain rows in
       an image, or planes in a cube. This can of course be done
       with the usual dimension tricks but this saves having to
       figure it out each time!

       This method is similar in functionality to the slice
       method, but slice requires that contiguous ranges or
       ranges with constant offset be extracted. ( i.e. slice
       requires ranges of the form "1,2,3,4,5" or "2,4,6,8,10").
       Because of this restriction, slice is more memory effi-
       cient and slightly faster than dice

        $slice = $data->dice([0,2,6],[2,1,6]); # Dicing a 2-D array

       The arguments to dice are arrays (or 1D PDLs) for each
       dimension in the PDL. These arrays are used as indexes to
       which rows/columns/cubes,etc to dice-out (or extract) from
       the $data PDL.

       Use "X" to select all indices along a given dimension
       (compare also mslice). As usual (in slicing methods)
       trailing dimensions can be omitted implying "X"'es for
       those.

        perldl> $a = sequence(10,4)
        perldl> p $a
        [
         [ 0  1  2  3  4  5  6  7  8  9]
         [10 11 12 13 14 15 16 17 18 19]
         [20 21 22 23 24 25 26 27 28 29]
         [30 31 32 33 34 35 36 37 38 39]
        ]
        perldl> p $a->dice([1,2],[0,3]) # Select columns 1,2 and rows 0,3
        [
         [ 1  2]
         [31 32]
        ]
        perldl> p $a->dice(X,[0,3])
        [
         [ 0  1  2  3  4  5  6  7  8  9]
         [30 31 32 33 34 35 36 37 38 39]
        ]
        perldl> p $a->dice([0,2,5])
        [
         [ 0  2  5]
         [10 12 15]
         [20 22 25]
         [30 32 35]
        ]

       As this is an index function, any modifications to the
       slice change the parent (use the ".=" operator).

       dice_axis

       Dice rows/columns/planes from a single PDL axis (dimen-
       sion) using index along a specified axis

       This function can be used to extract irregular subsets
       along any dimension, e.g. only certain rows in an image,
       or planes in a cube. This can of course be done with the
       usual dimension tricks but this saves having to figure it
       out each time!

        $slice = $data->dice_axis($axis,$index);








        perldl> $a = sequence(10,4)
        perldl> $idx = pdl(1,2)
        perldl> p $a->dice_axis(0,$idx) # Select columns
        [
         [ 1  2]
         [11 12]
         [21 22]
         [31 32]
        ]
        perldl> $t = $a->dice_axis(1,$idx) # Select rows
        perldl> $t.=0
        perldl> p $a
        [
         [ 0  1  2  3  4  5  6  7  8  9]
         [ 0  0  0  0  0  0  0  0  0  0]
         [ 0  0  0  0  0  0  0  0  0  0]
         [30 31 32 33 34 35 36 37 38 39]
        ]

       The trick to using this is that the index selects elements
       along the dimensions specified, so if you have a 2D image
       "axis=0" will select certain "X" values - i.e. extract
       columns

       As this is an index function, any modifications to the
       slice change the parent.

AUTHOR
       Copyright (C) 1997 Tuomas J. Lukka.  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                  Slices(s)