def realization(H0, basis, psi_i, w, I, start, stop, num, endpoint, i): print i disorder = [[np.random.uniform(-w, w), i] for i in range(L)] Hl = hamiltonian([["n", disorder]], [], basis=H0.basis, dtype=np.float32, check_pcon=False, check_herm=False, check_symm=False) expH = exp_op(H0 + Hl, a=-1j, start=start, stop=stop, num=num, endpoint=endpoint, iterate=True) times = expH.grid psi_t = expH.dot(psi_i) obs = obs_vs_time( psi_t, times, {"I": I}, basis=basis) #,Sent_args=dict(sparse=True,sub_sys_A=[0])) try: return obs["I"], obs["Sent_time"]["Sent"] except KeyError: return obs["I"]
def QAOA_evolution(psi_0, H, B, angles, t_it, opt_MT=False, store_states=False): psi = psi_0 energy = obs_vs_time(np.reshape(psi_0, (-1, 1)), [0], dict(energy=H))['energy'][0] if store_states or opt_MT: psi_t = np.array([psi]) if store_states: energy_t = np.array([energy]) H_t = np.zeros(1) B_t = np.zeros(1) t = np.zeros(1) for it in range(len(angles)): t_op = angles[it] * t_it op = H if it % 2 == 0 else B psi_it = op.evolve(psi, 0, t_op) obs_it = obs_vs_time(psi_it, t_op, dict(energy=H)) psi_it = np.transpose(psi_it) energy_it = obs_it['energy'] psi = psi_it[-1] energy = energy_it[-1] if store_states or opt_MT: psi_t = np.concatenate((psi_t, psi_it)) if store_states: energy_t = np.concatenate((energy_t, energy_it)) H_t = np.concatenate( (H_t, [angles[it] if it % 2 == 0 else 0 for _ in t_it])) B_t = np.concatenate( (B_t, [angles[it] if it % 2 == 1 else 0 for _ in t_it])) t = np.concatenate((t, it + t_it)) return (psi_t, energy_t, H_t, B_t, t) if store_states else psi_t if opt_MT else energy
def real(H_dict,I,psi_0,w,t,i): # body of function goes below ti = time() # start timing function for duration of reach realisation # create a parameter list which specifies the onsite potential with disorder params_dict=dict(H0=1.0) for j in range(L): params_dict["n"+str(j)] = uniform(-w,w) # using the parameters dictionary construct a hamiltonian object with those # parameters defined in the list H = H_dict.tohamiltonian(params_dict) # use exp_op to get the evolution operator U = exp_op(H,a=-1j,start=t.min(),stop=t.max(),num=len(t),iterate=True) psi_t = U.dot(psi_0) # get generator psi_t for time evolved state # use obs_vs_time to evaluate the dynamics t = U.grid # extract time grid stored in U, and defined in exp_op obs_t = obs_vs_time(psi_t,t,dict(I=I)) # print reporting the computation time for realization print("realization {}/{} completed in {:.2f} s".format(i+1,n_real,time()-ti)) # return observable values return obs_t["I"]
def getObs(v_t, times, J1, J2): Obs_time = obs_vs_time(v_t, times, {'Jx_1':J1[0], 'Jy_1':J1[1], 'Jz_1':J1[2], 'Jx_2':J2[0], 'Jy_2':J2[1], 'Jz_2':J2[2]}, return_state=True) print(Obs_time.keys()) Jx_1_time=Obs_time['Jx_1'] Jy_1_time=Obs_time['Jy_1'] Jz_1_time=Obs_time['Jz_1'] Jx_2_time=Obs_time['Jx_2'] Jy_2_time=Obs_time['Jy_2'] Jz_2_time=Obs_time['Jz_2'] J1_time = [Jx_1_time, Jy_1_time, Jz_1_time] J2_time = [Jx_2_time, Jy_2_time, Jz_2_time] return J1_time, J2_time
# define initial Fock state through strings s_f = "".join("1" for i in range(Nf)) + "".join("0" for i in range(L - Nf)) s_b = "".join("1" for i in range(Nb)) # basis.index accepts strings and returns the index which corresponds to that state in the basis list i_0 = basis.index(s_b, s_f) # find index of product state in basis psi_0 = np.zeros(basis.Ns) # allocate space for state psi_0[i_0] = 1.0 # set MB state to be the given product state print("H-space size: {:d}, initial state: |{:s}>|{:s}>".format( basis.Ns, s_b, s_f)) # ###### time evolve initial state and measure entanglement between species t = Floquet_t_vec(Omega, 10, len_T=10) # t.vals=times, t.i=initial time, t.T=drive period psi_t = H_BFM.evolve(psi_0, t.i, t.vals, iterate=True) # measure observable Sent_args = dict(basis=basis, sub_sys_A="left") meas = obs_vs_time(psi_t, t.vals, {}, Sent_args=Sent_args) # read off measurements Entropy_t = meas["Sent_time"]["Sent_A"] # ###### # configuring plots plt.plot(t / t.T, Entropy_t) plt.xlabel("$\\mathrm{driving\\ cycle}$", fontsize=18) plt.ylabel('$S_\\mathrm{ent}(t)$', fontsize=18) plt.grid(True) plt.tick_params(labelsize=16) plt.tight_layout() plt.savefig('BFM.pdf', bbox_inches='tight') #plt.show() plt.close()
"Initial state and energy calculated. It took {:.2f} seconds to calculate". format(time() - ti)) print("Ground state energy was calculated to be {:.2f}".format(E[0])) """evolve that energy and state""" print('Starting Evolution') ti = time() psi_t = FHM.operator_dict["H"].evolve(psi_0, 0.0, t_p.times) psi_t = np.squeeze(psi_t) print('Evolution finished. It took {:.2f} seconds to evolve the system'.format( time() - ti)) """creating additional operators""" FHM.create_number_operator() FHM.create_time_dependent_current_operator() """find the observables according to the state""" print('Generating our expectations from operators.') ti = time() expectations = obs_vs_time(psi_t, t_p.times, FHM.operator_dict) expectations['phi'] = phi(t_p.times, perimeter_params=lat, cycles=t_p.cycles) print("Expectations generated. It took {:.2f} seconds".format(time() - ti)) """save all observables to a file""" outfile = './Data/expectations:{}sites-{}up-{}down-{}t0-{}U-{}cycles-{}steps-{}pbc.npz'.format( param.L, param.N_up, param.N_down, param.t0, param.U, t_p.cycles, t_p.n_steps, param.pbc) print('Saving our expectations.') ti = time() np.savez(outfile, **expectations) print('Expectations saved. It took {:.2f} seconds.'.format(time() - ti)) print('Program finished. It took {:.2f} seconds to run'.format(time() - t_init))
}, VF=True) # call Floquet class VF = Floq.VF # read off Floquet states EF = Floq.EF # read off quasienergies # ##### calculate initial state (GS of HF_02) and its energy EF_02, psi_i = HF_02.eigsh(k=1, which="SA", maxiter=1E4) psi_i = psi_i.reshape((-1, )) # ##### time-dependent measurements # calculate measurements Sent_args = {"basis": basis, "chain_subsys": [j for j in range(L // 2)]} #meas = obs_vs_time((psi_i,EF,VF),t.vals,{"E_time":HF_02/L},Sent_args=Sent_args) #""" # alternative way by solving Schroedinger's eqn psi_t = H.evolve(psi_i, t.i, t.vals, rtol=1E-9, atol=1E-9) meas = obs_vs_time(psi_t, t.vals, {"E_time": HF_02 / L}, Sent_args=Sent_args) #""" # read off measurements Energy_t = meas["E_time"] Entropy_t = meas["Sent_time"]["Sent"] # ##### calculate diagonal ensemble measurements DE_args = { "Obs": HF_02, "Sd_Renyi": True, "Srdm_Renyi": True, "Srdm_args": Sent_args } DE = diag_ensemble(L, psi_i, EF, VF, **DE_args) Ed = DE["Obs_pure"] Sd = DE["Sd_pure"]
Lindblad_EOM_v2, f_params=EOM_args, iterate=False, atol=1E-12, rtol=1E-12, verbose=True) print(rho_t.shape) # this version returns the generator for psi # psi_t=ham.evolve(psi_0,0.0,times,iterate=True) # this version returns psi directly, last dimension contains time dynamics. The squeeze is necessary for the # obs_vs_time to work properly # psi_t = H.evolve(psi_0, 0.0, times) # psi_t = np.squeeze(psi_t) print("Evolution done! This one took {:.2f} seconds".format(time() - ti)) # calculate the expectations for every bastard in the operator dictionary ti = time() # note that here the expectations expectations = obs_vs_time(rho_t, times, operator_dict) print(type(expectations)) current_partial = (expectations['neighbour']) current = 1j * lat.a * (current_partial - current_partial.conjugate()) expectations['current'] = current print("Expectations calculated! This took {:.2f} seconds".format(time() - ti)) expectations['evotime'] = time() - t_evo print("Saving Expectations. We have {} of them".format(len(expectations))) np.savez(outfile, **expectations) # #
U1_1 = exp_op(Hzz_1+A*Hx_1,a=-1j*t.T/4) U2_1 = exp_op(Hzz_1-A*Hx_1,a=-1j*t.T/2) # user-defined generator for stroboscopic dynamics def evolve_gen(psi0,nT,*U_list): yield psi0 for i in range(nT): # loop over number of periods for U in U_list: # loop over unitaries psi0 = U.dot(psi0) yield psi0 # get generator objects for time-evolved states psi_12_t = evolve_gen(psi0_12,nT,U2_12,U1_12,U2_12) psi_1_t = evolve_gen(psi0_1,nT,U2_1,U1_1,U2_1) # ###### compute expectation values of observables ###### # measure Hzz as a function of time Obs_12_t = obs_vs_time(psi_12_t,t.vals,dict(E=Hzz_12),return_state=True) Obs_1_t = obs_vs_time(psi_1_t,t.vals,dict(E=Hzz_1),return_state=True) # calculating the entanglement entropy density Sent_t_12 = basis_12.ent_entropy(Obs_12_t["psi_t"],sub_sys_A=range(L_12//2))["Sent_A"]/(L_12//2) Sent_t_1 = basis_1.ent_entropy(Obs_1_t["psi_t"],sub_sys_A=range(L_1//2))["Sent_A"]/(L_1//2) # calculate Page entropy density values s_p_12 = np.log(2)-2.0**(-L_12//2-L_12)/(2*(L_12//2)) s_p_1 = np.log(3)-3.0**(-L_1//2-L_1)/(2*(L_1//2)) # ###### plotting results ###### plt.plot(t.strobo.inds,(Obs_12_t["E"]-E_12_min)/(-E_12_min),marker='.',markersize=5,label="$S=1/2$") plt.plot(t.strobo.inds,(Obs_1_t["E"]-E_1_min)/(-E_1_min),marker='.',markersize=5,label="$S=1$") plt.grid() plt.ylabel("$Q(t)$",fontsize=20) plt.xlabel("$t/T$",fontsize=20) plt.savefig("TFIM_Q.pdf")
i_0 = sp_basis.index(ind) # find index of product state psi_0 = np.zeros(sp_basis.Ns, dtype = np.complex64) # allocate space for state psi_0[i_0] = 1.0# set MB state to be the given product state psi_0 = psi_0.flatten() params_dict_quench = dict(H0=1.0) if dis_flag ==1: for j in range(L): params_dict_quench["z"+str(j)] = (W/2)*np.cos(2*math.pi*0.721*j+2*math.pi*phi) # create quench quasiperiodic fields list else: for j in range(L): params_dict_quench["z"+str(j)] = (W/2)*np.random.uniform(0,1) # create quench random fields list HAM_quench = H_dict.tohamiltonian(params_dict_quench) # build post-quench Hamiltonian psi_t = HAM_quench.evolve(psi_0, 0.0, t_tab) # evolve with post-quench Hamiltonian imb_t = obs_vs_time(psi_t, t_tab, dict(I=I)) # compute imbalance evolution i_t = imb_t["I"] Losch = np.square(np.abs(np.dot(psi_0,psi_t))).flatten() # Loschmidt echo return_rate = -np.log(Losch) # Loschmidt return rate if dis_flag == 1: directory = '../DATA/ImbQP/L'+str(L)+'/D'+str(W)+'/' PATH_now = LOCAL+os.sep+directory+os.sep if not os.path.exists(PATH_now): os.makedirs(PATH_now) else: directory = '../DATA/Neelrandom/L'+str(L)+'/D'+str(W)+'/' PATH_now = LOCAL+os.sep+directory+os.sep if not os.path.exists(PATH_now): os.makedirs(PATH_now)
# L = 12 # syste size # coupling strenghts J = 1.0 # spin-spin coupling h = 0.8945 # x-field strength g = 0.945 # z-field strength # create site-coupling lists J_zz = [[J, i, (i + 1) % L] for i in range(L)] # PBC 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]] static_2 = [["zz", J_zz], ["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) H2 = hamiltonian(static_2, dynamic, basis=basis, dtype=np.float64) # compute eigensystems of H1 and H2 E1, V1 = H1.eigh() psi1 = V1[:, 14] # pick any state as initial state E2, V2 = H2.eigh() # # time-evolve state under H2 times = np.linspace(0.0, 5.0, 10) psi1_t = H2.evolve(psi1, 0.0, times, iterate=True) # calculate expectation values of observables Obs_time = obs_vs_time(psi1_t, times, dict(E1=H1, Energy2=H2)) print("Output keys are same as input keys:", Obs_time.keys()) E1_time = Obs_time['E1']
# user-defined generator for stroboscopic dynamics def evolve_gen(psi0, nT, *U_list): yield psi0 for i in range(nT): # loop over number of periods for U in U_list: # loop over unitaries psi0 = U.dot(psi0) yield psi0 # get generator objects for time-evolved states psi_1d_t = evolve_gen(psi0_1d, nT, U1_1d, U2_1d, U1_1d) psi_2d_t = evolve_gen(psi0_2d, nT, U1_2d, U2_2d, U1_2d) # ###### compute expectation values of observables ###### # measure Hzz as a function of time Obs_1d_t = obs_vs_time(psi_1d_t, t.vals, dict(E=Hzz_1d), return_state=True) Obs_2d_t = obs_vs_time(psi_2d_t, t.vals, dict(E=Hzz_2d), return_state=True) # calculating the entanglement entropy density Sent_time_1d = basis_1d.ent_entropy( Obs_1d_t["psi_t"], sub_sys_A=range(L_1d // 2))["Sent_A"] / (L_1d // 2) Sent_time_2d = basis_2d.ent_entropy( Obs_2d_t["psi_t"], sub_sys_A=range(N_2d // 2))["Sent_A"] / (N_2d // 2) # calculate entanglement entropy density s_p_1d = np.log(2) - 2.0**(-L_1d // 2 - L_1d) / (2 * (L_1d // 2)) s_p_2d = np.log(2) - 2.0**(-N_2d // 2 - N_2d) / (2 * (N_2d // 2)) # ###### plotting results ###### plt.plot(t.strobo.inds, (Obs_1d_t["E"] - E_1d_min) / (-E_1d_min), marker='.', markersize=5, label="$S=1/2$")
H = H_0 + V_t psi_0 = psi_0.ravel() rho_0 = np.outer(psi_0.conj(), psi_0).astype(np.complex128) n_copies = 7 psi_0_vec = np.tile(psi_0, (n_copies, 1)).T psi_t_vec = H.evolve(psi_0_vec, 0, times, eom="SE", iterate=True, atol=1e-10, rtol=1e-10) O_expt_vec = obs_vs_time(psi_t_vec, times, dict(O=O_0))["O"] psi_t = H.evolve(psi_0, 0, times, eom="SE", iterate=True, atol=1e-10, rtol=1e-10) O_expt = obs_vs_time(psi_t, times, dict(O=O_0))["O"] rho_t = H.evolve(rho_0, 0, times, eom="LvNE", iterate=True,
t_a_relative_err_R_prime_track = [] t_a_relative_err_delay = [] min_steps = 1000 max_steps = 10000 delta_steps = 100 for j in range(int((max_steps - min_steps) / delta_steps) + 1): # create our time parameters class n_steps = min_steps + j * delta_steps t_p = time_evolution_params(perimeter_params=lat, cycles=2, nsteps=n_steps) # evolve the untracked state psi_t = FHM.operator_dict["H"].evolve(psi_0, 0.0, t_p.times) psi_t = np.squeeze(psi_t) # find expectation from these states current = obs_vs_time(psi_t, t_p.times, dict(J=FHM.operator_dict['current'])) # define the tracked time parameters class and the target J t_p_track = time_evolution_params(perimeter_params=lat_track, cycles=2, nsteps=n_steps) J_target = UnivariateSpline(t_p_track.times, param_track.J_scale * current['J'], s=0) # generate our extended vector and create our observables class for things to work (we don't actually use it for its # intended purpose here) gamma_t = np.append(np.squeeze(psi_0), 0.0) obs = observables( gamma_t[:-1], J_target(0.0),
rtol = rtols[_i] H=hamiltonian(static_pm,dynamic_zxz,basis=basis,dtype=dtype,check_herm=False,check_symm=False) Ozz=hamiltonian([],dynamic_zz,basis=basis,dtype=dtype,check_herm=False,check_symm=False) H2=hamiltonian(static_yy,[],basis=basis,dtype=dtype,check_herm=False,check_symm=False) _,psi0 = H.eigsh(time=0,k=1,sigma=-100.0) psi0=psi0.squeeze() psi_t=H.evolve(psi0,0.0,t,iterate=True,rtol=solver_rtol,atol=solver_atol) psi_t2=H.evolve(psi0,0.0,t,rtol=solver_rtol,atol=solver_atol) Obs_list = {"Ozz_t":Ozz,"Ozz":Ozz(time=np.sqrt(np.exp(0.0)) )} Sent_args={'basis':basis,'chain_subsys':range( L//2 )} Obs = obs_vs_time(psi_t,t,Obs_list,return_state=True,Sent_args=Sent_args) Obs2 = obs_vs_time(psi_t2,t,Obs_list,return_state=True,Sent_args=Sent_args) Expn = np.array([Obs['Ozz_t'],Obs['Ozz']]) psi_t = Obs['psi_t'] Sent = Obs['Sent_time']['Sent'] Expn2 = np.array([Obs2['Ozz_t'],Obs2['Ozz']]) psi_t2 = Obs2['psi_t'] Sent2 = Obs2['Sent_time']['Sent'] np.testing.assert_allclose(Expn,Expn2,atol=atol,rtol=rtol,err_msg='Failed observable comparison!') np.testing.assert_allclose(psi_t,psi_t2,atol=atol,rtol=rtol,err_msg='Failed state comparison!') np.testing.assert_allclose(Sent,Sent2,atol=atol,err_msg='Failed ent entropy comparison!')
E, psi_0 = H_0.eigsh(k=1, which="SA", maxiter=10000) H = H_0 + V_t psi_0 = psi_0.ravel() rho_0 = np.outer(psi_0.conj(), psi_0).astype(np.complex128) psi_t = H.evolve(psi_0, 0, times, eom="SE", iterate=True, atol=1e-10, rtol=1e-10) O_expt = obs_vs_time(psi_t, times, dict(O=O_0))["O"] rho_t = H.evolve(rho_0, 0, times, eom="LvNE", iterate=False, atol=1e-10, rtol=1e-10) O_expt_2 = np.einsum("ij...,ji->...", rho_t, O_0).real np.testing.assert_allclose(O_expt, O_expt_2) rho_t = H.evolve(rho_0, 0, times, eom="LvNE",
0.0, t, iterate=True, eom="SE", rtol=solver_rtol, atol=solver_atol) psi_t2 = H.evolve(psi0, 0.0, t, eom="SE", rtol=solver_rtol, atol=solver_atol) Obs = obs_vs_time(psi_t, t, Obs_list, return_state=True, Sent_args=Sent_args) Obs2 = obs_vs_time(psi_t2, t, Obs_list, return_state=True, Sent_args=Sent_args) Expn = np.array([Obs['Ozz_t'], Obs['Ozz']]) psi_t = Obs['psi_t'] Sent = Obs['Sent_time']['Sent_A'] Expn2 = np.array([Obs2['Ozz_t'], Obs2['Ozz']]) psi_t2 = Obs2['psi_t'] Sent2 = Obs2['Sent_time']['Sent_A']
# ax.text(j, i, '{:0.5f}'.format(z), ha='center', va='center') # # # plt.show() final_psis = np.array(time_psis).T print(final_psis.shape) # final_psis=np.sum(final_psis,axis=1) final_psis = np.swapaxes(final_psis, 1, 2) print('Low rank propagation done. Time taken %.5f seconds' % (time() - ti)) if K == 0: psi_t = final_psis[:, :, 0] expectations = obs_vs_time(psi_t, times, operator_dict) current_partial = (expectations['neighbour']) current = 1j * lat.a * (current_partial - current_partial.conjugate()) expectations['current'] = current else: expectation_dics = [] for j in range(rank): psi_t = (final_psis[:, :, j]) # print(psi_0.shape) # psi_t=np.concatenate(psi_0,psi_t,axis=1) # print(psi_t.shape) new = np.hstack((psi_0 / np.sqrt(rank), psi_t)) psi_t = new # print(psi_t.shape) expectations = obs_vs_time(psi_t, times, operator_dict)
# define observables parameters obs_args = {"basis": basis, "check_herm": False, "check_symm": False} obs_args_sc = {"basis": basis_sc, "check_herm": False, "check_symm": False} # in atom-photon Hilbert space n = hamiltonian([["|n", [[1.0]]]], [], dtype=np.float64, **obs_args) sz = hamiltonian([["z|", [[1.0, 0]]]], [], dtype=np.float64, **obs_args) sy = hamiltonian([["y|", [[1.0, 0]]]], [], dtype=np.complex128, **obs_args) # in the semi-classical Hilbert space sz_sc = hamiltonian([["z", [[1.0, 0]]]], [], dtype=np.float64, **obs_args_sc) sy_sc = hamiltonian([["y", [[1.0, 0]]]], [], dtype=np.complex128, **obs_args_sc) # ##### calculate expectation values ##### # in atom-photon Hilbert space Obs_t = obs_vs_time(psi_t, t.vals, {"n": n, "sz": sz, "sy": sy}) O_n, O_sz, O_sy = Obs_t["n"], Obs_t["sz"], Obs_t["sy"] # in the semi-classical Hilbert space Obs_sc_t = obs_vs_time(psi_sc_t, t.vals, {"sz_sc": sz_sc, "sy_sc": sy_sc}) O_sz_sc, O_sy_sc = Obs_sc_t["sz_sc"], Obs_sc_t["sy_sc"] ##### plot results ##### import matplotlib.pyplot as plt import pylab # define legend labels str_n = "$\\langle n\\rangle,$" str_z = "$\\langle\\sigma^z\\rangle,$" str_x = "$\\langle\\sigma^x\\rangle,$" str_z_sc = "$\\langle\\sigma^z\\rangle_\\mathrm{sc},$" str_x_sc = "$\\langle\\sigma^x\\rangle_\\mathrm{sc}$" # plot spin-photon data fig = plt.figure()
def spin_photon_Nsite_DM(N, coupling, Nph_tot=10, state='ferro', decouple=0, photon_state=0,coherent=False, t_max=10.00,t_steps=100, obs_photon=5, vect='x', omega=0.5, J_zz=0.0, J_xx=0.0, J_xy=0.0, J_z=0.0, J_x=0.0, return_state_DM=False, periodic=True, init_state=None): ##### define Boson model parameters ##### Nph_tot=Nph_tot # maximum photon occupation Nph=1.0# mean number of photons in initial state L=N; Omega=omega # drive frequency A=coupling # spin-photon coupling strength (drive amplitude) Delta=0.0 # difference between atom energy levels ph_energy=[[Omega]] # photon energy loss=[[0.2]] # emission term at_energy=[[Delta,i] for i in range(L)] # atom energy if type(decouple) == int: absorb=[[A / np.sqrt(N-decouple),i] for i in range(0, L-decouple)] # absorption term emit=[[A/ np.sqrt(N-decouple),i] for i in range(0, L-decouple)] # emission term elif type(decouple) == tuple: absorb=[[A / np.sqrt(len(decouple)),i] for i in decouple] # absorption term emit=[[A/ np.sqrt(len(decouple)),i] for i in decouple] # emission term else: ValueError('Improper input for decouple variable'); return -1; ##### define Boson model parameters ##### if periodic==True: boundary = L; else: boundary = L-1; H_zz = [[J_zz,i,(i+1)%L] for i in range(boundary)] # PBC H_xx = [[J_xx,i,(i+1)%L] for i in range(boundary)] # PBC H_xy = [[J_xy,i,(i+1)%L] for i in range(boundary)] # PBC H_z = [[J_z,i] for i in range(L)] # PBC H_x = [[J_x,i] for i in range(L)] # PBC psi_atom = get_product_state(N,state=state,vect=vect); # define static and dynamics lists static=[["|n",ph_energy],["x|-",absorb],["x|+",emit],["z|",at_energy], ["+-|",H_xy],["-+|",H_xy],["zz|",H_zz], ["z|",H_z],["x|",H_x]] dynamic=[] # compute atom-photon basis basis=photon_basis(spin_basis_1d,L=N,Nph=Nph_tot) atom_basis=spin_basis_1d(L=N) H=hamiltonian(static,dynamic,dtype=np.float64,basis=basis,check_herm=False) # compute atom-photon Hamiltonian H if type(init_state) == tuple: H_zz = [[init_state[0],i,(i+1)%L] for i in range(boundary)] # PBC H_xy = [[0,i,(i+1)%L] for i in range(boundary)] # PBC H_z = [[0,i] for i in range(L)] # PBC H_x = [[init_state[1],i] for i in range(L)] # PBC static=[["+-",H_xy],["-+",H_xy],["zz",H_zz], ["z",H_z],["x",H_x]]; init_Spin_Hamiltonian = hamiltonian(static,dynamic,dtype=np.float64,basis=spin_basis_1d(N),check_herm=False) psi_atom = get_ground_state(N,init_Spin_Hamiltonian); if coherent==False: psi_boson=np.zeros([Nph_tot+1]); psi_boson[photon_state]=1 else: psi_boson = coherent_state(np.sqrt(photon_state), Nph_tot+1) psi=np.kron(psi_atom,psi_boson) ##### calculate time evolution ##### obs_args={"basis":basis,"check_herm":False,"check_symm":False} t = np.linspace(0, t_max, t_steps); psi_t = H.evolve(psi, 0.0, t); a = hamiltonian([["|-", [[1.0 ]] ]],[],dtype=np.float64,**obs_args); n=hamiltonian([["|n", [[1.0 ]] ]],[],dtype=np.float64,**obs_args); a_psi = a.dot(psi); a_psi_t = H.evolve(a_psi, 0.0, t); g2_0 = n.expt_value(a_psi_t); n_t = n.expt_value(psi_t); g2_0 = g2_0 / (n_t[0] * n_t); g2_0 = np.real(g2_0); ##### define observables ##### # define GLOBAL observables parameters n_t=hamiltonian([["|n", [[1.0 ]] ]],[],dtype=np.float64,**obs_args) nn_t=hamiltonian([["|nn", [[1.0 ]] ]],[],dtype=np.float64,**obs_args) z_tot_t = hamiltonian([["z|", [[1.0,i] for i in range(L)] ]],[],dtype=np.float64,**obs_args); x_tot_t = hamiltonian([["x|", [[1.0,i] for i in range(L)] ]],[],dtype=np.float64,**obs_args); zz_tot_t = hamiltonian([["zz|", [[1.0,i,(i+1)%L] for i in range(boundary)] ]],[],dtype=np.float64,**obs_args); xx_tot_t = hamiltonian([["xx|", [[1.0,i,(i+1)%L] for i in range(boundary)] ]],[],dtype=np.float64,**obs_args); Obs_dict = {"n":n_t,"nn":nn_t,"z_tot":z_tot_t, "x_tot":x_tot_t, "zz_tot":zz_tot_t, "xx_tot":xx_tot_t}; for i in range(N): for j in range(i+1, N): stringz = "z%1dz%1d" % (i, j); stringx = "x%1dx%1d" % (i, j); zz_ham = hamiltonian([["zz|", [[1.0,i,j]] ]],[],dtype=np.float64,**obs_args); xx_ham = hamiltonian([["xx|", [[1.0,i,j]] ]],[],dtype=np.float64,**obs_args); Obs_dict.update({stringz:zz_ham, stringx, xx_ham}); Obs_t = obs_vs_time(psi_t,t,Obs_dict); ####### Number of times to sample the cavity state, could sample at every time so num = 1 ############### Sent = np.zeros_like(t); AC_ent = np.zeros_like(t); num = t_steps//obs_photon print(num) obs_pht_t = t[::num]; obs_pht_ray = np.zeros([len(obs_pht_t), Nph_tot+1, Nph_tot+1]); spin_subsys_dm = np.zeros([len(t), 2**(N//2), 2**(N//2)]) pairwise_concurrence = np.zeros([len(t), N, N]); for i in range(len(t)): dictionary = basis.ent_entropy(psi_t.T[i],sub_sys_A='particles',return_rdm='both'); AC_ent[i]=dictionary["Sent_A"]; spin_dm = dictionary["rdm_A"]; photon_dm = dictionary["rdm_B"]; dict_atom_subsys = atom_basis.ent_entropy(spin_dm,sub_sys_A=range(N//2),return_rdm='both'); Sent[i]=N//2 * dict_atom_subsys['Sent_A']; spin_subsys_dm[i]=dict_atom_subsys['rdm_A']; for j in range(N): for k in range(j+1, N): two_spin_dict = atom_basis.ent_entropy(spin_dm,sub_sys_A=(j,k),return_rdm='both'); two_spin_dm = two_spin_dict['rdm_A']; two_spin_conc = concurrence(two_spin_dm); pairwise_concurrence[i,j,k] = two_spin_conc; if t[i] in obs_pht_t: obs_pht_ray[i//num] = photon_dm if return_state_DM==False: return t, AC_ent, Sent, Obs_t, obs_pht_ray, g2_0, pairwise_concurrence; else: return t, AC_ent, Sent, Obs_t, obs_pht_ray, g2_0, pairwise_concurrence, spin_subsys_dm;
h = 0.8945 # x-field strength g = 0.945 # z-field strength # create site-coupling lists J_zz = [[J, i, (i + 1) % L] for i in range(L)] # PBC 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]] static_2 = [["zz", J_zz], ["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) H2 = hamiltonian(static_2, dynamic, basis=basis, dtype=np.float64) # compute eigensystems of H1 and H2 E1, V1 = H1.eigh() psi1 = V1[:, 14] # pick any state as initial state E2, V2 = H2.eigh() # # time-evolve state under H2 times = np.linspace(0.0, 5.0, 10) psi1_t = H2.evolve(psi1, 0.0, times, iterate=True) # calculate expectation values of observables Obs_time = obs_vs_time(psi1_t, times, dict(E1=H1, Energy2=H2), return_state=True) print("Output keys are same as input keys:", Obs_time.keys()) E1_time = Obs_time['E1'] psi_time = Obs_time['psi_t']