예제 #1
0
 def map_func(op: 'cirq.Operation', _) -> 'cirq.OP_TREE':
     op_untagged = op.untagged
     if (
         deep
         and isinstance(op_untagged, circuits.CircuitOperation)
         and merged_circuit_op_tag not in op.tags
     ):
         return op_untagged.replace(
             circuit=_rewrite_merged_k_qubit_unitaries(
                 op_untagged.circuit,
                 context=context,
                 k=k,
                 rewriter=rewriter,
                 merged_circuit_op_tag=merged_circuit_op_tag,
             ).freeze()
         ).with_tags(*op.tags)
     if not (protocols.num_qubits(op) <= k and protocols.has_unitary(op)):
         return op
     if rewriter:
         return rewriter(
             cast(circuits.CircuitOperation, op_untagged)
             if merged_circuit_op_tag in op.tags
             else circuits.CircuitOperation(circuits.FrozenCircuit(op))
         )
     return ops.MatrixGate(protocols.unitary(op)).on(*op.qubits)
예제 #2
0
 def apply_map(op: ops.Operation, idx: int) -> ops.OP_TREE:
     c = circuits.FrozenCircuit(map_func(op, idx))
     if not c.all_qubits().issubset(op.qubits):
         raise ValueError(
             f"Mapped operations {c.all_operations()} should act on a subset "
             f"of qubits of the original operation {op}"
         )
     if len(c) == 1:
         # All operations act in the same moment; so we don't need to wrap them in a circuit_op.
         return c[0].operations
     circuit_op = circuits.CircuitOperation(c).with_tags(MAPPED_CIRCUIT_OP_TAG)
     return circuit_op
예제 #3
0
    def merge_func(op1: 'cirq.Operation',
                   op2: 'cirq.Operation') -> Optional['cirq.Operation']:
        def get_ops(op: 'cirq.Operation'):
            op_untagged = op.untagged
            return ([*op_untagged.circuit.all_operations()]
                    if isinstance(op_untagged, circuits.CircuitOperation)
                    and merged_circuit_op_tag in op.tags else [op])

        left_ops, right_ops = get_ops(op1), get_ops(op2)
        if not can_merge(left_ops, right_ops):
            return None
        return circuits.CircuitOperation(
            circuits.FrozenCircuit(left_ops,
                                   right_ops)).with_tags(merged_circuit_op_tag)
예제 #4
0
 def apply_map(op: ops.Operation, idx: int) -> ops.OP_TREE:
     if not set(op.tags).isdisjoint(tags_to_ignore):
         return op
     c = circuits.FrozenCircuit(map_func(op, idx))
     if raise_if_add_qubits and not c.all_qubits().issubset(op.qubits):
         raise ValueError(
             f"Mapped operations {c.all_operations()} should act on a subset "
             f"of qubits of the original operation {op}")
     if len(c) <= 1:
         # Either empty circuit or all operations act in the same moment;
         # So, we don't need to wrap them in a circuit_op.
         return c[0].operations if c else []
     circuit_op = circuits.CircuitOperation(c).with_tags(
         MAPPED_CIRCUIT_OP_TAG)
     return circuit_op