class Tensor(T, S)

Included Modules

Defined in:

io/npy.cr
linalg/extension.cr
linalg/linalg.cr
tensor/allocation.cr
tensor/convert.cr
tensor/data_structure.cr
tensor/index.cr
tensor/iteration.cr
tensor/manipulate.cr
tensor/math.cr
tensor/random.cr
tensor/reduction.cr

Constructors

Class Method Summary

Instance Method Summary

Constructor Detail

def self.new(data : S, shape : Array(Int32), strides : Array(Int32), offset : Int32, flags : Num::ArrayFlags, dtype : T.class = T) #

Initialize a Tensor from a storage instance, a shape, strides, an offset, flags, and a data type. This should primarily be used by internal methods, since it assumes the passed shape and strides correspond to the storage provided.

The dtype is required to infer T without having it explicitly provided


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

Initialize a Tensor from a storage instance, a shape, an order, and a data type. This should primarily be used by internal methods, since it assumes the contiguity of the storage.

The dtype is required to infer T without having it explicitly provided


[View source]
def self.new(data : S, shape : Array(Int32), strides : Array(Int32), offset : Int32, dtype : T.class = T) #

Initialize a Tensor from a storage instance, a shape, strides, an offset, and a data type. This should primarily be used by internal methods, since it assumes the passed shape and strides correspond to the storage provided.

The dtype is required to infer T without having it explicitly provided


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

Initializes a Tensor onto a device with a provided shape and memory layout.

Examples

a = Tensor(Float32).new([3, 3, 2], device: OCL(Float32)) # => GPU Tensor
b = Tensor(Float32).new([2, 3, 4])                       # => CPU Tensor

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

Initializes a Tensor onto a device with a provided shape and memory layout, containing a specified value.

Examples

a = Tensor.new([2, 2], 3.5) # => CPU Tensor filled with 3.5

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

Creates a Tensor from a block onto a specified device. The type of the Tensor is inferred from the return type of the block

Examples

a = Tensor.new([3, 3, 2]) { |i| i } # => Int32 Tensor stored on a CPU

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

Creates a matrix Tensor from a block onto a specified device. The type of the Tensor is inferred from the return type of the block

Examples

a = Tensor.new(3, 3) { |i, j| i / j } # => Float64 Tensor stored on a CPU

[View source]

Class Method Detail

def self.beta(shape : Array(Int), a : Float, b : Float) #

Generates a Tensor containing a beta-distribution collection of values

Arguments

  • shape : Array(Int) - Shape of output Tensor
  • a : Float - Shape parameter of distribution
  • b : Float - Shape parameter of distribution

Examples

Num::Rand.set_seed(0)
a = Tensor(Float32, CPU(Float32)).beta([5], 0.1, 0.5)
puts a # => [0.000463782, 0.40858    , 1.67573e-07, 0.143055, 3.08452e-08]

[View source]
def self.binomial(shape : Array(Int), n : Int, prob : Float) : Tensor(T, S) #

Draw samples from a binomial distribution. Samples are drawn from a binomial distribution with specified parameters, n trials and prob probability of success where n an integer >= 0 and p is in the interval [0,1].

Arguments

  • shape : Array(Int) - Shape of output Tensor
  • n : Int - Number of trials
  • prob : Float - Probability of success on a single trial

Examples

Num::Rand.set_seed(0)
a = Tensor(Float32, CPU(Float32)).binomial([5], 50, 0.5)
puts a # => [23, 30, 22, 18, 28]

[View source]
def self.chisq(shape : Array(Int), df : Float) #

Generates a Tensor containing chi-square distributed values

Arguments

  • shape : Array(Int) - Shape of output Tensor
  • df : Float - Degrees of freedom

Examples

Num::Rand.set_seed(0)
a = Tensor(Float32, CPU(Float32)).chisq([5], 30.0)
puts a # => [32.2738, 27.2351, 26.0258, 22.136 , 31.9774]

[View source]
def self.exp(shape : Array(Int), scale : Float = 1.0) #

Generates a Tensor containing expontentially distributed values

Arguments

  • shape : Array(Int) - Shape of output Tensor
  • scale : Float - Scale of the distribution

Examples

Num::Rand.set_seed(0)
a = Tensor(Float32, CPU(Float32)).exp([5])
puts a # => [0.697832 , 0.710307 , 1.35733  , 0.0423776, 0.209743 ]

