def get_random(shape, num_charges, dtype=np.float64): R = len(shape) charges = [ BaseCharge( np.random.randint(-5, 5, (shape[n], num_charges)), charge_types=[U1Charge] * num_charges) for n in range(R) ] flows = list(np.full(R, fill_value=False, dtype=np.bool)) indices = [Index(charges[n], flows[n]) for n in range(R)] return BlockSparseTensor.random(indices=indices, dtype=dtype)
def test_subbtraction_raises(R, dtype, num_charges): np.random.seed(10) backend = symmetric_backend.SymmetricBackend() a = get_tensor(R, num_charges, dtype) b = get_tensor(R + 1, num_charges, dtype) with pytest.raises(ValueError): backend.subtraction(a, b) shape = b.sparse_shape c = BlockSparseTensor.random([shape[n] for n in reversed(range(len(shape)))]) with pytest.raises(ValueError): backend.subtraction(a, c)
def eye_sym(charges, flows, pivot=1): ind_temp = [Index(charges[n], flows[n]) for n in range(len(flows))] arr = BT.zeros(ind_temp) sparse_blocks, cs, dims = _find_transposed_diagonal_sparse_blocks( charges, flows, pivot, list(range(len(charges)))) for k in range(len(cs)): arr.data[sparse_blocks[k]] = np.eye(N=dims[0, k], M=dims[1, k]).flatten() return arr
def test_eigs_valid_init_operator_with_shape_sanity_check(dtype): np.random.seed(10) backend = symmetric_backend.SymmetricBackend() D = 16 index = Index(U1Charge.random(D, 0, 0), True) indices = [index, index.copy().flip_flow()] H = BlockSparseTensor.random(indices, dtype=dtype) def mv(vec, mat): return mat @ vec init = BlockSparseTensor.random([index], dtype=dtype) eta1, U1 = backend.eigs(mv, [H], init) eta2, U2 = np.linalg.eig(H.todense()) compare_eigvals_and_eigvecs(np.stack([u.todense() for u in U1], axis=1), eta1, U2, eta2, thresh=1E-8)
def test_sparse_shape(dtype, num_charges): np.random.seed(10) Ds = [11, 12, 13] R = len(Ds) charges = [ BaseCharge(np.random.randint(-5, 6, (num_charges, Ds[n])), charge_types=[U1Charge] * num_charges) for n in range(R) ] flows = list(np.full(R, fill_value=False, dtype=np.bool)) indices = [Index(charges[n], flows[n]) for n in range(R)] a = BlockSparseTensor.random(indices=indices, dtype=dtype) backend = symmetric_backend.SymmetricBackend() for s1, s2 in zip(a.sparse_shape, backend.sparse_shape(a)): assert s1 == s2
def test_sparse_shape(num_charges): np.random.seed(10) dtype = np.float64 shape = [10, 11, 12, 13] R = len(shape) charges = [ BaseCharge(np.random.randint(-5, 5, (shape[n], num_charges)), charge_types=[U1Charge] * num_charges) for n in range(R) ] flows = list(np.full(R, fill_value=False, dtype=np.bool)) indices = [Index(charges[n], flows[n]) for n in range(R)] a = BlockSparseTensor.random(indices=indices, dtype=dtype) node = tn.Node(a, backend='symmetric') for s1, s2 in zip(node.sparse_shape, indices): assert s1 == s2
def test_eigsh_valid_init_operator_with_shape_sanity_check(dtype): np.random.seed(10) backend = symmetric_backend.SymmetricBackend() D = 16 index = Index(U1Charge.random(D, 0, 0), True) indices = [index, index.copy().flip_flow()] a = BlockSparseTensor.random(indices, dtype=dtype) H = a + a.T.conj() def mv(vec, mat): return mat @ vec init = BlockSparseTensor.random([index], dtype=dtype) eta1, U1 = backend.eigsh_lanczos(mv, [H], init) v1 = np.reshape(U1[0].todense(), (D)) v1 = v1 / sum(v1) eta2, U2 = np.linalg.eigh(H.todense()) v2 = U2[:, 0] v2 = v2 / sum(v2) np.testing.assert_allclose(eta1[0], min(eta2)) np.testing.assert_allclose(v1, v2)
def test_eigsh_lanczos_sanity_check_1(dtype): np.random.seed(10) D = 16 backend = symmetric_backend.SymmetricBackend() index = Index(U1Charge.random(D, 0, 0), True) indices = [index, index.copy().flip_flow()] H = BlockSparseTensor.random(indices, dtype=dtype) H = H + H.conj().T init = BlockSparseTensor.random([index], dtype=dtype) def mv(x, mat): return mat @ x eta1, U1 = backend.eigsh_lanczos(mv, [H], init) eta2, U2 = np.linalg.eigh(H.todense()) v1 = np.reshape(U1[0].todense(), (D)) v1 = v1 / sum(v1) v2 = U2[:, 0] v2 = v2 / sum(v2) np.testing.assert_allclose(eta1[0], min(eta2)) np.testing.assert_allclose(v1, v2)
def test_decomps_raise(): np.random.seed(10) dtype = np.float64 backend = symmetric_backend.SymmetricBackend() D = 16 R = 3 indices = [Index(U1Charge.random(D, -5, 5), True) for _ in range(R)] H = BlockSparseTensor.random(indices, dtype=dtype) with pytest.raises( NotImplementedError, match="Can't specify non_negative_diagonal with BlockSparse."): backend.qr(H, non_negative_diagonal=True) with pytest.raises( NotImplementedError, match="Can't specify non_negative_diagonal with BlockSparse."): backend.rq(H, non_negative_diagonal=True)
def test_eigs_cache_exception(): dtype = np.float64 np.random.seed(10) backend = symmetric_backend.SymmetricBackend() D = 16 index = Index(U1Charge.random(D, 0, 0), True) def mv(vec): raise ValueError() init = BlockSparseTensor.random([index], dtype=dtype) with pytest.raises(ValueError): backend.eigs(mv, [], init) cacher = get_cacher() assert not cacher.do_caching assert not get_caching_status() assert cacher.cache == {}
# define quantum numbers q_chi_b = U1Charge([-2, 0, 0, 2]) ind_chib0 = Index(charges=q_chi_b, flow=True) ind_chib1 = Index(charges=q_chi_b, flow=False) # define hamiltonian and do 2-to-1 blocking chi_b = 4 sX = np.array([[0, 1], [1, 0]]) sY = np.array([[0, -1j], [1j, 0]]) sZ = np.array([[1, 0], [0, -1]]) ham_s = np.real(np.kron(sX, sX) + np.kron(sY, sY)) ham_temp = (0.5 * np.kron(np.eye(8), np.kron(ham_s, np.eye(2))) + np.kron(np.eye(4), np.kron(ham_s, np.eye(4))) + 0.5 * np.kron(np.eye(2), np.kron(ham_s, np.eye(8)))) bias_shift = max(LA.eigvalsh(ham_temp)) - min(LA.eigvalsh(ham_temp)) ham_init = BT.fromdense([ind_chib1] * 3 + [ind_chib0] * 3, ham_temp.reshape([chi_b] * 6)) if initialize_on: # initialize tensors u = [0] * n_levels w = [0] * n_levels utemp = np.eye(chi_b**2, chi_b**2).reshape(chi_b, chi_b, chi_b, chi_b) u[0] = BT.fromdense([ind_chib1] * 2 + [ind_chib0] * 2, utemp) w[0] = orthog_sym(BT.randn([ind_chib1] * 2 + [ind_chib0], dtype='float64'), pivot=2) for k in range(n_levels - 1): utemp = (np.eye(chi_b**2, chi_b**2)).reshape(chi_b, chi_b, chi_b, chi_b) u[k + 1] = BT.fromdense([ind_chib1] * 2 + [ind_chib0] * 2, utemp) w[k + 1] = orthog_sym(BT.randn([ind_chib1] * 2 + [ind_chib0], dtype='float64'),
# ----------------- # define hamiltonian and do 2-to-1 blocking # en_exact = (-2 / np.sin(np.pi / (2 * n_sites))) / n_sites en_exact = (-4 / np.sin(np.pi / n_sites)) / n_sites # PBC (XX model) sX = np.array([[0, 1], [1, 0]]) sZ = np.array([[1, 0], [0, -1]]) sY = np.array([[0, -1j], [1j, 0]]) ham_s = np.real(np.kron(sX, sX) + np.kron(sY, sY)) # ham_s = (-np.kron(sX, sX) + 0.5 * np.kron(np.eye(2), sZ) + # 0.5 * np.kron(np.eye(2), sZ)) ham_init = (0.5 * np.kron(np.eye(8), np.kron(ham_s, np.eye(2))) + np.kron(np.eye(4), np.kron(ham_s, np.eye(4))) + 0.5 * np.kron(np.eye(2), np.kron(ham_s, np.eye(8)))) bias = max(LA.eigvalsh(ham_init)) ham_z0 = BT.fromdense([ind_chib1] * 3 + [ind_chib0] * 3, ham_init.reshape([chib] * 6)) # initialize tensors u = [0] * n_levels w = [0] * n_levels ham = [0] * (n_levels + 1) rho = [0] * (n_levels + 1) # --- Martin: is there a way of directly defining blocksparse `eye` matrices? eye_mat = np.eye(chib**2, chib**2).reshape(chib, chib, chib, chib) u[0] = BT.fromdense([ind_chib1, ind_chib1, ind_chib0, ind_chib0], eye_mat) # ----------------- # --- Martin: is there a way of directly defining blocksparse isometries? w_temp = BT.randn([ind_chib1, ind_chib1, ind_chi0], dtype=np.float64) ut, st, vt = BLA.svd(w_temp.reshape([chib**2, chi]), full_matrices=False)
# ----------------- # define hamiltonian and do 2-to-1 blocking chi_b = 4 sX = np.array([[0, 1], [1, 0]]) sY = np.array([[0, -1j], [1j, 0]]) sZ = np.array([[1, 0], [0, -1]]) ham_s = np.real(np.kron(sX, sX) + np.kron(sY, sY)) # ham_s = (-np.kron(sX, sX) + 0.5 * np.kron(np.eye(2), sZ) + # 0.5 * np.kron(np.eye(2), sZ)) ham_temp = (0.5 * np.kron(np.eye(8), np.kron(ham_s, np.eye(2))) + np.kron(np.eye(4), np.kron(ham_s, np.eye(4))) + 0.5 * np.kron(np.eye(2), np.kron(ham_s, np.eye(8)))) bias_shift = max(LA.eigvalsh(ham_temp)) - min(LA.eigvalsh(ham_temp)) # ham_temp = ham_temp - min(LA.eigvalsh(ham_temp))*np.eye(64,64) ham_init = BT.fromdense([ind_chib1] * 3 + [ind_chib0] * 3, ham_temp.reshape([chi_b] * 6)) if initialize_on: # initialize tensors u = [0] * n_levels w = [0] * n_levels utemp = np.eye(chi_b**2, chi_b**2).reshape(chi_b, chi_b, chi_b, chi_b) u[0] = BT.fromdense([ind_chib1] * 2 + [ind_chib0] * 2, utemp) w[0] = orthog_sym(BT.randn([ind_chib1] * 2 + [ind_chi0], dtype='float64'), pivot=2) for k in range(n_levels - 1): utemp = (np.eye(chi**2, chi_p**2)).reshape(chi, chi, chi_p, chi_p) u[k + 1] = BT.fromdense([ind_chi1] * 2 + [ind_chip0] * 2, utemp) w[k + 1] = orthog_sym(BT.randn([ind_chip1] * 2 + [ind_chi0], dtype='float64'), pivot=2)
else: en_odd0 = -sum(wq2) # define Ising hamiltonian q_chib = Z2Charge([0, 1]) ind_chib0 = Index(charges=q_chib, flow=True) ind_chib1 = Index(charges=q_chib, flow=False) sX = np.array([[0, 1], [1, 0]]) sZ = np.array([[1, 0], [0, -1]]) ham_s = (-np.kron(sX, sX) + 0.5 * mag * np.kron(np.eye(2), sZ) + 0.5 * mag * np.kron(np.eye(2), sZ)) ham_init = (np.kron(ham_s, np.eye(2**(n_sites - 2)))).reshape( 2 * np.ones(2 * n_sites, dtype=int)) ham_Z0 = BT.fromdense([ind_chib1] * n_sites + [ind_chib0] * n_sites, ham_init) cyc_perm = np.array([*list(range(1, n_sites)), 0]) ham_temp = ham_Z0 ham_final = ham_Z0 for n in range(n_sites - 1): ham_temp = ham_temp.transpose([*cyc_perm, *(cyc_perm + n_sites)]) ham_final = ham_final + ham_temp # diagonalize Ising hamiltonian for GS in even and odd symmetry sector E, V = eigh(ham_final, link_charges=Z2Charge([0, 1]), which='SA') en_even1 = E.todense()[0].item() en_odd1 = E.todense()[1].item() # compare with analytic energies assert np.allclose(en_even0, en_even1)
ind_chi1 = Index(charges=q_chi, flow=False) ind_1 = Index(charges=U1Charge([0]), flow=False) # ----------------- # define hamiltonian and do 2-to-1 blocking chi_b = 4 sX = np.array([[0, 1], [1, 0]]) sY = np.array([[0, -1j], [1j, 0]]) sZ = np.array([[1, 0], [0, -1]]) ham_s = np.real(np.kron(sX, sX) + np.kron(sY, sY)) # ham_s = (-np.kron(sX, sX) + 0.5 * np.kron(np.eye(2), sZ) + # 0.5 * np.kron(np.eye(2), sZ)) ham_temp = (0.5 * np.kron(np.eye(8), np.kron(ham_s, np.eye(2))) + np.kron(np.eye(4), np.kron(ham_s, np.eye(4))) + 0.5 * np.kron(np.eye(2), np.kron(ham_s, np.eye(8)))) ham_init = BT.fromdense([ind_chib1] * 3 + [ind_chib0] * 3, ham_temp.reshape([chi_b] * 6)) bias_shift = max(LA.eigvalsh(ham_temp)) - min(LA.eigvalsh(ham_temp)) ham = [0] * (n_levels + 1) ham[0] = ham_init.copy() if initialize_on: # initialize tensors u = [0] * n_levels w = [0] * n_levels utemp = np.eye(chi_b**2, chi_b**2).reshape(chi_b, chi_b, chi_b, chi_b) u[0] = BT.fromdense([ind_chib1] * 2 + [ind_chib0] * 2, utemp) w[0] = BT.randn([ind_chib1] * 2 + [ind_chib0], dtype='float64') for k in range(n_levels - 1): utemp = (np.eye(chi**2, chi_p**2)).reshape(chi, chi, chi_p, chi_p) u[k + 1] = BT.fromdense([ind_chi1] * 2 + [ind_chip0] * 2, utemp) w[k + 1] = BT.randn([ind_chip1] * 2 + [ind_chi0], dtype='float64')
def get_square_matrix(shape, num_charges, dtype=np.float64): charge = BaseCharge(np.random.randint(-5, 5, (num_charges, shape)), charge_types=[U1Charge] * num_charges) flows = [True, False] indices = [Index(charge, flows[n]) for n in range(2)] return BlockSparseTensor.random(indices=indices, dtype=dtype)
def get_ones(shape, dtype=np.float64): R = len(shape) charges = [U1Charge(np.random.randint(-5, 5, shape[n])) for n in range(R)] flows = list(np.full(R, fill_value=False, dtype=np.bool)) indices = [Index(charges[n], flows[n]) for n in range(R)] return BlockSparseTensor.ones(indices=indices, dtype=dtype)