示例#1
0
def prepare_bath_hamilts(para):
    print('Starting iDMRG for the entanglement bath')
    bath_data = opath.join(para['bath_path'], para['bath_exp'])
    if para['if_load_bath'] and opath.isfile(bath_data):
        print('Bath data found. Load the bath.')
        bath, ob0, hamilt = load_pr(bath_data, ['A', 'ob0', 'hamilt'])
    else:
        print('Bath data not found. Calculate bath by iDMRG.')
        hamilt = hamiltonian_heisenberg(para['spin'], para['jxy'], para['jxy'],
                                        para['jz'], para['hx'] / 2,
                                        para['hz'] / 2)
        bath, ob0 = dmrg_infinite_size(para, hamilt=hamilt)[:2]
        save_pr(para['bath_path'], para['bath_exp'], [bath, ob0, hamilt],
                ['A', 'ob0', 'hamilt'])
    if (bath.is_symme_env is True) and (bath.dmrg_type is 'mpo'):
        bath.env[1] = bath.env[0]

    print('Preparing the physical-bath Hamiltonians')
    qes = QES_1D(para['d'], para['chi'], para['d'] * para['d'], para['l_phys'],
                 para['tau'])
    if bath.dmrg_type is 'mpo':
        qes.obtain_physical_gate_tensors(hamilt)
        qes.obtain_bath_h(bath.env, 'both')
    else:
        qes.obtain_bath_h_by_effective_ops_1d(bath.bath_op_onsite,
                                              bath.effective_ops,
                                              bath.hamilt_index)
    hamilts = [hamilt] + qes.hamilt_bath
    return hamilts, bath, ob0
示例#2
0
 def get_model_related_tree_dmrg(self, jx, jy, jz, hx, hz, tau=1e-6):
     if 'h2phys' not in self.model_related:
         self.model_related['h2phys'] = hamiltonian_heisenberg(
             self.spin, jx, jy, jz, hx, hz)
         self.model_related['h2_gate'] = expm(-tau / 2 *
                                              self.model_related['h2phys'])
     if 'tensor_gate' not in self.model_related:
         self.model_related['tensor_gate'] = hamiltonian2gate_tensors(
             self.model_related['h2phys'], tau)
     if 'hbath' not in self.model_related:
         self.model_related['hbath'] = bf.empty_list(self.nVirtual)
示例#3
0
def exact_ground_state(para=None):
    if para is None:
        para = parameters_ed_ground_state('chain')
    hamilt = hamiltonian_heisenberg(para['spin'], para['jx'], para['jy'],
                                    para['jz'], para['hx'] / 2, para['hz'] / 2)
    dims = [para['d'] for _ in range(para['l'])]
    a = EDbasic(dims)
    ob = dict()
    dim = para['d']**para['l']
    heff = LinearOp((dim, dim), lambda x: a.project_all_hamilt(
        x, [hamilt], para['tau'], para['couplings']))
    ob['e_eig'], a.v = eigs(heff, k=1, which='LM', v0=a.v.reshape(-1, ).copy())
    a.is_vec = True
    ob['e_eig'] = (1 - ob['e_eig']) / para['tau']
    ob['mx'], ob['mz'] = a.observe_magnetizations(list(range(para['l'])))
    ob['eb'] = a.observe_bond_energies(hamilt, para['positions_h2'])
    ob['lm'] = a.calculate_entanglement()
    ob['ent'] = entanglement_entropy(ob['lm'][-1])
    ob['e_site'] = sum(ob['eb']) / para['l']
    # ob['e_site'] = sum(ob['eb']) / para['l'] - sum(ob['mx']) * para['hx'] / para['l'] - \
    #                sum(ob['mz']) * para['hz'] / para['l']
    return a, ob
示例#4
0
def exact_time_evolution(v0, para=None):
    if para is None:
        para = parameters_ed_time_evolution('chain')
    a = EDbasic(para['d'], para['l'], ini=v0)

    hamilt = hamiltonian_heisenberg(para['spin'], para['jx'], para['jy'],
                                    para['jz'], para['hx'] / 2, para['hz'] / 2)
    gate = la.expm(1j * para['tau'] * hamilt)

    ob = dict()
    ob['lm'] = list()
    ob['ent'] = list()
    ob['mx'] = list()
    ob['mz'] = list()
    ob['eb'] = list()
    ob['e_site'] = list()

    time_now = 0
    for t in range(para['iterate_time']):
        for n in range(para['num_h2']):
            a.contract_with_local_matrix(gate,
                                         list(para['positions_h2'][n, :]))
        time_now += para['tau']
        tmp = time_now / para['ob_dt']
        if abs(tmp - round(tmp)) < 1e-9:
            mx, mz = a.observe_magnetizations()
            ob['mx'].append(mx)
            ob['mz'].append(mz)
            ob['eb'].append(
                a.observe_bond_energies(hamilt, para['positions_h2']))
            ob['lm'].append(a.calculate_entanglement())
            ob['ent'].append(entanglement_entropy(ob['lm'][-1]))
            ob['e_site'].append(
                sum(ob['eb'][-1]) / para['l'] +
                sum(ob['mx'][-1]) * para['hx'] / para['l'] +
                sum(ob['mz'][-1]) * para['hz'] / para['l'])
            print('t = ' + str(time_now) + ', Mz = ' +
                  str(sum(ob['mz']) / a.l))
