argamak/tensor

Types

A type for Native tensor representations.

pub external type Native

A Tensor is a generic container for n-dimensional data structures.

pub opaque type Tensor(a, dn, axis)

When a tensor operation cannot succeed.

pub type TensorError {
  EmptyTensor
  IncompatibleAxes
  IncompatibleShape
  InvalidData
  SpaceErrors(space.SpaceErrors)
}

Constructors

  • EmptyTensor
  • IncompatibleAxes
  • IncompatibleShape
  • InvalidData
  • SpaceErrors(space.SpaceErrors)

Functions

pub fn as_format(for tensor: Tensor(a, b, c), apply format: fn() ->
    Format(d)) -> Tensor(d, b, c)

Changes the Format of a Tensor.

Converting from float formats to integer formats truncates the data. For consistency, consider using round, floor, or ceil before casting from float formats to integer formats.

Lowering precision may lead to an overflow or underflow, the outcome of which depends on platform and compiler.

Examples

> import argamak/format
> as_format(for: from_int(0), apply: format.float32)
from_float(0.)

> import argamak/space
> type Axis { X }
> assert Ok(space) = space.d1(X)
> try tensor = from_floats(of: [1., 2., 3.], into: space)
> Ok(as_format(for: tensor, apply: format.int32))
from_ints(of: [1, 2, 3], into: space)
pub fn axes(tensor: Tensor(a, b, c)) -> List(c)

Returns the axes of a given Tensor.

Examples

> axes(from_int(3))
[]

> import argamak/space
> type Axis { X }
> assert Ok(space) = space.d1(X)
> try tensor = from_floats(of: [1., 2., 3.], into: space)
> Ok(axes(tensor))
Ok([X])

