class Tensor(T)

Overview

A Tensor is a multidimensional container of fixed size, containing elements of type T.

The number of dimensions is specified by a Tensor's #shape, which is an Array of integers specifying the size of a Tensor in each dimension.

A Tensor can be created from a wide variety of creation methods. Including from a scalar value and #shape, from an Array, or from JSON.

Tensor's store data using a Pointer, and can be sliced/indexed to return a #view into this data. The slice will share memory with it's parent Tensor, and modifications to the view will be reflected in the parent

Tensor's cannot be resized, and any operation the changes the total number of elements in a Tensor will return a new object.

Defined in:

tensor/creation.cr
tensor/extension.cr
tensor/linalg.cr
tensor/operators.cr
tensor/reductions.cr
tensor/tensor.cr

Constructors

Class Method Summary

Instance Method Summary

Macro Summary

Constructor Detail

def self.new(buffer : Pointer(T), shape : Array(Int), strides : Array(Int), flags : Num::ArrayFlags) #

[View source]
def self.new(buffer : Pointer(T), shape : Array(Int), strides : Array(Int)) #

Low level method for creating a Tensor. No checks are performed to ensure that the #shape and #strides provided are valid for the Tensor, so this should primarily be used by lower level methods

The generic type of the Tensor is inferred from the buffer

Arguments

buffer : Pointer(T) Raw memory for a Tensor's data shape : Array(Int) Size of an array along each dimension strides : Array(Int) Step along each dimension to reach the next element of a Tensor

Examples

p = Pointer.malloc(3, 1)
shape = [3]
strides = [1]

Tensor.new(p, shape, strides) # => [1, 1, 1]

[View source]
def self.new(shape : Array(Int), order : Num::OrderType = Num::RowMajor) #

Creates a new, zero-filled Tensor of shape #shape. The memory layout of the Tensor is specified by order.

When creating a Tensor from a shape alone, the generic type must be specified.

Arguments

shape : Array(Int) Size of an array along each dimension order : Num::OrderType Internal memory layout of a Tensor. Tensor's can be stored using either C-style or Fortran-style ordering

Examples

Tensor(Int32).new([1, 3]) # => [[0, 0, 0]]

[View source]
def self.new(shape : Array(Int), value : T, order : Num::OrderType = Num::RowMajor) #

Creates a new Tensor of shape #shape. The memory layout of the Tensor is specified by order. The Tensor is initially populated with the scalar value.

The generic type of the Tensor is inferred from the type of the scalar.

Arguments

shape : Array(Int) Size of an array along each dimension value : T Initial value to fill the Tensor order : Num::OrderType Internal memory layout of a Tensor. Tensor's can be stored using either C-style or Fortran-style ordering

Examples

Tensor.new([1, 3], 2.4) # => [[2.4, 2.4, 2.4]]

[View source]
def self.new(value : T) #

Creates a new Tensor with an empty #shape and #strides, that contains a scalar value. This is also similar to what is returned by an indexing operation that slices a Tensor along all dimensions.

This tensor cannot be indexed or sliced, and all operations on it will return a copy, not a view

Arguments

value : T A single scalar value for the Tensor

Examples

Tensor.new(2.5) # => Tensor(2.5)

[View source]
def self.new(shape : Array(Int), order : Num::OrderType = Num::RowMajor, &block : Int32 -> T) #

Creates a new Tensor from a provided #shape and order, using values returned from a captured block. The index passed to the block is one- dimensional.

The generic type is inferred from the return type of the block

Arguments

shape : Array(Int) Size of an array along each dimension order : Num::OrderType Internal memory layout of a Tensor. Tensor's can be stored using either C-style or Fortran-style ordering block : Proc(Int32, T) Proc that takes an integer, and returns a value to be stored at that flat index of a Tensor

Examples

Tensor.new([3]) { |i| i } # => [0, 1, 2]

[View source]
def self.new(m : Int, n : Int, &block : Int32, Int32 -> T) #

Creates a new Tensor from a number of rows and columns, as well as a captured block, providing a convenient method to create matrices.

The generic type is inferred from the return value of the block

Arguments

m : Int Number of rows for the Tensor n : Int Number of columns for the Tensor block : Proc(Int32, Int32, T) Proc that takes an row index and column index, and returns a value to be stored at that flat index of a Tensor

Examples

Tensor.new(2, 2) { |i, j| i + j }

# [[0, 1],
#  [1, 2]]

[View source]

Class Method Detail

def self.diag(a : Tensor | Enumerable) #

Creates a two dimensional Tensor with a one-dimensional Tensor placed along the diagonal

Arguments

a : Tensor | Enumerable Input Tensor, must be one-dimensional

Examples

Tensor.diag([1, 2, 3])

# [[1, 0, 0],
#  [0, 2, 0],
#  [0, 0, 3]]

[View source]
def self.eye(m : Int, n : Int | Nil = nil, offset : Int = 0) #

Return a two-dimensional Tensor with ones along the diagonal, and zeros elsewhere

Arguments

m : Int Number of rows in the Tensor n : Int? Number of columsn in the Tensor, defaults to m if nil offset : Int Indicates which diagonal to fill with ones

Examples

Tensor(Int32).eye(3, offset: -1)

# [[0, 0, 0],
#  [1, 0, 0],
#  [0, 1, 0]]

Tensor(Int8).eye(2)

# [[1, 0],
#  [0, 1]]

[View source]
def self.from_array(a : Array) #

Creates a Tensor from any standard library Array. The shape of the Array will be inferred.

The generic type will be inferred from the elements of the Array

Arguments

a : Array Array to be turned into a Tensor

Examples

a = [1, 2, 3]
Tensor.from_array a # => [1, 2, 3]

[View source]
def self.from_json(input, shape : Array(Int)) #

Creates a Tensor from a JSON object or string. Only one-dimensional JSON arrays will be accepted, but a provided shape will be used as the output shape of the Tensor

The generic type must be specified in order to cast the elements from the JSON array

Arguments

input : IO or String JSON object or String to be converted to a Tensor shape : Array(Int) Shape to be used for the output Tensor

Examples

a = "[1, 2, 3]"
Tensor(Int32).from_json(a, [3]) # => [1, 2, 3]

[View source]
def self.identity(n : Int) #

Returns an identity Tensor with ones along the diagonal, and zeros elsewhere

Arguments

n : Number of rows and columns in output

Examples

Tensor(Int8).identity(2)

# [[1, 0],
#  [0, 1]]

[View source]
def self.ones(shape : Array(Int)) : Tensor(T) #

Creates a Tensor of a provided shape, filled with 1. The generic type must be specified.

Arguments

shape Shape of returned Tensor

Examples

t = Tensor(Int8).ones([3]) # => [1, 1, 1]

[View source]
def self.ones_like(t : Tensor) : Tensor(T) #

Creates a Tensor filled with 1, sharing the shape of another provided Tensor

Arguments

t Tensor to use for output shape

Examples

t = Tensor.new([3]) &.to_f
u = Tensor(Int8).ones_like(t) # => [0, 0, 0]

