pyttb.pyttb_utils

PYTTB shared utilities across tensor types.

pyttb.pyttb_utils.tt_union_rows(MatrixA: ndarray, MatrixB: ndarray) ndarray[source]

Reproduce functionality of MATLABS intersect(a,b,’rows’).

Parameters:
  • MatrixA – First matrix.

  • MatrixB – Second matrix.

Returns:

location – List of intersection indices

Examples

>>> a = np.array([[1, 2], [3, 4]])
>>> b = np.array([[0, 0], [1, 2], [3, 4], [0, 0]])
>>> tt_union_rows(a, b)
array([[0, 0],
       [1, 2],
       [3, 4]])
pyttb.pyttb_utils.tt_dimscheck(N: int, M: None = None, dims: int | float | Iterable[int] | Iterable[float] | ndarray | None = None, exclude_dims: int | float | Iterable[int] | Iterable[float] | ndarray | None = None) Tuple[ndarray, None][source]
pyttb.pyttb_utils.tt_dimscheck(N: int, M: int, dims: int | float | Iterable[int] | Iterable[float] | ndarray | None = None, exclude_dims: int | float | Iterable[int] | Iterable[float] | ndarray | None = None) Tuple[ndarray, ndarray]

Preprocess dimensions for tensor operations.

Parameters:
  • N (Tensor order)

  • M (Num of multiplicands)

  • dims (Dimensions to check)

  • exclude_dims (Check all dimensions but these. (Mutually exclusive with dims))

Returns:

  • sdims (New dimensions)

  • vidx (Index into the multiplicands (if M defined).)

Examples

# Default captures all dims and no index

>>> rdims, _ = tt_dimscheck(6)
>>> np.array_equal(rdims, np.arange(6))
True

# Exclude single dim and still no index

>>> rdims, _ = tt_dimscheck(6, exclude_dims=np.array([5]))
>>> np.array_equal(rdims, np.arange(5))
True

# Exclude single dim and number of multiplicands equals resulting size

>>> rdims, ridx = tt_dimscheck(6, 5, exclude_dims=np.array([0]))
>>> np.array_equal(rdims, np.array([1, 2, 3, 4, 5]))
True
>>> np.array_equal(ridx, np.arange(0, 5))
True
pyttb.pyttb_utils.tt_setdiff_rows(MatrixA: ndarray, MatrixB: ndarray) ndarray[source]

Reproduce functionality of MATLABS setdiff(a,b,’rows’).

Parameters:
  • MatrixA – First matrix.

  • MatrixB – Second matrix.

Returns:

List of set difference indices.

pyttb.pyttb_utils.tt_intersect_rows(MatrixA: ndarray, MatrixB: ndarray) ndarray[source]

Reproduce functionality of MATLABS intersect(a,b,’rows’).

Parameters:
  • MatrixA – First matrix.

  • MatrixB – Second matrix.

Returns:

location – List of intersection indices.

Examples

>>> a = np.array([[1, 2], [3, 4]])
>>> b = np.array([[0, 0], [1, 2], [3, 4], [0, 0]])
>>> tt_intersect_rows(a, b)
array([0, 1])
>>> tt_intersect_rows(b, a)
array([1, 2])
pyttb.pyttb_utils.tt_irenumber(t: sptensor, shape: Tuple[int, ...], number_range: Sequence[int | integer | slice | Sequence[int] | ndarray]) ndarray[source]

Renumber indices for sptensor __setitem__.

Parameters:
  • t – Sptensor we are trying to assign from

  • shape – Shape of destination tensor

  • number_range – Key from __setitem__ for destination tensor

Returns:

Subscripts for sptensor assignment

pyttb.pyttb_utils.tt_renumber(subs: ndarray, shape: Tuple[int, ...], number_range: Sequence[int | integer | slice | Sequence[int] | ndarray]) Tuple[ndarray, Tuple[int, ...]][source]

Renumber indices for sptensor __getitem__.

[NEWSUBS,NEWSZ] = RENUMBER(SUBS,SZ,RANGE) takes a set of original subscripts SUBS with entries from a tensor of size SZ. All the entries in SUBS are assumed to be within the specified RANGE. These subscripts are then renumbered so that, in dimension i, the numbers range from 1:numel(RANGE(i)).

Parameters:
  • subs – Original subscripts for source tensor.

  • shape – Shape of source tensor.

  • number_range – Key from __getitem__ for tensor.

Returns:

  • newsubs – Updated subscripts.

  • newshape – Resulting shape.

