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
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)
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
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
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
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
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