Kruskal Tensor (pyttb.ktensor)

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

>>> import pyttb as ttb
>>> import numpy as np
class pyttb.ktensor(factor_matrices: Sequence[ndarray] | None = None, weights: ndarray | None = None, copy: bool = True)[source]

Class for Kruskal tensors (decomposed).

Parameters:
  • factor_matrices (optional) – list of numpy.ndarray. The length of the list is equal to the number of dimensions of the tensor. The shape of the ith element of the list is (n_i, r), where n_i is the length of dimension i and r is the rank of the tensor (as well as the length of the weights vector).

  • weights (optional) – numpy.ndarray vector containing the weights of the rank-1 tensors defined by the outer products of the column vectors of the factor_matrices. If not provided, all weights are set to 1.

  • copy (optional) – Whether to deep copy (versus reference) factor_matrices and weights. By default, factor_matrices and weights are deep copied.


Examples

Create a pyttb.ktensor from a list of factor matrices and weights:

>>> weights = np.array([1.0, 2.0])
>>> fm0 = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> fm1 = np.array([[5.0, 6.0], [7.0, 8.0]])
>>> fm2 = np.array([[9.0, 10.0], [11.0, 12.0]])
>>> K = ttb.ktensor([fm0, fm1, fm2], weights)
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 2.]
factor_matrices[0] =
[[1. 2.]
 [3. 4.]]
factor_matrices[1] =
[[5. 6.]
 [7. 8.]]
factor_matrices[2] =
[[ 9. 10.]
 [11. 12.]]

Create a pyttb.ktensor from a list of factor matrices (without providing weights):

>>> fm0 = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> fm1 = np.array([[5.0, 6.0], [7.0, 8.0]])
>>> fm2 = np.array([[9.0, 10.0], [11.0, 12.0]])
>>> factor_matrices = [fm0, fm1, fm2]
>>> K = ttb.ktensor([fm0, fm1, fm2])
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 1.]
factor_matrices[0] =
[[1. 2.]
 [3. 4.]]
factor_matrices[1] =
[[5. 6.]
 [7. 8.]]
factor_matrices[2] =
[[ 9. 10.]
 [11. 12.]]

Create an empty pyttb.ktensor:

>>> K = ttb.ktensor()
>>> print(K)
ktensor of shape () with order F
weights=[]
factor_matrices=[]

Notes

Instances of pyttb.ktensor can also be created using the following:


Tutorial

See the Kruskal Tensors tutorial for getting started with the ktensor class.


Attributes and Methods

weights

Weights of the rank-1 summands of the ktensor.

factor_matrices: list[ndarray]

Factor matrices of the ktensor.

property ncomponents: int

Number of columns in each factor matrix for the pyttb.ktensor.

Examples

Create a rank-2 pyttb.ktensor and display the number of components:

>>> K = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2)
>>> print(K.ncomponents)
2
property ndims: int

Number of dimensions of the pyttb.ktensor.

Examples

Create a rank-2 pyttb.ktensor and display the number of dimensions:

>>> K = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2)
>>> print(K.ndims)
3
property order: Literal['F']

Return the data layout of the underlying storage.

property shape: tuple[int, ...]

Shape of a pyttb.ktensor.

Returns a tuple containing the lengths of all dimensions of the pyttb.ktensor.

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

Construct a pyttb.ktensor.

Factor matrix entries are set using a function. The weights of the returned pyttb.ktensor will all be equal to 1.

Parameters:

Examples

Create a pyttb.ktensor with entries of the factor matrices taken from a uniform random distribution:

>>> np.random.seed(1)
>>> K = ttb.ktensor.from_function(np.random.random_sample, (2, 3, 4), 2)
>>> print(K)  
ktensor of shape (2, 3, 4) with order F
weights=[1. 1.]
factor_matrices[0] =
[[4.1702...e-01 7.2032...e-01]
 [1.1437...e-04 3.0233...e-01]]
factor_matrices[1] =
[[0.1467... 0.0923...]
 [0.1862... 0.3455...]
 [0.3967... 0.5388...]]
factor_matrices[2] =
[[0.4191... 0.6852...]
 [0.2044... 0.8781...]
 [0.0273... 0.6704...]
 [0.4173...  0.5586...]]

Create a pyttb.ktensor with entries equal to 1:

>>> K = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2)
>>> print(K)
ktensor of shape (2, 3, 4) with order F
weights=[1. 1.]
factor_matrices[0] =
[[1. 1.]
 [1. 1.]]
factor_matrices[1] =
[[1. 1.]
 [1. 1.]
 [1. 1.]]
factor_matrices[2] =
[[1. 1.]
 [1. 1.]
 [1. 1.]
 [1. 1.]]

Create a pyttb.ktensor with entries equal to 0:

>>> K = ttb.ktensor.from_function(np.zeros, (2, 3, 4), 2)
>>> print(K)
ktensor of shape (2, 3, 4) with order F
weights=[1. 1.]
factor_matrices[0] =
[[0. 0.]
 [0. 0.]]
factor_matrices[1] =
[[0. 0.]
 [0. 0.]
 [0. 0.]]
factor_matrices[2] =
[[0. 0.]
 [0. 0.]
 [0. 0.]
 [0. 0.]]
classmethod from_vector(data: ndarray, shape: int | Iterable[int], contains_weights: bool)[source]

Construct a pyttb.ktensor from a vector and shape.

The rank of the pyttb.ktensor is inferred from the shape and length of the vector.

Parameters:
  • data – Vector containing either elements of the factor matrices or elements of the weights and factor matrices. When both the elements of the weights and the factor_matrices are present, the weights come first and the columns of the factor matrices come next.

  • shape – Shape of the resulting ktensor.

  • contains_weights – Flag to specify if data contains weights. If False, all weights are set to 1.

Examples

Create a pyttb.ktensor from a vector containing only elements of the factor matrices:

>>> rank = 2
>>> shape = (2, 3, 4)
>>> data = np.arange(1, rank * sum(shape) + 1).astype(float)
>>> K = ttb.ktensor.from_vector(data[:], shape, False)
>>> print(K)
ktensor of shape (2, 3, 4) with order F
weights=[1. 1.]
factor_matrices[0] =
[[1. 3.]
 [2. 4.]]
factor_matrices[1] =
[[ 5.  8.]
 [ 6.  9.]
 [ 7. 10.]]
factor_matrices[2] =
[[11. 15.]
 [12. 16.]
 [13. 17.]
 [14. 18.]]

Create a pyttb.ktensor from a vector containing elements of both the weights and the factor matrices:

