1. Perl
  2. Module
  3. PDL

Representation of multidimensional data in PDL

So far, we have only dealt with one-dimensional data, but I would like to explain how to represent multidimensional data in PDL.

Representation of multidimensional data

To represent multidimensional data, use the pdl function as follows:

use PDL;

my $data = pdl [
  [one two Three],
  [4, 5, 6],
  [7, 8, 9],
  [10, 11, 12]
];;

First, let's learn the concepts called dimension and rank . It is easier to understand if you understand it visually, so I will show it.

1D
              Rank 1 Rank 2 Rank 3
2D rank 1 [1, 2, 3],
      Rank 2 [4, 5, 6],
      Rank 3 [7, 8, 9],
      Rank 4 [10, 11, 12]

Think of it as the one-dimensional data you've come up with.

1D
Rank 1 Rank 2 Rank 3
[one two Three],

Get and set elements

Learn how to get and set elements of multidimensional data. Use nice slice notation to get and set elements. Specify in the order of 1D rank and 2D rank, and the subscripts start from 0.

use PDL;
use PDL::NiceSlice;

# data
my $data = pdl [
  [one two Three],
  [4, 5, 6],
  [7, 8, 9],
  [10, 11, 12]
];;

# Get element as PDL variable (1D 2 rank-2D 3 rank)
my $data_1_2 = $data (1, 2);

# Get the element value itself
my $data_1_2_raw = $data->at(1, 2);

# Set element.
$data (1, 2). = 20;

Get multiple elements, set multiple elements

You can also get and set multiple elements for a PDL variable. In the following example, the 2nd to 3rd ranks of the 1st dimension and the 3rd rank of the 2nd dimension are got.

# Acquisition of multiple elements (1D 2-3 ranks, 2D 3 ranks)
my $data_sliced1 = $data (1: 2, 2);

To set multiple elements:

# Setting of multiple elements (1D 2-3 ranks, 2D 3 ranks)
$data (1: 2, 2). = pdl [21, 22];

Of course, it is possible to acquire not only the first dimension but also multiple elements in the second dimension.

# Get multiple elements (1D 3 ranks, 2D 1-2 ranks)
my $data_sliced2 = $data (2, 0: 1);

To set multiple elements in the second dimension:

# Setting of multiple elements (1D 3 ranks, 2D 1-2 ranks)
$data (2, 0: 1). = pdl [
  [30],
  [31]
];;

You can also acquire and set multiple ranks in multiple dimensions in the same way.

# Get multiple elements (1D 2-3 ranks, 2D 1-2 ranks)
my $data_sliced3 = $data (1: 2, 0: 1);

# Setting of multiple elements (1D 2-3 ranks, 2D 1-2 ranks)
$data (1: 2, 0: 1). = pdl [
  [40, 41],
  [42, 43]
];;

Example

This is an example that can be executed.

use strict;
use warnings;

use PDL;
use PDL::NiceSlice;

# data
my $data = pdl [
  [one two Three],
  [4, 5, 6],
  [7, 8, 9],
  [10, 11, 12]
];;

# Get element as PDL variable (1D 2 rank, 2D 3 rank)
my $data_1_2 = $data (1, 2);

# Get the element value itself
my $data_1_2_raw = $data->at(1, 2);

print "$data_1_2\n";
print "$data_1_2_raw\n";

# Set element.
$data (1, 2). = 20;

print "$data\n";

# Get multiple elements (1D 2 to 3 ranks, 2D 2 ranks)
my $data_sliced1 = $data (1: 2, 1);

print "$data_sliced1\n";

# Setting of multiple elements (1D 2-3 ranks, 2D 3 ranks)
$data (1: 2, 2). = pdl [21, 22];

print "$data\n";

# Get multiple elements (1D 3 ranks, 2D 1-2 ranks)
my $data_sliced2 = $data (2, 0: 1);

print "$data_sliced2\n";

# Setting of multiple elements (1D 3 rank, 2D 1-2 rank)
$data (2, 0: 1). = pdl [
  [30],
  [31]
];;

print "$data\n";

# Get multiple elements (1D 2-3 ranks, 2D 1-2 ranks)
my $data_sliced3 = $data (1: 2, 0: 1);

print "$data_sliced3\n";