[View source]
def self.random(r : Range(U, U), shape : Array(Int)) : Tensor(U) forall U #

Creates a Tensor sampled from a provided range, with a given shape.

The generic types of the Tensor are inferred from the endpoints of the range

Arguments

r : Range(U, U) Range of values to sample between shape : Array(Int) Shape of returned Tensor

Examples

Num::Rand.set_seed(0)
t = Tensor.random(0...10, [2, 2])
t

# [[8, 4],
#  [7, 4]]

[View source]
def self.range(start : T, stop : T, step : T) : Tensor(T) #

Creates a flat Tensor containing a monotonically increasing or decreasing range. The generic type is inferred from the inputs to the method

Arguments

start Beginning value for the range stop End value for the range step Offset between values of the range

Examples

Tensor.range(0, 5, 2)       # => [0, 2, 4]
Tensor.range(5, 0, -1)      # => [5, 4, 3, 2, 1]
Tensor.range(0.0, 3.5, 0.7) # => [0  , 0.7, 1.4, 2.1, 2.8]

[View source]
def self.range(start : T, stop : T) : Tensor(T) #

Creates a flat Tensor containing a monotonically increasing or decreasing range. The generic type is inferred from the inputs to the method

Arguments

start Beginning value for the range stop End value for the range step Offset between values of the range

Examples

Tensor.range(0, 5, 2)       # => [0, 2, 4]
Tensor.range(5, 0, -1)      # => [5, 4, 3, 2, 1]
Tensor.range(0.0, 3.5, 0.7) # => [0  , 0.7, 1.4, 2.1, 2.8]

[View source]
def self.range(stop : T) : Tensor(T) #

Creates a flat Tensor containing a monotonically increasing or decreasing range. The generic type is inferred from the inputs to the method

Arguments

start Beginning value for the range stop End value for the range step Offset between values of the range

Examples

Tensor.range(0, 5, 2)       # => [0, 2, 4]
Tensor.range(5, 0, -1)      # => [5, 4, 3, 2, 1]
Tensor.range(0.0, 3.5, 0.7) # => [0  , 0.7, 1.4, 2.1, 2.8]

[View source]
def self.vandermonde(t : Tensor | Enumerable, n : Int, increasing : Bool = false) #

Generate a Vandermonde matrix.

The columns of the output Tensor are powers of the input vector. The order of the powers is determined by the increasing boolean argument. Specifically, when increasing is False, the i-th output column is the input vector raised element-wise to the power of N - i - 1. Such a matrix with a geometric progression in each row is named for Alexandre- Theophile Vandermonde.

Arguments

t : Tensor(T) One dimensional input Tensor n : Int Number of columns in the output, defaults to t.size increasing : Bool Specifies the order of the powers in the output

Examples

a = Tensor.from_array [1, 2, 3]
Tensor.vandermonde(a)

# [[1, 1, 1],
#  [4, 2, 1],
#  [9, 3, 1]]

Tensor.vandermonde(a, 4, increasing: true)

# [[ 1,  1,  1,  1],
#  [ 1,  2,  4,  8],
#  [ 1,  3,  9, 27]]

[View source]
def self.vandermonde(t : Tensor(T), increasing : Bool = false) #

Generate a Vandermonde matrix.

The columns of the output Tensor are powers of the input vector. The order of the powers is determined by the increasing boolean argument. Specifically, when increasing is False, the i-th output column is the input vector raised element-wise to the power of N - i - 1. Such a matrix with a geometric progression in each row is named for Alexandre- Theophile Vandermonde.

Arguments

t : Tensor(T) One dimensional input Tensor n : Int Number of columns in the output, defaults to t.size increasing : Bool Specifies the order of the powers in the output

Examples

a = Tensor.from_array [1, 2, 3]
Tensor.vandermonde(a)

# [[1, 1, 1],
#  [4, 2, 1],
#  [9, 3, 1]]

Tensor.vandermonde(a, 4, increasing: true)

# [[ 1,  1,  1,  1],
#  [ 1,  2,  4,  8],
#  [ 1,  3,  9, 27]]

[View source]
def self.zeros(shape : Array(Int)) : Tensor(T) #

Creates a Tensor of a provided shape, filled with 0. The generic type must be specified.

Arguments

shape Shape of returned Tensor

Examples

t = Tensor(Int8).zeros([3]) # => [0, 0, 0]

[View source]
def self.zeros_like(t : Tensor) : Tensor(T) #

Creates a Tensor filled with 0, sharing the shape of another provided Tensor

Arguments

t Tensor to use for output shape

Examples

t = Tensor.new([3]) &.to_f
u = Tensor(Int8).zeros_like(t) # => [0, 0, 0]

[View source]

Instance Method Detail

def !=(b : Tensor | Enumerable) #

[View source]
def !=(b : Number) #

[View source]
def %(b : Tensor | Enumerable) #

[View source]
def %(b : Number) #

[View source]
def &(b : Tensor | Enumerable) #

[View source]
def &(b : Number) #

[View source]
def *(b : Tensor | Enumerable) #

[View source]
def *(b : Number) #

[View source]
def **(b : Tensor | Enumerable) #

[View source]
def **(b : Number) #

[View source]
def +(b : Tensor | Enumerable) #

[View source]
def +(b : Number) #

[View source]
def -(b : Tensor | Enumerable) #

[View source]
def -(b : Number) #

[View source]
def /(b : Tensor | Enumerable) #

[View source]
def /(b : Number) #

[View source]
def //(b : Tensor | Enumerable) #

[View source]
def //(b : Number) #

[View source]
def <(b : Tensor | Enumerable) #

[View source]
def <(b : Number) #

[View source]
def <<(b : Tensor | Enumerable) #

[View source]
def <<(b : Number) #

[View source]
def <=(b : Tensor | Enumerable) #

[View source]
def <=(b : Number) #

[View source]
def ==(b : Tensor | Enumerable) #

[View source]
def ==(b : Number) #

[View source]
def >(b : Tensor | Enumerable) #

[View source]
def >(b : Number) #

[View source]
def >=(b : Tensor | Enumerable) #

[View source]
def >=(b : Number) #

[View source]
def >>(b : Tensor | Enumerable) #

[View source]
def >>(b : Number) #

[View source]
def [](args : Array) : Tensor(T) #

Returns a view of a Tensor from any valid indexers. This view must be able to be represented as valid strided/shaped view, slicing as a copy is not supported.

When an Integer argument is passed, an axis will be removed from the Tensor, and a view at that index will be returned.

a = Tensor.new([2, 2]) { |i| i }
a[0] # => [0, 1]

When a Range argument is passed, an axis will be sliced based on the endpoints of the range.

a = Tensor.new([2, 2, 2]) { |i| i }
a[1...]

# [[[4, 5],
#   [6, 7]]]

When a Tuple containing a Range and an Integer step is passed, an axis is sliced based on the endpoints of the range, and the strides of the axis are updated to reflect the step. Negative steps will reflect the array along an axis.

a = Tensor.new([2, 2]) { |i| i }
a[{..., -1}]

# [[2, 3],
#  [0, 1]]

