Ejemplo n.º 1
0
    def from_op_list(
        cls, operations: Sequence[raw_types.Operation], qubit_order: Sequence[raw_types.Qid]
    ) -> 'CliffordGate':
        """Construct a new Clifford gates from several known operations.

        Args:
            operations: A list of cirq operations to construct the Clifford gate.
                The combination order is the first element in the list applies the transformation
                on the stabilizer state first.
            qubit_order: Determines how qubits are ordered when decomposite the operations.

        Returns:
            A CliffordGate instance, which has the transformation on the stabilizer
            state equivalent to the composition of operations.

        Raises:
            ValueError: When one or more operations do not have stabilizer effect.
        """
        for op in operations:
            if op.gate and op.gate._has_stabilizer_effect_():
                continue
            raise ValueError(
                "Clifford Gate can only be constructed from the "
                "operations that has stabilizer effect."
            )

        base_tableau = qis.CliffordTableau(len(qubit_order))
        args = sim.clifford.CliffordTableauSimulationState(
            tableau=base_tableau, qubits=qubit_order, prng=np.random.RandomState(0)  # unused
        )
        for op in operations:
            protocols.act_on(op, args, allow_decompose=True)

        return CliffordGate.from_clifford_tableau(args.tableau)
Ejemplo n.º 2
0
def _to_clifford_tableau(
    rotation_map: Optional[Dict[Pauli, Tuple[Pauli, bool]]] = None,
    *,
    x_to: Optional[Tuple[Pauli, bool]] = None,
    z_to: Optional[Tuple[Pauli, bool]] = None,
) -> qis.CliffordTableau:
    """Transfer the rotation map to clifford tableau representation"""
    if x_to is None and z_to is None and rotation_map is None:
        raise ValueError(
            "The function either takes rotation_map or a combination "
            ' of x_to and z_to but none were given.'
        )
    elif rotation_map is not None:
        x_to = rotation_map[pauli_gates.X]
        z_to = rotation_map[pauli_gates.Z]
    else:
        assert x_to is not None and z_to is not None, "Both x_to and z_to have to be provided."

    clifford_tableau = qis.CliffordTableau(num_qubits=1)
    clifford_tableau.xs[0, 0] = x_to[0] in (pauli_gates.X, pauli_gates.Y)
    clifford_tableau.zs[0, 0] = x_to[0] in (pauli_gates.Y, pauli_gates.Z)

    clifford_tableau.xs[1, 0] = z_to[0] in (pauli_gates.X, pauli_gates.Y)
    clifford_tableau.zs[1, 0] = z_to[0] in (pauli_gates.Y, pauli_gates.Z)

    clifford_tableau.rs = np.array([x_to[1], z_to[1]])
    return clifford_tableau
Ejemplo n.º 3
0
 def SWAP(cls) -> 'cirq.CliffordGate':
     if not hasattr(cls, '_SWAP'):
         t = qis.CliffordTableau(num_qubits=2)
         t.xs = np.array([[0, 1], [1, 0], [0, 0], [0, 0]])
         t.zs = np.array([[0, 0], [0, 0], [0, 1], [1, 0]])
         cls._SWAP = CliffordGate.from_clifford_tableau(t)
     return cls._SWAP
Ejemplo n.º 4
0
def _gate_tableau(num_qubits: int, gate: raw_types.Gate) -> 'cirq.CliffordTableau':
    qubits = devices.LineQubit.range(num_qubits)
    t = qis.CliffordTableau(num_qubits=num_qubits)
    args = sim.CliffordTableauSimulationState(
        tableau=t, qubits=qubits, prng=np.random.RandomState()
    )
    protocols.act_on(gate, args, qubits, allow_decompose=False)
    return args.tableau
Ejemplo n.º 5
0
    def _generate_clifford_from_known_gate(
            cls, num_qubits: int, gate: raw_types.Gate) -> 'CliffordGate':
        qubits = devices.LineQubit.range(num_qubits)
        t = qis.CliffordTableau(num_qubits=num_qubits)
        args = sim.ActOnCliffordTableauArgs(tableau=t,
                                            qubits=qubits,
                                            prng=np.random.RandomState(),
                                            log_of_measurement_results={})

        protocols.act_on(gate, args, qubits, allow_decompose=False)
        return CliffordGate.from_clifford_tableau(args.tableau)
Ejemplo n.º 6
0
    def _generate_clifford_from_known_gate(
        cls, num_qubits: int, gate: raw_types.Gate
    ) -> Union['SingleQubitCliffordGate', 'CliffordGate']:
        qubits = devices.LineQubit.range(num_qubits)
        t = qis.CliffordTableau(num_qubits=num_qubits)
        args = sim.CliffordTableauSimulationState(tableau=t,
                                                  qubits=qubits,
                                                  prng=np.random.RandomState())

        protocols.act_on(gate, args, qubits, allow_decompose=False)
        if num_qubits == 1:
            return SingleQubitCliffordGate.from_clifford_tableau(args.tableau)
        return CliffordGate.from_clifford_tableau(args.tableau)
Ejemplo n.º 7
0
def _pad_tableau(
    clifford_tableau: qis.CliffordTableau, num_qubits_after_padding: int, axes: List[int]
) -> qis.CliffordTableau:
    """Roughly, this function copies self.tableau into the "identity" matrix."""
    # Sanity check
    if len(set(axes)) != clifford_tableau.n:
        raise ValueError(
            "Input axes of padding should match with the number of qubits in the input tableau."
        )
    if clifford_tableau.n > num_qubits_after_padding:
        raise ValueError(
            "The number of qubits in the input tableau should not be larger than "
            "num_qubits_after_padding."
        )
    padded_tableau = qis.CliffordTableau(num_qubits_after_padding)
    v_index = np.concatenate((np.asarray(axes), num_qubits_after_padding + np.asarray(axes)))

    padded_tableau.xs[np.ix_(v_index, axes)] = clifford_tableau.xs
    padded_tableau.zs[np.ix_(v_index, axes)] = clifford_tableau.zs
    padded_tableau.rs[v_index] = clifford_tableau.rs
    return padded_tableau