>>> weights = 2 * np.ones(rank).astype(float)
>>> weights_and_data = np.concatenate((weights, data), axis=0)
>>> K = ttb.ktensor.from_vector(weights_and_data[:], shape, True)
>>> print(K)
ktensor of shape (2, 3, 4) with order F
weights=[2. 2.]
factor_matrices[0] =
[[1. 3.]
 [2. 4.]]
factor_matrices[1] =
[[ 5.  8.]
 [ 6.  9.]
 [ 7. 10.]]
factor_matrices[2] =
[[11. 15.]
 [12. 16.]
 [13. 17.]
 [14. 18.]]
arrange(weight_factor: int | None = None, permutation: tuple | list | ndarray | None = None)[source]

Arrange the rank-1 components of a pyttb.ktensor in place.

If permutation is passed, the columns of self.factor_matrices are arranged using the provided permutation, so you must make a copy before calling this method if you want to store the original pyttb.ktensor. If weight_factor is passed, then the values in self.weights are absorbed into self.factor_matrices[weight_factor]. If no parameters are passed, then the columns of self.factor_matrices are normalized and then permuted such that the resulting self.weights are sorted by magnitude, greatest to least. Passing both parameters leads to an error.

Parameters:
  • weight_factor – Index of the factor matrix the weights will be absorbed into.

  • permutation – The new order of the components of the pyttb.ktensor into which to permute. The permutation must be of length equal to the number of components of the pyttb.ktensor, self.ncomponents and must be a permutation of [0,…,`self.ncomponents`-1].

Examples

Create the initial pyttb.ktensor:

>>> weights = np.array([1.0, 2.0])
>>> fm0 = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> fm1 = np.array([[5.0, 6.0], [7.0, 8.0]])
>>> fm2 = np.array([[9.0, 10.0], [11.0, 12.0]])
>>> K = ttb.ktensor([fm0, fm1, fm2], weights)
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 2.]
factor_matrices[0] =
[[1. 2.]
 [3. 4.]]
factor_matrices[1] =
[[5. 6.]
 [7. 8.]]
factor_matrices[2] =
[[ 9. 10.]
 [11. 12.]]

Arrange the columns of the factor matrices using a permutation:

>>> p = [1, 0]
>>> K.arrange(permutation=p)
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[2. 1.]
factor_matrices[0] =
[[2. 1.]
 [4. 3.]]
factor_matrices[1] =
[[6. 5.]
 [8. 7.]]
factor_matrices[2] =
[[10.  9.]
 [12. 11.]]

Normalize and permute columns such that weights are sorted in decreasing order:

>>> K.arrange()
>>> print(K)  
ktensor of shape (2, 2, 2) with order F
weights=[1397.1399... 386.6264...]
factor_matrices[0] =
[[0.4472... 0.3162...]
 [0.8944... 0.9486...]]
factor_matrices[1] =
[[0.6... 0.5812...]
 [0.8... 0.8137...]]
factor_matrices[2] =
[[0.6401... 0.6332...]
 [0.7682... 0.7739...]]

Absorb the weights into the second factor:

>>> K.arrange(weight_factor=1)
>>> print(K)  
ktensor of shape (2, 2, 2) with order F
weights=[1. 1.]
factor_matrices[0] =
[[0.4472... 0.3162...]
 [0.8944... 0.9486...]]
factor_matrices[1] =
[[ 838.2839... 224.7220...]
 [1117.7119... 314.6108...]]
factor_matrices[2] =
[[0.6401... 0.6332...]
 [0.7682... 0.7739...]]
copy() ktensor[source]

Make a deep copy of a pyttb.ktensor.

Examples

Create a random pyttb.ktensor with weights of 1:

>>> np.random.seed(1)
>>> K = ttb.ktensor.from_function(np.random.random_sample, (2, 3, 4), 2)
>>> print(K)  
ktensor of shape (2, 3, 4) with order F
weights=[1. 1.]
factor_matrices[0] =
[[4.1702...e-01 7.2032...e-01]
 [1.1437...e-04 3.0233...e-01]]
factor_matrices[1] =
[[0.1467... 0.0923...]
 [0.1862... 0.3455...]
 [0.3967... 0.5388...]]
factor_matrices[2] =
[[0.4191... 0.6852...]
 [0.2044... 0.8781...]
 [0.0273... 0.6704...]
 [0.4173... 0.5586...]]

Create a copy of the pyttb.ktensor and change the weights:

>>> K2 = K.copy()
>>> K2.weights = np.array([2.0, 3.0])
>>> print(K2)  
ktensor of shape (2, 3, 4) with order F
weights=[2. 3.]
factor_matrices[0] =
[[4.1702...e-01 7.2032...e-01]
 [1.1437...e-04 3.023...e-01]]
factor_matrices[1] =
[[0.1467... 0.0923...]
 [0.1862... 0.3455...]
 [0.3967... 0.5388...]]
factor_matrices[2] =
[[0.4191... 0.6852...]
 [0.2044... 0.8781...]
 [0.0273... 0.6704...]
 [0.4173... 0.5586...]]

Show that the original pyttb.ktensor is unchanged:

>>> print(K)  
ktensor of shape (2, 3, 4) with order F
weights=[1. 1.]
factor_matrices[0] =
[[4.1702...e-01 7.2032...e-01]
 [1.1437...e-04 3.0233...e-01]]
factor_matrices[1] =
[[0.1467... 0.0923...]
 [0.1862... 0.3455...]
 [0.3967... 0.5388...]]
factor_matrices[2] =
[[0.4191... 0.6852...]
 [0.2044... 0.8781...]
 [0.0273... 0.6704...]
 [0.4173... 0.5586...]]
double(immutable: bool = False) ndarray[source]

Convert pyttb.ktensor to numpy.ndarray.

Parameters:

immutable (Whether or not the returned data cam be mutated. May enable) – additional optimizations.

Examples

Create the initial pyttb.ktensor:

>>> weights = np.array([1.0, 2.0])
>>> fm0 = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> fm1 = np.array([[5.0, 6.0], [7.0, 8.0]])
>>> fm2 = np.array([[9.0, 10.0], [11.0, 12.0]])
>>> K = ttb.ktensor([fm0, fm1, fm2], weights)

Convert to a numpy.ndarray (i.e., multidiemnsional array):

>>> K.double() 
array([[[285., 343.],
        [383., 461.]],
       [[615., 741.],
        [829., 999.]]])
>>> print(type(K.double()))
<class 'numpy.ndarray'>
extract(idx: int | tuple | list | ndarray | None = None) ktensor[source]

