示例#1
0
def run_out_of_equilibrium():
    L = 10
    chi = 5
    delta_t = 0.1
    model_params = {
        'L': L,
        'S': 0.5,
        'conserve': 'Sz',
        'Jz': 1.0,
        'Jy': 1.0,
        'Jx': 1.0,
        'hx': 0.0,
        'hy': 0.0,
        'hz': 0.0,
        'muJ': 0.0,
        'bc_MPS': 'finite',
    }

    heisenberg = tenpy.models.spins.SpinChain(model_params)
    product_state = ["up"] * int(L / 2) + ["down"] * (
        L - int(L / 2)
    )  #starting from a product state which is not an eigenstate of the Heisenberg model
    psi = MPS.from_product_state(heisenberg.lat.mps_sites(),
                                 product_state,
                                 bc=heisenberg.lat.bc_MPS,
                                 form='B')

    tdvp_params = {
        'start_time': 0,
        'dt': delta_t,
        'trunc_params': {
            'chi_max': chi,
            'svd_min': 1.e-10,
            'trunc_cut': None
        }
    }
    tdvp_engine = tdvp.Engine(psi=psi,
                              model=heisenberg,
                              TDVP_params=tdvp_params)
    times = []
    S_mid = []
    for i in range(30):
        tdvp_engine.run_two_sites(N_steps=1)
        times.append(tdvp_engine.evolved_time)
        S_mid.append(psi.entanglement_entropy(bonds=[L // 2])[0])
    for i in range(30):
        tdvp_engine.run_one_site(N_steps=1)
        #psi_2=copy.deepcopy(psi)
        #psi_2.canonical_form()
        times.append(tdvp_engine.evolved_time)
        S_mid.append(psi.entanglement_entropy(bonds=[L // 2])[0])
    import matplotlib.pyplot as plt
    plt.figure()
    plt.plot(times, S_mid)
    plt.xlabel('t')
    plt.ylabel('S')
    plt.axvline(x=3.1, color='red')
    plt.text(0.0, 0.0000015, "Two sites update")
    plt.text(3.1, 0.0000015, "One site update")
    plt.show()
示例#2
0
def test_tebd(bc_MPS, g=0.5):
    L = 2 if bc_MPS == 'infinite' else 6
    #  xxz_pars = dict(L=L, Jxx=1., Jz=3., hz=0., bc_MPS=bc_MPS)
    #  M = XXZChain(xxz_pars)
    # factor of 4 (2) for J (h) to change spin-1/2 to Pauli matrices
    model_pars = dict(L=L, Jx=0., Jy=0., Jz=-4., hx=2. * g, bc_MPS=bc_MPS, conserve=None)
    M = SpinChain(model_pars)
    state = ([[1, -1.], [1, -1.]] * L)[:L]  # pointing in (-x)-direction
    psi = MPS.from_product_state(M.lat.mps_sites(), state, bc=bc_MPS)

    tebd_param = {
        'verbose': 2,
        'dt': 0.01,
        'order': 2,
        'delta_tau_list': [0.1, 1.e-4, 1.e-8],
        'max_error_E': 1.e-9,
        'trunc_params': {
            'chi_max': 50,
            'trunc_cut': 1.e-13
        }
    }
    engine = tebd.Engine(psi, M, tebd_param)
    engine.run_GS()

    print("norm_test", psi.norm_test())
    if bc_MPS == 'finite':
        psi.canonical_form()
        ED = ExactDiag(M)
        ED.build_full_H_from_mpo()
        ED.full_diagonalization()
        psi_ED = ED.groundstate()
        Etebd = np.sum(M.bond_energies(psi))
        Eexact = np.min(ED.E)
        print("E_TEBD={Etebd:.14f} vs E_exact={Eex:.14f}".format(Etebd=Etebd, Eex=Eexact))
        assert (abs((Etebd - Eexact) / Eexact) < 1.e-7)
        ov = npc.inner(psi_ED, ED.mps_to_full(psi), do_conj=True)
        print("compare with ED: overlap = ", abs(ov)**2)
        assert (abs(abs(ov) - 1.) < 1.e-7)

        # Test real time TEBD: should change on an eigenstate
        Sold = np.average(psi.entanglement_entropy())
        for i in range(3):
            engine.run()
        Enew = np.sum(M.bond_energies(psi))
        Snew = np.average(psi.entanglement_entropy())
        assert (abs(Enew - Etebd) < 1.e-8)
        assert (abs(Sold - Snew) < 1.e-5)  # somehow we need larger tolerance here....

    if bc_MPS == 'infinite':
        Etebd = np.average(M.bond_energies(psi))
        Eexact = e0_tranverse_ising(g)
        print("E_TEBD={Etebd:.14f} vs E_exact={Eex:.14f}".format(Etebd=Etebd, Eex=Eexact))

        Sold = np.average(psi.entanglement_entropy())
        for i in range(2):
            engine.run()
        Enew = np.average(M.bond_energies(psi))
        Snew = np.average(psi.entanglement_entropy())
        assert (abs(Etebd - Enew) < 1.e-7)
        assert (abs(Sold - Snew) < 1.e-5)  # somehow we need larger tolerance here....
def DMRG_tf_ising_finite(Lx, Ly, g, verbose=True):
    print("finite DMRG, transverse field Ising model")
    print("Lx={Lx:d}, Ly={Ly:d}, g={g:.2f}".format(Lx=Lx, Ly=Ly, g=g))
    M = TFIModel(
        dict(g=g,
             J=1.,
             lattice='Triangular',
             bc_MPS='finite',
             Lx=Lx,
             Ly=Ly,
             conserve=None,
             verbose=verbose))
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(),
                                 product_state,
                                 bc=M.lat.bc_MPS)
    dmrg_params = {
        'mixer': None,
        'max_E_err': 1.e-10,
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
        'verbose': verbose,
        'combine': True
    }
    info = dmrg.run(psi, M, dmrg_params)
    E = info['E']
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    mag_x = np.sum(psi.expectation_value("Sigmax"))
    mag_z = np.sum(psi.expectation_value("Sigmaz"))
    print("magnetization in X = {mag_x:.5f}".format(mag_x=mag_x))
    print("magnetization in Z = {mag_z:.5f}".format(mag_z=mag_z))
    return E, psi, M
示例#4
0
def example_TEBD_gs_tf_ising_infinite(g, verbose=True):
    print("infinite TEBD, imaginary time evolution, transverse field Ising")
    print("g={g:.2f}".format(g=g))
    model_params = dict(L=2, J=1., g=g, bc_MPS='infinite', conserve=None, verbose=verbose)
    M = TFIChain(model_params)
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(), product_state, bc=M.lat.bc_MPS)
    tebd_params = {
        'order': 2,
        'delta_tau_list': [0.1, 0.01, 0.001, 1.e-4, 1.e-5],
        'N_steps': 10,
        'max_error_E': 1.e-8,
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
        'verbose': verbose,
    }
    eng = tebd.Engine(psi, M, tebd_params)
    eng.run_GS()  # the main work...
    E = np.sum(M.bond_energies(psi))  # M.bond_energies() works only a for NearestNeighborModel
    # alternative: directly measure E2 = np.mean(psi.expectation_value(M.H_bond))
    print("E (per site) = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    mag_x = np.mean(psi.expectation_value("Sigmax"))
    mag_z = np.mean(psi.expectation_value("Sigmaz"))
    print("<sigma_x> = {mag_x:.5f}".format(mag_x=mag_x))
    print("<sigma_z> = {mag_z:.5f}".format(mag_z=mag_z))
    print("correlation length:", psi.correlation_length())
    # compare to exact result
    from tfi_exact import infinite_gs_energy
    E_exact = infinite_gs_energy(1., g)
    print("Analytic result: E (per site) = {E:.13f}".format(E=E_exact))
    print("relative error: ", abs((E - E_exact) / E_exact))
    return E, psi, M
示例#5
0
def example_DMRG_heisenberg_xxz_finite(L, Jz, chi, conserve='best', verbose=True):
    print("finite DMRG, Heisenberg XXZ chain")
    print("L={L:d}, Jz={Jz:.2f}".format(L=L, Jz=Jz))
    model_params = dict(L=L, S=0.5, Jx=1., Jy=1., Jz=Jz,
                        bc_MPS='finite', conserve=conserve, verbose=verbose)
    M = SpinModel(model_params)
    product_state = ["up", "down"] * (M.lat.N_sites // 2)
    psi = MPS.from_product_state(M.lat.mps_sites(), product_state, bc=M.lat.bc_MPS)
    dmrg_params = {
        'mixer': True,  # setting this to True helps to escape local minima
        'max_E_err': 1.e-16,
        'trunc_params': {
            'chi_max': chi,
            'svd_min': 1.e-16
        },
        'verbose': verbose,
    }
    info = dmrg.run(psi, M, dmrg_params)  # the main work...
    E = info['E']
    E = E * 4
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    Sz = psi.expectation_value("Sz")  # Sz instead of Sigma z: spin-1/2 operators!
    mag_z = np.mean(Sz)
    print("<S_z> = [{Sz0:.5f}, {Sz1:.5f}]; mean ={mag_z:.5f}".format(Sz0=Sz[0],
                                                                     Sz1=Sz[1],
                                                                     mag_z=mag_z))
    # note: it's clear that mean(<Sz>) is 0: the model has Sz conservation!
    corrs = psi.correlation_function("Sz", "Sz", sites1=range(10))
    print("correlations <Sz_i Sz_j> =")
    print(corrs)
    return E, psi, M
示例#6
0
def example_DMRG_tf_ising_infinite(g, verbose=True):
    print("infinite DMRG, transverse field Ising model")
    print("g={g:.2f}".format(g=g))
    model_params = dict(L=2, J=1., g=g, bc_MPS='infinite', conserve=None, verbose=verbose)
    M = TFIChain(model_params)
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(), product_state, bc=M.lat.bc_MPS)
    dmrg_params = {
        'mixer': True,  # setting this to True helps to escape local minima
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
        'max_E_err': 1.e-10,
        'verbose': verbose,
    }
    # instead of
    #  info = dmrg.run(psi, M, dmrg_params)
    #  E = info['E']
    # we can also use the a Engine directly:
    eng = dmrg.EngineCombine(psi, M, dmrg_params)
    E, psi = eng.run()  # equivalent to dmrg.run() up to the return parameters.
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    mag_x = np.mean(psi.expectation_value("Sigmax"))
    mag_z = np.mean(psi.expectation_value("Sigmaz"))
    print("<sigma_x> = {mag_x:.5f}".format(mag_x=mag_x))
    print("<sigma_z> = {mag_z:.5f}".format(mag_z=mag_z))
    print("correlation length:", psi.correlation_length())
    # compare to exact result
    from tfi_exact import infinite_gs_energy
    E_exact = infinite_gs_energy(1., g)
    print("Analytic result: E (per site) = {E:.13f}".format(E=E_exact))
    print("relative error: ", abs((E - E_exact) / E_exact))
    return E, psi, M
示例#7
0
def run_tebd_tfi(L, mindim, g, tf, dt, verbose=False, order=2):
    model_params = dict(L=L,
                        J=1.,
                        g=g,
                        bc_MPS='finite',
                        conserve=None,
                        verbose=verbose)
    M = TFIChain(model_params)
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(),
                                 product_state,
                                 bc=M.lat.bc_MPS)
    tebd_params = {
        'order': order,
        'dt': dt,
        'N_steps': int(tf / dt),
        'trunc_params': {
            'trunc_cut': 1e-14,
            'svd_min': 1e-24,
            'chi_max': mindim
            # 'chi_min': mindim
        },
        'verbose': verbose,
    }
    eng = tebd.Engine(psi, M, tebd_params)
    eng.run()
    print(np.amax(psi.chi))
    return psi
示例#8
0
def example_TEBD_gs_finite(L, g):
    print("finite TEBD, imaginary time evolution, L={L:d}, g={g:.2f}".format(
        L=L, g=g))
    model_params = dict(L=L,
                        J=1.,
                        g=g,
                        bc_MPS='finite',
                        conserve=None,
                        verbose=0)
    M = TFIChain(model_params)
    psi = MPS.from_product_state(M.lat.mps_sites(), [0] * L, bc='finite')
    tebd_params = {
        'order': 2,
        'delta_tau_list': [0.1, 0.01, 0.001, 1.e-4, 1.e-5],
        'N_steps': 10,
        'max_error_E': 1.e-6,
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
        'verbose': 1
    }
    eng = tebd.Engine(psi, M, tebd_params)
    eng.run_GS()  # the main work...
    E = np.sum(psi.expectation_value(M.H_bond[1:]))
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    if L < 20:  # compare to exact result
        E_exact = tfi_exact.finite_gs_energy(L, 1., g)
        print("Exact diagonalization: E = {E:.13f}".format(E=E_exact))
        print("relative error: ", abs((E - E_exact) / E_exact))
    return E, psi, M
示例#9
0
def example_DMRG_infinite(g):
    print("infinite DMRG, g={g:.2f}".format(g=g))
    model_params = dict(L=2,
                        J=1.,
                        g=g,
                        bc_MPS='infinite',
                        conserve=None,
                        verbose=0)
    M = TFIChain(model_params)
    psi = MPS.from_product_state(M.lat.mps_sites(), [0] * 2, bc='infinite')
    dmrg_params = {
        'mixer': True,
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
        'max_E_err': 1.e-10,
        'verbose': 1
    }
    dmrg.run(psi, M, dmrg_params)
    E = np.mean(psi.expectation_value(M.H_bond))
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    print("correlation length:", psi.correlation_length())
    # compare to exact result
    E_exact = tfi_exact.infinite_gs_energy(1., g)
    print("Analytic result: E/L = {E:.13f}".format(E=E_exact))
    print("relative error: ", abs((E - E_exact) / E_exact))
    return E, psi, M
示例#10
0
def run_tenpy_tdvp(L, maxdim, tf, verbose=False):
    model_params = dict(L=L,
                        J=1.,
                        g=1,
                        bc_MPS='finite',
                        conserve=None,
                        verbose=verbose)
    M = TFIChain(model_params)
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(),
                                 product_state,
                                 bc=M.lat.bc_MPS)

    tdvp_params = {
        'start_time': 0,
        'dt': 0.1,
        'trunc_params': {
            'chi_max': maxdim,
            'svd_min': 0,
            'trunc_cut': None
        }
    }
    tdvp_engine = tdvp.Engine(psi=psi, model=M, TDVP_params=tdvp_params)
    tdvp_engine.run_two_sites(N_steps=int(tf / 0.1))

    return np.amax(psi.chi)
示例#11
0
def test_ToricCode(Lx=1, Ly=2):
    with warnings.catch_warnings():
        warnings.simplefilter('ignore')
        model_params = {'Lx': Lx, 'Ly': Ly}
        M = ToricCode(model_params)
        psi = MPS.from_product_state(M.lat.mps_sites(), [0] * M.lat.N_sites,
                                     bc='infinite')
        dmrg_params = {
            'mixer': True,
            'trunc_params': {
                'chi_max': 10,
                'svd_min': 1.e-10
            },
            'max_E_err': 1.e-10,
            'N_sweeps_check': 4,
            'verbose': 1
        }
        result = dmrg.run(psi, M, dmrg_params)
        E = result['E']
        print("E =", E)
        psi.canonical_form()
        # energy per "cell"=2 -> energy per site in the dual lattice = 1
        assert abs(E - (-1.)) < dmrg_params['max_E_err']
        print("chi=", psi.chi)
        if Ly == 2:
            assert tuple(psi.chi[:4]) == (2, 4, 4, 4)
        assert abs(
            psi.entanglement_entropy(bonds=[0])[0] - np.log(2) *
            (Ly - 1)) < 1.e-5
示例#12
0
def example_TEBD_gs_infinite(g):
    print("infinite TEBD, imaginary time evolution, g={g:.2f}".format(g=g))
    model_params = dict(L=2, J=1., g=g, bc_MPS='infinite', conserve=None, verbose=0)
    M = TFIChain(model_params)
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(), product_state, bc=M.lat.bc_MPS)
    tebd_params = {
        'order': 2,
        'delta_tau_list': [0.1, 0.01, 0.001, 1.e-4, 1.e-5],
        'N_steps': 10,
        'max_error_E': 1.e-8,
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
        'verbose': 1
    }
    eng = tebd.Engine(psi, M, tebd_params)
    eng.run_GS()  # the main work...
    E = np.mean(psi.expectation_value(M.H_bond))
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    print("correlation length:", psi.correlation_length())
    # compare to exact result
    E_exact = tfi_exact.infinite_gs_energy(1., g)
    print("Analytic result: E/L = {E:.13f}".format(E=E_exact))
    print("relative error: ", abs((E - E_exact) / E_exact))
    return E, psi, M
示例#13
0
    def random_prod_state_tenpy(L, a_model):
        product_state = []
        #the numpy mps used to compare
        psi_compare = []
        sz = 2. * np.random.randint(0, 2, size=L) - 1.0
        for i in range(L):
            psi_compare.append(np.zeros((2, 1, 1)))
            if sz[i] > 0:
                product_state += ["up"]
                psi_compare[-1][0, 0, 0] = 1
            else:
                product_state += ["down"]
                psi_compare[-1][1, 0, 0] = 1

        psi = MPS.from_product_state(a_model.lat.mps_sites(),
                                     product_state,
                                     bc=a_model.lat.bc_MPS,
                                     form='B')
        psi_converted = []
        for i in range(L):
            site = psi.sites[i]
            perm = site.perm
            B_tmp = psi.get_B(i).transpose(['p', 'vL', 'vR']).to_ndarray()
            B = B_tmp[inverse_permutation(perm), :, :]
            B = B[::-1, :, :]
            psi_converted.append(B)

        return psi
示例#14
0
def example_DMRG_tf_ising_finite(L, g, h=0, chi=2, verbose=True):
    print("finite DMRG, transverse field Ising model")
    print("L={L:d}, g={g:.2f}, h={h:.2f}".format(L=L, g=g, h=h))
    model_params = dict(L=L, J=1., g=g, bc_MPS='finite', h=h)
    M = IsingChain(model_params)

    # model_params = dict(L=L, J=1., g=g, bc_MPS='finite', conserve=None, verbose=verbose)
    # M = TFIChain(model_params)

    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(),
                                 product_state,
                                 bc=M.lat.bc_MPS)
    dmrg_params = {
        'mixer': None,  # setting this to True helps to escape local minima
        'max_E_err': 1.e-16,
        'trunc_params': {
            'chi_max': chi,
            'svd_min': 1.e-16
        },
        'verbose': verbose,
    }
    info = dmrg.run(psi, M, dmrg_params)  # the main work...
    E = info['E']
    print("E = {E:.16f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    mag_x = np.sum(psi.expectation_value("Sigmax"))
    mag_z = np.sum(psi.expectation_value("Sigmaz"))
    print("magnetization in X = {mag_x:.5f}".format(mag_x=mag_x))
    print("magnetization in Z = {mag_z:.5f}".format(mag_z=mag_z))
    return E, psi, M
示例#15
0
    def __init__(self, L=10, Jn=1, Jnn=0, hz=0, options={}):
        # use predefined local Hilbert space and onsite operators
        site = SpinSite(S=1 / 2, conserve=None)
        self.L = L
        lat = Chain(L, site, bc="open", bc_MPS="finite")  # define geometry
        MultiCouplingModel.__init__(self, lat)
        # add terms of the Hamiltonian;
        # operators "Sx", "Sy", "Sz" are defined by the SpinSite
        self.add_coupling(Jn, 0, "Sx", 0, "Sx", 1)
        self.add_coupling(Jn, 0, "Sy", 0, "Sy", 1)
        self.add_coupling(Jn, 0, "Sz", 0, "Sz", 1)

        self.add_multi_coupling(
            Jnn, [("Sx", -1, 0), ("Sx", 1, 0)]
        )  #(oper, shift, internal index - it's possible to merge sites together)
        self.add_multi_coupling(Jnn, [("Sy", -1, 0), ("Sy", 1, 0)])
        self.add_multi_coupling(Jnn, [("Sz", -1, 0), ("Sz", 1, 0)])

        self.add_onsite(hz, 0, "Sz")
        # finish initialization
        MPOModel.__init__(self, lat, self.calc_H_MPO())
        self.psi = MPS.from_product_state(self.lat.mps_sites(), [0] * L,
                                          "finite")
        self.options = options
        self.dmrg_retval = None
示例#16
0
def example_1site_DMRG_tf_ising_finite(L, g, verbose=True):
    print("single-site finite DMRG, transverse field Ising model")
    print("L={L:d}, g={g:.2f}".format(L=L, g=g))
    model_params = dict(L=L, J=1., g=g, bc_MPS='finite', conserve=None, verbose=verbose)
    M = TFIChain(model_params)
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(), product_state, bc=M.lat.bc_MPS)
    dmrg_params = {
        'mixer': True,  # setting this to True is essential for the 1-site algorithm to work.
        'max_E_err': 1.e-10,
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
        'verbose': verbose,
        'combine': False,
        'active_sites': 1  # specifies single-site
    }
    info = dmrg.run(psi, M, dmrg_params)
    E = info['E']
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    mag_x = np.sum(psi.expectation_value("Sigmax"))
    mag_z = np.sum(psi.expectation_value("Sigmaz"))
    print("magnetization in X = {mag_x:.5f}".format(mag_x=mag_x))
    print("magnetization in Z = {mag_z:.5f}".format(mag_z=mag_z))
    if L < 20:  # compare to exact result
        from tfi_exact import finite_gs_energy
        E_exact = finite_gs_energy(L, 1., g)
        print("Exact diagonalization: E = {E:.13f}".format(E=E_exact))
        print("relative error: ", abs((E - E_exact) / E_exact))
    return E, psi, M
示例#17
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'))
示例#18
0
def example_DMRG_finite(L, g):
    print("finite DMRG, L={L:d}, g={g:.2f}".format(L=L, g=g))
    model_params = dict(L=L,
                        J=1.,
                        g=g,
                        bc_MPS='finite',
                        conserve=None,
                        verbose=0)
    M = TFIChain(model_params)
    psi = MPS.from_product_state(M.lat.mps_sites(), [0] * L, bc='finite')
    dmrg_params = {
        'mixer': None,
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
        'max_E_err': 1.e-10,
        'verbose': 1
    }
    dmrg.run(psi, M, dmrg_params)
    E = np.sum(psi.expectation_value(M.H_bond[1:]))
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    if L < 20:  # compare to exact result
        E_exact = tfi_exact.finite_gs_energy(L, 1., g)
        print("Exact diagonalization: E = {E:.13f}".format(E=E_exact))
        print("relative error: ", abs((E - E_exact) / E_exact))
    return E, psi, M
示例#19
0
def example_DMRG_tf_ising_infinite_S_xi_scaling(g):
    model_params = dict(L=2,
                        J=1.,
                        g=g,
                        bc_MPS='infinite',
                        conserve='best',
                        verbose=0)
    M = TFIChain(model_params)
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(),
                                 product_state,
                                 bc=M.lat.bc_MPS)
    dmrg_params = {
        'start_env': 10,
        'mixer': False,
        #  'mixer_params': {'amplitude': 1.e-3, 'decay': 5., 'disable_after': 50},
        'trunc_params': {
            'chi_max': 5,
            'svd_min': 1.e-10
        },
        'max_E_err': 1.e-9,
        'max_S_err': 1.e-6,
        'update_env': 0,
        'verbose': 0
    }

    chi_list = np.arange(7, 31, 2)
    s_list = []
    xi_list = []
    eng = dmrg.TwoSiteDMRGEngine(psi, M, dmrg_params)

    for chi in chi_list:

        t0 = time.time()
        eng.reset_stats(
        )  # necessary if you for example have a fixed numer of sweeps, if you don't set this you option your simulation stops after initial number of sweeps!
        eng.trunc_params['chi_max'] = chi
        ##   DMRG Calculation    ##
        print("Start IDMRG CALCULATION")
        eng.run()
        eng.engine_params['mixer'] = None
        psi.canonical_form()

        ##   Calculating bond entropy and correlation length  ##
        s_list.append(np.mean(psi.entanglement_entropy()))
        xi_list.append(psi.correlation_length())

        print(chi,
              time.time() - t0,
              np.mean(psi.expectation_value(M.H_bond)),
              s_list[-1],
              xi_list[-1],
              flush=True)
        tenpy.tools.optimization.optimize(
            3)  # quite some speedup for small chi

        print("SETTING NEW BOND DIMENSION")

    return s_list, xi_list
