def test_map_operations_does_not_insert_too_many_moments(): q = cirq.LineQubit.range(5) c_orig = cirq.Circuit( cirq.CX(q[0], q[1]), cirq.CX(q[3], q[2]), cirq.CX(q[3], q[4]), ) def map_func(op: cirq.Operation, _: int) -> cirq.OP_TREE: if op.gate == cirq.CX: yield cirq.Z.on_each(*op.qubits) yield cirq.CX(*op.qubits) yield cirq.Z.on_each(*op.qubits) return op cirq.testing.assert_has_diagram( c_orig, ''' 0: ───@─────── │ 1: ───X─────── 2: ───X─────── │ 3: ───@───@─── │ 4: ───────X─── ''', ) c_mapped = cirq.map_operations(c_orig, map_func) circuit_op = cirq.CircuitOperation( cirq.FrozenCircuit(cirq.Z.on_each(q[0], q[1]), cirq.CNOT(q[0], q[1]), cirq.Z.on_each(q[0], q[1]))) c_expected = cirq.Circuit( circuit_op.with_qubits( q[0], q[1]).mapped_op().with_tags('<mapped_circuit_op>'), circuit_op.with_qubits( q[3], q[2]).mapped_op().with_tags('<mapped_circuit_op>'), circuit_op.with_qubits( q[3], q[4]).mapped_op().with_tags('<mapped_circuit_op>'), ) cirq.testing.assert_same_circuits(c_mapped, c_expected) cirq.testing.assert_has_diagram( cirq.map_operations_and_unroll(c_orig, map_func), ''' 0: ───Z───@───Z─────────────── │ 1: ───Z───X───Z─────────────── 2: ───Z───X───Z─────────────── │ 3: ───Z───@───Z───Z───@───Z─── │ 4: ───────────────Z───X───Z─── ''', )
def _decompose_two_qubit(operation: cirq.Operation) -> cirq.OP_TREE: """Decomposes a two qubit unitary operation into ZPOW, XPOW, and CNOT.""" mat = cirq.unitary(operation) q0, q1 = operation.qubits naive = cirq.two_qubit_matrix_to_cz_operations(q0, q1, mat, allow_partial_czs=False) temp = cirq.map_operations_and_unroll( cirq.Circuit(naive), lambda op, _: [cirq.H(op.qubits[1]), cirq.CNOT(*op.qubits), cirq.H(op.qubits[1])] if type(op.gate) == cirq.CZPowGate else op, ) temp = cirq.merge_single_qubit_gates_to_phased_x_and_z(temp) # A final pass breaks up PhasedXPow into Rz, Rx. yield cirq.map_operations_and_unroll( temp, lambda op, _: cirq.decompose_once(op) if type(op.gate) == cirq.PhasedXPowGate else op).all_operations()
def test_map_operations_can_write_new_gates_inline(): x = cirq.NamedQubit('x') y = cirq.NamedQubit('y') z = cirq.NamedQubit('z') c = cirq.Circuit( cirq.CZ(x, y), cirq.Y(x), cirq.Z(x), cirq.X(y), cirq.CNOT(y, z), cirq.Z(y), cirq.Z(x), cirq.CNOT(y, z), cirq.CNOT(z, y), ) cirq.testing.assert_has_diagram( c, ''' x: ───@───Y───Z───Z─────────── │ y: ───@───X───@───Z───@───X─── │ │ │ z: ───────────X───────X───@─── ''', ) expected_diagram = ''' x: ───X───X───X───X─────────── y: ───X───X───X───X───X───X─── z: ───────────X───────X───X─── ''' cirq.testing.assert_has_diagram( cirq.map_operations(c, lambda op, _: cirq.X.on_each(*op.qubits)), expected_diagram) cirq.testing.assert_has_diagram( cirq.map_operations_and_unroll( c, lambda op, _: cirq.X.on_each(*op.qubits)), expected_diagram, )
def _decompose_two_qubit_operation(self, op: cirq.Operation, _) -> cirq.OP_TREE: if not cirq.has_unitary(op): return NotImplemented mat = cirq.unitary(op) q0, q1 = op.qubits naive = cirq.two_qubit_matrix_to_cz_operations(q0, q1, mat, allow_partial_czs=False) temp = cirq.map_operations_and_unroll( cirq.Circuit(naive), lambda op, _: [ cirq.H(op.qubits[1]), cirq.CNOT(*op.qubits), cirq.H(op.qubits[1]) ] if op.gate == cirq.CZ else op, ) return cirq.merge_k_qubit_unitaries( temp, k=1, rewriter=lambda op: self._decompose_single_qubit_operation( op, -1)).all_operations()