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(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 cost_func(params, U2,U1,Ū2,Ū1): m = M(params) A1 = alternate_tensor(U2,U1) A2 = alternate_tensor(Ū2,Ū1) TransferMatrix = Map(A1,A2) EigenEqn = TransferMatrix @ m.reshape(4) return np.linalg.norm(m - EigenEqn.reshape(2,2))
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 scars_cost_fun_alternate(params, current_params, ham): ''' This cost function doesn't use the quantum circuit parameterisation params are formatted like: [θ1, ϕ1, ϕ2, θ2], for convenience with the classical differential eqn solver ''' θ1, ϕ1, ϕ2, θ2 = current_params θ1_, ϕ1_, ϕ2_, θ2_ = params A1 = A(θ1, ϕ1) A2 = A(θ2, ϕ2) A1_ = A(θ1_, ϕ1_) A2_ = A(θ2_, ϕ2_) A12 = merge(A1, A2) A12_ = merge(A1_, A2_) _, r = Map(A12, A12_).right_fixed_point() R = Environment(put_env_on_left_site(r), 'R') L = Environment(put_env_on_right_site(r.conj().T), 'L') U12 = Tensor(tensor_to_unitary(A12), 'U') U12_ = Tensor(tensor_to_unitary(A12_), 'U\'') q = cirq.LineQubit.range(8) circuit = cirq.Circuit.from_ops([ cirq.H(q[5]), cirq.CNOT(q[5], q[6]), U12(*q[3:6]), U12(*q[1:4]), L(*q[0:2]), ham(*q[2:6]), R(*q[6:8]), cirq.inverse(U12_(*q[1:4])), cirq.inverse(U12_(*q[3:6])), cirq.CNOT(q[5], q[6]), cirq.H(q[5]) ]) # print(circuit.to_text_diagram(transpose = True)) sim = cirq.Simulator() ψ = sim.simulate(circuit).final_state[0] return -np.abs(ψ) * 2
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 scars_time_evolve_cost_function(params, current_params, ham): ''' params are formatted like: [θ1, ϕ1, ϕ2, θ2], for convenience with the classical differential eqn solver ''' θ1, ϕ1, ϕ2, θ2 = current_params θ1_, ϕ1_, ϕ2_, θ2_ = params A1 = A(θ1, ϕ1) A2 = A(θ2, ϕ2) A1_ = A(θ1_, ϕ1_) A2_ = A(θ2_, ϕ2_) _, r = Map(merge(A1, A2), merge(A1_, A2_)).right_fixed_point() R = Environment(put_env_on_left_site(r), 'R') L = Environment(put_env_on_right_site(r.conj().T), 'L') U12 = ScarGate(current_params) U12_ = ScarGate(params) q = cirq.LineQubit.range(8) circuit = cirq.Circuit.from_ops([ cirq.H(q[5]), cirq.CNOT(q[5], q[6]), U12(*q[3:6]), U12(*q[1:4]), L(*q[0:2]), ham(*q[2:6]), R(*q[6:8]), cirq.inverse(U12_(*q[1:4])), cirq.inverse(U12_(*q[3:6])), cirq.CNOT(q[5], q[6]), cirq.H(q[5]) ]) # print(circuit.to_text_diagram(transpose = True)) sim = cirq.Simulator() ψ = sim.simulate(circuit).final_state[0] return -np.abs(ψ) * 2
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)
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) assert np.allclose(V.conj().T @ V, np.eye(U.shape[0])) assert np.allclose(U.conj().T @ U, np.eye(U.shape[0]))
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))