예제 #1
0
def dmrg_infinite_size(para=None):
    from MPSClass import MpsInfinite as Minf
    t_start = time.time()
    info = dict()
    print('Start iDMRG calculation')
    if para is None:
        para = pm.generate_parameters_infinite_dmrg()

    hamilt = hamiltonian_heisenberg(para['jxy'], para['jxy'], para['jz'],
                                    para['hx'] / 2, para['hz'] / 2)
    tensor = hamiltonian2cell_tensor(hamilt)
    A = Minf(para['form'], para['d'], para['chi'])

    e0 = 0
    for t in range(0, para['sweep_time']):
        A.update_left_env(tensor)
        A.update_right_env(tensor)
        A.update_central_tensor(tensor)
        if t % para['dt_ob'] == 0:
            e1 = A.observe_energy(hamilt)
            de = abs(e0 - e1)
            if de > para['break_tol']:
                e0 = e1
            else:
                print('Converged with de = %g' % de)
                break
        if t == para['sweep_time']:
            print('Not sufficiently converged with de = %g' % de)
    info['t_cost'] = time.time() - t_start
    return A
예제 #2
0
def find_degenerate_rho(para, it_time, tol=1e-2):
    dege_rho = list()
    for t in range(it_time):
        # Randomly initialize env
        env = list()
        env.append(np.random.randn(para['chi'], para['d']**para['n_site'], para['chi']))
        env[0] = env[0] + env[0].transpose(2, 1, 0)
        env[0] /= np.linalg.norm(env[0])
        env.append(env[0].copy())
        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, env=env)[:2]
        bath.rho_from_central_tensor()
        rho = bath.rho
        if len(dege_rho) > 0:
            delta = list()
            for n in range(len(dege_rho)):
                delta.append(np.sqrt(np.abs(2-2*np.abs(
                    dege_rho[n].reshape(1, -1).dot(rho.reshape(-1, 1))[0, 0]))))
                # delta.append(np.abs(np.trace(dege_rho[n].dot(rho))))
            print('Differences = ' + str(delta))
            if np.min(delta) > tol:
                dege_rho.append(rho)
                print(str(len(dege_rho)) + ' have been found.')
        else:
            dege_rho.append(rho)
    print('After ' + str(it_time) + ' iterations, ' + str(len(dege_rho)) + ' have been found.')
예제 #3
0
def find_degenerate_ground_state(para, it_time, tol=1e-2):
    # if not para['is_symme_env']:
    #     para['is_symme_env'] = True
    #     print('In \'find_degenerate_bath\', set para[\'is_symme_env\'] = True')

    dege_states = list()
    for t in range(it_time):
        # Randomly initialize env
        env = list()
        env.append(np.random.randn(para['chi'], para['d']**para['n_site'], para['chi']))
        env[0] = env[0] + env[0].transpose(2, 1, 0)
        env[0] /= np.linalg.norm(env[0])
        env.append(env[0].copy())
        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, env=env)[:2]
        gs = bath.mps[1]
        if len(dege_states) > 0:
            delta = list()
            add_new = True
            for n in range(len(dege_states)):
                delta.append(np.sqrt(np.abs(2-2*np.abs(
                    dege_states[n].reshape(1, -1).dot(gs.reshape(-1, 1))[0, 0]))))
                add_new = add_new and (delta[-1] > tol)
            print('Differences = ' + str(delta))
            if add_new:
                dege_states.append(gs)
                print(str(len(dege_states)) + ' envs have been found.')
        else:
            dege_states.append(gs)
    print('After ' + str(it_time) + ' iterations, ' + str(len(dege_states)) + ' have been found.')
예제 #4
0
def prepare_bath_hamilts(para, inputs=None):
    # inputs = (bath, ob0, hamilt)
    print('Starting iDMRG for the entanglement bath')
    bath_data = opath.join(para['bath_path'], para['bath_exp'])
    if inputs is None:
        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'])
    else:
        bath, ob0, hamilt = inputs
    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'], spin=para['spin'])
    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
예제 #5
0
def find_degenerate_hbaths(para, it_time, tol=1e-2):
    hbaths = list()
    for t in range(it_time):
        # Randomly initialize env
        env = list()
        env.append(np.random.randn(para['chi'], para['d'] ** para['n_site'], para['chi']))
        env[0] = env[0] + env[0].transpose(2, 1, 0)
        env[0] /= np.linalg.norm(env[0])
        env.append(env[0].copy())
        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, env=env)[:2]

        para_qes = parameter_qes_gs_by_ed(para)
        qes_hamilt = prepare_bath_hamilts(para_qes, (bath, ob0, hamilt))[0]
        qes_hamilt = qes_hamilt[1]
        # print(np.trace(qes_hamilt), qes_hamilt.shape)

        # find degenerate hbaths
        if len(hbaths) > 0:
            delta = list()
            add_new = True
            for n in range(len(hbaths)):
                delta1 = (hbaths[n]/np.linalg.norm(hbaths[n])).reshape(1, -1).dot(
                    (qes_hamilt/np.linalg.norm(qes_hamilt)).reshape(-1, 1))[0, 0]
                delta.append(np.sqrt(np.abs(2 - 2*delta1)))
                add_new = add_new and (delta[-1] > tol)
            print('Differences = ' + str(delta))
            if add_new:
                hbaths.append(qes_hamilt)
                print(str(len(hbaths)) + ' envs have been found.')
        else:
            hbaths.append(qes_hamilt)
    print('After ' + str(it_time) + ' iterations, ' + str(len(hbaths)) + ' have been found.')
예제 #6
0
def dmrg_infinite_size(para=None, A=None, hamilt=None):
    from 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()
    if hamilt is None:
        hamilt = hamiltonian_heisenberg(para['spin'], para['jxy'], para['jxy'],
                                        para['jz'], -para['hx'] / 2,
                                        -para['hz'] / 2)
    tensor = hamiltonian2cell_tensor(hamilt, para['tau'])
    if A is None:
        A = Minf(para['form'],
                 para['d'],
                 para['chi'],
                 para['d'],
                 n_site=para['n_site'],
                 is_symme_env=para['is_symme_env'])

    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']):
        if A.is_symme_env:
            A.update_ort_tensor_mps('left')
            A.update_left_env(tensor)
        else:
            A.update_ort_tensor_mps('both')
            A.update_left_env(tensor)
            A.update_right_env(tensor)
        A.update_central_tensor(tensor)
        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)
    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
예제 #7
0
def deep_dmrg_infinite_size(para=None):
    from 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, env=None):
    from 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()
    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'] == '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'],
                 spin=para['spin'],
                 is_symme_env=para['is_symme_env'],
                 dmrg_type=para['dmrg_type'],
                 hamilt_index=para['hamilt_index'],
                 env=env)
    # consider to change the initial mps tensors

    if A.dmrg_type == '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 == '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 == '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 == '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