[View source]
def [](*args) : Tensor(T) #

Returns a view of a Tensor from any valid indexers. This view must be able to be represented as valid strided/shaped view, slicing as a copy is not supported.

When an Integer argument is passed, an axis will be removed from the Tensor, and a view at that index will be returned.

a = Tensor.new([2, 2]) { |i| i }
a[0] # => [0, 1]

When a Range argument is passed, an axis will be sliced based on the endpoints of the range.

a = Tensor.new([2, 2, 2]) { |i| i }
a[1...]

# [[[4, 5],
#   [6, 7]]]

When a Tuple containing a Range and an Integer step is passed, an axis is sliced based on the endpoints of the range, and the strides of the axis are updated to reflect the step. Negative steps will reflect the array along an axis.

a = Tensor.new([2, 2]) { |i| i }
a[{..., -1}]

# [[2, 3],
#  [0, 1]]

[View source]
def []=(args : Array, value) #

The primary method of setting Tensor values. The slicing behavior for this method is identical to the #[] method.

If a Tensor is passed as the value to set, it will be broadcast to the shape of the slice if possible. If a scalar is passed, it will be tiled across the slice.

Arguments

args : *U Tuple of arguments. All but the last argument must be valid indexer, so a Range, Int, or Tuple(Range, Int). The final argument passed is used to set the values of the Tensor. It can be either a Tensor, or a scalar value.

Examples

a = Tensor.new([2, 2]) { |i| i }
a[1.., 1..] = 99
a

# [[ 0,  1],
#  [ 2, 99]]

[View source]
def []=(*args : *U) forall U #

The primary method of setting Tensor values. The slicing behavior for this method is identical to the #[] method.

If a Tensor is passed as the value to set, it will be broadcast to the shape of the slice if possible. If a scalar is passed, it will be tiled across the slice.

Arguments

args : *U Tuple of arguments. All but the last argument must be valid indexer, so a Range, Int, or Tuple(Range, Int). The final argument passed is used to set the values of the Tensor. It can be either a Tensor, or a scalar value.

Examples

a = Tensor.new([2, 2]) { |i| i }
a[1.., 1..] = 99
a

# [[ 0,  1],
#  [ 2, 99]]

[View source]
def ^(b : Tensor | Enumerable) #

[View source]
def ^(b : Number) #

[View source]
def |(b : Tensor | Enumerable) #

[View source]
def |(b : Number) #

[View source]
def acos #

[View source]
def acos! #

[View source]
def acosh #

[View source]
def acosh! #

[View source]
def add(b : Tensor | Enumerable) #

[View source]
def add(b : Number) #

[View source]
def add!(b : Tensor | Enumerable) #

[View source]
def add!(b : Number) #

[View source]
def all(axis : Int, dims : Bool = false) #

Reduces a Tensor along an axis, asserting the truthiness of all values in each view into the Tensor

Arguments

a : Tensor | Enumerable Argument to reduce axis : Int Axis of reduction dims : Bool Indicate if the axis of reduction should remain in the result

Examples

a = Tensor.new([2, 2]) { |i| i }
Num.all(a, 0) # => [false, true]
Num.all(a, 1, dims: true)
# [[false],
#  [ true]]

[View source]
def all #

Reduces a Tensor to a boolean by asserting the truthiness of all elements

Arguments

a : Tensor | Enumerable Argument to reduce

Examples

a = [0, 2, 3]
Num.all(a) # => false

[View source]
def any(axis : Int, dims : Bool = false) #

Reduces a Tensor along an axis, asserting the truthiness of any values in each view into the Tensor

Arguments

a : Tensor | Enumerable Argument to reduce axis : Int Axis of reduction dims : Bool Indicate if the axis of reduction should remain in the result

Examples

a = Tensor.new([2, 2]) { |i| i }
Num.any(a, 0) # => [true, true]
Num.any(a, 1, dims: true)
# [[true],
#  [ true]]

[View source]
def any #

Reduces a Tensor to a boolean by asserting the truthiness of any element

Arguments

a : Tensor | Enumerable Argument to reduce

Examples

a = [0, 2, 3]
Num.any(a) # => true

[View source]
def as_shape(shape : Array(Int)) : Tensor(T) #

Broadcasts a Tensor to a new shape. Returns a read-only view of the original Tensor. Many elements in the Tensor will refer to the same memory location, and the result is rarely contiguous.

Shapes must be broadcastable, and an error will be raised if broadcasting fails.

Arguments

shape : Array(Int) The shape of the desired output Tensor

Examples

a = Tensor.from_array [1, 2, 3]
a.broadcast_to([3, 3])

# [[1, 2, 3],
#  [1, 2, 3],
#  [1, 2, 3]]

[View source]
def as_strided(shape : Array(Int), strides : Array(Int)) : Tensor(T) #

#as_strided creates a view into the Tensor given the exact strides and shape. This means it manipulates the internal data structure of a Tensor and, if done incorrectly, the array elements can point to invalid memory and can corrupt results or crash your program.

It is advisable to always use the original #strides when calculating new strides to avoid reliance on a contiguous memory layout.

Furthermore, Tensors created with this function often contain self overlapping memory, so that two elements are identical. Vectorized write operations on such Tensors will typically be unpredictable. They may even give different results for small, large, or transposed Tensors.

Arguments

shape Shape of the new Tensor strides Strides of the new Tensor

Examples

a = Tensor.from_array [1, 2, 3]
a.as_strided([3, 3], [0, 1])

# [[1, 2, 3],
#  [1, 2, 3],
#  [1, 2, 3]]

[View source]
def as_type(u : U.class) : Tensor(U) forall U #

Casts a Tensor to a new dtype, by making a copy. Information may be lost when converting between data types, for example Float to Int or Int to Bool.

Arguments

u : U.class Data type the Tensor will be cast to

Examples

a = Tensor.from_array [1.5, 2.5, 3.5]

a.astype(Int32)   # => [1, 2, 3]
a.astype(Bool)    # => [true, true, true]
a.astype(Float32) # => [1.5, 2.5, 3.5]

[View source]
def asin #

[View source]
def asin! #

[View source]
def asinh #

[View source]
def asinh! #

[View source]
def atan #

[View source]
def atan! #

[View source]
def atan2(b : Tensor | Enumerable) #

[View source]
def atan2(b : Number) #

[View source]
def atan2!(b : Number) #

[View source]
def atanh #

[View source]
def atanh! #

[View source]
def besselj(b : Tensor | Enumerable) #

[View source]
def besselj(b : Number) #

[View source]
def besselj!(b : Number) #

[View source]
def besselj0 #

[View source]
def besselj0! #

[View source]
def besselj1 #

[View source]
def besselj1! #

[View source]
def bessely(b : Tensor | Enumerable) #

[View source]
def bessely(b : Number) #

[View source]
def bessely!(b : Number) #

[View source]
def bessely0 #

[View source]
def bessely0! #

[View source]
def bessely1 #

[View source]
def bessely1! #

[View source]
def bitwise_and(b : Tensor | Enumerable) #

[View source]
def bitwise_and(b : Number) #

