def test_BlockSparseTensor_init(): np.random.seed(10) D = 10 rank = 4 flows = np.random.choice([True, False], size=rank, replace=True) charges = [ U1Charge.random(dimension=D, minval=-5, maxval=5) for _ in range(rank) ] fused = fuse_charges(charges, flows) data = np.random.uniform(0, 1, size=len( np.nonzero(fused == np.zeros((1, 1)))[0])) order = [[n] for n in range(rank)] arr = BlockSparseTensor(data, charges, flows, order=order) np.testing.assert_allclose(data, arr.data) for c1, c2 in zip(charges, arr.charges): assert charge_equal(c1, c2[0]) for c1, c2 in zip(charges, arr._charges): assert charge_equal(c1, c2) data = np.random.uniform( 0, 1, size=len(np.nonzero(fused == np.zeros((1, 1)))[0]) + 1) with pytest.raises(ValueError): arr = BlockSparseTensor(data, charges, flows, order=order, check_consistency=True)
def test_tn_reshape(dtype): np.random.seed(10) Ds = [8, 9, 10, 11] indices = [ Index(U1Charge.random(dimension=Ds[n], minval=-5, maxval=5), False) for n in range(4) ] arr = BlockSparseTensor.random(indices, dtype=dtype) arr2 = reshape(arr, [72, 110]) for n in range(2): for m in range(2): assert charge_equal(arr2.charges[n][m], indices[n * 2 + m].charges) np.testing.assert_allclose(arr2.shape, [72, 110]) np.testing.assert_allclose(arr2._order, [[0, 1], [2, 3]]) np.testing.assert_allclose(arr2.flows, [[False, False], [False, False]]) assert arr2.ndim == 2 arr3 = reshape(arr, Ds) for n in range(4): assert charge_equal(arr3.charges[n][0], indices[n].charges) np.testing.assert_allclose(arr3.shape, Ds) np.testing.assert_allclose(arr3._order, [[0], [1], [2], [3]]) np.testing.assert_allclose(arr3.flows, [[False], [False], [False], [False]]) assert arr3.ndim == 4
def test_flat_charges(): Ds = [10, 11, 12, 13] charges = [U1Charge.random(Ds[n], -5, 5) for n in range(4)] flows = [True, False, True, False] inds = [Index(c, flows[n]) for n, c in enumerate(charges)] a = BlockSparseTensor.random(inds, dtype=np.float64) order = [0, 3, 1, 2] a = a.transpose(order) for n, o in enumerate(a.flat_order): charge_equal(a.flat_charges[n], a._charges[o])
def test_eigh(dtype, num_charges): np.random.seed(10) backend = symmetric_backend.SymmetricBackend() H = get_hermitian_matrix(num_charges, dtype) eta, U = backend.eigh(H) eta_ac, U_ac = eigh(H) np.testing.assert_allclose(eta.data, eta_ac.data) np.testing.assert_allclose(U.data, U_ac.data) assert charge_equal(eta._charges[0], eta_ac._charges[0]) assert np.all([ charge_equal(U._charges[n], U_ac._charges[n]) for n in range(len(U._charges)) ])
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_tensordot_outer(R1, R2, dtype, num_charges): np.random.seed(10) DsA = np.random.randint(3, 5, R1) Dscomm = np.random.randint(3, 5, 0) DsB = np.random.randint(3, 5, R2) A, B, _, _ = get_contractable_tensors(R1, R2, 0, dtype, num_charges, DsA, Dscomm, DsB) res = tensordot(A, B, axes=0) dense_res = np.tensordot(A.todense(), B.todense(), axes=0) np.testing.assert_allclose(dense_res, res.todense()) for n in range(R1): assert charge_equal(res.charges[n][0], A.charges[n][0]) for n in range(R1, R1 + R2): assert charge_equal(res.charges[n][0], B.charges[n - R1][0])
def test_ChargeArray_init(chargetype): np.random.seed(10) D = 10 rank = 4 charges = [get_charge(chargetype, 1, D) for _ in range(rank)] data = np.random.uniform(0, 1, size=D**rank) flows = np.random.choice([True, False], size=rank, replace=True) order = [[n] for n in range(rank)] arr = ChargeArray(data, charges, flows, order=order) np.testing.assert_allclose(data, arr.data) for c1, c2 in zip(charges, arr.charges): assert charge_equal(c1, c2[0]) for c1, c2 in zip(charges, arr._charges): assert charge_equal(c1, c2)
def assert_allclose(expected, actual, backend, **kwargs): if backend.name == 'symmetric': exp = expected.contiguous() act = actual.contiguous() if exp.shape != act.shape: raise ValueError(f"expected shape = {exp.shape}, " f"actual shape = {act.shape}") if len(exp.flat_charges) != len(act.flat_charges): raise ValueError("expected charges differ from actual charges") if len(exp.flat_flows) != len(act.flat_flows): raise ValueError(f"expected flat flows = {exp.flat_flows}" f" differ from actual flat flows = {act.flat_flows}") for c1, c2 in zip(exp.flat_charges, act.flat_charges): if not charge_equal(c1, c2): raise ValueError("expected charges differ from actual charges") if not np.all(np.array(exp.flat_flows) == np.array(act.flat_flows)): raise ValueError(f"expected flat flows = {exp.flat_flows}" f" differ from actual flat flows = {act.flat_flows}") if not np.all(np.abs(exp.data - act.data) < 1E-10): np.testing.assert_allclose(act.data, exp.data, **kwargs) else: np.testing.assert_allclose(actual, expected, **kwargs)
def test_split_node_mixed_order(dtype, num_charges): np.random.seed(111) a = tn.Node(get_zeros((2, 3, 4, 5, 6), num_charges, dtype), backend='symmetric') left_edges = [] for i in [0, 2, 4]: left_edges.append(a[i]) right_edges = [] for i in [1, 3]: right_edges.append(a[i]) left, right, _ = tn.split_node(a, left_edges, right_edges) tn.check_correct({left, right}) actual = left @ right np.testing.assert_allclose(actual.tensor.shape, (2, 4, 6, 3, 5)) np.testing.assert_allclose(a.tensor.shape, (2, 4, 6, 3, 5)) np.testing.assert_allclose(left.tensor.data, 0) np.testing.assert_allclose(right.tensor.data, 0) np.testing.assert_allclose(left.tensor.shape[0:3], (2, 4, 6)) np.testing.assert_allclose(right.tensor.shape[1:], (3, 5)) assert np.all([ charge_equal(a.tensor.charges[n][0], actual.tensor.charges[n][0]) for n in range(len(a.tensor._charges)) ])
def test_tensordot_empty_tensors(dtype, num_charges): A, B, iA, iB = get_contractable_tensors(R1=4, R2=4, cont=2, dtype=dtype, num_charges=num_charges, DsA=[10, 0], Dscomm=[0, 4], DsB=[8, 0]) free_inds_A = np.sort(list(set(np.arange(len(A.shape))) - set(iA))) free_inds_B = np.sort(list(set(np.arange(len(B.shape))) - set(iB))) res = tensordot(A, B, (iA, iB)) assert len(res.data) == 0 for n in range(2): assert charge_equal(res.charges[n][0], A.charges[free_inds_A[n]][0]) for n in range(2, 4): assert charge_equal(res.charges[n][0], B.charges[free_inds_B[n - 2]][0])
def test_tensordot(R1, R2, cont, dtype, num_charges): np.random.seed(10) DsA = np.random.randint(5, 10, R1 - cont) Dscomm = np.random.randint(5, 10, cont) DsB = np.random.randint(5, 10, R2 - cont) A, B, indsA, indsB = get_contractable_tensors(R1, R2, cont, dtype, num_charges, DsA, Dscomm, DsB) res = tensordot(A, B, (indsA, indsB)) dense_res = np.tensordot(A.todense(), B.todense(), (indsA, indsB)) np.testing.assert_allclose(dense_res, res.todense()) free_inds_A = np.sort(list(set(np.arange(len(A.shape))) - set(indsA))) free_inds_B = np.sort(list(set(np.arange(len(B.shape))) - set(indsB))) for n, fiA in enumerate(free_inds_A): assert charge_equal(res.charges[n][0], A.charges[fiA][0]) for n in range(len(free_inds_A), len(free_inds_A) + len(free_inds_B)): assert charge_equal(res.charges[n][0], B.charges[free_inds_B[n - len(free_inds_A)]][0])
def test_conj(dtype, num_charges): np.random.seed(10) a = tn.Node( get_random((6, 7, 8, 9, 10), num_charges=num_charges, dtype=dtype), backend='symmetric') abar = tn.linalg.node_linalg.conj(a) np.testing.assert_allclose(abar.tensor.data, a.backend.conj(a.tensor.data)) assert np.all([ charge_equal(abar.tensor._charges[n], a.tensor._charges[n]) for n in range(len(a.tensor._charges)) ])
def test_matrix_inv(dtype, num_charges): np.random.seed(10) backend = symmetric_backend.SymmetricBackend() H = get_hermitian_matrix(num_charges, dtype) Hinv = backend.inv(H) Hinv_ac = inv(H) np.testing.assert_allclose(Hinv_ac.data, Hinv.data) assert np.all([ charge_equal(Hinv._charges[n], Hinv_ac._charges[n]) for n in range(len(Hinv._charges)) ])
def test_sqrt(R, dtype, num_charges): np.random.seed(10) backend = symmetric_backend.SymmetricBackend() a = get_tensor(R, num_charges, dtype) actual = backend.sqrt(a) expected = sqrt(a) np.testing.assert_allclose(expected.data, actual.data) assert np.all([ charge_equal(expected._charges[n], actual._charges[n]) for n in range(len(actual._charges)) ])
def test_ChargeArray_generic(dtype, chargetype): Ds = [8, 9, 10, 11] indices = [Index(get_charge(chargetype, 1, Ds[n]), False) for n in range(4)] arr = ChargeArray.random(indices, dtype=dtype) assert arr.ndim == 4 assert arr.dtype == dtype np.testing.assert_allclose(arr.shape, Ds) np.testing.assert_allclose(arr.flat_flows, [False, False, False, False]) for n in range(4): assert charge_equal(indices[n]._charges[0], arr.flat_charges[n]) assert arr.sparse_shape[n] == indices[n]
def test_tensordot(R1, R2, cont, dtype, num_charges): np.random.seed(10) backend = symmetric_backend.SymmetricBackend() a, b, indsa, indsb = get_contractable_tensors(R1, R2, cont, dtype, num_charges) actual = backend.tensordot(a, b, (indsa, indsb)) expected = tensordot(a, b, (indsa, indsb)) np.testing.assert_allclose(expected.data, actual.data) assert np.all([ charge_equal(expected._charges[n], actual._charges[n]) for n in range(len(actual._charges)) ])
def test_BlockSparseTensor_contiguous_1(): Ds = [10, 11, 12, 13] charges = [U1Charge.random(Ds[n], -5, 5) for n in range(4)] flows = [True, False, True, False] inds = [Index(c, flows[n]) for n, c in enumerate(charges)] b = BlockSparseTensor.random(inds, dtype=np.float64) order = [0, 3, 2, 1] b = b.transpose(order) b_ = b.contiguous(inplace=False) np.testing.assert_allclose(b.flows, b_.flows) for n in range(4): assert charge_equal(b._charges[order[n]], b_._charges[n])
def test_svd_consistency(dtype, num_charges): np.random.seed(111) original_tensor = get_random((20, 20), num_charges, dtype) node = tn.Node(original_tensor, backend='symmetric') u, vh, _ = tn.split_node(node, [node[0]], [node[1]]) final_node = tn.contract_between(u, vh) np.testing.assert_allclose( final_node.tensor.data, original_tensor.data, rtol=1e-6) assert np.all([ charge_equal(final_node.tensor._charges[n], original_tensor._charges[n]) for n in range(len(original_tensor._charges)) ])
def test_ChargeArray_reshape(dtype): Ds = [8, 9, 10, 11] indices = [Index(U1Charge.random(-5, 5, Ds[n]), False) for n in range(4)] arr = ChargeArray.random(indices, dtype=dtype) arr2 = arr.reshape([72, 110]) for n in range(2): for m in range(2): assert charge_equal(arr2.charges[n][m], indices[n * 2 + m].charges) np.testing.assert_allclose(arr2.shape, [72, 110]) np.testing.assert_allclose(arr2._order, [[0, 1], [2, 3]]) np.testing.assert_allclose(arr2.flows, [[False, False], [False, False]]) assert arr2.ndim == 2 arr3 = arr.reshape(Ds) for n in range(4): assert charge_equal(arr3.charges[n][0], indices[n].charges) np.testing.assert_allclose(arr3.shape, Ds) np.testing.assert_allclose(arr3._order, [[0], [1], [2], [3]]) np.testing.assert_allclose(arr3.flows, [[False], [False], [False], [False]]) assert arr3.ndim == 4
def test_outer_product(R1, R2, dtype, num_charges): np.random.seed(10) backend = symmetric_backend.SymmetricBackend() a = get_tensor(R1, num_charges, dtype) b = get_tensor(R2, num_charges, dtype) actual = backend.outer_product(a, b) expected = tensordot(a, b, 0) np.testing.assert_allclose(expected.data, actual.data) assert np.all([ charge_equal(expected._charges[n], actual._charges[n]) for n in range(len(actual._charges)) ])
def test_transpose(R, dtype, num_charges): np.random.seed(10) backend = symmetric_backend.SymmetricBackend() a = get_tensor(R, num_charges, dtype) order = np.arange(R) np.random.shuffle(order) actual = backend.transpose(a, order) expected = transpose(a, order) np.testing.assert_allclose(expected.data, actual.data) assert np.all([ charge_equal(expected._charges[n], actual._charges[n]) for n in range(len(actual._charges)) ])
def test_eye(dtype, num_charges): np.random.seed(10) backend = symmetric_backend.SymmetricBackend() index = Index( BaseCharge(np.random.randint(-5, 6, (num_charges, 100)), charge_types=[U1Charge] * num_charges), False) actual = backend.eye(index, dtype=dtype) expected = eye(index, dtype=dtype) np.testing.assert_allclose(expected.data, actual.data) assert np.all([ charge_equal(expected._charges[n], actual._charges[n]) for n in range(len(actual._charges)) ])
def test_diag(dtype, num_charges): np.random.seed(10) backend = symmetric_backend.SymmetricBackend() a = get_tensor(3, num_charges, dtype) with pytest.raises(ValueError): backend.diag(a) b = get_chargearray(num_charges, dtype) expected = diag(b) actual = backend.diag(b) np.testing.assert_allclose(expected.data, actual.data) assert np.all([ charge_equal(expected._charges[n], actual._charges[n]) for n in range(len(actual._charges)) ])
def test_ChargeArray_reshape(dtype, Ds, chargetype): flat_Ds = sum(Ds, []) R = len(flat_Ds) indices = [ Index(get_charge(chargetype, 1, flat_Ds[n]), False) for n in range(R) ] arr = ChargeArray.random(indices, dtype=dtype) ds = [np.prod(D) for D in Ds] arr2 = arr.reshape(ds) cnt = 0 for n in range(arr2.ndim): for m in range(len(arr2.charges[n])): assert charge_equal(arr2.charges[n][m], indices[cnt].charges) cnt += 1 order = [] flows = [] start = 0 for D in Ds: order.append(list(range(start, start + len(D)))) start += len(D) flows.append([False] * len(D)) np.testing.assert_allclose(arr2.shape, ds) for n in range(len(arr2._order)): np.testing.assert_allclose(arr2._order[n], order[n]) np.testing.assert_allclose(arr2.flows[n], flows[n]) assert arr2.ndim == len(Ds) arr3 = arr.reshape(flat_Ds) for n in range(len(Ds)): assert charge_equal(arr3.charges[n][0], indices[n].charges) np.testing.assert_allclose(arr3.shape, flat_Ds) np.testing.assert_allclose(arr3._order, [[n] for n in range(len(flat_Ds))]) np.testing.assert_allclose(arr3.flows, [[False] for n in range(len(flat_Ds))]) assert arr3.ndim == len(flat_Ds)
def test_ChargeArray_reshape_with_index(dtype, chargetype): Ds = [8, 9, 10, 11] R = len(Ds) indices = [ Index(get_charge(chargetype, 1, Ds[n]), False) for n in range(R) ] arr = ChargeArray.random(indices, dtype=dtype) arr2 = arr.reshape([indices[0] * indices[1], indices[2] * indices[3]]) cnt = 0 for n in range(arr2.ndim): for m in range(len(arr2.charges[n])): assert charge_equal(arr2.charges[n][m], indices[cnt].charges) cnt += 1 np.testing.assert_allclose(arr2.shape, [72, 110]) assert arr2.ndim == 2
def test_BlockSparseTensor_zeros(dtype, num_charges, chargetype): np.random.seed(10) Ds = [8, 9, 10, 11] rank = 4 flows = np.random.choice([True, False], size=rank, replace=True) indices = [ Index(get_charge(chargetype, num_charges, Ds[n]), flows[n]) for n in range(rank) ] arr = BlockSparseTensor.zeros(indices, dtype=dtype) np.testing.assert_allclose(arr.data, 0) np.testing.assert_allclose(Ds, arr.shape) np.testing.assert_allclose(arr.flat_flows, flows) for n in range(4): assert charge_equal(arr.charges[n][0], indices[n].flat_charges[0])
def test_flat_meta_data(): i1 = Index([U1Charge.random(-2, 2, 20), U1Charge.random(-2, 2, 20)], flow=[True, False]) i2 = Index([U1Charge.random(-2, 2, 20), U1Charge.random(-2, 2, 20)], flow=[False, True]) expected_charges = [ i1._charges[0], i1._charges[1], i2._charges[0], i2._charges[1] ] expected_flows = [True, False, False, True] charges, flows = get_flat_meta_data([i1, i2]) np.testing.assert_allclose(flows, expected_flows) for n, c in enumerate(charges): assert charge_equal(c, expected_charges[n])
def test_zeros(R, dtype, num_charges): np.random.seed(10) backend = symmetric_backend.SymmetricBackend() indices = [ Index( BaseCharge(np.random.randint(-5, 6, (10, num_charges)), charge_types=[U1Charge] * num_charges), False) for _ in range(R) ] actual = backend.zeros(indices, dtype=dtype) expected = zeros(indices, dtype=dtype) np.testing.assert_allclose(expected.data, actual.data) assert np.all([ charge_equal(expected._charges[n], actual._charges[n]) for n in range(len(actual._charges)) ])
def test_tn_randn(dtype, num_charges): np.random.seed(10) Ds = [8, 9, 10, 11] rank = 4 flows = np.random.choice([True, False], size=rank, replace=True) indices = [ Index( BaseCharge(np.random.randint(-5, 6, (num_charges, Ds[n])), charge_types=[U1Charge] * num_charges), flows[n]) for n in range(rank) ] arr = randn(indices, dtype=dtype) np.testing.assert_allclose(Ds, arr.shape) np.testing.assert_allclose(arr.flat_flows, flows) for n in range(4): assert charge_equal(arr.charges[n][0], indices[n].flat_charges[0])
def test_random_uniform_seed(dtype, num_charges): np.random.seed(10) R = 4 backend = symmetric_backend.SymmetricBackend() indices = [ Index( BaseCharge(np.random.randint(-5, 6, (num_charges, 10)), charge_types=[U1Charge] * num_charges), False) for _ in range(R) ] a = backend.random_uniform(indices, dtype=dtype, seed=10) b = backend.random_uniform(indices, dtype=dtype, seed=10) np.testing.assert_allclose(a.data, b.data) assert np.all([ charge_equal(a._charges[n], b._charges[n]) for n in range(len(a._charges)) ])