def reg_spectral_learning(H_2l_cores, H_2l1_cores, H_l_cores): l = len(H_l_cores) rank = H_2l_cores[0].shape[-1] print(H_2l1_cores[0].shape) H_2l = mps_to_tensor(H_2l_cores) H_2l1 = mps_to_tensor(H_2l1_cores) H_l = mps_to_tensor(H_l_cores) #print('here') dim = H_l.shape[0] H_2l = H_2l.reshape(dim**l, dim**l) H_2l1 = H_2l1.reshape(dim**l, dim, dim**l) print(H_2l1.shape, H_2l.shape) H_l = H_l.reshape(-1, ) U, D, V = np.linalg.svd(H_2l) P = U[:, :rank] @ np.diag(D[:rank]) S = V[:rank, :] P_inv = np.linalg.pinv(P) S_inv = np.linalg.pinv(S) A = np.einsum('ij, jkl, lm->ikm', P_inv, H_2l1, S_inv) alpha = H_l @ S_inv print('here', H_l.shape, S_inv.shape, P_inv.shape) Omega = P_inv @ H_l return alpha, A, Omega
def mps_to_tensor(mps): import tensorly as tl from tensorly import mps_to_tensor for i in range(len(mps)): mps[i] = tl.tensor(mps[i]) ten = mps_to_tensor(mps).squeeze() return ten
def test_mps_to_tensor_random(): """ Test for mps_to_tensor Uses random tensor as input """ # Create tensor with random elements tensor = tl.tensor(np.random.rand(3, 4, 5, 6, 2, 10)) tensor_shape = tensor.shape # Find MPS decomposition of the tensor rank = 10 factors = matrix_product_state(tensor, rank) # Reconstruct the original tensor reconstructed_tensor = tl.mps_to_tensor(factors) # Check that the rank is 10 D = len(factors) for k in range(D): (r_prev, n_k, r_k) = factors[k].shape assert (r_prev <= rank), "MPS rank with index " + str(k) + "exceeds rank" assert (r_k <= rank), "MPS rank with index " + str(k + 1) + "exceeds rank"
def test_matrix_product_state(): """ Test for matrix_product_state """ rng = check_random_state(1234) ## Test 1 # Create tensor with random elements tensor = tl.tensor(rng.random_sample([3, 4, 5, 6, 2, 10])) tensor_shape = tensor.shape # Find MPS decomposition of the tensor rank = [1, 3, 3, 4, 2, 2, 1] factors = matrix_product_state(tensor, rank) assert ( len(factors) == 6 ), "Number of factors should be 6, currently has " + str(len(factors)) # Check that the ranks are correct and that the second mode of each factor # has the correct number of elements r_prev_iteration = 1 for k in range(6): (r_prev_k, n_k, r_k) = factors[k].shape assert (tensor_shape[k] == n_k ), "Mode 1 of factor " + str(k) + "needs " + str( tensor_shape[k]) + " dimensions, currently has " + str(n_k) assert (r_prev_k == r_prev_iteration), " Incorrect ranks of factors " r_prev_iteration = r_k ## Test 2 # Create tensor with random elements tensor = tl.tensor(rng.random_sample([3, 4, 5, 6, 2, 10])) tensor_shape = tensor.shape # Find MPS decomposition of the tensor rank = [1, 5, 4, 3, 8, 10, 1] factors = matrix_product_state(tensor, rank) for k in range(6): (r_prev, n_k, r_k) = factors[k].shape first_error_message = "MPS rank " + str( k) + " is greater than the maximum allowed " first_error_message += str(r_prev) + " > " + str(rank[k]) assert (r_prev <= rank[k]), first_error_message first_error_message = "MPS rank " + str( k + 1) + " is greater than the maximum allowed " first_error_message += str(r_k) + " > " + str(rank[k + 1]) assert (r_k <= rank[k + 1]), first_error_message ## Test 3 tol = 10e-5 tensor = tl.tensor(rng.random_sample([3, 3, 3])) factors = matrix_product_state(tensor, (1, 3, 3, 1)) reconstructed_tensor = tl.mps_to_tensor(factors) error = tl.norm(reconstructed_tensor - tensor, 2) error /= tl.norm(tensor, 2) assert_(error < tol, 'norm 2 of reconstruction higher than tol')
def test_mps_to_tensor(): """ Test for mps_to_tensor References ---------- .. [1] Anton Rodomanov. "Introduction to the Tensor Train Decomposition and Its Applications in Machine Learning", HSE Seminar on Applied Linear Algebra, Moscow, Russia, March 2016. """ # Create tensor n1 = 3 n2 = 4 n3 = 2 tensor = np.zeros((n1, n2, n3)) for i in range(n1): for j in range(n2): for k in range(n3): tensor[i][j][k] = (i + 1) + (j + 1) + (k + 1) tensor = tl.tensor(tensor) # Compute ground truth MPS factors factors = [None] * 3 factors[0] = np.zeros((1, 3, 2)) factors[1] = np.zeros((2, 4, 2)) factors[2] = np.zeros((2, 2, 1)) for i in range(3): for j in range(4): for k in range(2): factors[0][0][i][0] = i + 1 factors[0][0][i][1] = 1 factors[1][0][j][0] = 1 factors[1][0][j][1] = 0 factors[1][1][j][0] = j + 1 factors[1][1][j][1] = 1 factors[2][0][k][0] = 1 factors[2][1][k][0] = k + 1 factors = [tl.tensor(f) for f in factors] # Check that MPS factors re-assemble to the original tensor assert_array_almost_equal(tensor, tl.mps_to_tensor(factors))
def TT(target, rank): factors = tl.decomposition.matrix_product_state(target, rank) num_params = np.sum([A.size for A in factors]) return tl.mps_to_tensor(factors), num_params