示例#20
0
 def example_DMRG_heisenberg_xxz_infinite(Jx=1,
                                          Jy=1,
                                          Jz=1,
                                          hx=0,
                                          hy=0,
                                          hz=0,
                                          conserve='best',
                                          verbose=False,
                                          chi_max=100,
                                          S=0.5):
     if verbose:
         print("infinite DMRG, Heisenberg XXZ chain")
         print("Jz={Jz:.2f}, conserve={conserve!r}".format(
             Jz=Jz, conserve=conserve))
     model_params = dict(
         L=2,
         S=S,  # spin 1/2
         Jx=Jx,
         Jy=Jy,
         Jz=Jz,  # couplings
         hx=hx,
         hy=hy,
         hz=hz,
         bc_MPS='infinite',
         conserve=conserve,
         verbose=verbose)
     M = SpinModel(model_params)
     product_state = ["up", "up"]  # initial Neel state
     psi = MPS.from_product_state(M.lat.mps_sites(),
                                  product_state,
                                  bc=M.lat.bc_MPS)
     dmrg_params = {
         'mixer': True,  # setting this to True helps to escape local minima
         'trunc_params': {
             'chi_max': chi_max,
             'svd_min': 1.e-10,
         },
         'max_E_err': 1.e-10,
         'verbose': verbose,
     }
     info = dmrg.run(psi, M, dmrg_params)
     E = info['E']
     if verbose:
         print("E = {E:.13f}".format(E=E))
         print("final bond dimensions: ", psi.chi)
     Sz = psi.expectation_value(
         "Sz")  # Sz instead of Sigma z: spin-1/2 operators!
     mag_z = np.mean(Sz)
     if verbose:
         print("<S_z> = [{Sz0:.5f}, {Sz1:.5f}]; mean ={mag_z:.5f}".format(
             Sz0=Sz[0], Sz1=Sz[1], mag_z=mag_z))
     # note: it's clear that mean(<Sz>) is 0: the model has Sz conservation!
     if verbose:
         print("correlation length:", psi.correlation_length())
     corrs = psi.correlation_function("Sz", "Sz", sites1=range(10))
     if verbose:
         print("correlations <Sz_i Sz_j> =")
         print(corrs)
     return E, psi, M
