pyttb: Python Tensor Toolbox
Tensors (also known as multidimensional arrays or N-way arrays) are used in a variety of applications ranging from chemometrics to network analysis.
This is open source software. Please see LICENSE for the terms of the license (2-clause BSD).
For more information or for feedback on this project, please contact us.
Functionality
pyttb provides the following classes and functions for manipulating dense, sparse, and structured tensors, along with algorithms for computing low-rank tensor models.
-
pyttb supports multiple tensor types, including dense and sparse, as well as specially structured tensors, such as the Krusal format (stored as factor matrices).
-
CP methods such as alternating least squares, direct optimization, and weighted optimization (for missing data). Also alternative decompositions such as Poisson Tensor Factorization via alternating Poisson regression.
Python API
Python API
Tensor Classes
pyttb.ktensor
- class pyttb.ktensor[source]
Bases:
object
KTENSOR Class for Kruskal tensors (decomposed).
Contains the following data members:
weights
:numpy.ndarray
vector containing the weights of the rank-1 tensors defined by the outer products of the column vectors of the factor_matrices.factor_matrices
:list
ofnumpy.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 dimension i and r is the rank of the tensor (as well as the length of the weights vector).Although the constructor __init__() can be used to create an empty
pyttb.ktensor
, there are several class methods that can be used to create an instance of this class:Examples
For all examples listed below, the following module imports are assumed:
>>> import pyttb as ttb >>> import numpy as np
- classmethod from_data(weights, *factor_matrices)[source]
Construct a
pyttb.ktensor
from weights and factor matrices.The length of the list or the number of arguments specified by factor_matrices must equal the length of weights. See
pyttb.ktensor
for parameter descriptions.- Parameters:
weights (
numpy.ndarray
, required)factor_matrices (
list
ofnumpy.ndarray
or variable number ofnumpy.ndarray
, required)
- Returns:
Examples
Create a
pyttb.ktensor
from weights and a list of factor matrices:>>> weights = np.array([1., 2.]) >>> fm0 = np.array([[1., 2.], [3., 4.]]) >>> fm1 = np.array([[5., 6.], [7., 8.]]) >>> K = ttb.ktensor.from_data(weights, [fm0, fm1]) >>> print(K) ktensor of shape 2 x 2 weights=[1. 2.] factor_matrices[0] = [[1. 2.] [3. 4.]] factor_matrices[1] = [[5. 6.] [7. 8.]]
Create a
pyttb.ktensor
from weights and factor matrices passed as arguments:>>> K = ttb.ktensor.from_data(weights, fm0, fm1) >>> print(K) ktensor of shape 2 x 2 weights=[1. 2.] factor_matrices[0] = [[1. 2.] [3. 4.]] factor_matrices[1] = [[5. 6.] [7. 8.]]
- classmethod from_tensor_type(source) ktensor [source]
Construct a
pyttb.ktensor
from anotherpyttb.ktensor
. A deep copy of the data from the inputpyttb.ktensor
is used for the newpyttb.ktensor
.- Parameters:
source (
pyttb.ktensor
, required)- Returns:
Examples
Create an instance of a
pyttb.ktensor
:>>> fm0 = np.array([[1., 2.], [3., 4.]]) >>> fm1 = np.array([[5., 6.], [7., 8.]]) >>> factor_matrices = [fm0, fm1] >>> K_source = ttb.ktensor.from_factor_matrices(factor_matrices) >>> print(K_source) ktensor of shape 2 x 2 weights=[1. 1.] factor_matrices[0] = [[1. 2.] [3. 4.]] factor_matrices[1] = [[5. 6.] [7. 8.]]
Create another instance of a
pyttb.ktensor
from the original one above:>>> K = ttb.ktensor.from_tensor_type(K_source) >>> print(K) ktensor of shape 2 x 2 weights=[1. 1.] factor_matrices[0] = [[1. 2.] [3. 4.]] factor_matrices[1] = [[5. 6.] [7. 8.]]
See also
pyttb.ktensor.copy()
- classmethod from_factor_matrices(*factor_matrices)[source]
Construct a
pyttb.ktensor
from factor matrices. The weights of the returnedpyttb.ktensor
will all be equal to 1.- Parameters:
factor_matrices (
list
ofnumpy.ndarray
or variable number ofnumpy.ndarray
, required) – The number of columns of each of the factor matrices must be the same.- Returns:
Examples
Create a
pyttb.ktensor
from alist
of factor matrices:>>> fm0 = np.array([[1., 2.], [3., 4.]]) >>> fm1 = np.array([[5., 6.], [7., 8.]]) >>> factor_matrices = [fm0, fm1] >>> K = ttb.ktensor.from_factor_matrices(factor_matrices) >>> print(K) ktensor of shape 2 x 2 weights=[1. 1.] factor_matrices[0] = [[1. 2.] [3. 4.]] factor_matrices[1] = [[5. 6.] [7. 8.]]
Create a
pyttb.ktensor
from factor matrices passed as arguments:>>> K = ttb.ktensor.from_factor_matrices(fm0, fm1) >>> print(K) ktensor of shape 2 x 2 weights=[1. 1.] factor_matrices[0] = [[1. 2.] [3. 4.]] factor_matrices[1] = [[5. 6.] [7. 8.]]
- classmethod from_function(fun, shape, num_components)[source]
Construct a
pyttb.ktensor
whose factor matrix entries are set using a function. The weights of the returnedpyttb.ktensor
will all be equal to 1.- Parameters:
fun (function, required) – A function that can accept a shape (i.e.,
tuple
of dimension sizes) and return anumpy.ndarray
of that shape. Example functions include numpy.random.random_sample, numpy,zeros, numpy.ones.shape (
tuple
, required)num_components (int, required)
- Returns:
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 x 3 x 4 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 x 3 x 4 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 x 3 x 4 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, shape, contains_weights)[source]
Construct a
pyttb.ktensor
from a vector (given as anumpy.ndarray
) and shape (given as anumpy.ndarray
). The rank of thepyttb.ktensor
is inferred from the shape and length of the vector.- Parameters:
data (
numpy.ndarray
, required) – Vector containing either elements of the factor matrices (when `contains_weights`==False) or elements of the weights and factor matrices (when `contains_weights`==True). 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 (
numpy.ndarray
, required) – Vector containing the shape of the tensor (i.e., lengths of the dimensions).contains_weights (bool, required) – Flag to specify whether or not data contains weights. If False, all weights are set to 1.
- Returns:
Examples
Create a
pyttb.ktensor
from a vector containing only elements of the factor matrices:>>> rank = 2 >>> shape = np.array([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 x 3 x 4 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 x 3 x 4 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=None, permutation=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 originalpyttb.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 (int, optional) – The index of the factor matrix that the weights will be absorbed into.
permutation (
tuple
,list
, ornumpy.ndarray
, optional) – The new order of the components of thepyttb.ktensor
into which to permute. The permutation must be of length equal to the number of components of thepyttb.ktensor
, self.ncomponents and must be a permutation of [0,…,`self.ncomponents`-1].
Examples
Create the initial
pyttb.ktensor
:>>> weights = np.array([1., 2.]) >>> fm0 = np.array([[1., 2.], [3., 4.]]) >>> fm1 = np.array([[5., 6.], [7., 8.]]) >>> K = ttb.ktensor.from_data(weights, [fm0, fm1]) >>> print(K) ktensor of shape 2 x 2 weights=[1. 2.] factor_matrices[0] = [[1. 2.] [3. 4.]] factor_matrices[1] = [[5. 6.] [7. 8.]]
Arrange the columns of the factor matrices using a permutation:
>>> p = [1,0] >>> K.arrange(permutation=p) >>> print(K) ktensor of shape 2 x 2 weights=[2. 1.] factor_matrices[0] = [[2. 1.] [4. 3.]] factor_matrices[1] = [[6. 5.] [8. 7.]]
Normalize and permute columns such that weights are sorted in decreasing order:
>>> K.arrange() >>> print(K) ktensor of shape 2 x 2 weights=[89.4427... 27.2029...] factor_matrices[0] = [[0.4472... 0.3162...] [0.8944... 0.9486...]] factor_matrices[1] = [[0.6... 0.5812...] [0.8... 0.8137...]]
Absorb the weights into the second factor:
>>> K.arrange(weight_factor=1) >>> print(K) ktensor of shape 2 x 2 weights=[1. 1.] factor_matrices[0] = [[0.4472... 0.3162...] [0.8944... 0.9486...]] factor_matrices[1] = [[53.6656... 15.8113...] [71.5541... 22.1359...]]
- copy()[source]
Make a deep copy of a
pyttb.ktensor
.- Returns:
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 x 3 x 4 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., 3.]) >>> print(K2) ktensor of shape 2 x 3 x 4 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 x 3 x 4 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()[source]
Convert
pyttb.ktensor
tonumpy.ndarray
.- Returns:
Examples
>>> weights = np.array([1., 2.]) >>> fm0 = np.array([[1., 2.], [3., 4.]]) >>> fm1 = np.array([[5., 6.], [7., 8.]]) >>> factor_matrices = [fm0, fm1] >>> K = ttb.ktensor.from_data(weights, factor_matrices) >>> K.double() array([[29., 39.], [63., 85.]]) >>> type(K.double()) <class 'numpy.ndarray'>
- end(k=None)[source]
Last index of indexing expression for
pyttb.ktensor
.- Parameters:
k (int, optional) – dimension for subscripted indexing
- Returns:
int (index)
Examples
>>> K = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2) >>> print(K.end(2)) 3
- extract(idx=None)[source]
Creates a new
pyttb.ktensor
with only the specified components.- Parameters:
idx (int,
tuple
,list
,numpy.ndarray
, optional) – 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 thepyttb.ktensor
is returned.- Returns:
Examples
Create a
pyttb.ktensor
:>>> weights = np.array([1., 2.]) >>> fm0 = np.array([[1., 2.], [3., 4.]]) >>> fm1 = np.array([[5., 6.], [7., 8.]]) >>> K = ttb.ktensor.from_data(weights, [fm0, fm1]) >>> print(K) ktensor of shape 2 x 2 weights=[1. 2.] factor_matrices[0] = [[1. 2.] [3. 4.]] factor_matrices[1] = [[5. 6.] [7. 8.]]
Create a new
pyttb.ktensor
, extracting only the second component from each factor of the originalpyttb.ktensor
:>>> K.extract([1]) ktensor of shape 2 x 2 weights=[2.] factor_matrices[0] = [[2.] [4.]] factor_matrices[1] = [[6.] [8.]]
- fixsigns(other=None)[source]
Change the elements of a
pyttb.ktensor
in place 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 (
pyttb.ktensor
, optional) – If not None, returns a version of thepyttb.ktensor
where some of the signs of the columns of the factor matrices have been flipped to better align with other. In not None, bothpyttb.ktensor
objects are first normalized (usingnormalize()
).- Returns:
pyttb.ktensor
– The changes are made in place and a reference to the updated tensor is returned
Examples
Create a
pyttb.ktensor
with negative large magnitude entries:>>> weights = np.array([1., 2.]) >>> fm0 = np.array([[1., 2.], [3., 4.]]) >>> fm1 = np.array([[5., 6.], [7., 8.]]) >>> K = ttb.ktensor.from_data(weights, [fm0, fm1]) >>> 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 x 2 weights=[1. 2.] factor_matrices[0] = [[ 1. 2.] [ 3. -4.]] factor_matrices[1] = [[ 5. 6.] [ 7. -8.]]
Fix the signs of the largest magnitude entries:
>>> print(K.fixsigns()) ktensor of shape 2 x 2 weights=[1. 2.] factor_matrices[0] = [[ 1. -2.] [ 3. 4.]] factor_matrices[1] = [[ 5. -6.] [ 7. 8.]]
Fix the signs using another
pyttb.ktensor
:>>> K = ttb.ktensor.from_data(weights, [fm0, fm1]) >>> 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 = K.fixsigns(K2) >>> print(K) ktensor of shape 2 x 2 weights=[27.2029... 89.4427...] factor_matrices[0] = [[ 0.3162... -0.4472...] [ 0.9486... -0.8944...]] factor_matrices[1] = [[ 0.5812... -0.6...] [ 0.8137... -0.8...]]
- full()[source]
Convert a
pyttb.ktensor
to apyttb.tensor
.- Returns:
Examples
>>> weights = np.array([1., 2.]) >>> fm0 = np.array([[1., 2.], [3., 4.]]) >>> fm1 = np.array([[5., 6.], [7., 8.]]) >>> K = ttb.ktensor.from_data(weights, [fm0, fm1]) >>> print(K) ktensor of shape 2 x 2 weights=[1. 2.] factor_matrices[0] = [[1. 2.] [3. 4.]] factor_matrices[1] = [[5. 6.] [7. 8.]] >>> print(K.full()) tensor of shape 2 x 2 data[:, :] = [[29. 39.] [63. 85.]]
- innerprod(other)[source]
Efficient inner product with a
pyttb.ktensor
.- 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 ttv (tensor times vector) of other with all of the columns of self.factor_matrices.
- Parameters:
other (
pyttb.ktensor
,pyttb.sptensor
,pyttb.tensor
, orpyttb.ttensor
, required) – Tensor with which to compute the inner product.- Returns:
float
Examples
>>> K = ttb.ktensor.from_function(np.ones, (2,3,4), 2) >>> print(K.innerprod(K)) 96.0
- isequal(other)[source]
Equal comparator for
pyttb.ktensor
objects.- Parameters:
other (
pyttb.ktensor
, required) –pyttb.ktensor
with which to compare.- Returns:
bool
Examples
>>> K1 = ttb.ktensor.from_function(np.ones, (2,3,4), 2) >>> weights = np.ones((2, 1)) >>> factor_matrices = [np.ones((2, 2)), np.ones((3, 2)), np.ones((4, 2))] >>> K2 = ttb.ktensor.from_data(weights, factor_matrices) >>> print(K1.isequal(K2)) True
- issymmetric(return_diffs=False)[source]
Returns True if the
pyttb.ktensor
is exactly symmetric for every permutation.- Parameters:
return_diffs (bool, optional) – If True, returns the matrix of the norm of the differences between the factor matrices.
- Returns:
bool
numpy.ndarray
, optional – 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., 2.]) >>> fm0 = np.array([[1., 2.], [3., 4.]]) >>> fm1 = np.array([[5., 6.], [7., 8.]]) >>> K2 = ttb.ktensor.from_data(weights, [fm0, fm1]) >>> issym, diffs = K2.issymmetric(return_diffs=True) >>> print(diffs) [[0. 8.] [0. 0.]]
- mask(W)[source]
Extract
pyttb.ktensor
values as specified by W, apyttb.tensor
orpyttb.sptensor
containing only values of zeros (0) and ones (1). The values in thepyttb.ktensor
corresponding to the indices for the ones (1) in W will be returned as a column vector.- Parameters:
W (
pyttb.tensor
orpyttb.sptensor
, required)- Returns:
Examples
Create a
pyttb.ktensor
:>>> weights = np.array([1., 2.]) >>> fm0 = np.array([[1., 2.], [3., 4.]]) >>> fm1 = np.array([[5., 6.], [7., 8.]]) >>> K = ttb.ktensor.from_data(weights, [fm0, fm1])
Create a mask
pyttb.tensor
and extract the elements of thepyttb.ktensor
using the mask:>>> W = ttb.tensor.from_data(np.array([[0, 1], [1, 0]])) >>> print(K.mask(W)) [[63.] [39.]]
- mttkrp(U, n)[source]
Matricized tensor times Khatri-Rao product for
pyttb.ktensor
.Efficiently calculates the matrix product of the n-mode matricization of the ktensor with the Khatri-Rao product of all entries in U, a
list
of factor matrices, except the nth.- Parameters:
U (
list
of factor matrices, required)n (int, required) – Multiply by all modes except n.
- Returns:
Examples
>>> K = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2) >>> U = [np.ones((2, 2)), np.ones((3, 2)), np.ones(((4, 2)))] >>> print(K.mttkrp(U, 0)) [[24. 24.] [24. 24.]]
- property ncomponents
Number of components in the
pyttb.ktensor
(i.e., number of columns in each factor matrix) of thepyttb.ktensor
.- Returns:
int
Examples
>>> K = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2) >>> print(K.ncomponents) 2
- property ndims
Number of dimensions (i.e., number of factor matrices) of the
pyttb.ktensor
.- Returns:
int
Examples
>>> K = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2) >>> print(K.ndims) 3
- norm()[source]
Compute the norm (i.e., square root of the sum of squares of entries) of a
pyttb.ktensor
.- Returns:
int
Examples
>>> K = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2) >>> K.norm() 9.797958971132712
- normalize(weight_factor=None, sort=False, normtype=2, mode=None)[source]
Normalize the columns of the factor matrices of a
pyttb.ktensor
in place.- Parameters:
weight_factor ({“all”, int}, optional) – 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 (bool, optional) – Sort the columns in descending order of the weights.
normtype ({non-negative int, -1, -2, np.inf, -np.inf}, optional) – Order of the norm (see
numpy.linalg.norm()
for possible values).mode (int, optional) – Index of factor matrix to normalize. A value of None means normalize all factor matrices.
- Returns:
Examples
>>> K = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2) >>> print(K.normalize()) ktensor of shape 2 x 3 x 4 weights=[4.898... 4.898...] factor_matrices[0] = [[0.7071... 0.7071...] [0.7071... 0.7071...]] factor_matrices[1] = [[0.5773... 0.5773...] [0.5773... 0.5773...] [0.5773... 0.5773...]] factor_matrices[2] = [[0.5 0.5] [0.5 0.5] [0.5 0.5] [0.5 0.5]]
- nvecs(n, r, flipsign=True)[source]
Compute the leading mode-n vectors for a
pyttb.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 (int, required) – Mode for tensor matricization.
r (int, required) – Number of eigenvectors to compute and use.
flipsign (bool, optional) – If True, make each column’s largest element positive.
- Returns:
Examples
Compute single eigenvector for dimension 0:
>>> K = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2) >>> nvecs1 = K.nvecs(0, 1) >>> print(nvecs1) [[0.70710678...] [0.70710678...]]
Compute first 2 leading eigenvectors for dimension 0:
>>> nvecs2 = K.nvecs(0, 2) >>> print(nvecs2) [[ 0.70710678... 0.70710678...] [ 0.70710678... -0.70710678...]]
- permute(order)[source]
Permute
pyttb.ktensor
dimensions.Rearranges the dimensions of a
pyttb.ktensor
so that they are in the order specified by order. The corresponding tensor 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 (
numpy.ndarray
) – Permutation of [0,…,self.ndimensions].- Returns:
Examples
>>> weights = np.array([1., 2.]) >>> fm0 = np.array([[1., 2.], [3., 4.]]) >>> fm1 = np.array([[5., 6.], [7., 8.]]) >>> factor_matrices = [fm0, fm1] >>> K = ttb.ktensor.from_data(weights, factor_matrices) >>> print(K) ktensor of shape 2 x 2 weights=[1. 2.] factor_matrices[0] = [[1. 2.] [3. 4.]] factor_matrices[1] = [[5. 6.] [7. 8.]]
Permute the order of the dimension so they are in reverse order:
>>> K1 = K.permute(np.array([1, 0])) >>> print(K1) ktensor of shape 2 x 2 weights=[1. 2.] factor_matrices[0] = [[5. 6.] [7. 8.]] factor_matrices[1] = [[1. 2.] [3. 4.]]
- redistribute(mode)[source]
Distribute weights of a
pyttb.ktensor
to the specified mode. The redistribution is performed in place.- Parameters:
mode (int) – Must be value in [0,…self.ndims].
Example
Create a
pyttb.ktensor
:>>> weights = np.array([1., 2.]) >>> fm0 = np.array([[1., 2.], [3., 4.]]) >>> fm1 = np.array([[5., 6.], [7., 8.]]) >>> factor_matrices = [fm0, fm1] >>> K = ttb.ktensor.from_data(weights, factor_matrices) >>> print(K) ktensor of shape 2 x 2 weights=[1. 2.] factor_matrices[0] = [[1. 2.] [3. 4.]] factor_matrices[1] = [[5. 6.] [7. 8.]]
Distribute weights of that
pyttb.ktensor
to mode 0:>>> K.redistribute(0) >>> print(K) ktensor of shape 2 x 2 weights=[1. 1.] factor_matrices[0] = [[1. 4.] [3. 8.]] factor_matrices[1] = [[5. 6.] [7. 8.]]
- property shape
Shape of a
pyttb.ktensor
.Returns the lengths of all dimensions of the
pyttb.ktensor
.- Returns:
- score(other, weight_penalty=True, threshold=0.99, greedy=True)[source]
Checks if two
pyttb.ktensor
instances with the same shapes but potentially different number of components match except for permutation.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], rescpetively, then the score is defined asscore = penalty * (a1.T*b1) * (a2.T*b2) * … * (an.T*bn),
where the penalty is defined by the weights such that
penalty = 1 - abs(self.weights - other.weights) / max(self.weights, other.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.- Parameters:
other (
pyttb.ktensor
, required) –pyttb.ktensor
with which to match.weight_penalty (bool, optional) – Flag indicating whether or not to consider the weights in the calculations.
threshold (float, optional) – Threshold specified in the formula above for determining a match.
greedy (bool, optional) – Flag indicating whether or not to consider all possible matchings (exponentially expensive) or just do a greedy matching.
- Returns:
int – Score (between 0 and 1).
pyttb.ktensor
– Copy of self, which has been normalized and permuted to best match other.bool – Flag indicating a match according to a user-specified threshold.
numpy.ndarray
– Permutation (i.e. array of indices of the modes of self) of the components of self that was used to best match other.
Examples
Create two
pyttb.ktensor
instances and compute the score between them:>>> K = ttb.ktensor.from_data(np.array([2., 1., 3.]), np.ones((3,3)), np.ones((4,3)), np.ones((5,3))) >>> K2 = ttb.ktensor.from_data(np.array([2., 4.]), np.ones((3,2)), np.ones((4,2)), np.ones((5,2))) >>> score,Kperm,flag,perm = K.score(K2) >>> print(score) 0.875 >>> print(perm) [0 2 1]
Compute score without using weights:
>>> score,Kperm,flag,perm = K.score(K2,weight_penalty=False) >>> print(score) 1.0 >>> print(perm) [0 1 2]
- symmetrize()[source]
Symmetrize a
pyttb.ktensor
in all modes.Symmetrize a
pyttb.ktensor
with respect to all modes so that the resultingpyttb.ktensor
is symmetric with respect to any permutation of indices.- Returns:
Examples
Create a
pyttb.ktensor
:>>> weights = np.array([1., 2.]) >>> fm0 = np.array([[1., 2.], [3., 4.]]) >>> fm1 = np.array([[5., 6.], [7., 8.]]) >>> factor_matrices = [fm0, fm1] >>> K = ttb.ktensor.from_data(weights, factor_matrices) >>> print(K) ktensor of shape 2 x 2 weights=[1. 2.] factor_matrices[0] = [[1. 2.] [3. 4.]] factor_matrices[1] = [[5. 6.] [7. 8.]]
Make the factor matrices of the
pyttb.ktensor
symmetric with respect to any permutation of the factor matrices:>>> K1 = K.symmetrize() >>> print(K1) ktensor of shape 2 x 2 weights=[1. 1.] factor_matrices[0] = [[2.3404... 4.9519...] [4.5960... 8.0124...]] factor_matrices[1] = [[2.3404... 4.9519...] [4.5960... 8.0124...]]
- tolist(mode=None)[source]
Convert
pyttb.ktensor
to a list of factor matrices, evenly distributing the weights across factors. Optionally absorb the weights into a single mode.- Parameters:
mode (int, optional) – Index of factor matrix to absorb all of the weights.
- Returns:
Examples
Create a
pyttb.ktensor
of all ones:>>> weights = np.array([1., 2.]) >>> fm0 = np.array([[1., 2.], [3., 4.]]) >>> fm1 = np.array([[5., 6.], [7., 8.]]) >>> factor_matrices = [fm0, fm1] >>> K = ttb.ktensor.from_data(weights, factor_matrices) >>> print(K) ktensor of shape 2 x 2 weights=[1. 2.] factor_matrices[0] = [[1. 2.] [3. 4.]] factor_matrices[1] = [[5. 6.] [7. 8.]]
Spread weights equally to all factors and return list of factor matrices:
>>> fm_list = K.tolist() >>> for fm in fm_list: print(fm) [[1. 2.8284...] [3. 5.6568...]] [[ 5. 8.4852...] [ 7. 11.313...]]
Shift weight to single factor matrix and return list of factor matrices:
>>> fm_list = K.tolist(0) >>> for fm in fm_list: print(fm) [[ 8.6023... 40. ] [25.8069... 80. ]] [[0.5812... 0.6...] [0.8137... 0.8...]]
- tovec(include_weights=True)[source]
Convert
pyttb.ktensor
to column vector. Optionally include or exclude the weights.- Parameters:
include_weights (bool, optional) – Flag to specify whether or not to include weights in output.
- Returns:
numpy.ndarray
– The length of the column vector is (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.
Examples
Create a
pyttb.ktensor
from a vector:>>> rank = 2 >>> shape = np.array([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 x 3 x 4 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 anotherpyttb.ktensor
:>>> K2 = ttb.ktensor.from_vector(K.tovec(), shape, True) >>> print(K2) ktensor of shape 2 x 3 x 4 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, dims=None, exclude_dims=None)[source]
Tensor times vector for a
pyttb.ktensor
.Computes the product of a
pyttb.ktensor
with a vector (i.e., np.array). If dims is an integer, it specifies the dimension in thepyttb.ktensor
along which the vector is multiplied. If the shape of the vector is = (I,1), then the length of dimension dims of thepyttb.ktensor
must be I. Note that the number of dimensions of the returnedpyttb.ktensor
is 1 less than the dimension of thepyttb.ktensor
used in the multiplication because dimension dims is removed.If vector is a
list
of np.array instances, thepyttb.ktensor
is multiplied with each vector in the list. The products are computed sequentially along all dimensions (or modes) of thepyttb.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 thepyttb.ktensor
specified in dims.- Parameters:
vector (
numpy.ndarray
or list[numpy.ndarray
], required)dims (int,
numpy.ndarray
, optional)exclude_dims
- Returns:
float or
pyttb.ktensor
– The number of dimensions of the returnedpyttb.ktensor
is n-k, where n = self.ndims and k = number of vectors provided as input. If k == n, a scalar is returned.
Examples
Compute the product of a
pyttb.ktensor
and a single vector (results in apyttb.ktensor
):>>> rank = 2 >>> shape = np.array([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) >>> K0 = K.ttv(np.array([1, 1, 1]),dims=1) # compute along a single dimension >>> print(K0) ktensor of shape 2 x 4 weights=[36. 54.] factor_matrices[0] = [[1. 3.] [2. 4.]] factor_matrices[1] = [[11. 15.] [12. 16.] [13. 17.] [14. 18.]]
Compute the product of a
pyttb.ktensor
and a vector for each dimension (results in a float):>>> vec2 = np.array([1, 1]) >>> vec3 = np.array([1, 1, 1]) >>> vec4 = np.array([1, 1, 1, 1]) >>> K1 = K.ttv([vec2, vec3, vec4]) >>> print(K1) 30348.0
Compute the product of a
pyttb.ktensor
and multiple vectors out of order (results in apyttb.ktensor
):>>> K2 = K.ttv([vec4, vec3],np.array([2, 1])) >>> print(K2) ktensor of shape 2 weights=[1800. 3564.] factor_matrices[0] = [[1. 3.] [2. 4.]]
- update(modes, data)[source]
Updates a
pyttb.ktensor
in the specific dimensions with the values in data (in vector or matrix form). The value of modes must be a value in [-1,…,self.ndoms]. If the Further, the number of elements in data must equal self.shape[modes] * self.ncomponents. The update is performed in place.- Parameters:
modes (int or
list
of int, required) – 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].data (
numpy.ndarray
, required) – Data values to use in the update.Results
——-
:class:`pyttb.ktensor`
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 x 3 x 4 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 x 3 x 4 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 x 3 x 4 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.]]
- __add__(other)[source]
Binary addition for
pyttb.ktensor
.- Parameters:
other (
pyttb.ktensor
, required) –pyttb.ktensor
to add to self.- Returns:
- __getitem__(item)[source]
Subscripted reference for a
pyttb.ktensor
.Subscripted reference is used to query the components of a
pyttb.ktensor
.- Parameters:
item (tuple(int) or int, required)
Examples
>>> K = ttb.ktensor.from_function(np.ones, (2, 3, 4), 2) >>> K.weights array([1., 1.]) >>> K.factor_matrices [array([[1., 1.], [1., 1.]]), array([[1., 1.], [1., 1.], [1., 1.]]), array([[1., 1.], [1., 1.], [1., 1.], [1., 1.]])] >>> K.factor_matrices[0] array([[1., 1.], [1., 1.]]) >>> K[0] array([[1., 1.], [1., 1.]]) >>> K[1, 2, 0] 2.0 >>> K[0][:, [0]] array([[1.], [1.]])
- __neg__()[source]
Unary minus (negative) for
pyttb.ktensor
instances.- Returns:
- __pos__()[source]
Unary plus (positive) for
pyttb.ktensor
instances.- Returns:
- __setitem__(key, value)[source]
Subscripted assignment for
pyttb.ktensor
.Subscripted assignment cannot be used to update individual elements of a
pyttb.ktensor
. You can update the weights vector or the factor matrices of apyttb.ktensor
.Example
>>> K = ttb.ktensor.from_data(np.ones((4,1)), [np.random.random((2,4)), np.random.random((3,4)), np.random.random((4,4))]) >>> K.weights = 2 * np.ones((4,1)) >>> K.factor_matrices[0] = np.zeros((2, 4)) >>> K.factor_matrices = [np.zeros((2, 4)), np.zeros((3, 4)), np.zeros((4, 4))] >>> print(K) ktensor of shape 2 x 3 x 4 weights=[[2.] [2.] [2.] [2.]] factor_matrices[0] = [[0. 0. 0. 0.] [0. 0. 0. 0.]] factor_matrices[1] = [[0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.]] factor_matrices[2] = [[0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.]]
- __sub__(other)[source]
Binary subtraction for
pyttb.ktensor
.- Parameters:
other (
pyttb.ktensor
)- Returns:
- __mul__(other)[source]
Elementwise (including scalar) multiplication for
pyttb.ktensor
instances.- Parameters:
other (
pyttb.tensor
,pyttb.sptensor
, float, int)- Returns:
- __rmul__(other)[source]
Elementwise (including scalar) multiplication for
pyttb.ktensor
instances.- Parameters:
other (
pyttb.tensor
,pyttb.sptensor
, float, int)- Returns:
- __repr__()[source]
String representation of a
pyttb.ktensor
.- Returns:
str
- __str__()
String representation of a
pyttb.ktensor
.- Returns:
str
- __module__ = 'pyttb.ktensor'
pyttb.sptensor
Sparse Tensor Implementation
- pyttb.sptensor.tt_to_sparse_matrix(sptensorInstance: sptensor, mode: int, transpose: bool = False) coo_matrix [source]
Helper function to unwrap sptensor into sparse matrix, should replace the core need for sptenmat
- Parameters:
sptensorInstance (sparse tensor to unwrap)
mode (Mode around which to unwrap tensor)
transpose (Whether or not to tranpose unwrapped tensor)
- Returns:
spmatrix (unwrapped tensor)
- pyttb.sptensor.tt_from_sparse_matrix(spmatrix: coo_matrix, shape: Any, mode: int, idx: int) sptensor [source]
Helper function to wrap sparse matrix into sptensor. Inverse of
pyttb.tt_to_sparse_matrix
- Parameters:
spmatrix (
Scipy.sparse.coo_matrix
)mode (int) – Mode around which tensor was unwrapped
idx (int) – in {0,1}, idx of mode in spmatrix, s.b. 0 for tranpose=True
- Returns:
sptensorInstance (
pyttb.sptensor
)
- class pyttb.sptensor.sptensor[source]
Bases:
object
SPTENSOR Class for sparse tensors.
- classmethod from_data(subs: ndarray, vals: ndarray, shape: Tuple[int, ...]) sptensor [source]
Construct an sptensor from fully defined SUB, VAL and SIZE matrices. This does no validation to optimize for speed when components are known. For default initializer with error checking see
from_aggregator()
.- Parameters:
subs (location of non-zero entries)
vals (values for non-zero entries)
shape (shape of sparse tensor)
Examples
Import required modules:
>>> import pyttb as ttb >>> import numpy as np
Set up input data # Create sptensor with explicit data description
>>> subs = np.array([[1, 2], [1, 3]]) >>> vals = np.array([[6], [7]]) >>> shape = (4, 4, 4) >>> K0 = ttb.sptensor.from_data(subs,vals, shape)
- classmethod from_tensor_type(source: Union[sptensor, tensor, coo_matrix]) sptensor [source]
Contruct an
pyttb.sptensor
from compatible tensor types- Parameters:
source (Source tensor to create sptensor from)
- Returns:
Generated Sparse Tensor
- classmethod from_function(function_handle: Callable[[Tuple[int, ...]], ndarray], shape: Tuple[int, ...], nonzeros: float) sptensor [source]
Creates a sparse tensor of the specified shape with NZ nonzeros created from the specified function handle
- Parameters:
function_handle (function that accepts 2 arguments and generates) –
numpy.ndarray
of length nonzerosshape (tuple)
nonzeros (int or float)
- Returns:
Generated Sparse Tensor
- classmethod from_aggregator(subs: ndarray, vals: ndarray, shape: Optional[Tuple[int, ...]] = None, function_handle: Union[str, Callable[[Any], Union[float, ndarray]]] = 'sum') sptensor [source]
Construct an sptensor from fully defined SUB, VAL and shape matrices, after an aggregation is applied
- Parameters:
subs (location of non-zero entries)
vals (values for non-zero entries)
shape (shape of sparse tensor)
function_handle (Aggregation function, or name of supported) – aggregation function from numpy_groupies
- Returns:
Generated Sparse Tensor
Examples
>>> subs = np.array([[1, 2], [1, 3]]) >>> vals = np.array([[6], [7]]) >>> shape = np.array([4, 4]) >>> K0 = ttb.sptensor.from_aggregator(subs,vals) >>> K1 = ttb.sptensor.from_aggregator(subs,vals,shape) >>> function_handle = sum >>> K2 = ttb.sptensor.from_aggregator(subs,vals,shape,function_handle)
- allsubs() ndarray [source]
Generate all possible subscripts for sparse tensor
- Returns:
s (All possible subscripts for sptensor)
- collapse(dims: ~typing.Optional[~numpy.ndarray] = None, fun: ~typing.Callable[[~numpy.ndarray], ~typing.Union[float, ~numpy.ndarray]] = <function sum>) Union[float, ndarray, sptensor] [source]
Collapse sparse tensor along specified dimensions.
- Parameters:
dims (Dimensions to collapse)
fun (Method used to collapse dimensions)
- Returns:
Collapsed value
Example
>>> subs = np.array([[1, 2], [1, 3]]) >>> vals = np.array([[1], [1]]) >>> shape = np.array([4, 4]) >>> X = ttb.sptensor.from_data(subs, vals, shape) >>> X.collapse() 2 >>> X.collapse(np.arange(X.ndims), sum) 2
- contract(i: int, j: int) Union[ndarray, sptensor, tensor] [source]
Contract tensor along two dimensions (array trace).
- Parameters:
i (First dimension)
j (Second dimension)
- Returns:
Contracted sptensor, converted to tensor if sufficiently dense
Example
>>> X = ttb.tensor.from_data(np.ones((2,2))) >>> Y = sptensor.from_tensor_type(X) >>> Y.contract(0, 1) 2.0
- elemfun(function_handle: Callable[[ndarray], ndarray]) sptensor [source]
Manipulate the non-zero elements of a sparse tensor
- Parameters:
function_handle (Function that updates all values.)
- Returns:
Updated sptensor
Example
>>> X = ttb.tensor.from_data(np.ones((2,2))) >>> Y = sptensor.from_tensor_type(X) >>> Z = Y.elemfun(lambda values: values*2) >>> Z.isequal(Y*2) True
- end(k: Optional[int] = None) int [source]
Last index of indexing expression for sparse tensor
- Parameters:
k (int Dimension for subscript indexing)
- extract(searchsubs: ndarray) ndarray [source]
Extract value for a sptensor.
- Parameters:
searchsubs (subscripts to find in sptensor)
See also
- find() Tuple[ndarray, ndarray] [source]
FIND Find subscripts of nonzero elements in a sparse tensor.
- Returns:
subs (Subscripts of nonzero elements)
vals (Values at corresponding subscripts)
- innerprod(other: Union[sptensor, tensor, ktensor, ttensor]) float [source]
Efficient inner product with a sparse tensor
- Parameters:
other (Other tensor to take innerproduct with)
- isequal(other: Union[sptensor, tensor]) bool [source]
Exact equality for sptensors
- Parameters:
other (Other tensor to compare against)
- logical_and(B: Union[float, sptensor, tensor]) sptensor [source]
Logical and with self and another object
- Parameters:
B (Other value to compare with)
- Returns:
Indicator tensor
- logical_not() sptensor [source]
Logical NOT for sptensors
- Returns:
Sparse tensor with all zero-values marked from original
sparse tensor
- logical_or(B: Union[float, tensor]) tensor [source]
- logical_or(B: sptensor) sptensor
Logical OR for sptensor and another value
- Returns:
Indicator tensor
- logical_xor(other: Union[float, tensor]) tensor [source]
- logical_xor(other: sptensor) sptensor
Logical XOR for sptensors
- Parameters:
other (Other value to xor against)
- Returns:
Indicator tensor
- mask(W: sptensor) ndarray [source]
Extract values as specified by a mask tensor
- Parameters:
W (Mask tensor)
- Returns:
Extracted values
- mttkrp(U: Union[ktensor, List[ndarray]], n: int) ndarray [source]
Matricized tensor times Khatri-Rao product for sparse tensor.
- Parameters:
U (Matrices to create the Khatri-Rao product)
n (Mode to matricize sptensor in)
- Returns:
Matrix product
Examples
>>> matrix = np.ones((4, 4)) >>> 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) >>> sptensorInstance = sptensor.from_data(subs, vals, shape) >>> sptensorInstance.mttkrp(np.array([matrix, matrix, matrix]), 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]])
- nvecs(n: int, r: int, flipsign: bool = True) ndarray [source]
Compute the leading mode-n vectors for a sparse tensor.
- Parameters:
n (Mode to unfold)
r (Number of eigenvectors to compute)
flipsign (Make each eigenvector’s largest element positive)
- permute(order: ndarray) sptensor [source]
Rearrange the dimensions of a sparse tensor
- Parameters:
order (Updated order of dimensions)
- reshape(new_shape: Tuple[int, ...], old_modes: Optional[Union[ndarray, int]] = None) sptensor [source]
Reshape specified modes of sparse tensor
- Parameters:
new_shape (tuple)
old_modes (
Numpy.ndarray
)
- Returns:
- scale(factor: ndarray, dims: Union[float, ndarray]) sptensor [source]
Scale along specified dimensions for sparse tensors
- Parameters:
factor (
numpy.ndarray
)dims (int or
numpy.ndarray
)
- Returns:
- spmatrix() coo_matrix [source]
Converts a two-way sparse tensor to a sparse matrix in scipy.sparse.coo_matrix format
- squeeze() Union[sptensor, float] [source]
Remove singleton dimensions from a sparse tensor
- Returns:
pyttb.sptensor
or float if sptensor is only singleton dimensions
- subdims(region: Sequence[Union[int, np.ndarray, slice]]) np.ndarray [source]
SUBDIMS Compute the locations of subscripts within a subdimension.
- Parameters:
region (
numpy.ndarray
or tuple denoting indexing) – Subset of total sptensor shape in which to find non-zero values- Returns:
numpy.ndarray
– Index into subs for non-zero values in region
Examples
>>> 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) >>> sp = sptensor.from_data(subs,vals,shape) >>> region = [np.array([1]), np.array([1]), np.array([1,3])] >>> loc = sp.subdims(region) >>> print(loc) [0 1] >>> region = (1, 1, slice(None, None, None)) >>> loc = sp.subdims(region) >>> print(loc) [0 1]
- ttv(vector: Union[ndarray, List[ndarray]], dims: Optional[Union[ndarray, int]] = None, exclude_dims: Optional[Union[ndarray, int]] = None) Union[sptensor, tensor] [source]
Sparse tensor times vector
- Parameters:
vector (Vector(s) to multiply against)
dims (Dimensions to multiply with vector(s))
exclude_dims (Use all dimensions but these)
- __getitem__(item)[source]
Subscripted reference for a sparse tensor.
We can extract elements or subtensors from a sparse tensor in the following ways.
Case 1a: y = X(i1,i2,…,iN), where each in is an index, returns a scalar.
Case 1b: Y = X(R1,R2,…,RN), where one or more Rn is a range and the rest are indices, returns a sparse tensor. The elements are renumbered here as appropriate.
Case 2a: V = X(S) or V = X(S,’extract’), where S is a p x n array of subscripts, returns a vector of p values.
Case 2b: V = X(I) or V = X(I,’extract’), 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 particularily an issue if ndims(X)==1.
- Parameters:
item (tuple(int),tuple(slice),:class:numpy.ndarray)
- Returns:
Examples
>>> subs = np.array([[3,3,3],[1,1,0],[1,2,1]]) >>> vals = np.array([3,5,1]) >>> shape = (4,4,4) >>> X = sptensor.from_data(subs,vals,shape) >>> _ = X[0,1,0] #<-- returns zero >>> _ = X[3,3,3] #<-- returns 3 >>> _ = X[2:3,:,:] #<-- returns 1 x 4 x 4 sptensor
- __setitem__(key, value)[source]
Subscripted assignment for sparse tensor.
We can assign elements to a sptensor in three ways.
Case 1: X(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 sptensor.
Case 2: X(S) = V, where S is a p x n array of subscripts and V is a scalar value or a vector containing p values.
Linear indexing is not supported for sparse tensors.
Examples
X = sptensor([30 40 20]) <– Create an emtpy 30 x 40 x 20 sptensor X(30,40,20) = 7 <– Assign a single element to be 7 X([1,1,1;2,2,2]) = 1 <– Assign a list of elements to the same value X(11:20,11:20,11:20) = sptenrand([10,10,10],10) <– subtensor! X(31,41,21) = 7 <– grows the size of the tensor X(111:120,111:120,111:120) = sptenrand([10,10,10],10) <– grows X(1,1,1,1) = 4 <– increases the number of dimensions from 3 to 4
X = sptensor([30]) <– empty one-dimensional tensor X([4:6]) = 1 <– set subtensor to ones (does not increase dimension) X([10;12;14]) = (4:6)’ <– set three elements X(31) = 7 <– grow the first dimension X(1,1) = 0 <– add a dimension, but no nonzeros
Note regarding singleton dimensions: It is not possible to do, for instance, X(1,1:10,1:10) = sptenrand([1 10 10],5). However, it is okay to do X(1,1:10,1:10) = squeeze(sptenrand([1 10 10],5)).
- Parameters:
key (tuple(int),tuple(slice),:class:numpy.ndarray)
value (int,float,
numpy.ndarray
,pyttb.sptensor
)
- __eq__(other)[source]
Equal comparator for sptensors
- Parameters:
other (compare equality of sptensor to other)
- Returns:
- __ne__(other)[source]
Not equal comparator (~=) for sptensors
- Parameters:
other (compare equality of sptensor to other)
- Returns:
- __sub__(other)[source]
MINUS Binary subtraction for sparse tensors.
- Parameters:
other (
pyttb.tensor
,pyttb.sptensor
)- Returns:
- __add__(other)[source]
MINUS Binary addition for sparse tensors.
- Parameters:
other (
pyttb.tensor
,pyttb.sptensor
)- Returns:
- __pos__()[source]
Unary plus (+) for sptensors
- Returns:
pyttb.sptensor
, copy of tensor
- __neg__()[source]
Unary minus (-) for sptensors
- Returns:
pyttb.sptensor
, copy of tensor
- __mul__(other)[source]
Element wise multiplication (*) for sptensors
- Parameters:
other (
pyttb.sptensor
,pyttb.tensor
, float, int)- Returns:
- __rmul__(other)[source]
Element wise right multiplication (*) for sptensors
- Parameters:
other (float, int)
- Returns:
- __le__(other)[source]
Less than or equal (<=) for sptensor
- Parameters:
other (
pyttb.sptensor
,pyttb.tensor
, float, int)- Returns:
- __lt__(other)[source]
Less than (<) for sptensor
- Parameters:
other (
pyttb.sptensor
,pyttb.tensor
, float, int)- Returns:
- __ge__(other)[source]
Greater than or equal (>=) to for sptensor
- Parameters:
other (
pyttb.sptensor
,pyttb.tensor
, float, int)- Returns:
- __gt__(other)[source]
Greater than (>) to for sptensor
- Parameters:
other (
pyttb.sptensor
,pyttb.tensor
, float, int)- Returns:
- __repr__()[source]
String representation of a sparse tensor.
- Returns:
str – Contains the shape, subs and vals as strings on different lines.
- __hash__ = None
- __module__ = 'pyttb.sptensor'
- __str__()
String representation of a sparse tensor.
- Returns:
str – Contains the shape, subs and vals as strings on different lines.
- ttm(matrices: Union[ndarray, List[ndarray]], dims: Optional[Union[float, ndarray]] = None, exclude_dims: Optional[Union[float, ndarray]] = None, transpose: bool = False)[source]
Sparse tensor times matrix.
- 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)
- pyttb.sptensor.sptenrand(shape: Tuple[int, ...], density: Optional[float] = None, nonzeros: Optional[float] = None) sptensor [source]
Create sptensor with entries drawn from a uniform distribution on the unit interval
- Parameters:
shape (Shape of resulting tensor)
density (Density of resulting sparse tensor)
nonzeros (Number of nonzero entries in resulting sparse tensor)
- Returns:
Constructed tensor
Example
>>> X = ttb.sptenrand((2,2), nonzeros=1) >>> Y = ttb.sptenrand((2,2), density=0.25)
- pyttb.sptensor.sptendiag(elements: ndarray, shape: Optional[Tuple[int, ...]] = None) sptensor [source]
Creates a sparse tensor with elements along super diagonal If provided shape is too small the tensor will be enlarged to accomodate
- Parameters:
elements (Elements to set along the diagonal)
shape (Shape of resulting tensor)
- Returns:
Constructed tensor
Example
>>> shape = (2,) >>> values = np.ones(shape) >>> X = ttb.sptendiag(values) >>> Y = ttb.sptendiag(values, (2, 2)) >>> X.isequal(Y) True
pyttb.tensor
Dense Tensor Implementation
- class pyttb.tensor.tensor[source]
Bases:
object
TENSOR Class for dense tensors.
- classmethod from_data(data: ndarray, shape: Optional[Tuple[int, ...]] = None) tensor [source]
Creates a tensor from explicit description. Note that 1D tensors (i.e., when len(shape)==1) contains a data array that follow the Numpy convention of being a row vector, which is different than in the Matlab Tensor Toolbox.
- Parameters:
data (Tensor source data)
shape (Shape of resulting tensor if not the same as data shape)
- Returns:
Constructed tensor
Example
>>> X = ttb.tensor.from_data(np.ones((2,2))) >>> Y = ttb.tensor.from_data(np.ones((2,2)), shape=(4,1))
- classmethod from_tensor_type(source: Union[sptensor, tensor, ktensor, tenmat]) tensor [source]
Converts other tensor types into a dense tensor
- Parameters:
source (Tensor type to create dense tensor from)
- Returns:
Constructed tensor
Example
>>> X = ttb.tensor.from_data(np.ones((2,2))) >>> Y = ttb.tensor.from_tensor_type(X)
- classmethod from_function(function_handle: Callable[[Tuple[int, ...]], ndarray], shape: Tuple[int, ...]) tensor [source]
Creates a tensor from a function handle and size
- Parameters:
function_handle (Function to generate data to construct tensor)
shape (Shape of resulting tensor)
- Returns:
Constructed tensor
Example
>>> X = ttb.tensor.from_function(lambda a_shape: np.ones(a_shape), (2,2))
- collapse(dims: ~typing.Optional[~numpy.ndarray] = None, fun: ~typing.Callable[[~numpy.ndarray], ~typing.Union[float, ~numpy.ndarray]] = <function sum>) Union[float, ndarray, tensor] [source]
Collapse tensor along specified dimensions.
- Parameters:
dims (Dimensions to collapse)
fun (Method used to collapse dimensions)
- Returns:
Collapsed value
Example
>>> X = ttb.tensor.from_data(np.ones((2,2))) >>> X.collapse() 4.0 >>> X.collapse(np.arange(X.ndims), sum) 4.0
- contract(i: int, j: int) Union[ndarray, tensor] [source]
Contract tensor along two dimensions (array trace).
- Parameters:
i (First dimension)
j (Second dimension)
- Returns:
Contracted tensor
Example
>>> X = ttb.tensor.from_data(np.ones((2,2))) >>> X.contract(0, 1) 2.0
- double() ndarray [source]
Convert tensor to an array of doubles
- Returns:
Copy of tensor data
Example
>>> X = ttb.tensor.from_data(np.ones((2,2))) >>> X.double() array([[1., 1.], [1., 1.]])
- exp() tensor [source]
Exponential of the elements of tensor
- Returns:
Copy of tensor data element-wise raised to exponential
Examples
>>> tensor1 = ttb.tensor.from_data(np.array([[1, 2], [3, 4]])) >>> tensor1.exp().data array([[ 2.7182..., 7.3890... ], [20.0855..., 54.5981...]])
- end(k: Optional[int] = None) int [source]
Last index of indexing expression for tensor
- Parameters:
k (dimension for subscripted indexing)
Examples
>>> X = ttb.tensor.from_data(np.ones((2,2))) >>> X.end() # linear indexing 3 >>> X.end(0) 1
- find() Tuple[ndarray, ndarray] [source]
FIND Find subscripts of nonzero elements in a tensor.
S, V = FIND(X) returns the subscripts of the nonzero values in X and a column vector of the values.
Examples
>>> X = ttb.tensor.from_data(np.zeros((3,4,2))) >>> larger_entries = X > 0.5 >>> subs, vals = larger_entries.find()
See also
TENSOR
,TENSOR
- Returns:
Subscripts and values for non-zero entries
- innerprod(other: Union[tensor, sptensor, ktensor]) float [source]
Efficient inner product with a tensor
- Parameters:
other (Tensor type to take an innerproduct with)
Examples
>>> tensor1 = ttb.tensor.from_data(np.array([[1, 2], [3, 4]])) >>> tensor1.innerprod(tensor1) 30
- isequal(other: Union[tensor, sptensor]) bool [source]
Exact equality for tensors
- Parameters:
other (Tensor to compare against)
Examples
>>> X = ttb.tensor.from_data(np.ones((2,2))) >>> Y = ttb.tensor.from_data(np.zeros((2,2))) >>> X.isequal(Y) False
- issymmetric(grps: Optional[ndarray] = None, version: Optional[Any] = None, return_details: bool = False) Union[bool, Tuple[bool, ndarray, ndarray]] [source]
Determine if a dense tensor is symmetric in specified modes.
- Parameters:
grps (Modes to check for symmetry)
version (Flag) – 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
>>> X = ttb.tensor.from_data(np.ones((2,2))) >>> X.issymmetric() True >>> X.issymmetric(grps=np.arange(X.ndims)) True >>> is_sym, diffs, perms = X.issymmetric(grps=np.arange(X.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(B: Union[float, tensor]) tensor [source]
Logical and for tensors
- Parameters:
B (Value to and against self)
Examples
>>> X = ttb.tensor.from_data(np.ones((2,2), dtype=bool)) >>> X.logical_and(X).collapse() # All true 4
- logical_not() tensor [source]
Logical Not For Tensors
- Returns:
Negated tensor
Examples
>>> X = ttb.tensor.from_data(np.ones((2,2), dtype=bool)) >>> X.logical_not().collapse() # All false 0
- logical_or(other: Union[float, tensor]) tensor [source]
Logical or for tensors
- Parameters:
other (Value to perform or against)
Examples
>>> X = ttb.tensor.from_data(np.ones((2,2), dtype=bool)) >>> X.logical_or(X.logical_not()).collapse() # All true 4
- logical_xor(other: Union[float, tensor]) tensor [source]
Logical xor for tensors
- Parameters:
other (Value to perform xor against)
Examples
>>> X = ttb.tensor.from_data(np.ones((2,2), dtype=bool)) >>> X.logical_xor(X.logical_not()).collapse() # All true 4
- mask(W: tensor) ndarray [source]
Extract non-zero values at locations specified by mask tensor
- Parameters:
W (Mask tensor)
- Returns:
Extracted values
Examples
>>> W = ttb.tensor.from_data(np.ones((2,2))) >>> tensor1 = ttb.tensor.from_data(np.array([[1, 2], [3, 4]])) >>> tensor1.mask(W) array([1, 3, 2, 4])
- mttkrp(U: Union[ktensor, List[ndarray]], n: int) ndarray [source]
Matricized tensor times Khatri-Rao product
- Parameters:
U (Matrices to create the Khatri-Rao product)
n (Mode to matricize tensor in)
- Returns:
Matrix product
Example
>>> tensor1 = ttb.tensor.from_data(np.ones((2,2,2))) >>> matrices = [np.ones((2,2))] * 3 >>> tensor1.mttkrp(matrices, 2) array([[4., 4.], [4., 4.]])
- property ndims: int
Return the number of dimensions of a tensor
Examples
>>> X = ttb.tensor.from_data(np.ones((2,2))) >>> X.ndims 2
- property nnz: int
Number of non-zero elements in tensor
Examples
>>> X = ttb.tensor.from_data(np.ones((2,2))) >>> X.nnz 4
- norm() floating [source]
Frobenius Norm of Tensor
Examples
>>> X = ttb.tensor.from_data(np.ones((2,2))) >>> X.norm() 2.0
- nvecs(n: int, r: int, flipsign: bool = True) ndarray [source]
Compute the leading mode-n eigenvectors for a tensor
- Parameters:
n (Mode to unfold)
r (Number of eigenvectors to compute)
flipsign (Make each eigenvector’s largest element positive)
Examples
>>> tensor1 = ttb.tensor.from_data(np.array([[1, 2], [3, 4]])) >>> tensor1.nvecs(0,1) array([[0.4045...], [0.9145...]]) >>> tensor1.nvecs(0,2) array([[ 0.4045..., 0.9145...], [ 0.9145..., -0.4045...]])
- permute(order: ndarray) tensor [source]
Permute tensor dimensions.
- Parameters:
order (New order of tensor dimensions)
- Returns:
Updated tensor with shapeNew == shapePrevious[order]
Examples
>>> X = ttb.tensor.from_data(np.ones((2,2))) >>> Y = X.permute(np.array((1,0))) >>> X.isequal(Y) True
- reshape(shape: Tuple[int, ...]) tensor [source]
Reshapes a tensor
- Parameters:
shape (New shape)
Examples
>>> X = ttb.tensor.from_data(np.ones((2,2))) >>> Y = X.reshape((4,1)) >>> Y.shape (4, 1)
- squeeze() Union[tensor, ndarray, float] [source]
Removes singleton dimensions from a tensor
- Returns:
Tensor or scalar if all dims squeezed
Examples
>>> tensor1 = ttb.tensor.from_data(np.array([[[4]]])) >>> tensor1.squeeze() 4 >>> tensor2 = ttb.tensor.from_data(np.array([[1, 2, 3]])) >>> tensor2.squeeze().data array([1, 2, 3])
- symmetrize(grps: Optional[ndarray] = None, version: Optional[Any] = None) tensor [source]
Symmetrize a tensor in the specified modes .. rubric:: Notes
It is the same or less work to just call X = symmetrize(X) then to first check if X is symmetric and then symmetrize it, even if X is already symmetric.
- Parameters:
grps (Modes to check for symmetry)
version (Any non-None value will call the non-default old version)
- ttm(matrix: Union[ndarray, List[ndarray]], dims: Optional[Union[float, ndarray]] = None, exclude_dims: Optional[Union[ndarray, int]] = None, transpose: bool = False) tensor [source]
Tensor times matrix
- 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)
- ttt(other: tensor, selfdims: Optional[Union[ndarray, int]] = None, otherdims: Optional[Union[ndarray, int]] = None) tensor [source]
Tensor multiplication (tensor times tensor)
- Parameters:
other (Tensor to multiply by)
selfdims (Dimensions to contract this tensor by for multiplication)
otherdims (Dimensions to contract other tensor by for multiplication)
- ttv(vector: Union[ndarray, List[ndarray]], dims: Optional[Union[ndarray, int]] = None, exclude_dims: Optional[Union[ndarray, int]] = None) tensor [source]
Tensor times vector
- Parameters:
vector (Vector(s) to multiply against)
dims (Dimensions to multiply with vector(s))
exclude_dims (Use all dimensions but these)
- ttsv(vector: Union[ndarray, List[ndarray]], skip_dim: Optional[int] = None, version: Optional[int] = None) Union[ndarray, tensor] [source]
Tensor times same vector in multiple modes
- Parameters:
vector (Vector(s) to multiply against)
skip_dim (Multiply tensor by vector in all dims except [0, skip_dim])
- __setitem__(key, value)[source]
SUBSASGN Subscripted assignment for a tensor.
We can assign elements to a tensor in three ways.
Case 1: X(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 an MDA.
Case 2a: X(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: X(I) = V, where I is a set of p linear indices and V is a scalar or a vector containing p values. Resize is not allowed in this case.
Examples X = tensor(rand(3,4,2)) X(1:2,1:2,1) = ones(2,2) <– replaces subtensor X([1 1 1;1 1 2]) = [5;7] <– replaces two elements X([1;13]) = [5;7] <– does the same thing X(1,1,2:3) = 1 <– grows tensor X(1,1,4) = 1 %<- grows the size of the tensor
- __getitem__(item)[source]
SUBSREF Subscripted reference for tensors.
We can extract elements or subtensors from a tensor in the following ways.
Case 1a: y = X(i1,i2,…,iN), where each in is an index, returns a scalar.
Case 1b: Y = X(R1,R2,…,RN), where one or more Rn is a range and the rest are indices, returns a sparse tensor.
Case 2a: V = X(S) or V = X(S,’extract’), where S is a p x n array of subscripts, returns a vector of p values.
Case 2b: V = X(I) or V = X(I,’extract’), 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 ndims(X)==1.
Examples X = tensor(rand(3,4,2,1),[3 4 2 1]); X.data <– returns multidimensional array X.size <– returns size X(1,1,1,1) <– produces a scalar X(1,1,1,:) <– produces a tensor of order 1 and size 1 X(:,1,1,:) <– produces a tensor of size 3 x 1 X(1:2,[2 4],1,:) <– produces a tensor of size 2 x 2 x 1 X(1:2,[2 4],1,1) <– produces a tensor of size 2 x 2 X([1,1,1,1;3,4,2,1]) <– returns a vector of length 2 X = tensor(rand(10,1),10); X([1:6]’) <– extracts a subtensor X([1:6]’,’extract’) <– extracts a vector of 6 elements
- Returns:
- __eq__(other)[source]
Equal for tensors
- Parameters:
other (
pyttb.tensor
, float, int)- Returns:
- __ne__(other)[source]
Not equal (!=) for tensors
- Parameters:
other (
pyttb.tensor
, float, int)- Returns:
- __ge__(other)[source]
Greater than or equal (>=) for tensors
- Parameters:
other (
pyttb.tensor
, float, int)- Returns:
- __le__(other)[source]
Less than or equal (<=) for tensors
- Parameters:
other (
pyttb.tensor
, float, int)- Returns:
- __gt__(other)[source]
Greater than (>) for tensors
- Parameters:
other (
pyttb.tensor
, float, int)- Returns:
- __lt__(other)[source]
Less than (<) for tensors
- Parameters:
other (
pyttb.tensor
, float, int)- Returns:
- __sub__(other)[source]
Binary subtraction (-) for tensors
- Parameters:
other (
pyttb.tensor
, float, int)- Returns:
- __add__(other)[source]
Binary addition (+) for tensors
- Parameters:
other (
pyttb.tensor
, float, int)- Returns:
- __radd__(other)[source]
Right binary addition (+) for tensors
- Parameters:
other (
pyttb.tensor
, float, int)- Returns:
- __pow__(power)[source]
Element Wise Power (**) for tensors
- Parameters:
other (
pyttb.tensor
, float, int)- Returns:
- __mul__(other)[source]
Element wise multiplication (*) for tensors, self*other
- Parameters:
other (
pyttb.tensor
, float, int)- Returns:
- __rmul__(other)[source]
Element wise right multiplication (*) for tensors, other*self
- Parameters:
other (
pyttb.tensor
, float, int)- Returns:
- __truediv__(other)[source]
Element wise left division (/) for tensors, self/other
- Parameters:
other (
pyttb.tensor
, float, int)- Returns:
- __rtruediv__(other)[source]
Element wise right division (/) for tensors, other/self
- Parameters:
other (
pyttb.tensor
, float, int)- Returns:
- __pos__()[source]
Unary plus (+) for tensors
- Returns:
pyttb.tensor
– copy of tensor
- __neg__()[source]
Unary minus (-) for tensors
- Returns:
pyttb.tensor
– copy of tensor
- __repr__()[source]
String representation of a tensor.
- Returns:
str – Contains the shape and data as strings on different lines.
- __str__()
String representation of a tensor.
- Returns:
str – Contains the shape and data as strings on different lines.
- __annotations__ = {'data': 'np.ndarray', 'shape': 'Tuple'}
- __hash__ = None
- __module__ = 'pyttb.tensor'
- pyttb.tensor.tenones(shape: Tuple[int, ...]) tensor [source]
Creates a tensor of all ones
- Parameters:
shape (Shape of resulting tensor)
- Returns:
Constructed tensor
Example
>>> X = ttb.tenones((2,2))
- pyttb.tensor.tenzeros(shape: Tuple[int, ...]) tensor [source]
Creates a tensor of all zeros
- Parameters:
shape (Shape of resulting tensor)
- Returns:
Constructed tensor
Example
>>> X = ttb.tenzeros((2,2))
- pyttb.tensor.tenrand(shape: Tuple[int, ...]) tensor [source]
Creates a tensor with entries drawn from a uniform distribution on the unit interval
- Parameters:
shape (Shape of resulting tensor)
- Returns:
Constructed tensor
Example
>>> X = ttb.tenrand((2,2))
- pyttb.tensor.tendiag(elements: ndarray, shape: Optional[Tuple[int, ...]] = None) tensor [source]
Creates a tensor with elements along super diagonal If provided shape is too small the tensor will be enlarged to accomodate
- Parameters:
elements (Elements to set along the diagonal)
shape (Shape of resulting tensor)
- Returns:
Constructed tensor
Example
>>> shape = (2,) >>> values = np.ones(shape) >>> X = ttb.tendiag(values) >>> Y = ttb.tendiag(values, (2, 2)) >>> X.isequal(Y) True
pyttb.ttensor
- class pyttb.ttensor.ttensor[source]
Bases:
object
TTENSOR Class for Tucker tensors (decomposed).
- classmethod from_data(core, factors)[source]
Construct an ttensor from fully defined core tensor and factor matrices.
- Parameters:
core (:class: ttb.tensor)
factors (
list(numpy.ndarray)
)
- Returns:
Examples
Import required modules:
>>> import pyttb as ttb >>> import numpy as np
Set up input data # Create ttensor with explicit data description
>>> core_values = np.ones((2,2,2)) >>> core = ttb.tensor.from_data(core_values) >>> factors = [np.ones((1,2))] * len(core_values.shape) >>> K0 = ttb.ttensor.from_data(core, factors)
- classmethod from_tensor_type(source)[source]
Converts other tensor types into a ttensor
- Parameters:
source (
pyttb.ttensor
)- Returns:
- property shape
Shape of the tensor this deconstruction represents.
- Returns:
tuple(int)
- __repr__()[source]
String representation of a tucker tensor.
- Returns:
str – Contains the core, and factor matrices as strings on different lines.
- __str__()
String representation of a tucker tensor.
- Returns:
str – Contains the core, and factor matrices as strings on different lines.
- double()[source]
Convert ttensor to an array of doubles
- Returns:
numpy.ndarray
– copy of tensor data
- property ndims
Number of dimensions of a ttensor.
- Returns:
int – Number of dimensions of ttensor
- isequal(other)[source]
Component equality for ttensors
- Parameters:
other (
pyttb.ttensor
)- Returns:
bool (True if ttensors decompositions are identical, false otherwise)
- __pos__()[source]
Unary plus (+) for ttensors. Does nothing.
- Returns:
pyttb.ttensor
, copy of tensor
- __neg__()[source]
Unary minus (-) for ttensors
- Returns:
pyttb.ttensor
, copy of tensor
- innerprod(other)[source]
Efficient inner product with a ttensor
- Parameters:
other (
pyttb.tensor
,pyttb.sptensor
,pyttb.ktensor
,):class:`pyttb.ttensor`
- Returns:
float
- __mul__(other)[source]
Element wise multiplication (*) for ttensors (only scalars supported)
- Parameters:
other (float, int)
- Returns:
- __rmul__(other)[source]
Element wise right multiplication (*) for ttensors (only scalars supported)
- Parameters:
other (float, int)
- Returns:
- ttv(vector, dims=None, exclude_dims=None)[source]
TTensor times vector
- Parameters:
vector (
Numpy.ndarray
, list[Numpy.ndarray
])dims (
Numpy.ndarray
, int)
- mttkrp(U, n)[source]
Matricized tensor times Khatri-Rao product for ttensors.
- Parameters:
U (array of matrices or ktensor)
n (multiplies by all modes except n)
- Returns:
- ttm(matrix, dims=None, exclude_dims=None, transpose=False)[source]
Tensor times matrix for ttensor
- Parameters:
matrix (
Numpy.ndarray
, list[Numpy.ndarray
])dims (
Numpy.ndarray
, int)transpose (bool)
- reconstruct(samples=None, modes=None)[source]
Reconstruct or partially reconstruct tensor from ttensor.
- Parameters:
samples (
Numpy.ndarray
, list[Numpy.ndarray
])modes (
Numpy.ndarray
, list[Numpy.ndarray
])
- Returns:
- nvecs(n, r, flipsign=True)[source]
Compute the leading mode-n vectors for a ttensor.
- Parameters:
n (mode for tensor matricization)
r (number of eigenvalues)
flipsign (Make each column’s largest element positive if true)
- Returns:
- __module__ = 'pyttb.ttensor'
pyttb.tenmat
- class pyttb.tenmat.tenmat[source]
Bases:
object
TENMAT Store tensor as a matrix.
- double()[source]
Convert tenmat to an array of doubles
- Returns:
numpy.ndarray
– copy of tenmat data
- end(k)[source]
Last index of indexing expression for tenmat
- Parameters:
k (int) – dimension for subscripted indexing
- Returns:
int (index)
- property ndims
Return the number of dimensions of a tenmat
- Returns:
int
- property shape
Return the shape of a tenmat
- Returns:
tuple
- __getitem__(item)[source]
SUBSREF Subscripted reference for tenmat.
- Parameters:
item
- Returns:
numpy.ndarray
, float, int
- __mul__(other)[source]
Multiplies two tenmat objects.
- Parameters:
other (
pyttb.tenmat
)- Returns:
- __rmul__(other)[source]
Multiplies two tenmat objects.
- Parameters:
other (
pyttb.tenmat
)- Returns:
- __radd__(other)[source]
Reverse binary addition (+) for tenmats
- Parameters:
other (
pyttb.tenmat
, float, int)- Returns:
- __rsub__(other)[source]
Reverse binary subtraction (-) for tenmats
- Parameters:
other (
pyttb.tenmat
, float, int)- Returns:
- __pos__()[source]
Unary plus (+) for tenmats
- Returns:
pyttb.tenmat
– copy of tenmat
- __neg__()[source]
Unary minus (-) for tenmats
- Returns:
pyttb.tenmat
– copy of tenmat
- __repr__()[source]
String representation of a tenmat.
- Returns:
str – Contains the shape, row indices (rindices), column indices (cindices) and data as strings on different lines.
- __str__()
String representation of a tenmat.
- Returns:
str – Contains the shape, row indices (rindices), column indices (cindices) and data as strings on different lines.
- __module__ = 'pyttb.tenmat'
Algorithms
pyttb.cp_als
- pyttb.cp_als.cp_als(input_tensor, rank, stoptol=0.0001, maxiters=1000, dimorder=None, init='random', printitn=1, fixsigns=True)[source]
Compute CP decomposition with alternating least squares
- Parameters:
input_tensor (
pyttb.tensor
orpyttb.sptensor
orpyttb.ktensor
)rank (int) – Rank of the decomposition
stoptol (float) – Tolerance used for termination - when the change in the fitness function in successive iterations drops below this value, the iterations terminate (default: 1e-4)
dimorder (list) – Order to loop through dimensions (default: [range(tensor.ndims)])
maxiters (int) – Maximum number of iterations (default: 1000)
init (str or
pyttb.ktensor
) –Initial guess (default: “random”)
“random”: initialize using a
pyttb.ktensor
with values chosen from a Normal distribution with mean 0 and standard deviation 1“nvecs”: initialize factor matrices of a
pyttb.ktensor
using the eigenvectors of the outer product of the matricized input tensorpyttb.ktensor
: initialize using a specificpyttb.ktensor
as input - must be the same shape as the input tensor and have the same rank as the input rank
printitn (int) – Number of iterations to perform before printing iteration status - 0 for no status printing (default: 1)
fixsigns (bool) – Align the signs of the columns of the factorization to align with the input tensor data (default: True)
- Returns:
M (
pyttb.ktensor
) – Resulting ktensor from CP-ALS factorizationMinit (
pyttb.ktensor
) – Initial guessoutput (dict) –
Information about the computation. Dictionary keys:
params : tuple of (stoptol, maxiters, printitn, dimorder)
iters: number of iterations performed
normresidual: norm of the difference between the input tensor and ktensor factorization
fit: value of the fitness function (fraction of tensor data explained by the model)
Example
Random initialization causes slight pertubation in intermediate results. … is our place holder for these numeric values. Example using default values (“random” initialization):
>>> weights = np.array([1., 2.]) >>> fm0 = np.array([[1., 2.], [3., 4.]]) >>> fm1 = np.array([[5., 6.], [7., 8.]]) >>> K = ttb.ktensor.from_data(weights, [fm0, fm1]) >>> np.random.seed(1) >>> M, Minit, output = ttb.cp_als(K.full(), 2) CP_ALS: Iter 0: f = ... f-delta = ... Iter 1: f = ... f-delta = ... Final f = ... >>> print(M) ktensor of shape 2 x 2 weights=[108.4715... 8.6114...] factor_matrices[0] = [[0.4187... 0.3989...] [0.9080... 0.9169...]] factor_matrices[1] = [[0.6188... 0.2581...] [0.7854... 0.9661...]] >>> print(Minit) ktensor of shape 2 x 2 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...]] >>> print(output) {'params': (0.0001, 1000, 1, [0, 1]), 'iters': 1, 'normresidual': ..., 'fit': ...}
Example using “nvecs” initialization:
>>> M, Minit, output = ttb.cp_als(K.full(), 2, init="nvecs") CP_ALS: Iter 0: f = ... f-delta = ... Iter 1: f = ... f-delta = ... Final f = ...
Example using
pyttb.ktensor
initialization:>>> M, Minit, output = ttb.cp_als(K.full(), 2, init=K) CP_ALS: Iter 0: f = ... f-delta = ... Iter 1: f = ... f-delta = ... Final f = ...
pyttb.cp_apr
- pyttb.cp_apr.cp_apr(input_tensor, rank, algorithm='mu', stoptol=0.0001, stoptime=1000000.0, maxiters=1000, init='random', maxinneriters=10, epsDivZero=1e-10, printitn=1, printinneritn=0, kappa=0.01, kappatol=1e-10, epsActive=1e-08, mu0=1e-05, precompinds=True, inexact=True, lbfgsMem=3)[source]
Compute non-negative CP with alternating Poisson regression.
- Parameters:
input_tensor (
pyttb.tensor
orpyttb.sptensor
)rank (int) – Rank of the decomposition
algorithm (str) – in {‘mu’, ‘pdnr, ‘pqnr’}
stoptol (float) – Tolerance on overall KKT violation
stoptime (float) – Maximum number of seconds to run
maxiters (int) – Maximum number of iterations
init (str or
pyttb.ktensor
) – Initial guessmaxinneriters (int) – Maximum inner iterations per outer iteration
epsDivZero (float) – Safeguard against divide by zero
printitn (int) – Print every n outer iterations, 0 for none
printinneritn (int) – Print every n inner iterations
kappa (int) – MU ALGORITHM PARAMETER: Offset to fix complementary slackness
kappatol – MU ALGORITHM PARAMETER: Tolerance on complementary slackness
epsActive (float) – PDNR & PQNR ALGORITHM PARAMETER: Bertsekas tolerance for active set
mu0 (float) – PDNR ALGORITHM PARAMETER: Initial Damping Parameter
precompinds (bool) – PDNR & PQNR ALGORITHM PARAMETER: Precompute sparse tensor indices
inexact (bool) – PDNR ALGORITHM PARAMETER: Compute inexact Newton steps
lbfgsMem (int) – PQNR ALGORITHM PARAMETER: Precompute sparse tensor indices
- Returns:
M (
pyttb.ktensor
) – Resulting ktensor from CP APRMinit (
pyttb.ktensor
) – Initial Guessoutput (dict) – Additional output #TODO document this more appropriately
- pyttb.cp_apr.tt_cp_apr_mu(input_tensor, rank, init, stoptol, stoptime, maxiters, maxinneriters, epsDivZero, printitn, printinneritn, kappa, kappatol)[source]
Compute nonnegative CP with alternating Poisson regression.
- Parameters:
input_tensor (
pyttb.tensor
orpyttb.sptensor
)rank (int) – Rank of the decomposition
init (
pyttb.ktensor
) – Initial guessstoptol (float) – Tolerance on overall KKT violation
stoptime (float) – Maximum number of seconds to run
maxiters (int) – Maximum number of iterations
maxinneriters (int) – Maximum inner iterations per outer iteration
epsDivZero (float) – Safeguard against divide by zero
printitn (int) – Print every n outer iterations, 0 for none
printinneritn (int) – Print every n inner iterations
kappa (int) – MU ALGORITHM PARAMETER: Offset to fix complementary slackness
kappatol – MU ALGORITHM PARAMETER: Tolerance on complementary slackness
Notes
REFERENCE: E. C. Chi and T. G. Kolda. On Tensors, Sparsity, and Nonnegative Factorizations, arXiv:1112.2414 [math.NA], December 2011, URL: http://arxiv.org/abs/1112.2414. Submitted for publication.
- pyttb.cp_apr.tt_cp_apr_pdnr(input_tensor, rank, init, stoptol, stoptime, maxiters, maxinneriters, epsDivZero, printitn, printinneritn, epsActive, mu0, precompinds, inexact)[source]
Compute nonnegative CP with alternating Poisson regression computes an estimate of the best rank-R CP model of a tensor X using an alternating Poisson regression. The algorithm solves “row subproblems” in each alternating subproblem, using a Hessian of size R^2.
- Parameters:
# TODO it looks like this method of define union helps the typ hinting better than or
input_tensor (Union[
pyttb.tensor
,:class:pyttb.sptensor])rank (int) – Rank of the decomposition
init (str or
pyttb.ktensor
) – Initial guessstoptol (float) – Tolerance on overall KKT violation
stoptime (float) – Maximum number of seconds to run
maxiters (int) – Maximum number of iterations
maxinneriters (int) – Maximum inner iterations per outer iteration
epsDivZero (float) – Safeguard against divide by zero
printitn (int) – Print every n outer iterations, 0 for none
printinneritn (int) – Print every n inner iterations
epsActive (float) – PDNR & PQNR ALGORITHM PARAMETER: Bertsekas tolerance for active set
mu0 (float) – PDNR ALGORITHM PARAMETER: Initial Damping Parameter
precompinds (bool) – PDNR & PQNR ALGORITHM PARAMETER: Precompute sparse tensor indices
inexact (bool) – PDNR ALGORITHM PARAMETER: Compute inexact Newton steps
- Returns:
# TODO detail return dictionary
Notes
REFERENCE: Samantha Hansen, Todd Plantenga, Tamara G. Kolda. Newton-Based Optimization for Nonnegative Tensor Factorizations, arXiv:1304.4964 [math.NA], April 2013, URL: http://arxiv.org/abs/1304.4964. Submitted for publication.
- pyttb.cp_apr.tt_cp_apr_pqnr(input_tensor, rank, init, stoptol, stoptime, maxiters, maxinneriters, epsDivZero, printitn, printinneritn, epsActive, lbfgsMem, precompinds)[source]
Compute nonnegative CP with alternating Poisson regression.
tt_cp_apr_pdnr computes an estimate of the best rank-R CP model of a tensor X using an alternating Poisson regression. The algorithm solves “row subproblems” in each alternating subproblem, using a Hessian of size R^2. The function is typically called by cp_apr.
The model is solved by nonlinear optimization, and the code literally minimizes the negative of log-likelihood. However, printouts to the console reverse the sign to show maximization of log-likelihood.
- mu0: float
PDNR ALGORITHM PARAMETER: Initial Damping Parameter
- precompinds: bool
PDNR & PQNR ALGORITHM PARAMETER: Precompute sparse tensor indices
- inexact: bool
PDNR ALGORITHM PARAMETER: Compute inexact Newton steps
- Parameters:
input_tensor (Union[
pyttb.tensor
,:class:pyttb.sptensor])rank (int) – Rank of the decomposition
init (str or
pyttb.ktensor
) – Initial guessstoptol (float) – Tolerance on overall KKT violation
stoptime (float) – Maximum number of seconds to run
maxiters (int) – Maximum number of iterations
maxinneriters (int) – Maximum inner iterations per outer iteration
epsDivZero (float) – Safeguard against divide by zero
printitn (int) – Print every n outer iterations, 0 for none
printinneritn (int) – Print every n inner iterations
epsActive (float) – PDNR & PQNR ALGORITHM PARAMETER: Bertsekas tolerance for active set
lbfgsMem (int) – Number of vector pairs to store for L-BFGS
precompinds
- Returns:
# TODO detail return dictionary
Notes
REFERENCE: Samantha Hansen, Todd Plantenga, Tamara G. Kolda. Newton-Based Optimization for Nonnegative Tensor Factorizations, arXiv:1304.4964 [math.NA], April 2013, URL: http://arxiv.org/abs/1304.4964. Submitted for publication.
- pyttb.cp_apr.tt_calcpi_prowsubprob(Data, Model, rank, factorIndex, ndims, isSparse=False, sparse_indices=None)[source]
Compute Pi for a row subproblem.
- Parameters:
Data :class:`pyttb.sptensor` or :class:`pyttb.tensor`
isSparse (bool)
Model :class:`pyttb.ktensor`
rank (int)
factorIndex (int)
ndims (int)
sparse_indices (list) – Indices of row subproblem nonzero elements
- Returns:
Pi (
numpy.ndarray
)
See also
pyttb.calculatePi
- pyttb.cp_apr.calc_partials(isSparse, Pi, epsilon, data_row, model_row)[source]
Compute derivative quantities for a PDNR row subproblem.
- Parameters:
isSparse (bool)
Pi (
numpy.ndarray
)epsilon (float) – Prevent division by zero
data_row (
numpy.ndarray
)model_row (
numpy.ndarray
)
- Returns:
phi_row (
numpy.ndarray
) – gradient of row subproblem, except for a constant\(phi\_row[r] = \sum_{j=1}^{J_n}\frac{x_j\pi_{rj}}{\sum_i^R b_i\pi_{ij}}\)
ups_row (
numpy.ndarray
) – intermediate quantity (upsilon) used for second derivatives\(ups\_row[j] = \frac{x_j}{\left(\sum_i^R b_i\pi_{ij}\right)^2}\)
- pyttb.cp_apr.getSearchDirPdnr(Pi, ups_row, rank, gradModel, model_row, mu, epsActSet)[source]
Compute the search direction for PDNR using a two-metric projection with damped Hessian
- Parameters:
Pi (
numpy.ndarray
)ups_row (
numpy.ndarray
) – intermediate quantity (upsilon) used for second derivativesrank (int) – number of variables for the row subproblem
gradModel (
numpy.ndarray
) – gradient vector for the row subproblemmodel_row (
numpy.ndarray
) – vector of variables for the row subproblemmu (float) – damping parameter
epsActSet (float) – Bertsekas tolerance for active set determination
- Returns:
search_dir (
numpy.ndarray
) – search direction vectorpred_red (
numpy.ndarray
) – predicted reduction in quadratic model
- pyttb.cp_apr.tt_linesearch_prowsubprob(direction, grad, model_old, step_len, step_red, max_steps, suff_decr, isSparse, data_row, Pi, phi_row, display_warning)[source]
Perform a line search on a row subproblem
- Parameters:
direction (
numpy.ndarray
) – search directiongrad (
numpy.ndarray
) – gradient vector a model_oldmodel_old (
numpy.ndarray
) – current variable valuesstep_len (float) – initial step length, which is the maximum possible step length
step_red (float) – step reduction factor (suggest 1/2)
max_steps (int) – maximum number of steps to try (suggest 10)
suff_decr (float) – sufficent decrease for convergence (suggest 1.0e-4)
isSparse (bool) – sparsity flag for computing the objective
data_row (
numpy.ndarray
) – row subproblem data, for computing the objectivePi (
numpy.ndarray
) – Pi matrix, for computing the objectivephi_row (
numpy.ndarray
) – 1-grad, more accurate if failing over to multiplicative updatedisplay_warning (bool) – Flag to display warning messages or not
- Returns:
m_new (
numpy.ndarray
) – new (improved) model valuesnum_evals (int) – number of times objective was evaluated
f_old (float) – objective value at model_old
f_1 (float) – objective value at model_old + step_len*direction
f_new (float) – objective value at model_new
- pyttb.cp_apr.getHessian(upsilon, Pi, free_indices)[source]
Return the Hessian for one PDNR row subproblem of Model[n], for just the rows and columns corresponding to the free variables
- Parameters:
upsilon (
numpy.ndarray
) – intermediate quantity (upsilon) used for second derivativesPi (
numpy.ndarray
)free_indices (list)
- Returns:
Hessian (
numpy.ndarray
) – Sub-block of full Hessian identified by free-indices
- pyttb.cp_apr.tt_loglikelihood_row(isSparse, data_row, model_row, Pi)[source]
Compute log-likelihood of one row subproblem
- Parameters:
isSparse (bool) – Sparsity flag
data_row (
numpy.ndarray
) – vector of data valuesmodel_row (
numpy.ndarray
) – vector of model valuesPi (
numpy.ndarray
)
Notes
The row subproblem for a given mode includes one row of matricized tensor data (x) and one row of the model (m) in the same matricized mode. Then (dense case) m: R-length vector x: J-length vector Pi: R x J matrix (sparse case) m: R-length vector x: p-length vector, where p = nnz in row of matricized data tensor Pi: R x p matrix F = - (sum_r m_r - sum_j x_j * log (m * Pi_j) where Pi_j denotes the j^th column of Pi NOTE: Rows of Pi’ must sum to one
- Returns:
loglikelihood (float) – See notes for description
- pyttb.cp_apr.getSearchDirPqnr(model_row, gradModel, epsActSet, delta_model, delta_grad, rho, lbfgs_pos, iters, disp_warn)[source]
Compute the search direction by projecting with L-BFGS.
- Parameters:
model_row (
numpy.ndarray
) – current variable valuesgradModel (
numpy.ndarray
) – gradient at model_rowepsActSet (float) – Bertsekas tolerance for active set determination
delta_model (
numpy.ndarray
) – L-BFGS array of variable deltasdelta_grad (
numpy.ndarray
) – L-BFGS array of gradient deltasrho
lbfgs_pos (int) – pointer into L-BFGS arrays
iters
disp_warn (bool)
- Returns:
direction (
numpy.ndarray
) – Search direction based on current L-BFGS and grad
Notes
Adapted from MATLAB code of Dongmin Kim and Suvrit Sra written in 2008. Modified extensively to solve row subproblems and use a better linesearch; for details see REFERENCE: Samantha Hansen, Todd Plantenga, Tamara G. Kolda. Newton-Based Optimization for Nonnegative Tensor Factorizations, arXiv:1304.4964 [math.NA], April 2013, URL: http://arxiv.org/abs/1304.4964. Submitted for publication.
- pyttb.cp_apr.calc_grad(isSparse, Pi, eps_div_zero, data_row, model_row)[source]
Compute the gradient for a PQNR row subproblem
- Parameters:
isSparse (bool)
Pi (
numpy.ndarray
)eps_div_zero (float)
data_row (
numpy.ndarray
)model_row (
numpy.ndarray
)
- Returns:
phi_row (
numpy.ndarray
)grad_row (
numpy.ndarray
)
- pyttb.cp_apr.calculatePi(Data, Model, rank, factorIndex, ndims)[source]
Helper function to calculate Pi matrix # TODO verify what pi is
- Parameters:
Data (
pyttb.sptensor
orpyttb.tensor
)Model (
pyttb.ktensor
)rank (int)
factorIndex (int)
ndims (int)
- Returns:
Pi (
numpy.ndarray
)
- pyttb.cp_apr.calculatePhi(Data, Model, rank, factorIndex, Pi, epsilon)[source]
- Parameters:
Data (
pyttb.sptensor
orpyttb.tensor
)Model (
pyttb.ktensor
)rank (int)
factorIndex (int)
Pi (
numpy.ndarray
)epsilon (float)
- pyttb.cp_apr.tt_loglikelihood(Data, Model)[source]
Compute log-likelihood of data with model.
- Parameters:
Data (
pyttb.sptensor
orpyttb.tensor
)Model (
pyttb.ktensor
)
- Returns:
loglikelihood (float) –
(sum_i m_i - x_i * log_i) where i is a multiindex across all tensor dimensions.
Notes
We define for any x 0*log(x)=0, such that if our true data is 0 the loglikelihood is the value of the model.
- pyttb.cp_apr.vectorizeForMu(matrix)[source]
Helper Function to unravel matrix into vector
- Parameters:
matrix (
numpy.ndarray
)- Returns:
matrix (
numpy.ndarray
) – len(matrix.shape)==1
pyttb.hosvd
Higher Order SVD Implementation
- pyttb.hosvd.hosvd(input_tensor, tol: float, verbosity: float = 1, dimorder: Optional[List[int]] = None, sequential: bool = True, ranks: Optional[List[int]] = None)[source]
Compute sequentially-truncated higher-order SVD (Tucker).
Computes a Tucker decomposition with relative error specified by tol, i.e., it computes a ttensor T such that ||X-T||/||X|| <= tol.
- Parameters:
input_tensor (Tensor to factor)
tol (Relative error to stop at)
verbosity (Print level)
dimorder (Order to loop through dimensions)
sequential (Use sequentially-truncated version)
ranks (Specify ranks to consider rather than computing)
Example
>>> data = np.array([[29, 39.], [63., 85.]]) >>> tol = 1e-4 >>> disable_printing = -1 >>> tensorInstance = ttb.tensor().from_data(data) >>> result = hosvd(tensorInstance, tol, verbosity=disable_printing) >>> ((result.full() - tensorInstance).norm() / tensorInstance.norm()) < tol True
pyttb.tucker_als
- pyttb.tucker_als.tucker_als(input_tensor, rank, stoptol=0.0001, maxiters=1000, dimorder=None, init='random', printitn=1)[source]
Compute Tucker decomposition with alternating least squares
- Parameters:
input_tensor (
pyttb.tensor
)rank (int, list[int]) – Rank of the decomposition(s)
stoptol (float) – Tolerance used for termination - when the change in the fitness function in successive iterations drops below this value, the iterations terminate (default: 1e-4)
dimorder (list) – Order to loop through dimensions (default: [range(tensor.ndims)])
maxiters (int) – Maximum number of iterations (default: 1000)
init (str or list[np.ndarray]) –
Initial guess (default: “random”)
“random”: initialize using a
pyttb.ttensor
with values chosen from a Normal distribution with mean 1 and standard deviation 0“nvecs”: initialize factor matrices of a
pyttb.ttensor
using the eigenvectors of the outer product of the matricized input tensorpyttb.ttensor
: initialize using a specificpyttb.ttensor
as input - must be the same shape as the input tensor and have the same rank as the input rank
printitn (int) – Number of iterations to perform before printing iteration status - 0 for no status printing (default: 1)
- Returns:
M (
pyttb.ttensor
) – Resulting ttensor from Tucker-ALS factorizationMinit (
pyttb.ttensor
) – Initial guessoutput (dict) –
Information about the computation. Dictionary keys:
params : tuple of (stoptol, maxiters, printitn, dimorder)
iters: number of iterations performed
normresidual: norm of the difference between the input tensor and ktensor factorization
fit: value of the fitness function (fraction of tensor data explained by the model)
How to Cite
Please see references for how to cite a variety of algorithms implemented in this project.
BibTex Entries: Tensor Toolbox for Python
@misc{TTB_Software,
author = {Brett W. Bader and Tamara G. Kolda and others},
title = {MATLAB Tensor Toolbox Version 3.0-dev},
howpublished = {Available online},
month = oct,
year = {2017},
url = {https://www.tensortoolbox.org}
}
@article{TTB_Dense,
author = {Brett W. Bader and Tamara G. Kolda},
title = {Algorithm 862: {MATLAB} tensor classes for fast algorithm prototyping},
journal = {ACM Transactions on Mathematical Software},
month = dec,
year = {2006},
volume = {32},
number = {4},
pages = {635-653},
doi = {10.1145/1186785.1186794}
}
@article{TTB_Sparse,
author = {Brett W. Bader and Tamara G. Kolda},
title = {Efficient {MATLAB} computations with sparse and factored tensors},
journal = {SIAM Journal on Scientific Computing},
month = dec,
year = {2007},
volume = {30},
number = {1},
pages = {205-231},
doi = {10.1137/060676489}
}
@article{TTB_CPOPT,
author = {Evrim Acar and Daniel M. Dunlavy and Tamara G. Kolda},
title = {A Scalable Optimization Approach for Fitting Canonical Tensor Decompositions},
journal = {Journal of Chemometrics},
month = feb,
year = {2011},
volume = {25},
number = {2},
pages = {67-86},
doi = {10.1002/cem.1335}
}
@article{TTB_CPWOPT,
author = {Evrim Acar and Daniel M. Dunlavy and Tamara G. Kolda and Morten M{\o}rup},
title = {Scalable Tensor Factorizations for Incomplete Data},
journal = {Chemometrics and Intelligent Laboratory Systems},
month = mar,
year = {2011},
volume = {106},
number = {1},
pages = {41-56},
doi = {10.1016/j.chemolab.2010.08.004}
}
@article{TTB_SSHOPM,
author = {Tamara G. Kolda and Jackson R. Mayo},
title = {Shifted Power Method for Computing Tensor Eigenpairs},
journal = {SIAM Journal on Matrix Analysis and Applications},
month = oct,
year = {2011},
volume = {32},
number = {4},
pages = {1095-1124},
doi = {10.1137/100801482}
}
@Article{TTB_EIGGEAP,
title = {An Adaptive Shifted Power Method for Computing Generalized Tensor Eigenpairs},
author = {Tamara G. Kolda and Jackson R. Mayo},
doi = {10.1137/140951758},
journal = {SIAM Journal on Matrix Analysis and Applications},
number = {4},
volume = {35},
year = {2014},
month = dec,
pages = {1563-1581},
}
@Article{TTB_CPAPR,
title = {On Tensors, Sparsity, and Nonnegative Factorizations},
author = {Eric C. Chi and Tamara G. Kolda},
doi = {10.1137/110859063},
journal = {SIAM Journal on Matrix Analysis and Applications},
number = {4},
volume = {33},
year = {2012},
month = dec,
pages = {1272-1299},
}
@Article{TTB_CPAPRB,
author = {Samantha Hansen and Todd Plantenga and Tamara G. Kolda},
title = {Newton-Based Optimization for {Kullback-Leibler} Nonnegative Tensor Factorizations},
journal = {Optimization Methods and Software},
volume = {30},
number = {5},
pages = {1002-1029},
month = {April},
year = {2015},
doi = {10.1080/10556788.2015.1009977},
}
@article{TTB_CPSYM,
author = {Tamara G. Kolda},
title = {Numerical Optimization for Symmetric Tensor Decomposition},
journal = {Mathematical Programming B},
volume = {151},
number = {1},
pages = {225-248},
month = apr,
year = {2015},
doi = {10.1007/s10107-015-0895-0},
}
@misc{TTB_CPRALS,
author = {Casey Battaglino and Grey Ballard and Tamara G. Kolda},
title = {A Practical Randomized {CP} Tensor Decomposition},
howpublished = {arXiv:1701.06600},
month = jan,
year = {2017},
eprint = {1701.06600},
eprintclass = {cs.NA},
}
@inproceedings{TTB_MET,
author = {Tamara G. Kolda and Jimeng Sun},
title = {Scalable Tensor Decompositions for Multi-aspect Data Mining},
booktitle = {ICDM 2008: Proceedings of the 8th IEEE International Conference on Data Mining},
month = dec,
year = {2008},
pages = {363-372},
doi = {10.1109/ICDM.2008.89}
}
Contact
Please email dmdunla@sandia.gov with any questions about pyttb that cannot be resolved via issue reporting. Stories of its usefulness are especially welcome. We will try to respond to every email may not always be successful due to the volume of emails.