Skip to main content

Tensor

Struct Tensor 

Source
pub struct Tensor<T: Scalar> { /* private fields */ }
Expand description

An N-dimensional tensor with dynamic shape.

Data is stored contiguously in row-major (C) order. The tensor owns its data and cloning performs a deep copy.

§Type Parameters

  • T: The element type, which must implement Scalar.

§Examples

let t = Tensor::from_vec(vec![1.0, 2.0, 3.0, 4.0], vec![2, 2]).unwrap();
assert_eq!(t.shape(), &[2, 2]);
assert_eq!(t.numel(), 4);

Implementations§

Source§

impl<T: Scalar> Tensor<T>

Source

pub fn matvec(&self, x: &Tensor<T>) -> Result<Tensor<T>>

Matrix-vector multiply: returns A @ x as a new 1-D tensor.

self must be 2-D [m, n], x must be 1-D [n].

§Examples
let a = Tensor::from_vec(vec![1.0, 2.0, 3.0, 4.0], vec![2, 2]).unwrap();
let x = Tensor::from_vec(vec![5.0, 6.0], vec![2]).unwrap();
let y = a.matvec(&x).unwrap();
assert_eq!(y.as_slice(), &[17.0, 39.0]);
Source

pub fn matmul(&self, other: &Tensor<T>) -> Result<Tensor<T>>

Matrix-matrix multiply: returns self @ other as a new 2-D tensor.

self must be 2-D [m, k], other must be 2-D [k, n].

§Examples
let a = Tensor::from_vec(vec![1.0, 2.0, 3.0, 4.0], vec![2, 2]).unwrap();
let b = Tensor::from_vec(vec![5.0, 6.0, 7.0, 8.0], vec![2, 2]).unwrap();
let c = a.matmul(&b).unwrap();
assert_eq!(c.as_slice(), &[19.0, 22.0, 43.0, 50.0]);
Source

pub fn dot(&self, other: &Tensor<T>) -> Result<T>

Dot product with another 1-D tensor.

§Examples
let x = Tensor::from_vec(vec![1.0_f64, 2.0, 3.0], vec![3]).unwrap();
let y = Tensor::from_vec(vec![4.0, 5.0, 6.0], vec![3]).unwrap();
assert_eq!(x.dot(&y).unwrap(), 32.0);
Source§

impl<T: Float> Tensor<T>

Source

pub fn norm(&self) -> Result<T>

Euclidean (L2) norm of a 1-D tensor.

§Examples
let x = Tensor::from_vec(vec![3.0_f64, 4.0], vec![2]).unwrap();
assert!((x.norm().unwrap() - 5.0).abs() < 1e-10);
Source

pub fn solve(&self, b: &Tensor<T>) -> Result<Tensor<T>>

Solve the linear system self * x = b for a square matrix self.

Uses LU decomposition with partial pivoting.

§Examples
let a = Tensor::from_vec(vec![2.0_f64, 1.0, 1.0, 4.0], vec![2, 2]).unwrap();
let b = Tensor::from_vec(vec![5.0_f64, 6.0], vec![2]).unwrap();
let x = a.solve(&b).unwrap();
assert!((x.as_slice()[0] - 2.0).abs() < 1e-10);
assert!((x.as_slice()[1] - 1.0).abs() < 1e-10);
Source

pub fn inv(&self) -> Result<Tensor<T>>

Compute the inverse of a square matrix.

Uses LU decomposition with partial pivoting.

§Examples
let a = Tensor::from_vec(vec![2.0_f64, 1.0, 1.0, 4.0], vec![2, 2]).unwrap();
let inv = a.inv().unwrap();
let eye = a.matmul(&inv).unwrap();
assert!((eye.as_slice()[0] - 1.0).abs() < 1e-10);
Source

pub fn det(&self) -> Result<T>

Compute the determinant of a square matrix.

Uses LU decomposition with partial pivoting.

§Examples
let a = Tensor::from_vec(vec![2.0_f64, 1.0, 1.0, 4.0], vec![2, 2]).unwrap();
assert!((a.det().unwrap() - 7.0).abs() < 1e-10);
Source

pub fn lstsq(&self, b: &Tensor<T>) -> Result<Tensor<T>>

Solve the least-squares problem min ||self * x - b||_2.

Uses QR decomposition with Householder reflections.

§Examples
// Overdetermined system: 2x = [2, 4, 6] => x ≈ [1, 2, 3] / something
let a = Tensor::from_vec(vec![1.0_f64, 1.0, 1.0], vec![3, 1]).unwrap();
let b = Tensor::from_vec(vec![1.0_f64, 2.0, 3.0], vec![3]).unwrap();
let x = a.lstsq(&b).unwrap();
assert_eq!(x.shape(), &[1]);
Source§

