PDL::Basic(3pm)

NAME
PDL::Basic -- Basic utility functions for PDL

DESCRIPTION
This module contains basic utility functions for creating and manipulating ndarrays. Most of these functions are simplified interfaces to the more flexible functions in the modules PDL::Primitive and PDL::Slices.

SYNOPSIS
 use PDL::Basic;

FUNCTIONS

  axisvals, xvals, yvals, zvals
Fills an ndarray with index values on X, Y, Z, or Nth dimension

Uses similar specifications to zeroes and new_from_specification. CAVEAT: If you use the single argument ndarray form (top row in the usage table) the output will have the same type as the input, except that between 2.064 and 2.100, the returned ndarray will default to at least type "double"; as of 2.101 this upgrade is relaxed to "float". As of 2.085, this will respect a given type as in the second or third form below.

 $x = xvals($somearray); # at least type float
 $x = xvals([OPTIONAL TYPE],$nx,$ny,$nz...);
 $x = xvals([OPTIONAL TYPE], $somarray->dims);
 $y = yvals($somearray); yvals(inplace($somearray));
 $y = yvals([OPTIONAL TYPE],$nx,$ny,$nz...);
 $z = zvals($somearray); zvals(inplace($somearray));
 $z = zvals([OPTIONAL TYPE],$nx,$ny,$nz...);
 $axisv = axisvals ($ndarray, $nth);
 $axisv = $ndarray->axisvals($nth);
 $axisv = axisvals ([type,] $nth, $dim0, $dim1, ...); # new in PDL 2.101
 $axisv = axisvals ($nth, [type,] $dim0, $dim1, ...); # new in PDL 2.101

See also "allaxisvals", which generates all axis values simultaneously in a form useful for "range", "interpND", "indexND", etc.

  pdl> print xvals zeroes(5,2)
  [
   [0 1 2 3 4]
   [0 1 2 3 4]
  ]
  pdl> print yvals zeroes(5,2)
  [
   [0 0 0 0 0]
   [1 1 1 1 1]
  ]
  pdl> print zvals zeroes(3,2,2)
  [
   [
    [0 0 0]
    [0 0 0]
   ]
   [
    [1 1 1]
    [1 1 1]
   ]
  ]

  axislinvals, xlinvals, ylinvals, zlinvals
Axis values linearly spaced between endpoints (see "xvals").

 $w = zeroes(100,100);
 $x = $w->xlinvals(0.5,1.5);  # can give ndarrays as start and endpoints
 $y = $w->ylinvals(-2,-1);
 $z = f($x,$y); # calculate Z for X from 0.5 to 1.5, Y from -2 to -1
 # alternatively (new in PDL 2.101):
 $x = xlinvals(0.5,1.5,100);  # can give ndarrays as start and endpoints
 $y = xlinvals(-2,-1,100); # x = along 0-th dim
 $z = f(meshgrid($x,$y));  # should go faster as meshgrid makes better locality
 $pdl = xlinvals(float,0.5,1.5,100);        # can specify type
 $x = $w->axislinvals(0,0.5,1.5);           # same as xlinvals
 $x = axislinvals(0,0.5,1.5,100,100);       # same as xlinvals
 $x = axislinvals(float,0,0.5,1.5,100,100); # same as xlinvals
 $x = axislinvals(0,float,0.5,1.5,100,100); # same as xlinvals

"xlinvals", "ylinvals" and "zlinvals" return an ndarray with the same shape as their first argument if an ndarray, and linearly scaled values between the two other arguments along the given axis. Works with dim-length of one as of 2.093, giving the starting point. As of 2.101, instead of giving an ndarray you can give an optional type at the start, and dimensions after the two mandatory arguments.

  axislogvals, xlogvals, ylogvals, zlogvals