def qes_1d_ed(para=None):
    if para is None:
        para = parameter_qes_by_ed()
    print('Starting iDMRG for the entanglement bath')
    bath_data = opath.join(para['bath_path'], para['bath_exp'])
    if para['if_load_bath'] and opath.isfile(bath_data):
        print('Bath data found. Load the bath.')
        bath, ob0, hamilt = load_pr(bath_data, ['A', 'ob0', 'hamilt'])
    else:
        print('Bath data not found. Calculate bath by iDMRG.')
        hamilt = hamiltonian_heisenberg(para['spin'], para['jxy'], para['jxy'],
                                        para['jz'], para['hx'] / 2,
                                        para['hz'] / 2)
        bath, ob0 = dmrg_infinite_size(para, hamilt=hamilt)[:2]
        save_pr(para['bath_path'], para['bath_exp'], [bath, ob0, hamilt],
                ['A', 'ob0', 'hamilt'])
    if (bath.is_symme_env is True) and (bath.dmrg_type is 'mpo'):
        bath.env[1] = bath.env[0]

    print('Preparing the physical-bath Hamiltonians')
    qes = QES_1D(para['d'], para['chi'], para['d'] * para['d'], para['l_phys'],
                 para['tau'])
    if bath.dmrg_type is 'mpo':
        qes.obtain_physical_gate_tensors(hamilt)
        qes.obtain_bath_h(bath.env, 'both')
    else:
        qes.obtain_bath_h_by_effective_ops_1d(bath.bath_op_onsite,
                                              bath.effective_ops,
                                              bath.hamilt_index)

    print('Starting ED for the entanglement bath')
    dims = [para['d'] for _ in range(para['l_phys'])]
    dims = [para['chi']] + dims + [para['chi']]
    hamilts = [hamilt] + qes.hamilt_bath
    ob = dict()
    solver = EDbasic(dims)
    heff = LinearOp((solver.dim_tot, solver.dim_tot),
                    lambda x: solver.project_all_hamilt(
                        x, hamilts, para['tau'], para['couplings']))
    ob['e_eig'], solver.v = eigs(heff,
                                 k=1,
                                 which='LM',
                                 v0=solver.v.reshape(-1, ).copy())
    solver.is_vec = True
    ob['e_eig'] = (1 - ob['e_eig']) / para['tau']
    ob['mx'], ob['mz'] = solver.observe_magnetizations(para['phys_sites'])
    ob['eb'] = solver.observe_bond_energies(
        hamilt, para['positions_h2'][1:para['num_h2'] - 1, :])
    ob['lm'] = solver.calculate_entanglement()
    ob['ent'] = entanglement_entropy(ob['lm'])
    ob['e_site'] = sum(ob['eb']) / (para['l_phys'] - 1)
    ob['corr_xx'] = solver.observe_correlations(para['pos4corr'],
                                                para['op'][1])
    ob['corr_zz'] = solver.observe_correlations(para['pos4corr'],
                                                para['op'][3])
    for n in range(para['pos4corr'].shape[0]):
        p1 = para['pos4corr'][n, 0] - 1
        p2 = para['pos4corr'][n, 1] - 1
        ob['corr_xx'][n] -= ob['mx'][p1] * ob['mx'][p2]
        ob['corr_zz'][n] -= ob['mz'][p1] * ob['mz'][p2]
    return bath, solver, ob0, ob