impl<T: Float> Tensor<T>

Source

pub fn abs(&self) -> Tensor<T>

Element-wise absolute value.

§Examples
let t = Tensor::from_vec(vec![-3.0_f64, -1.0, 0.0, 2.0], vec![4]).unwrap();
assert_eq!(t.abs().as_slice(), &[3.0, 1.0, 0.0, 2.0]);
Source

pub fn sqrt(&self) -> Tensor<T>

Element-wise square root.

§Examples
let t = Tensor::from_vec(vec![4.0_f64, 9.0, 16.0], vec![3]).unwrap();
assert_eq!(t.sqrt().as_slice(), &[2.0, 3.0, 4.0]);
Source

pub fn sin(&self) -> Tensor<T>

Element-wise sine.

§Examples
let t = Tensor::from_vec(vec![0.0_f64, std::f64::consts::FRAC_PI_2], vec![2]).unwrap();
let s = t.sin();
assert!((s.as_slice()[0]).abs() < 1e-15);
assert!((s.as_slice()[1] - 1.0).abs() < 1e-15);
Source

pub fn cos(&self) -> Tensor<T>

Element-wise cosine.

§Examples
let t = Tensor::from_vec(vec![0.0_f64], vec![1]).unwrap();
assert!((t.cos().as_slice()[0] - 1.0).abs() < 1e-15);
Source

pub fn tan(&self) -> Tensor<T>

Element-wise tangent.

§Examples
let t = Tensor::from_vec(vec![0.0_f64], vec![1]).unwrap();
assert!(t.tan().as_slice()[0].abs() < 1e-15);
Source

pub fn exp(&self) -> Tensor<T>

Element-wise natural exponential.

§Examples
let t = Tensor::from_vec(vec![0.0_f64, 1.0], vec![2]).unwrap();
let e = t.exp();
assert!((e.as_slice()[0] - 1.0).abs() < 1e-15);
assert!((e.as_slice()[1] - std::f64::consts::E).abs() < 1e-14);
Source

pub fn ln(&self) -> Tensor<T>

Element-wise natural logarithm.

§Examples
let t = Tensor::from_vec(vec![1.0_f64, std::f64::consts::E], vec![2]).unwrap();
let l = t.ln();
assert!((l.as_slice()[0]).abs() < 1e-15);
assert!((l.as_slice()[1] - 1.0).abs() < 1e-14);
Source

pub fn log2(&self) -> Tensor<T>

Element-wise base-2 logarithm.

§Examples
let t = Tensor::from_vec(vec![1.0_f64, 2.0, 4.0, 8.0], vec![4]).unwrap();
assert_eq!(t.log2().as_slice(), &[0.0, 1.0, 2.0, 3.0]);
Source

pub fn log10(&self) -> Tensor<T>

Element-wise base-10 logarithm.

§Examples
let t = Tensor::from_vec(vec![1.0_f64, 10.0, 100.0], vec![3]).unwrap();
let l = t.log10();
assert!((l.as_slice()[1] - 1.0).abs() < 1e-15);
assert!((l.as_slice()[2] - 2.0).abs() < 1e-14);
Source

pub fn floor(&self) -> Tensor<T>

Element-wise floor.

§Examples
let t = Tensor::from_vec(vec![1.3_f64, 2.7, -0.5], vec![3]).unwrap();
assert_eq!(t.floor().as_slice(), &[1.0, 2.0, -1.0]);
Source

pub fn ceil(&self) -> Tensor<T>

Element-wise ceiling.

§Examples
let t = Tensor::from_vec(vec![1.3_f64, 2.7, -0.5], vec![3]).unwrap();
assert_eq!(t.ceil().as_slice(), &[2.0, 3.0, 0.0]);
Source

pub fn round(&self) -> Tensor<T>

Element-wise rounding to nearest integer.

§Examples
let t = Tensor::from_vec(vec![1.3_f64, 2.7], vec![2]).unwrap();
assert_eq!(t.round().as_slice(), &[1.0, 3.0]);
Source

pub fn recip(&self) -> Tensor<T>

Element-wise reciprocal (1/x).

§Examples
let t = Tensor::from_vec(vec![2.0_f64, 4.0, 5.0], vec![3]).unwrap();
assert_eq!(t.recip().as_slice(), &[0.5, 0.25, 0.2]);
Source

pub fn powf(&self, exponent: T) -> Tensor<T>

Raise every element to a floating-point power.

§Examples
let t = Tensor::from_vec(vec![2.0_f64, 3.0], vec![2]).unwrap();
let p = t.powf(3.0);
assert!((p.as_slice()[0] - 8.0).abs() < 1e-14);
assert!((p.as_slice()[1] - 27.0).abs() < 1e-14);
Source

