def test_generate_dnf_hamiltonian_content(self): clauses = [ dnf_lib.Clause(2, 4, True, False), dnf_lib.Clause(5, 4, True, True) ] dnf = dnf_lib.DNF(10, clauses) circuit = cirq.Circuit() circuit.append(dnf_circuit_lib.generate_dnf_hamiltonian_exponential( dnf, 0.25), strategy=insert_strategy.InsertStrategy.NEW_THEN_INLINE) operations = list(circuit.all_operations()) self.assertCountEqual(operations, [ cirq.ZPowGate(exponent=-0.5 / math.pi, global_shift=-0.5).on( cirq.LineQubit(4)), cirq.ZPowGate(exponent=0.5 / math.pi, global_shift=-0.5).on( cirq.LineQubit(2)), cirq.ZZPowGate(exponent=0.5 / math.pi, global_shift=-0.5).on( cirq.LineQubit(2), cirq.LineQubit(4)), cirq.ZPowGate(exponent=0.5 / math.pi, global_shift=-0.5).on( cirq.LineQubit(4)), cirq.ZPowGate(exponent=0.5 / math.pi, global_shift=-0.5).on( cirq.LineQubit(5)), cirq.ZZPowGate(exponent=-0.5 / math.pi, global_shift=-0.5).on( cirq.LineQubit(4), cirq.LineQubit(5)), ])
def test_zz_str(): assert str(cirq.ZZ) == 'ZZ' assert str(cirq.ZZ**0.5) == 'ZZ**0.5' assert str(cirq.ZZPowGate(global_shift=0.1)) == 'ZZ' iZZ = cirq.ZZPowGate(global_shift=0.5) assert str(iZZ) == 'ZZ'
def test_zz_repr(): assert repr(cirq.ZZPowGate()) == 'cirq.ZZ' assert repr(cirq.ZZPowGate(exponent=0.5)) == '(cirq.ZZ**0.5)' cirq.testing.assert_equivalent_repr(cirq.ZZ) cirq.testing.assert_equivalent_repr(cirq.ZZ**0.1) cirq.testing.assert_equivalent_repr(cirq.ZZ**0.5) cirq.testing.assert_equivalent_repr(cirq.ZZ**2) cirq.testing.assert_equivalent_repr( cirq.ZZPowGate(exponent=0.2, global_shift=0.3))
def test_zz_eq(): eq = cirq.testing.EqualsTester() eq.add_equality_group(cirq.ZZ, cirq.ZZPowGate(), cirq.ZZPowGate(exponent=1, global_shift=0), cirq.ZZPowGate(exponent=3, global_shift=0)) eq.add_equality_group(cirq.ZZ**0.5, cirq.ZZ**2.5, cirq.ZZ**4.5) eq.add_equality_group(cirq.ZZ**0.25, cirq.ZZ**2.25, cirq.ZZ**-1.75) iZZ = cirq.ZZPowGate(global_shift=0.5) eq.add_equality_group(iZZ**0.5, iZZ**4.5) eq.add_equality_group(iZZ**2.5, iZZ**6.5)
def test_zz_consistent(): cirq.testing.assert_eigen_gate_has_consistent_apply_unitary(cirq.ZZPowGate) cases = [ cirq.ZZ, cirq.ZZ**0.1, cirq.ZZPowGate(global_shift=0.1, exponent=0.2), cirq.ZZPowGate(global_shift=-0.5, exponent=0.4) ] for case in cases: cirq.testing.assert_qasm_is_consistent_with_unitary(case) cirq.testing.assert_decompose_is_consistent_with_unitary(case) cirq.testing.assert_phase_by_is_consistent_with_unitary(case)
def test_simplify_circuit_merge_one_parameter_gates(self, qubits): q0, q1 = qubits[:2] c = cirq.Circuit() c.append([ cirq.ZZPowGate(exponent=0.3)(q0, q1), cirq.ZZPowGate(exponent=0.1)(q0, q1), ]) new = simplify_circuit(c) # ZZPowGates have been merged assert len(new) == 1
def test_zztheta_qaoa_like(): qubits = cirq.LineQubit.range(4) for exponent in np.linspace(-1, 1, 10): circuit = cirq.Circuit([ cirq.H.on_each(qubits), cirq.ZZPowGate(exponent=exponent)(qubits[0], qubits[1]), cirq.ZZPowGate(exponent=exponent)(qubits[2], qubits[3]), cirq.rx(0.123).on_each(qubits), ]) converted_circuit = cirq.optimize_for_target_gateset( circuit, gateset=cirq_google.SycamoreTargetGateset()) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, converted_circuit, atol=1e-8)
def test_zztheta_qaoa_like(): qubits = cirq.LineQubit.range(4) for exponent in np.linspace(-1, 1, 10): cirq_circuit = cirq.Circuit([ cirq.H.on_each(qubits), cirq.ZZPowGate(exponent=exponent)(qubits[0], qubits[1]), cirq.ZZPowGate(exponent=exponent)(qubits[2], qubits[3]), cirq.rx(.123).on_each(qubits), ]) syc_circuit = cirq_circuit.copy() cgoc.ConvertToSycamoreGates().optimize_circuit(syc_circuit) cirq.testing.assert_allclose_up_to_global_phase( cirq.unitary(cirq_circuit), cirq.unitary(syc_circuit), atol=1e-7)
def _build_layer(label_qubit, data_qubits, label_symbol, data_symbols, full_layer_labeling=True): assert len(data_symbols) == len(data_qubits) * 3 - 1 # Add the label rotation layer = cirq.Circuit() if full_layer_labeling: for data_qubit in data_qubits: layer.append(cirq.rx(label_symbol).on(data_qubit)) if label_qubit is not None and label_symbol is not None: layer.append(cirq.rx(label_symbol).on(label_qubit)) # Define symbol iterator i = 0 # Add rx rotation for all qubits for data_qubit in data_qubits: layer.append([cirq.rx(data_symbols[i]).on(data_qubit)]) i += 1 # Add rz rotation to all qubits for data_qubit in data_qubits: layer.append([cirq.rz(data_symbols[i]).on(data_qubit)]) i += 1 # Add first moment of ZZ two qubit gates starting from 0th qubit j = 0 while j < len(data_qubits) - 1: layer.append([ cirq.ZZPowGate(exponent=data_symbols[i], global_shift=-0.5).on(data_qubits[j], data_qubits[j + 1]) ]) j += 2 i += 1 # Add second moment of ZZ two qubit gates starting from 1st qubit j = 1 while j < len(data_qubits) - 1: layer.append([ cirq.ZZPowGate(exponent=data_symbols[i], global_shift=-0.5).on(data_qubits[j], data_qubits[j + 1]) ]) j += 2 i += 1 return layer
def _swap_rzz(theta: float, q0: cirq.Qid, q1: cirq.Qid) -> cirq.OP_TREE: """An implementation of SWAP * exp(-1j * theta * ZZ) using three sycamore gates. This builds off of the _rzz method. Args: theta: The rotation parameter of Rzz Ising coupling gate. q0: First qubit to operate on. q1: Second qubit to operate on. Yields: The `cirq.OP_TREE`` that implements ZZ followed by a swap. """ # Set interaction part. angle_offset = np.pi / 24 - np.pi / 4 circuit = cirq.Circuit(ops.SYC(q0, q1), _rzz(theta - angle_offset, q0, q1)) # Get the intended circuit. intended_circuit = cirq.Circuit( cirq.SWAP(q0, q1), cirq.ZZPowGate(exponent=2 * theta / np.pi, global_shift=-0.5).on(q0, q1)) yield _create_corrected_circuit(cirq.unitary(intended_circuit), circuit, q0, q1)
def test_zz_qiskit(self): """Test the special ZZ (modified from cirq ZZPowGate) for qiskit """ #random.seed(RNDSEED) beta = random.uniform(-1, 1) # rotation angles (in multiples of pi) qubits = qiskit.QuantumRegister(2) circ = qiskit.QuantumCircuit(qubits) circ.cx(qubits[0], qubits[1]) circ.rz(beta * 2 * pi, qubits[1]) circ.cx(qubits[0], qubits[1]) z_circuit = Circuit(circ) u1 = z_circuit.to_unitary() circ2 = cirq.ZZPowGate(exponent=beta * 2) u2 = circ2._unitary_() u3 = [[cos(beta * pi) - 1j * sin(beta * pi), 0, 0, 0], [0, cos(beta * pi) + 1j * sin(beta * pi), 0, 0], [0, 0, cos(beta * pi) + 1j * sin(beta * pi), 0], [0, 0, 0, cos(beta * pi) - 1j * sin(beta * pi)]] self.assertTrue(compare_unitary(u1, u2, tol=1e-10)) self.assertTrue(compare_unitary(u2, u3, tol=1e-10))
def test_zz_pyquil(self): """Test the special ZZ (modified from cirq ZZPowGate) for pyquil """ #random.seed(RNDSEED) beta = random.uniform(-1, 1) # rotation angles (in multiples of pi) circ1 = pyquil.quil.Program(CNOT(0, 1), RZ(beta * 2 * pi, 1), CNOT(0, 1)) cirq_gate = cirq.ZZPowGate(exponent=beta * 2) cirq_circuit = cirq.Circuit() q = cirq.LineQubit(0) q2 = cirq.LineQubit(1) cirq_circuit.append(cirq_gate(q, q2)) z_circuit = Circuit(cirq_circuit) circ2 = z_circuit.to_pyquil() u1 = Circuit(circ1).to_unitary() u2 = Circuit(circ2).to_unitary() u3 = cirq_gate._unitary_() u4 = [[cos(beta * pi) - 1j * sin(beta * pi), 0, 0, 0], [0, cos(beta * pi) + 1j * sin(beta * pi), 0, 0], [0, 0, cos(beta * pi) + 1j * sin(beta * pi), 0], [0, 0, 0, cos(beta * pi) - 1j * sin(beta * pi)]] self.assertTrue(compare_unitary(u1, u2, tol=1e-10)) self.assertTrue(compare_unitary(u2, u3, tol=1e-10)) self.assertTrue(compare_unitary(u3, u4, tol=1e-10))
def test_zz_cirq(self): """Test the special ZZ (modified from cirq ZZPowGate) for cirq """ #random.seed(RNDSEED) beta = random.uniform(-1, 1) # we want to evolve under ZZ for time beta*pi cirq_gate = cirq.ZZPowGate(exponent=beta * 2) cirq_circuit = cirq.Circuit() q = cirq.LineQubit(0) q2 = cirq.LineQubit(1) cirq_circuit.append(cirq_gate(q, q2)) circuit2 = Circuit(cirq_circuit) circuit3 = circuit2.to_cirq() U1 = Circuit(cirq2pyquil(cirq_circuit)).to_unitary() U2 = Circuit(cirq2pyquil(circuit3)).to_unitary() U3 = [[cos(beta * pi) - 1j * sin(beta * pi), 0, 0, 0], [0, cos(beta * pi) + 1j * sin(beta * pi), 0, 0], [0, 0, cos(beta * pi) + 1j * sin(beta * pi), 0], [0, 0, 0, cos(beta * pi) - 1j * sin(beta * pi)]] if compare_unitary(U1, U2, tol=1e-10) == False: print(U1) print(U2) if compare_unitary(U2, U3, tol=1e-10) == False: print(U2) print(U3) self.assertTrue(compare_unitary(U1, U2, tol=1e-10), True) self.assertTrue(compare_unitary(U2, U3, tol=1e-10), True)
def __reset_circuit(self): self.__gamma_params = [] self.__beta_params = [] self.__circuit = cirq.Circuit( cirq.H.on_each(self.__circuit_graph.nodes())) for p_ in range(self.__p): gamma = sympy.Symbol('gamma_{}'.format(p_)) beta = sympy.Symbol('beta_{}'.format(p_)) self.__gamma_params.append(gamma) self.__beta_params.append(beta) self.__circuit.append( (cirq.ZZPowGate(exponent=2 * self.__gamma_params[-1] / np.pi)( u, v) for u, v in self.__circuit_graph.edges())) self.__circuit.append( cirq.Moment( cirq.rx(rads=2 * self.__beta_params[-1])(qubit) for qubit in self.__circuit_graph.nodes())) self.__circuit.append( (cirq.measure(qubit) for qubit in self.__circuit_graph.nodes()))
def _problem_to_zz(problem_graph: nx.Graph, qubits: Sequence[cirq.Qid], gamma: float): """Helper function used by `compile_problem_unitary_to_arbitrary_zz`.""" for i1, i2, weight in problem_graph.edges.data('weight'): q0 = qubits[i1] q1 = qubits[i2] yield cirq.ZZPowGate( exponent=2 * gamma * weight / np.pi, global_shift=-0.5).on(q0, q1)
def generate_clause_hamiltonian_exponential(clause, time): """Generates the operators for this clause. Applies e^(iZt) on each qubit, and e^(i ZZ t) on both. The sign of t gets flipped if the variable is negated. Args: clause: dnf_lib.Clause, the clause that defines the local Hamiltonian time: Float, how long to apply the Hamiltonian Returns: A list of operations corresponding to each of the gates being applied by this clause. """ # Corrects for the fact that ZPowGate and ZZPowGate perform e^(-i*\pi*Z*t/2) # up to global phase. time = -2 * time / math.pi return [ cirq.ZPowGate(exponent=_get_sign(clause.is_negative1) * time, global_shift=-0.5).on(cirq.LineQubit(clause.index1)), cirq.ZPowGate(exponent=_get_sign(clause.is_negative2) * time, global_shift=-0.5).on(cirq.LineQubit(clause.index2)), cirq.ZZPowGate( exponent=_get_sign(clause.is_negative1, clause.is_negative2) * time, global_shift=-0.5).on(cirq.LineQubit(clause.index1), cirq.LineQubit(clause.index2)) ]
def _interaction(row_start_offset=0, row_end_offset=0, row_step=1, col_start_offset=0, col_end_offset=0, col_step=1, get_neighbor=lambda row, col: (row, col)): for row in range(row_start + row_start_offset, row_end + row_end_offset, row_step): for col in range(col_start + col_start_offset, col_end + col_end_offset, col_step): coord1 = (row, col) if coord1 not in node_coordinates: continue coord2 = get_neighbor(row, col) if coord2 not in node_coordinates: continue node1 = coord_to_i[coord1] node2 = coord_to_i[coord2] if (node1, node2) not in problem_graph.edges: continue weight = problem_graph.edges[node1, node2]['weight'] yield cirq.ZZPowGate(exponent=2 * gamma * weight / np.pi, global_shift=-0.5) \ .on(qubits[node1], qubits[node2])
def get_match_circuit() -> cirq.Circuit: qubits = [cirq.LineQubit(i) for i in range(9)] g = cirq.CZPowGate(exponent=0.1) zz = cirq.ZZPowGate(exponent=0.3) px = cirq.PhasedXPowGate(phase_exponent=0.6, exponent=0.2) circ = cirq.Circuit( [ cirq.H(qubits[0]), cirq.X(qubits[1]), cirq.Y(qubits[2]), cirq.Z(qubits[3]), cirq.S(qubits[4]), cirq.CNOT(qubits[1], qubits[4]), cirq.T(qubits[3]), cirq.CNOT(qubits[6], qubits[8]), cirq.I(qubits[5]), cirq.XPowGate(exponent=0.1)(qubits[5]), cirq.YPowGate(exponent=0.1)(qubits[6]), cirq.ZPowGate(exponent=0.1)(qubits[7]), g(qubits[2], qubits[3]), zz(qubits[3], qubits[4]), px(qubits[6]), cirq.CZ(qubits[2], qubits[3]), cirq.ISWAP(qubits[4], qubits[5]), cirq.FSimGate(1.4, 0.7)(qubits[6], qubits[7]), cirq.google.SYC(qubits[3], qubits[0]), cirq.PhasedISwapPowGate(phase_exponent=0.7, exponent=0.8)( qubits[3], qubits[4]), cirq.GlobalPhaseOperation(1j), cirq.measure_each(*qubits[3:-2]), ], strategy=InsertStrategy.EARLIEST, ) return circ
def test_generate_dnf_hamiltonian_order(self): circuit = cirq.Circuit() dnf = dnf_lib.DNF(10, [dnf_lib.Clause(5, 7, False, False)]) circuit.append(dnf_circuit_lib.generate_dnf_hamiltonian_exponential( dnf, 0.5), strategy=insert_strategy.InsertStrategy.NEW_THEN_INLINE) generator = circuit.all_operations() operation = next(generator) self.assertEqual( operation, cirq.ZPowGate(exponent=-1.0 / math.pi, global_shift=-0.5).on(cirq.LineQubit(5))) operation = next(generator) self.assertEqual( operation, cirq.ZPowGate(exponent=-1.0 / math.pi, global_shift=-0.5).on(cirq.LineQubit(7))) operation = next(generator) self.assertEqual( operation, cirq.ZZPowGate(exponent=-1.0 / math.pi, global_shift=-0.5).on(cirq.LineQubit(5), cirq.LineQubit(7))) with self.assertRaises(StopIteration): next(generator)
def swap_rzz(theta: float, q0: cirq.Qid, q1: cirq.Qid) -> cirq.OP_TREE: """ An implementation of SWAP * EXP(1j theta ZZ) using three sycamore gates. This builds off of the zztheta method. A sycamore gate following the zz-gate is a SWAP EXP(1j (THETA - pi/24) ZZ). Args: theta: exp(1j * theta ) q0: First qubit id to operate on q1: Second qubit id to operate on Returns: The circuit that implements ZZ followed by a swap """ # Set interaction part. circuit = cirq.Circuit() angle_offset = np.pi / 24 - np.pi / 4 circuit.append(google.SYC(q0, q1)) circuit.append(rzz(theta - angle_offset, q0, q1)) # Get the intended circuit. intended_circuit = cirq.Circuit( cirq.SWAP(q0, q1), cirq.ZZPowGate(exponent=2 * theta / np.pi, global_shift=-0.5).on(q0, q1)) yield create_corrected_circuit(intended_circuit, circuit, q0, q1)
def exp_ZZ(self,angle,qubit1,qubit2): ''' returns Exp[i*angle*ZZ] ''' return cirq.ZZPowGate(exponent= (angle/sympy.pi)).on(qubit1,qubit2)
def create_mixer_ham(qubits_a, qubits_b, qubit_number, parameter_list): # Implements the exp(ZZ) operation on all entangled states for i in range(0, qubit_number): yield cirq.ZZPowGate(exponent= 2*parameter_list[0]/math.pi, global_shift= -0.5).on(qubits_a[i], qubits_b[i]) # Implements the exp(XX) operation on all entangled states for i in range(0, qubit_number): yield cirq.XXPowGate(exponent= 2*parameter_list[1]/math.pi, global_shift= -0.5).on(qubits_a[i], qubits_b[i])
def test_zz_as_syc(): q1, q2 = cirq.LineQubit.range(2) zz = cirq.ZZPowGate(exponent=np.random.rand(1)) circuit = zz_as_syc(zz.exponent * np.pi / 2, q1, q2) assert len(circuit) == 3 * 2 + 2 u1 = cirq.unitary(zz) u2 = cirq.unitary(circuit) cirq.testing.assert_allclose_up_to_global_phase(u1, u2, atol=1e-8)
def test_zztheta_zzpow(): qubits = cirq.LineQubit.range(2) for theta in np.linspace(0, 2 * np.pi, 10): syc_circuit = cirq.Circuit(cgoc.rzz(theta, qubits[0], qubits[1])) cirq_circuit = cirq.Circuit([ cirq.ZZPowGate(exponent=2 * theta / np.pi, global_shift=-0.5).on(*qubits) ]) cirq.testing.assert_allclose_up_to_global_phase( cirq.unitary(cirq_circuit), cirq.unitary(syc_circuit), atol=1e-7)
def test_zztheta_zzpow_unsorted_qubits(): qubits = cirq.LineQubit(1), cirq.LineQubit(0) exponent = 0.06366197723675814 circuit = cirq.Circuit( cirq.ZZPowGate(exponent=exponent, global_shift=-0.5).on(qubits[0], qubits[1]), ) converted_circuit = cirq.optimize_for_target_gateset( circuit, gateset=cirq_google.SycamoreTargetGateset()) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, converted_circuit, atol=1e-8)
def _create_U(self): """overwrite to remove Sympy parametrization.""" U_circuit = cirq.Circuit() p = 0 for n, j in enumerate(self.qubits): for k in self.qubits[n + 1:]: theta = tf.placeholder(dtype=tf.complex64, shape=(), name="Phi_{}".format(p)) U_circuit.append([cirq.ZZPowGate(exponent=theta)(j, k)], strategy=cirq.InsertStrategy.EARLIEST) p += 1 return U_circuit
def test_zz_as_syc_2(): q1, q2 = cirq.LineQubit.range(2) zz = cirq.ZZPowGate(exponent=0.123) circuit = zz_as_syc(zz.exponent * np.pi / 2, q1, q2) assert len(circuit) == 3 * 2 + 2 validate_well_structured(circuit) cirq.testing.assert_has_diagram(circuit, """ 0: ───PhX(1)^0.483───Z^(1/12)─────SYC────────────────────────SYC───PhX(0.917)^0.483───Z^(1/12)─── │ │ 1: ───PhX(-0.583)────Z^(-11/12)───SYC───PhX(0)^0.873───Z^0───SYC───PhX(0)─────────────T^-1─────── """)
def test_swap_zztheta(): qubits = cirq.LineQubit.range(2) a, b = qubits for theta in np.linspace(0, 2 * np.pi, 10): circuit = cirq.Circuit( cirq.SWAP(a, b), cirq.ZZPowGate(exponent=2 * theta / np.pi, global_shift=-0.5).on(a, b)) converted_circuit = cirq.optimize_for_target_gateset( circuit, gateset=cirq_google.SycamoreTargetGateset()) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, converted_circuit, atol=1e-8)
def specialized_kernel_circuit(qubits): """This circuit is N choose 2 exp(ZZ) gates interspersed with H wall.""" out = [] for i in range(2): H_gates = [cirq.H(q) for q in qubits] ZZ_gates = [] for n, qj in enumerate(qubits): for qk in qubits[n + 1:]: theta = random.uniform(-np.pi, np.pi) ZZ_gates.append(cirq.ZZPowGate(exponent=theta)(qj, qk)) out.append(H_gates + ZZ_gates) return out
def test_zztheta_zzpow_unsorted_qubits(): qubits = cirq.LineQubit(1), cirq.LineQubit(0) exponent = 0.06366197723675814 expected_circuit = cirq.Circuit( cirq.ZZPowGate(exponent=exponent, global_shift=-0.5).on(qubits[0], qubits[1]),) actual_circuit = expected_circuit.copy() cgoc.ConvertToSycamoreGates().optimize_circuit(actual_circuit) cirq.testing.assert_allclose_up_to_global_phase( cirq.unitary(expected_circuit), cirq.unitary(actual_circuit), atol=1e-7)