pyttb.sptensor

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

Bases: object

SPTENSOR Class for sparse tensors.

Contains the following data members:

subs: subscripts of the nonzero values in the sparse tensor. Row k specifies the subscripts of the k-th value in vals.

vals: data elements of the sparese tensor.

shape: sizes of the dimensions of the sparse tensor.

Instances of pyttb.sptensor can be created using __init__() or the following methods:

Examples

For all examples listed below, the following module imports are assumed:

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

Construct a pyttb.sptensor.

Constructed from a set of subs (subscripts),

vals (values), and shape. No validation is performed. For initializer with error checking see from_aggregator().

Parameters:
  • subs – Subscripts of nonzero entries.

  • vals – Values for nonzero entries.

  • shape – Shape of sparse tensor.

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

Examples

Create an empty pyttb.sptensor:

>>> shape = (4, 4, 4)
>>> S = ttb.sptensor(shape=shape)
>>> S
empty sparse tensor of shape (4, 4, 4) with order F

Create a pyttb.sptensor from subscripts and values:

>>> subs = np.array([[1, 2, 1], [1, 3, 1]])
>>> vals = np.array([[6], [7]])
>>> S = ttb.sptensor(subs, vals, shape)
>>> S
sparse tensor of shape (4, 4, 4) with 2 nonzeros and order F
[1, 2, 1] = 6
[1, 3, 1] = 7
classmethod from_function(function_handle: Callable[[Tuple[int, ...]], ndarray], shape: int | Iterable[int], nonzeros: float) sptensor[source]

Construct a pyttb.sptensor.

Constructed with nonzeros set using a function. The subscripts of the nonzero elements of the sparse tensor are generated randomly using numpy, so calling numpy.random.seed() before using this method will provide reproducible results.

Parameters:
  • function_handle – A function that can accept a shape (i.e., tuple of dimension sizes) and return a numpy.ndarray of that shape. Example functions include numpy.random.random_sample, numpy.zeros, and numpy.ones.

  • shape – Shape of generated sparse tensor.

  • nonzeros – Number of nonzeros in generated sparse tensor.

Examples

Create a pyttb.sptensor with entries taken from a uniform random distribution:

>>> np.random.seed(1)
>>> S = ttb.sptensor.from_function(np.random.random_sample, (2, 3, 4), 5)
>>> print(S)  
sparse tensor of shape (2, 3, 4) with 5 nonzeros and order F
[0, 1, 3] = 0.4478...
[0, 2, 0] = 0.9085...
[1, 2, 0] = 0.2936...
[1, 2, 1] = 0.2877...
[1, 2, 2] = 0.1300...

Create a pyttb.sptensor with entries equal to 1:

>>> np.random.seed(1)
>>> S = ttb.sptensor.from_function(np.ones, (2, 3, 4), 5)
>>> print(S)
sparse tensor of shape (2, 3, 4) with 5 nonzeros and order F
[0, 1, 3] = 1.0
[0, 2, 0] = 1.0
[1, 2, 0] = 1.0
[1, 2, 1] = 1.0
[1, 2, 2] = 1.0
classmethod from_aggregator(subs: ndarray, vals: ndarray, shape: int | Iterable[int] | None = None, function_handle: str | Callable[[Any], float | ndarray] = 'sum') sptensor[source]

Construct a pyttb.sptensor.

Constructed from a set of subs (subscripts),

vals (values), and shape after an aggregation function is applied to the values.

Parameters:
  • subs – Subscripts of nonzero entries.

  • vals – Values for nonzero entries.

  • shape – Shape of sparse tensor.

  • function_handle – Aggregation function, or name of supported aggregation function from numpy_groupies.

Examples

Create a pyttb.sptensor with some duplicate subscripts and use an aggregator function. The default aggregator is sum. The shape of the sparse tensor is inferred from the subscripts.

>>> subs = np.array([[1, 2], [1, 3], [1, 3]])
>>> vals = np.array([[6], [7], [8]])
>>> shape = (4, 4)
>>> S = ttb.sptensor.from_aggregator(subs, vals)
>>> print(S)
sparse tensor of shape (2, 4) with 2 nonzeros and order F
[1, 2] = 6
[1, 3] = 15

Create another pyttb.sptensor but specify the shape explicitly.

>>> S = ttb.sptensor.from_aggregator(subs, vals, shape)
>>> print(S)
sparse tensor of shape (4, 4) with 2 nonzeros and order F
[1, 2] = 6
[1, 3] = 15

Create another pyttb.sptensor but aggregate using the mean of values corresponding to duplicate subscripts.

>>> S3 = ttb.sptensor.from_aggregator(
...     subs, vals, shape, function_handle=np.mean
... )
>>> print(S3)
sparse tensor of shape (4, 4) with 2 nonzeros and order F
[1, 2] = 6.0
[1, 3] = 7.5
copy() sptensor[source]

Return a deep copy of the pyttb.sptensor.

Examples

Create a pyttb.sptensor (S1) and make a deep copy. Verify the deep copy (S3) is not just a reference (like S2) to the original.

>>> S1 = ttb.sptensor(shape=(2, 2))
>>> S1[0, 0] = 1
>>> S2 = S1
>>> S3 = S1.copy()
>>> S1[0, 0] = 3
>>> S1[0, 0] == S2[0, 0]
True
>>> S1[0, 0] == S3[0, 0]
False
property order: Literal['F']

Return the data layout of the underlying storage.

__deepcopy__(memo)[source]

Return deep copy of this sptensor.

allsubs() ndarray[source]

Generate all possible subscripts for the pyttb.sptensor.

Examples

Create an empty pyttb.sptensor and generate all subscripts:

>>> S = ttb.sptensor(shape=(2, 2))
>>> S.allsubs()
array([[0, 0],
       [0, 1],
       [1, 0],
       [1, 1]])
collapse(dims: int | float | Iterable[int] | Iterable[float] | ndarray | None = None, function_handle: Callable[[ndarray], float | ndarray] = sum) float | ndarray | sptensor[source]

