def objective_function(self, params): U_ = self.gate(params) U = self.u A = unitary_to_tensor(cirq.unitary(U)) A_ = unitary_to_tensor(cirq.unitary(U_)) _, r = Map(A,A_).right_fixed_point() R = Environment(put_env_on_left_site(r), 'R') L = Environment(put_env_on_right_site(r.conj().T), 'L') W = Environment(W, '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 time_evolve_sim_state(params, U, W): """ Circuit which returns the overlap between 2 MPS states, defined by the unitaries U_ = U4(params) & U = tensor_to_unitary(A). The full wavefunction is returns for debugging purposes. """ circ = QuantumCircuit(6, 6) U_ = self.gate(params) A = unitary_to_tensor(cirq.unitary(U)) A_ = unitary_to_tensor(cirq.unitary(U_)) _, r = Map(A, A_).right_fixed_point() R = Operator(put_env_on_left_site(r)) L = Operator(put_env_on_right_site(r.conj().T)) circ.h(3) circ.cx(3, 4) circ.unitary(U, [3, 2]) circ.unitary(U, [2, 1]) circ.unitary(L, [1, 0]) circ.unitary(R, [5, 4]) circ.unitary(H, [3, 2]) circ.unitary(target_u, [2, 1]) circ.unitary(target_u, [3, 2]) circ.cx(3, 4) circ.h(3) result = execute(circ, simulator).result() ψ = result.get_statevector(circ) return ψ
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 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 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()
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):
from qmps.tools import random_circuit, random_qaoa_circuit, unitary_to_tensor, svals from qmps.tools import random_full_rank_circuit import numpy as np import cirq from numpy import log2 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)$')
#params = res.x params = np.random.randn(15) # Define the time evolution operator WW = expm(-1j*Hamiltonian({'ZZ':-1, 'X':1}).to_matrix()*dt) # What to get expectation values of ops = paulis(0.5) ps = [params] evs = [] les = [] for _ in tqdm(T[1:]): # current mps tensor A_ = iMPS([unitary_to_tensor(cirq.unitary(gate(params)))]).left_canonicalise() res = minimize(obj, params, (A_[0], WW), options={'disp':True}) params = res.x #es, params = double_rotosolve(obj_H(), obj_state, params, (A_[0], WW)) # store params, expectation values and loschmidt echo evs.append(A_.Es(ops)) les.append(A_.overlap(A)) ps.append(params) np.save('params', np.array(ps)) fig, ax = plt.subplots(2, 1, sharex=True) ax[0].plot(T[1:], evs) ax[1].plot(T[1:], -np.log(np.array(les)))