def test_make_fixtures(self): fix_loc = 'tests/fixtures/' for d in [2, 3, 4]: for D in [2, 3, 4, 5, 10, 20, 50, 100]: iMPS().random( d, D).left_canonicalise().store(fix_loc + 'iMPS{}x{}'.format(d, D))
def get_overlap_exact(p1, p2, gate=gate, testing=True): A = iMPS([unitary_to_tensor(cirq.unitary(gate(p1))) ]).left_canonicalise()[0] B = iMPS([unitary_to_tensor(cirq.unitary(gate(p2))) ]).left_canonicalise()[0] x, r = Map(A, B).right_fixed_point() if testing: return np.abs(x)**2, r else: return np.abs(x)**2
def obj_state(p_, A, WW): p, rs = p_[:15], p_[15:] B = iMPS([unitary_to_tensor(cirq.unitary(gate(p)))]).left_canonicalise()[0] U = Environment(tensor_to_unitary(A), 'U') U_ = Environment(tensor_to_unitary(B), 'U\'') R = state_gate(rs) #R = Environment(environment_to_unitary(r), 'R') L = Environment(put_env_on_right_site(environment_from_unitary(cirq.unitary(R)).conj().T), 'L') W = Environment(WW, 'W') qbs = cirq.LineQubit.range(5) C = cirq.Circuit.from_ops([R(*qbs[3:5]), U(*qbs[2:4]), U(*qbs[1:3]), W(*qbs[2:4]), L(*qbs[0:2]), cirq.inverse(U_)(*qbs[1:3]), cirq.inverse(U_)(*qbs[2:4]), cirq.CNOT(*qbs[3:5]), cirq.H(qbs[3])]) s = cirq.Simulator(dtype=np.complex128) return s.simulate(C).final_state
def obj(p_, A, WW): p, rs = p_[:15], p_[15:] B = iMPS([unitary_to_tensor(cirq.unitary(gate(p)))]).left_canonicalise()[0] U = Environment(tensor_to_unitary(A), 'U') U_ = Environment(tensor_to_unitary(B), 'U\'') E = Map(np.tensordot(WW, merge(A, A), [1, 0]), merge(B, B)) x,r = E.right_fixed_point() x_,l = E.left_fixed_point() R = Environment(put_env_on_left_site(r), 'θR') L = Environment(put_env_on_right_site(r.conj().T), 'θL') W = Environment(WW, 'W') qbs = cirq.LineQubit.range(5) C = cirq.Circuit.from_ops([R(*qbs[3:5]), U(*qbs[2:4]), U(*qbs[1:3]), W(*qbs[2:4]), L(*qbs[0:2]), cirq.inverse(U_)(*qbs[1:3]), cirq.inverse(U_)(*qbs[2:4]), cirq.CNOT(*qbs[3:5]), cirq.H(qbs[3])]) s = cirq.Simulator(dtype=np.complex128) return -np.sqrt(np.abs(np.sqrt(2)*s.simulate(C).final_state[0]))
def test_time_evolve(): for AL, AR, C in [As[0]]: J, g = -1, 0.5 H = np.array([[J, g / 2, g / 2, 0], [g / 2, -J, 0, g / 2], [g / 2, 0, -J, g / 2], [0, g / 2, g / 2, J]]) T = np.linspace(0, 0.1, 100) dt = T[1] - T[0] evs = [] es = [] ################ CIRQ BIT ###################### counter = 0 bloch_sphere_results = [] U = FullStateTensor(tensor_to_unitary(AL.data[0])) V = FullEnvironment(environment_to_unitary(C)) hamiltonian = FullStateTensor(expm(-1j * H * dt)) # hamiltonian = FullStateTensor(np.identity(4)) # hamiltonian = FullStateTensor(expm(-1j * H * dt)) evolver = MPSTimeEvolve(u_initial=U, hamiltonian=hamiltonian, v_initial=V, settings={ 'method': 'Powell', 'maxiter': 100, 'verbose': True }) # initial classical value A = AL evs.append(iMPS([A.data[0]]).Es([Sx, Sy, Sz])) # initial unitary value results, qubits = evolver.simulate_state() bloch_sphere = results.bloch_vector_of(qubits[1]) bloch_sphere_results.append(bloch_sphere) for _ in T: print(counter) dA = A.dA_dt([H]) * dt es.append(A.e) A = (A + dA).left_canonicalise() evs.append(A.Es([Sx, Sy, Sz])) ''' Below is the cirq time evolution. Gate is made using scipy.expm(H) * dt which is put into a Tensor, and and this is the hamiltonian. ''' evolver.evolve_single_step() results, qubits = evolver.simulate_state() bloch_sphere = results.bloch_vector_of(qubits[1]) bloch_sphere_results.append(bloch_sphere) counter += 1 fig, ax = plt.subplots(2, 1, sharex=True, sharey=True) ax[0].plot(np.array(evs), c='r') ax[0].plot(np.array(bloch_sphere_results), c='b') ax[1].plot(es) plt.show() fig.savefig('longTimeEvo2.png') return np.array(evs), np.array(bloch_sphere_results)
def test_dH_dU(self): A = iMPS().random(2, 2).left_canonicalise() def H(λ): return [Sz12 @ Sz22 + λ * (Sx12 + Sx22)] λ = 1 A.dH_dU(H(λ))
def find_ground_state(H, D, ϵ=1e-2, maxiters=5000, tol=1e-3, noisy=False): ψ = iMPS().random(2, D).left_canonicalise() es = [] it = tqdm(range(maxiters)) if noisy else range(maxiters) for _ in it: dA = 1j*ϵ*ψ.dA_dt([H]) if norm(dA)< tol: break es.append(ψ.e) ψ=(ψ-dA).left_canonicalise() return ψ, es
def setUp(self): N = 10 D_min, D_max = 10, 11 d_min, d_max = 2, 3 p_min, p_max = 1, 2 # always 1 for now self.rand_cases1 = [ iMPS().random(randint(d_min, d_max), randint(D_min, D_max), period=randint(p_min, p_max)) for _ in range(N) ] self.rand_cases2 = [ iMPS().random(randint(d_min, d_max), randint(D_min, D_max), period=randint(p_min, p_max)) for _ in range(N) ] self.maps = [ Map(case1[0], case2[0]) for case1, case2 in zip(self.rand_cases1, self.rand_cases2) ]
def setUp(self): N = 5 D_min, D_max = 9, 10 d_min, d_max = 2, 3 p_min, p_max = 1, 2 # always 1 for now self.rand_cases = [ iMPS().random(randint(d_min, d_max), randint(D_min, D_max), period=randint(p_min, p_max)) for _ in range(N) ] self.transfer_matrices = [ TransferMatrix(case.data[0]) for case in self.rand_cases ]
def obj(rs, initial_params=initial, WW=None): WW = np.eye(4) if WW is None else WW A = iMPS([unitary_to_tensor(cirq.unitary(gate(p1))) ]).left_canonicalise()[0] B = iMPS([unitary_to_tensor(cirq.unitary(gate(p2))) ]).left_canonicalise()[0] U = Environment(tensor_to_unitary(A), 'U') U_ = Environment(tensor_to_unitary(B), 'U\'') r = rotate_to_hermitian((rs[:4] + 1j * rs[4:]).reshape(2, 2)) r /= np.sqrt(np.trace(r.conj().T @ r)) l = r R = Environment(put_env_on_left_site(r), 'R') L = Environment(put_env_on_right_site(l.conj().T), 'L') W = Environment(WW, 'W') qbs = cirq.LineQubit.range(6) C = cirq.Circuit.from_ops([ cirq.H(qbs[3]), cirq.CNOT(*qbs[3:5]), U(*qbs[2:4]), U(*qbs[1:3]), W(*qbs[2:4]), L(*qbs[0:2]), R(*qbs[4:]), cirq.inverse(U_)(*qbs[1:3]), cirq.inverse(U_)(*qbs[2:4]), cirq.CNOT(*qbs[3:5]), cirq.H(qbs[3]) ]) s = cirq.Simulator(dtype=np.complex128) return -np.abs(s.simulate(C).final_state[0]) * 2
def setUp(self): N = 3 D_min, D_max = 4, 5 d_min, d_max = 2, 3 p_min, p_max = 1, 2 # always 1 for now self.rand_cases = [ iMPS().random(randint(d_min, d_max), randint(D_min, D_max), period=randint(p_min, p_max)) for _ in range(N) ] self.rand_v_cases = [ ivMPS().random(randint(d_min, d_max), randint(D_min, D_max), period=randint(p_min, p_max)) for _ in range(N) ]
def obj(p, A, WW): B = iMPS([unitary_to_tensor(cirq.unitary(gate(p)))]).left_canonicalise()[0] WW_ = np.eye(WW.shape[0]) E = Map(np.tensordot(WW, merge(A, A), [1, 0]), merge(B, B)) x, r = E.right_fixed_point() x_, l = E.left_fixed_point() l = r U = Environment(tensor_to_unitary(A), 'U') U_ = Environment(tensor_to_unitary(B), 'U\'') R = Environment(put_env_on_left_site(r), 'θR') left = put_env_on_right_site(l.conj().T) L = Environment(left, 'θL') W = Environment(WW, 'W') qbs = cirq.LineQubit.range(6) C = cirq.Circuit([ cirq.H(qbs[3]), cirq.CNOT(*qbs[3:5]), U(*qbs[2:4]), U(*qbs[1:3]), W(*qbs[2:4]), L(*qbs[0:2]), R(*qbs[4:]), cirq.inverse(U_)(*qbs[1:3]), cirq.inverse(U_)(*qbs[2:4]), cirq.CNOT(*qbs[3:5]), cirq.H(qbs[3]) ]) #qbs = cirq.LineQubit.range(4) #normC = cirq.Circuit.from_ops([cirq.H(qbs[1]), # cirq.CNOT(*qbs[1:3]), # L(*qbs[:2]), # R(*qbs[-2:]), # cirq.CNOT(*qbs[1:3]), # cirq.H(qbs[1]) # ]) s = cirq.Simulator(dtype=np.complex128) ff = np.sqrt( 2 * np.abs(s.simulate(C).final_state[0]) ) #/np.abs(s.simulate(normC).final_state[0])), np.sqrt(np.abs(x[0])) #print(ff[0]-ff[1]) #print(ff[0], ff[1]) return -ff
def test_NonSparseFullEnergyOptimizer(self): for AL, AR, C in [self.As[0]]: gs = np.linspace(0, 2, 20) exact_es = [] qmps_es = [] xmps_es = [] for g in tqdm(gs): J, g = -1, g f = lambda k,g : -2*np.sqrt(1+g**2-2*g*np.cos(k))/np.pi/2. E0_exact = integrate.quad(f, 0, np.pi, args=(g,))[0] exact_es.append(E0_exact) H = np.array([[J,g/2,g/2,0], [g/2,-J,0,g/2], [g/2,0,-J,g/2], [0,g/2,g/2,J]] ) #ψ, e = find_ground_state(H, 2) #xmps_es.append(e[-1]) opt = NonSparseFullEnergyOptimizer(H, 4) sets = opt.settings sets['store_values'] = True sets['method'] = 'Nelder-Mead' sets['verbose'] = self.verbose sets['maxiter'] = 5000 sets['tol'] = 1e-5 opt.change_settings(sets) opt.optimize() tm = iMPS([unitary_to_tensor(opt.U)]).transfer_matrix().asmatrix() qmps_es.append(opt.obj_fun_values[-1]) plt.plot(gs, exact_es, label='exact') #plt.plot(gs, xmps_es) plt.plot(gs, qmps_es, label='optimized') plt.xlabel('$\\lambda$') plt.ylabel('$E_0$') plt.legend() plt.savefig('/Users/fergusbarratt/Desktop/gs_opt.pdf', bbox_inches='tight') plt.show()
def test_mixed(self): from numpy import sum, tensordot as td from numpy.linalg import inv A = self.rand_cases[0] d, D = A.d, A.D AL, L, λ = A._lmixed() self.assertTrue(allclose(sum(cT(AL) @ AL, axis=0), eye(D))) self.assertTrue(allclose(inv(L) @ AL @ L, 1 / λ * A)) AR, R, λ = A._rmixed() self.assertTrue(allclose(sum(AR @ cT(AR), axis=0), eye(D))) self.assertTrue(allclose(R @ AR @ inv(R), 1 / λ * A)) AR, C, λ = iMPS([AL])._rmixed() self.assertTrue(allclose(sum(AR @ cT(AR), axis=0), eye(D))) self.assertTrue(allclose(C @ AR @ inv(C), 1 / λ * AL)) AL, AR, C = A.mixed() AL, AR, C = AL.data[0], AR.data[0], C self.assertTrue(allclose(sum(cT(AL) @ AL, axis=0), eye(D))) self.assertTrue(allclose(sum(AR @ cT(AR), axis=0), eye(D))) self.assertTrue(allclose(C @ AR @ inv(C), 1 / λ * AL))
dt = T[1] - T[0] res = minimize(obj, np.random.randn(N), (A[0], np.eye(4)), method='Nelder-Mead', options={'disp': True}) params = res.x WW = expm(-1j * Hamiltonian({'ZZ': -1, 'X': g1}).to_matrix() * 2 * dt) ps = [params] ops = paulis(0.5) evs = [] les = [] errs = [res.fun] for _ in tqdm(T): A_ = iMPS([unitary_to_tensor(cirq.unitary(gate(params))) ]).left_canonicalise() evs.append(A_.Es(ops)) les.append(A_.overlap(A)) res = minimize(obj, params, (A_[0], WW), options={'disp': True}) params = res.x errs.append(res.fun) ps.append(params) lles.append(les) eevs.append(evs) eers.append(errs) def f(z, g0, g1): def theta(k, g): return np.arctan2(np.sin(k), g - np.cos(k)) / 2
def run_tests(N): """run_tests: just a whole bunch of tests. :param N: number of iterations to run """ for _ in range(N): q = np.random.randn(2, 2)+1j*np.random.randn(2, 2) assert np.allclose(get_env_off_left_site(np.prod(put_env_on_left_site(q, ret_n=True))), q) assert np.allclose(get_env_off_right_site(np.prod(put_env_on_right_site(q, ret_n=True))), q) U = put_env_on_left_site(q) V = put_env_on_right_site(q) assert np.allclose(V.conj().T@V, np.eye(U.shape[0])) assert np.allclose(U.conj().T@U, np.eye(U.shape[0])) A = iMPS().random(2, 2).left_canonicalise()[0] B = iMPS().random(2, 2).left_canonicalise()[0]#np.tensordot(expm(-1j*Z*dt), A, [1, 0]) U = Environment(tensor_to_unitary(A), 'U') U_ = Environment(tensor_to_unitary(B), 'U\'') x, r = Map(merge(A, A), merge(B, B)).right_fixed_point() x_, l = Map(merge(A, A), merge(B, B)).left_fixed_point() L = put_env_on_right_site(l) R = put_env_on_left_site(r) assert np.allclose(get_env_off_left_site(put_env_on_left_site(r)), r) assert np.allclose(get_env_off_right_site(put_env_on_right_site(l)), l) U = put_env_on_left_site(r) V = put_env_on_right_site(l) assert np.allclose(V.conj().T@V, np.eye(U.shape[0])) assert np.allclose(U.conj().T@U, np.eye(U.shape[0])) A = iMPS().random(2, 2).left_canonicalise()[0] B = iMPS().random(2, 2).left_canonicalise()[0]#np.tensordot(expm(-1j*Z*dt), A, [1, 0]) E = Map(A, B) x, r = E.right_fixed_point() x_, l = E.left_fixed_point() U = Environment(tensor_to_unitary(A), 'U') U_ = Environment(tensor_to_unitary(B), 'U\'') R = Environment(put_env_on_left_site(r), 'R') L = Environment(put_env_on_right_site(l.conj().T), 'L') qbs = cirq.LineQubit.range(4) for g in zip([cirq.I, cirq.X, cirq.Y, cirq.Z], [I, X, Y, Z]): C = cirq.Circuit.from_ops([cirq.H(qbs[1]), cirq.CNOT(*qbs[1:3]), R(*qbs[2:]), g[0](qbs[1]), cirq.CNOT(*qbs[1:3]), cirq.H(qbs[1])]) s = cirq.Simulator() assert np.allclose(2*s.simulate(C).final_state[0]-np.trace(g[1]@r), 0, 1e-6, 1e-6) # r is the matrix on the 1st qubit qbs = cirq.LineQubit.range(4) for g in zip([cirq.I, cirq.X, cirq.Y, cirq.Z], [I, X, Y, Z]): C = cirq.Circuit.from_ops([cirq.H(qbs[1]), cirq.CNOT(*qbs[1:3]), U(*qbs[0:2]), R(*qbs[2:]), g[0](qbs[0]), cirq.inverse(U_)(*qbs[0:2]), cirq.CNOT(*qbs[1:3]), cirq.H(qbs[1])]) s = cirq.Simulator() assert np.allclose(2*s.simulate(C).final_state[0]-x*np.trace(g[1]@r), 0, 1e-6, 1e-6) qbs = cirq.LineQubit.range(5) for g in zip([cirq.I, cirq.X, cirq.Y, cirq.Z], [I, X, Y, Z]): C = cirq.Circuit.from_ops([cirq.H(qbs[2]), cirq.CNOT(*qbs[2:4]), U(*qbs[1:3]), U(*qbs[0:2]), R(*qbs[3:]), g[0](qbs[0]), cirq.inverse(U_)(*qbs[0:2]), cirq.inverse(U_)(*qbs[1:3]), cirq.CNOT(*qbs[2:4]), cirq.H(qbs[2])]) s = cirq.Simulator() #print(C.to_text_diagram(transpose=True)) #raise Exception assert np.allclose(2*s.simulate(C).final_state[0]-x**2*np.trace(g[1]@r), 0, 1e-6, 1e-6) qbs = cirq.LineQubit.range(3) for g in zip([cirq.I, cirq.X, cirq.Y, cirq.Z], [I, X, Y, Z]): C = cirq.Circuit.from_ops([cirq.H(qbs[1]), cirq.CNOT(*qbs[1:3]), L(*qbs[:2]), g[0](qbs[2]), cirq.CNOT(*qbs[1:3]), cirq.H(qbs[1])]) s = cirq.Simulator() assert np.allclose(2*s.simulate(C).final_state[0]-np.trace(g[1]@l.conj()), 0, 1e-6, 1e-6) # r is the matrix on the 1st qubit qbs = cirq.LineQubit.range(4) for g in zip([cirq.I, cirq.X, cirq.Y, cirq.Z], [I, X, Y, Z]): C = cirq.Circuit.from_ops([cirq.H(qbs[2]), cirq.CNOT(*qbs[2:4]), U(*qbs[1:3]), L(*qbs[:2]), g[0](qbs[3]), cirq.inverse(U_)(*qbs[1:3]), cirq.CNOT(*qbs[2:4]), cirq.H(qbs[2])]) s = cirq.Simulator() #print(C.to_text_diagram(transpose=True)) #raise Exception assert np.allclose(2*s.simulate(C).final_state[0]-x*np.trace(g[1]@l.conj()), 0, 1e-6, 1e-6) qbs = cirq.LineQubit.range(5) for g in zip([cirq.I, cirq.X, cirq.Y, cirq.Z], [I, X, Y, Z]): C = cirq.Circuit.from_ops([cirq.H(qbs[3]), cirq.CNOT(*qbs[3:5]), U(*qbs[2:4]), U(*qbs[1:3]), L(*qbs[0:2]), g[0](qbs[4]), cirq.inverse(U_)(*qbs[1:3]), cirq.inverse(U_)(*qbs[2:4]), cirq.CNOT(*qbs[3:5]), cirq.H(qbs[3])]) s = cirq.Simulator() assert np.allclose(2*s.simulate(C).final_state[0]-x**2*np.trace(g[1]@l.conj()), 0, 1e-6, 1e-6) qbs = cirq.LineQubit.range(6) C = cirq.Circuit.from_ops([cirq.H(qbs[3]), cirq.CNOT(*qbs[3:5]), U(*qbs[2:4]), U(*qbs[1:3]), L(*qbs[0:2]), R(*qbs[4:]), cirq.inverse(U_)(*qbs[1:3]), cirq.inverse(U_)(*qbs[2:4]), cirq.CNOT(*qbs[3:5]), cirq.H(qbs[3])]) s = cirq.Simulator() assert np.allclose(2*s.simulate(C).final_state[0], x**2*np.trace(l.conj().T@r))
def test_store_load(self): for _ in range(10): A = iMPS().random(3, 10).left_canonicalise() A.store('x') A_ = iMPS().load('x.npy') self.assertTrue(A == A_)
import numpy as np from xmps.iMPS import iMPS from xmps.spin import paulis, N_body_spins import matplotlib as mpl import matplotlib.pyplot as plt from tqdm import tqdm #mpl.style.use('pub_fast') X, Y, Z = paulis(0.5) XI, YI, ZI = N_body_spins(0.5, 1, 2) IX, IY, IZ = N_body_spins(0.5, 2, 2) T = np.linspace(0, 1, 100) dt = T[1] - T[0] D = 10 mps = iMPS().random(2, D).left_canonicalise() evs = [] H = -(XI @ IX + YI @ IY + ZI @ IZ) for _ in tqdm(T): k1 = mps.dA_dt([H]) * dt k2 = (mps + k1 / 2).dA_dt([H]) * dt k3 = (mps + k2 / 2).dA_dt([H]) * dt k4 = (mps + k3).dA_dt([H]) * dt mps = (mps + (k1 + 2 * k2 + 2 * k3 + k4) / 6).left_canonicalise() evs.append(mps.Es(paulis(0.5))) plt.plot(T, evs) plt.scatter(T, evs, marker='x') plt.savefig('evo.jpg') #plt.show()
def test_density_matrix_cost_funtion(): N = 1 As = [iMPS().random(2, 2).mixed() for _ in range(N)] for AL, AR, C in As: U = FullStateTensor(tensor_to_unitary(AL.data[0])) v_analytic = FullEnvironment(environment_to_unitary(C)) represent = RepresentMPS(U) represent.change_settings({ 'method': 'Powell', 'maxiter': 1000, 'tol': 1e-8, 'verbose': True, 'store_values': True }) represent.optimize() v_optimized = represent.v # State with analytic environment analytic_state = State(U, v_analytic, 1) # State with 'optimized' environment optimized_state = State(U, v_optimized, 1) qubits = cirq.LineQubit.range(5) # circuit with the environment found by RepresentMPS optimized_circuit = cirq.Circuit.from_ops([ optimized_state(*[qubits[0], qubits[1], qubits[2]]), v_optimized(*[qubits[3], qubits[4]]) ]) # circuit with analytic environment analytic_circuit = cirq.Circuit.from_ops([ analytic_state(*[qubits[0], qubits[1], qubits[2]]), v_analytic(*[qubits[3], qubits[4]]) ]) # circuit using analytic environment that has CNOTS and H gates to get cost function analytic_swap_circuit = analytic_circuit.copy() analytic_swap_circuit.append( [cirq.CNOT(qubits[0], qubits[3]), cirq.H(qubits[0])]) # circuit with CNOT and H using optimized environment optimized_swap_circuit = optimized_circuit.copy() optimized_swap_circuit.append( [cirq.CNOT(qubits[0], qubits[3]), cirq.H(qubits[0])]) sim = cirq.Simulator() # results of optimized circuit and density matrix circuits optimized_results = sim.simulate(optimized_circuit) optimized_density_matrix_results = sim.simulate(optimized_swap_circuit) # results of analytic circuit and density matrix circuits analytic_results = sim.simulate(analytic_circuit) analytic_density_matrix_results = sim.simulate(analytic_swap_circuit) # bloch vectors optimized_bloch0 = optimized_results.bloch_vector_of(qubits[0]) optimized_bloch3 = optimized_results.bloch_vector_of(qubits[3]) analytic_bloch0 = analytic_results.bloch_vector_of(qubits[0]) analytic_bloch3 = analytic_results.bloch_vector_of(qubits[3]) # density matrices analytic_density_matrix = analytic_density_matrix_results.density_matrix_of( [qubits[0], qubits[3]]) analytic_prob_all_ones = analytic_density_matrix[-1, -1] print(np.abs(np.diag(analytic_density_matrix))) analytic_score = np.abs(analytic_prob_all_ones) optimized_density_matrix = optimized_density_matrix_results.density_matrix_of( [qubits[0], qubits[3]]) optimized_prob_all_ones = optimized_density_matrix[-1, -1] optimized_score = np.abs(optimized_prob_all_ones) print('Swap Test Results') print(optimized_bloch3) print(optimized_bloch0) print(np.dot(optimized_bloch0, optimized_bloch3)) print('opt score: ', optimized_score) print( np.trace( optimized_results.density_matrix_of([qubits[0]]) @ optimized_results.density_matrix_of([qubits[0]]))) print( np.trace( optimized_results.density_matrix_of([qubits[3]]) @ optimized_results.density_matrix_of([qubits[3]]))) print('Analytic Result') print(analytic_bloch0) print(analytic_bloch3) print(np.dot(analytic_bloch0, analytic_bloch3)) print('an score: ', analytic_score) print( np.trace( analytic_results.density_matrix_of([qubits[0]]) @ analytic_results.density_matrix_of([qubits[0]]))) print( np.trace( analytic_results.density_matrix_of([qubits[3]]) @ analytic_results.density_matrix_of([qubits[3]])))
L(*qbs[0:2]), cirq.inverse(U_)(*qbs[1:3]), cirq.inverse(U_)(*qbs[2:4]), cirq.CNOT(*qbs[3:5]), cirq.H(qbs[3])]) s = cirq.Simulator(dtype=np.complex128) return s.simulate(C).final_state def obj_H(): return -np.diag(np.eye(2**5)[0]) if __name__=='__main__': import matplotlib.pyplot as plt import matplotlib as mpl A = iMPS().random(2, 2).left_canonicalise() # initial state should be an iMPS object T = np.linspace(0, 1, 10) # timesteps dt = T[1]-T[0] # parametrise the initial state by minimizing the overlap with parametrised unitary. # This is janky and would be way better the other way around. # unless res.fun == -1, the initial state of the time evo is not what you want it to be. #res = minimize(obj, np.random.randn(15), # (A[0], np.eye(4)), # method='Nelder-Mead', # options={'disp':True}) #params = res.x params = np.random.randn(15) # Define the time evolution operator
def setUp(self): N = 3 self.xs = [randn(8, 8) + 1j * randn(8, 8) for _ in range(N)] self.As = [iMPS().random(2, 2).mixed() for _ in range(N)]
import numpy as np from xmps.spin import spins from xmps.iMPS import iMPS from scipy.linalg import expm from qmps.represent import FullStateTensor, FullEnvironment from qmps.tools import environment_to_unitary, tensor_to_unitary, unitary_to_tensor from qmps.time_evolve import MPSTimeEvolve import matplotlib.pyplot as plt from xmps.spin import U4 import cirq Sx, Sy, Sz = spins(0.5) Sx, Sy, Sz = 2*Sx, 2*Sy, 2*Sz As = [iMPS().random(2, 2).mixed() for _ in range(3)] def test_time_evolve(): for AL, AR, C in [As[0]]: J, g = -1, 0.5 H = np.array([[J, g / 2, g / 2, 0], [g / 2, -J, 0, g / 2], [g / 2, 0, -J, g / 2], [0, g / 2, g / 2, J]]) T = np.linspace(0, 0.1, 100) dt = T[1] - T[0] evs = [] es = []
for _ in range(50): q = np.random.randn(2, 2) + 1j * np.random.randn(2, 2) assert np.allclose( get_env_off_left_site(np.prod(put_env_on_left_site(q, ret_n=True))), q) assert np.allclose( get_env_off_right_site( np.prod(put_env_on_right_site(q, ret_n=True))), q) U = put_env_on_left_site(q) V = put_env_on_right_site(q) assert np.allclose(V.conj().T @ V, np.eye(U.shape[0])) assert np.allclose(U.conj().T @ U, np.eye(U.shape[0])) for _ in range(N): A = iMPS().random(2, 2).left_canonicalise()[0] B = iMPS().random( 2, 2).left_canonicalise()[0] #np.tensordot(expm(-1j*Z*dt), A, [1, 0]) U = Environment(tensor_to_unitary(A), 'U') U_ = Environment(tensor_to_unitary(B), 'U\'') x, r = Map(merge(A, A), merge(B, B)).right_fixed_point() x_, l = Map(merge(A, A), merge(B, B)).left_fixed_point() L = put_env_on_right_site(l) R = put_env_on_left_site(r) assert np.allclose(get_env_off_left_site(put_env_on_left_site(r)), r) assert np.allclose(get_env_off_right_site(put_env_on_right_site(l)), l) U = put_env_on_left_site(r) V = put_env_on_right_site(l)
def random_test(N=100, dt=1e-2, max_tries=20, η=0., noisy=False, k=1, tol=1e-10): evals = [] tqer = tqdm(range(N)) if not noisy else range(N) for _ in tqer: H = Hamiltonian({'ZZ': 1, 'X': 1}).to_matrix() A = iMPS().random(2, 2).left_canonicalise() B = (A + dt * A.dA_dt([H])).left_canonicalise() EAB = Map(A[0], B[0]) def objective(p, EAB=EAB, η=η): EAB = EAB.asmatrix() er, eim, p1, p2 = p[0], p[1], p[2:17], p[17:] e = er + 1j * eim #v = EAB@vec(p1)-e*vec(p1) v = vec(p1) return np.real(v.conj().T @ EAB.conj().T @ EAB @ v) + np.abs( e)**2 - 2 * np.real(e * v.conj().T @ EAB @ v) + η * np.abs( (0.99 - e))**2 #return np.real(v.conj().T@v) + η*np.abs((1-e))**2 def abs_objective(p, EAB=EAB, η=η): EAB = EAB.asmatrix() er, eim, p1, p2 = p[0], p[1], p[2:17], p[17:] e = er + 1j * eim #v = EAB@vec(p1)-e*vec(p1) v = vec(p1) return np.real(v.conj().T @ EAB.conj().T @ EAB @ v) + np.abs(e)**2 - 2 * np.abs(e) * np.abs( v.conj().T @ EAB @ v) + η * np.abs( (0.99 - e))**2 #return np.real(v.conj().T@v) + η*np.abs((1-e))**2 e, r = EAB.right_fixed_point() x = randn(9) x[0] = 1 x[1] = 0 abs_λ = 0 tries = 0 eigval_results = [] eigvec_results = [] while tries < max_tries and np.abs(abs_λ) < 1 - k * dt: abs_res = minimize(abs_objective, randn(9), method='BFGS', options={'disp': noisy}, tol=tol) abs_λ, abs_result_vector = abs_res.x[0] + 1j * abs_res.x[1], vec( abs_res.x[2:9]) tries += 1 eigval_results.append(np.abs(abs_λ)) eigvec_results.append(abs_result_vector) #print(np.abs(e), np.abs(abs_λ), 1-10*dt**2) if not noisy: tqer.set_description( f'{tries} repeats, {np.round(np.abs(abs_λ), 3)}') if tries == max_tries - 1: tqer.set_description('max_iters reached') abs_λ = np.max(eigval_results) abs_result_vector = eigvec_results[np.argmax( eigval_results)] def dephase(v): return v / np.exp(1j * np.angle(v[0])) if noisy: print('eigenvectors') print('actual: ', r.reshape(-1).real) print('variational: ', dephase(result_vector).real) print('abs variational: ', dephase(abs_result_vector).real) print('\n') print('eigenvalues') print('actual: ', np.abs(e)) print('variational: ', np.abs(λ)) print('abs variational: ', np.abs(abs_λ)) evals.append(np.abs(e) + 1j * np.abs(abs_λ)) return np.array(evals)
import matplotlib.pyplot as plt from tqdm import tqdm N = 100 L = 4 p = 1 As = [] print(random_full_rank_circuit(L, p).to_text_diagram(transpose=True)) for i in range(N): U = random_full_rank_circuit(L, p)._unitary_() As.append(unitary_to_tensor(U)) Ds = [] for A in tqdm(As): try: X = np.diag(iMPS([A]).left_canonicalise().L) except np.linalg.LinAlgError: raise Exception('Not good mps') plt.plot(list(range(len(X))), X, marker='x') plt.ylim([0, 1]) Ds.append(len(X[np.logical_not(np.isclose(X, 0))])) plt.show() plt.hist(log2(Ds).astype(int), bins=list(range(2, L + 1))) plt.xlabel('$\log_2(D)$') plt.ylabel('frequency') plt.title( 'bond dimension frequency for random p={} CNOT/Rx/Rz circuits'.format(p)) plt.xticks(list(range(1, L))) plt.xlim([2, L])
def get_env_exact_alternative(U): AL, AR, C = iMPS([unitary_to_tensor(U)]).mixed() return environment_to_unitary(C)
def env_function_unsure(self, U1, U2): A1 = unitary_to_tensor(U1) A2 = unitary_to_tensor(U2) Al, AR, C = iMPS([A1, A2]).mixed() return environment_to_unitary(C)