diff --git a/cirq-core/cirq/ops/phased_x_z_gate.py b/cirq-core/cirq/ops/phased_x_z_gate.py index a36722528f4..d4bc1401e3a 100644 --- a/cirq-core/cirq/ops/phased_x_z_gate.py +++ b/cirq-core/cirq/ops/phased_x_z_gate.py @@ -141,6 +141,15 @@ def _qasm_(self, args: 'cirq.QasmArgs', qubits: Tuple['cirq.Qid', ...]) -> Optio def _has_unitary_(self) -> bool: return not self._is_parameterized_() + def _unitary_(self) -> Optional[np.ndarray]: + """See `cirq.SupportsUnitary`.""" + if self._is_parameterized_(): + return None + z_pre = protocols.unitary(ops.Z ** -self._axis_phase_exponent) + x = protocols.unitary(ops.X ** self._x_exponent) + z_post = protocols.unitary(ops.Z ** (self._axis_phase_exponent + self._z_exponent)) + return z_post @ x @ z_pre + def _decompose_(self, qubits: Sequence['cirq.Qid']) -> 'cirq.OP_TREE': q = qubits[0] yield ops.Z(q) ** -self._axis_phase_exponent diff --git a/cirq-core/cirq/ops/phased_x_z_gate_test.py b/cirq-core/cirq/ops/phased_x_z_gate_test.py index 991d5457187..0536ff17984 100644 --- a/cirq-core/cirq/ops/phased_x_z_gate_test.py +++ b/cirq-core/cirq/ops/phased_x_z_gate_test.py @@ -199,6 +199,22 @@ def test_from_matrix_close_unitary(unitary: np.ndarray): ) +@pytest.mark.parametrize( + 'unitary', + [ + cirq.testing.random_unitary(2), + cirq.testing.random_unitary(2), + cirq.testing.random_unitary(2), + np.array([[0, 1], [1j, 0]]), + ], +) +def test_from_matrix_close_kraus(unitary: np.ndarray): + gate = cirq.PhasedXZGate.from_matrix(unitary) + kraus = cirq.kraus(gate) + assert len(kraus) == 1 + cirq.testing.assert_allclose_up_to_global_phase(kraus[0], unitary, atol=1e-8) + + def test_protocols(): a = random.random() b = random.random()