Example #1
0
def test_ED():
    # just quickly check that it runs without errors for a small system
    xxz_pars = dict(L=4, Jxx=1., Jz=1., hz=0.0, bc_MPS='finite')
    M = XXZChain(xxz_pars)
    ED = ExactDiag(M)
    ED.build_full_H_from_mpo()
    H, ED.full_H = ED.full_H, None
    ED.build_full_H_from_bonds()
    H2 = ED.full_H
    assert (npc.norm(H - H2, np.inf) < 1.e-14)
    ED.full_diagonalization()
    psi = ED.groundstate()
    print("select charge_sector =", psi.qtotal)
    ED2 = ExactDiag(M, psi.qtotal)
    ED2.build_full_H_from_mpo()
    ED2.full_diagonalization()
    psi2 = ED2.groundstate()
    full_psi2 = psi.zeros_like()
    full_psi2[ED2._mask] = psi2
    ov = npc.inner(psi, full_psi2, do_conj=True)
    print("overlab <psi | psi2> = 1. -", 1. - ov)
    assert (abs(abs(ov) - 1.) < 1.e-15)
    # starting from a random guess in the correct charge sector,
    # check if we can also do lanczos.
    np.random.seed(12345)
    psi3 = npc.Array.from_func(np.random.random,
                               psi2.legs,
                               qtotal=psi2.qtotal,
                               shape_kw='size')
    E0, psi3, N = lanczos(ED2, psi3)
    print("Lanczos E0 =", E0)
    ov = npc.inner(psi3, psi2, do_conj=True)
    print("overlab <psi2 | psi3> = 1. -", 1. - ov)
    assert (abs(abs(ov) - 1.) < 1.e-15)