[View source]
def bitwise_and!(b : Tensor | Enumerable) #

[View source]
def bitwise_and!(b : Number) #

[View source]
def bitwise_or(b : Tensor | Enumerable) #

[View source]
def bitwise_or(b : Number) #

[View source]
def bitwise_or!(b : Tensor | Enumerable) #

[View source]
def bitwise_or!(b : Number) #

[View source]
def bitwise_xor(b : Tensor | Enumerable) #

[View source]
def bitwise_xor(b : Number) #

[View source]
def bitwise_xor!(b : Tensor | Enumerable) #

[View source]
def bitwise_xor!(b : Number) #

[View source]
def cbrt #

[View source]
def cbrt! #

[View source]
def cholesky(*, lower = true) #

Cholesky decomposition.

Return the Cholesky decomposition, L * L.H, of the square matrix a, where L is lower-triangular and .H is the conjugate transpose operator (which is the ordinary transpose if a is real-valued). a must be Hermitian (symmetric if real-valued) and positive-definite. Only L is actually returned.

Arguments

lower Triangular of decomposition to return

Examples

t = [[2, -1, 0], [-1, 2, -1], [0, -1, 2]].to_tensor.astype(Float32)
t.cholesky

# [[ 1.414,    0.0,    0.0],
#  [-0.707,  1.225,    0.0],
#  [   0.0, -0.816,  1.155]]

[View source]
def cholesky!(*, lower = true) #

Cholesky decomposition.

Return the Cholesky decomposition, L * L.H, of the square matrix a, where L is lower-triangular and .H is the conjugate transpose operator (which is the ordinary transpose if a is real-valued). a must be Hermitian (symmetric if real-valued) and positive-definite. Only L is actually returned.

Arguments

lower Triangular of decomposition to return

Examples

t = [[2, -1, 0], [-1, 2, -1], [0, -1, 2]].to_tensor.astype(Float32)
t.cholesky

# [[ 1.414,    0.0,    0.0],
#  [-0.707,  1.225,    0.0],
#  [   0.0, -0.816,  1.155]]

[View source]
def copysign(b : Tensor | Enumerable) #

[View source]
def copysign(b : Number) #

[View source]
def copysign!(b : Number) #

[View source]
def cos #

[View source]
def cos! #

[View source]
def cosh #

[View source]
def cosh! #

[View source]
def cumsum(axis : Int) #

Accumulate's a Tensor along an axis, summing each view into the Tensor

Arguments

a : Tensor | Enumerable Argument to sum axis : Int Axis of summation

Examples

a = Tensor.new([3, 3, 2]) { |i| i }
Num.cumsum(a, 0)

# [[[ 0,  1],
#   [ 2,  3],
#   [ 4,  5]],
#
#  [[ 6,  8],
#   [10, 12],
#   [14, 16]],
#
#  [[18, 21],
#   [24, 27],
#   [30, 33]]]

[View source]
def cumsum #

Accumulate a Tensor as though it is flat. Returning a one dimensional result.

Arguments

a : Tensor | Enumerable Tensor to accumulate. Will be treated as one-dimensional

Examples

a = [1, 2, 3]
Num.cumsum(a) # => [1, 3, 6]

[View source]
def det #

Compute the determinant of an array.

Arguments

Examples

t = [[1, 2], [3, 4]].to_tensor.astype(Float32)
puts t.det # => -2.0

[View source]
def diagonal : Tensor(T) #

Returns a view of the diagonal of a Tensor. This method only works for two-dimensional arrays.

TODO Implement views for offset diagonals

Arguments

Examples

a = Tensor.new(3, 3) { |i, _| i }
a.diagonal # => [0, 1, 2]

[View source]
def divide(b : Tensor | Enumerable) #

[View source]
def divide(b : Number) #

[View source]
def divide!(b : Tensor | Enumerable) #

[View source]
def divide!(b : Number) #

[View source]
def dot(u : Tensor(T)) #

DOT forms the dot product of two vectors. Uses unrolled loops for increments equal to one.

Arguments

u : Tensor Right hand side of the dot product

Examples

a = [1, 2, 3, 4, 5].to_tensor
a.dot(a) # => 55.0

[View source]
def dup(order : Num::OrderType | Nil = nil) : Tensor(T) #

Deep-copies a Tensor. If an order is provided, the returned Tensor's memory layout will respect that order.

If no order is provided, the Tensor will retain it's same memory layout.

Arguments

order : Num::OrderType? Memory layout to use for the returned Tensor

Examples

a = Tensor.from_array [1, 2, 3]
a.dup # => [1, 2, 3]

[View source]
def each(&) #

Yields the elements of a Tensor, always in RowMajor order, as if the Tensor was flat.

Arguments

Examples

a = Tensor.new(2, 2) { |i| i }
a.each do |el|
  puts el
end

# 0
# 1
# 2
# 3

[View source]
def each_axis(axis : Int = -1, dims : Bool = false, &) #

Yields each view along the axis of a Tensor. Useful for reductions and accumulation operations along an axis.

The Tensor' yielded is a view, and changes made will be reflected in the parent Tensor

Arguments

axis : Int The axis to view dims : Bool If true, sets the axis shape to 1 for the axis view. Otherwise removes the axis when returning views

Examples

a = Tensor.new([2, 2]) { |i| i }
a.each_axis(1) do |m|
  puts m
end

# [0, 2]
# [1, 3]

a.each_axis(0, dims: true) do |m|
  puts m
end

# [[0, 1]]
# [[2, 3]]

[View source]
def each_matrix(&) #

Yields matrices along the final two dimensions of a Tensor. Useful for methods that operate on matrices in order to map them across a deeply nested Tensor. The matrices yielded are views into the Tensor

This method only can be called on Tensor's with 3 or more dimensions

Arguments

Examples

a = Tensor.new([3, 2, 2]) { |i| i }
a.each_matrix do |m|
  puts m
end

# [[0, 1],
#  [2, 3]]
# [[4, 5],
#  [6, 7]]
# [[ 8,  9],
#  [10, 11]]

[View source]
def each_pointer(&) #

Yields the memory locations of each element of a Tensor, always in RowMajor oder, as if the Tensor was flat.

This should primarily be used by internal methods. Methods such as #map! provided more convenient access to editing the values of a Tensor

Arguments

Examples

a = Tensor.new(2, 2) { |i| i }
a.each_pointer do |el|
  puts el.value
end

# 0
# 1
# 2
# 3

[View source]
def each_pointer_with_index(&) #

Yields the memory locations of each element of a Tensor, always in RowMajor oder, as if the Tensor was flat. Also yields the flat index of a Tensor

This should primarily be used by internal methods. Methods such as #map! provided more convenient access to editing the values of a Tensor

Arguments

Examples

a = Tensor.new(2, 2) { |i| i }
a.each_pointer_with_index do |el, i|
  puts "#{el.value}_#{i}"
end

# 0_0
# 1_1
# 2_2
# 3_3

[View source]
def each_with_index(&) #

Yields the elements of a Tensor, always in RowMajor order, as if the Tensor was flat. Also yields the flat index of each element.

Arguments

