pyttb.tensor

Classes and functions for working with dense tensors.

class pyttb.tensor.tensor(data: ndarray | None = None, shape: int | Iterable[int] | None = None, copy: bool = True)[source]

Bases: object

Class for dense tensors.

Members

  • data: numpy.ndarray containing the data elements of the tensor stored, by default, in Fortran order

  • shape: tuple of integers containing the size of each mode of the tensor

Construct a pyttb.tensor.

Parameters:
  • data (optional) – Source data as numpy.ndarray (default: empty).

  • shape (optional) – Shape of the tensor as a tuple (default: data.shape()).

  • copy (optional) – Whether to copy (versus reference) the data (default: True).

Examples

For all examples in this document, the following module imports are assumed:

>>> import pyttb as ttb
>>> import numpy as np

Create a pyttb.tensor from a three-way numpy.ndarray:

>>> data = np.array([[[1,13],[5,17],[9,21]],
... [[2,14],[6,18],[10,22]],
... [[3,15],[7,19],[11,23]],
...  [[4,16],[8,20],[12,24]]])
>>> T = ttb.tensor(data)
>>> print(T)
tensor of shape (4, 3, 2) with order F
data[:, :, 0] =
[[ 1  5  9]
 [ 2  6 10]
 [ 3  7 11]
 [ 4  8 12]]
data[:, :, 1] =
[[13 17 21]
 [14 18 22]
 [15 19 23]
 [16 20 24]]

Create a pyttb.tensor from a numpy.ndarray vector and reshape it:

>>> data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
... 17, 18, 19, 20, 21, 22, 23, 24])
>>> T = ttb.tensor(data, shape=(4, 3, 2))
>>> print(T)
tensor of shape (4, 3, 2) with order F
data[:, :, 0] =
[[ 1  5  9]
 [ 2  6 10]
 [ 3  7 11]
 [ 4  8 12]]
data[:, :, 1] =
[[13 17 21]
 [14 18 22]
 [15 19 23]
 [16 20 24]]

Create an empty pyttb.tensor:

>>> T = ttb.tensor()
>>> print(T)
empty tensor of shape ()
data = []

See also

property order: Literal['F']

Return the data layout of the underlying storage.

The data layout is required to be Fortran.

classmethod from_function(function_handle: Callable[[Tuple[int, ...]], ndarray], shape: int | Iterable[int]) tensor[source]

Construct pyttb.tensor with data generated by given function.

Parameters:
  • function_handle – A function that takes a tuple of integers and returns a numpy.ndarray. The array should be in Fortran order to avoid data being copied. The data will be reshaped to the shape, so returning a vector of length equal to the product of the shape is fine.

  • shape – Shape of the resulting tensor; e.g., a tuple of integers.

Returns:

Constructed tensor.

Examples

Create a pyttb.tensor with entries drawn from a normal distribution using numpy.random.randn(). Observe that we actually generate a vector to avoid having a C-ordered array (the default if we had provided the shape array) be rearranged as a F-ordered array:

>>> randn = lambda s : np.random.randn(np.prod(s))
>>> np.random.seed(0) # reproducibility
>>> T = ttb.tensor.from_function(randn, (4, 3, 2))
>>> print(T)
tensor of shape (4, 3, 2) with order F
data[:, :, 0] =
[[ 1.76405235  1.86755799 -0.10321885]
 [ 0.40015721 -0.97727788  0.4105985 ]
 [ 0.97873798  0.95008842  0.14404357]
 [ 2.2408932  -0.15135721  1.45427351]]
data[:, :, 1] =
[[ 0.76103773  1.49407907 -2.55298982]
 [ 0.12167502 -0.20515826  0.6536186 ]
 [ 0.44386323  0.3130677   0.8644362 ]
 [ 0.33367433 -0.85409574 -0.74216502]]

Create a pyttb.tensor with all entries equal to 1 using numpy.ones(). Observe that we specifically specify Fortran order:

>>> T = ttb.tensor.from_function(lambda s: np.ones(s,order='F'), (2, 3, 4))
>>> print(T)
tensor of shape (2, 3, 4) with order F
data[:, :, 0] =
[[1. 1. 1.]
 [1. 1. 1.]]
data[:, :, 1] =
[[1. 1. 1.]
 [1. 1. 1.]]
data[:, :, 2] =
[[1. 1. 1.]
 [1. 1. 1.]]
data[:, :, 3] =
[[1. 1. 1.]
 [1. 1. 1.]]
copy() tensor[source]

Make a deep copy of a pyttb.tensor.

The standard copy of a tensor creates a shallow copy of the data. Any changes to the old or new tensor will affect the other. In contrast, the copy method creates a deep copy of the tensor which is totally independent of what it was copied from.

Returns:

Deep copy of original tensor.

Examples

Observing the difference between a shallow copy and a deep copy. When the original tensor changes, so does the shallow copy, but the deep copy does not:

>>> T = ttb.tensor(np.ones((3, 2)))
>>> T_shallow = T
>>> T_deep = T.copy()
>>> T[0, 0] = 3
>>> T[0, 0] == T_shallow[0, 0]
True
>>> T[0, 0] == T_deep[0, 0]
False
__deepcopy__(memo)[source]