# Setting of multiple elements (1D 2-3 ranks, 2D 1-2 ranks)
$data (1: 2, 0: 1). = pdl [
  [40, 41],
  [42, 43]
];;

print "$data";

Data initialization

PDL has various data initialization functions. I will show you how to initialize the data.

Initialize with 0

Use the zeros method to specify a multidimensional rank number and initialize it with 0. zeros is defined in PDL::Core.

use PDL;

# Initialize with 0 (1D has 2 ranks, 2D has 3 ranks)
my $data_zeros = pdl->sequence(2, 3);

Initialize with 1

Use the ones method to specify the number of ranks in multiple dimensions and initialize with 1. ones is defined in PDL::Core.

# Initialize with 1 (1D has 2 ranks, 2D has 3 ranks)
my $data_ones = pdl->ones(2, 3);
print "$data_ones\n";

Initialize with null

The PDL defines a value of null. Use the null method to initialize with null. null is defined in PDL::Core.

# Initialize with null
my $data_null = pdl->null;

Initialize from 1 to n

Use the sequence method to initialize with a value between 0 and n-1 . sequence is defined in PDL::Basic.

# Initialize with 0-19
my $data_seq = pdl->sequence(20);

You can also specify multiple dimensions.

# Initialize with 0-14 (1D 3 ranks, 2D 5 ranks)
my $data_seq2 = pdl->sequence(3, 5);

Example

This is an example that can be executed.

use PDL;

# Initialize with 0 (1D has 2 ranks, 2D has 3 ranks)
my $data_zeros = pdl->zeros(2, 3);
print "$data_zeros\n";

# Initialize with 1 (1D has 2 ranks, 2D has 3 ranks)
my $data_ones = pdl->ones(2, 3);
print "$data_ones\n";

# Initialize with null
my $data_null = pdl->null;
print "$data_null\n";

# Initialize with 0-19
my $data_seq = pdl->sequence(20);
print "$data_seq\n";

# Initialize with 0-14 (1D 3 ranks, 2D 5 ranks)
my $data_seq2 = pdl->sequence(3, 5);
print "$data_seq2\n";

Calculate multiple elements at once

PDL allows you to calculate multiple elements at once. See the data below.

use PDL;

my $data = pdl [
  [one two Three],
  [4, 5, 6],
  [7, 8, 9],
  [10, 11, 12]
];;

Sum calculation to reduce one - dimensional rank

First, let's perform a sum operation that reduces the one-dimensional rank. The above data is an image that looks like the following.

[6]
[15]
[twenty four]
[33]

Use the sumover method to find the sum. someover is implemented in PDL::UfuncI am.

# Sum calculation to reduce one-dimensional rank
my $data_sumover1 = $data->sumover;

Use the sumover method when the contained value is an integer type. For floating point, use dsomeover instead.

If you perform an operation to reduce the rank, the dimension will be reduced by one and the data will be as follows.

[6, 15, 24, 33]

Sum calculation to reduce 2D rank

In the above example, the sum operation is performed to reduce the one-dimensional rank. Next, let's perform a sum operation that reduces the two-dimensional rank. To do this, use the xchg method to exchange 1D and 2D positions, and then use the someover function.

# Sum calculation to reduce 2D rank
my $data_sumover2 = $data->xchg(0, 1)->sumover;

You can get the following data.

[22 26 30]

In addition to xchg, there are mv and reorder methods for moving the position of the dimension, so let's check them.

Methods that perform other operations that reduce dimensions

In addition to sumover, PDL::Ufunc defines methods that perform the same type of operations.

Arithmetic Method
average average, daverage
Median medover, medoddover
Mode modeover
product prodover, dprodover
Cumulative product cumuprodover, dcumuprodover
Cumulative total cumusumover, dcumusumover
and operation andover
or operation orover
Bitwise and arithmetic bandover
Bitwise or operation borover

Example

This is an example that can be executed.

use strict;
use warnings;
use PDL;

my $data = pdl [
  [one two Three],
  [4, 5, 6],
  [7, 8, 9],
  [10, 11, 12]
];;

# Sum calculation to reduce one-dimensional rank
my $data_sumover1 = $data->sumover;
print "$data_sumover\n";

# Sum calculation to reduce 2D rank
my $data_sumover2 = $data->xchg(0, 1)->sumover;
print "$data_sumover2\n";

Related Informatrion