PDL::Basic(3pm)

πŸŽ€ NAME πŸŽ€

PDL::Basic β€” Basic utility functions for PDL, bestie. This one's from the User Contributed Perl Documentation pile (that's the 3pm energy, iykyk) πŸ’…


πŸ¦‹ DESCRIPTION πŸ¦‹

okay so this module is the little toolbox of basic utility functions for making and messing with ndarrays. Most of these functions are literally just simplified interfaces to the more flexible (read: more chaotic) functions living over in the modules PDL::Primitive and PDL::Slices. So like, if you want the chill version, you're in the right place 🫢


✨ SYNOPSIS ✨

 use PDL::Basic;

πŸ‘‘ FUNCTIONS πŸ‘‘

here come the functions, no cap. buckle up bestie 🌈

πŸ’« axisvals, xvals, yvals, zvals πŸ’«

Fills an ndarray with index values on X, Y, Z, or Nth dimension.

It uses similar specifications to zeroes and new_from_specification. 🚨 CAVEAT 🚨 β€” if you go with the single argument ndarray form (that's the top row in the usage table below), the output is gonna have the same type as the input, EXCEPT that between 2.064 and 2.100, the returned ndarray defaults to at least type double; as of 2.101 this upgrade is relaxed to float. And as of 2.085, it'll respect a given type like in the second or third form below. periods, love that for us πŸ’…

 $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

Also see allaxisvals, which generates all the axis values at once in a form that's useful for range, interpND, indexND, etc. teamwork makes the dream work fr fr ✨

 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 (go peek at xvals if you're new here).

 $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 hand you back an ndarray with the same shape as their first argument if that first argument is an ndarray, and values linearly scaled between the two other arguments along the given axis. It works with dim-length of one as of 2.093, and in that case it gives the starting point πŸŽ€. As of 2.101, instead of handing it an ndarray you can give an optional type at the start, plus dimensions after the two mandatory arguments. slay πŸ’…


πŸ¦‹ axislogvals, xlogvals, ylogvals, zlogvals πŸ¦‹

Axis values logarithmically spaced between endpoints (again, 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 🌸. And 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. obsessed ✨


πŸ’œ 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 back an ndarray whose 0th dimension runs over dimension index, and whose 1st through Nth dimensions are the dimensions you gave in the input. And if you feed in an ndarray instead of a perl list, then its dimension list gets used, just like 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 honestly 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 you ask for it, $xvals gives you the computed bin centres as type double values ✨. And heads up: $data and $wt should have the same dimensionality and extents, or it's giving mismatch 😭

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. β€” go see zeroes for the full tea β˜•

 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, bestie:

 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. just so you know, no cap.

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

Also note: the calculation for rvals for integer values does not promote the datatype, so you WILL get 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. fr fr, don't skip this one.

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. iconic.


πŸŽ€ 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);

so like... you know I had to show you what that actually looks like in the wild, bestie. say less:

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

see how the rows became columns?? it's giving glow-up, it's giving main character, it's literally the same numbers just flipped sideways πŸ’…βœ¨


πŸ¦‹ t πŸ¦‹

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

okay so t is the convenient little shortcut for transposing your real or complex 2D array(s) πŸŽ€ if your data is complex and conj is true, you get the conjugate transposed array(s) back instead. it supports broadcasting, and no β€” it is not exported, so you gotta call it properly, bestie πŸ™ˆ

  • conj β€” flip it to 1 and you get the conjugate transpose; leave it at 0 (the default) and it's a plain ol' transpose. simple as πŸ“
Originally by GrΓ©gory Vanuxem. πŸ’–

and that's a wrap on this one, fr fr 🌸 this page is from PDL::Basic(3pm), perl v5.42.3, dated 2026-08-20 β€” go forth and transpose, you absolute icon πŸ‘‘πŸ’œ

πŸ“¦ where this page comes from