Skip to content

Commit 05649c2

Browse files
authored
Deprecate ignore_measurement_results (quantumlib#4978)
This can now be done in the measurement transformers, which also handle classically controlled operations. The simulator option does not (and can not) handle classical controls. This no longer should be a simulator option. Fixes quantumlib#4975
1 parent 4a0956b commit 05649c2

6 files changed

+131
-72
lines changed

cirq/sim/act_on_args.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
import numpy as np
3434

3535
from cirq import ops, protocols, value
36-
from cirq._compat import deprecated
36+
from cirq._compat import deprecated, deprecated_parameter
3737
from cirq.protocols.decompose_protocol import _try_decompose_into_operations_and_qubits
3838
from cirq.sim.operation_target import OperationTarget
3939

@@ -46,6 +46,12 @@
4646
class ActOnArgs(OperationTarget[TSelf]):
4747
"""State and context for an operation acting on a state tensor."""
4848

49+
@deprecated_parameter(
50+
deadline='v0.15',
51+
fix='Use cirq.dephase_measurements to transform the circuit before simulating.',
52+
parameter_desc='ignore_measurement_results',
53+
match=lambda args, kwargs: 'ignore_measurement_results' in kwargs or len(args) > 4,
54+
)
4955
def __init__(
5056
self,
5157
prng: Optional[np.random.RandomState] = None,

cirq/sim/act_on_density_matrix_args.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ class ActOnDensityMatrixArgs(ActOnArgs):
3333
storing the density matrix of the quantum system with one axis per qubit.
3434
"""
3535

36+
@_compat.deprecated_parameter(
37+
deadline='v0.15',
38+
fix='Use cirq.dephase_measurements to transform the circuit before simulating.',
39+
parameter_desc='ignore_measurement_results',
40+
match=lambda args, kwargs: 'ignore_measurement_results' in kwargs or len(args) > 7,
41+
)
3642
@_compat.deprecated_parameter(
3743
deadline='v0.15',
3844
fix='Use initial_state instead and specify all the arguments with keywords.',
@@ -86,13 +92,21 @@ def __init__(
8692
ValueError: The dimension of `target_tensor` is not divisible by 2
8793
and `qid_shape` is not provided.
8894
"""
89-
super().__init__(
90-
prng=prng,
91-
qubits=qubits,
92-
log_of_measurement_results=log_of_measurement_results,
93-
ignore_measurement_results=ignore_measurement_results,
94-
classical_data=classical_data,
95-
)
95+
if ignore_measurement_results:
96+
super().__init__(
97+
prng=prng,
98+
qubits=qubits,
99+
log_of_measurement_results=log_of_measurement_results,
100+
ignore_measurement_results=ignore_measurement_results,
101+
classical_data=classical_data,
102+
)
103+
else:
104+
super().__init__(
105+
prng=prng,
106+
qubits=qubits,
107+
log_of_measurement_results=log_of_measurement_results,
108+
classical_data=classical_data,
109+
)
96110
if target_tensor is None:
97111
qubits_qid_shape = protocols.qid_shape(self.qubits)
98112
initial_matrix = qis.to_valid_density_matrix(

cirq/sim/density_matrix_simulator.py

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import numpy as np
1818

1919
from cirq import ops, protocols, study, value
20-
from cirq._compat import deprecated, proper_repr
20+
from cirq._compat import deprecated, deprecated_parameter, proper_repr
2121
from cirq.sim import (
2222
simulator,
2323
act_on_density_matrix_args,
@@ -117,6 +117,12 @@ class DensityMatrixSimulator(
117117
# step_result.density_matrix()
118118
"""
119119

120+
@deprecated_parameter(
121+
deadline='v0.15',
122+
fix='Use cirq.dephase_measurements to transform the circuit before simulating.',
123+
parameter_desc='ignore_measurement_results',
124+
match=lambda _, kwargs: 'ignore_measurement_results' in kwargs,
125+
)
120126
def __init__(
121127
self,
122128
*,
@@ -162,13 +168,21 @@ def __init__(
162168
when `ignore_measurement_results` has been set to True
163169
(for more see https://github.com/quantumlib/Cirq/issues/2777).
164170
"""
165-
super().__init__(
166-
dtype=dtype,
167-
noise=noise,
168-
seed=seed,
169-
ignore_measurement_results=ignore_measurement_results,
170-
split_untangled_states=split_untangled_states,
171-
)
171+
if ignore_measurement_results:
172+
super().__init__(
173+
dtype=dtype,
174+
noise=noise,
175+
seed=seed,
176+
ignore_measurement_results=ignore_measurement_results,
177+
split_untangled_states=split_untangled_states,
178+
)
179+
else:
180+
super().__init__(
181+
dtype=dtype,
182+
noise=noise,
183+
seed=seed,
184+
split_untangled_states=split_untangled_states,
185+
)
172186
if dtype not in {np.complex64, np.complex128}:
173187
raise ValueError(f'dtype must be complex64 or complex128, was {dtype}')
174188

@@ -195,11 +209,19 @@ def _create_partial_act_on_args(
195209
if isinstance(initial_state, act_on_density_matrix_args.ActOnDensityMatrixArgs):
196210
return initial_state
197211

212+
if self._ignore_measurement_results:
213+
return act_on_density_matrix_args.ActOnDensityMatrixArgs(
214+
qubits=qubits,
215+
prng=self._prng,
216+
classical_data=classical_data,
217+
ignore_measurement_results=self._ignore_measurement_results,
218+
initial_state=initial_state,
219+
dtype=self._dtype,
220+
)
198221
return act_on_density_matrix_args.ActOnDensityMatrixArgs(
199222
qubits=qubits,
200223
prng=self._prng,
201224
classical_data=classical_data,
202-
ignore_measurement_results=self._ignore_measurement_results,
203225
initial_state=initial_state,
204226
dtype=self._dtype,
205227
)

cirq/sim/density_matrix_simulator_test.py

Lines changed: 52 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,10 @@ def test_invalid_dtype():
7373
@pytest.mark.parametrize('split', [True, False])
7474
def test_run_with_ignore_measurement_results(dtype: Type[np.number], split: bool):
7575
q0, q1 = cirq.LineQubit.range(2)
76-
simulator = cirq.DensityMatrixSimulator(
77-
dtype=dtype, ignore_measurement_results=True, split_untangled_states=split
78-
)
76+
with cirq.testing.assert_deprecated('ignore_measurement_results', deadline='v0.15', count=2):
77+
simulator = cirq.DensityMatrixSimulator(
78+
dtype=dtype, ignore_measurement_results=True, split_untangled_states=split
79+
)
7980

8081
circuit = cirq.Circuit(cirq.X(q0), cirq.X(q1), cirq.measure(q0))
8182
with pytest.raises(ValueError, match="ignore_measurement_results = True"):
@@ -517,26 +518,32 @@ def test_simulate(dtype: Type[np.number], split: bool):
517518
@pytest.mark.parametrize('split', [True, False])
518519
def test_simulate_ignore_measurements(split: bool):
519520
q0 = cirq.LineQubit(0)
520-
simulator = cirq.DensityMatrixSimulator(
521-
split_untangled_states=split, ignore_measurement_results=True
522-
)
523-
circuit = cirq.Circuit(cirq.H(q0), cirq.measure(q0))
524-
result = simulator.simulate(circuit)
525-
np.testing.assert_almost_equal(result.final_density_matrix, np.eye(2) * 0.5)
526-
assert len(result.measurements) == 0
521+
with cirq.testing.assert_deprecated(
522+
'ignore_measurement_results', deadline='v0.15', count=6 if split else 4
523+
):
524+
simulator = cirq.DensityMatrixSimulator(
525+
split_untangled_states=split, ignore_measurement_results=True
526+
)
527+
circuit = cirq.Circuit(cirq.H(q0), cirq.measure(q0))
528+
result = simulator.simulate(circuit)
529+
np.testing.assert_almost_equal(result.final_density_matrix, np.eye(2) * 0.5)
530+
assert len(result.measurements) == 0
527531

528532

529533
@pytest.mark.parametrize('split', [True, False])
530534
def test_simulate_ignore_measurements_subcircuits(split: bool):
531535
q0 = cirq.LineQubit(0)
532-
simulator = cirq.DensityMatrixSimulator(
533-
split_untangled_states=split, ignore_measurement_results=True
534-
)
535-
circuit = cirq.Circuit(cirq.H(q0), cirq.measure(q0))
536-
circuit = cirq.Circuit(cirq.CircuitOperation(circuit.freeze()))
537-
result = simulator.simulate(circuit)
538-
np.testing.assert_almost_equal(result.final_density_matrix, np.eye(2) * 0.5)
539-
assert len(result.measurements) == 0
536+
with cirq.testing.assert_deprecated(
537+
'ignore_measurement_results', deadline='v0.15', count=6 if split else 4
538+
):
539+
simulator = cirq.DensityMatrixSimulator(
540+
split_untangled_states=split, ignore_measurement_results=True
541+
)
542+
circuit = cirq.Circuit(cirq.H(q0), cirq.measure(q0))
543+
circuit = cirq.Circuit(cirq.CircuitOperation(circuit.freeze()))
544+
result = simulator.simulate(circuit)
545+
np.testing.assert_almost_equal(result.final_density_matrix, np.eye(2) * 0.5)
546+
assert len(result.measurements) == 0
540547

541548

542549
@pytest.mark.parametrize('dtype', [np.complex64, np.complex128])
@@ -573,24 +580,25 @@ def test_reset_one_qubit_does_not_affect_partial_trace_of_other_qubits(
573580

574581
def test_ignore_measurements_remains_entangled():
575582
q0, q1 = cirq.LineQubit.range(2)
576-
simulator1 = cirq.DensityMatrixSimulator(
577-
ignore_measurement_results=True, split_untangled_states=False
578-
)
579-
simulator2 = cirq.DensityMatrixSimulator(
580-
ignore_measurement_results=True, split_untangled_states=True
581-
)
582-
circuit = cirq.Circuit(
583-
cirq.H(q0),
584-
cirq.CX(q0, q1),
585-
cirq.measure(q0),
586-
)
587-
result1 = simulator1.simulate(circuit)
588-
result2 = simulator2.simulate(circuit)
589-
np.testing.assert_almost_equal(result2.final_density_matrix, result1.final_density_matrix)
590-
expected = np.zeros((4, 4))
591-
expected[0, 0] = 0.5
592-
expected[3, 3] = 0.5
593-
np.testing.assert_almost_equal(result2.final_density_matrix, expected)
583+
with cirq.testing.assert_deprecated('ignore_measurement_results', deadline='v0.15', count=12):
584+
simulator1 = cirq.DensityMatrixSimulator(
585+
ignore_measurement_results=True, split_untangled_states=False
586+
)
587+
simulator2 = cirq.DensityMatrixSimulator(
588+
ignore_measurement_results=True, split_untangled_states=True
589+
)
590+
circuit = cirq.Circuit(
591+
cirq.H(q0),
592+
cirq.CX(q0, q1),
593+
cirq.measure(q0),
594+
)
595+
result1 = simulator1.simulate(circuit)
596+
result2 = simulator2.simulate(circuit)
597+
np.testing.assert_almost_equal(result2.final_density_matrix, result1.final_density_matrix)
598+
expected = np.zeros((4, 4))
599+
expected[0, 0] = 0.5
600+
expected[3, 3] = 0.5
601+
np.testing.assert_almost_equal(result2.final_density_matrix, expected)
594602

595603

596604
@pytest.mark.parametrize(
@@ -1225,13 +1233,14 @@ def with_qubits(self, *new_qubits):
12251233
def _kraus_(self):
12261234
return cirq.kraus(cirq.H)
12271235

1228-
s = cirq.DensityMatrixSimulator(ignore_measurement_results=True)
1229-
c = cirq.Circuit(HAsOp(cirq.LineQubit(0)))
1230-
np.testing.assert_allclose(
1231-
s.simulate(c).final_density_matrix,
1232-
[[0.5 + 0.0j, 0.5 + 0.0j], [0.5 + 0.0j, 0.5 + 0.0j]],
1233-
atol=1e-8,
1234-
)
1236+
with cirq.testing.assert_deprecated('ignore_measurement_results', deadline='v0.15', count=6):
1237+
s = cirq.DensityMatrixSimulator(ignore_measurement_results=True)
1238+
c = cirq.Circuit(HAsOp(cirq.LineQubit(0)))
1239+
np.testing.assert_allclose(
1240+
s.simulate(c).final_density_matrix,
1241+
[[0.5 + 0.0j, 0.5 + 0.0j], [0.5 + 0.0j, 0.5 + 0.0j]],
1242+
atol=1e-8,
1243+
)
12351244

12361245

12371246
def test_works_on_pauli_string_phasor():

cirq/sim/simulator_base.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import numpy as np
3737

3838
from cirq import ops, protocols, study, value, devices
39+
from cirq._compat import deprecated_parameter
3940
from cirq.sim import ActOnArgsContainer
4041
from cirq.sim.operation_target import OperationTarget
4142
from cirq.sim.simulator import (
@@ -92,6 +93,12 @@ class SimulatorBase(
9293
`_core_iterator` and `_run` methods.
9394
"""
9495

96+
@deprecated_parameter(
97+
deadline='v0.15',
98+
fix='Use cirq.dephase_measurements to transform the circuit before simulating.',
99+
parameter_desc='ignore_measurement_results',
100+
match=lambda _, kwargs: 'ignore_measurement_results' in kwargs,
101+
)
95102
def __init__(
96103
self,
97104
*,

cirq/transformers/measurement_transformers_test.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,19 @@ def assert_equivalent_to_deferred(circuit: cirq.Circuit):
3939

4040
def assert_equivalent_to_dephased(circuit: cirq.Circuit):
4141
qubits = list(circuit.all_qubits())
42-
sim = cirq.DensityMatrixSimulator(ignore_measurement_results=True)
43-
num_qubits = len(qubits)
44-
backwards = list(circuit.all_operations())[::-1]
45-
for j in range(num_qubits):
46-
backwards.append(cirq.H(qubits[j]) ** np.random.rand())
47-
modified = cirq.Circuit(backwards[::-1])
48-
for j in range(num_qubits):
49-
modified.append(cirq.H(qubits[j]) ** np.random.rand())
50-
dephased = cirq.dephase_measurements(modified)
51-
result = sim.simulate(modified)
52-
result1 = sim.simulate(dephased)
53-
np.testing.assert_almost_equal(result.final_density_matrix, result1.final_density_matrix)
42+
with cirq.testing.assert_deprecated('ignore_measurement_results', deadline='v0.15', count=14):
43+
sim = cirq.DensityMatrixSimulator(ignore_measurement_results=True)
44+
num_qubits = len(qubits)
45+
backwards = list(circuit.all_operations())[::-1]
46+
for j in range(num_qubits):
47+
backwards.append(cirq.H(qubits[j]) ** np.random.rand())
48+
modified = cirq.Circuit(backwards[::-1])
49+
for j in range(num_qubits):
50+
modified.append(cirq.H(qubits[j]) ** np.random.rand())
51+
dephased = cirq.dephase_measurements(modified)
52+
result = sim.simulate(modified)
53+
result1 = sim.simulate(dephased)
54+
np.testing.assert_almost_equal(result.final_density_matrix, result1.final_density_matrix)
5455

5556

5657
def test_basic():

0 commit comments

Comments
 (0)