Collapse the pyttb.sptensor along specified dimensions.

Parameters:
  • dims – Dimensions to collapse.

  • function_handle – Function used to collapse dimensions.

Examples

Create a pyttb.sptensor with two elements:

>>> subs = np.array([[0, 0, 0], [0, 1, 0]])
>>> vals = np.array([[6.0], [7.0]])
>>> shape = (1, 2, 1)
>>> S = ttb.sptensor(subs, vals, shape)

Collapse across all dimensions, resulting in a scalar value:

>>> S.collapse()
13.0

Collapse across a single dimension, resulting in a pyttb.sptensor:

>>> S.collapse(dims=np.array([0]))
sparse tensor of shape (2, 1) with 2 nonzeros and order F
[0, 0] = 6.0
[1, 0] = 7.0

Collapse across all but one dimension, resulting in a numpy.ndarray:

>>> S.collapse(dims=np.array([0, 2]))
array([6., 7.])
contract(i_0: int, i_1: int) ndarray | sptensor | tensor[source]

Contract the pyttb.sptensor along two dimensions.

If the result is sufficiently dense, it is returned as a pyttb.tensor.

Parameters:
  • i_0 – First dimension.

  • i_1 – Second dimension.

Examples

Create a pyttb.sptensor from a pyttb.tensor and contract, resulting in a dense tensor, since the result is dense:

>>> T = ttb.tensor(np.ones((2, 2, 2)))
>>> S = T.to_sptensor()
>>> S.contract(0, 1)
tensor of shape (2,) with order F
data[:] =
[2. 2.]

Create a pyttb.sptensor and contract, resulting in a pyttb.sptensor since the result is sparse:

>>> subs = np.array([[1, 1, 1], [2, 2, 2]])
>>> vals = np.array([[0.5], [1.5]])
>>> shape = (4, 4, 4)
>>> S = ttb.sptensor(subs, vals, shape)
>>> S.contract(1, 2)
sparse tensor of shape (4,) with 2 nonzeros and order F
[1] = 0.5
[2] = 1.5
double() ndarray[source]

Convert the pyttb.sptensor to a numpy.ndarray.

Examples

Create a pyttb.sptensor with two elements and convert it to a numpy.ndarray:

>>> S = ttb.sptensor()
>>> S[0, 1] = 1.5
>>> S
sparse tensor of shape (1, 2) with 1 nonzeros and order F
[0, 1] = 1.5
>>> S.double()
array([[0. , 1.5]])
elemfun(function_handle: Callable[[ndarray], ndarray]) sptensor[source]

Apply a function to the nonzero elements of the pyttb.sptensor.

Returns a copy of the sparse tensor, with the updated values.

Parameters:

function_handle – Function to apply to all values.

Examples

Create a the pyttb.sptensor and multiply each nonzero element by 2:

>>> S1 = ttb.sptensor()
>>> S1[2, 2, 2] = 1.5
>>> S2 = S1.elemfun(lambda values: values * 2)
>>> S2
sparse tensor of shape (3, 3, 3) with 1 nonzeros and order F
[2, 2, 2] = 3.0
extract(searchsubs: ndarray) ndarray[source]

Extract value from the pyttb.sptensor.

Parameters:

searchsubs – subscripts to find.

See also

__getitem__()

find() Tuple[ndarray, ndarray][source]

Find subscripts of nonzero elements in the pyttb.sptensor.

Examples

>>> S = ttb.sptensor()
>>> S[0, 1] = 1
>>> S.find()
(array([[0, 1]]), array([[1.]]))
to_tensor() tensor[source]

Convert to dense tensor.

Same as pyttb.sptensor.full().

full() tensor[source]

Convert the pyttb.sptensor to a pyttb.tensor.

Examples

Create a pyttb.sptensor and convert it to a pyttb.tensor:

>>> S = ttb.sptensor()
>>> S[1, 1] = 1
>>> S.to_tensor()
tensor of shape (2, 2) with order F
data[:, :] =
[[0. 0.]
 [0. 1.]]
to_sptenmat(rdims: ndarray | None = None, cdims: ndarray | None = None, cdims_cyclic: Literal['fc'] | Literal['bc'] | Literal['t'] | None = None) sptenmat[source]

Construct a pyttb.sptenmat from a pyttb.sptensor.

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[1]_) in the order range(rdims,self.ndims()) followed by range(0, rdims). _bc_ (backward cyclic[2]_) range(rdims-1, -1, -1) then range(self.ndims(), rdims, -1).

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

>>> subs = np.array([[1, 2, 1], [1, 3, 1]])
>>> vals = np.array([[6], [7]])
>>> tshape = (4, 4, 4)
>>> S = ttb.sptensor(subs, vals, tshape)
Convert to a pyttb.sptenmat unwrapping around the first dimension.

Either allow for implicit column or explicit column dimension specification.

>>> ST1 = S.to_sptenmat(rdims=np.array([0]))
>>> ST2 = S.to_sptenmat(rdims=np.array([0]), cdims=np.array([1, 2]))
>>> ST1.isequal(ST2)
True
Convert using cyclic column ordering. For the three mode case _fc_ is the same

result.

>>> ST3 = S.to_sptenmat(rdims=np.array([0]), cdims_cyclic="fc")
>>> ST3  
sptenmat corresponding to a sptensor of shape (4, 4, 4) with 2 nonzeros         and order F
rdims = [ 0 ] (modes of sptensor corresponding to rows)
cdims = [ 1, 2 ] (modes of sptensor corresponding to columns)
    [1, 6] = 6
    [1, 7] = 7

Backwards cyclic reverses the order.

>>> ST4 = S.to_sptenmat(rdims=np.array([0]), cdims_cyclic="bc")
>>> ST4  
sptenmat corresponding to a sptensor of shape (4, 4, 4) with 2 nonzeros         and order F
rdims = [ 0 ] (modes of sptensor corresponding to rows)
cdims = [ 2, 1 ] (modes of sptensor corresponding to columns)
    [1, 9] = 6
    [1, 13] = 7
