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.'