pub fn powi(&self, n: i32) -> Tensor<T>

Raise every element to an integer power.

§Examples
let t = Tensor::from_vec(vec![2.0_f64, 3.0], vec![2]).unwrap();
let p = t.powi(2);
assert!((p.as_slice()[0] - 4.0).abs() < 1e-14);
assert!((p.as_slice()[1] - 9.0).abs() < 1e-14);
Source

pub fn clamp(&self, min: T, max: T) -> Tensor<T>

Clamp every element to [min, max].

§Examples
let t = Tensor::from_vec(vec![-5.0_f64, 0.5, 3.0, 10.0], vec![4]).unwrap();
assert_eq!(t.clamp(0.0, 2.0).as_slice(), &[0.0, 0.5, 2.0, 2.0]);
Source§

impl<T: Scalar> Tensor<T>

Source

pub fn cast_to<U: Scalar + CastFrom<T>>(&self) -> Tensor<U>

Cast every element of this tensor to a different scalar type.

This allocates a new tensor with the same shape and copies each element through CastFrom.

§Examples
let t = Tensor::from_vec(vec![1_u8, 2, 3, 4], vec![2, 2]).unwrap();
let f: Tensor<f64> = t.cast_to();
assert_eq!(f.as_slice(), &[1.0, 2.0, 3.0, 4.0]);
Source§

impl<T: Scalar> Tensor<T>

Source

pub fn zeros(shape: Vec<usize>) -> Self

Create a tensor filled with zeros.

let t = Tensor::<f64>::zeros(vec![2, 3]);
assert_eq!(t.shape(), &[2, 3]);
assert!(t.iter().all(|&x| x == 0.0));
Source

pub fn ones(shape: Vec<usize>) -> Self

Create a tensor filled with ones.

let t = Tensor::<f64>::ones(vec![2, 3]);
assert!(t.iter().all(|&x| x == 1.0));
Source

pub fn full(shape: Vec<usize>, value: T) -> Self

Create a tensor filled with a constant value.

let t = Tensor::full(vec![2, 2], 7_i32);
assert!(t.iter().all(|&x| x == 7));
Source

pub fn arange(n: usize) -> Self

Create a 1-D tensor with values [0, 1, 2, ..., n-1].

let t = Tensor::<i32>::arange(5);
assert_eq!(t.as_slice(), &[0, 1, 2, 3, 4]);
Source

pub fn eye(n: usize) -> Self

Create an identity matrix of size n x n.

let eye = Tensor::<f64>::eye(3);
assert_eq!(eye.shape(), &[3, 3]);
assert_eq!(*eye.get(&[0, 0]).unwrap(), 1.0);
assert_eq!(*eye.get(&[0, 1]).unwrap(), 0.0);
Source§

impl<T: Float> Tensor<T>

Source

pub fn linspace(start: T, end: T, n: usize) -> Result<Self>

Create a 1-D tensor with n evenly spaced values from start to end (inclusive).

Returns an error if n < 2.

let t = Tensor::<f64>::linspace(0.0, 1.0, 5).unwrap();
assert_eq!(t.shape(), &[5]);
Source§

impl<T: Scalar> Tensor<T>

Source

pub fn to_html(&self) -> String

Render the tensor as an HTML string.

  • Scalars and 1-D tensors are shown as formatted values.
  • 2-D tensors are rendered as <table>.
  • Higher-dimensional tensors show shape and a data summary.
Source

pub fn evcxr_display(&self)

Display this tensor in an evcxr Jupyter notebook.

Auto-detected by the evcxr kernel for rich HTML output.

Source§

impl<T: Scalar> Tensor<T>

Source

pub fn add_checked(&self, other: &Tensor<T>) -> Result<Tensor<T>>

Element-wise addition, returning Err on shape mismatch.

§Examples
let a = Tensor::from_vec(vec![1, 2, 3], vec![3]).unwrap();
let b = Tensor::from_vec(vec![4, 5, 6], vec![3]).unwrap();
let c = a.add_checked(&b).unwrap();
assert_eq!(c.as_slice(), &[5, 7, 9]);
Source

pub fn sub_checked(&self, other: &Tensor<T>) -> Result<Tensor<T>>

Element-wise subtraction, returning Err on shape mismatch.

§Examples
let a = Tensor::from_vec(vec![10, 20, 30], vec![3]).unwrap();
let b = Tensor::from_vec(vec![1, 2, 3], vec![3]).unwrap();
let c = a.sub_checked(&b).unwrap();
assert_eq!(c.as_slice(), &[9, 18, 27]);
Source

pub fn mul_checked(&self, other: &Tensor<T>) -> Result<Tensor<T>>

Element-wise multiplication, returning Err on shape mismatch.