[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 returned Tensor
  • n : Int? - Number of columns in the Tensor, defaults to m if nil
  • offset : Int - Indicates which diagonal to fill with ones

Examples

Tensor(Int8, CPU(Int8)).eye(3, offset: -1)

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

Tensor(Int8, CPU(Int8)).eye(2)

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

[View source]
def self.from_array(a : Array, device = CPU) #

Creates a Tensor from a standard library array onto a specified device. The type of Tensor is inferred from the innermost element type, and the Array's shape must be uniform along all subarrays.

Examples

a = [[1, 2], [3, 4], [5, 6]]
Tensor.from_array(a, device: OCL) # => [3, 2] Tensor stored on a GPU

[View source]
def self.from_npy(path : String) : Tensor(T, S) #

Reads a .npy file and returns a Tensor of the specified type. If the ndarray is stored in a different type inside the file, it will be converted.

Arguments

  • path : String - Filename of npy file to load

NOTE Only integer, unsigned integer and float ndarrays are supported at the moment.

NOTE Only little endian files can be read due to laziness by the num.cr developer


[View source]
def self.fsned(shape : Array(Int), df1 : Float, df2 : Float) : Tensor(T, S) #

Generates a Tensor containing f-snedecor distributed values

Arguments

  • shape : Array(Int) - Shape of output Tensor
  • df1 : Float - Degrees of freedom of the underlying chi-square distribution, numerator side; usually mentioned as m.
  • df2 : Float - Degrees of freedom of the underlying chi-square distribution, denominator side; usually mentioned as n.

Examples

Num::Rand.set_seed(0)
a = Tensor(Float32, CPU(Float32)).fsned([5], 30.0, 50.0)
puts a # => [1.15436 , 1.08983 , 0.971573, 1.75811 , 2.06518 ]

[View source]
def self.full(shape : Array(Int), value : Number) : Tensor(T, S) #

Creates a Tensor of a provided shape, filled with a value. The generic type is inferred from the value

Arguments

Examples

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

[View source]
def self.full_like(t : Tensor, value : Number) : Tensor(T, S) #

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

Arguments

Examples

t = Tensor(Int8, CPU(Int8)) &.to_f
u = Tensor(Int8, CPU(Int8)).full_like(t, 3) # => [3, 3, 3]

[View source]
def self.gamma(t_shape : Array(Int), shape : Float, scale : Float = 1.0) : Tensor(T, S) #

Generate a gamma-distributed, pseudo-random Tensor

Arguments

  • t_shape : Array(Int) - Shape of output Tensor
  • shape : Float - shape parameter of the distribution; usually mentioned as k
  • scale : Float - scale parameter of the distribution; usually mentioned as θ

Examples

Num::Rand.set_seed(0)
a = Tensor(Float32, CPU(Float32)).gamma([5], 0.5)
puts a # => [0.169394 , 0.0336937, 0.921517 , 0.0210972, 0.0487926]

[View source]
def self.geometric_space(start : T, stop : T, num : Int = 50, endpoint : Bool = true, device = CPU) #

Return numbers spaced evenly on a log scale (a geometric progression). This is similar to logspace, but with endpoints specified directly. Each output sample is a constant multiple of the previous.

Arguments

  • start : T - Start of interval
  • stop : T - End of interval
  • num : Int - Number of samples
  • endpoint : Bool - Indicates if endpoint should be included in the results
  • device : Num::Storage

Examples

Tensor.geometric_space(1_f32, 1000_f32, 4) # => [1, 10, 100, 1000]

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

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

Arguments

  • n : Int - Number of rows and columns in output

Examples

Tensor(Int8, CPU(Int8)).identity(2)

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

[View source]
def self.laplace(shape : Array(Int), loc : Float = 0.0, scale : Float = 1.0) : Tensor(T, S) #

Generate a laplace-distributed, pseudo-random Tensor

Arguments

  • shape : Array(Int) - Shape of output Tensor
  • loc : Float - Centrality parameter, or mean of the distribution; usually mentioned as μ
  • scale : Float - scale parameter of the distribution; usually mentioned as b

Examples

Num::Rand.set_seed(0)
a = Tensor(Float32, CPU(Float32)).laplace([5], 0.5)
puts a # => [0.305384 , 0.601509 , 0.247952 , -3.34791 , -0.502075]

[View source]
def self.linear_space(start : T, stop : T, num : Int = 50, endpoint = true, device = CPU) #

Return evenly spaced numbers over a specified interval. Returns num evenly spaced samples, calculated over the interval [start, stop]. The endpoint of the interval can optionally be excluded.

Arguments

  • start : T - Start of interval
  • stop : T - End of interval
  • num : Int - Number of samples
  • endpoint : Bool - Indicates if endpoint of the interval should be included in the results
  • device : Num::Storage - Backend for the Tensor

Examples

Tensor.linspace(0_f32, 1_f32, 5) # => [0.0, 0.25, 0.5, 0.75, 1.0]

Tensor.linspace(0_f32, 1_f32, 5, endpoint: false) # => [0.0, 0.2, 0.4, 0.6, 0.8]

[View source]
def self.logarithmic_space(start : T, stop : T, num = 50, endpoint = true, base : T = T.new(10.0), device = CPU) #

Return numbers spaced evenly on a log scale. In linear space, the sequence starts at base ** start (base to the power of start) and ends with base ** stop (see endpoint below).

Arguments

  • start : T - Start of interval
  • stop : T - End of interval
  • num : Int - Number of samples
  • endpoint : Bool - Indicates if endpoint should be included in the results
  • device : Num::Storage - Backend for the Tensor

Examples

Tensor.logarithmic_space(2.0, 3.0, num: 4)

# [100    , 215.443, 464.159, 1000   ]

[View source]
def self.lognormal(shape : Array(Int), loc : Float = 0.0, sigma : Float = 1.0) : Tensor(T, S) #

Generate a log-normal-distributed, pseudo-random Tensor

Arguments

  • shape : Array(Int) - Shape of output Tensor
  • loc : Float - centrality parameter, or mean of the underlying normal distribution; usually mentioned as μ
  • sigma : Float - scale parameter, or standard deviation of the underlying normal distribution; usually mentioned as σ

Examples

Num::Rand.set_seed(0)
a = Tensor(Float32, CPU(Float32)).lognormal([5], 0.5)
puts a # => [1.41285 , 5.00594 , 0.766401, 1.61069 , 2.29073 ]

[View source]
def self.multinomial(input : Tensor(T, S), num_samples : Int32) #

Draw samples from a multinomial distribution. Returns a Tensor where each row contains num_samples samples from the multinomial distribution located in the corresponding row of Tensor input. The rows of input do not need to be normalized, but must sum to a positive number. If input is a vector (1-D Tensor), returns a vector of length num_samples If input is a matrix (2-D Tensor), returns a matrix where each row contains num_samples samples, with shape (m x num_samples).

Arguments

  • input : Tensor - Tensor containing probabilities of different outcomes
  • num_samples : Int - Number of samples to draw from the multinomial distribution

Examples

Num::Rand.set_seed(0)
input = [[0.5, 0.5], [0.5, 0.5]].to_tensor
a = Tensor.multinomial(input, 5)
puts a # => [[0, 1, 1, 0, 1], [1, 0, 1, 1, 0]]

input2 = [0.5, 0.5, 0.5, 0.5].to_tensor
b = Tensor.multinomial(input, 6)
puts b # => [3, 2, 1, 1, 0, 2]

[View source]
def self.normal(shape : Array(Int), loc = 0.0, sigma = 1.0) : Tensor(T, S) #

Generate a Tensor containing a normal-distribution collection of values

Arguments

  • shape : Array(Int) - Shape of Tensor to create
  • loc : Float - Centrality parameter
  • sigma : Float - Standard deviation

Examples

Num::Rand.set_seed(0)
a = Tensor(Float32, CPU(Float32)).normal([5], 0.5)
puts a # => 0.345609, 1.61063 , -0.26605, 0.476662, 0.828871]

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

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

Arguments

Examples

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

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

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

Arguments

Examples

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

[View source]
def self.poisson(shape : Array(Int), lam : Float = 1.0) : Tensor(T, S) #

Generate a poisson-distributed, pseudo-random Tensor(Int64)

Arguments

  • shape : Array(Int) - Shape of output Tensor
  • lam : Float - Separation parameter of the distribution; usually mentioned as λ

Examples

Num::Rand.set_seed(0)
a = Tensor(Int64, CPU(Int64)).poisson([5])
puts a # => [1, 0, 1, 0, 3]

[View source]
def self.rand(shape : Array(Int)) #

Generate random floating point values between 0 and 1

Arguments

Examples

Num::Rand.set_seed(0)
a = Tensor(Float32, CPU(Float32)).rand([5])
puts a # => [0.411575 , 0.548264 , 0.388604 , 0.0106621, 0.183558 ]

[View source]
def self.random(r : Range(U, U), shape : Array(Int), device = CPU) 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, device = CPU) #

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