Examples

a = Tensor.new(2, 2) { |i| i }
a.each_with_index do |el, i|
  puts "#{el}_#{i}"
end

# 0_0
# 1_1
# 2_2
# 3_3

[View source]
def eig #

Compute the eigenvalues and right eigenvectors of a square array.

Arguments

Examples

t = [[0, 1], [1, 1]].to_tensor.as_type(Float32)
w, v = t.eig
puts w
puts v

# [-0.618034, 1.61803  ]
# [[-0.850651, 0.525731 ],
#  [-0.525731, -0.850651]]

[View source]
def eigh #

Compute the eigenvalues and right eigenvectors of a square Tensor.

Arguments

Examples

t = [[0, 1], [1, 1]].to_tensor.as_type(Float32)
w, v = t.eigh
puts w
puts v

# [-0.618034, 1.61803  ]
# [[-0.850651, 0.525731 ],
#  [0.525731 , 0.850651 ]]

[View source]
def eigvals #

Compute the eigenvalues of a general matrix.

Main difference between eigvals and eig: the eigenvectors aren’t returned.

Arguments

Examples

t = [[0, 1], [1, 1]].to_tensor.as_type(Float32)
puts t.eigvals

# [-0.618034, 1.61803  ]

[View source]
def eigvalsh #

Compute the eigenvalues of a general matrix.

Main difference between eigvals and eig: the eigenvectors aren’t returned.

Arguments

Examples

t = [[0, 1], [1, 1]].to_tensor.as_type(Float32)
puts t.eigvalsh

# [-0.618034, 1.61803  ]

[View source]
def equal(b : Tensor | Enumerable) #

[View source]
def equal(b : Number) #

[View source]
def equal!(b : Tensor | Enumerable) #

[View source]
def equal!(b : Number) #

[View source]
def erf #

[View source]
def erf! #

[View source]
def erfc #

[View source]
def erfc! #

[View source]
def exp #

[View source]
def exp! #

[View source]
def exp2 #

[View source]
def exp2! #

[View source]
def expm1 #

[View source]
def expm1! #

[View source]
def flags : Num::ArrayFlags #

[View source]
def flags=(flags : Num::ArrayFlags) #

[View source]
def flat : Tensor(T) #

Flattens a Tensor to a single dimension. If a view can be created, the reshape operation will not copy data.

Arguments

Examples

a = Tensor.new([2, 2]) { |i| i }
a.flat # => [0, 1, 2, 3]

[View source]
def floordiv(b : Tensor | Enumerable) #

[View source]
def floordiv(b : Number) #

[View source]
def floordiv!(b : Tensor | Enumerable) #

[View source]
def floordiv!(b : Number) #

[View source]
def gamma #

[View source]
def gamma! #

[View source]
def greater(b : Tensor | Enumerable) #

[View source]
def greater(b : Number) #

[View source]
def greater!(b : Tensor | Enumerable) #

[View source]
def greater!(b : Number) #

[View source]
def greater_equal(b : Tensor | Enumerable) #

[View source]
def greater_equal(b : Number) #

[View source]
def greater_equal!(b : Tensor | Enumerable) #

[View source]
def greater_equal!(b : Number) #

[View source]
def hessenberg #

Compute Hessenberg form of a matrix.

The Hessenberg decomposition is:

A = Q H Q^H

where Q is unitary/orthogonal and H has only zero elements below the first sub-diagonal.

Arguments

Examples

a = [[2, 5, 8, 7],
     [5, 2, 2, 8],
     [7, 5, 6, 6],
     [5, 4, 4, 8]].to_tensor.as_type(Float64)

puts a.hessenberg

# [[2       , -11.6584, 1.42005 , 0.253491],
#  [-9.94987, 14.5354 , -5.31022, 2.43082 ],
#  [0       , -1.83299, 0.3897  , -0.51527],
#  [0       , 0       , -3.8319 , 1.07495 ]]

[View source]
def hypot(b : Tensor | Enumerable) #

[View source]
def hypot(b : Number) #

[View source]
def hypot!(b : Number) #

[View source]
def ilogb #

[View source]
def ilogb! #

[View source]
def inv #

Compute the (multiplicative) inverse of a matrix.

Given a square matrix a, return the matrix ainv satisfying dot(a, ainv) = dot(ainv, a) = eye(a.shape[0])

Arguments

Examples

t = [[1, 2], [3, 4]].to_tensor.as_type(Float32)
puts t.inv

# [[-2  , 1   ],
#  [1.5 , -0.5]]

[View source]
def ldexp(b : Tensor | Enumerable) #

[View source]
def ldexp(b : Number) #

[View source]
def ldexp!(b : Number) #

[View source]
def left_shift(b : Tensor | Enumerable) #

[View source]
def left_shift(b : Number) #

[View source]
def left_shift!(b : Tensor | Enumerable) #

[View source]
def left_shift!(b : Number) #

[View source]
def less(b : Tensor | Enumerable) #

[View source]
def less(b : Number) #

[View source]
def less!(b : Tensor | Enumerable) #

[View source]
def less!(b : Number) #

[View source]
def less_equal(b : Tensor | Enumerable) #

[View source]
def less_equal(b : Number) #

[View source]
def less_equal!(b : Tensor | Enumerable) #

[View source]
def less_equal!(b : Number) #

[View source]
def lgamma #

[View source]
def lgamma! #

[View source]
def log #

[View source]
def log! #

[View source]
def log10 #

[View source]
def log10! #

[View source]
def log1p #

[View source]
def log1p! #

[View source]
def log2 #

[View source]
def log2! #

[View source]
def logb #

[View source]
def logb! #

[View source]
def map(t : Tensor(U), v : Tensor(V), &block : T, U, V -> W) : Tensor(W) forall U, V, W #

Maps a block across three Tensors. This is more efficient than zipping iterators since it iterates all Tensor's in a single call, avoiding overhead from tracking multiple iterators.

The generic type of the returned Tensor is inferred from a block

Arguments

t : Tensor(U) The second Tensor for iteration. Must be broadcastable against the #shape of self and v *v) : Tensor(V) The third Tensor for iteration. Must be broadcastable against the #shape of self and t block : Proc(T, U, V, W) The block to map across all Tensors

Examples

a = Tensor.new([3]) { |i| i }
b = Tensor.new([3]) { |i| i }
c = Tensor.new([3]) { |i| i }

a.map(b, c) { |i, j, k| i + j + k } # => [0, 3, 6]

[View source]
def map(t : Tensor(U), &block : T, U -> V) : Tensor(V) forall U, V #

Maps a block across two Tensors. This is more efficient than zipping iterators since it iterates both Tensor's in a single call, avoiding overhead from tracking multiple iterators.

The generic type of the returned Tensor is inferred from a block

Arguments

t : Tensor(U) The second Tensor for iteration. Must be broadcastable against the #shape of self block : Proc(T, U, V) The block to map across both Tensors

Examples

a = Tensor.new([3]) { |i| i }
b = Tensor.new([3]) { |i| i }

a.map(b) { |i, j| i + j } # => [0, 2, 4]