Return deep copy of this tensor.

This a python construct to support copy operations; see https://docs.python.org/3/library/copy.html for details.

collapse(dims: int | float | Iterable[int] | Iterable[float] | ndarray | None = None, fun: Callable[[ndarray], float | ndarray] = np.sum) float | ndarray | tensor[source]

Collapse tensor along specified dimensions using a function.

Parameters:
  • dims (optional) – Dimensions to collapse (default: all).

  • fun (optional) – Method used to collapse dimensions (default: numpy.sum()).

Returns:

Scalar (if all dimensions collapsed) or tensor.

Examples

Sum all elements of tensor:

>>> T = ttb.tensor(np.ones((4,3,2),order='F'))
>>> T.collapse()
24.0

Compute the sum for each mode-0 fiber (output is a tensor):

>>> T.collapse(0)
tensor of shape (3, 2) with order F
data[:, :] =
[[4. 4.]
 [4. 4.]
 [4. 4.]]

Compute the sum of the entries in each mode-0 slice (output is a tensor):

>>> T.collapse([1, 2])
tensor of shape (4,) with order F
data[:] =
[6. 6. 6. 6.]

Compute the max entry in each mode-2 slice (output is a tensor):

>>> T.collapse([0, 1], np.max)
tensor of shape (2,) with order F
data[:] =
[1. 1.]

Find the maximum and minimum values in a tensor:

>>> randn = lambda s : np.random.randn(np.prod(s))
>>> np.random.seed(0) # reproducibility
>>> T = ttb.tensor.from_function(randn, (2, 2, 2))
>>> print(T)
tensor of shape (2, 2, 2) with order F
data[:, :, 0] =
[[1.76405235 0.97873798]
 [0.40015721 2.2408932 ]]
data[:, :, 1] =
[[ 1.86755799  0.95008842]
 [-0.97727788 -0.15135721]]
>>> max_val = T.collapse(fun=np.max)
>>> min_val = T.collapse(fun=np.min)
>>> print(f"Max value: {max_val}")
Max value: 2.240893199201458
>>> print(f"Min value: {min_val}")
Min value: -0.977277879876411
contract(i1: int, i2: int) ndarray | tensor[source]

Contract tensor along two dimensions (array trace).

Parameters:
  • i1 – First dimension

  • i2 – Second dimension

Returns:

Contracted tensor.

Examples

>>> T = ttb.tensor(np.ones((2, 2)))
>>> T.contract(0, 1)
2.0
>>> T = ttb.tensor(np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]))
>>> print(T)
tensor of shape (2, 2, 2) with order F
data[:, :, 0] =
[[1 3]
 [5 7]]
data[:, :, 1] =
[[2 4]
 [6 8]]
>>> T.contract(0, 1)
tensor of shape (2,) with order F
data[:] =
[ 8. 10.]
>>> T.contract(0, 2)
tensor of shape (2,) with order F
data[:] =
[ 7. 11.]
>>> T.contract(1, 2)
tensor of shape (2,) with order F
data[:] =
[ 5. 13.]
double() ndarray[source]

Convert :class:pyttb.tensor to an :class:numpy.ndarray of doubles.

Returns:

Copy of tensor data.

Examples

>>> T = ttb.tensor(np.ones((2, 2)))
>>> T.double()
array([[1., 1.],
       [1., 1.]])
exp() tensor[source]

Exponential of the elements of tensor.

Returns:

Copy of tensor data with the exponential function applied to data element-wise.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T.exp().data  
array([[ 2.7182...,  7.3890... ],
       [20.0855..., 54.5981...]])
find() Tuple[ndarray, ndarray][source]

Find subscripts of nonzero elements in a tensor.

Returns:

Array of subscripts of the nonzero values in the tensor and a column vector of the corresponding values.

Examples

>>> T = ttb.tensor(np.array([[1,2],[3,4]]))
>>> print(T)
tensor of shape (2, 2) with order F
data[:, :] =
[[1 2]
 [3 4]]
>>> T_threshold = T > 2
>>> subs, vals = T_threshold.find()
>>> subs.astype(int)
array([[1, 0],
       [1, 1]])
>>> vals
array([[ True],
       [ True]])
to_sptensor() sptensor[source]

Construct a pyttb.sptensor from :class:pyttb.tensor.

Returns:

Generated Sparse Tensor

Examples

>>> T = ttb.tensor(np.array([[0, 2], [3, 0]]))
>>> print(T)
tensor of shape (2, 2) with order F
data[:, :] =
[[0 2]
 [3 0]]
>>> S = T.to_sptensor()
>>> print(S)
sparse tensor of shape (2, 2) with 2 nonzeros and order F
[1, 0] = 3
[0, 1] = 2
full() tensor[source]

Convert dense tensor to dense tensor.

Returns:

Deep copy

to_tenmat(rdims: ndarray | None = None, cdims: ndarray | None = None, cdims_cyclic: Literal['fc'] | Literal['bc'] | Literal['t'] | None = None, copy: bool = True) tenmat[source]