innerprod(other: sptensor | tensor | ktensor | ttensor) float[source]

Compute inner product of the pyttb.sptensor with another tensor.

Parameters:

other – Other tensor to compute inner product with.

Examples

Create a pyttb.sptensor:

>>> S = ttb.sptensor()
>>> S[0, 0] = 1
>>> S[1, 1] = 2
>>> S
sparse tensor of shape (2, 2) with 2 nonzeros and order F
[0, 0] = 1.0
[1, 1] = 2.0

Compute inner product with pyttb.tensor of all ones that is the same shape as S:

>>> T = ttb.tenones(S.shape)
>>> S.innerprod(T)
3.0

Compute inner product with rank-1 pyttb.ktensor of all ones that is the same shape as S:

>>> factor_matrices = [np.ones((s, 1)) for s in S.shape]
>>> K = ttb.ktensor(factor_matrices)
>>> S.innerprod(K)
3.0
isequal(other: sptensor | tensor) bool[source]

Determine if the pyttb.sptensor is equal to another tensor.

Equal when all elements are exactly the same in both tensors.

Parameters:

other – Other tensor to compare against.

Examples

Create a pyttb.sptensor:

>>> S = ttb.sptensor()
>>> S[0, 0] = 1
>>> S[1, 1] = 2
>>> S
sparse tensor of shape (2, 2) with 2 nonzeros and order F
[0, 0] = 1.0
[1, 1] = 2.0

Compare with a tensor that should be equal:

>>> T = S.to_tensor()
>>> S.isequal(T)
True

Compare with a tensor that should not be equal:

>>> T[0, 0] = T[0, 0] + 1
>>> S.isequal(T)
False
logical_and(other: float | sptensor | tensor) sptensor[source]

Logical AND between the pyttb.sptensor and another object.

Parameters:

other – Other object to compute with.

Examples

Create a pyttb.sptensor:

>>> S = ttb.sptensor()
>>> S[0, 0] = 1
>>> S[1, 1] = 2
>>> S
sparse tensor of shape (2, 2) with 2 nonzeros and order F
[0, 0] = 1.0
[1, 1] = 2.0

Compute logical AND with a pyttb.tensor that has the same nonzero pattern but different values:

>>> T = S.to_tensor()
>>> T[0, 0] = T[0, 0] + 1
>>> S.logical_and(T)
sparse tensor of shape (2, 2) with 2 nonzeros and order F
[0, 0] = 1.0
[1, 1] = 1.0

Compute logical AND with a scalar value:

>>> S.logical_and(1.0)
sparse tensor of shape (2, 2) with 2 nonzeros and order F
[0, 0] = 1.0
[1, 1] = 1.0
logical_not() sptensor[source]

Logical NOT for the pyttb.sptensor.

Examples

Create a pyttb.sptensor and compute logical NOT:

>>> S = ttb.sptensor()
>>> S[0, 0] = 1
>>> S[1, 1] = 2
>>> S
sparse tensor of shape (2, 2) with 2 nonzeros and order F
[0, 0] = 1.0
[1, 1] = 2.0
>>> S.logical_not()
sparse tensor of shape (2, 2) with 2 nonzeros and order F
[0, 1] = 1.0
[1, 0] = 1.0
logical_or(other: float | tensor) tensor[source]
logical_or(other: sptensor) sptensor

Logical OR between the pyttb.sptensor and another object.

Parameters:

other – Other object to compute with.

Examples

Create a pyttb.sptensor and compute logical OR with itself:

>>> S = ttb.sptensor()
>>> S[0, 0] = 1
>>> S[1, 1] = 2
>>> S.logical_or(S)
sparse tensor of shape (2, 2) with 2 nonzeros and order F
[0, 0] = 1.0
[1, 1] = 1.0

Compute logical OR with a pyttb.tensor that has the same nonzero pattern:

>>> T = S.to_tensor()
>>> S.logical_or(T)
tensor of shape (2, 2) with order F
data[:, :] =
[[1. 0.]
 [0. 1.]]

Compute logical OR with a scalar value:

>>> S.logical_or(1)
tensor of shape (2, 2) with order F
data[:, :] =
[[1. 1.]
 [1. 1.]]
logical_xor(other: float | tensor) tensor[source]
logical_xor(other: sptensor) sptensor

Logical XOR between the pyttb.sptensor and another object.

Parameters:

other – Other object to compute with.

Examples

Create a pyttb.sptensor and compute logical XOR with itself:

>>> S = ttb.sptensor()
>>> S[0, 0] = 1
>>> S[1, 1] = 2
>>> S.logical_xor(S)
empty sparse tensor of shape (2, 2) with order F

Compute logical XOR with pyttb.tensor that has a different nonzero pattern:

>>> T = S.to_tensor()
>>> T[1, 0] = 1.0
>>> S.logical_xor(T)
tensor of shape (2, 2) with order F
data[:, :] =
[[0. 0.]
 [1. 0.]]

Compute logical XOR with a scalar value:

>>> S.logical_xor(1)
tensor of shape (2, 2) with order F
data[:, :] =
[[0. 1.]
 [1. 0.]]
mask(W: sptensor) ndarray[source]

Extract values of the pyttb.sptensor as specified by W.

The values in the sparse tensor corresponding to ones (1) in W will be returned as a column vector.

Parameters:

W – Mask tensor.

Examples

Create a pyttb.sptensor:

>>> S = ttb.sptensor()
>>> S[0, 0] = 1
>>> S[1, 1] = 2
>>> S
sparse tensor of shape (2, 2) with 2 nonzeros and order F
[0, 0] = 1.0
[1, 1] = 2.0

Create mask pyttb.sptensor and extract nonzero values from S:

>>> W = ttb.sptensor()
>>> W[0, 0] = 1
>>> W[1, 1] = 1
>>> S.mask(W)
array([[1.],
       [2.]])

Create mask pyttb.sptensor and extract some nonzero values and some zero values:

>>> W = ttb.sptensor()
>>> W[0, 0] = 1
>>> W[1, 0] = 1
>>> S.mask(W)
array([[1.],
       [0.]])
mttkrp(U: ktensor | Sequence[ndarray], n: int | integer) ndarray[source]

Matricized tensor times Khatri-Rao product using pyttb.sptensor.

This is an efficient form of the matrix product that avoids explicitly computing the matricized sparse tensor and the large intermediate Khatri-Rao product arrays.

If the input includes a list of 2-D arrays (factor_matrices), this computes a matrix product of the mode-n matricization of the sparse tensor with the Khatri-Rao product of all arrays in the list except the n th. The length of the list of arrays must equal the number of dimensions of the sparse tensor. The shapes of each array must have leading dimensions equal to the dimensions of the sparse tensor and the same second dimension.

If the input is a pyttb.ktensor, this computes a matrix product of the mode-n matricization of the sparse tensor with the Khatri-Rao product formed by the factor_matrices and weights from the ktensor, excluding the n th factor matrix and corresponding weight. The shape of the ktensor must be compatible with the shape of the sparse tensor.

Parameters:
  • U – Factor matrix or list of factor matrices.

  • n – Mode used to matricize the pyttb.sptensor.

Examples

Create list of factor matrices:

>>> A = np.ones((4, 4))
>>> U = [A, A, A]

Create a pyttb.sptensor and compute the matricized tensor times Khatri-Rao product between it and the factor matrices:

>>> subs = np.array([[1, 1, 1], [1, 1, 3], [2, 2, 2], [3, 3, 3]])
>>> vals = np.array([[0.5], [1.5], [2.5], [3.5]])
>>> shape = (4, 4, 4)
>>> S = ttb.sptensor(subs, vals, shape)
>>> S.mttkrp(U, 0)
array([[0. , 0. , 0. , 0. ],
       [2. , 2. , 2. , 2. ],
       [2.5, 2.5, 2.5, 2.5],
       [3.5, 3.5, 3.5, 3.5]])
property ndims: int

Number of dimensions of the pyttb.sptensor.

Examples

Create a pyttb.sptensor and return the number of dimensions:

>>> S = ttb.sptensor(shape=(1, 2, 3, 4, 5, 6))
>>> S
empty sparse tensor of shape (1, 2, 3, 4, 5, 6) with order F
>>> S.ndims
6
property nnz: int

Number of nonzero values in the pyttb.sptensor.

Examples

Create a pyttb.sptensor from a pyttb.tensor containing a 10x10 diagonal identity matrix and return the number of nonzeros:

>>> S = ttb.tensor(np.eye(10)).to_sptensor()
>>> S.nnz
10
norm() float[source]

Compute the norm of the pyttb.sptensor.

Frobenius norm, or square root of the sum of squares of entries.

Examples

Create a pyttb.sptensor from a diagonal matrix and compute its norm:

>>> S = ttb.tensor(np.diag([1.0, 2.0, 3.0, 4.0])).to_sptensor()
>>> S
sparse tensor of shape (4, 4) with 4 nonzeros and order F
[0, 0] = 1.0
[1, 1] = 2.0
[2, 2] = 3.0
[3, 3] = 4.0
>>> S.norm()  
5.47722557...
nvecs(n: int, r: int, flipsign: bool = True) ndarray[source]

Compute the leading mode-n vectors of the pyttb.sptensor.

Computes the r leading eigenvectors of Sn*Sn.T (where Sn is the mode-n matricization/unfolding of a sparse tensor S), 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 Sn*Sn.T. The output product for sparse tensors is not formed, making this operation very efficient when the tensor is very sparse.

Parameters:
  • n – Mode to use for matricization.

  • r – Number of eigenvectors to compute and use.

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

Examples

Create a pyttb.sptensor:

>>> subs = np.array([[0, 0], [0, 1], [1, 0]])
>>> vals = np.array([[1.0], [2.0], [3.0]])
>>> shape = (2, 2)
>>> S = ttb.sptensor(subs, vals, shape)

Compute two mode-0 leading eigenvectors of S, making sign of largest element of each eigenvector positive (i.e., flipsign =True).

>>> S.nvecs(0, 2, flipsign=True)  
array([[-0.4718...,  0.8816...],
       [ 0.8816...,  0.4718...]])

Compute the same nvecs of S, but do not adjust the sign of the largest element of each eigenvector.

>>> S.nvecs(0, 2, flipsign=False)  
array([[ 0.4718..., -0.8816...],
       [-0.8816..., -0.4718...]])
ones() sptensor[source]

Replace nonzero values of the pyttb.sptensor with ones (1).

Examples

Create a pyttb.sptensor:

>>> subs = np.array([[0, 0], [0, 1], [1, 0]])
>>> vals = np.array([[1.0], [2.0], [3.0]])
>>> shape = (2, 2)
>>> S = ttb.sptensor(subs, vals, shape)
>>> S
sparse tensor of shape (2, 2) with 3 nonzeros and order F
[0, 0] = 1.0
[0, 1] = 2.0
[1, 0] = 3.0

Replace the nonzero values of S with the value 1:

>>> S.ones()
sparse tensor of shape (2, 2) with 3 nonzeros and order F
[0, 0] = 1.0
[0, 1] = 1.0
[1, 0] = 1.0
permute(order: int | float | Iterable[int] | Iterable[float] | ndarray) sptensor[source]

Permute the pyttb.sptensor dimensions.

The result is a new sparse 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.

Examples

Create a pyttb.sptensor:

>>> subs = np.array([[0, 0], [0, 1], [1, 0]])
>>> vals = np.array([[1.0], [2.0], [3.0]])
>>> shape = (2, 2)
>>> S = ttb.sptensor(subs, vals, shape)
>>> S
sparse tensor of shape (2, 2) with 3 nonzeros and order F
[0, 0] = 1.0
[0, 1] = 2.0
[1, 0] = 3.0

Permute the order of the dimensions by reversing them:

>>> S1 = S.permute(np.array((1, 0)))
>>> S1
sparse tensor of shape (2, 2) with 3 nonzeros and order F
[0, 0] = 1.0
[1, 0] = 2.0
[0, 1] = 3.0
reshape(new_shape: int | Iterable[int], old_modes: ndarray | int | None = None) sptensor[source]

Reshape the pyttb.sptensor to the new_shape.

If old_modes is specified, reshape only those modes of the sparse tensor, moving newly reshaped modes to the end of the subscripts; otherwise use all modes. The product of the new shape must equal the product of the old shape.

Parameters:
  • new_shape – New shape.

  • old_modes – Modes used for reshaping.

Examples

Create a pyttb.sptensor from a pyttb.tensor:

>>> S = ttb.tensor(np.arange(9) + 1, shape=(1, 3, 3)).to_sptensor()
>>> S
sparse tensor of shape (1, 3, 3) with 9 nonzeros and order F
[0, 0, 0] = 1
[0, 1, 0] = 2
[0, 2, 0] = 3
[0, 0, 1] = 4
[0, 1, 1] = 5
[0, 2, 1] = 6
[0, 0, 2] = 7
[0, 1, 2] = 8
[0, 2, 2] = 9

Reshape to a 2-way pyttb.sptensor:

>>> S.reshape((1, 9))
sparse tensor of shape (1, 9) with 9 nonzeros and order F
[0, 0] = 1
[0, 1] = 2
[0, 2] = 3
[0, 3] = 4
[0, 4] = 5
[0, 5] = 6
[0, 6] = 7
[0, 7] = 8
[0, 8] = 9

Reshape the first two dimensions and move to the end of the subscripts. The first two subscripts are reshaped from (1,3) to (3,1) and moved after the remaining subscript (i.e., corresponding to mode 2).

>>> S.reshape(new_shape=(3, 1), old_modes=np.array((1, 0)))
sparse tensor of shape (3, 3, 1) with 9 nonzeros and order F
[0, 0, 0] = 1
[0, 1, 0] = 2
[0, 2, 0] = 3
[1, 0, 0] = 4
[1, 1, 0] = 5
[1, 2, 0] = 6
[2, 0, 0] = 7
[2, 1, 0] = 8
[2, 2, 0] = 9
scale(factor: ndarray | tensor | sptensor, dims: int | float | Iterable[int] | Iterable[float] | ndarray) sptensor[source]

Scale the pyttb.sptensor along specified dimensions.

Parameters:
  • factor – Scaling factor.

  • dims – Dimensions to scale.

Examples

Create a pyttb.sptensor from a pyttb.tensor:

>>> S = ttb.tensor(np.arange(9) + 1, shape=(1, 3, 3)).to_sptensor()
>>> S
sparse tensor of shape (1, 3, 3) with 9 nonzeros and order F
[0, 0, 0] = 1
[0, 1, 0] = 2
[0, 2, 0] = 3
[0, 0, 1] = 4
[0, 1, 1] = 5
[0, 2, 1] = 6
[0, 0, 2] = 7
[0, 1, 2] = 8
[0, 2, 2] = 9

Mode 2 is of length 3. Create a scaling factor array of length 3 and scale along mode 2:

>>> scaling_factor = np.array([1, 2, 3])
>>> S.scale(scaling_factor, np.array([2]))
sparse tensor of shape (1, 3, 3) with 9 nonzeros and order F
[0, 0, 0] = 1
[0, 1, 0] = 2
[0, 2, 0] = 3
[0, 0, 1] = 8
[0, 1, 1] = 10
[0, 2, 1] = 12
[0, 0, 2] = 21
[0, 1, 2] = 24
[0, 2, 2] = 27
spmatrix() coo_matrix[source]

Convert 2-way pyttb.sptensor to scipy.sparse.coo_matrix.

Examples

Create a 2-way pyttb.sptensor:

>>> S = ttb.tendiag([1, 2]).to_sptensor()
>>> S
sparse tensor of shape (2, 2) with 2 nonzeros and order F
[0, 0] = 1.0
[1, 1] = 2.0

Convert it to a scipy.sparse.coo_matrix:

>>> M = S.spmatrix()
>>> type(M)
<class 'scipy.sparse._coo.coo_matrix'>
>>> M.toarray()
array([[1., 0.],
       [0., 2.]])
squeeze() sptensor | float[source]

Remove singleton dimensions from the pyttb.sptensor.

Examples

Create a pyttb.sptensor with a single element and squeeze all the dimensions:

>>> S = ttb.sptensor(np.array([[0, 0, 0, 0, 0]]), np.array([[3.14]]))
>>> S.squeeze()
3.14

Create a pyttb.sptensor with and interior singleton dimension and squeeze it out:

>>> S = ttb.sptensor(np.array([[0, 0, 0], [1, 0, 1]]), np.array([[1.0], [2.0]]))
>>> S
sparse tensor of shape (2, 1, 2) with 2 nonzeros and order F
[0, 0, 0] = 1.0
[1, 0, 1] = 2.0
>>> S.squeeze()
sparse tensor of shape (2, 2) with 2 nonzeros and order F
[0, 0] = 1.0
[1, 1] = 2.0
subdims(region: Sequence[int | ndarray | slice]) ndarray[source]

Compute the locations of subscripts within a subdimension.

Finds the locations of the subscripts in the pyttb.sptensor that are within the range specified by region. For example, if region is [1, np.array([1,2]), np.array([1,2]]), then the locations of all elements of the sparse tensor that have a first subscript equal to 1, a second subscript equal to 1 or 2, and a third subscript equal to 1 or 2 are returned.

Parameters:

region – Subset of subscripts in which to find nonzero values.

Examples

Create a pyttb.sptensor:

>>> subs = np.array([[1, 1, 1], [1, 1, 3], [2, 2, 2], [2, 3, 2]])
>>> vals = np.array([[0.5], [1.5], [2.5], [3.5]])
>>> shape = (4, 4, 4)
>>> S = ttb.sptensor(subs, vals, shape)

Define a region with subscripts 1 in mode 0, 1 in mode 1, and either 1 or 3 in mode 2, then find the location of the subscripts of the S for that region:

