def test_MPO_hermitian(): s = spin_half ot = OnsiteTerms(4) ct = CouplingTerms(4) ct.add_coupling_term(1., 2, 3, 'Sm', 'Sp') H = mpo.MPOGraph.from_terms(ot, ct, [s] * 4, 'infinite').build_MPO() # assert not H.is_hermitian() ct.add_coupling_term(1., 2, 3, 'Sp', 'Sm') H = mpo.MPOGraph.from_terms(ot, ct, [s] * 4, 'infinite').build_MPO() # assert H.is_hermitian() ct.add_coupling_term(1., 3, 18, 'Sm', 'Sp') H = mpo.MPOGraph.from_terms(ot, ct, [s] * 4, 'infinite').build_MPO() assert not H.is_hermitian() ct.add_coupling_term(1., 3, 18, 'Sp', 'Sm') H = mpo.MPOGraph.from_terms(ot, ct, [s] * 4, 'infinite').build_MPO() assert H.is_hermitian()
def test_MPO_expectation_value(): s = spin_half psi1 = mps.MPS.from_singlets(s, 6, [(1, 3), (2, 5)], lonely=[0, 4], bc='infinite') psi1.test_sanity() ot = OnsiteTerms(4) ot.add_onsite_term(0.1, 0, 'Sz') # -> 0.5 ot.add_onsite_term(0.2, 3, 'Sz') # -> 0. ct = CouplingTerms(4) # note: ct.L != psi1.L ct.add_coupling_term(1., 2, 3, 'Sz', 'Sz') # -> 0. ct.add_coupling_term(1.5, 1, 3, 'Sz', 'Sz') # -> 1.5*(-0.25) ct.add_coupling_term(2.5, 0, 6, 'Sz', 'Sz') # -> 2.5*0.25 H = mpo.MPOGraph.from_terms(ot, ct, [s] * 4, 'infinite').build_MPO() ev = H.expectation_value(psi1) desired_ev = (0.1 * 0.5 + 0.2 * 0. + 1. * 0. + 1.5 * -0.25 + 2.5 * 0.25) / H.L assert abs(ev - desired_ev) < 1.e-8 grid = [[s.Id, s.Sz, 3 * s.Sz], [None, 0.1 * s.Id, s.Sz], [None, None, s.Id]] L = 1 exp_dec_H = mpo.MPO.from_grids([s] * L, [grid] * L, bc='infinite', IdL=0, IdR=2) ev = exp_dec_H.expectation_value(psi1) desired_ev = 3 * 0.5 + 0.25 * 0.1**(4 - 1) + 0.25 * 0.1**(6 - 1) + 0.25 * 0.1**( 10 - 1) # values > 1.e-15 assert abs(ev - desired_ev) < 1.e-15 L = 3 exp_dec_H = mpo.MPO.from_grids([s] * L, [grid] * L, bc='infinite', IdL=0, IdR=2) ev = exp_dec_H.expectation_value(psi1) desired_ev = ( desired_ev + # first site 3 * 0. - 0.25 * 0.1**(3 - 1 - 1) + # second site 3 * 0. - 0.25 * 0.1**(5 - 2 - 1)) / 3. print("ev = ", ev, "desired", desired_ev) assert abs(ev - desired_ev) < 1.e-14
def test_coupling_terms(): L = 4 sites = [] for i in range(L): s = site.Site(spin_half.leg) s.add_op("X_{i:d}".format(i=i), 2. * np.eye(2)) s.add_op("Y_{i:d}".format(i=i), 3. * np.eye(2)) sites.append(s) strength1 = np.arange(0., 5)[:, np.newaxis] + np.arange( 0., 0.625, 0.125)[np.newaxis, :] c1 = CouplingTerms(L) for i, j in [(2, 3)]: c1.add_coupling_term(strength1[i, j], i, j, "X_{i:d}".format(i=i), "Y_{j:d}".format(j=j)) assert c1.max_range() == 3 - 2 for i, j in [(0, 1), (0, 3), (0, 2)]: c1.add_coupling_term(strength1[i, j], i, j, "X_{i:d}".format(i=i), "Y_{j:d}".format(j=j)) c1_des = {0: {('X_0', 'Id'): {1: {'Y_1': 0.125}, 2: {'Y_2': 0.25}, 3: {'Y_3': 0.375}}}, 2: {('X_2', 'Id'): {3: {'Y_3': 2.375}}}} # yapf: disable assert c1.coupling_terms == c1_des c1._test_terms(sites) assert c1.max_range() == 3 - 0 tl1 = c1.to_TermList() term_list_des = [[('X_0', 0), ('Y_1', 1)], [('X_0', 0), ('Y_2', 2)], [('X_0', 0), ('Y_3', 3)], [('X_2', 2), ('Y_3', 3)]] assert tl1.terms == term_list_des assert np.all(tl1.strength == [0.125, 0.25, 0.375, 2.375]) ot1, ct1_conv = tl1.to_OnsiteTerms_CouplingTerms(sites) assert ot1.onsite_terms == [{}] * L assert ct1_conv.coupling_terms == c1_des mc = MultiCouplingTerms(L) for i, j in [(2, 3)]: # exact same terms as c1 mc.add_coupling_term(strength1[i, j], i, j, "X_{i:d}".format(i=i), "Y_{j:d}".format(j=j)) assert mc.max_range() == 3 - 2 for i, j in [(0, 1), (0, 3), (0, 2)]: # exact same terms as c1 mc.add_coupling_term(strength1[i, j], i, j, "X_{i:d}".format(i=i), "Y_{j:d}".format(j=j)) assert mc.coupling_terms == c1_des assert mc.max_range() == 3 - 0 mc.add_multi_coupling_term(20., [0, 1, 3], ['X_0', 'Y_1', 'Y_3'], ['Id', 'Id']) mc.add_multi_coupling_term(30., [0, 1, 3], ['X_0', 'Y_1', 'Y_3'], ['S1', 'S2']) mc.add_multi_coupling_term(40., [1, 2, 3], ['X_1', 'Y_2', 'Y_3'], ['Id', 'Id']) mc_des = {0: {('X_0', 'Id'): {1: {'Y_1': 0.125, ('Y_1', 'Id'): {3: {'Y_3': 20.0}}}, 2: {'Y_2': 0.25}, 3: {'Y_3': 0.375}}, ('X_0', 'S1'): {1: {('Y_1', 'S2'): {3: {'Y_3': 30.0}}}}}, 1: {('X_1', 'Id'): {2: {('Y_2', 'Id'): {3: {'Y_3': 40.0}}}}}, 2: {('X_2', 'Id'): {3: {'Y_3': 2.375}}}} # yapf: disable assert mc.coupling_terms == mc_des mc._test_terms(sites) # convert to TermList tl_mc = mc.to_TermList() term_list_des = [ [('X_0', 0), ('Y_1', 1)], [('X_0', 0), ('Y_1', 1), ('Y_3', 3)], [('X_0', 0), ('Y_2', 2)], [('X_0', 0), ('Y_3', 3)], [('X_0', 0), ('Y_1', 1), ('Y_3', 3)], # (!) droppend S1, S2 (!) [('X_1', 1), ('Y_2', 2), ('Y_3', 3)], [('X_2', 2), ('Y_3', 3)] ] assert tl_mc.terms == term_list_des assert np.all(tl_mc.strength == [0.125, 20., 0.25, 0.375, 30., 40., 2.375]) ot, mc_conv = tl_mc.to_OnsiteTerms_CouplingTerms(sites) assert ot1.onsite_terms == [{}] * L del (mc_des[0])[('X_0', 'S1')] # conversion dropped the opstring names mc_des[0][('X_0', 'Id')][1][('Y_1', 'Id')][3]['Y_3'] += 30. # add it to other term assert mc_conv.coupling_terms == mc_des # addition c2 = CouplingTerms(L) for i, j in [(0, 1), (1, 2)]: c1.add_coupling_term(strength1[i, j], i, j, "X_{i:d}".format(i=i), "Y_{j:d}".format(j=j)) c1 += c2 c1_des = {0: {('X_0', 'Id'): {1: {'Y_1': 0.25}, 2: {'Y_2': 0.25}, 3: {'Y_3': 0.375}}}, 1: {('X_1', 'Id'): {2: {'Y_2': 1.25}}}, 2: {('X_2', 'Id'): {3: {'Y_3': 2.375}}}} # yapf: disable assert c1.coupling_terms == c1_des c1._test_terms(sites) mc += c1 mc_des = {0: {('X_0', 'Id'): {1: {'Y_1': 0.375, ('Y_1', 'Id'): {3: {'Y_3': 20.0}}}, 2: {'Y_2': 0.5}, 3: {'Y_3': 0.75}}, ('X_0', 'S1'): {1: {('Y_1', 'S2'): {3: {'Y_3': 30.0}}}}}, 1: {('X_1', 'Id'): {2: {'Y_2': 1.25, ('Y_2', 'Id'): {3: {'Y_3': 40.0}}}}}, 2: {('X_2', 'Id'): {3: {'Y_3': 4.75}}}} # yapf: disable assert mc.coupling_terms == mc_des # coupling accross mps boundary mc.add_multi_coupling_term(50., [1, 3, 5], ['X_1', 'Y_3', 'Y_1'], ['STR', 'JW']) assert mc.max_range() == 5 - 1 mc._test_terms(sites) # remove the last coupling again mc.add_multi_coupling_term(-50., [1, 3, 5], ['X_1', 'Y_3', 'Y_1'], ['STR', 'JW']) mc.remove_zeros() assert mc.coupling_terms == mc_des assert mc.max_range() == 3 - 0
def test_MPO_expectation_value(tol=1.e-15): s = spin_half psi1 = mps.MPS.from_singlets(s, 6, [(1, 3), (2, 5)], lonely=[0, 4], bc='infinite') psi1.test_sanity() ot = OnsiteTerms(4) # H.L != psi.L, consider L = lcm(4, 6) = 12 ot.add_onsite_term(0.1, 0, 'Sz') # -> 0.5 * 2 (sites 0, 4, not 8) ot.add_onsite_term(0.2, 3, 'Sz') # -> 0. (not sites 4, 7, 11) ct = CouplingTerms(4) # note: ct.L != psi1.L ct.add_coupling_term(1., 2, 3, 'Sz', 'Sz') # -> 0. (not 2-3, 6-7, 10-11) ct.add_coupling_term(1.5, 1, 3, 'Sz', 'Sz') # -> 1.5*(-0.25) (1-3, not 5-7, not 9-11) ct.add_coupling_term(2.5, 0, 6, 'Sz', 'Sz') # -> 2.5*0.25*3 (0-6, 4-10, not 8-14) H = mpo.MPOGraph.from_terms((ot, ct), [s] * 4, 'infinite').build_MPO() desired_ev = (0.1 * 0.5 * 2 + 0.2 * 0. + 1. * 0. + 1.5 * -0.25 + 2.5 * 0.25 * 2) / 12 ev_power = H.expectation_value_power(psi1, tol=tol) assert abs(ev_power - desired_ev) < tol ev_TM = H.expectation_value_TM(psi1, tol=tol) assert abs(ev_TM - desired_ev) < tol ev = H.expectation_value(psi1, tol) assert abs(ev - desired_ev) < tol # now with exponentially decaying term grid = [ [s.Id, s.Sz, 3 * s.Sz], [None, 0.1 * s.Id, s.Sz], [None, None, s.Id], ] L = 1 exp_dec_H = mpo.MPO.from_grids([s] * L, [grid] * L, bc='infinite', IdL=0, IdR=2) desired_ev = ( 3 * 0.5 * 2 + # Sz onsite 0.25 * ( 0.1**3 + 0.1**5 + 0.1**9 + 0.1**11 + 0.1**15 + # Z_0 Z_i 0.1**1 + 0.1**5 + 0.1**7 + 0.1**11 + 0.1**13) + # Z_4 Z_i -0.25 * ( 0.1**1 + # Z_1 Z_3 0.1**2) # Z_2 Z_4 + 0. # other sites ) / 6. # values > 1.e-15 ev_power = exp_dec_H.expectation_value_power(psi1, tol=tol) ev_TM = exp_dec_H.expectation_value_TM(psi1, tol=tol) assert abs(ev_power - desired_ev) < tol assert abs(ev_TM - desired_ev) < tol ev = exp_dec_H.expectation_value(psi1, tol=tol) assert abs(ev - desired_ev) < tol L = 3 # should give exactly the same answer! exp_dec_H = mpo.MPO.from_grids([s] * L, [grid] * L, bc='infinite', IdL=0, IdR=2) ev_power = exp_dec_H.expectation_value_power(psi1, tol=tol) ev_TM = exp_dec_H.expectation_value_TM(psi1, tol=tol) assert abs(ev_power - desired_ev) < tol assert abs(ev_TM - desired_ev) < tol ev = exp_dec_H.expectation_value(psi1, tol=tol) assert abs(ev - desired_ev) < tol
def test_MPO_addition(): for bc in ['infinite', 'finite']: print('bc = ', bc, '-' * 40) s = spin_half ot1 = OnsiteTerms(4) ct1 = CouplingTerms(4) ct1.add_coupling_term(2., 2, 3, 'Sm', 'Sp') ct1.add_coupling_term(2., 2, 3, 'Sp', 'Sm') ct1.add_coupling_term(2., 1, 2, 'Sz', 'Sz') ot1.add_onsite_term(3., 1, 'Sz') H1 = mpo.MPOGraph.from_terms((ot1, ct1), [s] * 4, bc).build_MPO() ot2 = OnsiteTerms(4) ct2 = CouplingTerms(4) ct2.add_coupling_term(4., 0, 2, 'Sz', 'Sz') ct2.add_coupling_term(4., 1, 2, 'Sz', 'Sz') ot2.add_onsite_term(5., 1, 'Sz') H2 = mpo.MPOGraph.from_terms((ot2, ct2), [s] * 4, bc).build_MPO() H12_sum = H1 + H2 ot12 = OnsiteTerms(4) ot12 += ot1 ot12 += ot2 ct12 = CouplingTerms(4) ct12 += ct1 ct12 += ct2 H12 = mpo.MPOGraph.from_terms((ot12, ct12), [s] * 4, bc).build_MPO() assert H12.is_equal(H12_sum)