Axis values logarithmically spaced between endpoints (see "xvals").

 $w = zeroes(100,100);
 $x = $w->xlogvals(1e-6,1e-3);
 $y = $w->ylogvals(1e-4,1e3);
 $z = f($x,$y); # calculate Z for X from 1e-6 to 1e-3, Y from 1e-4 to 1e3
 # alternatively (new in PDL 2.101):
 $x = xlogvals(1e-6,1e-3,100);
 $y = xlogvals(1e-4,1e3,100); # x = along 0-th dim
 $z = f(meshgrid($x,$y));  # should go faster as meshgrid makes better locality
 $pdl = xlogvals(float,1e-6,1e-3,100); # can specify type
 $x = $w->axislogvals(0,0.5,1.5);           # same as xlogvals
 $x = axislogvals(0,0.5,1.5,100,100);       # same as xlogvals
 $x = axislogvals(float,0,0.5,1.5,100,100); # same as xlogvals
 $x = axislogvals(0,float,0.5,1.5,100,100); # same as xlogvals

"xlogvals", "ylogvals" and "zlogvals" return an ndarray with the same shape as their first argument and logarithmically scaled values between the two other arguments along the given axis. Works with dim-length of one as of 2.093, giving the starting point. As of 2.101, instead of giving an ndarray you can give an optional type at the start, and dimensions after the two mandatory arguments.

  ndcoords, allaxisvals, allaxislinvals, allaxislogvals
Enumerate pixel coordinates for an N-D ndarray

"ndcoords" and "allaxisvals" return an enumerated list of coordinates suitable for use in indexND, range, or interpND: you feed in a dimension list and get out an ndarray whose 0th dimension runs over dimension index and whose 1st through Nth dimensions are the dimensions given in the input. If you feed in an ndarray instead of a perl list, then its dimension list is used, as in "xvals" etc.

Unlike "xvals" etc., if you supply an ndarray input, you get out an ndarray of the default ndarray type: double. This causes less surprises than the previous default of keeping the data type of the input ndarray since that rarely made sense in most usages.

"allaxislinvals" and "allaxislogvals" enumerate a list of linear- or logarithm-spaced values respectively, like their non-"all" counterparts. The start- and endpoints can be 1-dimensional ndarrays, with one value each per desired dimension.

  $indices = ndcoords($pdl);                   # double
  $indices = ndcoords(@dimlist);               # double
  $indices = ndcoords($type,$pdl);             # $type
  $indices = $pdl->ndcoords($type);            # $type
  $indices = ndcoords($type,@dimlist);         # $type
  $indices = allaxisvals($pdl);
  $indices = allaxisvals(@dimlist);
  $indices = allaxisvals($type,$pdl);
  $indices = allaxisvals($type,@dimlist);
  $linvals = allaxislinvals($pdl,$start,$end); # start and end can be ndarrays
  $linvals = allaxislinvals($type,$pdl,$start,$end);     # also here
  $linvals = allaxislinvals($type,$start,$end,@dimlist); # also here
  $linvals = allaxislinvals($start,$end,@dimlist);       # not here
  $linvals = allaxislogvals($pdl,$start,$end);
  $linvals = allaxislogvals($type,$pdl,$start,$end);
  $linvals = allaxislogvals($start,$end,@dimlist);
  $linvals = allaxislogvals($type,$start,$end,@dimlist);

  pdl> print ndcoords(2,3)
  [
   [
    [0 0]
    [1 0]
   ]
   [
    [0 1]
    [1 1]
   ]
   [
    [0 2]
    [1 2]
   ]
  ]
  pdl> $w = zeroes(byte,2,3);        # $w is a 2x3 byte ndarray
  pdl> $y = ndcoords($w);            # $y is double to avoid problems
  pdl> $c = ndcoords(long,$w->dims); # $c is a long ndarray, same dims as $y
  pdl> $d = ndcoords(long,$w);       # $d overrides the default double
  pdl> help $y;
  This variable is Double D [2,2,3]        P            0.09KB
  pdl> help $c;
  This variable is   Long D [2,2,3]        P            0.05KB

  hist, whist
Create histogram, or weighted histogram, of an ndarray

 $hist = hist($data);
 ($xvals,$hist) = hist($data);
 # or:
 $hist = hist($data,$min,$max,$step);
 ($xvals,$hist) = hist($data,[$min,$max,$step]);
 # weighted:
 $whist = whist($data, $wt, [$min,$max,$step]);
 ($xvals,$whist) = whist($data, $wt, [$min,$max,$step]);

If requested, $xvals gives the computed bin centres as type double values. $data and $wt should have the same dimensionality and extents.

