Ejemplo n.º 1
0
def acquaint_insides(
    swap_gate: 'cirq.Gate',
    acquaintance_gate: 'cirq.Operation',
    qubits: Sequence['cirq.Qid'],
    before: bool,
    layers: Layers,
    mapping: Dict[ops.Qid, int],
) -> None:
    """Acquaints each of the qubits with another set specified by an
    acquaintance gate.

    Args:
        qubits: The list of qubits of which half are individually acquainted
            with another list of qubits.
        layers: The layers to put gates into.
        acquaintance_gate: The acquaintance gate that acquaints the end qubit
            with another list of qubits.
        before: Whether the acquainting is done before the shift.
        swap_gate: The gate used to swap logical indices.
        mapping: The mapping from qubits to logical indices. Used to keep track
            of the effect of inside-acquainting swaps.
    """

    max_reach = _get_max_reach(len(qubits), round_up=before)
    reaches = itertools.chain(range(1, max_reach + 1),
                              range(max_reach, -1, -1))
    offsets = (0, 1) * max_reach
    swap_gate = SwapPermutationGate(swap_gate)
    ops = []
    for offset, reach in zip(offsets, reaches):
        if offset == before:
            ops.append(acquaintance_gate)
        for dr in range(offset, reach, 2):
            ops.append(swap_gate(*qubits[dr:dr + 2]))
    intrastitial_layer = getattr(layers, 'pre' if before else 'post')
    intrastitial_layer += ops

    # add interstitial gate
    interstitial_layer = getattr(layers, ('prior' if before else 'posterior') +
                                 '_interstitial')
    interstitial_layer.append(acquaintance_gate)

    # update mapping
    reached_qubits = qubits[:max_reach + 1]
    positions = list(mapping[q] for q in reached_qubits)
    mapping.update(zip(reached_qubits, reversed(positions)))
Ejemplo n.º 2
0
def param_H(w_half_turns, w_axis_half_turns, z_half_turns, target):
    """Returns a parametrized Hadamard gate
    composed of gates in Cirq's native gate set."""
    op = []
    op.append(param_Winv(w_half_turns, w_axis_half_turns)(target))
    op.append(param_Z(z_half_turns)(target))
    op.append(param_W(w_half_turns, w_axis_half_turns)(target))
    return op
Ejemplo n.º 3
0
def param_CNOT(w_half_turns, w_axis_half_turns, proj11_half_turns,
               z_half_turns, control, target):
    """Returns a parametrized Hadamard gate
    composed of gates in Cirq's native gate set."""
    op = []
    op.append(param_H(w_half_turns, w_axis_half_turns, z_half_turns, target))
    op.append(param_11(proj11_half_turns)(control, target))
    op.append(param_H(w_half_turns, w_axis_half_turns, z_half_turns, target))
    out = np.asarray(op)
    out.flatten()
    out.tolist()
    return out
Ejemplo n.º 4
0
 def _decompose_(self) -> 'cirq.OP_TREE':
     result = self.circuit.unfreeze()
     result = result.transform_qubits(lambda q: self.qubit_map.get(q, q))
     if self.repetitions < 0:
         result = result**-1
     result = protocols.with_measurement_key_mapping(
         result, self.measurement_key_map)
     result = protocols.resolve_parameters(result,
                                           self.param_resolver,
                                           recursive=False)
     # repetition_ids don't need to be taken into account if the circuit has no measurements
     # or if repetition_ids are unset.
     if self.repetition_ids is None or not protocols.is_measurement(result):
         return list(result.all_operations()) * abs(self.repetitions)
     # If it's a measurement circuit with repetitions/repetition_ids, prefix the repetition_ids
     # to measurements. Details at https://tinyurl.com/measurement-repeated-circuitop.
     ops = []  # type: List[cirq.Operation]
     for parent_id in self.repetition_ids:
         for op in result.all_operations():
             if isinstance(op, CircuitOperation):
                 # For a CircuitOperation, prefix the current repetition_id to the children
                 # repetition_ids.
                 ops.append(
                     op.with_repetition_ids(
                         # If `op.repetition_ids` is None, this will return `[parent_id]`.
                         cartesian_product_of_string_lists(
                             [parent_id], op.repetition_ids)))
             elif protocols.is_measurement(op):
                 # For a non-CircuitOperation measurement, prefix the current repetition_id
                 # to the children measurement keys. Implemented by creating a mapping and
                 # using the with_measurement_key_mapping protocol.
                 ops.append(
                     protocols.with_measurement_key_mapping(
                         op,
                         key_map={
                             key:
                             f'{MEASUREMENT_KEY_SEPARATOR.join([parent_id, key])}'
                             for key in protocols.measurement_keys(op)
                         },
                     ))
             else:
                 ops.append(op)
     return ops