[View source]
def map(&block : T -> U) : Tensor(U) forall U #

Maps a block across a Tensor. The Tensor is treated as flat during iteration, and iteration is always done in RowMajor order

The generic type of the returned Tensor is inferred from the block

Arguments

block Proc(T, U) Proc to map across the Tensor

Examples

a = Tensor.new([3]) { |i| i }
a.map { |e| e + 5 } # => [5, 6, 7]

[View source]
def map!(t : Tensor, &) #

Maps a block across two Tensors. This is more efficient than zipping iterators since it iterates both Tensor's in a single call, avoiding overhead from tracking multiple iterators. The result of the block is stored in self.

Broadcasting rules still apply, but since this is an in place operation, the other Tensor must broadcast to the shape of self

Arguments

t : Tensor(U) The second Tensor for iteration. Must be broadcastable against the #shape of self block : Proc(T, U, T) The block to map across both Tensors

Examples

a = Tensor.new([3]) { |i| i }
b = Tensor.new([3]) { |i| i }

a.map!(b) { |i, j| i + j }
a # => [0, 2, 4]

[View source]
def map!(&) #

Maps a block across a Tensor in place. The Tensor is treated as flat during iteration, and iteration is always done in RowMajor order

Arguments

block Proc(T, U) Proc to map across the Tensor

Examples

a = Tensor.new([3]) { |i| i }
a.map! { |e| e + 5 }
a # => [5, 6, 7]

[View source]
def map!(t : Tensor, v : Tensor) #

Maps a block across three Tensors. This is more efficient than zipping iterators since it iterates all Tensor's in a single call, avoiding overhead from tracking multiple iterators. The result of the block is stored in self.

Broadcasting rules still apply, but since this is an in place operation, the other Tensor's must broadcast to the shape of self

Arguments

t : Tensor(U) The second Tensor for iteration. Must be broadcastable against the #shape of self and v *v) : Tensor(V) The third Tensor for iteration. Must be broadcastable against the #shape of self and t block : Proc(T, U, V, W) The block to map across all Tensors

Examples

a = Tensor.new([3]) { |i| i }
b = Tensor.new([3]) { |i| i }
c = Tensor.new([3]) { |i| i }

a.map!(b, c) { |i, j, k| i + j + k }
a # => [0, 3, 6]

[View source]
def matmul(other : Tensor(T)) #

Computes a matrix multiplication between two Tensors. The Tensors must be two dimensional with compatible shapes. Currently only Float and Complex Tensors are supported, as BLAS is used for this operation

Arguments

other : Tensor(T) The right hand side of the operation

Examples

Num::Rand.set_seed(0)
a = Tensor.random(0.0...10.0, [3, 3])
a.matmul(a)

# [[28.2001, 87.4285, 30.5423],
#  [12.4381, 30.9552, 26.2495],
#  [34.0873, 73.5366, 40.5504]]

[View source]
def max(b : Tensor | Enumerable) #

[View source]
def max(axis : Int, dims : Bool = false) #

Reduces a Tensor along an axis, finding the max of each view into the Tensor

Arguments

a : Tensor | Enumerable Argument to reduce axis : Int Axis of reduction dims : Bool Indicate if the axis of reduction should remain in the result

Examples

a = Tensor.new([2, 2]) { |i| i }
Num.max(a, 0) # => [2, 3]
Num.max(a, 1, dims: true)
# [[1],
#  [3]]

[View source]
def max(b : Number) #

[View source]
def max #

Reduces a Tensor to a scalar by finding the maximum value

Arguments

a : Tensor | Enumerable Argument to reduce

Examples

a = [1, 2, 3]
Num.max(a) # => 3

[View source]
def max!(b : Number) #

[View source]
def mean(axis : Int, dims : Bool = false) #

Reduces a Tensor along an axis, finding the average of each view into the Tensor

Arguments

a : Tensor | Enumerable Argument to reduce axis : Int Axis of reduction dims : Bool Indicate if the axis of reduction should remain in the result

Examples

a = Tensor.new([2, 2]) { |i| i }
Num.mean(a, 0) # => [1, 2]
Num.mean(a, 1, dims: true)
# [[0],
#  [2]]

[View source]
def mean #

Reduces a Tensor to a scalar by finding the average

Arguments

a : Tensor | Enumerable Argument to reduce

Examples

a = [1, 2, 3]
Num.mean(a) # => 2.0

[View source]
def min(b : Tensor | Enumerable) #

[View source]
def min(axis : Int, dims : Bool = false) #

Reduces a Tensor along an axis, finding the min of each view into the Tensor

Arguments

a : Tensor | Enumerable Argument to reduce axis : Int Axis of reduction dims : Bool Indicate if the axis of reduction should remain in the result

Examples

a = Tensor.new([2, 2]) { |i| i }
Num.min(a, 0) # => [0, 1]
Num.min(a, 1, dims: true)
# [[0],
#  [2]]

[View source]
def min(b : Number) #

[View source]
def min #

Reduces a Tensor to a scalar by finding the minimum value

Arguments

a : Tensor | Enumerable Argument to reduce

Examples

a = [1, 2, 3]
Num.min(a) # => 3

[View source]
def min!(b : Number) #

[View source]
def modulo(b : Tensor | Enumerable) #

[View source]
def modulo(b : Number) #

[View source]
def modulo!(b : Tensor | Enumerable) #

[View source]
def modulo!(b : Number) #

[View source]
def multiply(b : Tensor | Enumerable) #

[View source]
def multiply(b : Number) #

[View source]
def multiply!(b : Tensor | Enumerable) #

[View source]
def multiply!(b : Number) #

[View source]
def norm(*, order = 'F') #

Matrix norm

This function is able to return one of eight different matrix norms

Arguments

order : String Type of norm

Examples

t = [[0, 1], [1, 1], [1, 1], [2, 1]].to_tensor.as_type(Float32)
t.norm # => 3.6055512

[View source]
def not_equal(b : Tensor | Enumerable) #

[View source]
def not_equal(b : Number) #

[View source]
def not_equal!(b : Tensor | Enumerable) #

[View source]
def not_equal!(b : Number) #

[View source]
def opencl #

Move a Tensor from CPU backed storage to an OpenCL buffer. This will make a copy of the CPU Tensor if it is not C-style contiguous.

Arguments

Examples

a = [1, 2, 3].to_tensor
acl = a.opencl

[View source]
def power(b : Tensor | Enumerable) #

[View source]
def power(b : Number) #

[View source]
def power!(b : Tensor | Enumerable) #

[View source]
def power!(b : Number) #

[View source]
def prod(axis : Int, dims : Bool = false) #

Reduces a Tensor along an axis, multiplying each view into the Tensor

Arguments

a : Tensor | Enumerable Argument to reduce axis : Int Axis of reduction dims : Bool Indicate if the axis of reduction should remain in the result

Examples

a = Tensor.new([2, 2]) { |i| i }
Num.prod(a, 0) # => [0, 3]
Num.prod(a, 1, dims: true)
# [[0],
#  [6]]

[View source]
def prod #

Reduces a Tensor to a scalar by multiplying all of its elements