>>> region = [1, 1, np.array([1, 3])]
>>> subs_loc = S.subdims(region)
>>> print(subs_loc)
[0 1]
>>> S.subs[subs_loc]
array([[1, 1, 1],
       [1, 1, 3]])

Use slice() to define part of the region. In this case, allow any subscript in mode 1:

>>> region = (2, slice(None, None, None), 2)
>>> subs_loc = S.subdims(region)
>>> print(subs_loc)
[2 3]
>>> S.subs[subs_loc]
array([[2, 2, 2],
       [2, 3, 2]])
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) sptensor | tensor | float[source]

Multiplication of the pyttb.sptensor with a vector.

Computes the n-mode product of the pyttb.sptensor with a vector. Let n specify the dimension (or mode) along which the vector should be multiplied. If the vector has shape = (I,), then the sparse tensor must have shape[n] = I. The result 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 sparse tensor to use.

The dimensions of the sparse 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.

Examples

Create a 2-way pyttb.sptensor that is relatively dense:

>>> subs = np.array([[0, 0], [0, 1], [1, 0]])
>>> vals = np.array([[1.0], [2.0], [3.0]])
>>> shape = (2, 2)
>>> S = ttb.sptensor(subs, vals, shape)
>>> S
sparse tensor of shape (2, 2) with 3 nonzeros and order F
[0, 0] = 1.0
[0, 1] = 2.0
[1, 0] = 3.0

Compute the product of S with a vector of ones across mode 0. The result is a pyttb.tensor:

>>> S.ttv(np.ones(2), 0)
tensor of shape (2,) with order F
data[:] =
[4. 2.]

Create a 3-way pyttb.sptensor that is much more sparse:

>>> subs = np.array([[0, 0, 0], [0, 1, 0], [1, 0, 1]])
>>> vals = np.array([[1.0], [2.0], [3.0]])
>>> shape = (2, 2, 2)
>>> S1 = ttb.sptensor(subs, vals, shape)

Compute the product of S1 with a vector of ones across mode 1. The result is a pyttb.sptensor:

>>> S1.ttv(np.ones(2), 1)
sparse tensor of shape (2, 2) with 2 nonzeros and order F
[0, 0] = 3.0
[1, 1] = 3.0

Compute the product of S1 with multiple vectors across all dimensions. When all dimensions will be included in the product, dims does not need to be specified. The result is a scalar value.

>>> vectors = [(i + 1) * np.ones(2) for i in range(len(S1.shape))]
>>> vectors
[array([1., 1.]), array([2., 2.]), array([3., 3.])]
>>> S1.ttv(vectors)
36.0
__getitem__(item)[source]

Subscripted reference for the pyttb.sptensor.

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

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

Case 1b: Y = S[R1,R2,…,Rn], where one or more R is a range and the rest are subsctiprs, returns a sparse tensor. The elements are renumbered here as appropriate.

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

Case 2b: V = S[I] where I is a set of p linear subscripts, 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

Create a 3-way pyttb.sptensor:

>>> subs = np.array([[3, 3, 3], [1, 1, 0], [1, 2, 1]])
>>> vals = np.array([[3], [5], [1]])
>>> shape = (4, 4, 4)
>>> S = ttb.sptensor(subs, vals, shape)

Use a single subscript (Case 1a):

>>> print(S[1, 2, 1])
1

Use a range of subscripts (Case 1b):

>>> S[3, 3, :]
sparse tensor of shape (4,) with 1 nonzeros and order F
[3] = 3

Use an array of subscripts (Case 2a):

>>> M = np.array([[1, 1, 0], [1, 1, 1]])
>>> print(S[M])
[[5]
 [0]]

Use linear subscripting, including negative subscript for offsets from the end of the linear subscripts into the sparse tensor data (Case 2b):

>>> print(S[[5, -1]])
[[5]
 [3]]
__setitem__(key, value)[source]

Subscripted assignment for the pyttb.sptensor.

We can assign elements to a sparse tensor in the following ways.

