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(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_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 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 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 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]])))
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))