Create a new pyttb.ktensor with only the specified components.

Parameters:

idx – Index set of components to extract. It should be the case that idx is a subset of [0,…,`self.ncomponents`]. If this parameter is None or is empty, a copy of the pyttb.ktensor is returned.

Examples

Create the initial pyttb.ktensor:

>>> weights = np.array([1.0, 2.0])
>>> fm0 = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> fm1 = np.array([[5.0, 6.0], [7.0, 8.0]])
>>> fm2 = np.array([[9.0, 10.0], [11.0, 12.0]])
>>> K = ttb.ktensor([fm0, fm1, fm2], weights)

Create a new pyttb.ktensor, extracting only the second component from each factor of the original pyttb.ktensor:

>>> K.extract([1])
ktensor of shape (2, 2, 2) with order F
weights=[2.]
factor_matrices[0] =
[[2.]
 [4.]]
factor_matrices[1] =
[[6.]
 [8.]]
factor_matrices[2] =
[[10.]
 [12.]]
fixsigns(other: ktensor | None = None) ktensor[source]

Change the elements of a pyttb.ktensor in place.

Update so that the largest magnitude entries for each column vector in each factor matrix are positive, provided that the sign on pairs of vectors in a rank-1 component can be flipped.

Parameters:

other – If not None, returns a version of the pyttb.ktensor where some of the signs of the columns of the factor matrices have been flipped to better align with other. In not None, both pyttb.ktensor objects are first normalized (using normalize()).

Examples

Create a pyttb.ktensor with negative large magnitude entries:

>>> weights = np.array([1.0, 2.0])
>>> fm0 = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> fm1 = np.array([[5.0, 6.0], [7.0, 8.0]])
>>> fm2 = np.array([[9.0, 10.0], [11.0, 12.0]])
>>> K = ttb.ktensor([fm0, fm1, fm2], weights)
>>> K.factor_matrices[0][1, 1] = -K.factor_matrices[0][1, 1]
>>> K.factor_matrices[1][1, 1] = -K.factor_matrices[1][1, 1]
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 2.]
factor_matrices[0] =
[[ 1.  2.]
 [ 3. -4.]]
factor_matrices[1] =
[[ 5.  6.]
 [ 7. -8.]]
factor_matrices[2] =
[[ 9. 10.]
 [11. 12.]]

Fix the signs of the largest magnitude entries:

>>> print(K.fixsigns())
ktensor of shape (2, 2, 2) with order F
weights=[1. 2.]
factor_matrices[0] =
[[ 1. -2.]
 [ 3.  4.]]
factor_matrices[1] =
[[ 5. -6.]
 [ 7.  8.]]
factor_matrices[2] =
[[ 9. 10.]
 [11. 12.]]

Fix the signs using another pyttb.ktensor:

>>> K = ttb.ktensor([fm0, fm1, fm2], weights)
>>> K2 = K.copy()
>>> K2.factor_matrices[0][1, 1] = -K2.factor_matrices[0][1, 1]
>>> K2.factor_matrices[1][1, 1] = -K2.factor_matrices[1][1, 1]
>>> K.fixsigns(K2) 
ktensor of shape (2, 2, 2) with order F
weights=[ 386.6264... 1397.1399...]
factor_matrices[0] =
[[ 0.3162... -0.4472...]
 [ 0.9486... -0.8944...]]
factor_matrices[1] =
[[ 0.5812... -0.6...]
 [ 0.8137... -0.8...]]
factor_matrices[2] =
[[0.6332... 0.6401...]
 [0.7739... 0.7682...]]
full() tensor[source]

Convert a pyttb.ktensor to a pyttb.tensor.

Examples

Create the initial pyttb.ktensor:

>>> weights = np.array([1.0, 2.0])
>>> fm0 = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> fm1 = np.array([[5.0, 6.0], [7.0, 8.0]])
>>> fm2 = np.array([[9.0, 10.0], [11.0, 12.0]])
>>> K = ttb.ktensor([fm0, fm1, fm2], weights)

Convert to a dense pyttb.tensor:

>>> print(K.full())
tensor of shape (2, 2, 2) with order F
data[:, :, 0] =
[[285. 383.]
 [615. 829.]]
data[:, :, 1] =
[[343. 461.]
 [741. 999.]]
innerprod(other: tensor | sptensor | ktensor | ttensor) float[source]

Efficient inner product with a pyttb.ktensor and other tensor.

Efficiently computes the inner product between two tensors, self and other. If other is a pyttb.ktensor, the inner product is computed using inner products of the factor matrices. Otherwise, the inner product is computed using the pyttb.ktensor.ttv() (tensor times vector) of other with all of the columns of self.factor_matrices.

Parameters:

other – Tensor with which to compute the inner product.

Examples

Create a pyttb.ktensor of all ones and compute the inner product with itself:

>>> K = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2)
>>> print(K.innerprod(K))
96.0
isequal(other: ktensor) bool[source]

Equal comparator for pyttb.ktensor objects.

This verifies that the weights and factor matrices of the two pyttb.ktensor objects match exactly.

Parameters:

otherpyttb.ktensor with which to compare.

Examples

Create instances of the same pyttb.ktensor using two different approaches and show they are equal:

>>> K1 = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2)
>>> factor_matrices = [np.ones((2, 2)), np.ones((3, 2)), np.ones((4, 2))]
>>> weights = np.ones((2,))
>>> K2 = ttb.ktensor(factor_matrices, weights)
>>> print(K1.isequal(K2))
True
issymmetric(return_diffs: Literal[False]) bool[source]
issymmetric(return_diffs: Literal[True]) tuple[bool, numpy.ndarray]
issymmetric(return_diffs: bool = False) bool | tuple[bool, ndarray]

Check if pyttb.ktensor is symmetric for every permutation.

Parameters:

return_diffs – If True, returns the matrix of the norm of the differences between the factor matrices.

Examples

Create a pyttb.ktensor that is symmetric and test if it is symmetric:

>>> K = ttb.ktensor.from_function(np.ones, (3, 3, 3), 2)
>>> print(K.issymmetric())
True

Create a pyttb.ktensor that is not symmetric and return the differences:

>>> weights = np.array([1.0, 2.0])
>>> fm0 = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> fm1 = np.array([[5.0, 6.0], [7.0, 8.0]])
>>> fm2 = np.array([[9.0, 10.0], [11.0, 12.0]])
>>> K2 = ttb.ktensor([fm0, fm1, fm2], weights)
>>> issym, diffs = K2.issymmetric(return_diffs=True)
>>> print(diffs)
[[ 0.  8. 16.]
 [ 0.  0.  8.]
 [ 0.  0.  0.]]