Case 1: S[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 or an sparse tensor.

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

Assignment using linear subscripting is not supported for sparse tensors.

Examples

Create a 3-way pyttb.sptensor:

>>> S = ttb.sptensor(shape=(3, 4, 5))

Set a single element using subscripts or a tuple:

>>> S[0, 0, 0] = 1
>>> S[(0, 0, 0)] = 1
>>> S
sparse tensor of shape (3, 4, 5) with 1 nonzeros and order F
[0, 0, 0] = 1.0
>>> S
sparse tensor of shape (3, 4, 5) with 1 nonzeros and order F
[0, 0, 0] = 1.0

Set a range of elements using a single value:

>>> S[0, 0, 1:3] = 2
>>> S
sparse tensor of shape (3, 4, 5) with 3 nonzeros and order F
[0, 0, 0] = 1.0
[0, 0, 1] = 2.0
[0, 0, 2] = 2.0

Set a range of elements using a pyttb.sptensor:

>>> S[0:1, 1:3, 3:4] = 3 * ttb.tenones((1, 2, 1)).to_sptensor()
>>> S
sparse tensor of shape (3, 4, 5) with 5 nonzeros and order F
[0, 0, 0] = 1.0
[0, 0, 1] = 2.0
[0, 0, 2] = 2.0
[0, 1, 3] = 3.0
[0, 2, 3] = 3.0

Grow the sparse tensor by assigning an element with a subscript outside the current shape:

>>> S[3, 4, 5] = 4
>>> S
sparse tensor of shape (4, 5, 6) with 6 nonzeros and order F
[0, 0, 0] = 1.0
[0, 0, 1] = 2.0
[0, 0, 2] = 2.0
[0, 1, 3] = 3.0
[0, 2, 3] = 3.0
[3, 4, 5] = 4.0

Assign one or more values using an array of subscripts and a vector of values:

>>> S[S.subs] = 5 * np.ones((S.vals.shape[0], 1))
>>> S
sparse tensor of shape (4, 5, 6) with 6 nonzeros and order F
[0, 0, 0] = 5.0
[0, 0, 1] = 5.0
[0, 0, 2] = 5.0
[0, 1, 3] = 5.0
[0, 2, 3] = 5.0
[3, 4, 5] = 5.0

Note regarding singleton dimensions: It is not possible to do, for instance, S[1,1:10,1:10] = ttb.sptenrand((1,10,10),nonzeros=5). However, it is okay to do S[1,1:10,1:10] = ttb.sptenrand((1,10,10),nonzeros=5).squeeze().

__eq__(other)[source]

Element-wise equal operator (==).

Parameters:

other – Other object to compare with.

Examples

Compare the pyttb.sptensor to itself, returning all True values:

>>> S = ttb.sptensor(shape=(2, 2))
>>> S[1, 1] = 1.0
>>> S == S
sparse tensor of shape (2, 2) with 4 nonzeros and order F
[0, 0] = 1.0
[0, 1] = 1.0
[1, 0] = 1.0
[1, 1] = 1.0

Compare with a scalar value, returning only a single True value:

>>> S == 1
sparse tensor of shape (2, 2) with 1 nonzeros and order F
[1, 1] = 1.0
__ne__(other)[source]

Element-wise not equal operator (!=).

Parameters:

other – Other object to compare with.

Examples

Compare a pyttb.sptensor to itself, returning no True values:

>>> S = ttb.sptensor(shape=(2, 2))
>>> S[1, 1] = 1.0
>>> S != S
empty sparse tensor of shape (2, 2) with order F

Compare with a scalar value: :

>>> S != 1
sparse tensor of shape (2, 2) with 3 nonzeros and order F
[0, 0] = 1.0
[0, 1] = 1.0
[1, 0] = 1.0
__sub__(other)[source]

Binary subtraction operator (-).

Parameters:

other – Object to subtract from the sparse tensor.

Examples

Subtract a pyttb.sptensor from itself, returning a sparse tensor:

>>> S = ttb.sptensor(shape=(2, 2))
>>> S[1, 1] = 1.0
>>> S - S
empty sparse tensor of shape (2, 2) with order F

Subtract a scalar value, returning a dense tensor:

>>> S - 1
tensor of shape (2, 2) with order F
data[:, :] =
[[-1. -1.]
 [-1.  0.]]
__add__(other)[source]

Binary addition operator (+).

Parameters:

other – Object to add to the sparse tensor.

Examples

Add a pyttb.sptensor to itself, returning a sparse tensor:

>>> S = ttb.sptensor(shape=(2, 2))
>>> S[1, 1] = 1.0
>>> S + S
sparse tensor of shape (2, 2) with 1 nonzeros and order F
[1, 1] = 2.0

Add a scalar value, returning a dense tensor:

>>> S + 1
tensor of shape (2, 2) with order F
data[:, :] =
[[1. 1.]
 [1. 2.]]
__pos__()[source]

Unary plus operator (+).

Examples

Create a pyttb.sptensor:

>>> S = ttb.sptensor(shape=(2, 2, 2))
>>> S[1, 1, 1] = 1
>>> S
sparse tensor of shape (2, 2, 2) with 1 nonzeros and order F
[1, 1, 1] = 1.0

Apply the + operator:

>>> +S
sparse tensor of shape (2, 2, 2) with 1 nonzeros and order F
[1, 1, 1] = 1.0
__neg__()[source]

Unary minus operator (-).

Examples

Create a pyttb.sptensor:

>>> S = ttb.sptensor(shape=(2, 2, 2))
>>> S[1, 1, 1] = 1
>>> S
sparse tensor of shape (2, 2, 2) with 1 nonzeros and order F
[1, 1, 1] = 1.0

Apply the + operator:

>>> -S
sparse tensor of shape (2, 2, 2) with 1 nonzeros and order F
[1, 1, 1] = -1.0
__mul__(other)[source]

Element-wise multiplication operator (*).

Parameters:

other – Object to multiply with the sparsee tensor.

Examples

Multiply a pyttb.sptensor by a scalar:

>>> S = ttb.sptensor(shape=(2, 2))
>>> S[1, 1] = 1.0
>>> S * 3
sparse tensor of shape (2, 2) with 1 nonzeros and order F
[1, 1] = 3.0

Multiply two sparse tensors with no overlap in subscripts of nonzeros, resulting in an empty sparse tensor:

>>> S2 = ttb.sptensor(shape=(2, 2))
>>> S2[1, 0] = 1.0
>>> S * S2
empty sparse tensor of shape (2, 2) with order F
__rmul__(other)[source]

Element-wise right multiplication operator (*).

Parameters:

other – Object to multiple with sparse tensor.

Examples

Multiple scalar by a pyttb.sptensor:

>>> S = ttb.sptensor(shape=(2, 2))
>>> S[1, 1] = 1.0
>>> 3 * S
sparse tensor of shape (2, 2) with 1 nonzeros and order F
[1, 1] = 3.0
__le__(other)[source]

Less than or equal operator (<=).

Parameters:

other – Object to compare with.

Examples

Compare a pyttb.sptensor with itself:

>>> S = ttb.sptensor(shape=(2, 2))
>>> S[1, 1] = 1.0
>>> S <= S
sparse tensor of shape (2, 2) with 4 nonzeros and order F
[1, 1] = 1.0
[0, 0] = 1.0
[0, 1] = 1.0
[1, 0] = 1.0

Compare with a scalar:

>>> S <= -1
empty sparse tensor of shape (2, 2) with order F
__lt__(other)[source]

Less than operator (<).

Parameters:

other – Object to compare with.

Examples

Compare a pyttb.sptensor with itself:

>>> S = ttb.sptensor(shape=(2, 2))
>>> S[1, 1] = 1.0
>>> S < S
empty sparse tensor of shape (2, 2) with order F

Compare with a scalar:

>>> S < 1
sparse tensor of shape (2, 2) with 3 nonzeros and order F
[0, 0] = 1.0
[0, 1] = 1.0
[1, 0] = 1.0
__ge__(other)[source]

Greater than or equal operator (>=).

Parameters:

other – Object to compare with.

Examples

Compare a pyttb.sptensor with itself:

>>> S = ttb.sptensor(shape=(2, 2))
>>> S[1, 1] = 1.0
>>> S >= S
sparse tensor of shape (2, 2) with 4 nonzeros and order F
[1, 1] = 1.0
[0, 0] = 1.0
[0, 1] = 1.0
[1, 0] = 1.0

Compare with a scalar:

>>> S >= 1
sparse tensor of shape (2, 2) with 1 nonzeros and order F
[1, 1] = 1.0
__hash__ = None
__gt__(other)[source]

Greater than operator (>).

Parameters:

other – Object to compare with.

Examples

Compare a pyttb.sptensor with itself:

>>> S = ttb.sptensor(shape=(2, 2))
>>> S[1, 1] = 1.0
>>> S > S
empty sparse tensor of shape (2, 2) with order F

Compare with a scalar:

>>> S > 0
sparse tensor of shape (2, 2) with 1 nonzeros and order F
[1, 1] = 1.0
__truediv__(other)[source]

Element-wise left division operator (/).

Comparisons with empty tensors raise an exception.

Parameters:

other – Object to divide from the sparse tensor.

Examples

Divide a pyttb.sptensor by a pyttb.sptensor:

>>> S = ttb.sptensor(shape=(2, 2))
>>> S[1, 1] = 2.0
>>> S2 = ttb.sptensor(shape=(2, 2))
>>> S2[1, 1] = 4.0
>>> S / S2
sparse tensor of shape (2, 2) with 4 nonzeros and order F
[1, 1] = 0.5
[0, 0] = nan
[0, 1] = nan
[1, 0] = nan

Divide by a scalar:

>>> S / 3  
sparse tensor of shape (2, 2) with 1 nonzeros and order F
[1, 1] = 0.66666...
__rtruediv__(other)[source]

Element-wise right division operator (/).

Parameters:

other – Object to divide sparse tensor by.

Examples

Divide a scalar by a pyttb.sptensor:

>>> S = ttb.sptensor(shape=(2, 2))
>>> S[:, :] = 2.0
>>> 1 / S
tensor of shape (2, 2) with order F
data[:, :] =
[[0.5 0.5]
 [0.5 0.5]]
__repr__()[source]

Return string representation of a pyttb.sptensor.

Examples

Create a pyttb.sptensor and print it as a string:

>>> S = ttb.sptensor(shape=(2, 2))
>>> S[:, :] = 1.0
>>> print(S)
sparse tensor of shape (2, 2) with 4 nonzeros and order F
[0, 0] = 1.0
[0, 1] = 1.0
[1, 0] = 1.0
[1, 1] = 1.0
__str__()

Return string representation of a pyttb.sptensor.

Examples

Create a pyttb.sptensor and print it as a string:

>>> S = ttb.sptensor(shape=(2, 2))
>>> S[:, :] = 1.0
>>> print(S)
sparse tensor of shape (2, 2) with 4 nonzeros and order F
[0, 0] = 1.0
[0, 1] = 1.0
[1, 0] = 1.0
[1, 1] = 1.0
ttm(matrices: 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 | sptensor[source]

Multiplication of a pyttb.sptensor with a matrix.

Computes the n-mode product of the pyttb.sptensor with a matrix (i.e., array). Let n specify the dimension (or mode) along which the matrix should be multiplied. If the matrix has shape = (I,J), then the sparse tensor must have shape[n] = I. If the matrix has shape = (J,I), you can set transpose=True to multiply with the transpose of the matrix. The result has shape[n] = J.

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

The dimensions of the sparse 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:
  • matrices – A matrix or list of matrices.

  • dims – Dimensions to multiply against.

  • exclude_dims – Use all dimensions but these.

  • transpose – Transpose matrices to be multiplied.

Examples

Create a pyttb.sptensor with a region of elements set to 1:

>>> S = ttb.sptensor(shape=(2, 2, 2, 2))
>>> S[:, 0:1, :, 0:1] = 1

Compute the product of S with multiple matrices of ones along the first two dimensions, transposing the matrices when multiplying:

>>> A = 2 * np.ones((2, 1))
>>> S.ttm([A, A], dims=[0, 1], transpose=True)
tensor of shape (1, 1, 2, 2) with order F
data[:, :, 0, 0] =
[[8.]]
data[:, :, 1, 0] =
[[8.]]
data[:, :, 0, 1] =
[[0.]]
data[:, :, 1, 1] =
[[0.]]

Compute sparse tensor matrix product specifying which two tensor dimensions to exclude in the multiplication:

>>> S.ttm([A, A], exclude_dims=[0, 1], transpose=True)
tensor of shape (2, 2, 1, 1) with order F
data[:, :, 0, 0] =
[[8. 0.]
 [8. 0.]]
squash(return_inverse: Literal[False]) sptensor[source]
squash(return_inverse: Literal[True]) Tuple[sptensor, Dict]

Remove empty slices from a pyttb.sptensor.

Parameters:

return_inverse – Return mapping from new tensor to old tensor subscripts.

Examples

Create a pyttb.sptensor with a few entries and squash empty slices:

>>> S = ttb.sptensor(shape=(10, 10, 10))
>>> S[0, 1, 2] = 1
>>> S[0, 1, 3] = 2
>>> S
sparse tensor of shape (10, 10, 10) with 2 nonzeros and order F
[0, 1, 2] = 1.0
[0, 1, 3] = 2.0
>>> S.squash()
sparse tensor of shape (2, 2, 2) with 2 nonzeros and order F
[0, 0, 0] = 1.0
[0, 0, 1] = 2.0

Squash and return the inverse subscript mapping, checking that the mapping in all dimensions is correct:

>>> S2, inverse = S.squash(True)
>>> for i in range(S.ndims):
...     np.array_equal(S.subs[:, i], inverse[i][S2.subs[:, i]])
True
True
True