Arguments

a : Tensor | Enumerable Argument to reduce

Examples

a = [1, 2, 3]
Num.prod(a) # => 6

[View source]
def ptp(axis : Int, dims : Bool = false) #

Finds the difference between the maximum and minimum elements of a Tensor along an axis

Arguments

a : Tensor Argument to reduce axis : Tensor Axis of reduction dims : Bool Keep axis of reduction in output

Examples

a = [[3, 4], [1, 2], [6, 2]]
Num.ptp(a, 1) # [1, 1, 4]

[View source]
def ptp #

Finds the difference between the maximum and minimum elements of a Tensor

Arguments

a : Tensor to find peak to peak value

Examples

a = [1, 2, 3]
Num.ptp(a) # => 2

[View source]
def qr #

Compute the qr factorization of a matrix.

Factor the matrix a as qr, where q is orthonormal and r is upper-triangular.

Arguments

Examples

t = [[0, 1], [1, 1], [1, 1], [2, 1]].to_tensor.as_type(Float32)
q, r = t.qr
puts q
puts r

# [[   0.0,  0.866],
#  [-0.408,  0.289],
#  [-0.408,  0.289],
#  [-0.816, -0.289]]
# [[-2.449, -1.633],
#  [   0.0,  1.155],
#  [   0.0,    0.0],
#  [   0.0,    0.0]]

[View source]
def reshape(new_shape : Array(Int)) #

Transform's a Tensor's shape. If a view can be created, the reshape will not copy data. The number of elements in the Tensor must remain the same.

Arguments

result_shape : Array(Int) Result shape for the Tensor

Examples

a = Tensor.from_array [1, 2, 3, 4]
a.reshape([2, 2])

# [[1, 2],
#  [3, 4]]

[View source]
def reshape(*args : Int) #

Transform's a Tensor's shape. If a view can be created, the reshape will not copy data. The number of elements in the Tensor must remain the same.

Arguments

result_shape : Array(Int) Result shape for the Tensor

Examples

a = Tensor.from_array [1, 2, 3, 4]
a.reshape([2, 2])

# [[1, 2],
#  [3, 4]]

[View source]
def right_shift(b : Tensor | Enumerable) #

[View source]
def right_shift(b : Number) #

[View source]
def right_shift!(b : Tensor | Enumerable) #

[View source]
def right_shift!(b : Number) #

[View source]
def shape : Array(Int32) #

[View source]
def sin #

[View source]
def sin! #

[View source]
def sinh #

[View source]
def sinh! #

[View source]
def size : Int32 #

[View source]
def solve(x : Tensor(T)) #

Solve a linear matrix equation, or system of linear scalar equations.

Computes the “exact” solution, x, of the well-determined, i.e., full rank, linear matrix equation ax = b.

Arguments

x : Tensor Argument with which to solve

Examples

a = [[3, 1], [1, 2]].to_tensor.astype(Float32)
b = [9, 8].to_tensor.astype(Float32)
puts a.solve(b)

# [2, 3]

[View source]
def sqrt #

[View source]
def sqrt! #

[View source]
def std(axis : Int, dims : Bool = false) #

Reduces a Tensor along an axis, finding the std of each view into the Tensor

Arguments

a : Tensor | Enumerable Argument to reduce axis : Int Axis of reduction dims : Bool Indicate if the axis of reduction should remain in the result

Examples

a = Tensor.new([2, 2]) { |i| i }
Num.std(a, 0) # => [1, 1]
Num.std(a, 1, dims: true)
# [[0.707107],
#  [0.707107]]

[View source]
def std #

Reduces a Tensor to a scalar by finding the standard deviation

Arguments

a : Tensor | Enumerable Argument to reduce

Examples

a = [1, 2, 3]
Num.std(a) # => 0.816496580927726

[View source]
def strides : Array(Int32) #

[View source]
def subtract(b : Tensor | Enumerable) #

[View source]
def subtract(b : Number) #

[View source]
def subtract!(b : Tensor | Enumerable) #

[View source]
def subtract!(b : Number) #

[View source]
def sum(axis : Int, dims : Bool = false) #

Reduces a Tensor along an axis, summing each view into the Tensor

Arguments

a : Tensor | Enumerable Argument to sum axis : Int Axis of summation dims : Bool Indicate if the axis of reduction should remain in the result

Examples

a = Tensor.new([2, 2]) { |i| i }
Num.sum(a, 0) # => [2, 4]
Num.sum(a, 1, dims: true)
# [[1],
#  [5]]

[View source]
def sum #

Reduces a Tensor to a scalar by summing all of its elements

Arguments

a : Tensor | Enumerable Argument to sum

Examples

a = [1, 2, 3]
Num.sum(a) # => 6

[View source]
def svd #

Singular Value Decomposition.

When a is a 2D array, it is factorized as u @ np.diag(s) @ vh = (u * s) @ vh, where u and vh are 2D unitary arrays and s is a 1D array of a’s singular values.

Arguments

Examples

t = [[0, 1], [1, 1], [1, 1], [2, 1]].to_tensor.as_type(Float32)
a, b, c = t.svd
puts a
puts b
puts c

# [[-0.203749, 0.841716 , -0.330613, 0.375094 ],
#  [-0.464705, 0.184524 , -0.19985 , -0.842651],
#  [-0.464705, 0.184524 , 0.861075 , 0.092463 ],
#  [-0.725662, -0.472668, -0.330613, 0.375094 ]]
# [3.02045 , 0.936426]
# [[-0.788205, -0.615412],
#  [-0.615412, 0.788205 ]]

[View source]
def swap_axes(a : Int, b : Int) : Tensor(T) #

Permutes two axes of a Tensor. This will always create a view of the permuted Tensor

Arguments

a : Int First axis of permutation b : Int Second axis of permutation

Examples

a = Tensor.new([4, 3, 2]) { |i| i }
a.swap_axes(2, 0)

# [[[ 0,  6, 12, 18]
#   [ 2,  8, 14, 20]
#   [ 4, 10, 16, 22]]
#
#  [[ 1,  7, 13, 19]
#   [ 3,  9, 15, 21]
#   [ 5, 11, 17, 23]]]

[View source]
def tan #

[View source]
def tan! #

[View source]
def tanh #

[View source]
def tanh! #

[View source]
def tensordot(b : Tensor(T), axes : Array(Array(Int))) #

Compute tensor dot product along specified axes.

Given two tensors, a and b, and an array_like object containing two array_like objects, (a_axes, b_axes), sum the products of a’s and b’s elements (components) over the axes specified by a_axes and b_axes. The third argument can be a single non-negative integer_like scalar, N; if it is such, then the last N dimensions of a and the first N dimensions of b are summed over.

Arguments

b : Tensor Right hand side of dot products axes : Array(Array(Int)) | Array(Int) | Int Axes of summation

Examples

a = Tensor.range(60.0).reshape(3, 4, 5)
b = Tensor.range(24.0).reshape(4, 3, 2)
puts a.tensordot(b, axes: [[1, 0], [0, 1]])