Construct a pyttb.tenmat from a pyttb.tensor.

Parameters:
  • rdims – Mapping of row indices.

  • cdims – Mapping of column indices.

  • cdims_cyclic

    When only rdims is specified maps a single rdim to the rows and

    the remaining dimensions span the columns. _fc_ (forward cyclic) in the order range(rdims,self.ndims()) followed by range(0, rdims). _bc_ (backward cyclic) range(rdims-1, -1, -1) then range(self.ndims(), rdims, -1).

  • copy – Whether to make a copy of provided data or just reference it.

Notes

Forward cyclic is defined by Kiers [1] and backward cyclic is defined by

De Lathauwer, De Moor, and Vandewalle [2].

References

Examples

Create a pyttb.tensor.

>>> tshape = (2, 2, 2)
>>> data = np.reshape(np.arange(prod(tshape)), tshape)
>>> T = ttb.tensor(data)
>>> T  
tensor of shape (2, 2, 2) with order F
data[:, :, 0] =
[[0 2]
 [4 6]]
data[:, :, 1] =
[[1 3]
 [5 7]]
Convert to a pyttb.tenmat unwrapping around the first dimension.

Either allow for implicit column or explicit column dimension specification.

>>> TM1 = T.to_tenmat(rdims=np.array([0]))
>>> TM2 = T.to_tenmat(rdims=np.array([0]), cdims=np.array([1, 2]))
>>> TM1.isequal(TM2)
True
Convert using cyclic column ordering. For the three mode case _fc_ is the same

result.

>>> TM3 = T.to_tenmat(rdims=np.array([0]), cdims_cyclic="fc")
>>> TM3  
matrix corresponding to a tensor of shape (2, 2, 2)  with order F
rindices = [ 0 ] (modes of tensor corresponding to rows)
cindices = [ 1, 2 ] (modes of tensor corresponding to columns)
data[:, :] =
[[0 2 1 3]
 [4 6 5 7]]

Backwards cyclic reverses the order.

>>> TM4 = T.to_tenmat(rdims=np.array([0]), cdims_cyclic="bc")
>>> TM4  
matrix corresponding to a tensor of shape (2, 2, 2) with order F
rindices = [ 0 ] (modes of tensor corresponding to rows)
cindices = [ 2, 1 ] (modes of tensor corresponding to columns)
data[:, :] =
[[0 1 2 3]
 [4 5 6 7]]
innerprod(other: tensor | sptensor | ktensor | ttensor) float[source]

Efficient inner product between a tensor and other pyttb tensors.

Parameters:

other – Tensor to take an innerproduct with.

Examples

>>> T = ttb.tensor(np.array([[1.0, 0.0], [0.0, 4.0]]))
>>> T.innerprod(T)
17.0
>>> S = T.to_sptensor()
>>> T.innerprod(S)
17.0
isequal(other: tensor | sptensor) bool[source]

Exact equality for tensors.

Parameters:

other – Tensor to compare against.

Examples

>>> T1 = ttb.tensor(2 * np.ones((2, 2)))
>>> T2 = 2 * ttb.tensor(np.ones((2, 2)))
>>> T1.isequal(T2)
True
>>> T2[0, 0] = 1
>>> T1.isequal(T2)
False
issymmetric(grps: ndarray | None, version: Any | None, return_details: Literal[False]) bool[source]
issymmetric(grps: ndarray | None, version: Any | None, return_details: Literal[True]) Tuple[bool, ndarray, ndarray]

Determine if a dense tensor is symmetric in specified modes.

Parameters:
  • grps – Modes to check for symmetry

  • version – Any non-None value will call the non-default old version

  • return_details – Flag to return symmetry details in addition to bool

Returns:

If symmetric in modes, optionally all differences and permutations

Examples

>>> T = ttb.tensor(np.ones((2,2)))
>>> T.issymmetric()
True
>>> T.issymmetric(grps=np.arange(T.ndims))
True
>>> is_sym, diffs, perms =             T.issymmetric(grps=np.arange(T.ndims), version=1, return_details=True)
>>> print(f"Tensor is symmetric: {is_sym}")
Tensor is symmetric: True
>>> print(f"Differences in modes: {diffs}")
Differences in modes: [[0.]
 [0.]]
>>> print(f"Permutations: {perms}")
Permutations: [[0. 1.]
 [1. 0.]]
logical_and(other: float | tensor) tensor[source]

Logical and for tensors.

Parameters:

other – Value to perform and against.

Examples

>>> T = ttb.tenones((2, 2))
>>> T.logical_and(T).collapse()  # All true
4.0
logical_not() tensor[source]

Logical not for tensors.

Examples

>>> T = ttb.tenones((2, 2))
>>> T.logical_not().collapse()  # All false
0.0
logical_or(other: float | tensor) tensor[source]

Logical or for tensors.

Parameters:

other – Value to perform or against.

Examples

>>> T = ttb.tenones((2, 2))
>>> T.logical_or(T.logical_not()).collapse()  # All true
4.0
logical_xor(other: float | tensor) tensor[source]