Arguments

  • start : T - Beginning value for the range
  • stop : T - End value for the range
  • step : T - 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, device = CPU) #

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

Arguments

  • start : T - Beginning value for the range
  • stop : T - End value for the range
  • step : T - 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, device = CPU) #

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

Arguments

  • start : T - Beginning value for the range
  • stop : T - End value for the range
  • step : T - 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.t_student(shape : Array(Int), df : Float) : Tensor(T, S) #

Generate a t-student-distributed, pseudo-random Tensor

Arguments

  • shape : Array(Int) - Shape of output Tensor
  • df : Float - degrees of freedom of the distribution; usually mentioned as n

Examples

Num::Rand.set_seed(0)
a = Tensor(Float32, CPU(Float32)).t_student([5], 30.0)
puts a # => [-0.148853, -0.803994, 0.353089 , -1.25613 , -0.141144]

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

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

Arguments

Examples

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

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

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

Arguments

Examples

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

[View source]

Instance Method Detail

def !=(other) #

Implements the != operator for two Tensors element-wise.

Arguments

Examples

a = Tensor.from_array [1, 2, 3]
a != a

[View source]
def %(other) #

Return element-wise remainder of division for two Tensors elementwise

Arguments

Examples

a = Tensor.from_array [1.5, 2.2, 3.2]
a % a

[View source]
def &(other) #

Compute the bit-wise AND of two Tensors element-wise.

Arguments

Examples

a = Tensor.from_array [1, 2, 3]
a & a

[View source]
def *(other) #

Multiplies two Tensors elementwise

Arguments

Examples

a = Tensor.from_array [1.5, 2.2, 3.2]
a * a

[View source]
def **(other) #

Exponentiates two Tensors elementwise

Arguments

Examples

a = Tensor.from_array [1.5, 2.2, 3.2]
a ** a