§Examples
let a = Tensor::from_vec(vec![2, 3, 4], vec![3]).unwrap();
let b = Tensor::from_vec(vec![5, 6, 7], vec![3]).unwrap();
let c = a.mul_checked(&b).unwrap();
assert_eq!(c.as_slice(), &[10, 18, 28]);
Source

pub fn div_checked(&self, other: &Tensor<T>) -> Result<Tensor<T>>

Element-wise division, returning Err on shape mismatch.

§Examples
let a = Tensor::from_vec(vec![10, 20, 30], vec![3]).unwrap();
let b = Tensor::from_vec(vec![2, 5, 6], vec![3]).unwrap();
let c = a.div_checked(&b).unwrap();
assert_eq!(c.as_slice(), &[5, 4, 5]);
Source§

impl<T: Scalar> Tensor<T>

Source

pub fn sum(&self) -> T

Sum of all elements.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4], vec![4]).unwrap();
assert_eq!(t.sum(), 10);
Source

pub fn product(&self) -> T

Product of all elements.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4], vec![4]).unwrap();
assert_eq!(t.product(), 24);
Source

pub fn min_element(&self) -> Option<T>

Minimum element. Returns None for empty tensors.

§Examples
let t = Tensor::from_vec(vec![3, 1, 4, 1, 5], vec![5]).unwrap();
assert_eq!(t.min_element(), Some(1));
let empty = Tensor::<i32>::zeros(vec![0]);
assert_eq!(empty.min_element(), None);
Source

pub fn max_element(&self) -> Option<T>

Maximum element. Returns None for empty tensors.

§Examples
let t = Tensor::from_vec(vec![3, 1, 4, 1, 5], vec![5]).unwrap();
assert_eq!(t.max_element(), Some(5));
Source

pub fn sum_axis(&self, axis: usize) -> Result<Tensor<T>>

Sum along a given axis, producing a tensor with that axis removed.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4, 5, 6], vec![2, 3]).unwrap();
let s = t.sum_axis(0).unwrap();
assert_eq!(s.as_slice(), &[5, 7, 9]);
Source§

impl<T: Float> Tensor<T>

Source

pub fn mean(&self) -> T

Mean of all elements.

§Examples
let t = Tensor::from_vec(vec![1.0_f64, 2.0, 3.0, 4.0], vec![4]).unwrap();
assert_eq!(t.mean(), 2.5_f64);
Source

pub fn relu(&self) -> Tensor<T>

Element-wise ReLU: max(0, x) for each element.

Source§

impl<T: Scalar> Tensor<T>

Source

pub fn reshape(self, new_shape: Vec<usize>) -> Result<Self>

Reshape the tensor to a new shape without copying data.

The total number of elements must remain the same.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4, 5, 6], vec![6]).unwrap();
let t = t.reshape(vec![2, 3]).unwrap();
assert_eq!(t.shape(), &[2, 3]);
Source

pub fn reshaped(&self, new_shape: Vec<usize>) -> Result<Self>

Return a reshaped view without consuming the tensor (copies data).

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4], vec![4]).unwrap();
let r = t.reshaped(vec![2, 2]).unwrap();
assert_eq!(r.shape(), &[2, 2]);
assert_eq!(t.shape(), &[4]); // original unchanged
Source

pub fn flatten(self) -> Self

Flatten the tensor into a 1-D tensor (consumes self, no copy).

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4], vec![2, 2]).unwrap();
let flat = t.flatten();
assert_eq!(flat.shape(), &[4]);
Source

pub fn flattened(&self) -> Self

Return a flattened copy of the tensor.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4], vec![2, 2]).unwrap();
let flat = t.flattened();
assert_eq!(flat.shape(), &[4]);
assert_eq!(t.shape(), &[2, 2]); // original unchanged
Source

pub fn transpose(&self) -> Result<Self>

Transpose a 2-D tensor (matrix). Returns a new tensor with copied data.

For higher-rank tensors, use permute.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4, 5, 6], vec![2, 3]).unwrap();
let tt = t.transpose().unwrap();
assert_eq!(tt.shape(), &[3, 2]);
Source

pub fn permute(&self, axes: &[usize]) -> Result<Self>

Permute the dimensions of the tensor according to the given axes.

axes must be a permutation of 0..ndim.

§Examples
let t = Tensor::<i32>::arange(24).reshape(vec![2, 3, 4]).unwrap();
let p = t.permute(&[2, 0, 1]).unwrap();
assert_eq!(p.shape(), &[4, 2, 3]);
Source

pub fn unsqueeze(self, axis: usize) -> Result<Self>

Insert a dimension of size 1 at the given axis.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3], vec![3]).unwrap();
let t = t.unsqueeze(0).unwrap();
assert_eq!(t.shape(), &[1, 3]);
Source