Logical xor for tensors.

Parameters:

other – Value to perform xor against.

Examples

>>> T = ttb.tenones((2, 2))
>>> T.logical_xor(T.logical_not()).collapse()  # All true
4.0
mask(W: tensor) ndarray[source]

Extract non-zero values at locations specified by mask tensor W.

Parameters:

W – Mask tensor.

Returns:

Array of extracted values.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> W = ttb.tenones((2, 2))
>>> T.mask(W)
array([1, 3, 2, 4])
mttkrp(U: ktensor | Sequence[ndarray], n: int | integer) ndarray[source]

Matricized tensor times Khatri-Rao product.

The matrices used in the Khatri-Rao product are passed as a pyttb.ktensor (where the factor matrices are used) or as a list of numpy.ndarray objects.

Parameters:
  • U – Matrices to create the Khatri-Rao product.

  • n – Mode used to matricize tensor.

Returns:

Array containing matrix product.

Examples

>>> T = ttb.tenones((2, 2, 2))
>>> U = [np.ones((2, 2))] * 3
>>> T.mttkrp(U, 2)
array([[4., 4.],
       [4., 4.]])
mttkrps(U: ktensor | Sequence[ndarray]) List[ndarray][source]

Sequence of MTTKRP calculations for a tensor.

Result is equivalent to [T.mttkrp(U, k) for k in range(T.ndims)].

Parameters:

U – Matrices to create the Khatri-Rao product.

Returns:

Array containing matrix product.

Examples

>>> T = ttb.tenones((2, 2, 2))
>>> U = [np.ones((2, 2))] * 3
>>> T.mttkrps(U)
[array([[4., 4.],
       [4., 4.]]), array([[4., 4.],
       [4., 4.]]), array([[4., 4.],
       [4., 4.]])]
property ndims: int

Number of dimensions of the tensor.

Examples

>>> T = ttb.tenones((2, 2))
>>> T.ndims
2
property nnz: int

Number of non-zero elements in the tensor.

Examples

>>> T = ttb.tenones((2, 2, 2))
>>> T.nnz
8
norm() float[source]

Frobenius norm of the tensor.

Defined as the square root of the sum of the squares of the elements of the tensor.

Examples

>>> T = ttb.tenones((2, 2, 2, 2))
>>> T.norm()
4.0
nvecs(n: int, r: int, flipsign: bool = True) ndarray[source]

Compute the leading mode-n vectors of the tensor.

Computes the r leading eigenvectors of Tn*Tn.T (where Tn is the mode-n matricization/unfolding of self), which provides information about the mode-n fibers. In two-dimensions, the r leading mode-1 vectors are the same as the r left singular vectors and the r leading mode-2 vectors are the same as the r right singular vectors. By default, this method computes the top r eigenvectors of Tn*Tn.T.

Parameters:
  • n – Mode for tensor matricization.

  • r – Number of eigenvectors to compute and use.

  • flipsign – If True, make each column’s largest element positive.

Returns:

Computed eigenvectors.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T.nvecs(0, 1)  
array([[0.4045...],
       [0.9145...]])
>>> T.nvecs(0, 2)  
array([[ 0.4045...,  0.9145...],
       [ 0.9145..., -0.4045...]])
permute(order: int | float | Iterable[int] | Iterable[float] | ndarray) tensor[source]

Permute tensor dimensions.

The result is a tensor that has the same values, but the order of the subscripts needed to access any particular element are rearranged as specified by order.

Parameters:

order – New order of tensor dimensions.

Returns:

New tensor with permuted dimensions.

Examples

>>> T1 = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T1
tensor of shape (2, 2) with order F
data[:, :] =
[[1 2]
 [3 4]]
>>> T1.permute(np.array((1, 0)))
tensor of shape (2, 2) with order F
data[:, :] =
[[1 3]
 [2 4]]
reshape(shape: int | Iterable[int]) tensor[source]

Reshape the tensor.

Parameters:

shape – New shape

Examples

>>> T1 = ttb.tenones((2, 2))
>>> T1.shape
(2, 2)
>>> T2 = T1.reshape((4, 1))
>>> T2.shape
(4, 1)
scale(factor: ndarray | tensor, dims: float | ndarray) tensor[source]

Scale along specified dimensions for tensors.

Parameters:
  • factor (Scaling factor)

  • dims (Dimensions to scale)

Returns:

Scaled Tensor.

Examples

>>> T = ttb.tenones((3, 4, 5))
>>> S = np.arange(5)
>>> Y = T.scale(S, 2)
>>> Y.data[0, 0, :]
array([0., 1., 2., 3., 4.])
>>> S = ttb.tensor(np.arange(5))
>>> Y = T.scale(S, 2)
>>> Y.data[0, 0, :]
array([0., 1., 2., 3., 4.])
>>> S = ttb.tensor(np.arange(12), shape=(3, 4))
>>> Y = T.scale(S, [0, 1])
>>> Y.data[:, :, 0]
array([[ 0.,  3.,  6.,  9.],
       [ 1.,  4.,  7., 10.],
       [ 2.,  5.,  8., 11.]])