[View source]
def +(other) #

Adds two Tensors elementwise

Arguments

Examples

a = Tensor.from_array [1.5, 2.2, 3.2]
a + a

[View source]
def -(other) #

Subtracts two Tensors elementwise

Arguments

Examples

a = Tensor.from_array [1.5, 2.2, 3.2]
a - a

[View source]
def - #

Implements the negation operator on a Tensor

Examples

a = [1, 2, 3].to_tensor
-a # => [-1, -2, -3]

[View source]
def /(other) #

Divides two Tensors elementwise

Arguments

Examples

a = Tensor.from_array [1.5, 2.2, 3.2]
a / a

[View source]
def //(other) #

Floor divides two Tensors elementwise

Arguments

Examples

a = Tensor.from_array [1.5, 2.2, 3.2]
a // a

[View source]
def <(other) #

Implements the < operator for two Tensors element-wise.

Arguments

Examples

a = Tensor.from_array [1, 2, 3]
a < a

[View source]
def <<(other) #

Shift the bits of an integer to the left. Bits are shifted to the left by appending x2 0s at the right of x1. Since the internal representation of numbers is in binary format, this operation is equivalent to multiplying x1 by 2**x2.

Arguments

Examples

a = Tensor.from_array [1, 2, 3]
a << a

[View source]
def <=(other) #

Implements the <= operator for two Tensors element-wise.

Arguments

Examples

a = Tensor.from_array [1, 2, 3]
a <= a

[View source]
def ==(other) #

Implements the == operator for two Tensors element-wise.

Arguments

Examples

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

[View source]
def >(other) #

Implements the > operator for two Tensors element-wise.

Arguments

Examples

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

[View source]
def >=(other) #

Implements the >= operator for two Tensors element-wise.

Arguments

Examples

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

[View source]
def >>(other) #

Shift the bits of an integer to the right.

Bits are shifted to the right x2. Because the internal representation of numbers is in binary format, this operation is equivalent to dividing x1 by 2**x2.

Arguments

Examples

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

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

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 [](indices : Tensor) : Tensor(T, S) #

An indexing operation that accepts another Tensor for advanced indexing capabilities.

This method allows you to index a tensor by using another tensor as indices. It's particularly useful when you need to select or change complex patterns that can't be achieved with simple slicing.

The shape of the returned tensor is determined by the shape of the indices tensor concatenated with the remaining dimensions of the original tensor. Each value in indices selects a value from the original tensor at the corresponding index. If the corresponding index is a vector, than the returned tensor will include the vector as an additional dimension.

Parameters:

  • indices - A Tensor that contains the indices to index the original tensor.

Returns:

A new tensor containing the values of the original tensor indexed by indices.

Examples:

t = Tensor.new([[1, 2], [3, 4], [5, 6]])
indices = Tensor.new([[0, 2]])
result = t[indices] # Returns: Tensor([[1, 2], [5, 6]])

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

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 : Array - Array of arguments. All but the last argument must be valid indexer, so a Range, Int, or Tuple(Range, Int).
  • value : Tensor | Number - Value to assign to the slice

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 ^(other) #

Compute the bit-wise XOR of two Tensors element-wise.

Arguments

Examples

a = Tensor.from_array [1, 2, 3]
a ^ a

[View source]
def |(other) #

Compute the bit-wise OR of two Tensors element-wise.

Arguments

Examples

a = Tensor.from_array [1, 2, 3]
a | a

[View source]
def accumulate(&block : T, T -> T) : Tensor(T, S) #

Returns a Tensor containing the successive values of applying a binary operation, specified by the given block, to this Tensor's elements.

For each element in the Tensor the block is passed an accumulator value and the element. The result becomes the new value for the accumulator and is also appended to the returned Tensor. The initial value for the accumulator is the first element in the Tensor.

Examples

[2, 3, 4, 5]..to_tensor.accumulate { |x, y| x * y } # => [2, 6, 24, 120]

[View source]
def acos #

Trigonometric inverse cosine, element-wise.

Examples

a = Tensor.from_array [1, 2, 3]
a.acos

[View source]
def acosh #

Inverse hyperbolic cosine, element-wise.

Examples

a = Tensor.from_array [1, 2, 3]
a.acos

[View source]
def add(other) #

Adds two Tensors elementwise

Arguments

Examples

a = Tensor.from_array [1.5, 2.2, 3.2]
a + a

[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

  • 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 }
a.all(0) # => [false, true]
a.all(1, dims: true)
# [[false],
#  [ true]]

[View source]
def all : Bool #

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

Examples

a = [0, 2, 3].to_tensor
a.all # => false

[View source]
def all_close(other : Tensor, epsilon : Float = 1e-6) : Bool #

Asserts that two Tensors are equal, allowing for small margins of errors with floating point values using an EPSILON value.

Arguments

  • other : Tensor - Tensor to compare to self
  • epsilon : Float - Margin of error to accept between elements

Examples

a = [0.0, 0.0, 0.0000000001].to_tensor
b = [0.0, 0.0, 0.0].to_tensor
a.all_close(b)        # => true
a.all_close(b, 1e-12) # => 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

  • 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 }
