def unitaries(H, c_op_list, dt, K): U_ops = [] if K == 0: U_ops.append( expm_multiply_parallel(H.tocsr(), a=-1j * delta, dtype=np.complex128)) else: for op in c_op_list: exponent = -1j * H * dt exponent += (dt * K / 2) * (op * op - op.getH() * op) extra = 1j * np.sqrt(K * dt) * op P1 = exponent + extra P2 = exponent - extra # P1array=P1.toarray() # P2array=P2.toarray() # P1array=P1array-P2array # plt.spy(P1array.real,markersize=2,precision=10**(-6)) # plt.show() # plt.spy(P1array.imag, markersize=2, precision=10 ** (-6)) # plt.show() U_prop = expm_multiply_parallel(P1.tocsr(), a=1, dtype=np.complex128) V_prop = expm_multiply_parallel(P2.tocsr(), a=1, dtype=np.complex128) # U_prop = exp_op(P1, a=1) # V_prop = exp_op(P2, a=1) U_ops.append(U_prop) U_ops.append(V_prop) return U_ops
def test_ramdom_int_matrix(N=3500, ntest=10, seed=0): np.random.seed(seed) i = 0 while (i < ntest): print("testing random integer matrix {}".format(i + 1)) data_rvs = lambda n: np.random.randint( -100, 100, size=n, dtype=np.int8) A = random(N, N, density=np.log(N) / N, data_rvs=data_rvs, dtype=np.int8) A = A.tocsr() v = np.random.normal( 0, 1, size=(N, 10)) + 1j * np.random.normal(0, 1, size=(N, 10)) v /= np.linalg.norm(v) v1 = expm_multiply(-0.01j * A, v) v2 = expm_multiply_parallel(A, a=-0.01j, dtype=np.complex128).dot(v) np.testing.assert_allclose( v1, v2, rtol=0, atol=5e-15, err_msg='random matrix test failed, seed {:d}'.format(seed)) i += 1
def test_imag_time(L=20, seed=0): np.random.seed(seed) basis = spin_basis_1d(L, m=0, kblock=0, pblock=1, zblock=1) J = [[1.0, i, (i + 1) % L] for i in range(L)] static = [["xx", J], ["yy", J], ["zz", J]] H = hamiltonian(static, [], basis=basis, dtype=np.float64) (E, ), psi_gs = H.eigsh(k=1, which="SA") psi_gs = psi_gs.ravel() A = -(H.tocsr() - E * eye(H.Ns, format="csr", dtype=np.float64)) U = expm_multiply_parallel(A) v1 = np.random.normal(0, 1, size=(H.Ns, 10)) v1 /= np.linalg.norm(v1, axis=0) v2 = v1.copy() for i in range(100): v2 = U.dot(v2) v2 /= np.linalg.norm(v2) v1 = expm_multiply(A, v1) v1 /= np.linalg.norm(v1) if (np.all(np.abs(H.expt_value(v2) - E) < 1e-15)): break # i += 1 np.testing.assert_allclose( v1, v2, rtol=0, atol=5e-15, err_msg='imaginary time test failed, seed {:d}'.format(seed))
def test_ramdom_matrix(N=3500, ntest=10, seed=0): np.random.seed(seed) i = 0 while (i < ntest): print("testing random matrix {}".format(i + 1)) A = (random(N, N, density=np.log(N) / N) + 1j * random(N, N, density=np.log(N) / N)) A = A.tocsr() v = np.random.normal( 0, 1, size=(N, 10)) + 1j * np.random.normal(0, 1, size=(N, 10)) v /= np.linalg.norm(v) v1 = expm_multiply(A, v) v2 = expm_multiply_parallel(A).dot(v) np.testing.assert_allclose( v1, v2, rtol=0, atol=5e-15, err_msg='random matrix test failed, seed {:d}'.format(seed)) i += 1
sys.path.insert(0, qspin_path) #print(os.environ["OMP_NUM_THREADS"]) from quspin.tools.evolution import expm_multiply_parallel from scipy.sparse.linalg import expm_multiply from scipy.sparse import random, identity import numpy as np seed = np.random.randint(10000000) #9513926 np.random.seed(seed) N = 3500 for i in range(10): print("testing random matrix {}".format(i + 1)) A = (random(N, N) + 1j * random(N, N)) A = A.tocsr() A = (A + A.H) / 2.0 v = np.random.uniform(-1, 1, size=N) + 1j * np.random.uniform(-1, 1, size=N) v1 = expm_multiply(-1j * A, v) v2 = expm_multiply_parallel(A, a=-1j).dot(v) np.testing.assert_allclose(v1 - v2, 0, atol=1e-10, err_msg='failed seed {:d}'.format(seed)) print("expm_multiply_parallel tests passed!")
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=[["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 H=hamiltonian(static,dynamic,basis=basis,dtype=np.float64) # prealocate computation of matrix exponential expH = expm_multiply_parallel(H.tocsr(),a=0.2j) print(expH) # ##### change value of `a` print(expH.a) expH.set_a(0.3j) print(expH.a) # ##### compute expm_multiply applied on a state _,psi=H.eigsh(k=1,which='SA') # compute GS of H psi=psi.squeeze() # construct c++ work array for speed work_array=np.zeros((2*len(psi),), dtype=psi.dtype) print(H.expt_value(psi)) # measure energy of state |psi> expH.dot(psi,work_array=work_array,overwrite_v=True) # compute action of matrix exponential on a state print(H.expt_value(psi)) # measure energy of state exp(aH)|psi>
Hx = hamiltonian(static_x, [], basis=basis, dtype=np.float64, **no_checks) H_ave = 0.5 * (Hz + Hx) Hx_diag = hamiltonian(static_x_diag, [], basis=basis, dtype=np.float64, **no_checks).diagonal() Hz_diag = Hz.diagonal() # define initial state index_i = basis.index('0' * L) psi_0 = np.zeros(basis.Ns, dtype=np.complex128) psi_0[index_i] = 1.0 # preallocate matrix exponentials exp(a*H) expHz = expm_multiply_parallel(Hz.tocsr(), a=-1j * 0.5 * T) expHx = expm_multiply_parallel(Hx.tocsr(), a=-1j * 0.5 * T) expHz_diagonal = np.exp(-1j * 0.5 * T * Hz_diag) expHx_diagonal = np.exp(-1j * 0.5 * T * Hx_diag) cosHz_diagonal = +np.cos(0.5 * T * Hz_diag) sinHz_diagonal = -np.sin(0.5 * T * Hz_diag) cosHx_diagonal = +np.cos(0.5 * T * Hx_diag) sinHx_diagonal = -np.sin(0.5 * T * Hx_diag) # evolve state nT = 100 subsys = range(L // 2) energy_t = np.zeros((nT, ), dtype=np.float64) sent_t = np.zeros((nT, ), dtype=np.float64)
# calculate the eigenstate closest to energy E_star psi_i = psi_s[:, 0] ti = time.time() times = np.linspace(0.0, T, num=N_T) psi_t = H.evolve(psi_i, times[0], times, iterate=True) for psi in psi_t: pass tf = time.time() time_SE = tf - ti SE_str = "\ncomputing SE took {0:0.2f} secs.\n".format(time_SE) output_str.append(SE_str) print(SE_str) dt = T / N_T expH = expm_multiply_parallel(H.tocsr(), a=-1j * dt, dtype=np.complex128) # # auxiliary array for memory efficiency work_array = np.zeros((2 * len(psi), ), dtype=psi.dtype) # twice as long because complex-valued # # loop ober the time steps ti = time.time() for j in range(N_T): # # apply to state psi and update psi in-place expH.dot(psi, work_array=work_array, overwrite_v=True) tf = time.time() time_expm = tf - ti exp_str = "\ntime evolution took {0:0.2f} secs.\n".format(time_expm) output_str.append(exp_str)
psi_i = V[:, 0] # # preallocate arrays for the observables # E_density = np.zeros(N_steps + 1, dtype=dtype_real) Sent_density = np.zeros(N_steps + 1, dtype=dtype_real) # compute initial values for obsrvables E_density[0] = H_ave.expt_value(psi_i).real / L Sent_density[0] = basis.ent_entropy(psi_i, sub_sys_A=range(L // 2), density=True)['Sent_A'] # ##### compute the time evolution using expm_multple_parallel # # construct piece-wise constant unitaries expH0 = expm_multiply_parallel(H0.tocsr(), a=-1j * 0.5 * T, dtype=dtype_cmplx) expH1 = expm_multiply_parallel(H1.tocsr(), a=-1j * 0.5 * T, dtype=dtype_cmplx) # # auxiliary array for memory efficiency psi = psi_i.copy().astype(np.complex128) work_array = np.zeros((2 * len(psi), ), dtype=psi.dtype) # twice as long because complex-valued # # loop ober the time steps for j in range(N_steps): # # apply to state psi and update psi in-place expH0.dot(psi, work_array=work_array, overwrite_v=True) expH1.dot(psi, work_array=work_array, overwrite_v=True) # measure 'oservables' E_density[j + 1] = H_ave.expt_value(psi).real / L