squeeze() tensor | float[source]

Remove singleton dimensions from the tensor.

Returns:

Tensor or scalar if all dims squeezed.

Examples

>>> T = ttb.tensor(np.array([[[4]]]))
>>> T.squeeze()
4
>>> T = ttb.tensor(np.array([[1, 2, 3]]))
>>> T.squeeze().data
array([1, 2, 3])
symmetrize(grps: ndarray | None = None, version: Any | None = None) tensor[source]

Symmetrize a tensor in the specified modes.

It is the same or less work to just call T = T.symmetrize() then to first check if T is symmetric and then symmetrize it, even if T is already symmetric.

Parameters:
  • grps – Modes to check for symmetry.

  • version – Any non-None value will call the non-default old version.

Returns:

Symmetrized tensor.

Examples

>>> T = ttb.tenones((2, 2, 2))
>>> T.symmetrize(np.array([0, 2]))
tensor of shape (2, 2, 2) with order F
data[:, :, 0] =
[[1. 1.]
 [1. 1.]]
data[:, :, 1] =
[[1. 1.]
 [1. 1.]]
ttm(matrix: ndarray | Sequence[ndarray], dims: int | float | Iterable[int] | Iterable[float] | ndarray | None = None, exclude_dims: int | float | Iterable[int] | Iterable[float] | ndarray | None = None, transpose: bool = False) tensor[source]

Tensor times matrix.

Computes the n-mode product of self with the matrix matrix; i.e., self x_n matrix. The integer n specifies the dimension (or mode) along which the matrix should be multiplied. If matrix.shape = (J,I), then the tensor must have self.shape[n] = I. The result will be the same order and shape as self except that the size of dimension n will be J.

Multiplication with more than one matrix is provided using a list of matrices and corresponding dimensions in the tensor to use. Multiplication using the transpose of the matrix (or matrices) is also provided.

The dimensions of the tensor with which to multiply can be provided as dims, or the dimensions to exclude from [0, …, self.ndims] can be specified using exclude_dims.

Parameters:
  • matrix – Matrix or matrices to multiple by.

  • dims – Dimensions to multiply against.

  • exclude_dims – Use all dimensions but these.

  • transpose – Transpose matrices during multiplication.

Returns:

Tensor product.

Examples

>>> T = ttb.tenones((2, 2, 2, 2))
>>> A = 2 * np.ones((2, 1))
>>> T.ttm([A, A], dims=[0, 1], transpose=True)
tensor of shape (1, 1, 2, 2) with order F
data[:, :, 0, 0] =
[[16.]]
data[:, :, 1, 0] =
[[16.]]
data[:, :, 0, 1] =
[[16.]]
data[:, :, 1, 1] =
[[16.]]
>>> T.ttm([A, A], exclude_dims=[0, 1], transpose=True)
tensor of shape (2, 2, 1, 1) with order F
data[:, :, 0, 0] =
[[16. 16.]
 [16. 16.]]
ttt(other: tensor, selfdims: ndarray | int | None = None, otherdims: ndarray | int | None = None) tensor[source]

Tensor multiplication (tensor times tensor).

Computes the contracted product of tensors, self and other, in the dimensions specified by the selfdims and otherdims. The sizes of the dimensions specified by selfdims and otherdims must match; that is, self.shape(selfdims) must equal other.shape(otherdims). If only selfdims is provided as input, it is used to specify the dimensions for both self and other.

Parameters:
  • other – Tensor to multiply by.

  • selfdims – Dimensions to contract self by for multiplication.

  • otherdims – Dimensions to contract other tensor by for multiplication.

Returns:

Tensor product.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T.ttt(T)
tensor of shape (2, 2, 2, 2) with order F
data[:, :, 0, 0] =
[[1 2]
 [3 4]]
data[:, :, 1, 0] =
[[ 3  6]
 [ 9 12]]
data[:, :, 0, 1] =
[[2 4]
 [6 8]]
data[:, :, 1, 1] =
[[ 4  8]
 [12 16]]
>>> T.ttt(T, 0)
tensor of shape (2, 2) with order F
data[:, :] =
[[10 14]
 [14 20]]
>>> T.ttt(T, selfdims=0, otherdims=1)
tensor of shape (2, 2) with order F
data[:, :] =
[[ 7 15]
 [10 22]]
ttv(vector: ndarray | Sequence[ndarray], dims: int | float | Iterable[int] | Iterable[float] | ndarray | None = None, exclude_dims: int | float | Iterable[int] | Iterable[float] | ndarray | None = None) float | tensor[source]

Tensor times vector.

Computes the n-mode product of self with the vector vector; i.e., self x_n vector. The integer n specifies the dimension (or mode) along which the vector should be multiplied. If vector.shape = (I,), then the tensor must have self.shape[n] = I. The result will be the same order and shape as self except that the size of dimension n will be J. The resulting tensor has one less dimension, as dimension n is removed in the multiplication.

Multiplication with more than one vector is provided using a list of vectors and corresponding dimensions in the tensor to use.