pyttb.pyttb_utils.tt_renumberdim(idx: ndarray, shape: int, number_range: int | integer | slice | Sequence[int] | ndarray) Tuple[int, int][source]

Renumber a single dimension.

Helper function for RENUMBER.

Parameters:
  • idx

  • shape

  • number_range

Returns:

  • newidx

  • newshape

pyttb.pyttb_utils.tt_ismember_rows(search: ndarray, source: ndarray) Tuple[ndarray, ndarray][source]

Find location of search rows in source array.

Parameters:
  • search – Array to match to source array.

  • source – Array to be matched against.

Returns:

  • matched – len(results)==len(matched) Boolean for indexing matched results.

  • results – search.size==results.size, if search[0,:] == source[3,:], then results[0] = 3 if exists i such that search[i,:] != source[j,:] for any j, then results[i] = -1

Examples

>>> a = np.array([[4, 6], [1, 9], [2, 6]])
>>> b = np.array([[2, 6], [2, 1], [2, 4], [4, 6], [4, 7], [5, 9], [5, 2], [5, 1]])
>>> matched, results = tt_ismember_rows(a, b)
>>> print(results)
[ 3 -1  0]
>>> print(matched)
[ True False  True]
pyttb.pyttb_utils.tt_ind2sub(shape: Tuple[int, ...], idx: ndarray, order: Literal['F', 'C'] = 'F') ndarray[source]

Multiple subscripts from linear indices.

Parameters:
  • shape (Shape of tensor indexing into.)

  • idx (Array of linear indices into the tensor.)

Returns:

Multi-dimensional indices for the tensor.

Example

>>> shape = (2, 2, 2)
>>> linear_indices = np.array([0, 1])
>>> tt_ind2sub(shape, linear_indices)
array([[0, 0, 0],
       [1, 0, 0]])
pyttb.pyttb_utils.tt_subsubsref(obj: ndarray, s: Any) float | ndarray[source]

Helper function for tensor toolbox subsref.

Parameters:
  • obj – Tensor Data Structure

  • s – Reference into tensor

Returns:

Still uncertain to this functionality

pyttb.pyttb_utils.tt_sub2ind(shape: Tuple[int, ...], subs: ndarray, order: Literal['F', 'C'] = 'F') ndarray[source]

Convert multidimensional subscripts to linear indices.

Parameters:
  • shape – Shape of tensor

  • subs – Subscripts for tensor

  • order – Memory layout

Examples

>>> shape = (2, 2, 2)
>>> full_indices = np.array([[0, 0, 0], [1, 0, 0]], dtype=int)
>>> tt_sub2ind(shape, full_indices)
array([0, 1])

See also

tt_ind2sub()

pyttb.pyttb_utils.tt_sizecheck(shape: Tuple[int, ...], nargout: bool = True) bool[source]

TT_SIZECHECK Checks that the shape is valid.

TT_SIZECHECK(S) throws an error if S is not a valid shape tuple, which means that it is a row vector with strictly positive, real-valued, finite integer values.

Parameters:
  • shape – Shape of tensor

  • nargout – Controls if response returned or just acts as assert

Returns:

bool

Examples

>>> tt_sizecheck((0, -1, 2))
False
>>> tt_sizecheck((1, 1, 1))
True

See also

tt_subscheck()

pyttb.pyttb_utils.tt_subscheck(subs: ndarray, nargout: bool = True) bool[source]

TT_SUBSCHECK Checks for valid subscripts.

TT_SUBSCHECK(S) throws an error if S is not a valid subscript array, which means that S is a matrix of real-valued, finite, positive, integer subscripts.

Parameters:
  • subs – Subs of tensor

  • nargout – Controls if response returned or just acts as assert

Returns:

bool

Examples

>>> tt_subscheck(np.array([[2, 2], [3, 3]]))
True
>>> tt_subscheck(np.array([[2, 2], [3, -1]]))
False
pyttb.pyttb_utils.tt_valscheck(vals: ndarray, nargout: bool = True) bool[source]

TT_VALSCHECK Checks for valid values.

TT_VALSCHECK(S) throws an error if S is not a valid values array, which means that S is a column array.

Parameters:
  • vals – Values of tensor

  • nargout – Controls if response returned or just acts as assert

Returns:

bool

Examples

>>> tt_valscheck(np.array([[1], [2]]))
True
>>> tt_valscheck(np.array([[1, 2, 3], [2, 2, 2]]))
False
pyttb.pyttb_utils.isrow(v: ndarray) bool[source]