mask(W: tensor | sptensor) ndarray[source]

Extract pyttb.ktensor values as specified by mask tensor W.

W is a pyttb.tensor or pyttb.sptensor containing only values of zeros (0) and ones (1). The values in the pyttb.ktensor corresponding to the indices for the ones (1) in W will be returned as a column vector.

Parameters:

W – Mask tensor to apply to ktensor.

Examples

Create a pyttb.ktensor:

>>> weights = np.array([1.0, 2.0])
>>> fm0 = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> fm1 = np.array([[5.0, 6.0], [7.0, 8.0]])
>>> fm2 = np.array([[9.0, 10.0], [11.0, 12.0]])
>>> K = ttb.ktensor([fm0, fm1, fm2], weights)

Show the full tensor:

>>> print(K.full())
tensor of shape (2, 2, 2) with order F
data[:, :, 0] =
[[285. 383.]
 [615. 829.]]
data[:, :, 1] =
[[343. 461.]
 [741. 999.]]

Create a mask pyttb.tensor and extract the elements of the pyttb.ktensor using the mask:

>>> subs = np.array([[0, 0, 0], [1, 1, 1]])
>>> vals = np.array([[1], [1]])
>>> W = ttb.sptensor(subs, vals, shape=K.shape)
>>> print(K.mask(W))
[[285.]
 [999.]]
mttkrp(U: ktensor | Sequence[ndarray], n: int | integer) ndarray[source]

Matricized tensor times Khatri-Rao product for pyttb.ktensor.

Efficiently calculates the matrix product of the n-mode matricization of a pyttb.ktensor with the Khatri-Rao product of all entries in U, a list of factor matrices, except the nth.

Parameters:
  • U – Factor matrices.

  • n – Multiply by all modes except n.

Examples

Create a pyttb.ktensor and list of factor matrices, then compute the product of the matricization of pyttb.ktensor along mode 0 with the Khatri-Rao product of all the factor matrices except the first one (corresponding to dimension 0):

>>> K = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2)
>>> U = [1*np.ones((2, 2)), 2*np.ones((3, 2)), 3*np.ones(((4, 2)))]
>>> print(K.mttkrp(U, 0))
[[144. 144.]
 [144. 144.]]
norm() float[source]

Compute the norm of a pyttb.ktensor.

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

Examples

Create a pyttb.ktensor of ones (1) and compute its norm:

>>> K = ttb.ktensor.from_function(np.ones, (2, 4, 8), 2)
>>> K.norm()
16.0
normalize(weight_factor: int | Literal['all'] | None = None, sort: bool | None = False, normtype: float = 2, mode: int | None = None) ktensor[source]

Normalize the columns of the factor matrices in place.

Optionally, absorb the weights into desired normalized factors.

Parameters:
  • weight_factor – Absorb the weights into one or more factors. If “all”, absorb weight equally across all factors. If int, absorb weight into a single dimension (value must be in range(self.ndims)).

  • sort – Boolean flag indicating whether to sort the columns in descending order of the weights.

  • normtype – Order of the norm (see numpy.linalg.norm() for possible values).

  • mode – Index of factor matrix to normalize. A value of None means normalize all factor matrices.

Examples

Create a rank-2 4x4x4 pyttb.ktensor with factor matrices of ones (1) and then normalize the factor matrices:

>>> K = ttb.ktensor.from_function(np.ones, (4, 4, 4), 2)
>>> print(K.normalize())
ktensor of shape (4, 4, 4) with order F
weights=[8. 8.]
factor_matrices[0] =
[[0.5 0.5]
 [0.5 0.5]
 [0.5 0.5]
 [0.5 0.5]]
factor_matrices[1] =
[[0.5 0.5]
 [0.5 0.5]
 [0.5 0.5]
 [0.5 0.5]]
factor_matrices[2] =
[[0.5 0.5]
 [0.5 0.5]
 [0.5 0.5]
 [0.5 0.5]]

Normalize the pyttb.ktensor again, absorbing the weights of the factor matrices into the factor matrix associated with dimension 0:

>>> K.normalize(weight_factor=0)
ktensor of shape (4, 4, 4) with order F
weights=[1. 1.]
factor_matrices[0] =
[[4. 4.]
 [4. 4.]
 [4. 4.]
 [4. 4.]]
factor_matrices[1] =
[[0.5 0.5]
 [0.5 0.5]
 [0.5 0.5]
 [0.5 0.5]]
factor_matrices[2] =
[[0.5 0.5]
 [0.5 0.5]
 [0.5 0.5]
 [0.5 0.5]]
nvecs(n: int, r: int, flipsign: bool = True) ndarray[source]

Compute the leading mode-n vectors of the ktensor.

Computes the r leading eigenvectors of Xn*Xn.T (where Xn 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 Xn*Xn.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.

Examples

Create a pyttb.ktensor and compute a single eigenvector for dimension 0:

>>> K = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2)
>>> nvecs1 = K.nvecs(0, 1)
>>> print(nvecs1)  
[[0.7071...]
 [0.7071...]]

Compute first 2 leading eigenvectors for dimension 0:

>>> nvecs2 = K.nvecs(0, 2)
>>> print(nvecs2)  
[[ 0.7071...  0.7071...]
 [ 0.7071... -0.7071...]]
permute(order: int | float | Iterable[int] | Iterable[float] | ndarray) ktensor[source]

Permute pyttb.ktensor dimensions.

Rearranges the dimensions of a pyttb.ktensor so that they are in the order specified by order. The corresponding ktensor has the same components as self but the order of the subscripts needed to access any particular element is rearranged as specified by order.

Parameters:

order – Permutation of [0,…,self.ndims-1].

Examples

Create a pyttb.ktensor:

>>> weights = np.array([1.0, 2.0])
>>> fm0 = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> fm1 = np.array([[5.0, 6.0], [7.0, 8.0]])
>>> fm2 = np.array([[9.0, 10.0], [11.0, 12.0]])
>>> K = ttb.ktensor([fm0, fm1, fm2], weights)
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 2.]
factor_matrices[0] =
[[1. 2.]
 [3. 4.]]
factor_matrices[1] =
[[5. 6.]
 [7. 8.]]
factor_matrices[2] =
[[ 9. 10.]
 [11. 12.]]

Permute the order of the dimension so they are in reverse order:

>>> order = np.arange(K.ndims)[::-1]
>>> K1 = K.permute(order)
>>> print(K1)
ktensor of shape (2, 2, 2) with order F
weights=[1. 2.]
factor_matrices[0] =
[[ 9. 10.]
 [11. 12.]]