A nice idiom (with PDL::Graphics::Simple) is

 bins hist($data), {yrange=>[0,$data->dim(0)]};        # Plot histogram
 bin whist $data, $wt;                                 # weighted histogram
 bins whist($data, $wt), {yrange=>[0,$data->dim(0)]};  # weighted histogram

 pdl> p $y
 [13 10 13 10 9 13 9 12 11 10 10 13 7 6 8 10 11 7 12 9 11 11 12 6 12 7]
 pdl> $h = hist $y,0,20,1; # hist with step 1, min 0 and 20 bins
 pdl> p $h
 [0 0 0 0 0 0 2 3 1 3 5 4 4 4 0 0 0 0 0 0]
 # or, weighted:
 pdl> $wt = grandom($y->nelem)
 pdl> $h = whist $y, $wt, 0, 20, 1 # hist with step 1, min 0 and 20 bins
 pdl> p $h
 [0 0 0 0 0 0 -0.49552342  1.7987439 0.39450696  4.0073722 -2.6255299 -2.5084501  2.6458365  4.1671676 0 0 0 0 0 0]

  sequence
Create array filled with a sequence of values

 $w = sequence($y); $w = sequence [OPTIONAL TYPE], @dims;

etc. see zeroes.

 pdl> p sequence(10)
 [0 1 2 3 4 5 6 7 8 9]
 pdl> p sequence(3,4)
 [
  [ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]
  [ 9 10 11]
 ]

  rvals
Fills an ndarray with radial distance values from some centre.

 $r = rvals $ndarray,{OPTIONS};
 $r = rvals [OPTIONAL TYPE],$nx,$ny,...{OPTIONS};

 Options:

 Centre => [$x,$y,$z...] # Specify centre
 Center => [$x,$y.$z...] # synonym.
 Center => $c            # as 1d array
 Squared => 1 # return distance squared (i.e., don't take the square root)

 pdl> print rvals long,7,7,{Centre=>[2,2]}
 [
  [2 2 2 2 2 3 4]
  [2 1 1 1 2 3 4]
  [2 1 0 1 2 3 4]
  [2 1 1 1 2 3 4]
  [2 2 2 2 2 3 4]
  [3 3 3 3 3 4 5]
  [4 4 4 4 4 5 5]
 ]

If "Center" is not specified, the midpoint for a given dimension of size "N" is given by int(N/2) so that the midpoint always falls on an exact pixel point in the data. For dimensions of even size, that means the midpoint is shifted by 1/2 pixel from the true center of that dimension.

If "Center" has less components than the number of dimensions of the array, its remaining components are computed as above. If it has more, a warning is issued.

Also note that the calculation for "rvals" for integer values does not promote the datatype so you will have wraparound when the value calculated for " r**2 " is greater than the datatype can hold. If you need exact values, be sure to use large integer or floating point datatypes.

For a more general metric, one can define, e.g.,

 sub distance {
   my ($w,$centre,$f) = @_;
   my ($r) = $w->allaxisvals-$centre;
   $f->($r);
 }
 sub l1 { sumover(abs($_[0])); }
 sub euclid { use PDL::Math 'pow'; pow(sumover(pow($_[0],2)),0.5); }
 sub linfty { maximum(abs($_[0])); }

so now

 distance($w, $centre, \&euclid);

will emulate rvals, while "\&l1" and "\&linfty" will generate other well-known norms.

  sec
Take a subsection of an ndarray with given coordinates.

  $new  = sec($input,  $x1, $x2, $y1, $y2, $z1, $z2, ... ) # Take subsection

  ins
Insert one ndarray into another at given coordinates.

  $newimage = ins($bigimage,$smallimage,$x,$y,$z...) # Insert at x,y,z

  transpose
transpose rows and columns.

 $y = transpose($w);

 pdl> $w = sequence(3,2)
 pdl> p $w
 [
  [0 1 2]
  [3 4 5]
 ]
 pdl> p transpose( $w )
 [
  [0 3]
  [1 4]
  [2 5]
 ]

  t
 $pdl = $pdl->t(SCALAR(conj))
 conj : Conjugate Transpose = 1 | Transpose = 0, default = 0;

Convenient function for transposing real or complex 2D array(s). For complex data, if conj is true returns conjugate transposed array(s). Supports broadcasting. Not exported.

Originally by Grégory Vanuxem.