示例#21
0
def hubbard_dmrg(L,U,V,init="11",t=1.,mu=0,n_max=3,conserve="N",chi_max=100,bc="finite",extra_fill=0):
    """ Run DMRG for the Bose Hubbard model """
    # Setting the initial state
    where = int(L/3)
    if where % 2:
        where += 1
    if where > L:
        where = 1
    if init == "11":
        init_config = [1] * L
        init_config[where] += extra_fill
    if init == "20":
        init_config = [2,0] * int(L/2)
        init_config[where] += extra_fill
    if init == "02":
        init_config = [0,2] * int(L/2)
        init_config[where] += extra_fill
    filling = np.sum(init_config)/L
    t0 = datetime.datetime.now()
    model_params = dict(
        filling = filling,
        n_max = n_max,
        t = t,
        U = U,
        V = V,
        mu = mu,
        L=L,
        bc_MPS=bc,
        conserve = conserve,
        verbose=0)
    M = BoseHubbardChain(model_params)
    psi = MPS.from_product_state(M.lat.mps_sites(), init_config, bc=bc)
    dmrg_params = {
        'mixer': None,
        'trunc_params': {
            'chi_max': chi_max,
            'svd_min': 1.e-10
        },
        'max_E_err': 1.e-10,
        'verbose': 0,
        "norm_tol":1e-5
    }
    eng = dmrg.TwoSiteDMRGEngine(psi, M, dmrg_params)
    eng.reset_stats()
    eng.trunc_params["chi_max"] = chi_max
    eng.run()
    E = np.sum(psi.expectation_value(M.H_bond[1:]))
    print("E = {E:.13f}".format(E=E))
    #print("final bond dimensions: ", psi.chi)
    time = datetime.datetime.now() - t0
    print(time)
    params = model_params
    params["chi_max"] = chi_max
    params["chis"] = psi.chi
    params["E"] = E
    params["time"] = time
    params["init_config"] = init_config
    params["init"] = init
    return psi, params