factor_matrices[1] =
[[5. 6.]
 [7. 8.]]
factor_matrices[2] =
[[1. 2.]
 [3. 4.]]

Permute dimensions again to recover the original pyttb.ktensor:

>>> K.isequal(K1.permute(order))
True
redistribute(mode: int) ktensor[source]

Distribute weights of a pyttb.ktensor to the specified mode.

The redistribution of weights is performed in place.

Parameters:

mode – Must be value in [0,…self.ndims-1].

Example

Create a pyttb.ktensor:

>>> weights = np.array([2.0, 3.0])
>>> fm0 = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> fm1 = np.array([[5.0, 6.0], [7.0, 8.0]])
>>> fm2 = np.array([[9.0, 10.0], [11.0, 12.0]])
>>> K = ttb.ktensor([fm0, fm1, fm2], weights)
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[2. 3.]
factor_matrices[0] =
[[1. 2.]
 [3. 4.]]
factor_matrices[1] =
[[5. 6.]
 [7. 8.]]
factor_matrices[2] =
[[ 9. 10.]
 [11. 12.]]

Distribute weights of that pyttb.ktensor to mode 0:

>>> K.redistribute(0)
ktensor of shape (2, 2, 2) with order F
weights=[1. 1.]
factor_matrices[0] =
[[ 2.  6.]
 [ 6. 12.]]
factor_matrices[1] =
[[5. 6.]
 [7. 8.]]
factor_matrices[2] =
[[ 9. 10.]
 [11. 12.]]
score(other: ktensor, weight_penalty: bool = True, threshold: float | None = None, greedy: bool = True) tuple[float, ktensor, bool, ndarray][source]

Check if two pyttb.ktensor objects with the same shape match.

Matching is defined as follows. If self and other are single-component pyttb.ktensor instances that have been normalized so that their weights are self.weights and other.weights, and their factor matrices are single column vectors containing [a1,a2,…,an] and [b1,b2,…bn], respectively, then the score is defined as

score = penalty * (a1.T*b1) * (a2.T*b2) * … * (an.T*bn),

where the penalty is defined by the weights such that

max_weights = max(self.weights, other.weights)

penalty = 1 - abs(self.weights - other.weights) / max_weights.

The score of multi-component pyttb.ktensor instances is a normalized sum of the scores across the best permutation of the components of self. self can have more components than other; any extra components are ignored in terms of the matching score.

Returns the score, normalized pyttb.ktensor, a Boolean flag indicating whether a match was found, and a permutation array specifying the dimensions of self that were used to best match other.

Parameters:
  • otherpyttb.ktensor with which to match.

  • weight_penalty – Flag indicating whether or not to consider the weights in the calculations.

  • threshold – Threshold specified in the formula above for determining a match. (defaults to: 0.99**self.ndims)

  • greedy – Flag indicating whether or not to consider all possible matchings (exponentially expensive) or just do a greedy matching.

Examples

Create two pyttb.ktensor objects with an exact match in the first columns of the factor matrices but only near matches in the other columns of the factor matrices, and compute the score between them:

>>> factors = [
...     np.ones((3, 3)) + 0.1,
...     np.ones((4, 3)) + 0.2,
...     np.ones((5, 3)) + 0.3,
... ]
>>> weights = np.array([2.0, 1.0, 3.0])
>>> K = ttb.ktensor(factors, weights)
>>> factors_2 = [
...     np.ones((3, 2)) + 0.1,
...     np.ones((4, 2)) + 0.2,
...     np.ones((5, 2)) + 0.3,
... ]
>>> weights_2 = np.array([2.0, 4.0])
>>> K2 = ttb.ktensor(factors_2, weights_2)
>>> score, Kperm, flag, perm = K.score(K2)
>>> print(np.isclose(score, 0.875))
True
>>> print(perm)
[0 2 1]

Compute score without using weights, illustrating that the first two columns of the factor matrices of the two pyttb.ktensor objects match exactly:

>>> score, Kperm, flag, perm = K.score(K2, weight_penalty=False)
>>> print(np.isclose(score, 1.0))
True
>>> print(perm)
[0 1 2]
symmetrize() ktensor[source]

Symmetrize a pyttb.ktensor in all modes.

Symmetrize a pyttb.ktensor with respect to all modes so that the resulting pyttb.ktensor is symmetric with respect to any permutation of indices.

Examples

Create a pyttb.ktensor and verify that it is not symmetric:

>>> weights = np.array([1.0, 2.0])
>>> fm0 = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> fm1 = np.array([[5.0, 6.0], [7.0, 8.0]])
>>> fm2 = np.array([[9.0, 10.0], [11.0, 12.0]])
>>> K = ttb.ktensor([fm0, fm1, fm2], weights)
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 2.]
factor_matrices[0] =
[[1. 2.]
 [3. 4.]]
factor_matrices[1] =
[[5. 6.]
 [7. 8.]]
factor_matrices[2] =
[[ 9. 10.]
 [11. 12.]]
>>> print(K.issymmetric())
False

Make the pyttb.ktensor symmetric and verify that it is symmetric:

>>> K1 = K.symmetrize()
>>> print(K1)  
ktensor of shape (2, 2, 2) with order F
weights=[1. 1.]
factor_matrices[0] =
[[3.7170... 6.2879...]
 [6.1591... 9.1768...]]
factor_matrices[1] =
[[3.7170... 6.2879...]
 [6.1591... 9.1768...]]
factor_matrices[2] =
[[3.7170... 6.2879...]
 [6.1591... 9.1768...]]
>>> print(K1.issymmetric())
True
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.ktensor.

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 the initial pyttb.ktensor:

>>> weights = np.array([1.0, 2.0])
>>> fm0 = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> fm1 = np.array([[5.0, 6.0], [7.0, 8.0]])
>>> fm2 = np.array([[9.0, 10.0], [11.0, 12.0]])
>>> K = ttb.ktensor([fm0, fm1, fm2], weights)

Show what the full tensor looks like:

>>> print(K.full())
tensor of shape (2, 2, 2) with order F
data[:, :, 0] =
[[285. 383.]
 [615. 829.]]
data[:, :, 1] =
[[343. 461.]
 [741. 999.]]

Convert to pyttb.tenmat:

>>> K.to_tenmat(np.array([0]))
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[:, :] =
[[285. 383. 343. 461.]
 [615. 829. 741. 999.]]
to_tensor() tensor[source]

Convert to tensor.

Same as pyttb.ktensor.full().

tolist(mode: int | None = None) list[ndarray][source]

