def test_matmul(): # 1-dim x n-dim a = tl.randn((4, )) b = tl.randn((2, 3, 4, 5)) res = tl.matmul(a, b) assert_equal(res.shape, (2, 3, 5)) # n_dim x 1-dim a = tl.randn((5, )) res = tl.matmul(b, a) assert_equal(res.shape, (2, 3, 4)) # n-dim x n-dim a = tl.randn((2, 3, 6, 4)) res = tl.matmul(a, b) assert_equal(res.shape, (2, 3, 6, 5))
def test_vonneumann_entropy_pure_state(): """Test for vonneumann_entropy on 2-dimensional tensors. This test checks that pure states have a VNE of zero. """ state = tl.randn((8, 1)) state = state / tl.norm(state) mat_pure = tl.dot(state, tl.transpose(state)) tl_vne = vonneumann_entropy(mat_pure) assert_array_almost_equal(tl_vne, 0, decimal=3)
def test_cp_vonneumann_entropy_pure_state(): """Test for cp_vonneumann_entropy on 2-dimensional CP tensors. This test checks that pure states have a VNE of zero. """ state = tl.randn((8, 1)) state = state / tl.norm(state) mat_pure = tl.dot(state, tl.transpose(state)) mat = parafac(mat_pure, rank=1, normalize_factors=True) tl_vne = cp_vonneumann_entropy(mat) assert_array_almost_equal(tl_vne, 0, decimal=3)
def test_tt_vonneumann_entropy_pure_state(): """Test for tt_vonneumann_entropy TT tensors. This test checks that pure states have a VNE of zero. """ state = tl.randn((8, 1)) state = state/tl.norm(state) mat_pure = tl.reshape(tl.dot(state, tl.transpose(state)), (2, 2, 2, 2, 2, 2)) mat_pure = matrix_product_state(mat_pure, rank=(1, 3, 2, 1, 2, 3, 1)) tl_vne = tt_vonneumann_entropy(mat_pure) assert_array_almost_equal(tl_vne, 0, decimal=3)
def test_tr_to_tensor(): # Create ground truth TR factors factors = [tl.randn((2, 4, 3)), tl.randn((3, 5, 2)), tl.randn((2, 6, 2))] # Create tensor tensor = tl.zeros((4, 5, 6)) for i in range(4): for j in range(5): for k in range(6): product = tl.dot( tl.dot(factors[0][:, i, :], factors[1][:, j, :]), factors[2][:, k, :]) # TODO: add trace to backend instead of this tensor = tl.index_update( tensor, tl.index[i, j, k], tl.sum(product * tl.eye(product.shape[0]))) # Check that TR factors re-assemble to the original tensor assert_array_almost_equal(tensor, tr_to_tensor(factors))
def test_linear_tensor_dot_tucker(factorization, factorized_linear): in_shape = (4, 5) in_dim = prod(in_shape) out_shape = (6, 2) rank = 3 batch_size = 2 tensor = tl.randn((batch_size, in_dim)) fact_weight = TensorizedTensor.new((out_shape, in_shape), rank=rank, factorization=factorization) fact_weight.normal_() full_weight = fact_weight.to_matrix() true_res = torch.matmul(tensor, full_weight.T) res = factorized_linear(tensor, fact_weight, transpose=True) res = res.reshape(batch_size, -1) testing.assert_array_almost_equal(true_res, res, decimal=5)
def test_svd(): """Test for the SVD functions""" tol = 0.1 tol_orthogonality = 0.01 for name, svd_fun in T.SVD_FUNS.items(): sizes = [(100, 100), (100, 5), (10, 10), (10, 4), (5, 100)] n_eigenvecs = [90, 4, 5, 4, 5] for s, n in zip(sizes, n_eigenvecs): matrix = np.random.random(s) matrix_backend = T.tensor(matrix) fU, fS, fV = svd_fun(matrix_backend, n_eigenvecs=n) U, S, V = svd(matrix) U, S, V = U[:, :n], S[:n], V[:n, :] assert_array_almost_equal( np.abs(S), T.abs(fS), decimal=3, err_msg= 'eigenvals not correct for "{}" svd fun VS svd and backend="{}, for {} eigenenvecs, and size {}".' .format(name, tl.get_backend(), n, s)) # True reconstruction error (based on numpy SVD) true_rec_error = np.sum((matrix - np.dot(U, S.reshape( (-1, 1)) * V))**2) # Reconstruction error with the backend's SVD rec_error = T.sum( (matrix_backend - T.dot(fU, T.reshape(fS, (-1, 1)) * fV))**2) # Check that the two are similar assert_( true_rec_error - rec_error <= tol, msg= 'Reconstruction not correct for "{}" svd fun VS svd and backend="{}, for {} eigenenvecs, and size {}".' .format(name, tl.get_backend(), n, s)) # Check for orthogonality when relevant left_orthogonality_error = T.norm( T.dot(T.transpose(fU), fU) - T.eye(n)) assert_( left_orthogonality_error <= tol_orthogonality, msg= 'Left eigenvecs not orthogonal for "{}" svd fun VS svd and backend="{}, for {} eigenenvecs, and size {}".' .format(name, tl.get_backend(), n, s)) right_orthogonality_error = T.norm( T.dot(fV, T.transpose(fV)) - T.eye(n)) assert_( right_orthogonality_error <= tol_orthogonality, msg= 'Right eigenvecs not orthogonal for "{}" svd fun VS svd and backend="{}, for {} eigenenvecs, and size {}".' .format(name, tl.get_backend(), n, s)) # Should fail on non-matrices with assert_raises(ValueError): tensor = T.tensor(np.random.random((3, 3, 3))) svd_fun(tensor) # Test for singular matrices (some eigenvals will be zero) # Rank at most 5 matrix = tl.dot(tl.randn((20, 5), seed=12), tl.randn((5, 20), seed=23)) U, S, V = tl.partial_svd(matrix, n_eigenvecs=6, random_state=0) true_rec_error = tl.sum((matrix - tl.dot(U, tl.reshape(S, (-1, 1)) * V))**2) assert_(true_rec_error <= tol) assert_(np.isfinite(T.to_numpy(U)).all(), msg="Left singular vectors are not finite") assert_(np.isfinite(T.to_numpy(V)).all(), msg="Right singular vectors are not finite") # Test orthonormality when max_dim > n_eigenvecs > matrix_rank matrix = tl.dot(tl.randn((4, 2), seed=1), tl.randn((2, 4), seed=12)) U, S, V = tl.partial_svd(matrix, n_eigenvecs=3, random_state=0) left_orthogonality_error = T.norm(T.dot(T.transpose(U), U) - T.eye(3)) assert_(left_orthogonality_error <= tol_orthogonality) right_orthogonality_error = T.norm(T.dot(V, T.transpose(V)) - T.eye(3)) assert_(right_orthogonality_error <= tol_orthogonality) # Test if partial_svd returns the same result for the same setting matrix = T.tensor(np.random.random((20, 5))) random_state = np.random.RandomState(0) U1, S1, V1 = tl.partial_svd(matrix, n_eigenvecs=2, random_state=random_state) U2, S2, V2 = tl.partial_svd(matrix, n_eigenvecs=2, random_state=0) assert_array_equal(U1, U2) assert_array_equal(S1, S2) assert_array_equal(V1, V2)