pub fn squeeze(self) -> Self

Remove all dimensions of size 1.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3], vec![1, 3, 1]).unwrap();
let t = t.squeeze();
assert_eq!(t.shape(), &[3]);
Source

pub fn concat(tensors: &[&Tensor<T>], axis: usize) -> Result<Self>

Concatenate a list of tensors along the given axis.

All tensors must have the same shape except along the concatenation axis.

§Examples
let a = Tensor::from_vec(vec![1, 2, 3], vec![1, 3]).unwrap();
let b = Tensor::from_vec(vec![4, 5, 6], vec![1, 3]).unwrap();
let c = Tensor::concat(&[&a, &b], 0).unwrap();
assert_eq!(c.shape(), &[2, 3]);
Source

pub fn stack(tensors: &[&Tensor<T>], axis: usize) -> Result<Self>

Stack tensors along a new axis inserted at position axis.

All tensors must have identical shapes.

§Examples
let a = Tensor::from_vec(vec![1, 2, 3], vec![3]).unwrap();
let b = Tensor::from_vec(vec![4, 5, 6], vec![3]).unwrap();
let c = Tensor::stack(&[&a, &b], 0).unwrap();
assert_eq!(c.shape(), &[2, 3]);
Source§

impl<T: Scalar> Tensor<T>

Source

pub fn sort(&self) -> Tensor<T>

Sort all elements, returning a 1-D tensor in ascending order.

let t = Tensor::from_vec(vec![3, 1, 4, 1, 5], vec![5]).unwrap();
assert_eq!(t.sort().as_slice(), &[1, 1, 3, 4, 5]);
Source

pub fn argsort(&self) -> Tensor<usize>

Return indices that would sort all elements (flat), as a 1-D Tensor<usize>.

let t = Tensor::from_vec(vec![30, 10, 20], vec![3]).unwrap();
assert_eq!(t.argsort().as_slice(), &[1, 2, 0]);
Source

pub fn sort_axis(&self, axis: usize) -> Result<Tensor<T>>

Sort along a given axis, returning a new tensor with the same shape.

Each 1-D slice along axis is sorted independently in ascending order.

let t = Tensor::from_vec(vec![3, 1, 4, 2], vec![2, 2]).unwrap();
let s = t.sort_axis(1).unwrap(); // sort each row
assert_eq!(s.as_slice(), &[1, 3, 2, 4]);
Source

pub fn argsort_axis(&self, axis: usize) -> Result<Tensor<usize>>

Return indices that would sort each slice along axis.

The result has the same shape as self but element type usize.

let t = Tensor::from_vec(vec![3.0, 1.0, 4.0, 2.0], vec![2, 2]).unwrap();
let idx = t.argsort_axis(1).unwrap();
assert_eq!(idx.as_slice(), &[1, 0, 1, 0]);
Source§

impl<T: Scalar> Tensor<T>

Source

pub fn slice(&self, ranges: &[SliceRange]) -> Result<Self>

Extract a sub-tensor by slicing along each axis.

ranges must have exactly ndim elements. Each SliceRange specifies which indices to take along that axis.

Returns a new tensor with copied data.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4, 5, 6, 7, 8, 9], vec![3, 3]).unwrap();
let s = t.slice(&[SliceRange::range(0, 2), SliceRange::range(1, 3)]).unwrap();
assert_eq!(s.shape(), &[2, 2]);
assert_eq!(s.as_slice(), &[2, 3, 5, 6]);
Source

pub fn select(&self, axis: usize, index: usize) -> Result<Self>

Select a single index along the given axis, reducing dimensionality by 1.

For a 2-D tensor, select(0, i) returns row i as a 1-D tensor.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4, 5, 6], vec![2, 3]).unwrap();
let row = t.select(0, 1).unwrap();
assert_eq!(row.shape(), &[3]);
assert_eq!(row.as_slice(), &[4, 5, 6]);
Source§

impl<T: Scalar> Tensor<T>

Source

pub fn index_select(&self, axis: usize, indices: &[usize]) -> Result<Self>

Select elements along an axis using an array of indices.

Like numpy np.take(arr, indices, axis). For a tensor of shape [d0, d1, ..., dk, ...], selecting along axis k with indices of length m produces a tensor of shape [d0, ..., m, ..., dn].

§Examples
let t = Tensor::from_vec(vec![10, 20, 30, 40, 50], vec![5]).unwrap();
let s = t.index_select(0, &[4, 0, 2]).unwrap();
assert_eq!(s.as_slice(), &[50, 10, 30]);
Source

pub fn masked_select(&self, mask: &[bool]) -> Result<Self>

Select elements where mask is true, returning a flat 1-D tensor.

