Beispiel #1
0
    def decompose_rotation(self) -> Sequence[Tuple[Pauli, int]]:
        """Decomposes this clifford into a series of pauli rotations.

        Each rotation is given as a tuple of (axis, quarter_turns),
        where axis is a Pauli giving the axis to rotate about. The
        result will be a sequence of zero, one, or two rotations.

        Note that the combined unitary effect of these rotations may
        differ from cirq.unitary(self) by a global phase.
        """
        x_rot = self.pauli_tuple(pauli_gates.X)
        y_rot = self.pauli_tuple(pauli_gates.Y)
        z_rot = self.pauli_tuple(pauli_gates.Z)
        whole_arr = (
            x_rot[0] == pauli_gates.X,
            y_rot[0] == pauli_gates.Y,
            z_rot[0] == pauli_gates.Z,
        )
        num_whole = sum(whole_arr)
        flip_arr = (x_rot[1], y_rot[1], z_rot[1])
        num_flip = sum(flip_arr)
        if num_whole == 3:
            if num_flip == 0:
                # Gate is identity
                return []

            # 180 rotation about some axis
            pauli = Pauli.by_index(flip_arr.index(False))
            return [(pauli, 2)]
        if num_whole == 1:
            index = whole_arr.index(True)
            pauli = Pauli.by_index(index)
            next_pauli = Pauli.by_index(index + 1)
            flip = flip_arr[index]
            output = []
            if flip:
                # 180 degree rotation
                output.append((next_pauli, 2))
            # 90 degree rotation about some axis
            if self.pauli_tuple(next_pauli)[1]:
                # Negative 90 degree rotation
                output.append((pauli, -1))
            else:
                # Positive 90 degree rotation
                output.append((pauli, 1))
            return output
        elif num_whole == 0:
            # Gate is a 120 degree rotation
            if x_rot[0] == pauli_gates.Y:
                return [
                    (pauli_gates.X, -1 if y_rot[1] else 1),
                    (pauli_gates.Z, -1 if x_rot[1] else 1),
                ]

            return [(pauli_gates.Z, 1 if y_rot[1] else -1), (pauli_gates.X, 1 if z_rot[1] else -1)]
        # coverage: ignore
        assert (
            False
        ), 'Impossible condition where this gate only rotates one Pauli to a different Pauli.'
    def decompose_rotation(self) -> Sequence[Tuple[Pauli, int]]:
        """Returns ((first_rotation_axis, first_rotation_quarter_turns), ...)

        This is a sequence of zero, one, or two rotations."""
        x_rot = self.transform(pauli_gates.X)
        y_rot = self.transform(pauli_gates.Y)
        z_rot = self.transform(pauli_gates.Z)
        whole_arr = (
            x_rot.to == pauli_gates.X,
            y_rot.to == pauli_gates.Y,
            z_rot.to == pauli_gates.Z,
        )
        num_whole = sum(whole_arr)
        flip_arr = (x_rot.flip, y_rot.flip, z_rot.flip)
        num_flip = sum(flip_arr)
        if num_whole == 3:
            if num_flip == 0:
                # Gate is identity
                return []

            # 180 rotation about some axis
            pauli = Pauli.by_index(flip_arr.index(False))
            return [(pauli, 2)]
        if num_whole == 1:
            index = whole_arr.index(True)
            pauli = Pauli.by_index(index)
            next_pauli = Pauli.by_index(index + 1)
            flip = flip_arr[index]
            output = []
            if flip:
                # 180 degree rotation
                output.append((next_pauli, 2))
            # 90 degree rotation about some axis
            if self.transform(next_pauli).flip:
                # Negative 90 degree rotation
                output.append((pauli, -1))
            else:
                # Positive 90 degree rotation
                output.append((pauli, 1))
            return output
        elif num_whole == 0:
            # Gate is a 120 degree rotation
            if x_rot.to == pauli_gates.Y:
                return [
                    (pauli_gates.X, -1 if y_rot.flip else 1),
                    (pauli_gates.Z, -1 if x_rot.flip else 1),
                ]

            return [
                (pauli_gates.Z, 1 if y_rot.flip else -1),
                (pauli_gates.X, 1 if z_rot.flip else -1),
            ]
        # coverage: ignore
        assert (
            False
        ), 'Impossible condition where this gate only rotates one Pauli to a different Pauli.'