a.any(0) # => [true, true]
a.any(1, dims: true)
# [[true],
#  [ true]]

[View source]
def any : Bool #

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

Examples

a = [0, 2, 3].to_tensor
a.any # => true

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

Find the maximum index value of a Tensor along an axis

Arguments

  • axis : Int - Axis of reduction
  • dims : Bool - Indicate if the axis of reduction should remain in the result

Examples

a = [[4, 2], [0, 1]].to_tensor
a.argmax(1) # => [0, 1]

[View source]
def argmax : Int32 #

Find the maximum index value of a Tensor

Examples

a = [1, 2, 3].to_tensor
a.argmax # => 2

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

Find the minimum index value of a Tensor along an axis

Arguments

  • axis : Int - Axis of reduction
  • dims : Bool - Indicate if the axis of reduction should remain in the result

Examples

a = [[4, 2], [0, 1]].to_tensor
a.argmin(1) # => [1, 0]

[View source]
def argmin : Int32 #

Find the minimum index value of a Tensor

Examples

a = [1, 2, 3].to_tensor
a.argmin # => 0

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

#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

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(dtype : U.class) forall U #

Converts a Tensor to a given dtype. No rounding is done on floating point values.

Arguments

  • dtype : U.class - desired data type of the returned Tensor

Examples

a = Tensor.from_array [1.5, 2.2, 3.2]
a.as_type(Int32) # => [1, 2, 3]

[View source]
def asin #

Inverse sine, element-wise.

Examples

a = Tensor.from_array [1, 2, 3]
a.asin

[View source]
def asinh #

Inverse hyperbolic sine, element-wise.

Examples

a = Tensor.from_array [1, 2, 3]
a.asinh

[View source]
def atan #

Inverse tangent, element-wise.

Examples

a = Tensor.from_array [1, 2, 3]
a.atan

[View source]
def atanh #

Inverse hyperbolic tangent, element-wise.

Examples

a = Tensor.from_array [1, 2, 3]
a.atanh

[View source]
def besselj0 #

Calculates besselj0, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.besselj0

[View source]
def besselj1 #

Calculates besselj1, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.besselj1

[View source]
def bessely0 #

Calculates bessely0, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.bessely0

[View source]
def bessely1 #

Calculates bessely1, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.bessely1

[View source]
def bitwise_and(other) #

Compute the bit-wise AND of two Tensors element-wise.

Arguments

Examples

a = Tensor.from_array [1, 2, 3]
a & a

[View source]
def bitwise_or(other) #

Compute the bit-wise OR of two Tensors element-wise.

Arguments

Examples

a = Tensor.from_array [1, 2, 3]
a | a

[View source]
def bitwise_xor(other) #

Compute the bit-wise XOR of two Tensors element-wise.

Arguments

Examples

a = Tensor.from_array [1, 2, 3]
a ^ a

[View source]
def broadcast(other1 : Tensor(U, V), other2 : Tensor(W, X)) forall U, V, W, X #

Broadcasts three Tensor's' to a new shape. This allows for elementwise operations between the three Tensors with the new shape.

Broadcasting rules apply, and imcompatible shapes will raise an error.

Arguments

Examples

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

x, y, z = a.broadcast(b, c)
x.shape # => [3, 3, 3]

[View source]
def broadcast(other : Tensor(U, V)) forall U, V #

Broadcasts two Tensor's' to a new shape. This allows for elementwise operations between the two Tensors with the new shape.

Broadcasting rules apply, and imcompatible shapes will raise an error.

Arguments

  • other : Tensor - RHS of the broadcast

Examples

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

x, y = a.broadcast(b)
x.shape # => [3, 3]

[View source]
def broadcast_to(shape : Array(Int)) : Tensor(T, S) #

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 cbrt #

Calculates cube root, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.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 : Bool - Which 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 cos #

Calculates cosine, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.cos

[View source]
def cosh #

Calculates hyperbolic cosine, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.cosh

[View source]
def cpu : Tensor(T, CPU(T)) #

Places a Tensor onto a CPU backend. No copy is done if the Tensor is already on a CPU

Arguments

Examples

a = Tensor(Float32, OCL(Float32)).ones([3])
a.cpu # => [1, 1, 1]

[View source]
def data : S #

[View source]
def det #

Compute the determinant of an array.

Examples

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

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

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

TODO Implement views for offset diagonals

Examples

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

[View source]
def divide(other) #

Divides two Tensors elementwise

Arguments

Examples

a = Tensor.from_array [1.5, 2.2, 3.2]
a / a

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

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 = Num::RowMajor) #

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

Arguments

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.

Examples

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

# 0
# 1
# 2
# 3

[View source]
def each #

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

Examples

a = Tensor.new(2, 2) { |i| i }
iter = a.each
a.size.times do
  puts iter.next.value
end

# 0
# 1
# 2
# 3

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

Yields a view of each lane of an axis. Changes made in the passed block will be reflected in the original Tensor

Arguments

  • axis : Int - Axis of reduction
  • dims : Bool - Indicates if the axis of reduction should be removed from the result