Convert pyttb.ktensor to a list of factor matrices.

Evenly distributes the weights across factors. Optionally absorb the weights into a single mode.

Parameters:

mode – Index of factor matrix to absorb all of the weights.

Examples

Create a pyttb.ktensor:

>>> K = ttb.ktensor.from_function(np.ones, (4, 4, 4), 2) * 8
>>> print(K)
ktensor of shape (4, 4, 4) with order F
weights=[8. 8.]
factor_matrices[0] =
[[1. 1.]
 [1. 1.]
 [1. 1.]
 [1. 1.]]
factor_matrices[1] =
[[1. 1.]
 [1. 1.]
 [1. 1.]
 [1. 1.]]
factor_matrices[2] =
[[1. 1.]
 [1. 1.]
 [1. 1.]
 [1. 1.]]

Spread weights equally to all factors and return list of factor matrices:

>>> fm_list = K.tolist()
>>> for k, fm in enumerate(fm_list):
...     print(f"factor_matrix[{k}] =")
...     print(f"{fm}")
factor_matrix[0] =
[[2. 2.]
 [2. 2.]
 [2. 2.]
 [2. 2.]]
factor_matrix[1] =
[[2. 2.]
 [2. 2.]
 [2. 2.]
 [2. 2.]]
factor_matrix[2] =
[[2. 2.]
 [2. 2.]
 [2. 2.]
 [2. 2.]]

Shift weight to single factor matrix and return list of factor matrices:

>>> fm_list = K.tolist(0)
>>> for k, fm in enumerate(fm_list):
...     print(f"factor_matrix[{k}] =")
...     print(f"{fm}")
factor_matrix[0] =
[[32. 32.]
 [32. 32.]
 [32. 32.]
 [32. 32.]]
factor_matrix[1] =
[[0.5 0.5]
 [0.5 0.5]
 [0.5 0.5]
 [0.5 0.5]]
factor_matrix[2] =
[[0.5 0.5]
 [0.5 0.5]
 [0.5 0.5]
 [0.5 0.5]]
tovec(include_weights: bool = True) ndarray[source]

Convert pyttb.ktensor to column vector.

Returns a column vector with length (sum(self.shape)+1)*self.ncomponents. The vector contains the weights (if requested) stacked on top of each of the columns of the factor_matrices in order. Optionally include or exclude the weights. The output of this method can be consumed by from_vector().

Parameters:

include_weights – Flag to specify whether or not to include weights in output.

Examples

Create a pyttb.ktensor from a vector:

>>> rank = 2
>>> shape = (2, 3, 4)
>>> data = np.arange(1, rank * sum(shape) + 1)
>>> weights = 2 * np.ones(rank)
>>> weights_and_data = np.concatenate((weights, data), axis=0)
>>> K = ttb.ktensor.from_vector(weights_and_data[:], shape, True)
>>> print(K)
ktensor of shape (2, 3, 4) with order F
weights=[2. 2.]
factor_matrices[0] =
[[1. 3.]
 [2. 4.]]
factor_matrices[1] =
[[ 5.  8.]
 [ 6.  9.]
 [ 7. 10.]]
factor_matrices[2] =
[[11. 15.]
 [12. 16.]
 [13. 17.]
 [14. 18.]]

Create a pyttb.ktensor from a vector of data extracted from another pyttb.ktensor:

>>> K2 = ttb.ktensor.from_vector(K.tovec(), shape, True)
>>> print(K2)
ktensor of shape (2, 3, 4) with order F
weights=[2. 2.]
factor_matrices[0] =
[[1. 3.]
 [2. 4.]]
factor_matrices[1] =
[[ 5.  8.]
 [ 6.  9.]
 [ 7. 10.]]
factor_matrices[2] =
[[11. 15.]
 [12. 16.]
 [13. 17.]
 [14. 18.]]
ttv(vector: Sequence[ndarray] | ndarray, dims: int | float | Iterable[int] | Iterable[float] | ndarray | None = None, exclude_dims: int | float | Iterable[int] | Iterable[float] | ndarray | None = None) float | ktensor[source]

Tensor times vector for a pyttb.ktensor.

Computes the product of a pyttb.ktensor with a vector (i.e., numpy.ndarray). If dims is an integer, it specifies the dimension in the pyttb.ktensor along which the vector is multiplied. If the shape of the vector is = (I,), then the length of dimension dims of the pyttb.ktensor must be I. Note that the number of dimensions of the returned pyttb.ktensor is 1 less than the dimension of the pyttb.ktensor used in the multiplication because dimension dims is removed.

If vector is a list of np.array instances, the pyttb.ktensor is multiplied with each vector in the list. The products are computed sequentially along all dimensions (or modes) of the pyttb.ktensor, and thus the list must contain self.ndims vectors.

When dims is not None, compute the products along the dimensions specified by dims. In this case, the number of products can be less than self.ndims and the order of the sequence does not need to match the order of the dimensions in the pyttb.ktensor. Note that the number of vectors must match the number of dimensions provided, and the length of each vector must match the size of each dimension of the pyttb.ktensor specified in dims.

The number of dimensions of the returned pyttb.ktensor is n-k, where n = self.ndims and k = number of vectors provided as input. If k == n, a scalar is returned.

Parameters:
  • vector – Vector to multiply by.

  • dims – Dimension(s) along which to multiply. Exclusively provide dims or exclude_dims.

  • exclude_dims – Multiply by all but excluded dimension(s). Exclusively provide dims or exclude_dims.

Examples

Create a pyttb.ktensor:

>>> weights = np.array([1.0, 2.0])
>>> fm0 = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> fm1 = np.array([[5.0, 6.0], [7.0, 8.0]])
>>> fm2 = np.array([[9.0, 10.0], [11.0, 12.0]])
>>> K = ttb.ktensor([fm0, fm1, fm2], weights)
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 2.]
factor_matrices[0] =
[[1. 2.]
 [3. 4.]]
factor_matrices[1] =
[[5. 6.]
 [7. 8.]]
factor_matrices[2] =
[[ 9. 10.]
 [11. 12.]]

Compute the product of a pyttb.ktensor and a single vector (results in a pyttb.ktensor):

>>> K0 = K.ttv(np.array([1, 1]), dims=1)
>>> print(K0)
ktensor of shape (2, 2) with order F
weights=[12. 28.]
factor_matrices[0] =
[[1. 2.]
 [3. 4.]]
factor_matrices[1] =
[[ 9. 10.]
 [11. 12.]]

Compute the product of a pyttb.ktensor and a vector for each dimension (results in a float):