示例#22
0
def run(model_params, phi_ext=np.linspace(0, 1.0, 7)):

    data = dict(phi_ext=phi_ext, QL=[], ent_spectrum=[])

    dmrg_params = {
        'mixer': True,  # setting this to True helps to escape local minima
        'mixer_params': {
            'amplitude': 1.e-5,
            'decay': 1.2,
            'disable_after': 30
        },
        'trunc_params': {
            'svd_min': 1.e-10,
        },
        'lanczos_params': {
            'N_min': 5,
            'N_max': 20
        },
        'chi_list': {
            0: 9,
            10: 49,
            20: 100
        },
        'max_E_err': 1.e-10,
        'max_S_err': 1.e-6,
        'max_sweeps': 150,
        'verbose': 1.,
    }

    prod_state = ['empty', 'full'] * (model_params['Lx'] * model_params['Ly'])

    eng = None

    for phi in phi_ext:

        print("=" * 100)
        print("phi_ext = ", phi)

        model_params['phi_ext'] = phi

        if eng is None:  # first time in the loop
            M = FermionicHaldaneModel(model_params)
            psi = MPS.from_product_state(M.lat.mps_sites(),
                                         prod_state,
                                         bc=M.lat.bc_MPS)
            eng = dmrg.TwoSiteDMRGEngine(psi, M, dmrg_params)
        else:
            del eng.engine_params['chi_list']
            M = FermionicHaldaneModel(model_params)
            eng.init_env(model=M)

        E, psi = eng.run()

        data['QL'].append(psi.average_charge(bond=0)[0])
        data['ent_spectrum'].append(
            psi.entanglement_spectrum(by_charge=True)[0])

    return data