Examples

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

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

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

Returns an iterator along each element of an axis. Each element returned by the iterator is a view, not a copy

Arguments

  • axis : Int - Axis of reduction
  • dims : Bool - Indicates if the axis of reduction should be removed from the result

Examples

a = Tensor.new([3, 3]) { |i| i }
a.each_axis(1).next # => [0, 3, 6]

[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

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

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.

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.

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.

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.

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 symmetric matrix.

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

Examples

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

# [-0.618034, 1.61803  ]

[View source]
def equal(other) #

Implements the == operator for two Tensors element-wise.

Arguments

Examples

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

[View source]
def erf #

Calculates erf, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.erf

[View source]
def erfc #

Calculates erfc, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.erfc

[View source]
def exp #

Calculates exp, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.exp

[View source]
def exp2 #

Calculates exp2, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.exp2

[View source]
def expand_dims(axis : Int) : Tensor(T, S) #

Expands the dimensions of a Tensor, along a single axis

Arguments

  • axis : Int - Axis on which to expand dimensions

Examples

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

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

[View source]
def expm1 #

Calculates expm1, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.expm1

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

Returns the flags of a Tensor, describing its memory and read status

Examples

a = Tensor(Float32, CPU(Float32)).new([2, 3, 4])
b = a[..., 1]
a.flags # => CONTIGUOUS | OWNDATA | WRITE
b.flags # => WRITE

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

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

Examples

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

[View source]
def flip(axis : Int) : Tensor(T, S) #

Flips a Tensor along an axis, returning a view

Arguments

  • axis : Int - Axis to flip

Examples

a = [[1, 2, 3], [4, 5, 6]]
a.flip(1)

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

[View source]
def flip : Tensor(T, S) #

Flips a Tensor along all axes, returning a view

Examples

a = [[1, 2, 3], [4, 5, 6]]
a.flip

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

[View source]
def floordiv(other) #

Floor divides two Tensors elementwise

Arguments

Examples

a = Tensor.from_array [1.5, 2.2, 3.2]
a // a

[View source]
def gamma #

Calculates gamma function, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.gamma

[View source]
def greater(other) #

Implements the > operator for two Tensors element-wise.

Arguments

Examples

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

[View source]
def greater_equal(other) #

Implements the >= operator for two Tensors element-wise.

Arguments

Examples

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

[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.

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 ilogb #

Calculates ilogb, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.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])

Examples

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

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

[View source]
def left_shift(other) #

Shift the bits of an integer to the left. Bits are shifted to the left by appending x2 0s at the right of x1. Since the internal representation of numbers is in binary format, this operation is equivalent to multiplying x1 by 2**x2.

Arguments

Examples

a = Tensor.from_array [1, 2, 3]
a << a

[View source]
def less(other) #

Implements the < operator for two Tensors element-wise.

Arguments

Examples

a = Tensor.from_array [1, 2, 3]
a < a

[View source]
def less_equal(other) #

Implements the <= operator for two Tensors element-wise.

Arguments

Examples

a = Tensor.from_array [1, 2, 3]
a <= a

[View source]
def lgamma #

Calculates logarithmic gamma, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.lgamma

[View source]
def log #

Calculates log, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.log

[View source]
def log10 #

Calculates log10, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.log10

[View source]
def log1p #

Calculates log1p, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.log1p

[View source]
def log2 #

Calculates log2, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.log2

[View source]
def logb #

Calculates logb, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.logb