Like numpy arr[mask]. The mask length must equal the total number of elements in the tensor.

§Examples
let t = Tensor::from_vec(vec![10, 20, 30, 40, 50], vec![5]).unwrap();
let s = t.masked_select(&[true, false, true, false, true]).unwrap();
assert_eq!(s.as_slice(), &[10, 30, 50]);
Source

pub fn masked_select_along(&self, mask: &[bool]) -> Result<Self>

Select rows (slices along axis 0) where mask is true.

mask.len() must equal self.shape()[0]. The result has the same number of dimensions, with dimension 0 reduced to the count of true entries.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4, 5, 6], vec![3, 2]).unwrap();
let s = t.masked_select_along(&[false, true, true]).unwrap();
assert_eq!(s.shape(), &[2, 2]);
assert_eq!(s.as_slice(), &[3, 4, 5, 6]);
Source

pub fn index_put( &mut self, axis: usize, indices: &[usize], values: &Tensor<T>, ) -> Result<()>

Set elements along an axis at the given indices.

values must have the same shape as the result of self.index_select(axis, indices).

§Examples
let mut t = Tensor::from_vec(vec![1, 2, 3, 4, 5, 6], vec![2, 3]).unwrap();
let vals = Tensor::from_vec(vec![10, 20, 30], vec![1, 3]).unwrap();
t.index_put(0, &[0], &vals).unwrap();
assert_eq!(t.as_slice(), &[10, 20, 30, 4, 5, 6]);
Source

pub fn masked_put(&mut self, mask: &[bool], values: &[T]) -> Result<()>

Set elements where mask is true to corresponding values from values.

mask.len() must equal self.numel(), and values.len() must equal the number of true entries in the mask.

§Examples
let mut t = Tensor::from_vec(vec![1, 2, 3, 4, 5], vec![5]).unwrap();
t.masked_put(&[false, true, false, true, false], &[99, 88]).unwrap();
assert_eq!(t.as_slice(), &[1, 99, 3, 88, 5]);
Source

pub fn gather(&self, axis: usize, indices: &Tensor<usize>) -> Result<Tensor<T>>

Gather values along axis using an index tensor.

The indices tensor must have the same number of dimensions as self, and all dimensions except axis must match self’s shape. The output has the same shape as indices.

This is equivalent to PyTorch’s torch.gather.

§Examples
let t = Tensor::from_vec(vec![10, 20, 30, 40, 50, 60], vec![2, 3]).unwrap();
let idx = Tensor::from_vec(vec![2, 0, 1, 0], vec![2, 2]).unwrap();
let g = t.gather(1, &idx).unwrap();
assert_eq!(g.as_slice(), &[30, 10, 50, 40]);
Source§

impl<T: Scalar> Tensor<T>

Source

pub fn from_vec(data: Vec<T>, shape: Vec<usize>) -> Result<Self>

Create a tensor from a flat data vector and a shape.

Returns an error if the product of shape does not equal data.len().

§Examples
let t = Tensor::from_vec(vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0], vec![2, 3]).unwrap();
assert_eq!(t.shape(), &[2, 3]);
assert_eq!(t.numel(), 6);
Source

pub fn from_slice(data: &[T], shape: Vec<usize>) -> Result<Self>

Create a tensor from a flat slice and a shape (copies the data).

§Examples
let data = [1, 2, 3, 4];
let t = Tensor::from_slice(&data, vec![2, 2]).unwrap();
assert_eq!(t.shape(), &[2, 2]);
assert_eq!(*t.get(&[1, 0]).unwrap(), 3);
Source

pub fn scalar(value: T) -> Self

Create a scalar (0-dimensional) tensor.

§Examples
let t = Tensor::scalar(42.0_f64);
assert_eq!(t.ndim(), 0);
assert_eq!(t.numel(), 1);
assert_eq!(t.as_slice(), &[42.0]);
Source

pub fn shape(&self) -> &[usize]

The shape of the tensor as a slice.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4, 5, 6], vec![2, 3]).unwrap();
assert_eq!(t.shape(), &[2, 3]);
Source

pub fn strides(&self) -> &[usize]

The strides of the tensor as a slice (in number of elements).

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4, 5, 6], vec![2, 3]).unwrap();
assert_eq!(t.strides(), &[3, 1]);
Source

pub fn ndim(&self) -> usize

The number of dimensions (rank) of the tensor.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4, 5, 6], vec![2, 3]).unwrap();
assert_eq!(t.ndim(), 2);
Source

pub fn numel(&self) -> usize

The total number of elements.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4, 5, 6], vec![2, 3]).unwrap();
assert_eq!(t.numel(), 6);
Source

pub fn is_empty(&self) -> bool

Whether the tensor has zero elements.