ISROW Checks if vector is a row vector.

ISROW(V) returns True if V is a row vector; otherwise returns False.

Parameters:

v – Vector input

Examples

>>> isrow(np.array([[1, 2]]))
True
>>> isrow(np.array([[1, 2], [3, 4]]))
False
pyttb.pyttb_utils.isvector(a: ndarray) bool[source]

ISVECTOR Checks if vector is a row vector.

ISVECTOR(A) returns True if A is a vector; otherwise returns False.

Parameters:

a

Returns:

bool

pyttb.pyttb_utils.islogical(a: ndarray) bool[source]

ISLOGICAL Checks if vector is a logical vector.

ISLOGICAL(A) returns True if A is a logical array; otherwise returns False.

Parameters:

a

Returns:

bool

class pyttb.pyttb_utils.IndexVariant(value)[source]

Bases: Enum

Methods for indexing entries of tensors.

pyttb.pyttb_utils.get_index_variant(indices: int | integer | slice | Sequence[int] | ndarray) IndexVariant[source]

Decide on intended indexing variant. No correctness checks.

See getitem or setitem in pyttb.tensor for elaboration of the various indexing options.

pyttb.pyttb_utils.get_mttkrp_factors(U: ktensor | Sequence[ndarray], n: int | integer, ndims: int) Sequence[ndarray][source]

Apply standard checks and type conversions for mttkrp factors.

pyttb.pyttb_utils.gather_wrap_dims(ndims: int, rdims: ndarray | None = None, cdims: ndarray | None = None, cdims_cyclic: Literal['fc'] | Literal['bc'] | Literal['t'] | None = None) Tuple[ndarray, ndarray][source]

Extract tensor modes mapped to rows and columns for matricized tensors.

Parameters:
  • ndims – Number of dimensions.

  • rdims – Mapping of row indices.

  • cdims – Mapping of column indices.

  • cdims_cyclic

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

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

Notes

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

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

References

pyttb.pyttb_utils.np_to_python(iterable: Iterable) Iterable[source]

Convert a structure containing numpy scalars to pure python types.

Mostly useful for prettier printing post numpy 2.0.

Parameters:

iterable – Structure potentially containing numpy scalars.

pyttb.pyttb_utils.parse_shape(shape: int | Iterable[int]) Tuple[int, ...][source]

Parse flexible type into shape tuple.

Examples

>>> integer_shape = 4
>>> parse_shape(integer_shape)
(4,)
>>> flat_numpy_shape = np.ones((4,), dtype=int)
>>> parse_shape(flat_numpy_shape)
(1, 1, 1, 1)
>>> stacked_numpy_shape = np.ones((4, 1, 1), dtype=int)
>>> parse_shape(stacked_numpy_shape)
(1, 1, 1, 1)
>>> list_shape = [1, 1, 1, 1]
>>> parse_shape(list_shape)
(1, 1, 1, 1)
pyttb.pyttb_utils.parse_one_d(maybe_vector: int | float | Iterable[int] | Iterable[float] | ndarray) ndarray[source]

Parse flexible type into numpy array.

Examples

>>> int_scalar = 1
>>> parse_one_d(int_scalar)
array([1])
>>> np_int_scalar = np.int8(1)
>>> parse_one_d(np_int_scalar)
array([1], dtype=int8)
>>> float_scalar = 1.0
>>> parse_one_d(float_scalar)
array([1.])
>>> np_float_scalar = 1.0
>>> parse_one_d(np_float_scalar)
array([1.])
>>> example_list = [1.0, 1.0]
>>> parse_one_d(example_list)
array([1., 1.])
>>> extra_dims = np.array([[1, 1]])
>>> parse_one_d(extra_dims)
array([1, 1])
pyttb.pyttb_utils.to_memory_order(array: ndarray, order: Literal['F', 'C'], copy: bool = False) ndarray[source]
pyttb.pyttb_utils.to_memory_order(array: coo_matrix, order: Literal['F', 'C'], copy: bool = False) coo_matrix

Convert an array to the specified memory layout.

Parameters:
  • array (Data to ensure matches memory order.)

  • order (Desired memory order.)

  • copy (Whether to force a copy even if data already in supported memory order.)

Examples

>>> c_order = np.arange(16).reshape((2, 2, 2, 2))
>>> c_order.flags["C_CONTIGUOUS"]
True
>>> to_memory_order(c_order, "F").flags["F_CONTIGUOUS"]
True