[View source]
def map(d1 : Tensor, d2 : 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 generic type of the returned Tensor is inferred from a block

Arguments

  • t : Tensor - The second Tensor for iteration. Must be broadcastable against the #shape of self and v
  • v : Tensor - The third Tensor for iteration. Must be broadcastable against the #shape of self and t
  • block : Proc(T, U, V, W) - The Proc 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(other : 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 generic type of the returned Tensor is inferred from a block

Arguments

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

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) 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!(d1 : Tensor, d2 : 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 - The second Tensor for iteration. Must be broadcastable against the #shape of self and v
  • v : Tensor - The third Tensor for iteration. Must be broadcastable against the #shape of self and t
  • block : Proc(T, U, V, T) - The Proc 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 map!(other : 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 - The second Tensor for iteration. Must be broadcastable against the #shape of self
  • block : Proc(T, U, T) - Proc to map across the Tensor

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 matmul(other : Tensor(T, S), output : Tensor(T, S) | Nil = nil) #

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 - 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(axis : Int, dims : Bool = false) #

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

Arguments

  • 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 }
a.max(0) # => [2, 3]
a.max(1, dims: true)
# [[1],
#  [3]]

[View source]
def max : T #

Reduces a Tensor to a scalar by finding the maximum value

Examples

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

[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

  • 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 }
a.mean(0) # => [1, 2]
a.mean(1, dims: true)
# [[0],
#  [2]]

[View source]
def mean #

Reduces a Tensor to a scalar by finding the average

Examples

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

[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

  • 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 }
a.min(0) # => [0, 1]
a.min(1, dims: true)
# [[0],
#  [2]]

[View source]
def min : T #

Reduces a Tensor to a scalar by finding the minimum value

Examples

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

[View source]
def modulo(other) #

Return element-wise remainder of division for two Tensors elementwise

Arguments

Examples

a = Tensor.from_array [1.5, 2.2, 3.2]
a % a

[View source]
def move_axis(source : Array(Int), destination : Array(Int)) : Tensor(T, S) #

Move axes of a Tensor to new positions, other axes remain in their original order

Arguments

  • source : Array(Int) - Original positions of axes to move
  • destination : Array(Int) - Destination positions to permute axes

Examples

a = Tensor(Int8, CPU(Int8)).new([3, 4, 5])
a.moveaxis([0], [-1]).shape # => 4, 5, 3

[View source]
def move_axis(source : Int, destination : Int) : Tensor(T, S) #

Move axes of a Tensor to new positions, other axes remain in their original order

Arguments

  • source : Int - Original position of axis to move
  • destination : Int - Destination position of axis

Examples

a = Tensor(Int8, CPU(Int8)).new([3, 4, 5])
a.moveaxis(0, -1).shape # => 4, 5, 3

[View source]
def multiply(other) #

Multiplies two Tensors elementwise

Arguments

Examples

a = Tensor.from_array [1.5, 2.2, 3.2]
a * a

[View source]
def negate #

Implements the negation operator on a Tensor

Examples

a = [1, 2, 3].to_tensor
-a # => [-1, -2, -3]

[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(other) #

Implements the != operator for two Tensors element-wise.

Arguments

Examples

a = Tensor.from_array [1, 2, 3]
a != a

[View source]
def offset : Int32 #

Returns the offset of a Tensor's data

Examples

a = Tensor(Int8, CPU(Int8)).new([2, 3, 4])
a.offset # => 0

[View source]
def opencl : Tensor(T, OCL(T)) #

Places a Tensor onto an OpenCL backend. No copy is done if the Tensor is already on a CPU

Examples

a = Tensor(Float32, CPU(Float32)).ones([3])
a.opencl # => <[3] on OpenCL Backend>

[View source]
def power(other) #

Exponentiates two Tensors elementwise

Arguments

Examples

a = Tensor.from_array [1.5, 2.2, 3.2]
a ** a

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

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

Arguments

  • 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 }
a.prod(0) # => [0, 3]
a.prod(1, dims: true)
# [[0],
#  [6]]

[View source]
def prod : T #

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

Examples

a = [1, 2, 3]
a.prod # => 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

  • axis : Int - Axis of reduction
  • dims : Bool - Indicate if the axis of reduction should remain in the result

Examples

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

[View source]
def ptp : T #

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

Examples

a = [1, 2, 3].to_tensor
a.ptp # => 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

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 rank : Int32 #

Returns the number of dimensions in a Tensor

Examples

a = Tensor(Int8, CPU(Int8)).new([3, 3, 3, 3])
a.rank # => 4

[View source]
def reduce(memo, &) #

Just like the other variant, but you can set the initial value of the accumulator.

Arguments

  • memo - Value to start off the accumulator

Examples

[1, 2, 3, 4, 5].to_tensor.reduce(10) { |acc, i| acc + i } # => 25

[View source]
def reduce(&) #

Combines all elements in the Tensor by applying a binary operation, specified by a block, so as to reduce them to a single value.

For each element in the Tensor the block is passed an accumulator value (memo) and the element. The result becomes the new value for memo. At the end of the iteration, the final value of memo is the return value for the method. The initial value for the accumulator is the first element in the Tensor.

Raises Enumerable::EmptyError if the Tensor is empty.

Examples

[1, 2, 3, 4, 5].to_tensor.reduce { |acc, i| acc + i } # => 15

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

Equivalent of calling #reduce on each slice into an axis. Used primarily for reductions like Num.sum, Num.prod, in their axis versions.

Arguments

  • axis : Int - Axis of reduction
  • dims : Bool - Indicates if the axis of reduction should be removed from the result

Examples

a = Tensor.new([3, 3]) { |i| i }
a.reduce_axis(0) { |i, j| i + j } # => [ 9, 12, 15]

[View source]
def repeat(n : Int, axis : Int) : Tensor(T, S) #

Repeat elements of a Tensor along an axis

Arguments

  • n : Int - Number of times to repeat
  • axis : Int - Axis along which to repeat

Examples

a = [[1, 2, 3], [4, 5, 6]]
a.repeat(2, 1)

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

[View source]
def repeat(n : Int) : Tensor(T, S) #

Repeat elements of a Tensor, treating the Tensor as flat

Arguments

  • n : Int - Number of times to repeat

Examples

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

[View source]
def reshape(shape : Array(Int)) : Tensor(T, S) #

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(*shape : Int) : Tensor(T, S) #

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(other) #

Shift the bits of an integer to the right.

Bits are shifted to the right x2. Because the internal representation of numbers is in binary format, this operation is equivalent to dividing x1 by 2**x2.

Arguments

Examples

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

[View source]
def set(*args, 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 : Tuple - Tuple of arguments. All must be valid indexers, so a Range, Int, or Tuple(Range, Int).
  • value : Tensor | Number - Value to assign to the slice

Examples

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

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

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

Returns the size of a Tensor along each dimension

Examples

a = Tensor(Int8, CPU(Int8)).new([2, 3, 4])
a.shape # => [2, 3, 4]

[View source]
def sin #

Calculates sine, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.sin

[View source]
def sinh #

Calculates hyperbolic sine, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.sinh

[View source]
def size : Int32 #

Returns the size of a Tensor along each dimension

a = Tensor(Int8, CPU(Int8)).new([2, 3, 4])
a.shape # => [2, 3, 4]

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

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 solve(x : Tensor(T, S)) #

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.as_type(Float32)
b = [9, 8].to_tensor.as_type(Float32)
puts a.solve(b)

# [2, 3]

[View source]
def sort(axis : Int) : Tensor(T, S) #

Sorts a Tensor along an axis.

Arguments

  • axis : Int - Axis of reduction

Examples

t = Tensor.random(0...10, [3, 3, 2])
puts t.sort(axis: 1)

# [[[1, 1],
#   [4, 5],
#   [5, 7]],
#
#  [[0, 0],
#   [2, 3],
#   [8, 4]],
#
#  [[2, 5],
#   [5, 7],
#   [5, 7]]]

[View source]
def sort : Tensor(T, S) #

Sorts a Tensor, treating it's elements like the Tensor is flat.

Examples

a = [3, 2, 1].to_tensor
a.sort # => [1, 2, 3]

[View source]
def sort(axis : Int, &block : T, T -> _) #

Sorts a Tensor along an axis.

Arguments

  • axis : Int - Axis of reduction

Examples

t = Tensor.random(0...10, [3, 3, 2])
puts t.sort(axis: 1) { |i, j| i <=> j }

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

[View source]
def sort(&block : T, T -> _) #

Sorts a Tensor, treating it's elements like the Tensor is flat. Sorts using criteria specified by a passed block

Arguments

  • block : Proc(T, T, _) - Function used to sort

Examples

a = [3, 2, 1].to_tensor
a.sort { |i, j| j - i } # => [3, 2, 1]

[View source]
def sqrt #

Calculates square root, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.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

  • 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 }
a.std(0) # => [1, 1]
a.std(1, dims: true)
# [[0.707107],
#  [0.707107]]

[View source]
def std : Float64 #

Reduces a Tensor to a scalar by finding the standard deviation

Examples

a = [1, 2, 3].to_tensor
a.std # => 0.816496580927726

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

Returns the step of a Tensor along each dimension

Examples

a = Tensor(Int8, CPU(Int8)).new([3, 3, 2])
a.shape # => [4, 2, 1]

[View source]
def subtract(other) #

Subtracts two Tensors elementwise

Arguments

Examples

a = Tensor.from_array [1.5, 2.2, 3.2]
a - a

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

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

Arguments

  • 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 }
a.sum(0) # => [2, 4]
a.sum(1, dims: true)
# [[1],
#  [5]]

[View source]
def sum : T #

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

Examples

a = [1, 2, 3]
a.sum # => 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.

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, S) #

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 #