# [[4400, 4730],
#  [4532, 4874],
#  [4664, 5018],
#  [4796, 5162],
#  [4928, 5306]]

[View source]
def tensordot(b : Tensor(T), axes : Int) #

Compute tensor dot product along specified axes.

Given two tensors, a and b, and an array_like object containing two array_like objects, (a_axes, b_axes), sum the products of a’s and b’s elements (components) over the axes specified by a_axes and b_axes. The third argument can be a single non-negative integer_like scalar, N; if it is such, then the last N dimensions of a and the first N dimensions of b are summed over.

Arguments

b : Tensor Right hand side of dot products axes : Array(Array(Int)) | Array(Int) | Int Axes of summation

Examples

a = Tensor.range(60.0).reshape(3, 4, 5)
b = Tensor.range(24.0).reshape(4, 3, 2)
puts a.tensordot(b, axes: [[1, 0], [0, 1]])

# [[4400, 4730],
#  [4532, 4874],
#  [4664, 5018],
#  [4796, 5162],
#  [4928, 5306]]

[View source]
def tensordot(b : Tensor(T), axes : Array(Int)) #

Compute tensor dot product along specified axes.

Given two tensors, a and b, and an array_like object containing two array_like objects, (a_axes, b_axes), sum the products of a’s and b’s elements (components) over the axes specified by a_axes and b_axes. The third argument can be a single non-negative integer_like scalar, N; if it is such, then the last N dimensions of a and the first N dimensions of b are summed over.

Arguments

b : Tensor Right hand side of dot products axes : Array(Array(Int)) | Array(Int) | Int Axes of summation

Examples

a = Tensor.range(60.0).reshape(3, 4, 5)
b = Tensor.range(24.0).reshape(4, 3, 2)
puts a.tensordot(b, axes: [[1, 0], [0, 1]])

# [[4400, 4730],
#  [4532, 4874],
#  [4664, 5018],
#  [4796, 5162],
#  [4928, 5306]]

[View source]
def to_a : Array(T) #

Converts a Tensor to a standard library array. The returned array will always be one-dimensional to avoid return type ambiguity

Arguments

Examples

a = Tensor.new([2, 2]) { |i| i }
a.to_a # => [0, 1, 2, 3]

[View source]
def to_json(b : JSON::Builder) : String #

Converts a Tensor to a JSON String. The returned JSON array will always be one-dimensional

Arguments

Examples

a = Tensor.new([2, 2]) { |i| i }
a.to_json # => "[0, 1, 2, 3]"

[View source]
def transpose(axes : Array(Int) = [] of Int32) #

Permutes a Tensor's axes to a different order. This will always create a view of the permuted Tensor.

Arguments

axes : Array(Int) New ordering of axes for the permuted Tensor. If empty, a full transpose will occur

Examples

a = Tensor.new([4, 3, 2]) { |i| i }
a.transpose([2, 0, 1])

# [[[ 0,  2,  4],
#   [ 6,  8, 10],
#   [12, 14, 16],
#   [18, 20, 22]],
#
#  [[ 1,  3,  5],
#   [ 7,  9, 11],
#   [13, 15, 17],
#   [19, 21, 23]]]

[View source]
def transpose(*args : Int) #

Permutes a Tensor's axes to a different order. This will always create a view of the permuted Tensor.

Arguments

axes : Array(Int) New ordering of axes for the permuted Tensor. If empty, a full transpose will occur

Examples

a = Tensor.new([4, 3, 2]) { |i| i }
a.transpose([2, 0, 1])

# [[[ 0,  2,  4],
#   [ 6,  8, 10],
#   [12, 14, 16],
#   [18, 20, 22]],
#
#  [[ 1,  3,  5],
#   [ 7,  9, 11],
#   [13, 15, 17],
#   [19, 21, 23]]]

[View source]
def tril(k : Int = 0) #

Computes the lower triangle of a Tensor. Zeros out values above the kth diagonal

Arguments

k : Int Diagonal

Examples

a = Tensor(Int32).ones([3, 3])
a.tril!
a

# [[1, 0, 0],
#  [1, 1, 0],
#  [1, 1, 1]]

[View source]
def tril!(k : Int = 0) #

Computes the lower triangle of a Tensor. Zeros out values above the kth diagonal

Arguments

k : Int Diagonal

Examples

a = Tensor(Int32).ones([3, 3])
a.tril!
a

# [[1, 0, 0],
#  [1, 1, 0],
#  [1, 1, 1]]

[View source]
def triu(k : Int = 0) #

Computes the upper triangle of a Tensor. Zeros out values below the kth diagonal

Arguments

k : Int Diagonal

Examples

a = Tensor(Int32).ones([3, 3])
a.triu!
a

# [[1, 1, 1],
#  [0, 1, 1],
#  [0, 0, 1]]

[View source]
def triu!(k : Int = 0) #

Computes the upper triangle of a Tensor. Zeros out values below the kth diagonal

Arguments

k : Int Diagonal

Examples

a = Tensor(Int32).ones([3, 3])
a.triu!
a

# [[1, 1, 1],
#  [0, 1, 1],
#  [0, 0, 1]]

[View source]
def unique #

[View source]
def unsafe_axis_iter(axis : Int, dims : Bool = false) #

[View source]
def value_counts #

[View source]
def view : Tensor(T) #

Return a shallow copy of a Tensor. The underlying data buffer is shared, but the Tensor owns its other attributes. Changes to a view of a Tensor will be reflected in the original Tensor

Arguments

Examples

a = Tensor(Int32).new([3, 3])
b = a.view
b[...] = 99
a

# [[99, 99, 99],
#  [99, 99, 99],
#  [99, 99, 99]]

[View source]
def view_as_type(u : U.class) forall U #

Return a shallow copy of a Tensor with a new dtype. The underlying data buffer is shared, but the Tensor owns its other attributes. The size of the new dtype must be a multiple of the current dtype

Arguments

u : U.class The data type used to reintepret the underlying data buffer of a Tensor

Examples

a = Tensor.new([3]) { |i| i }
a.view(Int16) # => [0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0]

[View source]
def with_broadcast(n : Int) : Tensor(T) #

Expands a Tensors dimensions n times by broadcasting the shape and strides. No data is copied, and the result is a read-only view of the original Tensor

Arguments

n : Int Number of dimensions to broadcast

Examples

a = [1, 2, 3].to_tensor
a.with_broadcast(2)

# [[[1]],
#
#  [[2]],
#
#  [[3]]]

[View source]
def with_dims(n : Int) : Tensor(T) #

Add dimensions to a Tensor so that it has at least n dimensions. Zero element Tensors cannot be expanded using this method. If a Tensor has more than n dimensions it will not be modified

Arguments

n: Int Minimum number of dimensions for the Tensor

Examples

a = [1, 2, 3].to_tensor
a.with_dims(4) # => [[[[1, 2, 3]]]]

[View source]

Macro Detail

macro blas(storage, name, *args) #

[View source]
macro blas_call(fn, *args) #

[View source]
macro lapack(name, *args, worksize = nil) #

[View source]
macro lapack_util(name, worksize, *args) #

[View source]