left_svd#
- t3toolbox.backend.linalg.left_svd(G0_i_a_j, min_rank=None, max_rank=None, rtol=None, atol=None)#
def left_svd( G0_i_a_j: NDArray, # shape=(..., ni, na, nj) min_rank: int = None, # 1 <= min_rank <= max_rank <= minimum(ni*na, nj) max_rank: int = None, # 1 <= min_rank <= max_rank <= minimum(ni*na, nj) rtol: float = None, # removes singular values satisfying sigma < maximum(atol, rtol*sigma1) atol: float = None, # removes singular values satisfying sigma < maximum(atol, rtol*sigma1) ) -> typ.Tuple[ NDArray, # U_i_a_x, shape=(..., ni, na, r) NDArray, # ss_x, shape=(.., r) NDArray, # Vt_x_j, shape=(..., r, nj) ]:
Compute (truncated) singular value decomposition of 3-tensor left unfolding.
First two indices of the tensor are grouped for the SVD:
G[i,a,j] = sum_x U[i,a,x] ss[x] Vt[x,j], withUorthonormal in its grouped(i,a)rows. Truncation args behave as intruncated_svd().Examples
>>> import numpy as np >>> import t3toolbox.backend.linalg as linalg >>> np.random.seed(0) >>> G = np.random.randn(4, 5, 6) # (ni, na, nj) >>> U, ss, Vt = linalg.left_svd(G) >>> print(U.shape, ss.shape, Vt.shape) # U keeps (i,a); Vt is the 2d right factor (4, 5, 6) (6,) (6, 6) >>> print(np.allclose(np.einsum('iax,x,xj->iaj', U, ss, Vt), G)) # reconstructs G True >>> Um = U.reshape(4 * 5, -1) >>> print(np.allclose(Um.T @ Um, np.eye(Um.shape[1]))) # left unfolding of U is orthonormal True