§Examples
let empty = Tensor::<f64>::zeros(vec![0]);
assert!(empty.is_empty());
let nonempty = Tensor::<f64>::ones(vec![3]);
assert!(!nonempty.is_empty());
Source

pub fn as_slice(&self) -> &[T]

A flat slice of all elements in storage order.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3], vec![3]).unwrap();
assert_eq!(t.as_slice(), &[1, 2, 3]);
Source

pub fn as_mut_slice(&mut self) -> &mut [T]

A mutable flat slice of all elements in storage order.

§Examples
let mut t = Tensor::from_vec(vec![1, 2, 3], vec![3]).unwrap();
t.as_mut_slice()[0] = 99;
assert_eq!(t.as_slice(), &[99, 2, 3]);
Source

pub fn into_vec(self) -> Vec<T>

Consume the tensor and return the underlying Vec<T>.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3], vec![3]).unwrap();
let v: Vec<i32> = t.into_vec();
assert_eq!(v, vec![1, 2, 3]);
Source

pub fn get(&self, index: &[usize]) -> Result<&T>

Get a reference to the element at the given multi-dimensional index.

§Examples
let t = Tensor::from_vec(vec![10, 20, 30, 40], vec![2, 2]).unwrap();
assert_eq!(*t.get(&[0, 1]).unwrap(), 20);
assert_eq!(*t.get(&[1, 0]).unwrap(), 30);
Source

pub fn get_mut(&mut self, index: &[usize]) -> Result<&mut T>

Get a mutable reference to the element at the given index.

§Examples
let mut t = Tensor::from_vec(vec![1, 2, 3, 4], vec![2, 2]).unwrap();
*t.get_mut(&[0, 0]).unwrap() = 42;
assert_eq!(*t.get(&[0, 0]).unwrap(), 42);
Source

pub fn set(&mut self, index: &[usize], value: T) -> Result<()>

Set the element at the given multi-dimensional index.

§Examples
let mut t = Tensor::from_vec(vec![1, 2, 3, 4], vec![2, 2]).unwrap();
t.set(&[0, 1], 99).unwrap();
assert_eq!(*t.get(&[0, 1]).unwrap(), 99);
Source

pub fn iter(&self) -> impl Iterator<Item = &T>

Iterate over all elements in storage order.

§Examples
let t = Tensor::from_vec(vec![10, 20, 30], vec![3]).unwrap();
let sum: i32 = t.iter().sum();
assert_eq!(sum, 60);
Source

pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T>

Iterate mutably over all elements in storage order.

§Examples
let mut t = Tensor::from_vec(vec![1, 2, 3], vec![3]).unwrap();
for x in t.iter_mut() {
    *x *= 10;
}
assert_eq!(t.as_slice(), &[10, 20, 30]);
Source

pub fn map<F>(&self, f: F) -> Tensor<T>
where F: Fn(T) -> T,

Apply a function to every element, returning a new tensor.

§Examples
let t = Tensor::from_vec(vec![1, 2, 3, 4], vec![2, 2]).unwrap();
let doubled = t.map(|x| x * 2);
assert_eq!(doubled.as_slice(), &[2, 4, 6, 8]);
Source

pub fn cast<U: Scalar + Float>(&self) -> Tensor<U>
where T: Float,

Cast every element to a different scalar type, preserving shape.

Uses to_f64() / from_f64() for the conversion, which is lossless for f32→f64 and lossy (but intentionally so) for f64→f32 or f32→f16.

§Examples
let t = Tensor::from_vec(vec![1.0_f64, 2.0, 3.0], vec![3]).unwrap();
let t32: Tensor<f32> = t.cast();
assert_eq!(t32.as_slice(), &[1.0_f32, 2.0, 3.0]);
Source

pub fn zip_map<F>(&self, other: &Tensor<T>, f: F) -> Result<Tensor<T>>
where F: Fn(T, T) -> T,

Apply a function element-wise to two tensors of the same shape.

§Examples
let a = Tensor::from_vec(vec![1, 2, 3], vec![3]).unwrap();
let b = Tensor::from_vec(vec![10, 20, 30], vec![3]).unwrap();
let c = a.zip_map(&b, |x, y| x + y).unwrap();
assert_eq!(c.as_slice(), &[11, 22, 33]);
Source

pub fn apply<F>(&mut self, f: F)
where F: Fn(T) -> T,

Apply a function to every element in place.

§Examples
let mut t = Tensor::from_vec(vec![1, 2, 3, 4], vec![2, 2]).unwrap();
t.apply(|x| x * x);
assert_eq!(t.as_slice(), &[1, 4, 9, 16]);

Trait Implementations§

Source§

impl<T: Scalar> Add<T> for &Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the + operator.
Source§

fn add(self, rhs: T) -> Tensor<T>

