def test_eigsh_caching(): def matvec(mps, A, B, C): return ncon([A, mps, B, C], [[3, 1, -1], [1, 2, 4], [3, 5, -2, 2], [5, 4, -3]], backend='symmetric') backend = symmetric_backend.SymmetricBackend() D = 100 M = 5 mpsinds = [ Index(U1Charge(np.random.randint(5, 15, D, dtype=np.int16)), False), Index(U1Charge(np.array([0, 1, 2, 3], dtype=np.int16)), False), Index(U1Charge(np.random.randint(5, 18, D, dtype=np.int16)), True) ] mpoinds = [ Index(U1Charge(np.random.randint(0, 5, M)), False), Index(U1Charge(np.random.randint(0, 10, M)), True), mpsinds[1], mpsinds[1].flip_flow() ] Linds = [mpoinds[0].flip_flow(), mpsinds[0].flip_flow(), mpsinds[0]] Rinds = [mpoinds[1].flip_flow(), mpsinds[2].flip_flow(), mpsinds[2]] mps = BlockSparseTensor.random(mpsinds) mpo = BlockSparseTensor.random(mpoinds) L = BlockSparseTensor.random(Linds) R = BlockSparseTensor.random(Rinds) ncv = 20 backend.eigsh_lanczos(matvec, [L, mpo, R], initial_state=mps, num_krylov_vecs=ncv) assert get_cacher().cache == {}
def test_clear_cache(): D = 100 M = 5 mpsinds = [ Index(U1Charge(np.random.randint(5, 15, D, dtype=np.int16)), False), Index(U1Charge(np.array([0, 1, 2, 3], dtype=np.int16)), False), Index(U1Charge(np.random.randint(5, 18, D, dtype=np.int16)), True) ] mpoinds = [ Index(U1Charge(np.random.randint(0, 5, M)), False), Index(U1Charge(np.random.randint(0, 10, M)), True), mpsinds[1], mpsinds[1].flip_flow() ] Linds = [mpoinds[0].flip_flow(), mpsinds[0].flip_flow(), mpsinds[0]] Rinds = [mpoinds[1].flip_flow(), mpsinds[2].flip_flow(), mpsinds[2]] mps = BlockSparseTensor.random(mpsinds) mpo = BlockSparseTensor.random(mpoinds) L = BlockSparseTensor.random(Linds) R = BlockSparseTensor.random(Rinds) enable_caching() ncon([L, mps, mpo, R], [[3, 1, -1], [1, 2, 4], [3, 5, -2, 2], [5, 4, -3]], backend='symmetric') cacher = get_cacher() assert len(cacher.cache) > 0 disable_caching() clear_cache() assert len(cacher.cache) == 0
def test_index_copy_2(): D = 10 B = 4 dtype = np.int16 np.random.seed(10) q1 = U1Charge(np.random.randint( -B // 2, B // 2 + 1, D).astype(dtype)) #quantum numbers on leg 1 q2 = U1Charge(np.random.randint( -B // 2, B // 2 + 1, D).astype(dtype)) #quantum numbers on leg 1 i1 = Index(charges=q1, flow=False) i2 = Index(charges=q2, flow=False) i3 = Index(charges=q1, flow=True) i4 = Index(charges=q2, flow=True) i12 = i1 * i2 i34 = i3 * i4 i1234 = i12 * i34 i1234_copy = i1234.copy() flat1234 = i1234_copy.flat_charges assert flat1234[0] is not i1.flat_charges[0] assert flat1234[1] is not i2.flat_charges[0] assert flat1234[2] is not i3.flat_charges[0] assert flat1234[3] is not i4.flat_charges[0]
def test_reduce_charges_non_trivial_2(): np.random.seed(10) left_charges1 = np.random.randint(-5, 5, 200, dtype=np.int16) left_charges2 = np.random.randint(-5, 5, 200, dtype=np.int16) right_charges1 = np.random.randint(-5, 5, 200, dtype=np.int16) right_charges2 = np.random.randint(-5, 5, 200, dtype=np.int16) target_charge = np.array([[-2, 0, 3], [-1, 1, 0]]).astype(np.int16) fused_charges1 = fuse_ndarrays([left_charges1, right_charges1]) fused_charges2 = fuse_ndarrays([left_charges2, right_charges2]) dense_positions = reduce_charges([ U1Charge(left_charges1) @ U1Charge(left_charges2), U1Charge(right_charges1) @ U1Charge(right_charges2) ], [False, False], target_charge, return_locations=True) masks = [] assert np.all(dense_positions[0].isin(target_charge)) #pylint: disable=unsubscriptable-object for n in range(target_charge.shape[1]): mask1 = np.isin(fused_charges1, np.squeeze(target_charge[0, n])) mask2 = np.isin(fused_charges2, np.squeeze(target_charge[1, n])) masks.append(np.logical_and(mask1, mask2)) #pylint: disable=no-member np.testing.assert_allclose( np.nonzero(np.logical_or.reduce(masks))[0], dense_positions[1])
def test_eq_2(): np.random.seed(10) c1 = U1Charge(np.array([-2, -1, 0, 1, -1, 3, 4, 5, 1], dtype=np.int16)) c2 = U1Charge(np.array([-1, 0, 1, 2, 0, 4, 5, 6, 2], dtype=np.int16)) c = c1 @ c2 c3 = np.array([[-1, 0], [1, 2]]) inds = np.nonzero(c == c3)[0] np.testing.assert_allclose(inds, [1, 3, 4, 8])
def test_index_raises(): D = 10 B = 4 dtype = np.int16 np.random.seed(10) q1 = U1Charge(np.random.randint(-B // 2, B // 2 + 1, D).astype(dtype)) q2 = U1Charge(np.random.randint(-B // 2, B // 2 + 1, D).astype(dtype)) with pytest.raises(TypeError): Index(charges=[q1, q2], flow=[2, True])
def test_index_flip_flow(): D = 10 B = 4 dtype = np.int16 np.random.seed(10) q1 = U1Charge(np.random.randint(-B // 2, B // 2 + 1, D).astype(dtype)) q2 = U1Charge(np.random.randint(-B // 2, B // 2 + 1, D).astype(dtype)) i = Index(charges=[q1, q2], flow=[False, True]) np.testing.assert_allclose(i.flip_flow().flow, [True, False])
def test_index(): D = 10 B = 4 dtype = np.int16 np.random.seed(10) q1 = U1Charge(np.random.randint(-B // 2, B // 2 + 1, D).astype(dtype)) q2 = U1Charge(np.random.randint(-B // 2, B // 2 + 1, D).astype(dtype)) i = Index(charges=[q1, q2], flow=[False, True]) assert len(i) == D**2 assert i.dim == D**2
def test_BaseCharge_matmul_raises(): B = 5 np.random.seed(10) C1 = np.random.randint(-B // 2, B // 2 + 1, 10).astype(np.int16) C2 = np.random.randint(-B // 2, B // 2 + 1, 11).astype(np.int16) q1 = U1Charge(C1) q2 = U1Charge(C2) with pytest.raises(ValueError): q1 @ q2
def test_eq_1(): np.random.seed(10) c1 = U1Charge(np.array([-2, -1, 0, 1, -1, 3, 4, 5], dtype=np.int16)) c2 = U1Charge(np.array([-1, 0, 1, 2, 0, 4, 5, 6], dtype=np.int16)) c = c1 @ c2 c3 = np.array([[-1, 0]]) inds = np.nonzero(c == c3)[0] np.testing.assert_allclose(inds, [1, 4]) for i in inds: np.array_equal(c[i].charges, c3)
def test_index_charges(): D = 10 B = 4 dtype = np.int16 np.random.seed(10) q1 = U1Charge(np.random.randint(-B // 2, B // 2 + 1, D).astype(dtype)) q2 = U1Charge(np.random.randint(-B // 2, B // 2 + 1, D).astype(dtype)) i = Index(charges=[q1, q2], flow=[False, True]) fused = fuse_charges([q1, q2], [False, True]) np.testing.assert_allclose(i.charges.charges, fused.charges)
def test_index_copy(): D = 10 B = 4 dtype = np.int16 np.random.seed(10) q1 = U1Charge(np.random.randint(-B // 2, B // 2 + 1, D).astype(dtype)) q2 = U1Charge(np.random.randint(-B // 2, B // 2 + 1, D).astype(dtype)) i = Index(charges=[q1, q2], flow=[False, True]) icopy = i.copy() assert not np.any([a is b for a, b in zip(i._charges, icopy._charges)]) assert i.flow is not icopy.flow
def test_U1Charge_mul(): D = 100 B = 5 np.random.seed(10) C1 = np.random.randint(-B // 2, B // 2 + 1, D).astype(np.int16) C2 = np.random.randint(-B // 2, B // 2 + 1, D).astype(np.int16) q1 = U1Charge(C1) q2 = U1Charge(C2) q = q1 @ q2 res = q * True np.testing.assert_allclose(res.charges, (-1) * np.stack([C1, C2]))
def test_iter(): np.random.seed(10) arr1 = np.array([-2, -1, 0, 1, -1, 3, 4, 5, 1], dtype=np.int16) arr2 = np.array([-1, 0, 1, 2, 0, 4, 5, 6, 2], dtype=np.int16) c1 = U1Charge(arr1) c2 = U1Charge(arr2) c = c1 @ c2 m = 0 for n in c: np.testing.assert_allclose(n, np.array([arr1[m], arr2[m]])) m += 1
def test_eq_2(): np.random.seed(10) c1 = U1Charge(np.array([-2, -1, 0, 1, -1, 3, 4, 5, 1], dtype=np.int16)) c2 = U1Charge(np.array([-1, 0, 1, 2, 0, 4, 5, 6, 2], dtype=np.int16)) c = c1 @ c2 c3 = np.array([[-1, 1], [0, 2]]) inds = np.nonzero(c3 == c) np.testing.assert_allclose(inds[0][inds[1] == 0], [1, 4]) np.testing.assert_allclose(inds[0][inds[1] == 1], [3, 8]) for i, j in zip(inds[0], inds[1]): np.array_equal(c[i].charges, c3[:, j])
def test_compute_sparse_lookup_non_ordered(flow): np_flow = np.int(-(np.int(flow) - 0.5) * 2) charge_labels = np.array([0, 0, 1, 5, 5, 0, 2, 3, 2, 3, 4, 0, 3, 3, 1, 5]) unique_charges = np.array([-1, 0, 1, -5, 7, 2]) np_targets = np.array([-1, 0, 2]) charges = [U1Charge(unique_charges, charge_labels=charge_labels)] inds = np.nonzero( np.isin((np_flow * unique_charges)[charge_labels], np_targets))[0] targets = U1Charge(np_targets) lookup, unique, labels = compute_sparse_lookup(charges, [flow], targets) np.testing.assert_allclose(labels, np.sort(labels)) np.testing.assert_allclose(np.squeeze(unique.charges[:, lookup]), (np_flow * unique_charges)[charge_labels][inds])
def test_cache(): D = 10 mpsinds = [ Index(U1Charge(np.random.randint(-5, 5, D, dtype=np.int16)), False), Index(U1Charge(np.random.randint(-5, 5, D, dtype=np.int16)), False), Index(U1Charge(np.random.randint(-5, 5, D, dtype=np.int16)), False), Index(U1Charge(np.random.randint(-5, 5, D, dtype=np.int16)), True) ] A = BlockSparseTensor.random(mpsinds) B = A.conj() res_charges = [ A.flat_charges[2], A.flat_charges[3], B.flat_charges[2], B.flat_charges[3] ] res_flows = [ A.flat_flows[2], A.flat_flows[3], B.flat_flows[2], B.flat_flows[3] ] enable_caching() ncon([A, B], [[1, 2, -1, -2], [1, 2, -3, -4]], backend='symmetric') cacher = get_cacher() sA = _to_string(A.flat_charges, A.flat_flows, 2, [2, 3, 0, 1]) sB = _to_string(B.flat_charges, B.flat_flows, 2, [0, 1, 2, 3]) sC = _to_string(res_charges, res_flows, 2, [0, 1, 2, 3]) blocksA, chargesA, dimsA = _find_transposed_diagonal_sparse_blocks( A.flat_charges, A.flat_flows, 2, [2, 3, 0, 1]) blocksB, chargesB, dimsB = _find_transposed_diagonal_sparse_blocks( B.flat_charges, B.flat_flows, 2, [0, 1, 2, 3]) blocksC, chargesC, dimsC = _find_transposed_diagonal_sparse_blocks( res_charges, res_flows, 2, [0, 1, 2, 3]) assert sA in cacher.cache assert sB in cacher.cache assert sC in cacher.cache for b1, b2 in zip(cacher.cache[sA][0], blocksA): np.testing.assert_allclose(b1, b2) for b1, b2 in zip(cacher.cache[sB][0], blocksB): np.testing.assert_allclose(b1, b2) for b1, b2 in zip(cacher.cache[sC][0], blocksC): np.testing.assert_allclose(b1, b2) assert charge_equal(cacher.cache[sA][1], chargesA) assert charge_equal(cacher.cache[sB][1], chargesB) assert charge_equal(cacher.cache[sC][1], chargesC) np.testing.assert_allclose(cacher.cache[sA][2], dimsA) np.testing.assert_allclose(cacher.cache[sB][2], dimsB) np.testing.assert_allclose(cacher.cache[sC][2], dimsC) disable_caching() clear_cache()
def test_getitem(): q1 = np.array([0, 1, 2, 0, 6, 1, -9, 0, -7]) q2 = np.array([2, 3, 4, -1, 4, 3, 1, 2, 0]) Q1 = U1Charge(charges=q1) Q2 = U1Charge(charges=q2) Q = Q1 @ Q2 t1 = Q[5] np.testing.assert_allclose(t1.charges, [[1, 3]]) assert np.all([t1.charge_types[n] == U1Charge for n in range(2)]) t2 = Q[[2, 5, 7]] assert np.all([t2.charge_types[n] == U1Charge for n in range(2)]) np.testing.assert_allclose(t2.charges, [[2, 4], [1, 3], [0, 2]]) t3 = Q[[5, 2, 7]] assert np.all([t3.charge_types[n] == U1Charge for n in range(2)]) np.testing.assert_allclose(t3.charges, [[1, 3], [2, 4], [0, 2]])
def test_repr(): D = 10 B = 4 dtype = np.int16 np.random.seed(10) q1 = U1Charge(np.random.randint(-B // 2, B // 2 + 1, D).astype(dtype)) q2 = U1Charge(np.random.randint(-B // 2, B // 2 + 1, D).astype(dtype)) index = Index(charges=[q1, q2], flow=[False, True]) dense_shape = f"Dimension: {str(index.dim)} \n" charge_str = str(index._charges).replace('\n,', ',\n') charge_str = charge_str.replace('\n', '\n ') charges = f"Charges: {charge_str} \n" flow_info = f"Flows: {str(index.flow)} \n" res = f"Index:\n {dense_shape} {charges} {flow_info} " assert res == index.__repr__()
def test_index_eq(): q1 = U1Charge(np.array([-1, -2, 0, 8, 7])) q2 = U1Charge(np.array([-1, -2, 0, 8, 7])) q3 = U1Charge(np.array([-1, 0, 8, 7])) i1 = Index(charges=q1, flow=False) i2 = Index(charges=q2, flow=False) i3 = Index(charges=q3, flow=False) i4 = Index(charges=[q1, q2], flow=[False, True]) i5 = Index(charges=[q1, q2], flow=[False, True]) i6 = Index(charges=[q1, q2], flow=[False, False]) assert i1 == i2 assert i1 != i3 assert i1 != i4 assert i4 == i5 assert i5 != i6
def test_reduce_charges(): left_charges = np.asarray([-2, 0, 1, 0, 0]).astype(np.int16) right_charges = np.asarray([-1, 0, 2, 1]).astype(np.int16) target_charge = np.zeros((1, 1), dtype=np.int16) fused_charges = fuse_ndarrays([left_charges, right_charges]) dense_positions = reduce_charges( [U1Charge(left_charges), U1Charge(right_charges)], [False, False], target_charge, return_locations=True) np.testing.assert_allclose(dense_positions[0].charges, 0) np.testing.assert_allclose( dense_positions[1], np.nonzero(fused_charges == target_charge[0, 0])[0])
def test_U1Charge_identity(): D = 100 B = 5 np.random.seed(10) C1 = np.random.randint(-B // 2, B // 2 + 1, D).astype(np.int16) C2 = np.random.randint(-B // 2, B // 2 + 1, D).astype(np.int16) C3 = np.random.randint(-B // 2, B // 2 + 1, D).astype(np.int16) q1 = U1Charge(C1) q2 = U1Charge(C2) q3 = U1Charge(C3) Q = q1 @ q2 @ q3 eye = Q.identity_charges np.testing.assert_allclose(eye.unique_charges, 0) assert eye.num_symmetries == 3
def test_compute_sparse_lookup(): q1 = np.array([-2, 0, -5, 7]) q2 = np.array([-3, 1, -2, 6, 2, -2]) expected_unique = np.array( [-11, -8, -7, -6, -4, -3, -2, -1, 0, 1, 2, 3, 5, 6, 9, 10]) expected_labels_to_unique = np.array([7, 8, 9]) expected_lookup = np.array([9, 8, 8, 7, 9]) charges = [U1Charge(q1), U1Charge(q2)] targets = U1Charge(np.array([-1, 0, 1])) flows = [False, True] lookup, unique, labels = compute_sparse_lookup(charges, flows, targets) np.testing.assert_allclose(lookup, expected_lookup) np.testing.assert_allclose(expected_unique, np.squeeze(unique.charges)) np.testing.assert_allclose(labels, expected_labels_to_unique)
def fuse_many_charges(num_charges, num_charge_types, seed, D, B, use_flows=False): np.random.seed(seed) if use_flows: flows = np.random.choice([True, False], num_charges, replace=True) else: flows = np.asarray([False] * num_charges) np_flows = np.ones(num_charges, dtype=np.int16) np_flows[flows] = -1 charges = [ get_charges(-B // 2, B // 2, D, num_charge_types) for _ in range(num_charges) ] fused = [ fuse_ndarrays( [charges[n][m] * np_flows[n] for n in range(num_charges)]) for m in range(num_charge_types) ] final_charges = [U1Charge(charges[n][0]) for n in range(num_charges)] for n in range(num_charges): for m in range(1, num_charge_types): final_charges[n] = final_charges[n] @ U1Charge(charges[n][m]) np_target_charges = np.random.randint(-B, B, num_charge_types, dtype=np.int16) target_charges = [ U1Charge(np.array([np_target_charges[n]])) for n in range(num_charge_types) ] target = target_charges[0] for m in range(1, num_charge_types): target = target @ target_charges[m] final = final_charges[0] * flows[0] for n in range(1, num_charges): final = final + final_charges[n] * flows[n] nz_1 = np.nonzero(final == target)[0] masks = [fused[m] == target.charges[0, m] for m in range(num_charge_types)] #pylint: disable=no-member nz_2 = np.nonzero(np.logical_and.reduce(masks))[0] return nz_1, nz_2
def test_fuse_indices(): D = 10 B = 4 dtype = np.int16 np.random.seed(10) q1 = U1Charge(np.random.randint( -B // 2, B // 2 + 1, D).astype(dtype)) #quantum numbers on leg 1 q2 = U1Charge(np.random.randint( -B // 2, B // 2 + 1, D).astype(dtype)) #quantum numbers on leg 1 charges = [q1, q2] i1 = Index(charges=q1, flow=False) #index on leg 1 i2 = Index(charges=q2, flow=False) #index on leg 2 i12 = fuse_indices([i1, i2]) for n in range(i12.charges.charges.shape[1]): assert np.all(i12._charges[n].charges == charges[n].charges) assert np.all(i12.charges.charges == (q1 + q2).charges)
def test_index_fusion_mul(): D = 10 B = 4 dtype = np.int16 np.random.seed(10) q1 = U1Charge(np.random.randint( -B // 2, B // 2 + 1, D).astype(dtype)) #quantum numbers on leg 1 q2 = U1Charge(np.random.randint( -B // 2, B // 2 + 1, D).astype(dtype)) #quantum numbers on leg 1 charges = [q1, q2] i1 = Index(charges=q1, flow=False) #index on leg 1 i2 = Index(charges=q2, flow=False) #index on leg 2 i12 = i1 * i2 for n in range(len(i12.charges.charges)): assert np.all(i12._charges[n].charges == charges[n].charges) assert np.all(i12.charges.charges == (q1 + q2).charges)
def test_U1Charge_matmul(): D = 1000 B = 5 np.random.seed(10) C1 = np.random.randint(-B // 2, B // 2 + 1, D).astype(np.int16) C2 = np.random.randint(-B // 2, B // 2 + 1, D).astype(np.int16) C3 = np.random.randint(-B // 2, B // 2 + 1, D).astype(np.int16) q1 = U1Charge(C1) q2 = U1Charge(C2) q3 = U1Charge(C3) Q = q1 @ q2 @ q3 Q_ = BaseCharge(np.stack([C1, C2, C3], axis=0), charge_labels=None, charge_types=[U1Charge, U1Charge, U1Charge]) assert np.all(Q.charges == Q_.charges)
def test_eq_0(): np.random.seed(10) arr = np.array([-2, -1, 0, 1, -1, 3, 4, 5], dtype=np.int16) c1 = U1Charge(arr) targets = np.array([-1, 0]) m1 = c1 == targets m2 = arr[:, None] == targets[None, :] np.testing.assert_allclose(m1, m2)
def test_Charge_mul_raises(): D = 100 np.random.seed(10) C = np.random.randint(-5, 6, D).astype(np.int16) q = U1Charge(C) with pytest.raises(ValueError, match="can only multiply by `True` or `False`"): q * 10 #pytype: disable=unsupported-operands
def test_U1Charge_dual(): D = 100 B = 6 np.random.seed(10) charges = np.random.randint(-B // 2, B // 2 + 1, D).astype(np.int16) q1 = U1Charge(charges) assert np.all(q1.dual(True).charges == -charges)