Calculates tangent, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.tan

[View source]
def tanh #

Calculates hyperbolic tangent, elementwise

Examples

a = Tensor.from_array [1, 2, 3]
a.tanh

[View source]
def tile(n : Int) : Tensor(T, S) #

Tile elements of a Tensor

Arguments

  • n : Int - Number of times to tile

Examples

a = [[1, 2, 3], [4, 5, 6]]
puts a.tile(2)

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

[View source]
def tile(n : Array(Int)) : Tensor(T, S) #

Tile elements of a Tensor

Arguments

  • n : Int - Number of times to tile

Examples

a = [[1, 2, 3], [4, 5, 6]]
puts Num.tile(a, 2)

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

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

Converts a Tensor to an Array. To avoid return type ambiguity this will always return a 1D Array

Arguments

Examples

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

[View source]
def to_npy(path : String) #

Export a Tensor to the Numpy format

Arguments

  • path : String - filename of output .npy file.

Only integer, unsigned integer and float ndarrays are supported at the moment.


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

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(*axes : Int) : Tensor(T, S) #

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 view(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(Int8) # => [0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0]

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

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

Examples

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

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

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

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 yield_along_axis(axis : Int, &) #

Similar to #each_axis, but instead of yielding slices of an axis, it yields slices along an axis, useful for methods that require an entire view of an axis slice for a reduction operation, such as #std, rather than being able to incrementally reduce.

Arguments

  • axis : Int - Axis of reduction

Examples

a = Tensor.new([3, 3, 3]) { |i| i }
a.yield_along_axis(0) do |ax|
  puts ax
end

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

[View source]
def zip(b : Tensor(U, CPU(U)), &block : T, U -> _) forall U, V #

Yields the elements of two Tensors, always in RowMajor order, as if the Tensors were flat.

Arguments

Examples

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

# { 0, 2}
# { 1, 3}
# { 2, 4}
# { 3, 5}

[View source]