>>> vec = np.array([1, 1])
>>> K1 = K.ttv([vec, 2 * vec, 3 * vec])
>>> print(K1)
27936.0

Compute the product of a pyttb.ktensor and multiple vectors out of order (results in a pyttb.ktensor):

>>> K2 = K.ttv([vec, vec], np.array([2, 1]))
>>> print(K2)
ktensor of shape (2,) with order F
weights=[240. 616.]
factor_matrices[0] =
[[1. 2.]
 [3. 4.]]
update(modes: int | float | Iterable[int] | Iterable[float] | ndarray, data: ndarray) ktensor[source]

Update a pyttb.ktensor in the specific dimensions.

Updates with the values in data (in vector or matrix form). The value of modes must be a value in [-1,…,self.ndims]. If the Further, the number of elements in data must equal self.shape[modes] * self.ncomponents. The update is performed in place.

Parameters:
  • modes – List of dimensions to update; values must be in ascending order. If the first element of the list is -1, then update the weights. All other integer values values must be sorted and in [0,…,self.ndims-1].

  • data – Data values to use in the update.

Examples

Create a pyttb.ktensor of all ones:

>>> K = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2)

Create vectors for updating various factor matrices of the pyttb.ktensor:

>>> vec0 = 2 * np.ones(K.shape[0] * K.ncomponents)
>>> vec1 = 3 * np.ones(K.shape[1] * K.ncomponents)
>>> vec2 = 4 * np.ones(K.shape[2] * K.ncomponents)

Update a single factor matrix:

>>> K1 = K.copy()
>>> K1 = K1.update(0, vec0)
>>> print(K1)
ktensor of shape (2, 3, 4) with order F
weights=[1. 1.]
factor_matrices[0] =
[[2. 2.]
 [2. 2.]]
factor_matrices[1] =
[[1. 1.]
 [1. 1.]
 [1. 1.]]
factor_matrices[2] =
[[1. 1.]
 [1. 1.]
 [1. 1.]
 [1. 1.]]

Update all factor matrices:

>>> K2 = K.copy()
>>> vec_all = np.concatenate((vec0, vec1, vec2))
>>> K2 = K2.update([0, 1, 2], vec_all)
>>> print(K2)
ktensor of shape (2, 3, 4) with order F
weights=[1. 1.]
factor_matrices[0] =
[[2. 2.]
 [2. 2.]]
factor_matrices[1] =
[[3. 3.]
 [3. 3.]
 [3. 3.]]
factor_matrices[2] =
[[4. 4.]
 [4. 4.]
 [4. 4.]
 [4. 4.]]

Update some but not all factor matrices:

>>> K3 = K.copy()
>>> vec_some = np.concatenate((vec0, vec2))
>>> K3 = K3.update([0, 2], vec_some)
>>> print(K3)
ktensor of shape (2, 3, 4) with order F
weights=[1. 1.]
factor_matrices[0] =
[[2. 2.]
 [2. 2.]]
factor_matrices[1] =
[[1. 1.]
 [1. 1.]
 [1. 1.]]
factor_matrices[2] =
[[4. 4.]
 [4. 4.]
 [4. 4.]
 [4. 4.]]
viz(plots: tuple | list | None = None, show_figure: bool = True, normalize: bool = True, norm: int | float = 2, rel_weights: bool = True, rel_heights: tuple | list | None = None, rel_widths: tuple | list | None = None, horz_space: float | None = None, vert_space: float | None = None, left_space: float | None = None, right_space: float | None = None, top_space: float | None = None, bot_space: float | None = None, mode_titles: tuple | list | None = None, title=None) tuple[Figure, Axes][source]

Visualize factors for pyttb.ktensor.

Returns a matplotlib.figure.Figure handle for the generated figure and matplotlib.axes.Axes for the generated figure.

Parameters:
  • plots – List of functions (one per mode) which visualize the respective vectors of a factor. Function for mode i must have signature f(v_i,ax) where v_i is a numpy.ndarray vector of dimension n_i and ax is a matplotlib.axes.Axes on which to plot.

  • show_figure – Boolean determining if the resulting figure should be shown.

  • normalize – Boolean controlling whether to normalize factors and generate a compensating weight, then sort components by weight.

  • norm – Norm used to normalize factors; 1 for 1-norm, 2 for 2-norm, etc.

  • rel_weights – Boolean determining whether weights should be made relative by dividing by the largest weight.

  • rel_widths – List of numbers (one per mode) specifying relative widths of each plot column.

  • rel_heights – List of numbers (one per component) specifying relative height of each plot row.

  • horz/vert_space – Number determining amount of space between subplots (horizontally/vertically) as a fraction of the average axis width/height.

  • left/right/top/bot_space – Extent of subplots as fraction of figure width or height.

  • mode_titles – List of strings used as titles for each column (mode).

  • title – String containing overall figure title.

Examples

Set up a pyttb.ktensor to plot:

>>> np.random.seed(1)
>>> K = ttb.ktensor.from_function(np.random.random_sample, (2, 3, 10), 2)

Use plot K using default behavior K.viz():

>>> fig, axs = K.viz(show_figure=False)  
>>> plt.close(fig)

Define a more realistic plot function with x labels, control relative widths of each plot, and set mode titles.

>>> def mode_1_plot(v, ax):
...     ax.bar([1, 2], v, width=0.2)
...     ax.set_xticks([1, 2], labels=["neutron", "electron"], rotation=45)
>>> def mode_2_plot(v, ax):
...     ax.plot(np.arange(v.shape[0]), v)
...     ax.set_xlabel("$v$, [m/s]")
>>> def mode_3_plot(v, ax):
...     ax.semilogx(np.logspace(-2, 2, v.shape[0]), v)
...     ax.set_xlabel("$E$, [kJ]")
>>> plots = [mode_1_plot, mode_2_plot, mode_3_plot]
>>> fig, axs = K.viz(
...     show_figure=False,
...     plots=plots,
...     rel_widths=[1, 2, 3],
...     horz_space=0.4,
...     left_space=0.2,
...     bot_space=0.2,
...     mode_titles=["Particle", "Velocity", "Energy"],
... )  
>>> plt.close(fig)
__add__(other)[source]

Binary addition for pyttb.ktensor.

When adding two pyttb.ktensor objects, the weights vectors and columns of the factor_matrices of the second pyttb.ktensor are concatenated to those of the first pyttb.ktensor.

Parameters:

other (pyttb.ktensor) – pyttb.ktensor to add to self.

Examples

Create a pyttb.ktensor and add it to itself:

