t3toolbox.tucker_tensor_train.t3svd#
- t3toolbox.tucker_tensor_train.t3svd(x: TuckerTensorTrain, min_tt_ranks: t3toolbox.backend.common.typ.Sequence[int] = None, min_tucker_ranks: t3toolbox.backend.common.typ.Sequence[int] = None, max_tt_ranks: t3toolbox.backend.common.typ.Sequence[int] = None, max_tucker_ranks: t3toolbox.backend.common.typ.Sequence[int] = None, rtol: float = None, atol: float = None, squash_tails_first: bool = True, use_jax: bool = False) t3toolbox.backend.common.typ.Tuple[TuckerTensorTrain, t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.NDArray, Ellipsis], t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.NDArray, Ellipsis]]#
Compute (truncated) T3-SVD of TuckerTensorTrain.
- Parameters:
x (TuckerTensorTrain) – The Tucker tensor train. structure=((N1,…,Nd), (n1,…,nd), (1,r1,…r(d-1),1))
min_tucker_ranks (typ.Sequence[int]) – Minimum Tucker ranks for truncation.
min_tt_ranks (typ.Sequence[int]) – Minimum TT-ranks for truncation.
max_tucker_ranks (typ.Sequence[int]) – Maximum Tucker ranks for truncation.
max_tt_ranks (typ.Sequence[int]) – Maximum TT-ranks for truncation.
rtol (float) – Relative tolerance for truncation.
atol (float) – Absolute tolerance for truncation.
xnp – Linear algebra backend. Default: np (numpy)
- Returns:
NDArray – New TuckerTensorTrain representing the same tensor (or a truncated version), but with modified cores
typ.Tuple[NDArray,…] – Singular values associated with edges between Tucker cores and TT-cores
typ.Tuple[NDArray,…] – Singular values associated with edges between adjacent TT-cores
See also
left_svd_3tensor,right_svd_3tensor,outer_svd_3tensor,up_svd_ith_tucker_core,left_svd_ith_tt_core,right_svd_ith_tt_core,up_svd_ith_tt_core,down_svd_ith_tt_core,truncated_svdExamples
T3-SVD with no truncation: (ranks may decrease to minimal values, but no approximation error)
>>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> x = t3.t3_corewise_randn((5,6,3), (4,4,3), (1,3,2,1)) >>> x2, ss_tucker, ss_tt = t3.t3svd(x) # Compute T3-SVD >>> x_dense = x.to_dense() >>> x2_dense = x2.to_dense() >>> print(np.linalg.norm(x_dense - x2_dense)) # Tensor unchanged 7.556835759880194e-13 >>> ss_tt1 = np.linalg.svd(x_dense.reshape((5, 6*3)))[1] # Singular values of unfolding 1 >>> print(ss_tt1); print(ss_tt[1]) [1.75326490e+02 3.41363029e+01 9.31164204e+00 1.33610061e-14 4.11601708e-15] [175.32648969 34.13630287 9.31164204] >>> ss_tucker2 = np.linalg.svd(x_dense.transpose([2,0,1]).reshape((3,5*6)))[1] # Singular values of matricization 2 >>> print(ss_tucker2); print(ss_tucker[2]) [1.71350937e+02 5.12857505e+01 1.36927051e-14] [171.35093708 51.28575045]
T3-SVD with truncation based on relative tolerance:
>>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> B0 = np.random.randn(35,40) @ np.diag(1.0 / np.arange(1, 41)**2) # preconditioned indices >>> B1 = np.random.randn(45,50) @ np.diag(1.0 / np.arange(1, 51)**2) >>> B2 = np.random.randn(55,60) @ np.diag(1.0 / np.arange(1, 61)**2) >>> G0 = np.random.randn(1,35,30) >>> G1 = np.random.randn(30,45,40) >>> G2 = np.random.randn(40,55,1) >>> tucker_cores_x = (B0, B1, B2) >>> tt_cores_x = (G0, G1, G2) >>> x = t3.TuckerTensorTrain(tucker_cores_x, tt_cores_x) # Tensor has spectral decay due to preconditioning >>> x2, ss_tucker, ss_tt = t3.t3svd(x, rtol=1e-2) # Truncate singular values to reduce rank >>> print(x.uniform_structure) ((40, 50, 60), (35, 45, 55), (1, 30, 40, 1), ()) >>> print(x2.uniform_structure) ((40, 50, 60), (6, 6, 5), (1, 6, 5, 1), ()) >>> x_dense = x.to_dense() >>> x2_dense = x2.to_dense() >>> print(np.linalg.norm(x_dense - x2_dense)/np.linalg.norm(x_dense)) # Should be near rtol=1e-2 0.01919726997372989
T3-SVD with truncation based on absolute tolerance:
>>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> x = t3.t3_corewise_randn((14,15,16), (10,11,12), (1,8,9,1)) >>> x2, ss_tucker, ss_tt = t3.t3svd(x, max_tucker_ranks=(3,3,3), max_tt_ranks=(1,2,2,1)) # Truncate based on ranks >>> print(x.uniform_structure) ((14, 15, 16), (10, 11, 12), (1, 8, 9, 1), ()) >>> print(x2.uniform_structure) ((14, 15, 16), (3, 3, 2), (1, 2, 2, 1), ())
Example where first and last ranks are not ones:
>>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> x = t3.t3_corewise_randn((5,6,3), (4,4,3), (2,3,2,2)) >>> x2, ss_tucker, ss_tt = t3.t3svd(x, squash_tails_first=False) # Compute T3-SVD >>> x_dense = x.to_dense(squash_tails=False) >>> x2_dense = x2.to_dense(squash_tails=False) >>> print(np.linalg.norm(x_dense - x2_dense)) # Tensor unchanged 5.486408687260824e-13 >>> ss_tt0 = np.linalg.svd(x_dense.reshape((2,5*6*3*2)))[1] # Singular values of leading unfolding >>> print(ss_tt0); print(ss_tt[0]) [303.0474449 88.85034392] [303.0474449 88.85034392] >>> ss_tt3 = np.linalg.svd(x_dense.reshape((2*5*6*3,2)))[1] # Singular values of trailing unfolding >>> print(ss_tt3); print(ss_tt[3]) [299.45433768 100.29574828] [299.45433768 100.29574828]