Skip to content

Commit 689dc69

Browse files
95-martin-orionrht
authored andcommitted
Cirq monofsv cleanup (quantumlib#5685)
Fixes quantumlib#3494. This PR bundles together a bunch of cleanup around `[final_]state_vector` deprecations.
1 parent d6934c2 commit 689dc69

15 files changed

+59
-116
lines changed

cirq-core/cirq/circuits/circuit.py

+3-13
Original file line numberDiff line numberDiff line change
@@ -1091,12 +1091,11 @@ def _superoperator_(self) -> np.ndarray:
10911091
)
10921092
def final_state_vector(
10931093
self,
1094-
# TODO(v0.16): Force kwargs and match order found in:
1095-
# cirq-core/cirq/sim/mux.py:final_state_vector
1094+
*,
10961095
initial_state: 'cirq.STATE_VECTOR_LIKE' = 0,
10971096
qubit_order: 'cirq.QubitOrderOrList' = ops.QubitOrder.DEFAULT,
10981097
qubits_that_should_be_present: Iterable['cirq.Qid'] = (),
1099-
ignore_terminal_measurements: Optional[bool] = None,
1098+
ignore_terminal_measurements: bool = False,
11001099
dtype: Type[np.complexfloating] = np.complex128,
11011100
param_resolver: 'cirq.ParamResolverOrSimilarType' = None,
11021101
seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
@@ -1120,7 +1119,7 @@ def final_state_vector(
11201119
regardless when generating the matrix.
11211120
ignore_terminal_measurements: When set, measurements at the end of
11221121
the circuit are ignored instead of causing the method to
1123-
fail.
1122+
fail. Defaults to False.
11241123
dtype: The `numpy.dtype` used by the simulation. Typically one of
11251124
`numpy.complex64` or `numpy.complex128`.
11261125
param_resolver: Parameters to run with the program.
@@ -1138,15 +1137,6 @@ def final_state_vector(
11381137
ValueError: If the program doesn't have a well defined final state
11391138
because it has non-unitary gates.
11401139
"""
1141-
if ignore_terminal_measurements is None:
1142-
if self.has_measurements():
1143-
_compat._warn_or_error(
1144-
'`ignore_terminal_measurements` will default to False in v0.16. '
1145-
'To drop terminal measurements, please explicitly include '
1146-
'`ignore_terminal_measurements=True` when calling this method.'
1147-
)
1148-
ignore_terminal_measurements = True
1149-
11501140
from cirq.sim.mux import final_state_vector
11511141

11521142
program = Circuit(cirq.I(q) for q in qubits_that_should_be_present) + self

cirq-core/cirq/circuits/circuit_operation_test.py

+17-17
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ def test_recursive_params():
269269

270270
# First example should behave like an X when simulated
271271
result = cirq.Simulator().simulate(cirq.Circuit(circuitop), param_resolver=outer_params)
272-
assert np.allclose(result.state_vector(copy=False), [0, 1])
272+
assert np.allclose(result.state_vector(), [0, 1])
273273

274274

275275
@pytest.mark.parametrize('add_measurements', [True, False])
@@ -345,9 +345,9 @@ def test_repeat_zero_times(add_measurements, use_repetition_ids, initial_reps):
345345
subcircuit.freeze(), repetitions=initial_reps, use_repetition_ids=use_repetition_ids
346346
)
347347
result = cirq.Simulator().simulate(cirq.Circuit(op))
348-
assert np.allclose(result.state_vector(copy=False), [0, 1] if initial_reps % 2 else [1, 0])
348+
assert np.allclose(result.state_vector(), [0, 1] if initial_reps % 2 else [1, 0])
349349
result = cirq.Simulator().simulate(cirq.Circuit(op**0))
350-
assert np.allclose(result.state_vector(copy=False), [1, 0])
350+
assert np.allclose(result.state_vector(), [1, 0])
351351

352352

353353
def test_no_repetition_ids():
@@ -377,13 +377,13 @@ def test_parameterized_repeat():
377377
assert cirq.parameter_names(op) == {'a'}
378378
assert not cirq.has_unitary(op)
379379
result = cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 0})
380-
assert np.allclose(result.state_vector(copy=False), [1, 0])
380+
assert np.allclose(result.state_vector(), [1, 0])
381381
result = cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 1})
382-
assert np.allclose(result.state_vector(copy=False), [0, 1])
382+
assert np.allclose(result.state_vector(), [0, 1])
383383
result = cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 2})
384-
assert np.allclose(result.state_vector(copy=False), [1, 0])
384+
assert np.allclose(result.state_vector(), [1, 0])
385385
result = cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': -1})
386-
assert np.allclose(result.state_vector(copy=False), [0, 1])
386+
assert np.allclose(result.state_vector(), [0, 1])
387387
with pytest.raises(TypeError, match='Only integer or sympy repetitions are allowed'):
388388
cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 1.5})
389389
with pytest.raises(ValueError, match='Circuit contains ops whose symbols were not specified'):
@@ -392,13 +392,13 @@ def test_parameterized_repeat():
392392
assert cirq.parameter_names(op) == {'a'}
393393
assert not cirq.has_unitary(op)
394394
result = cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 0})
395-
assert np.allclose(result.state_vector(copy=False), [1, 0])
395+
assert np.allclose(result.state_vector(), [1, 0])
396396
result = cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 1})
397-
assert np.allclose(result.state_vector(copy=False), [0, 1])
397+
assert np.allclose(result.state_vector(), [0, 1])
398398
result = cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 2})
399-
assert np.allclose(result.state_vector(copy=False), [1, 0])
399+
assert np.allclose(result.state_vector(), [1, 0])
400400
result = cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': -1})
401-
assert np.allclose(result.state_vector(copy=False), [0, 1])
401+
assert np.allclose(result.state_vector(), [0, 1])
402402
with pytest.raises(TypeError, match='Only integer or sympy repetitions are allowed'):
403403
cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 1.5})
404404
with pytest.raises(ValueError, match='Circuit contains ops whose symbols were not specified'):
@@ -407,11 +407,11 @@ def test_parameterized_repeat():
407407
assert cirq.parameter_names(op) == {'a', 'b'}
408408
assert not cirq.has_unitary(op)
409409
result = cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 1, 'b': 1})
410-
assert np.allclose(result.state_vector(copy=False), [0, 1])
410+
assert np.allclose(result.state_vector(), [0, 1])
411411
result = cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 2, 'b': 1})
412-
assert np.allclose(result.state_vector(copy=False), [1, 0])
412+
assert np.allclose(result.state_vector(), [1, 0])
413413
result = cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 1, 'b': 2})
414-
assert np.allclose(result.state_vector(copy=False), [1, 0])
414+
assert np.allclose(result.state_vector(), [1, 0])
415415
with pytest.raises(TypeError, match='Only integer or sympy repetitions are allowed'):
416416
cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 1.5, 'b': 1})
417417
with pytest.raises(ValueError, match='Circuit contains ops whose symbols were not specified'):
@@ -420,11 +420,11 @@ def test_parameterized_repeat():
420420
assert cirq.parameter_names(op) == {'a', 'b'}
421421
assert not cirq.has_unitary(op)
422422
result = cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 1, 'b': 1})
423-
assert np.allclose(result.state_vector(copy=False), [1, 0])
423+
assert np.allclose(result.state_vector(), [1, 0])
424424
result = cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 1.5, 'b': 1})
425-
assert np.allclose(result.state_vector(copy=False), [0, 1])
425+
assert np.allclose(result.state_vector(), [0, 1])
426426
result = cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 1, 'b': 1.5})
427-
assert np.allclose(result.state_vector(copy=False), [0, 1])
427+
assert np.allclose(result.state_vector(), [0, 1])
428428
with pytest.raises(TypeError, match='Only integer or sympy repetitions are allowed'):
429429
cirq.Simulator().simulate(cirq.Circuit(op), param_resolver={'a': 1.5, 'b': 1.5})
430430
with pytest.raises(ValueError, match='Circuit contains ops whose symbols were not specified'):

cirq-core/cirq/contrib/quantum_volume/quantum_volume.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,12 @@ def compute_heavy_set(circuit: cirq.Circuit) -> List[int]:
8181
# output is defined in terms of probabilities, where our wave function is in
8282
# terms of amplitudes. We convert it by using the Born rule: squaring each
8383
# amplitude and taking their absolute value
84-
median = np.median(np.abs(results.state_vector(copy=False) ** 2))
84+
median = np.median(np.abs(results.state_vector() ** 2))
8585

8686
# The output wave function is a vector from the result value (big-endian) to
8787
# the probability of that bit-string. Return all of the bit-string
8888
# values that have a probability greater than the median.
89-
return [
90-
idx for idx, amp in enumerate(results.state_vector(copy=False)) if np.abs(amp**2) > median
91-
]
89+
return [idx for idx, amp in enumerate(results.state_vector()) if np.abs(amp**2) > median]
9290

9391

9492
@dataclass

cirq-core/cirq/experiments/xeb_simulation.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ def __call__(self, task: _Simulate2qXEBTask) -> List[Dict[str, Any]]:
6565
if cycle_depth not in cycle_depths:
6666
continue
6767

68-
# copy=False is safe because state_vector_to_probabilities will copy anyways
69-
psi = step_result.state_vector(copy=False)
68+
psi = step_result.state_vector()
7069
pure_probs = value.state_vector_to_probabilities(psi)
7170

7271
records += [

cirq-core/cirq/ops/boolean_hamiltonian_test.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,7 @@ def test_circuit(boolean_str):
8080

8181
circuit.append(hamiltonian_gate.on(*qubits))
8282

83-
phi = (
84-
cirq.Simulator()
85-
.simulate(circuit, qubit_order=qubits, initial_state=0)
86-
.state_vector(copy=False)
87-
)
83+
phi = cirq.Simulator().simulate(circuit, qubit_order=qubits, initial_state=0).state_vector()
8884
actual = np.arctan2(phi.real, phi.imag) - math.pi / 2.0 > 0.0
8985

9086
# Compare the two:

cirq-core/cirq/sim/mux.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ def final_state_vector(
172172
param_resolver=param_resolver,
173173
)
174174

175-
return result.state_vector(copy=False)
175+
return result.state_vector()
176176

177177

178178
def sample_sweep(

cirq-core/cirq/sim/simulator_test.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -430,9 +430,7 @@ def _kraus_(self):
430430
cirq.Circuit(Reset11To00().on(*cirq.LineQubit.range(2))), initial_state=k
431431
)
432432
np.testing.assert_allclose(
433-
out.state_vector(copy=False),
434-
cirq.one_hot(index=k % 3, shape=4, dtype=np.complex64),
435-
atol=1e-8,
433+
out.state_vector(), cirq.one_hot(index=k % 3, shape=4, dtype=np.complex64), atol=1e-8
436434
)
437435

438436

cirq-core/cirq/sim/sparse_simulator.py

+2-8
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
import numpy as np
2020

21-
from cirq import _compat, ops
21+
from cirq import ops
2222
from cirq.sim import simulator, state_vector, state_vector_simulator, state_vector_simulation_state
2323

2424
if TYPE_CHECKING:
@@ -236,7 +236,7 @@ def __init__(
236236
self._dtype = dtype
237237
self._state_vector: Optional[np.ndarray] = None
238238

239-
def state_vector(self, copy: Optional[bool] = None):
239+
def state_vector(self, copy: bool = False):
240240
"""Return the state vector at this point in the computation.
241241
242242
The state is returned in the computational basis with these basis
@@ -269,12 +269,6 @@ def state_vector(self, copy: Optional[bool] = None):
269269
parameters from the state vector and store then using False
270270
can speed up simulation by eliminating a memory copy.
271271
"""
272-
if copy is None:
273-
_compat._warn_or_error(
274-
"Starting in v0.16, state_vector will not copy the state by default. "
275-
"Explicitly set copy=True to copy the state."
276-
)
277-
copy = True
278272
if self._state_vector is None:
279273
self._state_vector = np.array([1])
280274
state = self._merged_sim_state

cirq-core/cirq/sim/sparse_simulator_test.py

+10-21
Original file line numberDiff line numberDiff line change
@@ -558,17 +558,6 @@ def test_simulate_moment_steps(dtype: Type[np.complexfloating], split: bool):
558558
np.testing.assert_almost_equal(step.state_vector(copy=True), np.array([1, 0, 0, 0]))
559559

560560

561-
def test_simulate_moment_steps_implicit_copy_deprecated():
562-
q0 = cirq.LineQubit(0)
563-
simulator = cirq.Simulator()
564-
steps = list(simulator.simulate_moment_steps(cirq.Circuit(cirq.X(q0))))
565-
566-
with cirq.testing.assert_deprecated(
567-
"state_vector will not copy the state by default", deadline="v0.16"
568-
):
569-
_ = steps[0].state_vector()
570-
571-
572561
@pytest.mark.parametrize('dtype', [np.complex64, np.complex128])
573562
@pytest.mark.parametrize('split', [True, False])
574563
def test_simulate_moment_steps_empty_circuit(dtype: Type[np.complexfloating], split: bool):
@@ -726,8 +715,8 @@ def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs):
726715

727716
initial_state = np.array([np.sqrt(0.5), np.sqrt(0.5)], dtype=np.complex64)
728717
result = simulator.simulate(circuit, initial_state=initial_state)
729-
np.testing.assert_array_almost_equal(result.state_vector(copy=False), initial_state)
730-
assert not initial_state is result.state_vector(copy=False)
718+
np.testing.assert_array_almost_equal(result.state_vector(), initial_state)
719+
assert not initial_state is result.state_vector()
731720

732721

733722
def test_does_not_modify_initial_state():
@@ -751,7 +740,7 @@ def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs):
751740
result = simulator.simulate(circuit, initial_state=initial_state)
752741
np.testing.assert_array_almost_equal(np.array([1, 0], dtype=np.complex64), initial_state)
753742
np.testing.assert_array_almost_equal(
754-
result.state_vector(copy=False), np.array([0, 1], dtype=np.complex64)
743+
result.state_vector(), np.array([0, 1], dtype=np.complex64)
755744
)
756745

757746

@@ -803,7 +792,7 @@ def test_simulates_composite():
803792
np.testing.assert_allclose(
804793
c.final_state_vector(ignore_terminal_measurements=False, dtype=np.complex64), expected
805794
)
806-
np.testing.assert_allclose(cirq.Simulator().simulate(c).state_vector(copy=False), expected)
795+
np.testing.assert_allclose(cirq.Simulator().simulate(c).state_vector(), expected)
807796

808797

809798
def test_simulate_measurement_inversions():
@@ -820,15 +809,15 @@ def test_works_on_pauli_string_phasor():
820809
a, b = cirq.LineQubit.range(2)
821810
c = cirq.Circuit(np.exp(0.5j * np.pi * cirq.X(a) * cirq.X(b)))
822811
sim = cirq.Simulator()
823-
result = sim.simulate(c).state_vector(copy=False)
812+
result = sim.simulate(c).state_vector()
824813
np.testing.assert_allclose(result.reshape(4), np.array([0, 0, 0, 1j]), atol=1e-8)
825814

826815

827816
def test_works_on_pauli_string():
828817
a, b = cirq.LineQubit.range(2)
829818
c = cirq.Circuit(cirq.X(a) * cirq.X(b))
830819
sim = cirq.Simulator()
831-
result = sim.simulate(c).state_vector(copy=False)
820+
result = sim.simulate(c).state_vector()
832821
np.testing.assert_allclose(result.reshape(4), np.array([0, 0, 0, 1]), atol=1e-8)
833822

834823

@@ -1325,7 +1314,7 @@ def _apply_unitary_(self, args):
13251314
vectors = []
13261315
copy_of_vectors = []
13271316
for step in sim.simulate_moment_steps(circuit):
1328-
state_vector = step.state_vector(copy=False)
1317+
state_vector = step.state_vector()
13291318
vectors.append(state_vector)
13301319
copy_of_vectors.append(state_vector.copy())
13311320
assert any(not np.array_equal(x, y) for x, y in zip(vectors, copy_of_vectors))
@@ -1338,9 +1327,9 @@ def test_final_state_vector_is_not_last_object():
13381327
initial_state = np.array([1, 0], dtype=np.complex64)
13391328
circuit = cirq.Circuit(cirq.wait(q))
13401329
result = sim.simulate(circuit, initial_state=initial_state)
1341-
assert result.state_vector(copy=False) is not initial_state
1342-
assert not np.shares_memory(result.state_vector(copy=False), initial_state)
1343-
np.testing.assert_equal(result.state_vector(copy=False), initial_state)
1330+
assert result.state_vector() is not initial_state
1331+
assert not np.shares_memory(result.state_vector(), initial_state)
1332+
np.testing.assert_equal(result.state_vector(), initial_state)
13441333

13451334

13461335
def test_deterministic_gate_noise():

cirq-core/cirq/sim/state_vector.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def _qid_shape_(self) -> Tuple[int, ...]:
5757
return self._qid_shape
5858

5959
@abc.abstractmethod
60-
def state_vector(self, copy: Optional[bool] = False) -> np.ndarray:
60+
def state_vector(self, copy: bool = False) -> np.ndarray:
6161
"""Return the state vector (wave function).
6262
6363
The vector is returned in the computational basis with these basis
@@ -101,9 +101,7 @@ def dirac_notation(self, decimals: int = 2) -> str:
101101
Returns:
102102
A pretty string consisting of a sum of computational basis kets
103103
and non-zero floats of the specified accuracy."""
104-
return qis.dirac_notation(
105-
self.state_vector(copy=False), decimals, qid_shape=self._qid_shape
106-
)
104+
return qis.dirac_notation(self.state_vector(), decimals, qid_shape=self._qid_shape)
107105

108106
def density_matrix_of(self, qubits: List['cirq.Qid'] = None) -> np.ndarray:
109107
r"""Returns the density matrix of the state.
@@ -139,7 +137,7 @@ def density_matrix_of(self, qubits: List['cirq.Qid'] = None) -> np.ndarray:
139137
corresponding to the state.
140138
"""
141139
return qis.density_matrix_from_state_vector(
142-
self.state_vector(copy=False),
140+
self.state_vector(),
143141
[self.qubit_map[q] for q in qubits] if qubits is not None else None,
144142
qid_shape=self._qid_shape,
145143
)
@@ -164,7 +162,7 @@ def bloch_vector_of(self, qubit: 'cirq.Qid') -> np.ndarray:
164162
corresponding to the state.
165163
"""
166164
return qis.bloch_vector_from_state_vector(
167-
self.state_vector(copy=False), self.qubit_map[qubit], qid_shape=self._qid_shape
165+
self.state_vector(), self.qubit_map[qubit], qid_shape=self._qid_shape
168166
)
169167

170168

cirq-core/cirq/sim/state_vector_simulator.py

+9-8
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
import numpy as np
2020

21-
from cirq import _compat, ops, value, qis
21+
from cirq import ops, value, qis
2222
from cirq._compat import proper_repr
2323
from cirq.sim import simulator, state_vector, simulator_base
2424

@@ -130,7 +130,7 @@ def final_state_vector(self) -> np.ndarray:
130130
self._final_state_vector = tensor
131131
return self._final_state_vector
132132

133-
def state_vector(self, copy: bool = None) -> np.ndarray:
133+
def state_vector(self, copy: bool = False) -> np.ndarray:
134134
"""Return the state vector at the end of the computation.
135135
136136
The state is returned in the computational basis with these basis
@@ -155,13 +155,14 @@ def state_vector(self, copy: bool = None) -> np.ndarray:
155155
| 5 | 1 | 0 | 1 |
156156
| 6 | 1 | 1 | 0 |
157157
| 7 | 1 | 1 | 1 |
158+
159+
Args:
160+
copy: If True, the returned state vector will be a copy of that
161+
stored by the object. This is potentially expensive for large
162+
state vectors, but prevents mutation of the object state, e.g. for
163+
operating on intermediate states of a circuit.
164+
Defaults to False.
158165
"""
159-
if copy is None:
160-
_compat._warn_or_error(
161-
"Starting in v0.16, state_vector will not copy the state by default. "
162-
"Explicitly set copy=True to copy the state."
163-
)
164-
copy = True
165166
return self.final_state_vector.copy() if copy else self.final_state_vector
166167

167168
def _value_equality_values_(self):

0 commit comments

Comments
 (0)