示例#6
0
def tebd_standard(para=None):
    """
    # Standard TEBD algorithm for any physical H (but only one in-equivalent H)
    # For multiple in-equivalent H's or QES, use tebd_any_h instead
    # Prepare para['positions_h2'] to determine the lattice
    """
    start = time.time()
    if para is None:
        para = para_standard()
    ob = dict()
    ob['lm'] = list()
    ob['ent'] = list()
    ob['mx'] = list()
    ob['mz'] = list()
    ob['eb'] = list()
    ob['e_site'] = list()
    mps = MpsStandardTEBD(para['l'],
                          para['d'],
                          para['chi'],
                          para['spin'],
                          evolve_way='gates')
    mps.correct_orthogonal_center(0, True)
    hamilt = hamiltonian_heisenberg(para['spin'], para['jxy'], para['jxy'],
                                    para['jz'], para['hx'] / 2, para['hz'] / 2)
    n_now = 0
    time_now = 0
    e0 = 100  # for checking convergence
    for nt in range(0, para['taut']):
        tau = para['tau0'] * (para['dtau']**nt)
        print('Now tau = ' + str(tau))
        u2 = la.expm(-tau * hamilt)
        gates = [[], []]
        gates[0], lm0, gates[1] = np.linalg.svd(
            u2.reshape(para['d'], para['d'], para['d'],
                       para['d']).transpose(0, 2, 1,
                                            3).reshape(para['d'] * para['d'],
                                                       para['d'] * para['d']))
        gates[0] = (gates[0].dot(np.diag(np.sqrt(lm0)))).reshape(
            para['d'], para['d'], para['d'] * para['d']).transpose(0, 2, 1)
        gates[1] = (np.diag(np.sqrt(lm0)).dot(gates[1])).reshape(
            para['d'] * para['d'], para['d'], para['d']).transpose(1, 0, 2)
        for t in range(para['iterate_time']):
            for nh in range(para['num_h2']):
                p1 = para['positions_h2'][nh, 0]
                p2 = para['positions_h2'][nh, 1]
                mps.evolve_gate_tebd(p1, p2, gates)
                mps.truncate_mps_tebd(p1, p2)
            mps.norm_mps(True)  # normalize MPS
            time_now += tau
            if (para['save_mode'] is 'all') and ((t % para['dt_ob']) == 0):
                print('time(beta) = ' + str(time_now))
                ob['lm'].append(mps.lm)
                ob['ent'].append(mps.ent)
                ob['mx'].append(mps.observe_magnetization(para['op'][1]))
                ob['mz'].append(mps.observe_magnetization(para['op'][3]))
                ob['e_site'].append(
                    sum(ob['eb'][n_now]) / para['l'] +
                    sum(ob['mx'][n_now]) * para['hx'] / para['l'] +
                    sum(ob['mz'][n_now]) * para['hz'] / para['l'])
                print('E per site = ' + str(ob['e_site'][n_now]))
                n_now += 1
            elif para['if_break'] is True:
                e1 = sum(
                    mps.observe_bond_energy_from_jxyz(para['positions_h2'],
                                                      para['jxy'], para['jxy'],
                                                      para['jz'])) / para['l']
                if (abs(e0 - e1) < para['break_tol'] and ((t % para['dt_ob']) == 0)) \
                        or (t == para['iterate_time']):
                    ob['lm'].append(mps.lm)
                    ob['ent'].append(mps.ent)
                    ob['mx'].append(mps.observe_magnetization(1))
                    ob['mz'].append(mps.observe_magnetization(3))
                    ob['eb'].append(
                        mps.observe_bond_energy_from_jxyz(
                            para['positions_h2'], para['jxy'], para['jxy'],
                            para['jz']))
                    ob['e_site'].append(
                        sum(ob['eb'][n_now]) / para['l'] +
                        sum(ob['mx'][n_now]) * para['hx'] / para['l'] +
                        sum(ob['mz'][n_now]) * para['hz'] / para['l'])
                    print('effective beta = ' + str(time_now))
                    print('Converged with E = ' + str(ob['e_site'][n_now]) +
                          '; Convergence  = ' + str(abs(e0 - e1)))
                    n_now += 1
                    break
                elif (t % para['dt_ob']) == 0:
                    print('effective beta = ' + str(time_now))
                    print('<ss> = ' + str(e1) + '; Convergence  = ' +
                          str(abs(e0 - e1)))
                    e0 = e1
        print('TEBD finished with ' + str(time.time() - start) + 's')
    mps.clean_to_save()
    return mps, ob, para