The dimensions of the tensor with which to multiply can be provided as dims, or the dimensions to exclude from [0, …, self.ndims] can be specified using exclude_dims.

Parameters:
  • vector – Vector or vectors to multiply by.

  • dims – Dimensions to multiply against.

  • exclude_dims – Use all dimensions but these.

Returns:

Tensor product.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T.ttv(np.ones(2), 0)
tensor of shape (2,) with order F
data[:] =
[4. 6.]
>>> T.ttv(np.ones(2), 1)
tensor of shape (2,) with order F
data[:] =
[3. 7.]
>>> T.ttv([np.ones(2), np.ones(2)])
10.0
ttsv(vector: int | float | Iterable[int] | Iterable[float] | ndarray, skip_dim: int | None = None, version: int | None = None) float | ndarray | tensor[source]

Tensor times same vector in multiple modes.

See ttv() for details on multiplication of a tensor with a vector. When skip_dim is provided, multiply the vector by all but dimensions except [0, …, skip_dim].

Parameters:
  • vector – Vector to multiply by.

  • skip_dim – Initial dimensions of the tensor to skip when multiplying.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T.ttsv(np.ones(2))
10.0
>>> T.ttsv(np.ones(2), 0)
array([3., 7.])
>>> T.ttsv(np.ones(2), 1)
array([[1, 2],
       [3, 4]])
tenfun(function_handle: Callable[[ndarray, ndarray], ndarray] | Callable[[ndarray], ndarray], *inputs: float | int | ndarray | tensor | ktensor | ttensor | sptensor | sumtensor) tensor[source]

Apply a function to each element in a tensor or tensors.

See pyttb.tensor.tenfun_binary() and pyttb.tensor.tenfun_binary_unary() for supported options.

tenfun_binary(function_handle: Callable[[ndarray, ndarray], ndarray], other: tensor | int | float, first: bool = True) tensor[source]

Apply a binary operation to two tensors or a tensor and a scalar.

Parameters:
  • function_handle (Function to apply.)

  • other (Other input to the binary function.)

  • first (Whether the tensor comes first in the method call (if ordering matters).)

Example

>>> add = lambda x, y: x + y
>>> t0 = ttb.tenones((2, 2))
>>> t1 = t0.tenfun_binary(add, t0)
>>> t1.isequal(t0 * 2)
True
>>> t2 = t0.tenfun_binary(add, 1)
>>> t2.isequal(t1)
True
tenfun_unary(function_handle: Callable[[ndarray], ndarray], *inputs: tensor) tensor[source]

Apply a unary operation to multiple tensors columnwise.

Example

>>> tensor_max = lambda x: np.max(x, axis=0)
>>> data = np.array([[1, 2, 3], [4, 5, 6]])
>>> t0 = ttb.tensor(data)
>>> t1 = ttb.tensor(data)
>>> t2 = t0.tenfun_unary(tensor_max, t1)
>>> t2.isequal(t1)
True
__setitem__(key, value)[source]

Subscripted assignment for a tensor.

We can assign elements to a tensor in three ways.

Case 1: T[R1,R2,…,Rn] = Y, in which case we replace the rectangular subtensor (or single element) specified by the ranges R1,…,`Rn` with Y. The right-hand-side can be a scalar, a tensor, or a numpy.ndarray.

Case 2a: T[S] = V, where S is a p x n array of subscripts and V is a scalar or a vector containing p values.

Case 2b: T[I] = V, where I is a set of p linear indices and V is a scalar or a vector containing p values. Resizing is not allowed in this case.

Examples

>>> T = tenones((3, 4, 2))
>>> # replaces subtensor
>>> T[0:2, 0:2, 0] = np.ones((2, 2))
>>> # replaces two elements
>>> T[np.array([[1, 1, 1], [1, 1, 2]])] = [5, 7]
>>> # replaces two elements with linear indices
>>> T[np.array([1, 13])] = [5, 7]
>>> # grows tensor to accept new element
>>> T[1, 1, 2:3] = 1
>>> T[1, 1, 4] = 1
__getitem__(item)[source]

Subscripted reference for tensors.

We can extract elements or subtensors from a tensor in the following ways.

Case 1a: y = T[I1,I2,…,In], where each I is an index, returns a scalar.

Case 1b: Y = T[R1,R2,…,Rn], where one or more R is a range and the rest are indices, returns a tensor.

Case 2a: V = T[S] where S is a p x n array of subscripts, returns a vector of p values.

Case 2b: V = T[I] where I is a set of p linear indices, returns a vector of p values.

Any ambiguity results in executing the first valid case. This is particularly an issue if self.ndims == 1.

Examples

>>> T = tenones((3, 4, 2, 1))
>>> T[0, 0, 0, 0]  # produces a scalar
1.0
>>> # produces a tensor of order 1 and size 1
>>> T[1, 1, 1, :]  
tensor of shape (1,) with order F
data[:] =
[1.]
>>> # produces a tensor of size 2 x 2 x 1
>>> T[0:2, [2, 3], 1, :]  
tensor of shape (2, 2, 1) with order F
data[:, :, 0] =
[[1. 1.]
 [1. 1.]]