Example #2
0
def example_exact_diagonalization(L, Jz):
    xxz_pars = dict(L=L, Jxx=1., Jz=Jz, hz=0.0, bc_MPS='finite')
    M = XXZChain(xxz_pars)

    product_state = ["up", "down"] * (xxz_pars['L'] // 2)  # this selects a charge sector!
    psi_DMRG = MPS.from_product_state(M.lat.mps_sites(), product_state)
    charge_sector = psi_DMRG.get_total_charge(True)  # ED charge sector should match

    ED = ExactDiag(M, charge_sector=charge_sector, max_size=2.e6)
    ED.build_full_H_from_mpo()
    # ED.build_full_H_from_bonds()  # whatever you prefer
    print("start diagonalization")
    ED.full_diagonalization()  # the expensive part for large L
    E0_ED, psi_ED = ED.groundstate()  # return the ground state
    print("psi_ED =", psi_ED)

    print("run DMRG")
    dmrg.run(psi_DMRG, M, {'verbose': 0})  # modifies psi_DMRG in place!
    # first way to compare ED with DMRG: convert MPS to ED vector
    psi_DMRG_full = ED.mps_to_full(psi_DMRG)
    print("psi_DMRG_full =", psi_DMRG_full)
    ov = npc.inner(psi_ED, psi_DMRG_full, axes='range', do_conj=True)
    print("<psi_ED|psi_DMRG_full> =", ov)
    assert (abs(abs(ov) - 1.) < 1.e-13)

    # second way: convert ED vector to MPS
    psi_ED_mps = ED.full_to_mps(psi_ED)
    ov2 = psi_ED_mps.overlap(psi_DMRG)
    print("<psi_ED_mps|psi_DMRG> =", ov2)
    assert (abs(abs(ov2) - 1.) < 1.e-13)
    assert (abs(ov - ov2) < 1.e-13)
    # -> advantage: expectation_value etc. of MPS are available!
    print("<Sz> =", psi_ED_mps.expectation_value('Sz'))
Example #3
0
def test_CouplingMPOModel_group():
    m1 = MyMod(dict(x=0.5, L=5, bc_MPS='finite'))
    model_params = {'L': 6, 'hz': np.random.random([6]), 'bc_MPS': 'finite'}
    m2 = XXZChain(model_params)
    for m in [m1, m2]:
        print("model = ", m)
        assert m.H_MPO.max_range == 1
        # test grouping sites
        ED = ExactDiag(m)
        #  ED.build_full_H_from_mpo()
        ED.build_full_H_from_bonds()
        m.group_sites(n=2)
        assert m.H_MPO.max_range == 1
        ED_gr = ExactDiag(m)
        ED_gr.build_full_H_from_mpo()
        H = ED.full_H.split_legs().to_ndarray()
        Hgr = ED_gr.full_H.split_legs()
        Hgr.idrop_labels()
        Hgr = Hgr.split_legs().to_ndarray()
        assert np.linalg.norm(H - Hgr) < 1.e-14
        ED_gr.full_H = None
        ED_gr.build_full_H_from_bonds()
        Hgr = ED_gr.full_H.split_legs()
        Hgr.idrop_labels()
        Hgr = Hgr.split_legs().to_ndarray()
        assert np.linalg.norm(H - Hgr) < 1.e-14
Example #4
0
def test_purification_TEBD(L=3):
    xxz_pars = dict(L=L, Jxx=1., Jz=3., hz=0., bc_MPS='finite')
    M = XXZChain(xxz_pars)
    for disent in [
            None, 'backwards', 'min(None,last)-renyi', 'noise-norm',
            'renyi-min(None,noise-renyi)'
    ]:
        psi = purification_mps.PurificationMPS.from_infiniteT(
            M.lat.mps_sites(), bc='finite')
        TEBD_params = {
            'trunc_params': {
                'chi_max': 16,
                'svd_min': 1.e-8
            },
            'disentangle': disent,
            'dt': 0.1,
            'verbose': 30,
            'N_steps': 2
        }
        eng = PurificationTEBD(psi, M, TEBD_params)
        eng.run()
        N = psi.expectation_value('Id')  # check normalization : <1> =?= 1
        npt.assert_array_almost_equal_nulp(N, np.ones([L]), 100)
        eng.run_imaginary(0.2)
        N = psi.expectation_value('Id')  # check normalization : <1> =?= 1
        npt.assert_array_almost_equal_nulp(N, np.ones([L]), 100)
        if disent == 'last-renyi':
            eng.run_imaginary(0.3)
            eng.disentangle_global()
Example #5
0
def test_purification_MPO(L=6):
    xxz_pars = dict(L=L, Jxx=1., Jz=2., hz=0., bc_MPS='finite')
    M = XXZChain(xxz_pars)
    psi = purification_mps.PurificationMPS.from_infiniteT(M.lat.mps_sites(),
                                                          bc='finite')
    options = {'trunc_params': {'chi_max': 50, 'svd_min': 1.e-8}}
    U = M.H_MPO.make_U_II(dt=0.1)
    PurificationApplyMPO(psi, U, options).run()
    N = psi.expectation_value('Id')  # check normalization : <1> =?= 1
    npt.assert_array_almost_equal_nulp(N, np.ones([L]), 100)
Example #6
0
def test_model_H_conversion(L=6):
    bc = 'finite'
    model_params = {'L': L, 'hz': np.random.random([L]), 'bc_MPS': bc}
    m = XXZChain(model_params)
    # can we run the conversion?
    # conversion from bond to MPO in NearestNeighborModel
    H_MPO = m.calc_H_MPO_from_bond()
    # conversion from MPO to bond in MPOModel
    H_bond = m.calc_H_bond_from_MPO()
    # compare: did we get the correct result?
    ED = ExactDiag(m)
    ED.build_full_H_from_bonds()
    H0 = ED.full_H  # this should be correct
    ED.full_H = None
    m.H_MPO = H_MPO
    ED.build_full_H_from_mpo()
    full_H_mpo = ED.full_H  # the one generated by NearstNeighborModel.calc_H_MPO_from_bond()
    print("npc.norm(H0 - full_H_mpo) = ", npc.norm(H0 - full_H_mpo))
    assert npc.norm(H0 -
                    full_H_mpo) < 1.e-14  # round off errors on order of 1.e-15
    m.H_bond = H_bond
    ED.full_H = None
    ED.build_full_H_from_bonds()
    full_H_bond = ED.full_H  # the one generated by NearstNeighborModel.calc_H_MPO_from_bond()
    print("npc.norm(H0 - full_H_bond) = ", npc.norm(H0 - full_H_bond))
    assert npc.norm(
        H0 - full_H_bond) < 1.e-14  # round off errors on order of 1.e-15
Example #7
0
def test_XXZChain_general(tol=1.e-14):
    check_general_model(XXZChain, dict(L=4, Jxx=1., hz=0., bc_MPS='finite'), {
        'Jz': [0., 1., 2.],
        'hz': [0., 0.2]
    })
    model_param = dict(L=3, Jxx=1., Jz=1.5, hz=0.25, bc_MPS='finite')
    m1 = XXZChain(model_param)
    m2 = XXZChain2(model_param)
    for Hb1, Hb2 in zip(m1.H_bond, m2.H_bond):
        if Hb1 is None:
            assert Hb2 is None
            continue
        assert npc.norm(Hb1 - Hb2) < tol
Example #8
0
def test_MPSEnvironment():
    xxz_pars = dict(L=4, Jxx=1., Jz=1.1, hz=0.1, bc_MPS='finite')
    L = xxz_pars['L']
    M = XXZChain(xxz_pars)
    state = ([0, 1] * L)[:L]  # Neel state
    psi = mps.MPS.from_product_state(M.lat.mps_sites(), state, bc='finite')
    env = mps.MPSEnvironment(psi, psi)
    env.get_LP(3, True)
    env.get_RP(0, True)
    env.test_sanity()
    for i in range(4):
        ov = env.full_contraction(i)  # should be one
        print("total contraction on site", i, ": ov = 1. - ", ov - 1.)
        assert (abs(abs(ov) - 1.) < 1.e-14)
    env.expectation_value('Sz')
Example #9
0
def test_MPOEnvironment():
    xxz_pars = dict(L=4, Jxx=1., Jz=1.1, hz=0.1, bc_MPS='finite')
    L = xxz_pars['L']
    M = XXZChain(xxz_pars)
    state = ([0, 1] * L)[:L]  # Neel
    psi = mps.MPS.from_product_state(M.lat.mps_sites(), state, bc='finite')
    env = mpo.MPOEnvironment(psi, M.H_MPO, psi)
    env.get_LP(3, True)
    env.get_RP(0, True)
    env.test_sanity()
    E_exact = -0.825
    for i in range(4):
        E = env.full_contraction(i)  # should be one
        print("total energy for contraction at site ", i, ": E =", E)
        assert (abs(E - E_exact) < 1.e-14)
Example #10
0
def test_renyi_disentangler(L=4, eps=1.e-15):
    xxz_pars = dict(L=L, Jxx=1., Jz=3., hz=0., bc_MPS='finite')
    M = XXZChain(xxz_pars)
    psi = purification_mps.PurificationMPS.from_infiniteT(M.lat.mps_sites(),
                                                          bc='finite')
    eng = PurificationTEBD(psi, M, {'verbose': 30, 'disentangle': 'renyi'})
    theta = eng.psi.get_theta(1, 2)
    print(theta[0, :, :, 0, :, :])
    # find random unitary: SVD of random matix
    pleg = psi.sites[0].leg
    pipe = npc.LegPipe([pleg, pleg])
    A = npc.Array.from_func_square(rmat.CUE, pipe).split_legs()
    A.iset_leg_labels(['p0', 'p1', 'p0*', 'p1*'])
    # Now we have unitary `A`, i.e. the optimal `U` should be `A^dagger`.
    theta = npc.tensordot(A, theta, axes=[['p0*', 'p1*'], ['p0', 'p1']])

    U0 = npc.outer(
        npc.eye_like(theta, 'q0').iset_leg_labels(['q0', 'q0*']),
        npc.eye_like(theta, 'q1').iset_leg_labels(['q1', 'q1*']))
    U = U0
    Sold = np.inf
    for i in range(20):
        S, U = eng.used_disentangler.iter(theta, U)
        if i == 0:
            S_0 = S
        print("iteration {i:d}: S={S:.5f}, DS={DS:.4e} ".format(i=i,
                                                                S=S,
                                                                DS=Sold - S))
        if abs(Sold - S) < eps:
            print("break: S converged down to {eps:.1e}".format(eps=eps))
            break
        Sold, S = S, Sold
    else:
        print("maximum number of iterations reached")
    theta = npc.tensordot(U, theta, axes=[['q0*', 'q1*'], ['q0', 'q1']])
    print("new theta = ")
    print(theta.itranspose(['vL', 'vR', 'p0', 'q0', 'p1', 'q1']))
    print(theta[0, 0])
    assert (S < S_0)  # this should always be true...
    if S > 100 * eps:
        print("final S =", S)
        warnings.warn("test of purification failed to find the optimum.")
Example #11
0
def test_canoncial_purification(L=6, charge_sector=0, eps=1.e-14):
    site = spin_half
    psi = purification_mps.PurificationMPS.from_infiniteT_canonical(
        [site] * L, [charge_sector])
    psi.test_sanity()
    total_psi = psi.get_theta(0, L).take_slice(0, 'vL').take_slice(0, 'vR')
    total_psi.itranspose(['p' + str(i) for i in range(L)] +
                         ['q' + str(i) for i in range(L)])
    # note: don't `combine_legs`: it will permute the p legs differently than q due to charges
    total_psi_dense = total_psi.to_ndarray().reshape(2**L, 2**L)
    # now it should be diagonal
    diag = np.diag(total_psi_dense)
    assert np.all(
        np.abs(total_psi_dense - np.diag(diag) < eps))  # is it diagonal?
    # and the diagonal should be sqrt(L choose L//2) for states with fitting numbers
    pref = 1. / scipy.special.comb(L, L // 2 + charge_sector)**0.5
    Q_p = site.leg.to_qflat()[:, 0]
    for i, entry in enumerate(diag):
        Q_i = sum([Q_p[int(b)] for b in format(i, 'b').zfill(L)])
        if Q_i == charge_sector:
            assert abs(entry - pref) < eps
        else:
            assert abs(entry) < eps

    # and one quick test of TEBD
    xxz_pars = dict(L=L, Jxx=1., Jz=3., hz=0., bc_MPS='finite')
    M = XXZChain(xxz_pars)
    TEBD_params = {
        'trunc_params': {
            'chi_max': 16,
            'svd_min': 1.e-8
        },
        'disentangle': None,  # 'renyi' should work as well, 'backwards' not.
        'dt': 0.1,
        'N_steps': 2
    }
    eng = PurificationTEBD(psi, M, TEBD_params)
    eng.run_imaginary(0.2)
    eng.run()
    N = psi.expectation_value('Id')  # check normalization : <1> =?= 1
    npt.assert_array_almost_equal_nulp(N, np.ones([L]), 100)
Example #12
0
def gen_disentangler_psi_singlet_test(site_P=spin_half, L=6, max_range=4):
    psi0, pairs_PQ = gen_disentangler_psi_singlets(site_P, L, max_range)
    psi0.test_sanity()
    print("pairs: P", pairs_PQ[0])
    print("pairs: Q", pairs_PQ[1])
    print("entanglement entropy: ", psi0.entanglement_entropy() / np.log(2.))
    coords, mutinf_pq = psi0.mutinf_two_site(legs='pq')
    print("(i,j)=", [tuple(c) for c in coords])
    print("PQ:", np.round(mutinf_pq / np.log(2), 3))
    print("P: ", np.round(psi0.mutinf_two_site(legs='p')[1] / np.log(2), 3))
    print("Q: ", np.round(psi0.mutinf_two_site(legs='q')[1] / np.log(2), 3))
    M = XXZChain(dict(L=L))
    tebd_pars = dict(trunc_params={'trunc_cut': 1.e-10}, disentangle='diag')
    eng = PurificationTEBD(psi0, M, tebd_pars)
    for i in range(L):
        eng.disentangle_global()
    print(psi0.entanglement_entropy() / np.log(2))
    mutinf_Q = psi0.mutinf_two_site(legs='q')[1]
    print("P: ", np.round(psi0.mutinf_two_site(legs='p')[1] / np.log(2), 3))
    print("Q: ", np.round(mutinf_Q / np.log(2), 3))
    assert (np.all(mutinf_Q < 1.e-10))
Example #13
0
def test_XXZChain():
    pars = dict(L=4, Jxx=1., Jz=1., hz=0., bc_MPS='finite')
    chain = XXZChain(pars)
    chain.test_sanity()
    for Hb in chain.H_bond[1:]:  # check bond eigenvalues
        Hb2 = Hb.combine_legs([['p0', 'p1'], ['p0*', 'p1*']], qconj=[+1, -1])
        print(Hb2.to_ndarray())
        W = npc.eigvalsh(Hb2)
        npt.assert_array_almost_equal_nulp(np.sort(W), np.sort([-0.75, 0.25, 0.25, 0.25]), 16**3)
    # now check with non-trivial onsite terms
    pars['hz'] = 0.2
    print("hz =", pars['hz'])
    chain = XXZChain(pars)
    chain.test_sanity()
    Hb = chain.H_bond[2]  # the only central bonds: boundaries have different hz.
    Hb2 = Hb.combine_legs([['p0', 'p1'], ['p0*', 'p1*']], qconj=[+1, -1])
    print(Hb2.to_ndarray())
    W = npc.eigvalsh(Hb2)
    print(W)
    npt.assert_array_almost_equal_nulp(
        np.sort(W),
        np.sort(
            [-0.75, 0.25 - 2 * 0.5 * 0.5 * pars['hz'], 0.25, 0.25 + 2. * 0.5 * 0.5 * pars['hz']]),
        16**3)
    pars['bc_MPS'] = 'infinite'

    for L in [2, 3, 4, 5, 6]:
        print("L =", L)
        pars['L'] = L
        chain = XXZChain(pars)
        pprint.pprint(chain.coupling_terms)
        assert len(chain.H_bond) == L
        Hb0 = chain.H_bond[0]
        for Hb in chain.H_bond[1:]:
            assert (npc.norm(Hb - Hb0, np.inf) == 0.)  # exactly equal
    pars['Jxx'] = 0.
    chain = XXZChain(pars)
    chain.test_sanity()
Example #14
0
"""A simple example comparing DMRG output with full diagonalization (ED).

Sorry that this is not well documented!
ED is meant to be used for debugging only ;)
"""
# Copyright 2018 TeNPy Developers

import tenpy.linalg.np_conserved as npc
from tenpy.models.xxz_chain import XXZChain
from tenpy.networks.mps import MPS

from tenpy.algorithms.exact_diag import ExactDiag
from tenpy.algorithms.dmrg import run as run_DMRG

xxz_pars = dict(L=4, Jxx=1., Jz=1., hz=0.0, bc_MPS='finite')
M = XXZChain(xxz_pars)
ED = ExactDiag(M, [0])
ED.build_full_H_from_mpo()
# ED.build_full_H_from_bonds()  # whatever you prefer
print("start diagonalization")
ED.full_diagonalization()
psi_ED = ED.groundstate()
print("psi_ED =", psi_ED)

print("start DMRG")
product_state = [0, 1] * (xxz_pars['L'] // 2)  # this selects a charge sector!
psi_DMRG = MPS.from_product_state(M.lat.mps_sites(), product_state)

res = run_DMRG(psi_DMRG, M, {'verbose': 0})
# first way to compare ED with DMRG: convert MPS to ED vector
psi_DMRG_full = ED.mps_to_full(psi_DMRG)
Example #15
0
# setup circuit-generated isoMPS
psi = IsoMPS(preg, breg, pcircs, L=L)

## Example (resolve parameters => random values and print circuit)
# pick some random parameter values
param_vals = [4 * np.pi * np.random.rand() for j in range(len(param_names))]
param_dict = dict(zip(param_names, param_vals))
psi.construct_circuit(param_dict, include_measurements=False)
#psi.circ.draw('mpl')

#%%
## Setup XXZ model in Tenpy ##
from tenpy.models.xxz_chain import XXZChain

h_param_dict = {'Jz': Delta, 'hz': 0}
model = XXZChain(h_param_dict)
H_mpo = model.calc_H_MPO()

# function to calculate energy using MPO/MPS contraction in tenpy
#def energy_tp(param_vals,*args):
"""
inputs:
    - param_vals = dict {parameter:value}
    - *args, 
        args[0] should be psi: state as IsoMPS
        args[1] should be H_mpo: Hamiltonian as MPO
    (input made this way to be compatible w/ scipy.optimize)
outputs:
    - float, <psi|H|psi> computed w/ tenpy
"""
# parse inputs