>>> K = ttb.ktensor.from_function(np.ones, (2, 2, 2), 2)
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 1.]
factor_matrices[0] =
[[1. 1.]
 [1. 1.]]
factor_matrices[1] =
[[1. 1.]
 [1. 1.]]
factor_matrices[2] =
[[1. 1.]
 [1. 1.]]
>>> print(K + K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 1. 1. 1.]
factor_matrices[0] =
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]]
factor_matrices[1] =
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]]
factor_matrices[2] =
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]]
__mul__(other)[source]

Element-wise (including scalar) multiplication for pyttb.ktensor.

When multiplying with a scalar, the weights of the pyttb.ktensor are multiplied by that scalar. When multiplying with a pyttb.tensor or pyttb.sptensor, the full tensor represented by the pyttb.ktensor is multiplied with the other tensor, and the result is returned as either a pyttb.tensor or pyttb.sptensor.

Parameters:

other (pyttb.tensor, pyttb.sptensor, float, int)

Examples

Create a pyttb.ktensor:

>>> K = ttb.ktensor.from_function(np.ones, (2, 2, 2), 2)
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 1.]
factor_matrices[0] =
[[1. 1.]
 [1. 1.]]
factor_matrices[1] =
[[1. 1.]
 [1. 1.]]
factor_matrices[2] =
[[1. 1.]
 [1. 1.]]

Multiply the pyttb.ktensor by a scalar:

>>> print(K * 3)
ktensor of shape (2, 2, 2) with order F
weights=[3. 3.]
factor_matrices[0] =
[[1. 1.]
 [1. 1.]]
factor_matrices[1] =
[[1. 1.]
 [1. 1.]]
factor_matrices[2] =
[[1. 1.]
 [1. 1.]]

Multiply the pyttb.ktensor by a pyttb.tensor of all ones (1):

>>> print(K * ttb.tensor.from_function(np.ones, K.shape))
tensor of shape (2, 2, 2) with order F
data[:, :, 0] =
[[2. 2.]
 [2. 2.]]
data[:, :, 1] =
[[2. 2.]
 [2. 2.]]

Multiply the pyttb.ktensor by a pyttb.sptensor containing a single nonzero element:

>>> subs = np.array([[1, 1, 1]])
>>> vals = np.array([[1]])
>>> print(K * ttb.sptensor(subs, vals, shape=K.shape))
sparse tensor of shape (2, 2, 2) with 1 nonzeros and order F
[1, 1, 1] = 2.0
__neg__()[source]

Unary minus (negative) for pyttb.ktensor instances.

When negating a pyttb.ktensor object, the elements of the weights vectors are negated.

Examples

Create a pyttb.ktensor and negate it:

>>> K = ttb.ktensor.from_function(np.ones, (2, 2, 2), 2)
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 1.]
factor_matrices[0] =
[[1. 1.]
 [1. 1.]]
factor_matrices[1] =
[[1. 1.]
 [1. 1.]]
factor_matrices[2] =
[[1. 1.]
 [1. 1.]]
>>> print(-K)
ktensor of shape (2, 2, 2) with order F
weights=[-1. -1.]
factor_matrices[0] =
[[1. 1.]
 [1. 1.]]
factor_matrices[1] =
[[1. 1.]
 [1. 1.]]
factor_matrices[2] =
[[1. 1.]
 [1. 1.]]
__pos__()[source]

Unary plus (positive) for pyttb.ktensor instances.

The effect of this operation is to return a copy of the pyttb.ktensor.

Examples

Create a pyttb.ktensor and compute the positive of it:

>>> K = ttb.ktensor.from_function(np.ones, (2, 2, 2), 2)
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 1.]
factor_matrices[0] =
[[1. 1.]
 [1. 1.]]
factor_matrices[1] =
[[1. 1.]
 [1. 1.]]
factor_matrices[2] =
[[1. 1.]
 [1. 1.]]
>>> print(+K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 1.]
factor_matrices[0] =
[[1. 1.]
 [1. 1.]]
factor_matrices[1] =
[[1. 1.]
 [1. 1.]]
factor_matrices[2] =
[[1. 1.]
 [1. 1.]]
__repr__()[source]

Return string representation of a pyttb.ktensor.

Examples

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

>>> K = ttb.ktensor.from_function(np.ones, (2, 2, 2), 2)
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 1.]
factor_matrices[0] =
[[1. 1.]
 [1. 1.]]
factor_matrices[1] =
[[1. 1.]
 [1. 1.]]
factor_matrices[2] =
[[1. 1.]
 [1. 1.]]
__rmul__(other)[source]

Element-wise reverse multiplication for pyttb.ktensor.

Parameters:

other (pyttb.tensor, pyttb.sptensor, float, int)

See also

__mul__()

Examples

Create a pyttb.ktensor:

>>> K = ttb.ktensor.from_function(np.ones, (2, 2, 2), 2)
>>> (2 * K).isequal(K * 2)
True
__str__()

Return string representation of a pyttb.ktensor.

Examples

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

>>> K = ttb.ktensor.from_function(np.ones, (2, 2, 2), 2)
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 1.]
factor_matrices[0] =
[[1. 1.]
 [1. 1.]]
factor_matrices[1] =
[[1. 1.]
 [1. 1.]]
factor_matrices[2] =
[[1. 1.]
 [1. 1.]]
__sub__(other)[source]

Binary subtraction for pyttb.ktensor.

When subtracting two pyttb.ktensor objects, the weights vectors and columns of the factor_matrices of the second pyttb.ktensor are concatenated to those of the first pyttb.ktensor, and the weights of the second pyttb.ktensor are negated.

Parameters:

other (pyttb.ktensor) – pyttb.ktensor to subtract from self.

Examples

Create a pyttb.ktensor and add it to itself:

>>> K = ttb.ktensor.from_function(np.ones, (2, 2, 2), 2)
>>> print(K)
ktensor of shape (2, 2, 2) with order F
weights=[1. 1.]
factor_matrices[0] =
[[1. 1.]
 [1. 1.]]
factor_matrices[1] =
[[1. 1.]
 [1. 1.]]
factor_matrices[2] =
[[1. 1.]
 [1. 1.]]
>>> print(K - K)
ktensor of shape (2, 2, 2) with order F
weights=[ 1.  1. -1. -1.]
factor_matrices[0] =
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]]
factor_matrices[1] =
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]]
factor_matrices[2] =
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]]

Verify that the result is indeed equivalent to a zero pyttb.tensor when expanded:

>>> (K - K).norm()
0.0
>>> (K - K).full().isequal(ttb.tensor.from_function(np.zeros, K.shape))
True