>>> # returns a vector of length 2
>>> # Equivalent to selecting [0,0,0,0] and [1,1,1,0] separately
>>> T[np.array([[0, 0, 0, 0], [1, 1, 1, 0]])]
array([1., 1.])
>>> T[[0, 1, 2]]  # extracts the first three linearized indices
array([1., 1., 1.])
__eq__(other)[source]

Equal for tensors (element-wise).

Parameters:

other (pyttb.tensor, float, int)

Returns:

pyttb.tensor of bool.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T == T
tensor of shape (2, 2) with order F
data[:, :] =
[[ True  True]
 [ True  True]]
>>> T == 1
tensor of shape (2, 2) with order F
data[:, :] =
[[ True False]
 [False False]]
__ne__(other)[source]

Not equal (!=) for tensors (element-wise).

Parameters:

other (pyttb.tensor, float, int)

Returns:

pyttb.tensor of bool.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T != T
tensor of shape (2, 2) with order F
data[:, :] =
[[False False]
 [False False]]
>>> T != 1
tensor of shape (2, 2) with order F
data[:, :] =
[[False  True]
 [ True  True]]
__ge__(other)[source]

Greater than or equal (>=) for tensors (element-wise).

Parameters:

other (pyttb.tensor, float, int)

Returns:

pyttb.tensor of bool.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T >= T
tensor of shape (2, 2) with order F
data[:, :] =
[[ True  True]
 [ True  True]]
>>> T >= 1
tensor of shape (2, 2) with order F
data[:, :] =
[[ True  True]
 [ True  True]]
__le__(other)[source]

Less than or equal (<=) for tensors (element-wise).

Parameters:

other (pyttb.tensor, float, int)

Returns:

pyttb.tensor of bool.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T <= T
tensor of shape (2, 2) with order F
data[:, :] =
[[ True  True]
 [ True  True]]
>>> T <= 1
tensor of shape (2, 2) with order F
data[:, :] =
[[ True False]
 [False False]]
__gt__(other)[source]

Greater than (>) for tensors (element-wise).

Parameters:

other (pyttb.tensor, float, int)

Returns:

pyttb.tensor of bool.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T > T
tensor of shape (2, 2) with order F
data[:, :] =
[[False False]
 [False False]]
>>> T > 1
tensor of shape (2, 2) with order F
data[:, :] =
[[False  True]
 [ True  True]]
__lt__(other)[source]

Less than (<) for tensors (element-wise).

Parameters:

other (pyttb.tensor, float, int)

Returns:

pyttb.tensor of bool.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T < T
tensor of shape (2, 2) with order F
data[:, :] =
[[False False]
 [False False]]
>>> T < 1
tensor of shape (2, 2) with order F
data[:, :] =
[[False False]
 [False False]]
__sub__(other)[source]

Binary subtraction (-) for tensors.

Parameters:

other (pyttb.tensor, float, int)

Returns:

pyttb.tensor

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T - T
tensor of shape (2, 2) with order F
data[:, :] =
[[0 0]
 [0 0]]
>>> T - 1
tensor of shape (2, 2) with order F
data[:, :] =
[[0 1]
 [2 3]]
__add__(other)[source]

Binary addition (+) for tensors.

Parameters:

other (pyttb.tensor, float, int)

Returns:

pyttb.tensor

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T + T
tensor of shape (2, 2) with order F
data[:, :] =
[[2 4]
 [6 8]]
>>> T + 1
tensor of shape (2, 2) with order F
data[:, :] =
[[2 3]
 [4 5]]
__radd__(other)[source]

Right binary addition (+) for tensors.

Parameters:

other (pyttb.tensor, float, int)

Returns:

pyttb.tensor

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> 1 + T
tensor of shape (2, 2) with order F
data[:, :] =
[[2 3]
 [4 5]]
__pow__(power)[source]

Element-wise Power (**) for tensors.

Parameters:

other (pyttb.tensor, float, int)

Returns:

pyttb.tensor

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T**2
tensor of shape (2, 2) with order F
data[:, :] =
[[ 1  4]
 [ 9 16]]
__mul__(other)[source]

Element-wise multiplication (*) for tensors, self*other.

Parameters:

other (pyttb.tensor, float, int)

Returns:

pyttb.tensor

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T * T
tensor of shape (2, 2) with order F
data[:, :] =
[[ 1  4]
 [ 9 16]]
>>> T * 2
tensor of shape (2, 2) with order F
data[:, :] =
[[2 4]
 [6 8]]
__rmul__(other)[source]

Element wise right multiplication (*) for tensors, other*self.

Parameters:

other (pyttb.tensor, float, int)

Returns:

pyttb.tensor

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> 2 * T
tensor of shape (2, 2) with order F
data[:, :] =
[[2 4]
 [6 8]]
__truediv__(other)[source]

Element-wise left division (/) for tensors, self/other.

Parameters:

other (pyttb.tensor, float, int)

Returns:

