def test_TensorNetwork_init_checks(self): a = rand_tensor((2, 3, 4), inds=[0, 1, 2], tags={'red'}) b = rand_tensor((3, 4, 5), inds=[1, 2, 3], tags={'blue'}) c = rand_tensor((3, 4, 5), inds=[1, 2, 3], tags={'blue', 'c'}) with pytest.raises(TypeError): TensorNetwork(a, b) # missing brackets around ``a, b``. tn = a & b with pytest.raises(TypeError): tn['red'] = 1 tn.add_tag('foo') assert len(tn['foo']) == 2 with pytest.raises(KeyError): tn['foo'] = c tn[('foo', 'blue')] = c assert 'c' in tn.tags assert tn[('blue', 'c')] is c assert 'red' in tn.tags del tn['red'] assert 'red' not in tn.tags assert set(tn.tag_map.keys()) == {'blue', 'c'} tn.drop_tags('c') assert set(tn.tag_map.keys()) == {'blue'} tn.drop_tags(['blue']) assert set(tn.tag_map.keys()) == set()
def test_retagging(self): x = rand_tensor((2, 4), inds='ab', tags={'X', 'I0'}) y = rand_tensor((4, 2, 5), inds='bcd', tags={'Y', 'I1'}) z = rand_tensor((5, 3), inds='de', tags={'Z', 'I2'}) tn = TensorNetwork((x, y, z)) tn.retag_({"I0": "I1", "I1": "I2", "I2": "I3", "Z": "A"}) assert set(tn.tag_map.keys()) == {'X', 'I1', 'I2', 'I3', 'Y', 'A'}
def test_multiply(self): a = rand_tensor((2, 3, 4), inds=['0', '1', '2'], tags='red') b = rand_tensor((3, 4, 5), inds=['1', '2', '3'], tags='blue') c = rand_tensor((5, 2, 6), inds=['3', '0', '4'], tags='blue') tn = a & b & c x1 = (tn & tn.H) ^ ... x2 = ((2 * tn) & tn.H) ^ ... assert_allclose(2 * x1, x2)
def test_fuse_multibonds(self): x = rand_tensor((2, 2, 2), ['a', 'b', 'c']) y = rand_tensor((2, 2, 2, 2), ['b', 'c', 'd', 'e']) z = rand_tensor((2, 2, 2), ['a', 'e', 'd']) tn = (x & y & z) assert len(tn.inner_inds()) == 5 tn.fuse_multibonds(inplace=True) assert len(tn.inner_inds()) == 3
def test_divide(self): a = rand_tensor((2, 3, 4), inds=['0', '1', '2'], tags='red') b = rand_tensor((3, 4, 5), inds=['1', '2', '3'], tags='blue') c = rand_tensor((5, 2, 6), inds=['3', '0', '4'], tags='blue') tn = a & b & c x1 = (tn & tn.H) ^ ... x2 = ((tn / 2) & tn.H) ^ ... assert_allclose(x1 / 2, x2)
def test_column_reduce(self): A = rand_tensor([2, 3], 'ab') A.new_ind('c', size=4) B = rand_tensor([4, 5, 6], 'cde') tn = A & B assert tn.num_indices == 5 tn_s = tn.column_reduce() assert tn_s.num_indices == 4 assert (tn ^ all).almost_equals(tn_s ^ all)
def test_diagonal_reduce(self): A = rand_tensor([2, 2], 'ab', dtype=complex) B = Tensor([[3j, 0.], [0., 4j]], 'bc') C = rand_tensor([2, 2], 'ca', dtype=complex) tn = A & B & C tn_s = tn.diagonal_reduce() assert tn.num_indices == 3 assert tn_s.num_indices == 2 assert tn ^ all == pytest.approx(tn_s.contract(all, output_inds=[]))
def test_rand_tensor(self, dtype): if dtype == 'raise': with pytest.raises(TypeError): rand_tensor((2, 3, 4), 'abc', dtype=dtype) else: t = rand_tensor((2, 3, 4), 'abc', dtype=dtype) assert t.dtype == dtype tn = t & t assert tn.dtype == dtype
def test_direct_product(self): a1 = rand_tensor((2, 3, 4), inds='abc') b1 = rand_tensor((3, 4, 5), inds='bcd') a2 = rand_tensor((2, 3, 4), inds='abc') b2 = rand_tensor((3, 4, 5), inds='bcd') c1 = (a1 @ b1) + (a2 @ b2) c2 = (tensor_direct_product(a1, a2, sum_inds=('a')) @ tensor_direct_product(b1, b2, sum_inds=('d'))) assert c1.almost_equals(c2)
def test_compress_between(self, backend): A = rand_tensor((3, 4, 5), 'abd', tags={'T1'}) tensor_direct_product(A, A, inplace=True) B = rand_tensor((5, 6), 'dc', tags={'T2'}) tensor_direct_product(B, B, inplace=True) tn = A & B assert A.shared_bond_size(B) == 10 tn.compress_between('T1', 'T2', backend=backend)
def test_replace_with_identity(self): A, B, C, D = (rand_tensor((2, 3, 4), 'abc', tags=['I0']), rand_tensor((4, 5, 6), 'cde', tags=['I1']), rand_tensor((5, 6, 7), 'def', tags=['I2']), rand_tensor((7, ), 'f', tags=['I3'])) tn = (A & B & C & D) with pytest.raises(ValueError): tn.replace_with_identity(('I1', 'I2'), inplace=True) tn['I2'] = rand_tensor((5, 6, 4), 'def', tags=['I2']) tn['I3'] = rand_tensor((4, ), 'f', tags=['I3']) tn1 = tn.replace_with_identity(('I1', 'I2')) assert len(tn1.tensors) == 2 x = tn1 ^ ... assert set(x.inds) == {'a', 'b'} A, B, C = (rand_tensor( (2, 2), 'ab', tags={'0'}), rand_tensor( (2, 2), 'bc', tags={'1'}), rand_tensor((2, 3), 'cd', tags={'2'})) tn = A & B & C tn2 = tn.replace_with_identity('1') assert len(tn2.tensors) == 2 x = tn2 ^ ... assert set(x.inds) == {'a', 'd'}
def test_add_tag(self): a = rand_tensor((2, 3, 4), inds='abc', tags={'red'}) b = rand_tensor((2, 3, 4), inds='abc', tags={'blue'}) tn = a & b tn.add_tag('green') assert 'green' in tn.tag_map assert 'green' in tn['red'].tags assert 'green' in tn['blue'].tags tn.add_tag('blue') for t in tn: assert 'blue' in t.tags
def test_rank_simplify(self): A = rand_tensor([2, 2, 3], 'abc', tags='A') B = rand_tensor([3, 2], 'cd', tags='B') C = rand_tensor([2, 2, 2], 'def', tags='C') tn = A & B & C tn_s = tn.rank_simplify() assert tn.num_tensors == 3 assert tn_s.num_tensors == 2 assert (tn ^ all).almost_equals(tn_s ^ all) # checl that 'B' was absorbed into 'A' not 'C' assert tn_s['B'].tags == {'A', 'B'}
def test_contract_with_slices(self): a = rand_tensor((2, 3, 4), inds=[0, 1, 2], tags='I0') b = rand_tensor((3, 4, 5), inds=[1, 2, 3], tags='I1') c = rand_tensor((5, 2, 6), inds=[3, 0, 4], tags='I2') d = rand_tensor((5, 2, 6), inds=[5, 6, 4], tags='I3') tn = TensorNetwork((a, b, c, d), structure="I{}") assert len((tn ^ slice(2)).tensors) == 3 assert len((tn ^ slice(..., 1, -1)).tensors) == 3 assert len((tn ^ slice(-1, 1)).tensors) == 3 assert len((tn ^ slice(None, -2, -1)).tensors) == 3 assert len((tn ^ slice(-2, 0)).tensors) == 3
def test_copy_deep(self): a = rand_tensor((2, 3, 4), inds='abc', tags='t0') b = rand_tensor((2, 3, 4), inds='abd', tags='t1') tn1 = TensorNetwork((a, b)) tn2 = tn1.copy(deep=True) # check can modify tensor structure tn2['t1'].modify(inds=('a', 'b', 'X')) assert tn1['t1'] is not tn2['t1'] assert tn2['t1'].inds == ('a', 'b', 'X') assert tn1['t1'].inds == ('a', 'b', 'd') # and that data is not the same assert tn1['t1'].data is not tn2['t1'].data tn2['t1'].data[:] /= 2 assert_allclose(tn1['t1'].data / 2, tn2['t1'].data)
def test_copy(self): a = rand_tensor((2, 3, 4), inds='abc', tags='t0') b = rand_tensor((2, 3, 4), inds='abd', tags='t1') tn1 = TensorNetwork((a, b)) tn2 = tn1.copy() # check can modify tensor structure tn2['t1'].inds = ('a', 'b', 'X') assert tn1['t1'] is not tn2['t1'] assert tn2['t1'].inds == ('a', 'b', 'X') assert tn1['t1'].inds == ('a', 'b', 'd') # but that data remains the same assert tn1['t1'].data is tn2['t1'].data tn2['t1'].data /= 2 assert_allclose(tn1['t1'].data, tn2['t1'].data)
def test_antidiag_gauge(self): A = rand_tensor([2, 2], 'ab', dtype=complex) B = Tensor([[0., 3j], [4j, 0.]], 'bc') C = rand_tensor([2, 2], 'ca', dtype=complex) tn = A & B & C assert tn.num_indices == 3 # can't use diagonal reduction yet assert tn.diagonal_reduce().num_indices == 3 # initial gauge doesn't change indices tn_a = tn.antidiag_gauge() assert tn_a.num_indices == 3 # but allows the diagonal reduction tn_ad = tn_a.diagonal_reduce() assert tn_ad.num_indices == 2 assert tn ^ all == pytest.approx(tn_ad.contract(all, output_inds=[]))
def test_connect(self): x = rand_tensor((2, 3), 'ab') y = rand_tensor((3, 2), 'cd') with pytest.raises(ValueError): qtn.connect(x, y, 0, 0) tn = x | y assert len(tn.outer_inds()) == 4 qtn.connect(x, y, 0, 1) assert len(tn.outer_inds()) == 2 qtn.connect(x, y, 1, 0) assert len(tn.outer_inds()) == 0 assert (tn ^ all).shape == () # make sure bond is newly labelled assert set('abcd') & set(tn.all_inds()) == set()
def test_against_dense(self): A, B, C, D = ( rand_tensor([3, 5, 5], 'aef'), rand_tensor([3, 5, 5], 'beg'), rand_tensor([3, 5, 5], 'cfh'), rand_tensor([3, 5, 5], 'dhg'), ) tn = A & B & C & D tn_lo = tn.aslinearoperator(('a', 'b'), ('c', 'd')) tn_d = (tn ^ ...).fuse([('u', ['a', 'b']), ('l', ['c', 'd'])]).data u, s, v = svds(tn_lo, k=5, backend='scipy') ud, sd, vd = svds(tn_d, k=5, backend='scipy') assert_allclose(s, sd)
def test_squeeze(self): a = rand_tensor((1, 2, 3, 1, 4), inds='abcde', tags=['hello']) b = a.squeeze() assert b.shape == (2, 3, 4) assert b.inds == ('b', 'c', 'e') assert 'hello' in b.tags assert a.shape == (1, 2, 3, 1, 4)
def test_select_tensors_mode(self): A, B, C = (rand_tensor((2, 2), 'ab', tags={'0', 'X'}), rand_tensor((2, 2), 'bc', tags={'1', 'X', 'Y'}), rand_tensor((2, 3), 'cd', tags={'2', 'Y'})) tn = A & B & C ts = tn.select_tensors(('X', 'Y'), which='all') assert len(ts) == 1 assert not any(map(A.almost_equals, ts)) assert any(map(B.almost_equals, ts)) assert not any(map(C.almost_equals, ts)) ts = tn.select_tensors(('X', 'Y'), which='any') assert len(ts) == 3 assert any(map(A.almost_equals, ts)) assert any(map(B.almost_equals, ts)) assert any(map(C.almost_equals, ts))
def test_tensors_sorted(self): tn1, tn2 = TensorNetwork([]), TensorNetwork([]) A, B, C = (rand_tensor((1, 2, 3), 'abc', tags=['I0']), rand_tensor((2, 3, 4), 'bcd', tags=['I1']), rand_tensor((4, 1, 1), 'dae', tags=['I2'])) tn1 &= A tn1 &= B tn1 &= C tn2 &= C tn2 &= A tn2 &= B for t1, t2 in zip(tn1.tensors_sorted(), tn2.tensors_sorted()): assert t1.tags == t2.tags assert t1.almost_equals(t2)
def test_multiply_spread(self): a = rand_tensor([2, 2], inds=['a', 'b'], tags='A') b = Tensor(a.data, ['b', 'c'], tags='B') c = Tensor(a.data, ['c', 'd'], tags='C') tn = (a | b | c) tn.multiply_(-8j + 1 / 3, spread_over=3) assert_allclose(tn['A'].data, tn['B'].data) assert_allclose(tn['B'].data, tn['C'].data)
def test_combining_tensors(self): a = rand_tensor((2, 3, 4), inds=[0, 1, 2], tags='red') b = rand_tensor((3, 4, 5), inds=[1, 2, 3], tags='blue') c = rand_tensor((5, 2, 6), inds=[3, 0, 4], tags='blue') with pytest.raises(TypeError): a & np.array([0, 0]) abc1 = (a & b & c).H.contract() abc2 = (a & (b & c)).H.contract() abc3 = (TensorNetwork([a, b, c])).H.contract() abc4 = (TensorNetwork([a, TensorNetwork([b, c])])).H.contract() abc5 = (TensorNetwork([a]) & TensorNetwork([b, c])).H.contract() assert_allclose(abc1.data, abc2.data) assert_allclose(abc1.data, abc3.data) assert_allclose(abc1.data, abc4.data) assert_allclose(abc1.data, abc5.data)
def test_multiply_spread_neg_stays_real(self): a = rand_tensor([2, 2], inds=['a', 'b'], tags='A', dtype='float32') b = Tensor(a.data, ['b', 'c'], tags='B') c = Tensor(a.data, ['c', 'd'], tags='C') tn = (a | b | c) tn.multiply_(-1000) assert a.dtype == b.dtype == c.dtype == 'float32' assert_allclose(abs(tn['A'].data), abs(tn['B'].data)) assert_allclose(abs(tn['B'].data), abs(tn['C'].data))
def test_squeeze(self): A, B, C = (rand_tensor((1, 2, 3), 'abc', tags=['I0']), rand_tensor((2, 3, 4), 'bcd', tags=['I1']), rand_tensor((4, 1, 1), 'dae', tags=['I2'])) tn = A & B & C x1 = tn ^ ... stn = tn.squeeze() assert tn['I0'].shape == (1, 2, 3) assert tn['I1'].shape == (2, 3, 4) assert tn['I2'].shape == (4, 1, 1) assert stn['I0'].shape == (2, 3) assert stn['I1'].shape == (2, 3, 4) assert stn['I2'].shape == (4, ) x2 = stn ^ ... assert_allclose(x1.data, x2) # x2 should be scalar already
def test_cumulative_contract(self): a = rand_tensor((2, 3, 4), inds=[0, 1, 2], tags='red') b = rand_tensor((3, 4, 5), inds=[1, 2, 3], tags='blue') c = rand_tensor((5, 2, 6), inds=[3, 0, 4], tags='green') d = (a & b & c) d2 = d.copy() cd = d >> ['red', 'green', 'blue'] assert cd.shape == (6, ) assert cd.inds == (4, ) # make sure inplace operations didn't effect original tensor for tag, names in d2.tag_map.items(): assert d.tag_map[tag] == names # test inplace d >>= ['red', 'green', 'blue'] assert isinstance(d, Tensor)
def test_against_dense(self): A, B, C, D = ( rand_tensor([3, 5, 5], 'aef'), rand_tensor([3, 5, 5], 'beg'), rand_tensor([3, 5, 5], 'cfh'), rand_tensor([3, 5, 5], 'dhg'), ) tn = A & B & C & D tn_lo = tn.aslinearoperator(('a', 'b'), ('c', 'd')) tn_d = tn.to_dense(['a', 'b'], ['c', 'd']) u, s, v = qu.svds(tn_lo, k=5, backend='scipy') ud, sd, vd = qu.svds(tn_d, k=5, backend='scipy') assert_allclose(s, sd) # test matmat X = np.random.randn(9, 8) + 1.0j * np.random.randn(9, 8) assert_allclose(tn_lo.dot(X), tn_d.dot(X))
def test_split_tensor_no_vals(self, method, linds): a = rand_tensor((2, 3, 4, 5, 6), inds='abcde', tags='red') a_split = a.split(linds, method=method) assert len(a_split.tensors) == 2 if linds == 'abd': assert ((a_split.shape == (2, 3, 5, 4, 6)) or (a_split.shape == (4, 6, 2, 3, 5))) elif linds == 'edc': assert ((a_split.shape == (6, 5, 4, 2, 3)) or (a_split.shape == (2, 3, 6, 5, 4))) assert (a_split ^ ...).almost_equals(a)
def test_contracting_tensors(self): a = rand_tensor((2, 3, 4), inds=[0, 1, 2], tags='red') b = rand_tensor((3, 4, 5), inds=[1, 2, 3], tags='blue') c = rand_tensor((5, 2, 6), inds=[3, 0, 4], tags='blue') a_b_c = a & b & c print(a_b_c) repr(a_b_c) assert isinstance(a_b_c, TensorNetwork) a_bc = a_b_c ^ 'blue' assert isinstance(a_bc, TensorNetwork) assert len(a_bc.tensors) == 2 abc = a_bc ^ ['red', 'blue'] assert isinstance(abc, Tensor) assert_allclose(abc.data, a_b_c.contract().data) assert len(a_b_c.tensors) == 3 a_b_c ^= 'blue' assert len(a_b_c.tensors) == 2