From d432730d10aeddbb26d180edda3e6b4dddb784fb Mon Sep 17 00:00:00 2001 From: Tanuj Khattar Date: Fri, 16 Feb 2024 12:40:28 -0800 Subject: [PATCH 1/2] Bugfix in _strat_has_stabilizer_effect_from_decompose (#6467) --- .../protocols/has_stabilizer_effect_protocol.py | 6 +----- .../has_stabilizer_effect_protocol_test.py | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/cirq-core/cirq/protocols/has_stabilizer_effect_protocol.py b/cirq-core/cirq/protocols/has_stabilizer_effect_protocol.py index 0192c42d145..1958c3e61de 100644 --- a/cirq-core/cirq/protocols/has_stabilizer_effect_protocol.py +++ b/cirq-core/cirq/protocols/has_stabilizer_effect_protocol.py @@ -102,11 +102,7 @@ def _strat_has_stabilizer_effect_from_unitary(val: Any) -> Optional[bool]: def _strat_has_stabilizer_effect_from_decompose(val: Any) -> Optional[bool]: - qid_shape = qid_shape_protocol.qid_shape(val, default=None) - if qid_shape is None or len(qid_shape) <= 3: - return None - - decomposition = decompose_protocol.decompose_once(val, default=None) + decomposition, _, _ = decompose_protocol._try_decompose_into_operations_and_qubits(val) if decomposition is None: return None for op in decomposition: diff --git a/cirq-core/cirq/protocols/has_stabilizer_effect_protocol_test.py b/cirq-core/cirq/protocols/has_stabilizer_effect_protocol_test.py index 0fb293681cc..e664a102ab6 100644 --- a/cirq-core/cirq/protocols/has_stabilizer_effect_protocol_test.py +++ b/cirq-core/cirq/protocols/has_stabilizer_effect_protocol_test.py @@ -41,15 +41,15 @@ def _has_stabilizer_effect_(self): return True -q = cirq.LineQubit(0) - - class EmptyOp(cirq.Operation): """A trivial operation.""" + def __init__(self, q: cirq.Qid = cirq.LineQubit(0)): + self.q = q + @property def qubits(self): - return (q,) + return (self.q,) def with_qubits(self, *new_qubits): # pragma: no cover return self @@ -97,6 +97,14 @@ def qubits(self): return cirq.LineQubit.range(self.unitary.shape[0].bit_length() - 1) +class GateDecomposes(cirq.Gate): + def _num_qubits_(self): + return 1 + + def _decompose_(self, qubits): + yield YesOp(*qubits) + + def test_inconclusive(): assert not cirq.has_stabilizer_effect(object()) assert not cirq.has_stabilizer_effect('boo') @@ -146,3 +154,4 @@ def test_via_decompose(): assert not cirq.has_stabilizer_effect( OpWithUnitary(cirq.unitary(cirq.Circuit(cirq.T.on_each(cirq.LineQubit.range(4))))) ) + assert cirq.has_stabilizer_effect(GateDecomposes()) From a8bd9a59d44a3d071084d34f22c57e2b87d39461 Mon Sep 17 00:00:00 2001 From: Doug Strain Date: Fri, 16 Feb 2024 14:26:53 -0800 Subject: [PATCH 2/2] Change str of ResultDict to print out repeated measurements (#6468) - ResultDict will now print out repeated measurements on each line, as opposed to throwing ValueError Fixes: #6447 --- cirq-core/cirq/study/result.py | 14 ++++++++++++++ cirq-core/cirq/study/result_test.py | 6 ++++++ 2 files changed, 20 insertions(+) diff --git a/cirq-core/cirq/study/result.py b/cirq-core/cirq/study/result.py index 53158848d3a..0786e997240 100644 --- a/cirq-core/cirq/study/result.py +++ b/cirq-core/cirq/study/result.py @@ -74,6 +74,18 @@ def _keyed_repeated_bitstrings(vals: Mapping[str, np.ndarray]) -> str: return '\n'.join(keyed_bitstrings) +def _keyed_repeated_records(vals: Mapping[str, np.ndarray]) -> str: + keyed_bitstrings = [] + for key in sorted(vals.keys()): + reps = vals[key] + n = reps.shape[2] + num_records = reps.shape[1] + for j in range(num_records): + all_bits = ', '.join(_bitstring(reps[:, j, i]) for i in range(n)) + keyed_bitstrings.append(f'{key}={all_bits}') + return '\n'.join(keyed_bitstrings) + + def _key_to_str(key: TMeasurementKey) -> str: if isinstance(key, str): return key @@ -388,6 +400,8 @@ def _repr_pretty_(self, p: Any, cycle: bool) -> None: p.text(str(self)) def __str__(self) -> str: + if self._records: + return _keyed_repeated_records(self.records) return _keyed_repeated_bitstrings(self.measurements) def _json_dict_(self): diff --git a/cirq-core/cirq/study/result_test.py b/cirq-core/cirq/study/result_test.py index a335bed2859..04adccf2b14 100644 --- a/cirq-core/cirq/study/result_test.py +++ b/cirq-core/cirq/study/result_test.py @@ -127,6 +127,12 @@ def test_str(): ) assert str(result) == 'ab=13579, 2 4 6 8 10\nc=01234' + result = cirq.ResultDict(records={'c': np.array([[[True], [True]]])}) + assert str(result) == 'c=1\nc=1' + + result = cirq.ResultDict(records={'c': np.array([[[True, False], [False, True]]])}) + assert str(result) == 'c=1, 0\nc=0, 1' + def test_df(): result = cirq.ResultDict(