pyttb.tensor

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T / T
tensor of shape (2, 2) with order F
data[:, :] =
[[1. 1.]
 [1. 1.]]
>>> T / 2
tensor of shape (2, 2) with order F
data[:, :] =
[[0.5 1. ]
 [1.5 2. ]]
__rtruediv__(other)[source]

Element wise right division (/) for tensors, other/self.

Parameters:

other (pyttb.tensor, float, int)

Returns:

pyttb.tensor

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> np.set_printoptions(precision=8)
>>> 2 / T  
tensor of shape (2, 2) with order F
data[:, :] =
[[2.         1.        ]
 [0.66666... 0.5       ]]
__pos__()[source]

Unary plus (+) for tensors.

Returns:

Copy of tensor.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> +T
tensor of shape (2, 2) with order F
data[:, :] =
[[1 2]
 [3 4]]
__neg__()[source]

Unary minus (-) for tensors.

Returns:

Copy of negated tensor.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> -T
tensor of shape (2, 2) with order F
data[:, :] =
[[-1 -2]
 [-3 -4]]
__repr__()[source]

Return string representation of the tensor.

Returns:

String displaying shape and data as strings on different lines.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T
tensor of shape (2, 2) with order F
data[:, :] =
[[1 2]
 [3 4]]
__str__()

Return string representation of the tensor.

Returns:

String displaying shape and data as strings on different lines.

Examples

>>> T = ttb.tensor(np.array([[1, 2], [3, 4]]))
>>> T
tensor of shape (2, 2) with order F
data[:, :] =
[[1 2]
 [3 4]]
__hash__ = None
pyttb.tensor.tenones(shape: int | Iterable[int], order: Literal['F', 'C'] = 'F') tensor[source]

Create a tensor of all ones.

Parameters:
  • shape – Shape of resulting tensor.

  • order (optional) – Memory layout for resulting tensor (default: F). Note: C order is not recommended.

Returns:

Constructed tensor.

Examples

>>> T = ttb.tenones((3,))
>>> T
tensor of shape (3,) with order F
data[:] =
[1. 1. 1.]
>>> T = ttb.tenones((3, 3))
>>> T
tensor of shape (3, 3) with order F
data[:, :] =
[[1. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]

See also

  • pyttb.tensor.from_function() - Create a tensor from a function.

pyttb.tensor.tenzeros(shape: int | Iterable[int], order: Literal['F', 'C'] = 'F') tensor[source]

Create a tensor of all zeros.

Parameters:
  • shape – Shape of resulting tensor.

  • order (optional) – Memory layout for resulting tensor (default: F). Note: C order is not recommended.

Returns:

Constructed tensor.

Examples

>>> T = ttb.tenzeros((3,))
>>> T
tensor of shape (3,) with order F
data[:] =
[0. 0. 0.]
>>> T = ttb.tenzeros((3, 3))
>>> T
tensor of shape (3, 3) with order F
data[:, :] =
[[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]
pyttb.tensor.tenrand(shape: int | Iterable[int], order: Literal['F', 'C'] = 'F') tensor[source]

Create a tensor with entries drawn from a uniform distribution on [0, 1].

Parameters:
  • shape – Shape of resulting tensor.

  • order (optional) – Memory layout for resulting tensor (default: F). Note: C order is not recommended.

Returns:

Constructed tensor.

Examples

>>> np.random.seed(1)
>>> T = ttb.tenrand((3,))
>>> T  
tensor of shape (3,) with order F
data[:] =
[4.170...e-01 7.203...e-01 1.143...e-04]
pyttb.tensor.tendiag(elements: int | float | Iterable[int] | Iterable[float] | ndarray, shape: int | Iterable[int] | None = None, order: Literal['F', 'C'] = 'F') tensor[source]

Create a tensor with elements along super diagonal.

If provided shape is too small the tensor will be enlarged to accommodate.

Parameters:
  • elements – Elements to set along the diagonal.

  • shape – Shape of resulting tensor.

  • order – Memory layout for resulting tensor.

Returns:

Constructed tensor.

Examples

>>> shape = (3,)
>>> values = np.ones(shape)
>>> T1 = ttb.tendiag(values)
>>> T2 = ttb.tendiag(values, (3, 3, 3))
>>> T1.isequal(T2)
True
pyttb.tensor.teneye(ndims: int, size: int, order: Literal['F', 'C'] = 'F') tensor[source]

Create identity tensor of specified shape.

T is an “identity tensor if T.ttsv(x, skip_dim=0) = x for all x such that norm(x) == 1.

An identity tensor only exists if order is even. This method is resource intensive for even moderate orders or sizes (>=6).

Parameters:
  • ndims (Number of dimensions of tensor.)

  • size (Number of elements in any dimension of the tensor.)

  • order – Memory layout for resulting tensor.

Examples

>>> ttb.teneye(2, 3)
tensor of shape (3, 3) with order F
data[:, :] =
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]
>>> x = np.ones((5,))
>>> x /= np.linalg.norm(x)
>>> T = ttb.teneye(4, 5)
>>> np.allclose(T.ttsv(x, 0), x)
True
Returns:

Identity tensor.