argamak/tensor
Types
A Result
alias type for Native
tensor data.
pub type NativeResult =
Result(Native, TensorError)
A Tensor
is a generic container for n-dimensional data structures.
pub opaque type Tensor(a)
When a tensor operation cannot succeed.
pub type TensorError {
AxisNotFound
CannotBroadcast
IncompatibleAxes
IncompatibleShape
InvalidData
SpaceErrors(space.SpaceErrors)
ZeroDivision
}
Constructors
-
AxisNotFound
-
CannotBroadcast
-
IncompatibleAxes
-
IncompatibleShape
-
InvalidData
-
SpaceErrors(space.SpaceErrors)
-
ZeroDivision
A Result
alias type for tensors.
pub type TensorResult(a) =
Result(Tensor(a), TensorError)
Functions
pub fn absolute_value(x: Tensor(a)) -> Tensor(a)
Returns the element-wise absolute value of the given Tensor
.
Examples
> let x = from_int(3)
> absolute_value(x) |> print
Tensor(
Format(Int32),
Space(),
3,
)
Nil
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [-0.3], into: d1)
> absolute_value(x) |> print
Tensor(
Format(Float32),
Space(X(1)),
[0.3],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(x) = from_ints(of: [-1, 8, 0], into: d3)
> absolute_value(x) |> print
Tensor(
Format(Int32),
Space(X(1), Y(3), Z(1)),
[[[1],
[8],
[0]]],
)
Nil
pub fn add(
a: Tensor(a),
b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise addition of the given tensors
on success (broadcast as needed), or a TensorError
on failure.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [0, 9], into: d1)
> let assert Ok(x) = add(a, from_int(3))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[ 3, 12],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [0, 4, 5, 0], into: d2)
> let assert Ok(x) = add(a, b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[ 0, 13],
[ 5, 9]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 0], into: d3)
> add(b, c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> add(b, c)
Error(CannotBroadcast)
pub fn all(
from x: Tensor(a),
with filter: fn(Axis) -> Bool,
) -> Tensor(a)
Reduces the given Tensor
over select axes to 1
if all values across
those axes are nonzero, otherwise 0
, with Format
retained.
Any Axis
for which the given filter
function returns True
is selected
for reduction and will be removed from the reduced tensor’s Space
.
If the filter
function returns False
for every Axis
, all Axes
will
be retained and the operation applied to every value of the Tensor
individually.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [-1, 0], into: d1)
> all(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
0,
)
Nil
> all(x, with: fn(_) { False }) |> print
Tensor(
Format(Int32),
Space(X(2)),
[1, 0],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(x) = from_ints(of: [1, 2], into: d3)
> all(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
1,
)
Nil
> all(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2)),
[[1, 1]],
)
Nil
pub fn any(
from x: Tensor(a),
with filter: fn(Axis) -> Bool,
) -> Tensor(a)
Reduces the given Tensor
over select axes to 1
if any values across
those axes are nonzero, otherwise 0
, with Format
retained.
Any Axis
for which the given filter
function returns True
is selected
for reduction and will be removed from the reduced tensor’s Space
.
If the filter
function returns False
for every Axis
, all Axes
will
be retained and the operation applied to every value of the Tensor
individually.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [-1, 0], into: d1)
> any(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
1,
)
Nil
> any(x, with: fn(_) { False }) |> print
Tensor(
Format(Int32),
Space(X(2)),
[1, 0],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(x) = from_ints(of: [0, 0], into: d3)
> any(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
0,
)
Nil
> any(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2)),
[[0, 0]],
)
Nil
pub fn arg_max(
from x: Tensor(a),
with find: fn(Axis) -> Bool,
) -> Tensor(a)
Reduces the given Tensor
over a select Axis
to the lowest index of the
max value across that Axis
, with Format
retained.
The first Axis
for which the given find
function returns True
is
selected for reduction and will be removed from the reduced tensor’s
Space
.
If the find
function returns False
for every Axis
, the Tensor
will
be flattened and the operation applied over the remaining Axis
.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [-1, 0], into: d1)
> arg_max(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
1,
)
Nil
> arg_max(x, with: fn(_) { False }) |> print
Tensor(
Format(Int32),
Space(),
1,
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(2))
> let assert Ok(x) = from_ints(of: [1, 2, 3, 4], into: d3)
> arg_max(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(Y(2), Z(2)),
[[0, 0],
[0, 0]],
)
Nil
> arg_max(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2)),
[[1, 0]],
)
Nil
pub fn arg_min(
from x: Tensor(a),
with find: fn(Axis) -> Bool,
) -> Tensor(a)
Reduces the given Tensor
over a select Axis
to the lowest index of the
min value across that Axis
, with Format
retained.
The first Axis
for which the given find
function returns True
is
selected for reduction and will be removed from the reduced tensor’s
Space
.
If the find
function returns False
for every Axis
, the Tensor
will
be flattened and the operation applied over the remaining Axis
.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [-1, 0], into: d1)
> arg_min(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
0,
)
Nil
> arg_min(x, with: fn(_) { False }) |> print
Tensor(
Format(Int32),
Space(),
0,
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(2))
> let assert Ok(x) = from_ints(of: [1, 2, 3, 4], into: d3)
> arg_min(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(Y(2), Z(2)),
[[0, 0],
[0, 0]],
)
Nil
> arg_min(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2)),
[[0, 1]],
)
Nil
pub fn axes(x: Tensor(a)) -> List(Axis)
Returns the Axes
of a given Tensor
.
Examples
> axes(from_int(3))
[]
> import argamak/axis.{Axis, X}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [1.0, 2.0, 3.0], into: d1)
> axes(x)
[X(3)]
> let assert Ok(d2) = space.d2(Axis("Alpha", 1), Axis("Omega", 3))
> let assert Ok(x) = from_ints(of: [1, 2, 3], into: d2)
> axes(x)
[Axis("Alpha", 1), Axis("Omega", 3)]
pub fn broadcast(
from x: Tensor(a),
into new_space: Space,
) -> Result(Tensor(a), TensorError)
Results in a Tensor
broadcast into a given Space
on success, or a
TensorError
on failure.
The new Space
cannot have fewer Axes
than the current Space
.
Each current Axis
size must be 1
or equal to its counterpart in the new
Space
(a dimensionless Tensor
can be broadcast into any Space
). Axis
compatibility is considered element-wise, tail-first.
Any Infer
in the new Space
will result in failure.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(X(3))
> let assert Ok(x) = broadcast(from: from_int(0), into: d1)
> print(x)
Tensor(
Format(Int32),
Space(X(3)),
[0, 0, 0],
)
Nil
> let assert Ok(d1) = space.d1(Infer("X"))
> let x = from_ints(of: [-1], into: d1)
> let assert Ok(d1) = space.d1(Y(5))
> let assert Ok(x) = broadcast(from: x, into: d1)
> print(x)
Tensor(
Format(Int32),
Space(Y(5)),
[-1, -1, -1, -1, -1],
)
Nil
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [1.0, 2.0, 3.0], into: d1)
> let assert Ok(d2) = space.d2(X(2), Y(3))
> let assert Ok(x) = broadcast(from: x, into: d2)
> print(x)
Tensor(
Format(Float32),
Space(X(2), Y(3)),
[[1.0, 2.0, 3.0],
[1.0, 2.0, 3.0]],
)
Nil
> let assert Ok(d3) = space.d3(X(2), Y(3), Infer("Z"))
> broadcast(from: x, into: d3)
Error(IncompatibleShape)
pub fn broadcast_over(
from x: Tensor(a),
into new_space: Space,
with space_map: fn(Axis) -> String,
) -> Result(Tensor(a), TensorError)
A variant of broadcast
that maps the given Tensor
’s current Axes
to
arbitrary counterparts in the new Space
.
The map function allows broadcasting into a Space
that is incompatible
with a standard broadcast
operation. Any given new Axis
must not be
matched with multiple axes from the Tensor
‘s current Space
, and the
current axes’ relative order may be interrupted, but not altered, when axes
are translated to their mapped counterparts.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [1.0, 2.0, 3.0], into: d1)
> let assert Ok(d2) = space.d2(X(3), Y(2))
> let assert Ok(y) = broadcast_over(from: x, into: d2, with: fn(_) { "X" })
> print(y)
Tensor(
Format(Float32),
Space(X(3), Y(2)),
[[1.0, 1.0],
[2.0, 2.0],
[3.0, 3.0]],
)
Nil
> let assert Ok(x) = from_ints(of: [1, 2, 3, 4, 5, 6], into: d2)
> let assert Ok(d3) = space.d3(X(3), Y(2), Z(2))
> let assert Ok(y) = broadcast_over(
from: x,
into: d3,
with: fn(a) {
case axis.name(a) {
"Y" -> "Z"
name -> name
}
},
)
> print(y)
Tensor(
Format(Int32),
Space(X(3), Y(2), Z(2))
[[[1, 2],
[1, 2]],
[[3, 4],
[3, 4]],
[[5, 6],
[5, 6]]],
)
Nil
> let assert Ok(y) = broadcast_over(
from: x,
into: d3,
with: axis.name,
)
> print(y)
Tensor(
Format(Int32),
Space(X(3), Y(2), Z(2)),
[[[1, 1],
[2, 2]],
[[3, 3],
[4, 4]],
[[5, 5],
[6, 6]]],
)
Nil
> let assert Ok(d3) = space.d3(X(2), Y(3), Infer("Z"))
> broadcast_over(from: x, into: d3, with: axis.name)
Error(IncompatibleShape)
pub fn ceiling(x: Tensor(a)) -> Tensor(a)
Returns the element-wise ceiling of the given Tensor
, with Format
retained.
Examples
> let x = from_int(3)
> ceiling(x) |> print
Tensor(
Format(Int32),
Space(),
3,
)
Nil
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [-0.5], into: d1)
> ceiling(x) |> print
Tensor(
Format(Float32),
Space(X(1)),
[0.0],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(x) = from_floats(of: [-1.2, 7.8, 0.0], into: d3)
> ceiling(x) |> print
Tensor(
Format(Float32),
Space(X(1), Y(3), Z(1)),
[[[-1.0],
[ 8.0],
[ 0.0]]],
)
Nil
pub fn concat(
xs: List(Tensor(a)),
with find: fn(Axis) -> Bool,
) -> Result(Tensor(a), TensorError)
Results in a new Tensor
formed by concatenating (joining) the given list
of tensors along a select Axis
on success, or a TensorError
on failure.
The first Axis
for which the given find
function returns True
is
selected for joining.
If the find
function returns False
for every Axis
, an AxisNotFound
error is returned.
Examples
> import argamak/axis.{Infer, X, Y}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(a) = from_ints(of: [0, 1, 2, 3], into: d1)
> let assert Ok(b) = from_ints(of: [4, 5, 6, 7], into: d1)
> let assert Ok(x) = concat([a, b], with: fn(_) { True })
> print(x)
Tensor(
Format(Int32),
Space(X(8)),
[0, 1, 2, 3, 4, 5, 6, 7],
)
Nil
> let assert Ok(d2) = space.d2(X(2), Infer("Y"))
> let assert Ok(a) = reshape(put: a, into: d2)
> let assert Ok(b) = from_ints(of: [4, 5], into: d2)
> let assert Ok(x) = concat([a, b], with: fn(a) { axis.name(a) == "Y" })
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(3)),
[[0, 1, 4],
[2, 3, 5]],
)
Nil
> concat([a, b], with: fn(_) { False })
Error(AxisNotFound)
> concat([a, b], with: fn(a) { axis.name(a) == "X" })
Error(IncompatibleShape)
> let assert Ok(b) = reshape(put: b, into: d1)
> concat([a, b], with: fn(a) { axis.name(a) == "X" })
Error(IncompatibleShape)
> let assert Ok(d2) = space.d2(Infer("Z"), Y(1))
> let assert Ok(b) = reshape(put: b, into: d2)
> concat([a, b], with: fn(a) { axis.name(a) == "Y" })
Error(IncompatibleShape)
pub fn debug(x: Tensor(a)) -> Tensor(a)
Prints the data and metadata from a given Tensor
and returns the Tensor
.
Examples
> import argamak/axis.{X, Y, Z}
> import argamak/space
> let assert Ok(d2) = space.d2(X(2), Y(2))
> let assert Ok(x) = from_ints(of: [1, 2, 3, 4], into: d2)
> debug(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[1, 2],
[3, 4]],
)
x
> let assert Ok(d3) = space.d3(X(2), Y(1), Z(4))
> let xs = [1, 2, 3, 4, 5, 6, 7, 8]
> let assert Ok(x) = from_ints(of: xs, into: d3)
> debug(x)
Tensor(
Format(Int32),
Space(X(2), Y(1), Z(4)),
[[[1, 2, 3, 4]],
[[5, 6, 7, 8]]],
)
x
pub fn divide(
from a: Tensor(a),
by b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise division of one Tensor
by
another on success (broadcast as needed), or a TensorError
on failure.
As with Gleam’s operators, division by zero returns zero.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [1, 9], into: d1)
> let assert Ok(x) = divide(from: a, by: from_int(3))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[0, 3],
)
Nil
> let a = reformat(a, apply: format.float32())
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_floats(of: [0.0, 4.0, 5.0, 9.0], into: d2)
> let assert Ok(x) = divide(from: a, by: b)
> print(x)
Tensor(
Format(Float32),
Space(X(2), Y(2)),
[[ 0.0, 2.25],
[ 0.2, 1.0]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_floats(of: [4.0, 5.0, 0.0], into: d3)
> divide(from: b, by: c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> divide(from: b, by: c)
Error(CannotBroadcast)
pub fn equal(
is a: Tensor(a),
to b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise comparison of the given
tensors on success (broadcast as needed), or a TensorError
on failure.
Equality is represented by 1
, inequality by 0
, with Format
retained.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [5, 4], into: d1)
> let assert Ok(x) = equal(is: a, to: from_int(4))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[0, 1],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [4, 4, 5, 5], into: d2)
> let assert Ok(x) = equal(is: a, to: b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[0, 1],
[1, 0]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 6], into: d3)
> equal(is: b, to: c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> equal(is: b, to: c)
Error(CannotBroadcast)
pub fn exp(x: Tensor(a)) -> Tensor(a)
Returns the element-wise natural exponential (Euler’s number raised to the
power of x
) of the given Tensor
, with Format
retained.
Examples
> let x = from_int(3)
> exp(x) |> print
Tensor(
Format(Int32),
Space(),
20,
)
Nil
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [-0.5], into: d1)
> exp(x) |> print
Tensor(
Format(Float32),
Space(X(1)),
[0.223],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(x) = from_floats(of: [-1.2, 7.8, 0.0], into: d3)
> exp(x) |> print
Tensor(
Format(Float32),
Space(X(1), Y(3), Z(1)),
[[[ 0.301],
[2440.603],
[ 1.0]]],
)
Nil
pub fn floor(x: Tensor(a)) -> Tensor(a)
Returns the element-wise floor of the given Tensor
, with Format
retained.
Examples
> let x = from_int(3)
> floor(x) |> print
Tensor(
Format(Int32),
Space(),
3,
)
Nil
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [-0.5], into: d1)
> floor(x) |> print
Tensor(
Format(Float32),
Space(X(1)),
[-1.0],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(x) = from_floats(of: [-1.2, 7.8, 0.0], into: d3)
> floor(x) |> print
Tensor(
Format(Float32),
Space(X(1), Y(3), Z(1)),
[[[-2.0],
[ 7.0],
[ 0.0]]],
)
Nil
pub fn format(x: Tensor(a)) -> Format(a)
Returns the Format
of a given Tensor
.
Examples
import argamak/format
> format(from_float(0.0))
format.float32()
> import argamak/axis.{Infer}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [1, 2, 3], into: d1)
> format(x)
format.int32()
pub fn from_bool(x: Bool) -> Tensor(Int32)
Creates a Tensor(Int32)
from a Bool
.
True
is represented by 1
, False
by 0
.
Examples
> from_bool(True) |> print_data
1
Nil
> from_bool(False) |> print_data
0
Nil
pub fn from_bools(
of xs: List(Bool),
into space: Space,
) -> Result(Tensor(Int32), TensorError)
Results in a Tensor(Int32)
created from a list of booleans and placed into
a given Space
on success, or a TensorError
on failure.
True
is represented by 1
, False
by 0
.
The Space
may have a single Infer
Axis
, the size of which will be
determined based on the given list. This is useful when working with lists
of unknown length.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_bools(of: [True], into: d1)
> print(x)
Tensor(
Format(Int32),
Space(X(1)),
[1],
)
Nil
> let assert Ok(d2) = space.d2(X(2), Y(2))
> let assert Ok(x) = from_bools(of: [True, False, True, True], into: d2)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[1, 0],
[1, 1]],
)
Nil
> let assert Ok(d3) = space.d3(Infer("X"), Y(2), Z(2))
> let xs = [True, False, True, False, False, True, False, True]
> let assert Ok(x) = from_bools(of: xs, into: d3)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2), Z(2)),
[[[1, 0],
[1, 0]],
[[0, 1],
[0, 1]]],
)
Nil
pub fn from_float(x: Float) -> Tensor(Float32)
Creates a Tensor
from a Float
.
Examples
> from_float(1.0) |> print_data
1.0
Nil
pub fn from_floats(
of xs: List(Float),
into space: Space,
) -> Result(Tensor(Float32), TensorError)
Results in a Tensor
created from a list of floats and placed into a given
Space
on success, or a TensorError
on failure.
The Space
may have a single Infer
Axis
, the size of which will be
determined based on the given list. This is useful when working with lists
of unknown length.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [1.0], into: d1)
> print(x)
Tensor(
Format(Float32),
Space(X(1)),
[1.0],
)
Nil
> let assert Ok(d2) = space.d2(X(2), Y(2))
> let assert Ok(x) = from_floats(of: [1.0, 2.0, 3.0, 4.0], into: d2)
> print(x)
Tensor(
Format(Float32),
Space(X(2), Y(2)),
[[1.0, 2.0],
[3.0, 4.0]],
)
Nil
> let assert Ok(d3) = space.d3(Infer("X"), Y(2), Z(2))
> let xs = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
> let assert Ok(x) = from_floats(of: xs, into: d3)
> print(x)
Tensor(
Format(Float32),
Space(X(2), Y(2), Z(2)),
[[[1.0, 2.0],
[3.0, 4.0]],
[[5.0, 6.0],
[7.0, 8.0]]],
)
Nil
pub fn from_int(x: Int) -> Tensor(Int32)
Creates a Tensor
from an Int
.
Examples
> from_int(1) |> print_data
1
Nil
pub fn from_ints(
of xs: List(Int),
into space: Space,
) -> Result(Tensor(Int32), TensorError)
Results in a Tensor
created from a list of integers and placed into a
given Space
on success, or a TensorError
on failure.
The Space
may have a single Infer
Axis
, the size of which will be
determined based on the given list. This is useful when working with lists
of unknown length.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [1], into: d1)
> print(x)
Tensor(
Format(Int32),
Space(X(1)),
[1],
)
Nil
> let assert Ok(d2) = space.d2(X(2), Y(2))
> let assert Ok(x) = from_ints(of: [1, 2, 3, 4], into: d2)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[1, 2],
[3, 4]],
)
Nil
> let assert Ok(d3) = space.d3(Infer("X"), Y(2), Z(2))
> let xs = [1, 2, 3, 4, 5, 6, 7, 8]
> let assert Ok(x) = from_ints(of: xs, into: d3)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2), Z(2)),
[[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]],
)
Nil
pub fn from_native(
of x: Native,
into space: Space,
with format: Format(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
created from a Native
representation on success, or
a TensorError
on failure.
Examples
> import argamak/axis.{Infer, X, Y}
> import argamak/format
> import argamak/space
> import gleam/dynamic.{Dynamic}
> @external(erlang, "Elixir.Nx", "tensor")
> fn erlang_tensor(data: Dynamic) -> Native
> let native = erlang_tensor(dynamic.from([[1, 2], [3, 4]]))
> let assert Ok(d2) = space.d2(X(2), Infer("Y"))
> let assert Ok(x) = from_native(of: native, into: d2, with: format.int32)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[1, 2],
[3, 4]],
)
Nil
pub fn greater(
is a: Tensor(a),
than b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise comparison of the given
tensors on success (broadcast as needed), or a TensorError
on failure.
Values in the first Tensor
that are greater than those in the second are
represented by 1
, otherwise 0
, with Format
retained.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [5, 4], into: d1)
> let assert Ok(x) = greater(is: a, than: from_int(4))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[1, 0],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [4, 4, 5, 5], into: d2)
> let assert Ok(x) = greater(is: a, than: b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[1, 0],
[0, 0]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 6], into: d3)
> greater(is: b, than: c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> greater(is: b, than: c)
Error(CannotBroadcast)
pub fn greater_or_equal(
is a: Tensor(a),
to b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise comparison of the given
tensors on success (broadcast as needed), or a TensorError
on failure.
Values in the first Tensor
that are greater than or equal to those in the
second are represented by 1
, otherwise 0
, with Format
retained.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [5, 4], into: d1)
> let assert Ok(x) = greater_or_equal(is: a, to: from_int(4))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[1, 1],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [4, 4, 5, 5], into: d2)
> let assert Ok(x) = greater_or_equal(is: a, to: b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[1, 1],
[1, 0]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 6], into: d3)
> greater_or_equal(is: b, to: c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> greater_or_equal(is: b, to: c)
Error(CannotBroadcast)
pub fn in_situ_all(
from x: Tensor(a),
with filter: fn(Axis) -> Bool,
) -> Tensor(a)
A variant of all
that preserves all Axes
from the given Tensor
.
Any Axis
for which the given filter
function returns True
will retain
a size of 1
after the operation.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(x) = from_ints(of: [0, 2], into: d3)
> in_situ_all(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2), Z(1)),
[[[0],
[1]]],
)
Nil
pub fn in_situ_any(
from x: Tensor(a),
with filter: fn(Axis) -> Bool,
) -> Tensor(a)
A variant of any
that preserves all Axes
from the given Tensor
.
Any Axis
for which the given filter
function returns True
will retain
a size of 1
after the operation.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(x) = from_ints(of: [0, 2], into: d3)
> in_situ_any(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2), Z(1)),
[[[0],
[1]]],
)
Nil
pub fn in_situ_arg_max(
from x: Tensor(a),
with find: fn(Axis) -> Bool,
) -> Tensor(a)
A variant of arg_max
that preserves all Axes
from the given Tensor
.
An Axis
for which the given find
function returns True
will retain a
size of 1
after the operation.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(2))
> let assert Ok(x) = from_ints(of: [1, 2, 3, 4], into: d3)
> in_situ_arg_max(x, with: fn(a) { axis.name(a) == "Y" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(1), Z(2)),
[[[1, 0]]],
)
Nil
> in_situ_arg_max(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2), Z(1)),
[[[1],
[0]]],
)
Nil
pub fn in_situ_arg_min(
from x: Tensor(a),
with find: fn(Axis) -> Bool,
) -> Tensor(a)
A variant of arg_min
that preserves all Axes
from the given Tensor
.
An Axis
for which the given find
function returns True
will retain a
size of 1
after the operation.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(2))
> let assert Ok(x) = from_ints(of: [1, 2, 3, 4], into: d3)
> in_situ_arg_min(x, with: fn(a) { axis.name(a) == "Y" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(1), Z(2)),
[[[0, 1]]],
)
Nil
> in_situ_arg_min(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2), Z(1)),
[[[0],
[1]]],
)
Nil
pub fn in_situ_max_over(
from x: Tensor(a),
with filter: fn(Axis) -> Bool,
) -> Tensor(a)
A variant of max_over
that preserves all Axes
from the given Tensor
.
Any Axis
for which the given filter
function returns True
will retain
a size of 1
after the operation.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(2))
> let assert Ok(x) = from_ints(of: [1, 4, 3, 2], into: d3)
> in_situ_max_over(x, with: fn(a) { axis.name(a) == "Y" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(1), Z(2)),
[[[3, 4]]],
)
Nil
> in_situ_max_over(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2), Z(1)),
[[[4],
[3]]],
)
Nil
pub fn in_situ_mean(
from x: Tensor(a),
with filter: fn(Axis) -> Bool,
) -> Tensor(a)
A variant of mean
that preserves all Axes
from the given Tensor
.
Any Axis
for which the given filter
function returns True
will retain
a size of 1
after the operation.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(2))
> let assert Ok(x) = from_floats(of: [1.0, 4.0, 3.0, 2.0], into: d3)
> in_situ_mean(x, with: fn(_) { True }) |> print
Tensor(
Format(Float32),
Space(X(1), Y(1), Z(1)),
[[[2.5]]],
)
Nil
> in_situ_mean(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Float32),
Space(X(1), Y(2), Z(1)),
[[[2.5],
[2.5]]],
)
Nil
pub fn in_situ_min_over(
from x: Tensor(a),
with filter: fn(Axis) -> Bool,
) -> Tensor(a)
A variant of min_over
that preserves all Axes
from the given Tensor
.
Any Axis
for which the given filter
function returns True
will retain
a size of 1
after the operation.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(2))
> let assert Ok(x) = from_ints(of: [1, 4, 3, 2], into: d3)
> in_situ_min_over(x, with: fn(a) { axis.name(a) == "Y" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(1), Z(2)),
[[[1, 2]]],
)
Nil
> in_situ_min_over(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2), Z(1)),
[[[1],
[2]]],
)
Nil
pub fn in_situ_product(
from x: Tensor(a),
with filter: fn(Axis) -> Bool,
) -> Tensor(a)
A variant of product
that preserves all Axes
from the given Tensor
.
Any Axis
for which the given filter
function returns True
will retain
a size of 1
after the operation.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(2))
> let assert Ok(x) = from_ints(of: [1, 4, 3, 2], into: d3)
> in_situ_product(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(1), Z(1)),
[[[24]]],
)
Nil
> in_situ_product(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2), Z(1)),
[[[4],
[6]]],
)
Nil
pub fn in_situ_sum(
from x: Tensor(a),
with filter: fn(Axis) -> Bool,
) -> Tensor(a)
A variant of sum
that preserves all Axes
from the given Tensor
.
Any Axis
for which the given filter
function returns True
will retain
a size of 1
after the operation.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(2))
> let assert Ok(x) = from_ints(of: [2, 4, 3, 0], into: d3)
> in_situ_sum(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(1), Z(1)),
[[[9]]],
)
Nil
> in_situ_sum(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2), Z(1)),
[[[6],
[3]]],
)
Nil
pub fn less(
is a: Tensor(a),
than b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise comparison of the given
tensors on success (broadcast as needed), or a TensorError
on failure.
Values in the first Tensor
that are less than those in the second are
represented by 1
, otherwise 0
, with Format
retained.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [5, 4], into: d1)
> let assert Ok(x) = less(is: a, than: from_int(5))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[0, 1],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [4, 4, 5, 5], into: d2)
> let assert Ok(x) = less(is: a, than: b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[0, 0],
[0, 1]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 6], into: d3)
> less(is: b, than: c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> less(is: b, than: c)
Error(CannotBroadcast)
pub fn less_or_equal(
is a: Tensor(a),
to b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise comparison of the given
tensors on success (broadcast as needed), or a TensorError
on failure.
Values in the first Tensor
that are less than or equal to those in the
second are represented by 1
, otherwise 0
, with Format
retained.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [5, 4], into: d1)
> let assert Ok(x) = less_or_equal(is: a, to: from_int(5))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[1, 1],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [4, 4, 5, 5], into: d2)
> let assert Ok(x) = less_or_equal(is: a, to: b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[0, 1],
[1, 1]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 6], into: d3)
> less_or_equal(is: b, to: c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> less_or_equal(is: b, to: c)
Error(CannotBroadcast)
pub fn ln(x: Tensor(a)) -> Result(Tensor(a), TensorError)
Results in the element-wise natural logarithm of the given Tensor
on
success, or a TensorError
on failure, with Format
retained.
Examples
> let assert Ok(x) = ln(from_int(3))
> print(x)
Tensor(
Format(Int32),
Space(),
1,
)
Nil
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [1.5], into: d1)
> let assert Ok(x) = ln(x)
> print(x)
Tensor(
Format(Float32),
Space(X(1)),
[0.405],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(x) = from_floats(of: [1.2, 7.8, 0.0], into: d3)
> let assert Ok(x) = ln(x)
> print(x)
Tensor(
Format(Float32),
Space(X(1), Y(3), Z(1)),
[[[ 0.182],
[ 2.054],
[-Infinity]]],
)
Nil
> ln(from_float(-0.1))
Error(InvalidData)
pub fn logical_and(
a: Tensor(a),
b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise comparison of the given
tensors on success (broadcast as needed), or a TensorError
on failure.
Values that are nonzero in both the first and second tensors are represented
by 1
, otherwise 0
, with Format
retained.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [9, 0], into: d1)
> let assert Ok(x) = logical_and(a, from_int(3))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[1, 0],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [0, 4, 5, 0], into: d2)
> let assert Ok(x) = logical_and(a, b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[0, 0],
[1, 0]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 0], into: d3)
> logical_and(b, c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> logical_and(b, c)
Error(CannotBroadcast)
pub fn logical_not(x: Tensor(a)) -> Tensor(a)
Returns the element-wise logical opposite of the given Tensor
.
Values that are nonzero are represented by 0
, otherwise 1
, with Format
retained.
Examples
> let x = from_int(3)
> logical_not(x) |> print
Tensor(
Format(Int32),
Space(),
0,
)
Nil
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [-0.3], into: d1)
> logical_not(x) |> print
Tensor(
Format(Float32),
Space(X(1)),
[0.0],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(x) = from_ints(of: [-1, 8, 0], into: d3)
> logical_not(x) |> print
Tensor(
Format(Int32),
Space(X(1), Y(3), Z(1)),
[[[0],
[0],
[1]]],
)
Nil
pub fn logical_or(
a: Tensor(a),
b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise comparison of the given
tensors on success (broadcast as needed), or a TensorError
on failure.
Values that are nonzero in either the first or second Tensor
, or both, are
represented by 1
, otherwise 0
, with Format
retained.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [9, 0], into: d1)
> let assert Ok(x) = logical_or(a, from_int(3))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[1, 1],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [0, 4, 5, 0], into: d2)
> let assert Ok(x) = logical_or(a, b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[1, 1],
[1, 0]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 0], into: d3)
> logical_or(b, c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> logical_or(b, c)
Error(CannotBroadcast)
pub fn logical_xor(
a: Tensor(a),
b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise comparison of the given
tensors on success (broadcast as needed), or a TensorError
on failure.
Values that are nonzero in either the first or second Tensor
, but not
both, are represented by 1
, otherwise 0
, with Format
retained.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [9, 0], into: d1)
> let assert Ok(x) = logical_xor(a, from_int(3))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[0, 1],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [0, 4, 5, 0], into: d2)
> let assert Ok(x) = logical_xor(a, b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[1, 1],
[0, 0]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 0], into: d3)
> logical_xor(b, c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> logical_xor(b, c)
Error(CannotBroadcast)
pub fn max(
a: Tensor(a),
b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise maximum of the given tensors
on success (broadcast as needed), or a TensorError
on failure.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [1, 9], into: d1)
> let assert Ok(x) = max(a, from_int(3))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[3, 9],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [0, 4, 5, -9], into: d2)
> let assert Ok(x) = max(a, b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[1, 9],
[5, 9]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 0], into: d3)
> max(b, c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> max(b, c)
Error(CannotBroadcast)
pub fn max_over(
from x: Tensor(a),
with filter: fn(Axis) -> Bool,
) -> Tensor(a)
Reduces the given Tensor
over select axes to the max value across those
axes.
Any Axis
for which the given filter
function returns True
is selected
for reduction and will be removed from the reduced tensor’s Space
.
If the filter
function returns False
for every Axis
, all Axes
will
be retained and the operation applied to every value of the Tensor
individually.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [-1, 2], into: d1)
> max_over(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
2,
)
Nil
> max_over(x, with: fn(_) { False }) |> print
Tensor(
Format(Int32),
Space(X(2)),
[-1, 2],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(2))
> let assert Ok(x) = from_ints(of: [1, 4, 3, 2], into: d3)
> max_over(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
4,
)
Nil
> max_over(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2)),
[[4, 3]],
)
Nil
pub fn mean(
from x: Tensor(a),
with filter: fn(Axis) -> Bool,
) -> Tensor(a)
Reduces the given Tensor
over select axes to the mean of the values across
those axes.
Any Axis
for which the given filter
function returns True
is selected
for reduction and will be removed from the reduced tensor’s Space
.
If the filter
function returns False
for every Axis
, all Axes
will
be retained and the operation applied to every value of the Tensor
individually.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [-1, 2], into: d1)
> mean(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
0,
)
Nil
> mean(x, with: fn(_) { False }) |> print
Tensor(
Format(Int32),
Space(X(2)),
[-1, 2],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(2))
> let assert Ok(x) = from_floats(of: [1.0, 4.0, 3.0, 2.0], into: d3)
> mean(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
2.5,
)
Nil
> mean(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2)),
[[2.5, 2.5]],
)
Nil
pub fn min(
a: Tensor(a),
b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise minimum of the given tensors
on success (broadcast as needed), or a TensorError
on failure.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [1, 9], into: d1)
> let assert Ok(x) = min(a, from_int(3))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[1, 3],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [0, 4, 5, -9], into: d2)
> let assert Ok(x) = min(a, b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[ 0, 4],
[ 1, -9]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 0], into: d3)
> min(b, c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> min(b, c)
Error(CannotBroadcast)
pub fn min_over(
from x: Tensor(a),
with filter: fn(Axis) -> Bool,
) -> Tensor(a)
Reduces the given Tensor
over select axes to the min value across those
axes.
Any Axis
for which the given filter
function returns True
is selected
for reduction and will be removed from the reduced tensor’s Space
.
If the filter
function returns False
for every Axis
, all Axes
will
be retained and the operation applied to every value of the Tensor
individually.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [-1, 2], into: d1)
> min_over(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
-1,
)
Nil
> min_over(x, with: fn(_) { False }) |> print
Tensor(
Format(Int32),
Space(X(2)),
[-1, 2],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(2))
> let assert Ok(x) = from_ints(of: [1, 4, 3, 2], into: d3)
> min_over(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
1,
)
Nil
> min_over(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2)),
[[1, 2]],
)
Nil
pub fn modulo(
from a: Tensor(a),
divided_by b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise modulus when dividing one
Tensor
by another on success (broadcast as needed), or a TensorError
on
failure.
As with Gleam’s operators, division by zero returns zero.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [13, -13], into: d1)
> let assert Ok(x) = modulo(from: a, divided_by: from_int(0))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[0, 0],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [3, 3, -3, -3], into: d2)
> let assert Ok(x) = modulo(from: a, divided_by: b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[ 1, 2],
[ -2, -1]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 0], into: d3)
> modulo(from: b, divided_by: c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> modulo(from: b, divided_by: c)
Error(CannotBroadcast)
pub fn multiply(
a: Tensor(a),
b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise multiplication of the given
tensors on success (broadcast as needed), or a TensorError
on failure.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [1, 9], into: d1)
> let assert Ok(x) = multiply(a, from_int(3))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[ 3, 27],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [0, 4, 5, 9], into: d2)
> let assert Ok(x) = multiply(a, b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[ 0, 36],
[ 5, 81]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 0], into: d3)
> multiply(b, c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> multiply(b, c)
Error(CannotBroadcast)
pub fn negate(x: Tensor(a)) -> Tensor(a)
Returns the element-wise negation of the given Tensor
.
Examples
> let x = from_int(3)
> negate(x) |> print
Tensor(
Format(Int32),
Space(),
-3,
)
Nil
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [-0.3], into: d1)
> negate(x) |> print
Tensor(
Format(Float32),
Space(X(1)),
[0.3],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(x) = from_ints(of: [-1, 8, 0], into: d3)
> negate(x) |> print
Tensor(
Format(Int32),
Space(X(1), Y(3), Z(1)),
[[[ 1],
[-8],
[ 0]]],
)
Nil
pub fn not_equal(
is a: Tensor(a),
to b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise comparison of the given
tensors on success (broadcast as needed), or a TensorError
on failure.
Inequality is represented by 1
, equality by 0
, with Format
retained.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [5, 4], into: d1)
> let assert Ok(x) = not_equal(is: a, to: from_int(4))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[1, 0],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [4, 4, 5, 5], into: d2)
> let assert Ok(x) = not_equal(is: a, to: b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[1, 0],
[0, 1]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 6], into: d3)
> not_equal(is: b, to: c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> not_equal(is: b, to: c)
Error(CannotBroadcast)
pub fn power(
raise a: Tensor(a),
to_the b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise raising of one Tensor
to
the power of another on success (broadcast as needed), or a TensorError
on
failure.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [1, 9], into: d1)
> let assert Ok(x) = power(raise: a, to_the: from_int(3))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[ 1, 729],
)
Nil
> let a = reformat(a, apply: format.float32())
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_floats(of: [0.0, 0.4, 0.5, 0.9], into: d2)
> let assert Ok(x) = power(raise: a, to_the: b)
> print(x)
Tensor(
Format(Float32),
Space(X(2), Y(2)),
[[ 1.0, 2.408],
[ 1.0, 7.225]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_floats(of: [4.0, 5.0, 0.0], into: d3)
> power(raise: b, to_the: c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> power(raise: b, to_the: c)
Error(CannotBroadcast)
pub fn print(x: Tensor(a)) -> Nil
Prints the data and metadata from a given Tensor
.
Examples
> import argamak/axis.{X, Y, Z}
> import argamak/space
> let assert Ok(d2) = space.d2(X(2), Y(2))
> let assert Ok(x) = from_ints(of: [1, 2, 3, 4], into: d2)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[1, 2],
[3, 4]],
)
Nil
> let assert Ok(d3) = space.d3(X(2), Y(1), Z(4))
> let xs = [1, 2, 3, 4, 5, 6, 7, 8]
> let assert Ok(x) = from_ints(of: xs, into: d3)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(1), Z(4)),
[[[1, 2, 3, 4]],
[[5, 6, 7, 8]]],
)
Nil
pub fn print_data(x: Tensor(a)) -> Nil
Prints the data from a given Tensor
.
Examples
> import argamak/axis.{X, Y, Z}
> import argamak/space
> let assert Ok(d2) = space.d2(X(2), Y(2))
> let assert Ok(x) = from_ints(of: [1, 2, 3, 4], into: d2)
> print_data(x)
[[1, 2],
[3, 4]]
Nil
> let assert Ok(d3) = space.d3(X(2), Y(1), Z(4))
> let xs = [1, 2, 3, 4, 5, 6, 7, 8]
> let assert Ok(x) = from_ints(of: xs, into: d3)
> print_data(x)
[[[1, 2, 3, 4]],
[[5, 6, 7, 8]]]
Nil
pub fn product(
from x: Tensor(a),
with filter: fn(Axis) -> Bool,
) -> Tensor(a)
Reduces the given Tensor
over select axes to the product of the values
across those axes.
Any Axis
for which the given filter
function returns True
is selected
for reduction and will be removed from the reduced tensor’s Space
.
If the filter
function returns False
for every Axis
, all Axes
will
be retained and the operation applied to every value of the Tensor
individually.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [-1, 2], into: d1)
> product(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
-2,
)
Nil
> product(x, with: fn(_) { False }) |> print
Tensor(
Format(Int32),
Space(X(2)),
[-1, 2],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(2))
> let assert Ok(x) = from_ints(of: [1, 4, 3, 2], into: d3)
> product(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
24,
)
Nil
> product(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2)),
[[4, 6]],
)
Nil
pub fn rank(x: Tensor(a)) -> Int
Returns the rank of a given Tensor
as an Int
representing the number of
Axes
.
Examples
> rank(from_float(0.0))
0
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [1, 2, 3], into: d1)
> rank(x)
1
> let assert Ok(d3) = space.d3(X(2), Y(2), Z(2))
> let assert Ok(x) = from_ints(of: [1, 2, 3, 4, 5, 6, 7, 8], into: d3)
> rank(x)
3
pub fn reformat(
x: Tensor(a),
apply format: Format(b),
) -> Tensor(b)
Changes the Format
of a Tensor
.
Reformatting from Float
-like formats to Int
-like formats truncates the
data. For consistency, consider using round
, floor
, or ceiling
beforehand.
Lowering precision may lead to an overflow or underflow, the outcome of which depends on platform and compiler.
Examples
> import argamak/format
> reformat(from_int(0), apply: format.float32()) |> print
Tensor(
Format(Float32),
Space(),
0.0,
)
Nil
> import argamak/axis.{Infer}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [1.0, 2.0, 3.0], into: d1)
> reformat(x, apply: format.int32()) |> print
Tensor(
Format(Int32),
Space(X(3)),
[1, 2, 3],
)
Nil
pub fn remainder(
from a: Tensor(a),
divided_by b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise remainder when dividing one
Tensor
by another on success (broadcast as needed), or a TensorError
on
failure.
As with Gleam’s operators, division by zero returns zero.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [13, -13], into: d1)
> let assert Ok(x) = remainder(from: a, divided_by: from_int(0))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[0, 0],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [3, 3, -3, -3], into: d2)
> let assert Ok(x) = remainder(from: a, divided_by: b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[ 1, -1],
[ 1, -1]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 0], into: d3)
> remainder(from: b, divided_by: c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> remainder(from: b, divided_by: c)
Error(CannotBroadcast)
pub fn reshape(
put x: Tensor(a),
into new_space: Space,
) -> Result(Tensor(a), TensorError)
Results in a Tensor
placed into a given Space
on success, or a
TensorError
on failure.
The new Space
may have a single Infer
Axis
, the size of which will
be determined based on the given Tensor
.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = reshape(put: from_float(1.0), into: d1)
> print(x)
Tensor(
Format(Float32),
Space(X(1)),
[1.0],
)
Nil
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [1.0, 2.0, 3.0, 4.0], into: d1)
> let assert Ok(d2) = space.d2(X(2), Y(2))
> let assert Ok(x) = reshape(put: x, into: d2)
> print(x)
Tensor(
Format(Float32),
Space(X(2), Y(2)),
[[1.0, 2.0],
[3.0, 4.0]],
)
Nil
> let assert Ok(d2) = space.d2(X(2), Infer("Y"))
> let xs = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
> let assert Ok(x) = from_floats(of: xs, into: d2)
> let assert Ok(d3) = space.d3(Infer("X"), Y(2), Z(2))
> let assert Ok(x) = reshape(put: x, into: d3)
> print(x)
Tensor(
Format(Float32),
Space(X(2), Y(2), Z(2)),
[[[1.0, 2.0],
[3.0, 4.0]],
[[5.0, 6.0],
[7.0, 8.0]]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Y(1), Z(1))
> let assert Ok(x) = from_floats(of: [1.0], into: d3)
> let assert Ok(x) = reshape(put: x, into: space.new())
> print_data(x)
1.0
Nil
> reshape(put: x, into: d2)
Error(IncompatibleShape)
pub fn round(x: Tensor(a)) -> Tensor(a)
Returns the element-wise rounding of the given Tensor
, with Format
retained.
Examples
> let x = from_int(3)
> round(x) |> print
Tensor(
Format(Int32),
Space(),
3,
)
Nil
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [-0.5], into: d1)
> round(x) |> print
Tensor(
Format(Float32),
Space(X(1)),
[-1.0],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(x) = from_floats(of: [-1.2, 7.8, 0.0], into: d3)
> round(x) |> print
Tensor(
Format(Float32),
Space(X(1), Y(3), Z(1)),
[[[-1.0],
[ 8.0],
[ 0.0]]],
)
Nil
pub fn shape(x: Tensor(a)) -> List(Int)
Returns the shape of a given Tensor
.
Examples
> shape(from_float(0.0))
[]
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [1, 2, 3], into: d1)
> shape(x)
[3]
> let assert Ok(d3) = space.d3(X(2), Y(2), Z(2))
> let assert Ok(x) = from_ints(of: [1, 2, 3, 4, 5, 6, 7, 8], into: d3)
> shape(x)
[2, 2, 2]
pub fn sign(x: Tensor(a)) -> Tensor(a)
Returns an element-wise indication of the sign of the given Tensor
.
Positive numbers are represented by 1
, negative numbers by -1
, and zero
by 0
, with Format
retained.
Examples
> let x = from_int(3)
> sign(x) |> print
Tensor(
Format(Int32),
Space(),
1,
)
Nil
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [-0.3], into: d1)
> sign(x) |> print
Tensor(
Format(Float32),
Space(X(1)),
[-1.0],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(x) = from_ints(of: [-1, 8, 0], into: d3)
> sign(x) |> print
Tensor(
Format(Int32),
Space(X(1), Y(3), Z(1)),
[[[-1],
[ 1],
[ 0]]],
)
Nil
pub fn size(x: Tensor(a)) -> Int
Returns the number of values in a given Tensor
.
Examples
> size(from_float(0.0))
1
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [1, 2, 3], into: d1)
> size(x)
3
> let assert Ok(d3) = space.d3(X(2), Y(2), Z(2))
> let assert Ok(x) = from_ints(of: [0, 1, 2, 3, 4, 5, 6, 7], into: d3)
> size(x)
8
pub fn space(x: Tensor(a)) -> Space
Returns the Space
a given Tensor
is currently in.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> space(from_float(0.0)) |> space.axes
[]
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [1, 2, 3], into: d1)
> space(x) |> space.axes
[X(3)]
> let assert Ok(d3) = space.d3(X(2), Y(2), Z(2))
> let assert Ok(x) = from_ints(of: [1, 2, 3, 4, 5, 6, 7, 8], into: d3)
> space(x) |> space.axes
[X(2), Y(2), Z(2)]
pub fn square_root(
x: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in the element-wise square root of the given Tensor
on success, or
a TensorError
on failure, with Format
retained.
Examples
> let assert Ok(x) = square_root(from_int(3))
> print(x)
Tensor(
Format(Int32),
Space(),
1,
)
Nil
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_floats(of: [1.5], into: d1)
> let assert Ok(x) = square_root(x)
> print(x)
Tensor(
Format(Float32),
Space(X(1)),
[1.225],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(x) = from_floats(of: [1.2, 7.8, 0.0], into: d3)
> let assert Ok(x) = square_root(x)
> print(x)
Tensor(
Format(Float32),
Space(X(1), Y(3), Z(1)),
[[[1.095],
[2.793],
[ 0.0]]],
)
Nil
> square_root(from_float(-0.1))
Error(InvalidData)
pub fn squeeze(
from x: Tensor(a),
with filter: fn(Axis) -> Bool,
) -> Tensor(a)
Removes from the given Tensor
axes of size 1
for which filter
returns
True
.
Examples
> let x = from_int(3)
> squeeze(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
3,
)
Nil
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [3], into: d1)
> squeeze(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
3,
)
Nil
> squeeze(x, with: fn(_) { False }) |> print
Tensor(
Format(Int32),
Space(X(1)),
[3],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(x) = from_ints(of: [1, 2], into: d3)
> squeeze(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(Y(2)),
[1, 2],
)
Nil
> squeeze(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2)),
[[1, 2]],
)
Nil
pub fn subtract(
from a: Tensor(a),
value b: Tensor(a),
) -> Result(Tensor(a), TensorError)
Results in a Tensor
that is the element-wise subtraction of one Tensor
from another on success (broadcast as needed), or a TensorError
on
failure.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [0, 9], into: d1)
> let assert Ok(x) = subtract(from: a, value: from_int(3))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[-3, 6],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [0, 4, 5, 0], into: d2)
> let assert Ok(x) = subtract(from: a, value: b)
> print(x)
Tensor(
Format(Int32),
Space(X(2), Y(2)),
[[ 0, 5],
[-5, 9]],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(1))
> let assert Ok(c) = from_ints(of: [4, 5, 0], into: d3)
> subtract(from: b, value: c)
Error(SpaceErrors([
SpaceError(CannotMerge, [Y(3), X(2)]),
SpaceError(CannotMerge, [Z(1), Y(2)]),
]))
> let assert Ok(d3) = space.d3(Z(1), Infer("X"), Y(1))
> let assert Ok(c) = reshape(put: c, into: d3)
> subtract(from: b, value: c)
Error(CannotBroadcast)
pub fn sum(
from x: Tensor(a),
with filter: fn(Axis) -> Bool,
) -> Tensor(a)
Reduces the given Tensor
over select axes to the sum of the values across
those axes.
Any Axis
for which the given filter
function returns True
is selected
for reduction and will be removed from the reduced tensor’s Space
.
If the filter
function returns False
for every Axis
, all Axes
will
be retained and the operation applied to every value of the Tensor
individually.
Examples
> import argamak/axis.{Infer, X, Y, Z}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [-1, 2], into: d1)
> sum(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
1,
)
Nil
> sum(x, with: fn(_) { False }) |> print
Tensor(
Format(Int32),
Space(X(2)),
[-1, 2],
)
Nil
> let assert Ok(d3) = space.d3(X(1), Infer("Y"), Z(2))
> let assert Ok(x) = from_ints(of: [2, 4, 3, 0], into: d3)
> sum(x, with: fn(_) { True }) |> print
Tensor(
Format(Int32),
Space(),
9,
)
Nil
> sum(x, with: fn(a) { axis.name(a) == "Z" }) |> print
Tensor(
Format(Int32),
Space(X(1), Y(2)),
[[6, 3]],
)
Nil
pub fn to_bool(x: Tensor(a)) -> Result(Bool, TensorError)
Results in a Bool
converted from a dimensionless Tensor
on success, or a
TensorError
on failure.
Nonzero values become True
, otherwise False
.
Examples
> to_bool(from_float(0.0))
Ok(False)
> to_bool(from_int(1))
Ok(True)
import argamak/axis.{Infer}
import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [1], into: d1)
> to_bool(x)
Error(IncompatibleShape)
pub fn to_bools(x: Tensor(a)) -> List(Bool)
Converts a Tensor
into a flat list of booleans.
Nonzero values become True
, otherwise False
.
Examples
> to_bools(from_float(0.0))
[False]
> import argamak/axis.{X, Y}
> import argamak/space
> let assert Ok(d2) = space.d2(X(3), Y(1))
> let assert Ok(x) = from_ints(of: [1, 0, -3], into: d2)
> to_bools(x)
[True, False, True]
pub fn to_float(x: Tensor(a)) -> Result(Float, TensorError)
Results in a Float
converted from a dimensionless Tensor
on success, or
a TensorError
on failure.
Values that are infinite will be clipped to min/max finite values based on
the current Format
.
Examples
> to_float(from_float(0.0))
Ok(0.0)
> to_float(from_int(0))
Ok(0.0)
import argamak/axis.{Infer}
import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [1], into: d1)
> to_float(x)
Error(IncompatibleShape)
pub fn to_floats(x: Tensor(a)) -> List(Float)
Converts a Tensor
into a flat list of floats.
Values that are infinite will be clipped to min/max finite values based on
the current Format
.
Examples
> to_floats(from_int(0))
[0.0]
> import argamak/axis.{X, Y}
> import argamak/space
> let assert Ok(d2) = space.d2(X(3), Y(1))
> let assert Ok(x) = from_floats(of: [1.0, 2.0, 3.0], into: d2)
> to_floats(x)
[1.0, 2.0, 3.0]
pub fn to_int(x: Tensor(a)) -> Result(Int, TensorError)
Results in an Int
converted from a dimensionless Tensor
on success, or a
TensorError
on failure.
Values that are infinite will be clipped to min/max finite values based on
the current Format
.
Examples
> to_int(from_float(0.0))
Ok(0)
> to_int(from_int(0))
Ok(0)
import argamak/axis.{Infer}
import argamak/space
> let assert Ok(d1) = space.d1(Infer("X"))
> let assert Ok(x) = from_ints(of: [1], into: d1)
> to_int(x)
Error(IncompatibleShape)
pub fn to_ints(x: Tensor(a)) -> List(Int)
Converts a Tensor
into a flat list of integers.
Values that are infinite will be clipped to min/max finite values based on
the current Format
.
Examples
> to_ints(from_float(0.0))
[0]
> import argamak/axis.{X, Y}
> import argamak/space
> let assert Ok(d2) = space.d2(X(3), Y(1))
> let assert Ok(x) = from_ints(of: [1, 2, 3], into: d2)
> to_ints(x)
[1, 2, 3]
pub fn to_native(x: Tensor(a)) -> Native
Converts a Tensor
into its Native
representation.
Examples
> @external(erlang, "Elixir.Nx", "rank")
> fn erlang_rank(tensor: Native) -> Int
> to_native(from_int(3)) |> erlang_rank
0
pub fn to_string(
from x: Tensor(a),
return record_or_data: ToString,
wrap_at column: Int,
) -> String
Returns a string representation of the given Tensor
, either the whole
Record
or just its Data
.
Takes a column
argument for which the special values -1
and 0
represent default and no wrapping, respectively.
Examples
> import argamak/axis.{X, Y, Z}
> import argamak/space
> let assert Ok(d2) = space.d2(X(2), Y(2))
> let assert Ok(x) = from_ints(of: [1, 2, 3, 4], into: d2)
> to_string(from: x, return: Data, wrap_at: 0)
"[[1, 2],
[3, 4]]"
> let assert Ok(d3) = space.d3(X(2), Y(1), Z(4))
> let xs = [1, 2, 3, 4, 5, 6, 7, 8]
> let assert Ok(x) = from_ints(of: xs, into: d3)
> do_print(from: x, return: Record, wrap_at: 10)
"Tensor(
Format(Int32),
Space(X(2), Y(1), Z(4)),
[[[1, 2,
3, 4]],
[[5, 6,
7, 8]]],
)"
pub fn try_divide(
from a: Tensor(a),
by b: Tensor(a),
) -> Result(Tensor(a), TensorError)
A variant of divide
that results in a TensorError
if any value of the
divisor is zero.
Examples
> import argamak/axis.{Infer, X, Y}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [1, 9], into: d1)
> let assert Ok(x) = try_divide(from: a, by: from_int(3))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[0, 3],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [0, 4, 5, 9], into: d2)
> try_divide(from: a, by: b)
Error(ZeroDivision)
pub fn try_modulo(
from a: Tensor(a),
divided_by b: Tensor(a),
) -> Result(Tensor(a), TensorError)
A variant of modulo
that results in a TensorError
if any value of the
divisor is zero.
Examples
> import argamak/axis.{Infer, X, Y}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [1, 9], into: d1)
> let assert Ok(x) = try_modulo(from: a, divided_by: from_int(3))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[1, 0],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [0, 4, 5, 9], into: d2)
> try_modulo(from: a, divided_by: b)
Error(ZeroDivision)
pub fn try_remainder(
from a: Tensor(a),
divided_by b: Tensor(a),
) -> Result(Tensor(a), TensorError)
A variant of remainder
that results in a TensorError
if any value of the
divisor is zero.
Examples
> import argamak/axis.{Infer, X, Y}
> import argamak/space
> let assert Ok(d1) = space.d1(Infer("Y"))
> let assert Ok(a) = from_ints(of: [1, 9], into: d1)
> let assert Ok(x) = try_remainder(from: a, divided_by: from_int(3))
> print(x)
Tensor(
Format(Int32),
Space(Y(2)),
[1, 0],
)
Nil
> let assert Ok(d2) = space.d2(Infer("X"), Y(2))
> let assert Ok(b) = from_ints(of: [0, 4, 5, 9], into: d2)
> try_remainder(from: a, divided_by: b)
Error(ZeroDivision)