def quencher(psi0, ti, tf, Nt): H_block = block_ops(blocks, static, dynamic, gen_basis, basis_args, dtype) return H_block.expm(psi0, iterate=False, n_jobs=njobs, a=-1j, start=ti, stop=tf, endpoint=True, num=Nt)
hop_list.extend([[-J_perp,i,i+1] for i in range(0,N,2)]) # perp/rung hopping hop_list_hc = [[J.conjugate(),i,j] for J,i,j in hop_list] # add h.c. terms # set up static and dynamic lists static = [ ["+-",hop_list], # hopping ["-+",hop_list_hc], # hopping h.c. ["nn",int_list_2], # U n_i^2 ["n",int_list_1] # -U n_i ] dynamic = [] # no dynamic operators # create block_ops object blocks=[dict(kblock=kblock) for kblock in range(L)] # blocks to project on to baisis_args = (N,) # boson_basis_1d manditory arguments basis_kwargs = dict(nb=nb,sps=sps,a=2) # boson_basis_1d optional args get_proj_kwargs = dict(pcon=True) # set projection to full particle basis H_block = block_ops(blocks,static,dynamic,boson_basis_1d,baisis_args,np.complex128, basis_kwargs=basis_kwargs,get_proj_kwargs=get_proj_kwargs) # setting up local Fock basis basis = boson_basis_1d(N,nb=nb,sps=sps) # setting up observables no_checks = dict(check_herm=False,check_symm=False,check_pcon=False) n_list = [hamiltonian([["n",[[1.0,i]]]],[],basis=basis,dtype=np.float64,**no_checks) for i in range(N)] ##### do time evolution # set up initial state i0 = np.random.randint(basis.Ns) # pick random state from basis set psi = np.zeros(basis.Ns,dtype=np.float64) psi[i0] = 1.0 # print info about setup state_str = "".join(str(int((basis[i0]//basis.sps**(L-i-1)))%basis.sps) for i in range(N)) print("total H-space size: {}, initial state: |{}>".format(basis.Ns,state_str)) # setting up parameters for evolution start,stop,num = 0,30,301 # 0.1 equally spaced points
def test(): L = 5 start = 0 stop = 10 num = 10 J = [[1.0, i, (i + 1) % L] for i in range(L)] h = [[1.0, i] for i in range(L)] static = [["xx", J], ["yy", J], ["zz", J]] dynamic = [["z", h, np.sin, ()]] blocks = [] for Nup in range(L + 1): blocks.append({"Nup": Nup}) H_block = block_diag_hamiltonian(blocks, static, dynamic, spin_basis_1d, (L, ), np.float64) H = hamiltonian(static, dynamic, N=L) for t in np.linspace(0, 2 * np.pi): E = H.eigvalsh(time=t) E_blocks = H.eigvalsh(time=t) np.testing.assert_allclose(E, E_blocks) static = [["zz", J]] dynamic = [["x", h, f, []]] blocks = [] for kblock in range(L): blocks.append({"kblock": kblock}) H = hamiltonian(static, dynamic, N=L) [E0] = H.eigsh(time=0.3, k=1, which='SA', return_eigenvectors=False) block_op = block_ops(blocks, static, dynamic, spin_basis_1d, (L, ), np.complex128, compute_all_blocks=True) # real time. expH = exp_op(H, a=-1j, start=start, stop=stop, iterate=True, num=num, endpoint=True) times = np.linspace(start, stop, num=num, endpoint=True) psi0 = np.random.ranf(H.Ns) psi0 /= np.linalg.norm(psi0) psi_exact_1 = H.evolve(psi0, 0, times, iterate=True, atol=1e-15, rtol=1e-15) psi_block_1 = block_op.evolve(psi0, 0, times, iterate=True, atol=1e-15, rtol=1e-15, n_jobs=4) psi_exact_2 = expH.dot(psi0, time=0.3) psi_block_2 = block_op.expm(psi0, H_time_eval=0.3, start=start, stop=stop, iterate=True, num=num, endpoint=True, n_jobs=2, block_diag=True) for psi_e_1, psi_e_2, psi_b_1, psi_b_2 in izip(psi_exact_1, psi_exact_2, psi_block_1, psi_block_2): np.testing.assert_allclose(psi_b_1, psi_e_1, atol=1e-7) np.testing.assert_allclose(psi_b_2, psi_e_2, atol=1e-7) expH.set_iterate(False) psi_exact_1 = H.evolve(psi0, 0, times, iterate=False, atol=1e-15, rtol=1e-15) psi_block_1 = block_op.evolve(psi0, 0, times, iterate=False, atol=1e-15, rtol=1e-15, n_jobs=4) psi_exact_2 = expH.dot(psi0, time=0.3) psi_block_2 = block_op.expm(psi0, H_time_eval=0.3, start=start, stop=stop, iterate=False, num=num, endpoint=True, block_diag=True) for psi_e_1, psi_b_1 in izip(psi_exact_1, psi_block_1): np.testing.assert_allclose(psi_b_1, psi_e_1, atol=1e-7) for psi_e_2, psi_b_2 in izip(psi_exact_2, psi_block_2): np.testing.assert_allclose(psi_b_2, psi_e_2, atol=1e-7) # imaginary time expH = exp_op(H, a=-1, start=start, stop=stop, iterate=True, num=num, endpoint=True) times = np.linspace(start, stop, num=num, endpoint=True) psi0 = np.random.ranf(H.Ns) psi0 /= np.linalg.norm(psi0) psi_exact_2 = expH.dot(psi0, time=0.3, shift=-E0) psi_block_2 = block_op.expm(psi0, a=-1, shift=-E0, H_time_eval=0.3, start=start, stop=stop, iterate=True, num=num, endpoint=True, block_diag=True) for psi_e_2, psi_b_2 in izip(psi_exact_2, psi_block_2): np.testing.assert_allclose(psi_b_2, psi_e_2, atol=1e-7) # same for iterate=False expH.set_iterate(False) psi_exact_2 = expH.dot(psi0, time=0.3, shift=-E0) psi_block_2 = block_op.expm(psi0, a=-1, shift=-E0, H_time_eval=0.3, start=start, stop=stop, iterate=False, num=num, endpoint=True, block_diag=True) for psi_e_2, psi_b_2 in izip(psi_exact_2, psi_block_2): np.testing.assert_allclose(psi_b_2, psi_e_2, atol=1e-7)