Performs the + operation. Read more
Source§

impl<T: Scalar> Add<T> for Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the + operator.
Source§

fn add(self, rhs: T) -> Tensor<T>

Performs the + operation. Read more
Source§

impl<T: Scalar> Add for &Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the + operator.
Source§

fn add(self, rhs: &Tensor<T>) -> Tensor<T>

Performs the + operation. Read more
Source§

impl<T: Scalar> Add for Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the + operator.
Source§

fn add(self, rhs: Tensor<T>) -> Tensor<T>

Performs the + operation. Read more
Source§

impl<T: Scalar> AddAssign<&Tensor<T>> for Tensor<T>

Source§

fn add_assign(&mut self, rhs: &Tensor<T>)

Performs the += operation. Read more
Source§

impl<T: Scalar> AddAssign for Tensor<T>

Source§

fn add_assign(&mut self, rhs: Tensor<T>)

Performs the += operation. Read more
Source§

impl<T: Clone + Scalar> Clone for Tensor<T>

Source§

fn clone(&self) -> Tensor<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug + Scalar> Debug for Tensor<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Scalar> Display for Tensor<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Scalar> Div<T> for &Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the / operator.
Source§

fn div(self, rhs: T) -> Tensor<T>

Performs the / operation. Read more
Source§

impl<T: Scalar> Div<T> for Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the / operator.
Source§

fn div(self, rhs: T) -> Tensor<T>

Performs the / operation. Read more
Source§

impl<T: Scalar> Div for &Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the / operator.
Source§

fn div(self, rhs: &Tensor<T>) -> Tensor<T>

Performs the / operation. Read more
Source§

impl<T: Scalar> Div for Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the / operator.
Source§

fn div(self, rhs: Tensor<T>) -> Tensor<T>

Performs the / operation. Read more
Source§

impl<T: Scalar> DivAssign<&Tensor<T>> for Tensor<T>

Source§

fn div_assign(&mut self, rhs: &Tensor<T>)

Performs the /= operation. Read more
Source§

impl<T: Scalar> DivAssign for Tensor<T>

Source§

fn div_assign(&mut self, rhs: Tensor<T>)

Performs the /= operation. Read more
Source§

impl<T: Scalar> Mul<T> for &Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: T) -> Tensor<T>

Performs the * operation. Read more
Source§

impl<T: Scalar> Mul<T> for Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: T) -> Tensor<T>

Performs the * operation. Read more
Source§

impl<T: Scalar> Mul for &Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &Tensor<T>) -> Tensor<T>

Performs the * operation. Read more
Source§

impl<T: Scalar> Mul for Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Tensor<T>) -> Tensor<T>

Performs the * operation. Read more
Source§

impl<T: Scalar> MulAssign<&Tensor<T>> for Tensor<T>

Source§

fn mul_assign(&mut self, rhs: &Tensor<T>)

Performs the *= operation. Read more
Source§

impl<T: Scalar> MulAssign for Tensor<T>

Source§

fn mul_assign(&mut self, rhs: Tensor<T>)

Performs the *= operation. Read more
Source§

impl<T: Float> Neg for &Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the - operator.
Source§

fn neg(self) -> Tensor<T>

Performs the unary - operation. Read more
Source§

impl<T: Float> Neg for Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the - operator.
Source§

fn neg(self) -> Tensor<T>

Performs the unary - operation. Read more
Source§

impl<T: Scalar> PartialEq for Tensor<T>

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T: Scalar> Sub<T> for &Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: T) -> Tensor<T>

Performs the - operation. Read more
Source§

impl<T: Scalar> Sub<T> for Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: T) -> Tensor<T>

Performs the - operation. Read more
Source§

impl<T: Scalar> Sub for &Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: &Tensor<T>) -> Tensor<T>

Performs the - operation. Read more
Source§

impl<T: Scalar> Sub for Tensor<T>

Source§

type Output = Tensor<T>

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: Tensor<T>) -> Tensor<T>

Performs the - operation. Read more
Source§

impl<T: Scalar> SubAssign<&Tensor<T>> for Tensor<T>

Source§

fn sub_assign(&mut self, rhs: &Tensor<T>)

Performs the -= operation. Read more
Source§

impl<T: Scalar> SubAssign for Tensor<T>

Source§

fn sub_assign(&mut self, rhs: Tensor<T>)

Performs the -= operation. Read more

Auto Trait Implementations§

§

impl<T> Freeze for Tensor<T>

§

impl<T> RefUnwindSafe for Tensor<T>
where T: RefUnwindSafe,

§

impl<T> Send for Tensor<T>

§

impl<T> Sync for Tensor<T>

§

impl<T> Unpin for Tensor<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for Tensor<T>

§

impl<T> UnwindSafe for Tensor<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.