示例#23
0
def main():
    L = 60
    chi = 80
    U = 10.0
    beta = 0.02

    file_name = "U" + str(int(U)) +\
      "_L"+str(L)+\
      "_Ds_ch"+str(chi)+\
      ".pkl"

    verbose_model = 0
    verbose_dmrg = 0

    t = 1.0
    Mu = 16.0
    alpha = 0.5

    cnsrv_bsn = 'N'
    cnsrv_spn = None
    pkl_pack = []

    for ddelta in range(51):
        delta = 0.50 + ddelta * 0.01
        model_params = {
            'n_max': 2,
            'L': L,
            'bc_MPS': 'finite',
            'filling': 0.5,
            't': t,
            'U': U,
            'mu': Mu,
            'alpha': alpha,
            'delta': delta,
            'beta': beta,
            'conserve_boson': cnsrv_bsn,
            'conserve_spin': cnsrv_spn,
            'verbose': verbose_model
        }
        M = BosonSpin(model_params)
        initial_state = [0] * (L // 2) + [2] * (L // 2)
        psi = MPS.from_product_state(M.lat.mps_sites(),
                                     initial_state,
                                     bc='finite')
        dmrg_params = {'mixer': None, 'verbose': verbose_dmrg, \
              'trunc_params': {'chi_max': chi, 'svd_min': 1.e-10}}
        start_time = time.time()
        dmrg.run(psi, M, dmrg_params)
        end_time = time.time()
        print("$\Delta = {a:.04f}$\tDMRG time = {b}".format(a=delta,
                                                            b=end_time -
                                                            start_time))
        pkl_pack += [[psi, model_params, dmrg_params]]

    with open(file_name, 'wb') as g:
        pickle.dump(pkl_pack, g)

    return 0
示例#24
0
def main():
    L = 80
    delta = 0.9064

    file_name="L"+str(L) + \
      "_D"+str(int(delta*10000))+\
      "E0" + \
      "_CHIall.pkl"

    verbose_model = 0
    verbose_dmrg = 0

    t = 1.0
    alpha = 0.5
    beta = 0.02

    cnsrv_bsn = 'Sz'
    cnsrv_spn = None

    model_params = {
        'L': L,
        'bc_MPS': 'finite',
        't': t,
        'alpha': alpha,
        'delta': delta,
        'beta': beta,
        'conserve_fermionic_boson': cnsrv_bsn,
        'conserve_spin': cnsrv_spn,
        'verbose': verbose_model
    }
    M = FermionOnSpinLattice(model_params)
    initial_state = [0] * (L // 2) + [2] * (L // 2)

    pkl_pack = [model_params, M]

    chi_start = np.arange(10) + 5
    chi_end = np.arange(35) * 2 + 15

    #chis = np.concatenate((chi_start, chi_end))
    # extra chi for 80
    chis = np.arange(10) * 2 + 85
    for chi in chis:
        psi = MPS.from_product_state(M.lat.mps_sites(),
                                     initial_state,
                                     bc='finite')
        dmrg_params = {'mixer': None, 'verbose': verbose_dmrg, \
              'trunc_params': {'chi_max': chi, 'svd_min': 1.e-10}}
        start_time = time.time()
        dmrg.run(psi, M, dmrg_params)
        end_time = time.time()
        print("D max = {c}\tDMRG time = {b}".format(c=chi,
                                                    b=end_time - start_time))
        pkl_pack += [[psi, chi]]

    with open(file_name, 'wb') as g:
        pickle.dump(pkl_pack, g)

    return 0
def test_ExpMPOEvolution(bc_MPS, approximation, compression, g=1.5):
    # Test a time evolution against exact diagonalization for finite bc
    dt = 0.01
    if bc_MPS == 'finite':
        L = 6
    else:
        L = 2
    model_pars = dict(L=L,
                      Jx=0.,
                      Jy=0.,
                      Jz=-4.,
                      hx=2. * g,
                      bc_MPS=bc_MPS,
                      conserve=None)
    M = SpinChain(model_pars)
    state = ([[1 / np.sqrt(2), -1 / np.sqrt(2)]] * L
             )  # pointing in (-x)-direction
    state = ['up'] * L  # pointing in (-z)-direction
    psi = MPS.from_product_state(M.lat.mps_sites(), state, bc=bc_MPS)

    options = {
        'dt': dt,
        'N_steps': 1,
        'order': 1,
        'approximation': approximation,
        'compression_method': compression,
        'trunc_params': {
            'chi_max': 30
        }
    }
    eng = mpo_evolution.ExpMPOEvolution(psi, M, options)

    if bc_MPS == 'finite':
        ED = exact_diag.ExactDiag(M)
        ED.build_full_H_from_mpo()
        ED.full_diagonalization()
        psiED = ED.mps_to_full(psi)
        psiED /= psiED.norm()

        UED = ED.exp_H(dt)
        for i in range(30):
            psi = eng.run()
            psiED = npc.tensordot(UED, psiED, ('ps*', [0]))
            psi_full = ED.mps_to_full(psi)
            assert (abs(abs(npc.inner(psiED, psi_full, [0, 0], True)) - 1) <
                    dt)

    if bc_MPS == 'infinite':
        psiTEBD = psi.copy()
        TEBD_params = {'dt': dt, 'N_steps': 1}
        EngTEBD = tebd.Engine(psiTEBD, M, TEBD_params)
        for i in range(30):
            EngTEBD.run()
            psi = eng.run()
            print(psi.norm)
            print(np.abs(psi.overlap(psiTEBD) - 1))
            #This test fails
            assert (abs(abs(psi.overlap(psiTEBD)) - 1) < 1e-2)
示例#26
0
def setup_benchmark(mod_q=[1], legs=10, size=20, **kwargs):
    """Setup DMRG benchmark.

    Mapping of parameters:
        size -> chi
        legs -> L = number of sites
        mod_q -> conserve
    """
    L = legs  # number of sites: legs is abbreviated with `l`
    if len(mod_q) == 0:
        conserve = None
    elif mod_q == [2]:
        conserve = 'parity'
    elif mod_q == [1]:
        conserve = 'Sz'
    model_params = dict(L=L,
                        S=2.,
                        D=0.3,
                        bc_MPS='infinite',
                        conserve=conserve,
                        verbose=0)
    #  print("conserve =", repr(conserve))
    M = SpinChain(model_params)
    initial_state = (['up', 'down'] * L)[:L]
    psi = MPS.from_product_state(M.lat.mps_sites(),
                                 initial_state,
                                 bc='infinite')
    dmrg_params = {
        'trunc_params': {
            'chi_max': size,
            'svd_min': 1.e-45,
        },
        'lanczos_params': {
            'N_min': 10,
            'N_max': 10
        },
        #  'mixer': None,
        #  'N_sweeps_check': 1,
        #  'min_sweeps': 10,
        #  'max_sweeps': 100,
        #  'max_E_err': 1.e-13,
        'verbose': 0.,
    }
    eng = dmrg.TwoSiteDMRGEngine(psi, M, dmrg_params)
    eng.verbose = 0.02
    for i in range(100):
        eng.sweep(meas_E_trunc=False)
        eng.sweep(optimize=False, meas_E_trunc=False)  # environment sweep
        if eng.verbose > 0.1:
            print(eng.psi.chi)
            print(eng.psi.entanglement_entropy())
    if eng.verbose > 0.1:
        print("set up dmrg for size", size)
    if eng.verbose > 0.01:
        print('initial chi', eng.psi.chi)
    eng.reset_stats()
    return eng
示例#27
0
def run(phi_ext=np.linspace(0, 1.0, 11)):
    data = dict(phi_ext=phi_ext, QL=[], ent_spectrum=[])

    model_params = dict(conserve='N',
                        filling=1 / 2.,
                        Lx=1,
                        Ly=3,
                        t=-1.,
                        mu=0,
                        V=1.,
                        phi_ext=0.,
                        bc_MPS='infinite',
                        bc_y='cylinder',
                        verbose=0)
    dmrg_params = {
        'mixer': True,  # setting this to True helps to escape local minima
        'mixer_params': {
            'amplitude': 1.e-5,
            'decay': 1.2,
            'disable_after': 30
        },
        'trunc_params': {
            'svd_min': 1.e-10,
        },
        'lanczos_params': {
            'N_min': 5,
            'N_max': 20
        },
        'chi_list': {
            0: 9,
            10: 49,
            20: 200
        },
        'max_E_err': 1.e-10,
        'max_S_err': 1.e-6,
        'max_sweeps': 150,
        'verbose': 1.,
    }
    prod_state = ['full', 'empty'] * (model_params['Lx'] * model_params['Ly'] * 2 // 2)
    # TODO allow tiling of list in from_product_state...
    eng = None
    for phi in phi_ext:
        print("=" * 100)
        print("phi_ext = ", phi)
        model_params['phi_ext'] = phi
        if eng is None:  # first time in the loop
            M = FermionicHaldaneModel(model_params)
            psi = MPS.from_product_state(M.lat.mps_sites(), prod_state, bc=M.lat.bc_MPS)
            eng = dmrg.EngineCombine(psi, M, dmrg_params)
        else:
            del eng.DMRG_params['chi_list']
            M = FermionicHaldaneModel(model_params)
            eng.init_env(model=M)
        E, psi = eng.run()
        data['QL'].append(psi.average_charge(bond=0)[0])
        data['ent_spectrum'].append(psi.entanglement_spectrum(by_charge=True)[0])
    return data
示例#28
0
def run(Jzs):
    L = 2
    model_params = dict(L=L,
                        Jx=1.,
                        Jy=1.,
                        Jz=Jzs[0],
                        bc_MPS='infinite',
                        conserve='Sz',
                        verbose=0)
    chi = 300
    dmrg_params = {
        'trunc_params': {
            'chi_max': chi,
            'svd_min': 1.e-10,
            'trunc_cut': None
        },
        'update_env': 20,
        'start_env': 20,
        'max_E_err': 0.0001,
        'max_S_err': 0.0001,
        'verbose': 1,
        'mixer': False
    }

    M = SpinChain(model_params)
    psi = MPS.from_product_state(M.lat.mps_sites(), (["up", "down"] * L)[:L],
                                 M.lat.bc_MPS)

    engine = dmrg.TwoSiteDMRGEngine(psi, M, dmrg_params)
    np.set_printoptions(linewidth=120)
    corr_length = []
    for Jz in Jzs:
        print("-" * 80)
        print("Jz =", Jz)
        print("-" * 80)
        model_params['Jz'] = Jz
        M = SpinChain(model_params)
        engine.init_env(
            model=M)  # (re)initialize DMRG environment with new model
        # this uses the result from the previous DMRG as first initial guess
        engine.run()
        # psi is modified by engine.run() and now represents the ground state for the current `Jz`.
        corr_length.append(psi.correlation_length(tol_ev0=1.e-3))
        print("corr. length", corr_length[-1])
        print("<Sz>", psi.expectation_value('Sz'))
        dmrg_params[
            'start_env'] = 0  # (some of) the parameters are read out again
    corr_length = np.array(corr_length)
    results = {
        'model_params': model_params,
        'dmrg_params': dmrg_params,
        'Jzs': Jzs,
        'corr_length': corr_length,
        'eval_transfermatrix': np.exp(-1. / corr_length)
    }
    return results
示例#29
0
def run_groundstate_xxz(L=30,
                        Jz=1.,
                        hz=0.,
                        conserve='best',
                        chi_max=50,
                        Jz_init=None):
    model_params = dict(L=L,
                        Jx=1.,
                        Jy=1.,
                        Jz=Jz,
                        hz=hz,
                        bc_MPS='finite',
                        conserve='best',
                        verbose=1)
    result = {}
    M = SpinChain(model_params)
    result['model'] = 'SpinChain'
    result['model_params'] = model_params

    result['sites'] = np.arange(L)
    result['bonds'] = np.arange(L - 1) + 0.5

    psi = MPS.from_product_state(M.lat.mps_sites(), (["up", "down"] * L)[:L])
    dmrg_params = {
        'trunc_params': {
            'chi_max': chi_max,
            'svd_min': 1.e-10,
            'trunc_cut': None
        },
        'mixer': True,
        'verbose': 1
    }
    if Jz_init:
        # run first time with small hx to break the symmetry
        model_params_Jz = model_params.copy()
        model_params_Jz['Jz'] = Jz_init
        M_Jz = SpinChain(model_params_Jz)
        dmrg_params['start_env'] = 10,
        run_DMRG(psi, M_Jz, dmrg_params)

    # run simulation
    t0 = time.time()

    info = run_DMRG(psi, M, dmrg_params)
    print("DMRG finished after", time.time() - t0, "s")

    # save results in output file
    result['chi'] = np.array(psi.chi)
    result['S'] = np.array(psi.entanglement_entropy())
    result['E'] = info['E']
    result['sweeps'] = info['sweep_statistics']['sweep']
    for key in ['E', 'S', 'max_trunc_err', 'max_E_trunc', 'max_chi']:
        result_key = 'sweep_' + key
        result[result_key] = np.array(info['sweep_statistics'][key])
    return result
示例#30
0
def example_TEBD_gs_tf_ising_next_nearest_neighbor(L, g, Jp, verbose=True):
    from tenpy.models.spins_nnn import SpinChainNNN2
    from tenpy.models.model import NearestNeighborModel
    print("finite TEBD, imaginary time evolution, transverse field Ising next-nearest neighbor")
    print("L={L:d}, g={g:.2f}, Jp={Jp:.2f}".format(L=L, g=g, Jp=Jp))
    model_params = dict(L=L,
                        Jx=1.,
                        Jy=0.,
                        Jz=0.,
                        Jxp=Jp,
                        Jyp=0.,
                        Jzp=0.,
                        hz=g,
                        bc_MPS='finite',
                        conserve=None,
                        verbose=verbose)
    # we start with the non-grouped sites, but next-nearest neighbor interactions, building the MPO
    M = SpinChainNNN2(model_params)
    product_state = ["up"] * M.lat.N_sites
    psi = MPS.from_product_state(M.lat.mps_sites(), product_state, bc=M.lat.bc_MPS)

    # now we group each to sites ...
    psi.group_sites(n=2)  # ... in the state
    M.group_sites(n=2)  # ... and model
    # now, M has only 'nearest-neighbor' interactions with respect to the grouped sites
    # thus, we can convert the MPO into H_bond terms:
    M_nn = NearestNeighborModel.from_MPOModel(M)  # hence, we can initialize H_bond from the MPO

    # now, we continue to run TEBD as before
    tebd_params = {
        'order': 2,
        'delta_tau_list': [0.1, 0.01, 0.001, 1.e-4, 1.e-5],
        'N_steps': 10,
        'max_error_E': 1.e-6,
        'trunc_params': {
            'chi_max': 30,
            'svd_min': 1.e-10
        },
        'verbose': verbose,
    }
    eng = tebd.Engine(psi, M_nn, tebd_params)  # use M_nn and grouped psi
    eng.run_GS()  # the main work...

    # expectation values:
    E = np.sum(M_nn.bond_energies(psi))  # bond_energies() works only a for NearestNeighborModel
    print("E = {E:.13f}".format(E=E))
    print("final bond dimensions: ", psi.chi)
    # we can split the sites of the state again for an easier evaluation of expectation values
    psi.group_split()
    mag_x = 2. * np.sum(psi.expectation_value("Sx"))  # factor of 2 for Sx vs Sigmax
    mag_z = 2. * np.sum(psi.expectation_value("Sz"))
    print("magnetization in X = {mag_x:.5f}".format(mag_x=mag_x))
    print("magnetization in Z = {mag_z:.5f}".format(mag_z=mag_z))
    return E, psi, M