示例#7
0
def deep_dmrg_infinite_size(para=None):
    from library.MPSClass import MpsDeepInfinite as Minf
    is_print = True

    t_start = time.time()
    info = dict()
    if is_print:
        print('Start deep DMRG calculation')
    if para is None:
        para = pm.generate_parameters_deep_mps_infinite()

    hamilt = hamiltonian_heisenberg(para['spin'], para['jxy'], para['jxy'],
                                    para['jz'], -para['hx'] / 2,
                                    -para['hz'] / 2)
    tensor = hamiltonian2cell_tensor(hamilt, para['tau'])
    A = Minf(para['form'],
             para['d'],
             para['chi'],
             para['d'],
             para['chib0'],
             para['chib'],
             para['is_symme_env'],
             n_site=para['n_site'],
             is_debug=is_debug)
    # use standard DMRG to get the GS MPS
    A, ob0, info0 = dmrg_infinite_size(para, A, hamilt)
    # get uMPO from the MPS
    A.get_unitary_mpo_from_mps()

    if A.n_site == 1:
        e0 = 0
        e1 = 1
    else:
        e0 = np.zeros((1, 3))
        e1 = np.ones((1, 3))
    de = 1
    for t in range(0, para['sweep_time']):
        A.update_ort_tensor_dmps('left')
        A.update_left_env_dmps_simple(tensor)
        if not A.is_symme_env:
            A.update_ort_tensor_dmps('right')
            A.update_right_env_dmps_simple(tensor)
        A.update_central_tensor_dmps(tensor)
        if t % para['dt_ob'] == 0:
            A.rho_from_central_tensor_dmps()
            e1 = A.observe_energy(hamilt)
            if is_print:
                print('At the %g-th sweep: Eb = ' % t + str(e1))
            de = np.sum(abs(e0 - e1))
            if de > para['break_tol']:
                e0 = e1
            elif is_print:
                print('Converged with de = %g' % de)
                break
        if t == para['sweep_time']:
            print('Not sufficiently converged with de = %g' % de)
    ob = {'eb': e1}
    info['t_cost'] = time.time() - t_start
    if is_print:
        print('Total time cost: %g' % info['t_cost'])
    return A, ob, info, ob0, info0
示例#8
0
def dmrg_infinite_size(para=None, A=None, hamilt=None):
    from library.MPSClass import MpsInfinite as Minf
    is_print = True

    t_start = time.time()
    info = dict()
    if is_print:
        print('Start ' + str(para['n_site']) + '-site iDMRG calculation')
    if para is None:
        para = pm.generate_parameters_infinite_dmrg_sawtooth()
    if hamilt is None:
        hamilt = hamiltonian_heisenberg(para['spin'], para['jxy'], para['jxy'],
                                        para['jz'], para['hx'] / 2,
                                        para['hz'] / 2)
    if A is None:
        if para['dmrg_type'] is 'mpo':
            d = para['d']**para['n_site']
        else:
            d = para['d']
        A = Minf(para['form'],
                 d,
                 para['chi'],
                 para['d']**para['n_site'],
                 n_site=para['n_site'],
                 is_symme_env=para['is_symme_env'],
                 dmrg_type=para['dmrg_type'],
                 hamilt_index=para['hamilt_index'])
    if A.dmrg_type is 'mpo':
        tensor = hamiltonian2cell_tensor(hamilt, para['tau'])
    else:
        tensor = np.zeros(0)
    if A.n_site == 1:
        # singe-site iDMRG
        e0 = 0
        e1 = 1
    else:
        # double-site iDMRG (including White's way)
        e0 = np.zeros((1, 3))
        e1 = np.ones((1, 3))
    de = 1
    if A.is_symme_env:
        A.update_ort_tensor_mps('left')
        if A.dmrg_type is 'white':
            A.update_bath_onsite()
            A.update_effective_ops()
        else:
            A.update_left_env(tensor)
    else:
        A.update_ort_tensor_mps('both')
        A.update_left_env(tensor)
        A.update_right_env(tensor)
    # iDMRG sweep
    for t in range(0, para['sweep_time']):
        if A.dmrg_type is 'mpo':
            A.update_central_tensor(tensor)
        else:
            A.update_central_tensor((para['tau'], 'full'))

        if t % para['dt_ob'] == 0:
            A.rho_from_central_tensor()
            e1 = A.observe_energy(hamilt)
            if is_print:
                print('At the %g-th sweep: Eb = ' % t + str(e1))
            de = np.sum(abs(e0 - e1)) / A.n_site
            if de > para['break_tol']:
                e0 = e1
            elif is_print:
                print('Converged with de = %g' % de)
                break
        if t == para['sweep_time']:
            print('Not sufficiently converged with de = %g' % de)

        if A.is_symme_env:
            A.update_ort_tensor_mps('left')
            if A.dmrg_type is 'mpo':
                A.update_left_env(tensor)
            else:
                A.update_bath_onsite()
                A.update_effective_ops()
        else:
            A.update_ort_tensor_mps('both')
            A.update_left_env(tensor)
            A.update_right_env(tensor)
    ob = {'eb': e1}
    info['t_cost'] = time.time() - t_start
    if is_print:
        print('Total time cost: %g' % info['t_cost'])
    return A, ob, info