dense_t3svd#
- t3toolbox.backend.t3_svd.dense_t3svd(T, stack_shape=(), max_tucker_ranks=None, max_tt_ranks=None, rtol=None, atol=None)#
def dense_t3svd( T: common.NDArray, # shape=stack_shape+(N0, .., N(d-1)) stack_shape: typ.Sequence[int] = (), max_tucker_ranks: typ.Sequence[int] = None, # len=d max_tt_ranks: typ.Sequence[int] = None, # len=d+1 rtol: float = None, atol: float = None, ) -> typ.Tuple[ typ.Tuple[ typ.Tuple[common.NDArray,...], # tucker_cores typ.Tuple[common.NDArray,...], # tt_cores ], # Approximation of T by Tucker tensor train typ.Tuple[common.NDArray,...], # Tucker singular values, len=d typ.Tuple[common.NDArray,...], # TT singular values, len=d+1 ]:
Compute TuckerTensorTrain and edge singular values for dense tensor.
Examples
No truncation – a lossless T3 (Tucker + tensor-train) decomposition. Each Tucker basis
Bis contracted into its TT coreGto rebuild the dense tensor:>>> import numpy as np >>> import t3toolbox.backend.t3_svd as t3_svd >>> np.random.seed(0) >>> T = np.random.randn(5, 6, 7) >>> (tucker_cores, tt_cores), ss_tucker, ss_tt = t3_svd.dense_t3svd(T) >>> print([B.shape for B in tucker_cores], [G.shape for G in tt_cores]) [(5, 5), (6, 6), (7, 7)] [(1, 5, 5), (5, 6, 7), (7, 7, 1)] >>> GG_big = [np.einsum('io,aib->aob', B, G) for B, G in zip(tucker_cores, tt_cores)] >>> T2 = np.einsum('aib,bjc,ckd->ijk', *GG_big) >>> print(np.allclose(T, T2)) # exact reconstruction True >>> print(len(ss_tucker), len(ss_tt)) # d Tucker spectra, d+1 TT spectra 3 4
Stacked – a leading
stack_shaperides along on every core; the decomposition is vectorized over the stack:>>> import numpy as np >>> import t3toolbox.backend.t3_svd as t3_svd >>> np.random.seed(0) >>> T = np.random.randn(2, 3, 5, 6, 7) >>> (tucker_cores, tt_cores), _, _ = t3_svd.dense_t3svd(T, stack_shape=(2, 3)) >>> print([B.shape for B in tucker_cores]) # stack_shape=(2,3) prefixes each core [(2, 3, 5, 5), (2, 3, 6, 6), (2, 3, 7, 7)] >>> GG_big = [np.einsum('...io,...aib->...aob', B, G) for B, G in zip(tucker_cores, tt_cores)] >>> T2 = np.einsum('...aib,...bjc,...ckd->...ijk', *GG_big) >>> print(np.allclose(T, T2)) True
Truncation – a smooth tensor has gradually decaying spectra, so
rtoltruncates meaningfully (a sharp random spectrum would not):>>> import numpy as np >>> import t3toolbox.backend.t3_svd as t3_svd >>> i, j, k = np.ogrid[1:9, 1:9, 1:9] >>> T = 1.0 / (i + j + k) # graded-spectrum tensor >>> (tk_f, tt_f), ss_tk_full, ss_tt_full = t3_svd.dense_t3svd(T) # full spectra >>> (tk, tt), _, _ = t3_svd.dense_t3svd(T, rtol=1e-3) # truncate at rtol >>> tucker_ranks = tuple(B.shape[0] for B in tk) >>> tt_ranks = tuple(G.shape[0] for G in tt) + (1,) >>> print(tuple(B.shape[0] for B in tk_f), '->', tucker_ranks) # Tucker ranks drop (8, 8, 8) -> (3, 3, 3) >>> print(tuple(G.shape[0] for G in tt_f) + (1,), '->', tt_ranks) # TT ranks drop (1, 8, 8, 1) -> (1, 3, 3, 1) >>> GG_big = [np.einsum('io,aib->aob', B, G) for B, G in zip(tk, tt)] >>> T2 = np.einsum('aib,bjc,ckd->ijk', *GG_big) >>> dropped_sq = (sum(float(np.sum(s[r:]**2)) for s, r in zip(ss_tt_full, tt_ranks)) ... + sum(float(np.sum(s[r:]**2)) for s, r in zip(ss_tk_full, tucker_ranks))) >>> print(bool(np.linalg.norm(T - T2) <= np.sqrt(dropped_sq))) # accuracy bound [Oseledets] True
Tolerances need a single (unstacked) tensor –
rtol/atolwith a non-emptystack_shaperaise, since different slices could truncate to different ranks (usemax_*_ranksinstead):>>> import numpy as np >>> import t3toolbox.backend.t3_svd as t3_svd >>> np.random.seed(0) >>> T = np.random.randn(2, 3, 5, 6, 7) >>> t3_svd.dense_t3svd(T, stack_shape=(2, 3), rtol=1e-3) Traceback (most recent call last): ... ValueError
- Parameters:
T (NDArray)
stack_shape (t3toolbox.backend.common.typ.Sequence[int])
max_tucker_ranks (t3toolbox.backend.common.typ.Sequence[int])
max_tt_ranks (t3toolbox.backend.common.typ.Sequence[int])
rtol (float)
atol (float)
- Return type:
t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.typ.Tuple[NDArray, Ellipsis], t3toolbox.backend.common.typ.Tuple[NDArray, Ellipsis]], t3toolbox.backend.common.typ.Tuple[NDArray, Ellipsis], t3toolbox.backend.common.typ.Tuple[NDArray, Ellipsis]]