Skip to content

Creating tensors

Tensors can be created using other tensors by applying the various operations on previous tensors using binary or unary operators. If there is no previous tensor that can be used to create a new tensor, a tensor can also be created from scratch using either an array of elements or booleans, or by calling certain functions that create tensor with certain values or properties:

  • A tensor can be created and filled with a specific value, all zeros, or all ones.

  • A tensor can be created with elements in a certain range or in a linear, logarithmic, or geometric space.

  • An identity matrix or 2-D tensor with specific elements on the main diagonal can be created.

From arrays

A 1-D tensor can be created from an array of elements using the function To_Tensor:

Tensor : constant CPU_Tensor := To_Tensor ([1.0, 2.0, 3.0, 4.0]);

A boolean tensor can be created from an array of booleans using the function To_Boolean_Tensor:

Values : constant Boolean_Array := [False, True, False, True];
Tensor : constant CPU_Tensor := To_Boolean_Tensor (Values);

If a 2-D tensor is desired, provide the desired shape as the second parameter:

Matrix : constant CPU_Tensor := To_Tensor ([1.0, 2.0, 3.0, 4.0], [2, 2]);

Info

The function Reshape can be used to create a 2-D tensor from a 1-D tensor. This may require copying the data, which the use of a shape as the second parameter will avoid.

Filled with some value

A tensor consisting solely of zeros (0.0) or ones (1.0) can be created with the functions Zeros and Ones. Each function has one parameter, indicating the number of elements for a 1-D tensor, or the shape of the returned tensor.

For example, a 1-D tensor consisting of a 1000 ones can be created by writing:

Tensor : constant CPU_Tensor := Ones (1_000);

While a zero matrix with the shape 4 × 8 is created with:

Tensor : constant CPU_Tensor := Zeros ([4, 8]);

To create a tensor of a particular shape filled with a specific value, use the function Fill. For example, a tensor of some shape where each element has the value e is created with:

E_Lambda : CPU_Tensor := Fill (Shape, Ada.Numerics.e ** (-Lambda));

Uninitialized

Sometimes it is useful to create a tensor with some specified shape, but without initializing the elements to some given value. This avoids useless memory copies when the elements are later set with the procedure Set by some algorithm. The function Empty can create such an uninitialized array:

Sigmas : Matrix := Empty ([2 * N + 1, N]);

Range or space

The functions Array_Range, Linear_Space, Log_Space, and Geometric_Space return a tensor containing numbers in the request space.

Range

Function Array_Range will return a tensor with numbers in the interval from 0.0 (including) to (excluding) the given stop value, using a step size of 1.0 between two adjacent elements. For example, Array_Range (3.0) returns a tensor with the values 0.0, 1.0, and 2.0. Optionally, the start of the interval can be given by calling the function with two or three parameters:

Tensor_1 : constant CPU_Tensor := Array_Range (2.0, 5.0);
Tensor_2 : constant CPU_Tensor := Array_Range (2.0, 5.0, Step => 1.0);

Tensor_1 and Tensor_2 both contain numbers in the interval [0.0, 5.0): the numbers 2.0, 3.0, and 4.0. The start of the interval must be less than the stop. The third parameter Step is optional and has the default value 1.0. Its value must be greater than 0.0 if given.

Linear space

Instead of specifying an interval and a step size, the number of elements in the returned tensor can be given for the function Linear_Space:

Tensor_1 : constant CPU_Tensor := Linear_Space (1.0, 5.0, Count => 5);

This will create a tensor Tensor_1 with the elements 1.0, 2.0, 3.0, 4.0, and 5.0. Function Linear_Space has a fourth parameter Interval with the default value Closed, which causes the function to return a tensor containing numbers in a linear scale in the interval [start, stop]. If the value Half_Open is used instead, the interval will be [start, stop):

Tensor_2 : constant CPU_Tensor :=
  Linear_Space (1.0, 5.0, Count => 5, Interval => Half_Open);

Due to the value Half_Open, tensor Tensor_2 will contain the numbers 1.0, 1.8, 2.6, 3.4, and 4.2 instead.

Unlike Array_Range, the start of the interval may be greater or equal to the stop of the interval. If parameter Start is greater than Stop, the numbers in the tensor will be decreasing. If Start is equal to Stop, the interval is degenerate and all numbers are equal to Start and Stop.

Logarithmic space

The function Log_Space can be used to create a tensor with numbers in a logarithmic scale in the interval [basestart, basestop] when interval is closed and [basestart, basestop) when half open. The base can be specified with the optional fourth parameter Base. Its default value is 10.0.

For example, a tensor with the numbers 100.0, 1000.0, and 10000.0 can be created using the default base 10.0:

Tensor : constant CPU_Tensor := Log_Space (2.0, 4.0, Count => 3);

And a tensor with the numbers 2.0, 4.0, and 8.0 can be created by specifying a base 2.0:

Tensor : constant CPU_Tensor := Log_Space (1.0, 3.0, Count => 3, Base => 2.0);

Geometric space

The function Geometric_Space is similar to Log_Space with the difference that the actual start and stop of the interval instead of the exponents are specified.

For example, a tensor with three numbers in the half open interval [0.0, 1000.0) can be created with:

Tensor : constant CPU_Tensor :=
  Geometric_Space (1.0, 1_000.0, Count => 3, Interval => Half_Open);

The tensor will contain the numbers 1.0, 10.0, and 100.0.

Identity matrix or diagonal

To create a square identity matrix, call function Identity with the size of the matrix (rows and column) as the first parameter. A second optional parameter controls on which diagonal the ones are placed. The default value of this parameter is 0, which places the ones on the main diagonal. For example, a 3 × 3 matrix with the ones on the diagonal one position above the main diagonal can be created as follows:

Tensor : constant CPU_Tensor := Identity (3, Offset => 1);

Printing the image of this tensor will display:

tensor([[ 0.0, 1.0, 0.0],
        [ 0.0, 0.0, 1.0],
        [ 0.0, 0.0, 0.0]])

To create a non-square matrix, provide two separate parameters representing the number of rows and columns to function Identity.

If one wishes to create an identity matrix with certain elements instead of ones on the diagonal, use function Diagonal instead. The returned 2-D tensor will always be a square matrix with the number of rows and columns equal to the number of elements in the given array.

Tensor_1 : constant CPU_Tensor := Diagonal ([1.0, 2.0, 3.0]);

Alternatively, the elements from a 1-D tensor instead of an array can be used:

Main_Diagonal : constant CPU_Tensor := To_Tensor ([1.0, 2.0, 3.0]);
Tensor_2      : constant CPU_Tensor := Diagonal (Main_Diagonal);

In the examples above, Tensor_1 is equal to Tensor_2.

Just like Identity, the function Diagonal accepts a second parameter that specifies on which diagonal the elements must be placed.

Triangular parts

The upper triangular part of a matrix A with zeros in the lower triangular part can be created with the function Upper_Triangular.