> type OtherAxis { Alpha Omega }
> assert Ok(space) = space.d2(#(Alpha, 1), #(Omega, 3))
> try tensor = from_ints(of: [1, 2, 3], into: space)
> Ok(axes(tensor))
Ok([Alpha, Omega])
pub fn format(tensor: Tensor(a, b, c)) -> Format(a)

Returns the Format of a given Tensor.

See argamak/format for more information.

Examples

import argamak/format
> format(from_float(0.))
format.float32()

> import argamak/space
> type Axis { X }
> assert Ok(space) = space.d1(X)
> try tensor = from_ints(of: [1, 2, 3], into: space)
> Ok(format(tensor))
Ok(format.int32())
pub fn from_float(float: Float) -> Tensor(Float, D0, Nil)

Converts a Float into a Tensor.

Examples

> let tensor = from_float(1.)
> print(from: tensor, wrap_at: -1, meta: False)
// 1.0
Nil
pub fn from_floats(of list: List(Float), into space: Space(a, b)) -> Result(
  Tensor(Float, a, b),
  TensorError,
)

Results in a Tensor created from a list of floats and placed into a given n-dimensional Space on success, or a TensorError on failure.

The Space’s Shape may have a single dimension given as -1, in which case that dimension’s size will be inferred from the given list. This is useful when working with lists of unknown length.

Examples

> import argamak/space
> type Axis { X Y Z }
> assert Ok(space) = space.d1(X)
> try tensor = from_floats(of: [1.], into: space)
> Ok(print(from: tensor, wrap_at: -1, meta: True))
// Tensor
// format: Float32
// space: D1 #(X, 1)
// data:
// [1.0]
Ok(Nil)

> assert Ok(space) = space.d2(#(X, 2), #(Y, 2))
> try tensor = from_floats(of: [1., 2., 3., 4.], into: space)
> Ok(print(from: tensor, wrap_at: -1, meta: True))
// Tensor
// format: Float32
// space: D2 #(X, 2), #(Y, 2)
// data:
// [[1.0, 2.0],
//  [3.0, 4.0]]
Ok(Nil)

> assert Ok(space) = space.d3(#(X, -1), #(Y, 2), #(Z, 2))
> let list = [1., 2., 3., 4., 5., 6., 7., 8.]
> try tensor = from_floats(of: list, into: space)
> Ok(print(from: tensor, wrap_at: -1, meta: True))
// Tensor
// format: Float32
// space: D3 #(X, 2), #(Y, 2), #(Z, 2)
// data:
// [[[1.0, 2.0],
//   [3.0, 4.0]],
//  [[5.0, 6.0],
//   [7.0, 8.0]]]
Ok(Nil)
pub fn from_int(int: Int) -> Tensor(Int, D0, Nil)

Converts an Int into a Tensor.

Examples

> let tensor = from_int(1)
> print(from: tensor, wrap_at: -1, meta: False)
// 1
Nil
pub fn from_ints(of list: List(Int), into space: Space(a, b)) -> Result(
  Tensor(Int, a, b),
  TensorError,
)

Results in a Tensor created from a list of integers and placed into a given n-dimensional Space on success, or a TensorError on failure.

The Space’s Shape may have a single dimension given as -1, in which case that dimension’s size will be inferred from the given list. This is useful when working with lists of unknown length.

Examples

> import argamak/space
> type Axis { X Y Z }
> assert Ok(space) = space.d1(X)
> try tensor = from_ints(of: [1], into: space)
> Ok(print(from: tensor, wrap_at: -1, meta: True))
// Tensor
// format: Int32
// space: D1 #(X, 1)
// data:
// [1]
Ok(Nil)

> assert Ok(space) = space.d2(#(X, 2), #(Y, 2))
> try tensor = from_ints(of: [1, 2, 3, 4], into: space)
> Ok(print(from: tensor, wrap_at: -1, meta: True))
// Tensor
// format: Int32
// space: D2 #(X, 2), #(Y, 2)
// data:
// [[1, 2],
//  [3, 4]]
Ok(Nil)

> assert Ok(space) = space.d3(#(X, -1), #(Y, 2), #(Z, 2))
> let list = [1, 2, 3, 4, 5, 6, 7, 8]
> try tensor = from_ints(of: list, into: space)
> Ok(print(from: tensor, wrap_at: -1, meta: True))
// Tensor
// format: Int32
// space: D3 #(X, 2), #(Y, 2), #(Z, 2)
// data:
// [[[1, 2],
//   [3, 4]],
//  [[5, 6],
//   [7, 8]]]
Ok(Nil)
pub fn from_native(of native: Native, into space: Space(a, b), with format: fn() ->
    Format(c)) -> Result(Tensor(c, a, b), TensorError)

Results in a Tensor created from a Native representation on success, or a TensorError on failure.

Examples

> import argamak/format
> import argamak/space
> import gleam/dynamic.{Dynamic}
> external fn erlang_tensor(Dynamic) -> Native =
>   "Elixir.Nx" "tensor"
> let native = erlang_tensor(dynamic.from([[1, 2], [3, 4]]))
> assert Ok(space) = space.d2(#(X, 2), #(Y, -1))
> try tensor = from_native(of: native, into: space, with: format.int32)
> Ok(print(from: tensor, wrap_at: -1, meta: True))
// Tensor
// format: Int32
// space: D2 #(X, 2), #(Y, 2)
// data:
// [[1, 2],
//  [3, 4]]
Ok(Nil)
pub fn print(from tensor: Tensor(a, b, c), wrap_at max_width: Int, meta meta: Bool) -> Nil

Prints a Tensor’s underlying data to standard out.

Takes a max_width (in columns) argument for which the special values -1 and 0 represent default and no wrapping, respectively.

If the meta argument is True, various Tensor details will be printed with the data.

Examples

> import argamak/space
> type Axis { X Y Z }
> assert Ok(space) = space.d2(#(X, 2), #(Y, 2))
> try tensor = from_ints(of: [1, 2, 3, 4], into: space)
> Ok(print(from: tensor, wrap_at: -1, meta: False))
// [[1, 2],
//  [3, 4]]
Ok(Nil)

> assert Ok(space) = space.d3(#(X, 2), #(Y, 1), #(Z, 4))
> let list = [1, 2, 3, 4, 5, 6, 7, 8]
> try tensor = from_ints(of: list, into: space)
> Ok(print(from: tensor, wrap_at: 10, meta: True))
// Tensor
// format: Int64
// space: D3 #(X, 2), #(Y, 1), #(Z, 4)
// data:
// [[[1, 2,
//    3, 4]],
//  [[5, 6,
//    7, 8]]]
Ok(Nil)
pub fn rank(tensor: Tensor(a, b, c)) -> Int

Returns the rank of a given Tensor as an Int representing the number of dimensions.

Examples

> rank(from_float(0.))
0

> import argamak/space
> type Axis { X Y Z }
> assert Ok(space) = space.d1(X)
> try tensor = from_ints(of: [1, 2, 3], into: space)
> Ok(rank(tensor))
Ok(1)

> assert Ok(space) = space.d3(#(X, 2), #(Y, 2), #(Z, 2))
> try tensor = from_ints(of: [1, 2, 3, 4, 5, 6, 7, 8], into: space)
> Ok(rank(tensor))
Ok(3)
pub fn reshape(put tensor: Tensor(a, b, c), into space: Space(
    d,
    e,
  )) -> Result(Tensor(a, d, e), TensorError)

Results in a Tensor placed into a given n-dimensional Space on success, or a TensorError on failure.

The Space’s Shape may have a single dimension given as -1, in which case that dimension’s size will be inferred from the given list. This is useful when working with lists of unknown length.

Examples

> import argamak/space
> type Axis { X Y Z }
> let tensor = from_float(1.)
> assert Ok(space) = space.d1(X)
> try tensor = reshape(put: tensor, into: space)
> Ok(print(from: tensor, wrap_at: -1, meta: True))
// Tensor
// format: Float32
// space: D1 #(X, 1)
// data:
// [1.0]
Ok(Nil)

> assert Ok(space) = space.d1(X)
> try tensor = from_floats(of: [1., 2., 3., 4.], into: space)
> assert Ok(space) = space.d2(#(X, 2), #(Y, 2))
> try tensor = reshape(put: tensor, into: space)
> Ok(print(from: tensor, wrap_at: -1, meta: True))
// Tensor
// format: Float32
// space: D2 #(X, 2), #(Y, 2)
// data:
// [[1.0, 2.0],
//  [3.0, 4.0]]
Ok(Nil)

> assert Ok(space) = space.d2(#(X, 2), #(Y, -1))
> let list = [1., 2., 3., 4., 5., 6., 7., 8.]
> try tensor = from_floats(of: list, into: space)
> assert Ok(space) = space.d3(#(X, -1), #(Y, 2), #(Z, 2))
> try tensor = reshape(put: tensor, into: space)
> Ok(print(from: tensor, wrap_at: -1, meta: True))
// Tensor
// format: Float32
// space: D3 #(X, 2), #(Y, 2), #(Z, 2)
// data:
// [[[1.0, 2.0],
//   [3.0, 4.0]],
//  [[5.0, 6.0],
//   [7.0, 8.0]]]
Ok(Nil)

> assert Ok(space) = space.d3(#(X, 1), #(Y, 1), #(Z, 1))
> try tensor = from_floats(of: [1.], into: space)
> assert Ok(space) = space.d0()
> try tensor = reshape(put: tensor, into: space)
> Ok(print(from: tensor, wrap_at: -1, meta: False))
// 1.0
Ok(Nil)
pub fn shape(tensor: Tensor(a, b, c)) -> List(Int)

Returns the shape of a given Tensor.

Examples

> shape(from_float(0.))
[]

> import argamak/space
> type Axis { X Y Z }
> assert Ok(space) = space.d1(X)
> try tensor = from_ints(of: [1, 2, 3], into: space)
> Ok(shape(tensor))
Ok([3])

> assert Ok(space) = space.d3(#(X, 2), #(Y, 2), #(Z, 2))
> try tensor = from_ints(of: [1, 2, 3, 4, 5, 6, 7, 8], into: space)
> Ok(shape(tensor))
Ok([2, 2, 2])
pub fn space(tensor: Tensor(a, b, c)) -> Space(b, c)

Returns the Space a given Tensor is currently in.

Examples

> import argamak/space
> assert Ok(space) = space.d0()
> space(from_float(0.))
space

> type Axis { X Y Z }
> assert Ok(space) = space.d1(X)
> try tensor = from_ints(of: [1, 2, 3], into: space)
> Ok(space(tensor))
Ok(space)

> assert Ok(space) = space.d3(#(X, 2), #(Y, 2), #(Z, 2))
> try tensor = from_ints(of: [1, 2, 3, 4, 5, 6, 7, 8], into: space)
> Ok(space(tensor))
Ok(space)
pub fn to_float(tensor: Tensor(Float, D0, a)) -> Float

Converts a Tensor without dimensions into a Float.

Examples

> let tensor = from_float(0.)
> to_float(tensor)
0.

> import argamak/format
> let tensor = from_int(0)
> let tensor = as_format(for: tensor, apply: format.float32)
> to_float(tensor)
0.
pub fn to_int(tensor: Tensor(Int, D0, a)) -> Int

Converts a Tensor without dimensions into an Int.

Examples

> let tensor = from_int(0)
> to_int(tensor)
0

> import argamak/format
> let tensor = from_float(0.)
> let tensor = as_format(for: tensor, apply: format.int32)
> to_int(tensor)
0
pub fn to_list(tensor: Tensor(a, b, c)) -> List(a)

Converts a Tensor into a flat list of numbers.

Examples

> to_list(from_int(0))
[0]

> import argamak/space
> type Axis { X Y }
> assert Ok(space) = space.d2(#(X, 3), #(Y, 1))
> try tensor = from_floats(of: [1., 2., 3.], into: space)
> Ok(to_list(tensor))
Ok([1., 2., 3.])
pub fn to_native(tensor: Tensor(a, b, c)) -> Native

Coverts a Tensor into its Native representation.

Examples

> external fn erlang_rank(Native) -> Int =
>   "Elixir.Nx" "rank"
> let native = to_native(from_int(3))
> erlang_rank(native)
0