def spin_entropy(dtype, symm, Sent_args): if symm: basis = spin_basis_1d(L, kblock=0, pblock=1, zblock=1) else: basis = spin_basis_1d(L) # define operators with OBC using site-coupling lists J_zz = [[1.0, i, (i + 1) % L, (i + 2) % L] for i in range(0, L)] J_xy = [[1.0, i, (i + 1) % L] for i in range(0, L)] # static and dynamic lists static = [["+-", J_xy], ["-+", J_xy], ["zxz", J_zz]] # build Hamiltonian H = hamiltonian(static, [], basis=basis, dtype=dtype, check_herm=False, check_symm=False) # diagonalise H E, V = H.eigh() psi0 = V[:, 0] rho0 = np.outer(psi0.conj(), psi0) rho_d = rho0 Ed, Vd = np.linalg.eigh(rho_d) S_pure = ent_entropy(psi0, basis, **Sent_args) S_DM = ent_entropy(rho0, basis, **Sent_args) S_DMd = ent_entropy({"V_rho": Vd, "rho_d": abs(Ed)}, basis, **Sent_args) S_all = ent_entropy({"V_states": V}, basis, **Sent_args) return (S_pure, S_DM, S_DMd, S_all)
def spin_entropy(dtype, symm, Sent_args): if symm: basis = spin_basis_1d(L, kblock=0, pblock=1, zblock=1) else: basis = spin_basis_1d(L) # define operators with OBC using site-coupling lists J_zz = [[1.0, i, (i + 1) % L, (i + 2) % L] for i in range(0, L)] J_xy = [[1.0, i, (i + 1) % L] for i in range(0, L)] # static and dynamic lists static = [["+-", J_xy], ["-+", J_xy], ["zxz", J_zz]] # build Hamiltonian H = hamiltonian(static, [], basis=basis, dtype=dtype, check_herm=False, check_symm=False) # diagonalise H E, V = H.eigh() psi0 = V[:, 0] rho0 = np.outer(psi0.conj(), psi0) rho_d = rho0 Ed, Vd = np.linalg.eigh(rho_d) S_pure = ent_entropy(psi0, basis, **Sent_args) S_DM = ent_entropy(rho0, basis, **Sent_args) S_all = ent_entropy({'V_states': V}, basis, **Sent_args) return (S_pure, S_DM, S_all)
def spin_photon_entropy(dtype, symm, Sent_args): Nph = 6 if symm: basis = photon_basis(spin_basis_1d, L, Nph=Nph, kblock=0, pblock=1) else: basis = photon_basis(spin_basis_1d, L, Nph=Nph) # spin x_field = [[-1.0, i] for i in range(L)] z_field = [[-1.0, i] for i in range(L)] J_nn = [[-1.0, i, (i + 1) % L] for i in range(L)] # spin-photon absorb = [[-0.5 * 1.0 / np.sqrt(Nph), i] for i in range(L)] emit = [[-0.5 * np.conj(1.0) / np.sqrt(Nph), i] for i in range(L)] # photon ph_energy = [[11.0 / L, i] for i in range(L)] static = [["zz|", J_nn], ["z|", z_field], ["x|", x_field], ["x|-", absorb], ["x|+", emit], ["I|n", ph_energy]] H = hamiltonian(static, [], L, dtype=np.float64, basis=basis, check_herm=False, check_symm=False) # diagonalise H E, V = H.eigh() psi0 = V[:, 0] rho0 = np.outer(psi0.conj(), psi0) rho_d = rho0 Ed, Vd = np.linalg.eigh(rho_d) S_pure = ent_entropy(psi0, basis, **Sent_args) S_DM = ent_entropy(rho0, basis, **Sent_args) S_DMd = ent_entropy({"V_rho": Vd, "rho_d": abs(Ed)}, basis, **Sent_args) S_all = ent_entropy({"V_states": V}, basis, **Sent_args) return (S_pure, S_DM, S_DMd, S_all)
def _do_ramp(psi_0, H, basis, v, E_final, V_final): """ Auxiliary function to evolve the state and calculate the entropies after the ramp. --- arguments --- psi_0: initial state H: time-dependent Hamiltonian basis: spin_basis_1d object containing the spin basis (required for Sent) E_final, V_final: eigensystem of H(t_f) at the end of the ramp t_f=1/(2v) """ # determine total ramp time t_f = 0.5 / v # time-evolve state from time 0.0 to time t_f psi = H.evolve(psi_0, 0.0, t_f) # calculate entanglement entropy subsys = range(basis.L // 2) # define subsystem Sent = ent_entropy(psi, basis, chain_subsys=subsys)["Sent"] # calculate diagonal entropy in the basis of H(t_f) S_d = diag_ensemble(basis.L, psi, E_final, V_final, Sd_Renyi=True)["Sd_pure"] # return np.asarray([S_d, Sent])
sys.path.insert(0, quspin_path) from quspin.operators import hamiltonian # Hamiltonians and operators from quspin.basis import boson_basis_1d, spin_basis_1d # Hilbert space spin basis from quspin.tools.measurements import ent_entropy import numpy as np # generic math functions ##### define model parameters ##### L = 6 # system size J = 1.0 # hopping U = np.sqrt(2) # interactions strenth # define site-coupling lists interaction = [[U / 2.0, i, i] for i in range(L)] # PBC chem_pot = [[-U / 2.0, i] for i in range(L)] # PBC hopping = [[J, i, (i + 1) % L] for i in range(L)] # PBC #### define hcb model basis = boson_basis_1d(L=L, Nb=L, sps=L + 1, kblock=0, pblock=1) # Hubbard-related model static = [["+-", hopping], ["-+", hopping], ["n", chem_pot], ["nn", interaction]] H = hamiltonian(static, [], basis=basis, dtype=np.float32) E, V = H.eigh() Sent = ent_entropy({'V_states': V}, basis, chain_subsys=range(L // 2))['Sent'] #print(Sent)
base=hf.Base_states(N,N//2) ind_n=np.zeros((len(base), 2)) for i in range(len(base)): somma=0 for j in range(N//2): somma+=int(base[i][j]) ind_n[i]=[somma,i] StateList=[] for i in range(N//2+1): StateList.append(np.where(ind_n[:,0]==i)[0]) compute = { 'time': lambda t, p: t, 'losch': lambda t, p: np.square(np.absolute(qu.fidelity(psi_0, p))), 'imb': lambda t,p: np.real(I.expt_value(p)), 'entropy': lambda t, p: ent_entropy(p, basis, chain_subsys=subsys)['Sent_A'], 'num_ent': lambda t, p: hf.Num_ent(N, p, StateList) } evo = qu.Evolution(psi_0, H, compute=compute, method='solve') for pt in evo.at_times(t_tab): ts=evo.results['time'] Sent=N//2*(np.array(evo.results['entropy'])/np.log2(math.e)) P_N=np.array(evo.results['num_ent'])/np.log2(math.e) Losch=np.array(-np.log(evo.results['losch']))/N Imb=2*np.array(evo.results['imb']) if dis_flag == 1: directory = '../DATA/NeelQPLongJz'+str(int_flag)+'/L'+str(N)+'/D'+str(W)+'/'
from __future__ import print_function, division # import sys, os quspin_path = os.path.join(os.getcwd(), "../../") sys.path.insert(0, quspin_path) # from quspin.operators import hamiltonian # Hamiltonians and operators from quspin.basis import spin_basis_1d # Hilbert space spin basis from quspin.tools.measurements import ent_entropy import numpy as np # generic math functions # L = 12 # syste size # coupling strenghts h = 0.8945 # x-field strength g = 0.945 # z-field strength # create site-coupling lists x_field = [[h, i] for i in range(L)] z_field = [[g, i] for i in range(L)] # create static and dynamic lists static_1 = [["x", x_field], ["z", z_field]] dynamic = [] # create spin-1/2 basis basis = spin_basis_1d(L, kblock=0, pblock=1) # set up Hamiltonian H1 = hamiltonian(static_1, dynamic, basis=basis, dtype=np.float64) # compute eigensystems of H1 E1, V1 = H1.eigh() psi1 = V1[:, 14] # pick any state as initial state # calculate entanglement entropy Sent = ent_entropy(psi1, basis, chain_subsys=[1, 3, 6, 7, 11]) print(Sent['Sent_A'])
def Fidelity(psi_i, H_fid, t_vals, delta_t, psi_f=None, all_obs=False, Vf=None): ''' This function calculates the physical quantities given a time-dep Hamiltonian H_fid. If psi_f is not given, then it returns the fidelity in the instantaneous eigenstate, otherwise --- the fidelity in the final state. ''' basis = H_fid.basis # evolve state #psi_t = H_fid.evolve(psi_i,t_vals[0],t_vals,iterate=True,atol=1E-12,rtol=1E-12) # fidelity fid = [] if all_obs: # get sysstem size L = basis.L # entanglement entropy density Sent = [] subsys = [j for j in range(L / 2)] # energy E = [] # energy fluctuations dE = [] Sd = [] psi = psi_i.copy() for i, t_i in enumerate(t_vals): #for i, psi in enumerate(psi_t): psi = exp_op(H_fid(time=t_i), a=-1j * delta_t).dot(psi) if psi_f is not None: # calculate w.r.t. final state psi_target = psi_f else: # calculate w.r.t. instantaneous state _, psi_inst = H_fid.eigsh(time=t_vals[i], k=1, sigma=-100.0) psi_target = psi_inst.squeeze() fid.append(abs(psi.conj().dot(psi_target))**2) #print i, abs(psi.conj().dot(psi_target))**2 if all_obs: if L > 1: EGS, _ = H_fid.eigsh(time=t_vals[i], k=2, which='BE', maxiter=1E10, return_eigenvectors=False) else: EGS = H_fid.eigvalsh(time=t_vals[i])[0] E.append( H_fid.matrix_ele(psi, psi, time=t_vals[i]).real / L - EGS / L) if i == 0: dE.append(0.0) else: dE.append( np.sqrt((H_fid * H_fid(time=t_vals[i])).matrix_ele( psi, psi, time=t_vals[i]).real / L**2 - E[i]**2)) #print H_fid2.matrix_ele(psi,psi,time=t_vals[i]).real/L**2 - E[i]**2 pn = abs(Vf.conj().T.dot(psi))**2.0 + np.finfo(psi[0].dtype).eps Sd.append(-pn.dot(np.log(pn)) / L) if basis.L != 1: Sent.append( ent_entropy(psi, basis, chain_subsys=subsys)['Sent']) else: Sent.append(float('nan')) if not all_obs: return fid else: return fid, E, dE, Sent, Sd
def MB_observables(psi, times, protocol, pos_actions, h_field, L, J=1.0, hx_i=-2.0, hx_f=2.0, hz=1.0, fin_vals=False, bang=True): """ this function returns instantaneous observalbes during ramp OR when fin_vals=True only the final values at the end of the ramp ---------------- observables: ---------------- Fidelity E: energy above instantaneous GS delta_E: energy fluctuations Sd: diagonal entropy Sent: entanglement entropy """ # read in local directory path str1 = os.getcwd() str2 = str1.split('\\') n = len(str2) my_dir = str2[n - 1] # define Hamiltonian b = hx_f lin_fun = lambda t: b # define Hamiltonian H = Hamiltonian(L, fun=lin_fun, **{'J': J, 'hz': hz}) if bang: exp_dict_dataname = my_dir + "/unitaries/unitaries_L={}_bang".format( L) + '.pkl' V_target_dataname = my_dir + "/unitaries/target_basis_L={}_bang".format( L) + '.pkl' else: exp_dict_dataname = my_dir + "/unitaries/unitaries_L={}_cont".format( L) + '.pkl' V_target_dataname = my_dir + "/unitaries/target_basis_L={}_cont".format( L) + '.pkl' # define Sent subsystem subsys = [i for i in range(L // 2)] # preallocate variables Fidelity, E, delta_E, Sd, Sent = [], [], [], [], [] expm_dict = cPickle.load(open(exp_dict_dataname, "rb")) V_target = cPickle.load(open(V_target_dataname, "rb")) """ # define matrix exponential delta_times=times[1]-times[0] exp_H=exp_op(H,a=-1j*delta_times) # calculate final basis _,V_target=H.eigh() """ i = 0 while True: # instantaneous fidelity Fidelity.append(abs(psi.conj().dot(V_target[:, 0]))**2) # excess energy above inst energy EGS = H.eigsh(k=1, which='SA', maxiter=1E10, return_eigenvectors=False)[0] E.append(H.matrix_ele(psi, psi).real / L - EGS / L) # inst energy density delta_E.append( np.sqrt((H(time=0) * H).matrix_ele(psi, psi) - H.matrix_ele(psi, psi)**2 + 1E-21 * 1j).real / L) # diagonal entropy in target basis pn = abs(V_target.conj().T.dot(psi))**2.0 + np.finfo(psi[0].dtype).eps Sd.append(-pn.dot(np.log(pn)) / L) # entanglement entropy if L == 1: Sent.append(0.0) else: Sent.append(ent_entropy(psi, H.basis, chain_subsys=subsys)['Sent']) if i == len(protocol): break else: # go to next step b = protocol[i] # --> induces a change in H #psi = exp_H.dot(psi) psi = expm_dict[int(np.rint( (b - min(h_field)) / min(pos_actions)))].dot(psi) i += 1 if fin_vals: return Fidelity[-1], E[-1], delta_E[-1], Sd[-1], Sent[-1] else: return Fidelity, E, delta_E, Sd, Sent
basis = spin_basis_1d(L=L, pauli=False) # Hubbard-related model static = [["+-", hopping], ["-+", hopping], ["zz", interaction], ["x", field]] # define operators Sx_0 = hamiltonian([['x', sigmaz]], [], basis=basis_0, dtype=np.float32) Sx_full = np.kron(Sx_0.todense(), np.eye(2**(L - 1))) H = hamiltonian(static, [], basis=basis, dtype=np.float32) E, V = H.eigh() psi = V[:, 0] DM = ent_entropy(psi, basis, chain_subsys=[0], DM='chain_subsys')['DM_chain_subsys'] #print(np.around(DM,3)) # calculate expectation in full and reduced basis Exct_1 = np.trace(Sx_0.dot(DM)) try: Exct_2 = float(reduce(np.dot, [psi.conjugate(), Sx_full, psi])) except NameError: Exct_2 = float( functools.reduce(np.dot, [psi.conjugate(), Sx_full, psi])) np.testing.assert_allclose( Exct_1 - Exct_2, 0.0, atol=1E-5, err_msg='Failed onsite DM comaprison for PBC={}!'.format(PBC))
basis = spin_basis_1d(L, S=S, kblock=0, pblock=1) #print(chain_subsys) #print(basis.Ns) H = hamiltonian(static, [], basis=basis, check_symm=False, check_herm=False, check_pcon=False) _, V = H.eigh() psi = V[:, 0] tools_ent = ent_entropy(psi, basis, chain_subsys=chain_subsys, DM='both') basis_ent = basis.ent_entropy(psi, sub_sys_A=chain_subsys, return_rdm='both') Sent_tools = tools_ent['Sent'] Sent_basis = basis_ent['Sent_A'] rho_tools_A = tools_ent['DM_chain_subsys'] rho_basis_A = basis_ent['rdm_A'] rho_tools_B = tools_ent['DM_other_subsys'] rho_basis_B = basis_ent['rdm_B'] #print(rho_tools_A)
def MB_observables(protocol, param_SA, matrix_dict, fin_vals=False): global hx_discrete """ this function returns instantaneous observalbes during ramp OR when fin_vals=True only the final values at the end of the ramp ---------------- observables: ---------------- Fidelity E: energy above instantaneous GS delta_E: energy fluctuations Sd: diagonal entropy Sent: entanglement entropy """ # calculate final basis V_target = param_SA['V_target'] hx_i = param_SA['hx_initial_state'] hx_f = param_SA['hx_final_state'] J = param_SA['J'] L = param_SA['L'] hz = param_SA['hz'] H = param_SA['H'] # calculate initial state psi = param_SA['psi_i'] psif = param_SA['psi_target'].squeeze() psi = psi.squeeze() # define Sent subsystem subsys = [i for i in range(L // 2)] # preallocate variables Fidelity, E, delta_E, Sd, Sent = ([], [], [], [], []) i = 0 hx_discrete = protocol while True: # instantaneous fidelity Fidelity.append(abs(psi.conj().dot(V_target[:, 0]))**2) # excess energy above inst energy EGS = H.eigsh(k=1, which='SA', maxiter=1E10, return_eigenvectors=False)[0] E.append(H.matrix_ele(psi, psi).real / L - EGS / L) # inst energy density delta_E.append( np.sqrt((H(time=0) * H).matrix_ele(psi, psi) - H.matrix_ele(psi, psi)**2).real / L) # diagonal entropy in target basis pn = abs(V_target.conj().T.dot(psi))**2.0 + np.finfo(psi[0].dtype).eps Sd.append(-pn.dot(np.log(pn)) / L) # entanglement entropy Sent.append(ent_entropy(psi, H.basis, chain_subsys=subsys)['Sent']) if i == len(protocol) - 1: break else: # go to next step b = hx_discrete[i] # --> induces a change in H psi = matrix_dict[b].dot(psi) i += 1 if fin_vals: return Fidelity[-1], E[-1], delta_E[-1], Sd[-1], Sent[-1] else: return Fidelity, E, delta_E, Sd, Sent