TuckerTensorTrain.t3svd_dense#

static t3toolbox.tucker_tensor_train.TuckerTensorTrain.t3svd_dense(T, stack_shape=(), max_tucker_ranks=None, max_tt_ranks=None, rtol=None, atol=None)#
def t3svd_dense(
        T: NDArray,                              # shape=stack_shape+(N1, N2, .., Nd)
        stack_shape: Sequence[int] = (),
        max_tucker_ranks: typ.Union[int, Sequence[int]] = None,  # scalar (caps all) or len=d
        max_tt_ranks: typ.Union[int, Sequence[int]] = None,      # scalar (caps all) or len=d+1
        rtol: float = None,
        atol: float = None,
) -> Tuple[
    'TuckerTensorTrain',  # Approximation of T by Tucker tensor train
    Tuple[NDArray, ...],  # Tucker singular values, len=d
    Tuple[NDArray, ...],  # TT singular values, len=d+1
]:

Compute TuckerTensorTrain representation or approximation of a dense tensor.

Parameters:
  • T (NDArray) – The dense tensor. shape = stack_shape + (N0, ..., N(d-1))

  • stack_shape (Sequence[int], optional) – The stack shape. Default: no stacking (stack_shape=())

  • max_tucker_ranks (int or Sequence[int], optional) – Maximum Tucker ranks ni. A scalar caps every mode; a sequence is per-mode, e.g., (5,5,5) with len(max_tucker_ranks)=d. Default: no max Tucker rank truncation (None).

  • max_tt_ranks (int or Sequence[int], optional) – Maximum TT-ranks ri. A scalar caps every bond; a sequence is per-bond, e.g., (1,5,5,5,1) with len(max_tt_ranks)=d+1. Default: no max TT rank truncation (None).

  • rtol (float, optional) – Relative tolerance for truncation (in the Frobenius norm), applied per truncation step (see Notes – the overall error can be larger). Default: no rtol truncation (None). Requires stack_shape=().

  • atol (float, optional) – Absolute tolerance for truncation (in the Frobenius norm), applied per truncation step (see Notes). Default: no atol truncation (None). Requires stack_shape=().

Returns:

  • TuckerTensorTrain – Tucker tensor train approximation of T

  • Tuple[NDArray,…] – Singular values of matricizations. len=d. elm_shape=(ni,)

  • Tuple[NDArray,…] – Singular values of unfoldings. len=d+1. elm_shape=(ri,)

Raises:

ValueError – If stack_shape is not empty and rtol or atol are supplied. (Cannot use tolerances with stacking)

Return type:

Tuple[TuckerTensorTrain, Tuple[NDArray, Ellipsis], Tuple[NDArray, Ellipsis]]

Notes

rtol/atol bound the truncation error at each step (each unfolding/matricization SVD truncation), not the overall error. The per-step errors accumulate in quadrature over the 2d-1 steps (d-1 TT unfoldings + d Tucker matricizations), so the realized error can exceed the requested tolerance by up to a factor sqrt(2d-1) (the generalized Oseledets bound). See docs/contributor/t3svd_verification.md for the bound and its proof.

Notes

See the dense T3-SVD (Algorithm 9) in Appendix A of [1].

References

Examples

>>> import numpy as np
>>> import t3toolbox.tucker_tensor_train as t3
>>> import math
>>> np.random.seed(0)
>>> T0 = np.random.randn(40, 50, 60)
>>> c0 = 1.0 / np.arange(1, 41)**2
>>> c1 = 1.0 / np.arange(1, 51)**2
>>> c2 = 1.0 / np.arange(1, 61)**2
>>> T = np.einsum('ijk,i,j,k->ijk', T0, c0, c1, c2) # graded-spectrum (preconditioned) tensor
>>> x, ss_tucker, ss_tt = t3.TuckerTensorTrain.t3svd_dense(T, rtol=1e-3) # truncated T3-SVD
>>> print(x.tucker_ranks, x.tt_ranks)          # rtol reduces the ranks below full (40,50,60)
(11, 11, 10) (1, 10, 11, 1)
>>> T2 = x.to_dense()
>>> rel_err = np.linalg.norm(T - T2) / np.linalg.norm(T)
>>> # per-step rtol accumulates over 2d-1 steps -> realized error within sqrt(2d-1)*rtol (d=3)
>>> print(bool(rel_err <= math.sqrt(2 * 3 - 1) * 1e-3))
True