cirq-core 1.5.0.dev20250403170622__py3-none-any.whl → 1.5.0.dev20250404021339__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cirq-core might be problematic. Click here for more details.

Files changed (54) hide show
  1. cirq/_version.py +1 -1
  2. cirq/_version_test.py +1 -1
  3. cirq/circuits/circuit.py +144 -147
  4. cirq/circuits/circuit_operation.py +37 -34
  5. cirq/circuits/circuit_operation_test.py +1 -1
  6. cirq/circuits/circuit_test.py +4 -6
  7. cirq/circuits/frozen_circuit.py +30 -26
  8. cirq/circuits/moment.py +37 -37
  9. cirq/circuits/optimization_pass.py +11 -11
  10. cirq/circuits/optimization_pass_test.py +6 -8
  11. cirq/circuits/qasm_output.py +13 -11
  12. cirq/circuits/text_diagram_drawer.py +9 -7
  13. cirq/contrib/acquaintance/bipartite.py +7 -5
  14. cirq/contrib/acquaintance/devices.py +3 -1
  15. cirq/contrib/acquaintance/executor.py +14 -16
  16. cirq/contrib/acquaintance/gates.py +19 -21
  17. cirq/contrib/acquaintance/inspection_utils.py +8 -6
  18. cirq/contrib/acquaintance/mutation_utils.py +8 -6
  19. cirq/contrib/acquaintance/optimizers.py +5 -3
  20. cirq/contrib/acquaintance/permutation.py +19 -19
  21. cirq/contrib/acquaintance/shift.py +5 -3
  22. cirq/contrib/acquaintance/shift_swap_network.py +5 -3
  23. cirq/contrib/acquaintance/strategies/complete.py +4 -2
  24. cirq/contrib/acquaintance/strategies/cubic.py +4 -2
  25. cirq/contrib/acquaintance/strategies/quartic_paired.py +8 -6
  26. cirq/contrib/acquaintance/topological_sort.py +4 -2
  27. cirq/contrib/bayesian_network/bayesian_network_gate.py +4 -2
  28. cirq/contrib/circuitdag/circuit_dag.py +18 -16
  29. cirq/contrib/custom_simulators/custom_state_simulator.py +10 -8
  30. cirq/contrib/custom_simulators/custom_state_simulator_test.py +9 -7
  31. cirq/contrib/graph_device/graph_device.py +4 -2
  32. cirq/contrib/noise_models/noise_models.py +7 -5
  33. cirq/contrib/paulistring/clifford_target_gateset.py +11 -9
  34. cirq/contrib/qcircuit/qcircuit_diagram.py +5 -2
  35. cirq/contrib/quantum_volume/quantum_volume.py +4 -4
  36. cirq/contrib/quimb/mps_simulator.py +25 -26
  37. cirq/contrib/routing/greedy.py +5 -3
  38. cirq/contrib/routing/initialization.py +3 -1
  39. cirq/contrib/routing/swap_network.py +5 -5
  40. cirq/contrib/routing/utils.py +4 -2
  41. cirq/contrib/svg/svg.py +9 -6
  42. cirq/devices/device.py +11 -9
  43. cirq/devices/grid_device_metadata.py +14 -11
  44. cirq/devices/grid_qubit.py +17 -21
  45. cirq/devices/grid_qubit_test.py +1 -1
  46. cirq/devices/insertion_noise_model.py +5 -5
  47. cirq/devices/line_qubit.py +15 -17
  48. cirq/devices/named_topologies.py +6 -4
  49. cirq/devices/noise_model.py +27 -31
  50. {cirq_core-1.5.0.dev20250403170622.dist-info → cirq_core-1.5.0.dev20250404021339.dist-info}/METADATA +1 -1
  51. {cirq_core-1.5.0.dev20250403170622.dist-info → cirq_core-1.5.0.dev20250404021339.dist-info}/RECORD +54 -54
  52. {cirq_core-1.5.0.dev20250403170622.dist-info → cirq_core-1.5.0.dev20250404021339.dist-info}/LICENSE +0 -0
  53. {cirq_core-1.5.0.dev20250403170622.dist-info → cirq_core-1.5.0.dev20250404021339.dist-info}/WHEEL +0 -0
  54. {cirq_core-1.5.0.dev20250403170622.dist-info → cirq_core-1.5.0.dev20250404021339.dist-info}/top_level.txt +0 -0
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import math
16
18
  from typing import Any, cast, Dict, Iterator, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
17
19
 
@@ -158,7 +160,7 @@ class BayesianNetworkGate(raw_types.Gate):
158
160
  raise ValueError('Conditional prob should be between 0 and 1.')
159
161
  self._arc_probs = arc_probs
160
162
 
161
- def _decompose_(self, qubits: Sequence['raw_types.Qid']) -> Iterator['cirq.OP_TREE']:
163
+ def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
162
164
  parameter_names = [init_prob[0] for init_prob in self._init_probs]
163
165
  qubit_map = dict(zip(parameter_names, qubits))
164
166
 
@@ -188,7 +190,7 @@ class BayesianNetworkGate(raw_types.Gate):
188
190
  init_probs: List[List[Union[str, Optional[float]]]],
189
191
  arc_probs: List[List[Union[str, List[str], List[float]]]],
190
192
  **kwargs,
191
- ) -> 'BayesianNetworkGate':
193
+ ) -> BayesianNetworkGate:
192
194
  converted_init_probs = cast(
193
195
  List[Tuple[str, Optional[float]]],
194
196
  [(param, init_prob) for param, init_prob in init_probs],
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import functools
16
18
  from typing import Any, Callable, cast, Dict, Generic, Iterator, TypeVar
17
19
 
@@ -48,7 +50,7 @@ class Unique(Generic[T]):
48
50
  return id(self) < id(other)
49
51
 
50
52
 
51
- def _disjoint_qubits(op1: 'cirq.Operation', op2: 'cirq.Operation') -> bool:
53
+ def _disjoint_qubits(op1: cirq.Operation, op2: cirq.Operation) -> bool:
52
54
  """Returns true only if the operations have qubits in common."""
53
55
  return not set(op1.qubits) & set(op2.qubits)
54
56
 
@@ -70,7 +72,7 @@ class CircuitDag(networkx.DiGraph):
70
72
 
71
73
  def __init__(
72
74
  self,
73
- can_reorder: Callable[['cirq.Operation', 'cirq.Operation'], bool] = _disjoint_qubits,
75
+ can_reorder: Callable[[cirq.Operation, cirq.Operation], bool] = _disjoint_qubits,
74
76
  incoming_graph_data: Any = None,
75
77
  ) -> None:
76
78
  """Initializes a CircuitDag.
@@ -91,27 +93,27 @@ class CircuitDag(networkx.DiGraph):
91
93
  self.can_reorder = can_reorder
92
94
 
93
95
  @staticmethod
94
- def make_node(op: 'cirq.Operation') -> Unique:
96
+ def make_node(op: cirq.Operation) -> Unique:
95
97
  return Unique(op)
96
98
 
97
99
  @staticmethod
98
100
  def from_circuit(
99
101
  circuit: cirq.Circuit,
100
- can_reorder: Callable[['cirq.Operation', 'cirq.Operation'], bool] = _disjoint_qubits,
101
- ) -> 'CircuitDag':
102
+ can_reorder: Callable[[cirq.Operation, cirq.Operation], bool] = _disjoint_qubits,
103
+ ) -> CircuitDag:
102
104
  return CircuitDag.from_ops(circuit.all_operations(), can_reorder=can_reorder)
103
105
 
104
106
  @staticmethod
105
107
  def from_ops(
106
- *operations: 'cirq.OP_TREE',
107
- can_reorder: Callable[['cirq.Operation', 'cirq.Operation'], bool] = _disjoint_qubits,
108
- ) -> 'CircuitDag':
108
+ *operations: cirq.OP_TREE,
109
+ can_reorder: Callable[[cirq.Operation, cirq.Operation], bool] = _disjoint_qubits,
110
+ ) -> CircuitDag:
109
111
  dag = CircuitDag(can_reorder=can_reorder)
110
112
  for op in ops.flatten_op_tree(operations):
111
113
  dag.append(cast(ops.Operation, op))
112
114
  return dag
113
115
 
114
- def append(self, op: 'cirq.Operation') -> None:
116
+ def append(self, op: cirq.Operation) -> None:
115
117
  new_node = self.make_node(op)
116
118
  for node in list(self.nodes()):
117
119
  if not self.can_reorder(node.val, op):
@@ -140,21 +142,21 @@ class CircuitDag(networkx.DiGraph):
140
142
 
141
143
  __hash__ = None # type: ignore
142
144
 
143
- def ordered_nodes(self) -> Iterator[Unique['cirq.Operation']]:
145
+ def ordered_nodes(self) -> Iterator[Unique[cirq.Operation]]:
144
146
  if not self.nodes():
145
147
  return
146
148
  g = self.copy()
147
149
 
148
- def get_root_node(some_node: Unique['cirq.Operation']) -> Unique['cirq.Operation']:
150
+ def get_root_node(some_node: Unique[cirq.Operation]) -> Unique[cirq.Operation]:
149
151
  pred = g.pred
150
152
  while pred[some_node]:
151
153
  some_node = next(iter(pred[some_node]))
152
154
  return some_node
153
155
 
154
- def get_first_node() -> Unique['cirq.Operation']:
156
+ def get_first_node() -> Unique[cirq.Operation]:
155
157
  return get_root_node(next(iter(g.nodes())))
156
158
 
157
- def get_next_node(succ: networkx.classes.coreviews.AtlasView) -> Unique['cirq.Operation']:
159
+ def get_next_node(succ: networkx.classes.coreviews.AtlasView) -> Unique[cirq.Operation]:
158
160
  if succ:
159
161
  return get_root_node(next(iter(succ)))
160
162
 
@@ -171,7 +173,7 @@ class CircuitDag(networkx.DiGraph):
171
173
 
172
174
  node = get_next_node(succ)
173
175
 
174
- def all_operations(self) -> Iterator['cirq.Operation']:
176
+ def all_operations(self) -> Iterator[cirq.Operation]:
175
177
  return (node.val for node in self.ordered_nodes())
176
178
 
177
179
  def all_qubits(self):
@@ -181,8 +183,8 @@ class CircuitDag(networkx.DiGraph):
181
183
  return cirq.Circuit(self.all_operations(), strategy=cirq.InsertStrategy.EARLIEST)
182
184
 
183
185
  def findall_nodes_until_blocked(
184
- self, is_blocker: Callable[['cirq.Operation'], bool]
185
- ) -> Iterator[Unique['cirq.Operation']]:
186
+ self, is_blocker: Callable[[cirq.Operation], bool]
187
+ ) -> Iterator[Unique[cirq.Operation]]:
186
188
  """Finds all nodes before blocking ones.
187
189
 
188
190
  Args:
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  from typing import Any, Dict, Generic, Sequence, Type, TYPE_CHECKING
16
18
 
17
19
  import numpy as np
@@ -47,7 +49,7 @@ class CustomStateSimulator(
47
49
  self,
48
50
  state_type: Type[TSimulationState],
49
51
  *,
50
- noise: 'cirq.NOISE_MODEL_LIKE' = None,
52
+ noise: cirq.NOISE_MODEL_LIKE = None,
51
53
  split_untangled_states: bool = False,
52
54
  ):
53
55
  """Initializes a CustomStateSimulator.
@@ -63,24 +65,24 @@ class CustomStateSimulator(
63
65
 
64
66
  def _create_simulator_trial_result(
65
67
  self,
66
- params: 'cirq.ParamResolver',
68
+ params: cirq.ParamResolver,
67
69
  measurements: Dict[str, np.ndarray],
68
- final_simulator_state: 'cirq.SimulationStateBase[TSimulationState]',
69
- ) -> 'CustomStateTrialResult[TSimulationState]':
70
+ final_simulator_state: cirq.SimulationStateBase[TSimulationState],
71
+ ) -> CustomStateTrialResult[TSimulationState]:
70
72
  return CustomStateTrialResult(
71
73
  params, measurements, final_simulator_state=final_simulator_state
72
74
  )
73
75
 
74
76
  def _create_step_result(
75
- self, sim_state: 'cirq.SimulationStateBase[TSimulationState]'
76
- ) -> 'CustomStateStepResult[TSimulationState]':
77
+ self, sim_state: cirq.SimulationStateBase[TSimulationState]
78
+ ) -> CustomStateStepResult[TSimulationState]:
77
79
  return CustomStateStepResult(sim_state)
78
80
 
79
81
  def _create_partial_simulation_state(
80
82
  self,
81
83
  initial_state: Any,
82
- qubits: Sequence['cirq.Qid'],
83
- classical_data: 'cirq.ClassicalDataStore',
84
+ qubits: Sequence[cirq.Qid],
85
+ classical_data: cirq.ClassicalDataStore,
84
86
  ) -> TSimulationState:
85
87
  return self.state_type(
86
88
  initial_state=initial_state, qubits=qubits, classical_data=classical_data
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  from typing import List, Sequence, Tuple
16
18
 
17
19
  import numpy as np
@@ -25,10 +27,10 @@ class ComputationalBasisState(cirq.qis.QuantumStateRepresentation):
25
27
  def __init__(self, initial_state: List[int]):
26
28
  self.basis = initial_state
27
29
 
28
- def copy(self, deep_copy_buffers: bool = True) -> 'ComputationalBasisState':
30
+ def copy(self, deep_copy_buffers: bool = True) -> ComputationalBasisState:
29
31
  return ComputationalBasisState(self.basis) # pragma: no cover
30
32
 
31
- def measure(self, axes: Sequence[int], seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None):
33
+ def measure(self, axes: Sequence[int], seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None):
32
34
  return [self.basis[i] for i in axes]
33
35
 
34
36
 
@@ -137,18 +139,18 @@ class ComputationalBasisProductState(cirq.qis.QuantumStateRepresentation):
137
139
  def __init__(self, initial_state: List[int]):
138
140
  self.basis = initial_state
139
141
 
140
- def copy(self, deep_copy_buffers: bool = True) -> 'ComputationalBasisProductState':
142
+ def copy(self, deep_copy_buffers: bool = True) -> ComputationalBasisProductState:
141
143
  return ComputationalBasisProductState(self.basis)
142
144
 
143
- def measure(self, axes: Sequence[int], seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None):
145
+ def measure(self, axes: Sequence[int], seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None):
144
146
  return [self.basis[i] for i in axes]
145
147
 
146
- def kron(self, other: 'ComputationalBasisProductState') -> 'ComputationalBasisProductState':
148
+ def kron(self, other: ComputationalBasisProductState) -> ComputationalBasisProductState:
147
149
  return ComputationalBasisProductState(self.basis + other.basis)
148
150
 
149
151
  def factor(
150
152
  self, axes: Sequence[int], *, validate=True, atol=1e-07
151
- ) -> Tuple['ComputationalBasisProductState', 'ComputationalBasisProductState']:
153
+ ) -> Tuple[ComputationalBasisProductState, ComputationalBasisProductState]:
152
154
  extracted = ComputationalBasisProductState(
153
155
  [self.basis[i] for i in axes]
154
156
  ) # pragma: no cover
@@ -157,7 +159,7 @@ class ComputationalBasisProductState(cirq.qis.QuantumStateRepresentation):
157
159
  ) # pragma: no cover
158
160
  return extracted, remainder # pragma: no cover
159
161
 
160
- def reindex(self, axes: Sequence[int]) -> 'ComputationalBasisProductState':
162
+ def reindex(self, axes: Sequence[int]) -> ComputationalBasisProductState:
161
163
  return ComputationalBasisProductState([self.basis[i] for i in axes])
162
164
 
163
165
  @property
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import abc
16
18
  import itertools
17
19
  from typing import cast, Iterable, Optional, Tuple, TYPE_CHECKING
@@ -150,7 +152,7 @@ class UndirectedGraphDevice(devices.Device):
150
152
  self.crosstalk_graph = crosstalk_graph
151
153
 
152
154
  @property
153
- def qubits(self) -> Tuple['cirq.Qid', ...]:
155
+ def qubits(self) -> Tuple[cirq.Qid, ...]:
154
156
  return cast(Tuple['cirq.Qid', ...], tuple(sorted(self.device_graph.vertices)))
155
157
 
156
158
  @property
@@ -192,7 +194,7 @@ class UndirectedGraphDevice(devices.Device):
192
194
  ):
193
195
  validator(operation, *crosstalk_operations)
194
196
 
195
- def validate_moment(self, moment: 'cirq.Moment'):
197
+ def validate_moment(self, moment: cirq.Moment):
196
198
  super().validate_moment(moment)
197
199
  ops = moment.operations
198
200
  for i, op in enumerate(ops):
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  from typing import Sequence, TYPE_CHECKING
16
18
 
17
19
  from cirq import circuits, devices, ops, value
@@ -40,7 +42,7 @@ class DepolarizingNoiseModel(devices.NoiseModel):
40
42
  self.qubit_noise_gate = ops.DepolarizingChannel(depol_prob)
41
43
  self._prepend = prepend
42
44
 
43
- def noisy_moment(self, moment: 'cirq.Moment', system_qubits: Sequence['cirq.Qid']):
45
+ def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]):
44
46
  if validate_all_measurements(moment) or self.is_virtual_moment(moment): # pragma: no cover
45
47
  return moment
46
48
 
@@ -76,7 +78,7 @@ class ReadoutNoiseModel(devices.NoiseModel):
76
78
  self.readout_noise_gate = ops.BitFlipChannel(bitflip_prob)
77
79
  self._prepend = prepend
78
80
 
79
- def noisy_moment(self, moment: 'cirq.Moment', system_qubits: Sequence['cirq.Qid']):
81
+ def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]):
80
82
  if self.is_virtual_moment(moment):
81
83
  return moment
82
84
  if validate_all_measurements(moment):
@@ -113,7 +115,7 @@ class DampedReadoutNoiseModel(devices.NoiseModel):
113
115
  self.readout_decay_gate = ops.AmplitudeDampingChannel(decay_prob)
114
116
  self._prepend = prepend
115
117
 
116
- def noisy_moment(self, moment: 'cirq.Moment', system_qubits: Sequence['cirq.Qid']):
118
+ def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]):
117
119
  if self.is_virtual_moment(moment):
118
120
  return moment
119
121
  if validate_all_measurements(moment):
@@ -146,7 +148,7 @@ class DepolarizingWithReadoutNoiseModel(devices.NoiseModel):
146
148
  self.qubit_noise_gate = ops.DepolarizingChannel(depol_prob)
147
149
  self.readout_noise_gate = ops.BitFlipChannel(bitflip_prob)
148
150
 
149
- def noisy_moment(self, moment: 'cirq.Moment', system_qubits: Sequence['cirq.Qid']):
151
+ def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]):
150
152
  if validate_all_measurements(moment):
151
153
  return [circuits.Moment(self.readout_noise_gate(q) for q in system_qubits), moment]
152
154
  return [moment, circuits.Moment(self.qubit_noise_gate(q) for q in system_qubits)]
@@ -176,7 +178,7 @@ class DepolarizingWithDampedReadoutNoiseModel(devices.NoiseModel):
176
178
  self.readout_noise_gate = ops.BitFlipChannel(bitflip_prob)
177
179
  self.readout_decay_gate = ops.AmplitudeDampingChannel(decay_prob)
178
180
 
179
- def noisy_moment(self, moment: 'cirq.Moment', system_qubits: Sequence['cirq.Qid']):
181
+ def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]):
180
182
  if validate_all_measurements(moment):
181
183
  return [
182
184
  circuits.Moment(self.readout_decay_gate(q) for q in system_qubits),
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  from enum import Enum
16
18
  from types import NotImplementedType
17
19
  from typing import cast, List, Type, TYPE_CHECKING, Union
@@ -25,7 +27,7 @@ if TYPE_CHECKING:
25
27
 
26
28
 
27
29
  def _matrix_to_clifford_op(
28
- mat: np.ndarray, qubit: 'cirq.Qid', *, atol: float
30
+ mat: np.ndarray, qubit: cirq.Qid, *, atol: float
29
31
  ) -> Union[ops.Operation, NotImplementedType]:
30
32
  rotations = transformers.single_qubit_matrix_to_pauli_rotations(mat, atol)
31
33
  clifford_gate = ops.SingleQubitCliffordGate.I
@@ -43,7 +45,7 @@ def _matrix_to_clifford_op(
43
45
 
44
46
 
45
47
  def _matrix_to_pauli_string_phasors(
46
- mat: np.ndarray, qubit: 'cirq.Qid', *, keep_clifford: bool, atol: float
48
+ mat: np.ndarray, qubit: cirq.Qid, *, keep_clifford: bool, atol: float
47
49
  ) -> ops.OP_TREE:
48
50
  rotations = transformers.single_qubit_matrix_to_pauli_rotations(mat, atol)
49
51
  out_ops: List[ops.GateOperation] = []
@@ -95,7 +97,7 @@ class CliffordTargetGateset(transformers.TwoQubitCompilationTargetGateset):
95
97
  """
96
98
  self.atol = atol
97
99
  self.single_qubit_target = single_qubit_target
98
- gates: List[Union['cirq.Gate', Type['cirq.Gate']]] = [ops.CZ, ops.MeasurementGate]
100
+ gates: List[Union[cirq.Gate, Type[cirq.Gate]]] = [ops.CZ, ops.MeasurementGate]
99
101
  if single_qubit_target in [
100
102
  self.SingleQubitTarget.SINGLE_QUBIT_CLIFFORDS,
101
103
  self.SingleQubitTarget.PAULI_STRING_PHASORS_AND_CLIFFORDS,
@@ -109,8 +111,8 @@ class CliffordTargetGateset(transformers.TwoQubitCompilationTargetGateset):
109
111
  super().__init__(*gates)
110
112
 
111
113
  def _decompose_single_qubit_operation(
112
- self, op: 'cirq.Operation', _
113
- ) -> Union[NotImplementedType, 'cirq.OP_TREE']:
114
+ self, op: cirq.Operation, _
115
+ ) -> Union[NotImplementedType, cirq.OP_TREE]:
114
116
  if not protocols.has_unitary(op):
115
117
  return NotImplemented
116
118
  mat = protocols.unitary(op)
@@ -126,8 +128,8 @@ class CliffordTargetGateset(transformers.TwoQubitCompilationTargetGateset):
126
128
  )
127
129
 
128
130
  def _decompose_two_qubit_operation(
129
- self, op: 'cirq.Operation', _
130
- ) -> Union[NotImplementedType, 'cirq.OP_TREE']:
131
+ self, op: cirq.Operation, _
132
+ ) -> Union[NotImplementedType, cirq.OP_TREE]:
131
133
  if not protocols.has_unitary(op):
132
134
  return NotImplemented
133
135
  return transformers.two_qubit_matrix_to_cz_operations(
@@ -139,10 +141,10 @@ class CliffordTargetGateset(transformers.TwoQubitCompilationTargetGateset):
139
141
  )
140
142
 
141
143
  @property
142
- def postprocess_transformers(self) -> List['cirq.TRANSFORMER']:
144
+ def postprocess_transformers(self) -> List[cirq.TRANSFORMER]:
143
145
  """List of transformers which should be run after decomposing individual operations."""
144
146
 
145
- def rewriter(o: 'cirq.CircuitOperation'):
147
+ def rewriter(o: cirq.CircuitOperation):
146
148
  result = self._decompose_single_qubit_operation(o, -1)
147
149
  return o.circuit.all_operations() if result is NotImplemented else result
148
150
 
@@ -11,6 +11,9 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
14
17
  from typing import TYPE_CHECKING
15
18
 
16
19
  from cirq import circuits, ops
@@ -23,7 +26,7 @@ if TYPE_CHECKING:
23
26
  import cirq
24
27
 
25
28
 
26
- def qcircuit_qubit_namer(qubit: 'cirq.Qid') -> str:
29
+ def qcircuit_qubit_namer(qubit: cirq.Qid) -> str:
27
30
  """Returns the latex code for a QCircuit label of given qubit.
28
31
 
29
32
  Args:
@@ -64,7 +67,7 @@ def _render(diagram: circuits.TextDiagramDrawer) -> str:
64
67
 
65
68
 
66
69
  def circuit_to_latex_using_qcircuit(
67
- circuit: 'cirq.Circuit', qubit_order: 'cirq.QubitOrderOrList' = ops.QubitOrder.DEFAULT
70
+ circuit: cirq.Circuit, qubit_order: cirq.QubitOrderOrList = ops.QubitOrder.DEFAULT
68
71
  ) -> str:
69
72
  """Returns a QCircuit-based latex diagram of the given circuit.
70
73
 
@@ -15,7 +15,7 @@ import cirq.contrib.routing as ccr
15
15
 
16
16
 
17
17
  def generate_model_circuit(
18
- num_qubits: int, depth: int, *, random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None
18
+ num_qubits: int, depth: int, *, random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None
19
19
  ) -> cirq.Circuit:
20
20
  """Generates a model circuit with the given number of qubits and depth.
21
21
 
@@ -277,7 +277,7 @@ def compile_circuit(
277
277
  # Replace the PermutationGates with regular gates, so we don't proliferate
278
278
  # the routing implementation details to the compiler and the device itself.
279
279
 
280
- def replace_swap_permutation_gate(op: 'cirq.Operation', _):
280
+ def replace_swap_permutation_gate(op: cirq.Operation, _):
281
281
  if isinstance(op.gate, cirq.contrib.acquaintance.SwapPermutationGate):
282
282
  return [op.gate.swap_gate.on(*op.qubits)]
283
283
  return op
@@ -327,7 +327,7 @@ def prepare_circuits(
327
327
  num_qubits: int,
328
328
  depth: int,
329
329
  num_circuits: int,
330
- random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
330
+ random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
331
331
  ) -> List[Tuple[cirq.Circuit, List[int]]]:
332
332
  """Generates circuits and computes their heavy set.
333
333
 
@@ -423,7 +423,7 @@ def calculate_quantum_volume(
423
423
  num_circuits: int,
424
424
  device_graph: nx.Graph,
425
425
  samplers: List[cirq.Sampler],
426
- random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
426
+ random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
427
427
  compiler: Optional[Callable[[cirq.Circuit], cirq.Circuit]] = None,
428
428
  repetitions=10_000,
429
429
  routing_attempts=30,
@@ -17,6 +17,8 @@ This is based on this paper:
17
17
  https://arxiv.org/abs/2002.07730
18
18
  """
19
19
 
20
+ from __future__ import annotations
21
+
20
22
  import dataclasses
21
23
  import math
22
24
  from typing import Any, Dict, List, Optional, Sequence, Set, Tuple, TYPE_CHECKING, Union
@@ -58,10 +60,10 @@ class MPSSimulator(
58
60
 
59
61
  def __init__(
60
62
  self,
61
- noise: 'cirq.NOISE_MODEL_LIKE' = None,
62
- seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
63
+ noise: cirq.NOISE_MODEL_LIKE = None,
64
+ seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
63
65
  simulation_options: MPSOptions = MPSOptions(),
64
- grouping: Optional[Dict['cirq.Qid', int]] = None,
66
+ grouping: Optional[Dict[cirq.Qid, int]] = None,
65
67
  ):
66
68
  """Creates instance of `MPSSimulator`.
67
69
 
@@ -84,10 +86,10 @@ class MPSSimulator(
84
86
 
85
87
  def _create_partial_simulation_state(
86
88
  self,
87
- initial_state: Union[int, 'MPSState'],
88
- qubits: Sequence['cirq.Qid'],
89
- classical_data: 'cirq.ClassicalDataStore',
90
- ) -> 'MPSState':
89
+ initial_state: Union[int, MPSState],
90
+ qubits: Sequence[cirq.Qid],
91
+ classical_data: cirq.ClassicalDataStore,
92
+ ) -> MPSState:
91
93
  """Creates MPSState args for simulating the Circuit.
92
94
 
93
95
  Args:
@@ -114,15 +116,15 @@ class MPSSimulator(
114
116
  classical_data=classical_data,
115
117
  )
116
118
 
117
- def _create_step_result(self, sim_state: 'cirq.SimulationStateBase[MPSState]'):
119
+ def _create_step_result(self, sim_state: cirq.SimulationStateBase[MPSState]):
118
120
  return MPSSimulatorStepResult(sim_state)
119
121
 
120
122
  def _create_simulator_trial_result(
121
123
  self,
122
- params: 'cirq.ParamResolver',
124
+ params: cirq.ParamResolver,
123
125
  measurements: Dict[str, np.ndarray],
124
- final_simulator_state: 'cirq.SimulationStateBase[MPSState]',
125
- ) -> 'MPSTrialResult':
126
+ final_simulator_state: cirq.SimulationStateBase[MPSState],
127
+ ) -> MPSTrialResult:
126
128
  """Creates a single trial results with the measurements.
127
129
 
128
130
  Args:
@@ -144,16 +146,16 @@ class MPSTrialResult(simulator_base.SimulationTrialResultBase['MPSState']):
144
146
 
145
147
  def __init__(
146
148
  self,
147
- params: 'cirq.ParamResolver',
149
+ params: cirq.ParamResolver,
148
150
  measurements: Dict[str, np.ndarray],
149
- final_simulator_state: 'cirq.SimulationStateBase[MPSState]',
151
+ final_simulator_state: cirq.SimulationStateBase[MPSState],
150
152
  ) -> None:
151
153
  super().__init__(
152
154
  params=params, measurements=measurements, final_simulator_state=final_simulator_state
153
155
  )
154
156
 
155
157
  @property
156
- def final_state(self) -> 'MPSState':
158
+ def final_state(self) -> MPSState:
157
159
  return self._get_merged_sim_state()
158
160
 
159
161
  def __str__(self) -> str:
@@ -173,7 +175,7 @@ class MPSTrialResult(simulator_base.SimulationTrialResultBase['MPSState']):
173
175
  class MPSSimulatorStepResult(simulator_base.StepResultBase['MPSState']):
174
176
  """A `StepResult` that can perform measurements."""
175
177
 
176
- def __init__(self, sim_state: 'cirq.SimulationStateBase[MPSState]'):
178
+ def __init__(self, sim_state: cirq.SimulationStateBase[MPSState]):
177
179
  """Results of a step of the simulator.
178
180
  Attributes:
179
181
  sim_state: The qubit:SimulationState lookup for this step.
@@ -309,7 +311,7 @@ class _MPSHandler(qis.QuantumStateRepresentation):
309
311
  def _value_equality_values_(self) -> Any:
310
312
  return self._qid_shape, self._M, self._simulation_options, self._grouping
311
313
 
312
- def copy(self, deep_copy_buffers: bool = True) -> '_MPSHandler':
314
+ def copy(self, deep_copy_buffers: bool = True) -> _MPSHandler:
313
315
  """Copies the object.
314
316
 
315
317
  Args:
@@ -520,7 +522,7 @@ class _MPSHandler(qis.QuantumStateRepresentation):
520
522
  return results
521
523
 
522
524
  def measure(
523
- self, axes: Sequence[int], seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None
525
+ self, axes: Sequence[int], seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None
524
526
  ) -> List[int]:
525
527
  """Measures the MPS.
526
528
 
@@ -533,10 +535,7 @@ class _MPSHandler(qis.QuantumStateRepresentation):
533
535
  return self._measure(axes, value.parse_random_state(seed))
534
536
 
535
537
  def sample(
536
- self,
537
- axes: Sequence[int],
538
- repetitions: int = 1,
539
- seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
538
+ self, axes: Sequence[int], repetitions: int = 1, seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None
540
539
  ) -> np.ndarray:
541
540
  """Samples the MPS.
542
541
 
@@ -564,12 +563,12 @@ class MPSState(SimulationState[_MPSHandler]):
564
563
  def __init__(
565
564
  self,
566
565
  *,
567
- qubits: Sequence['cirq.Qid'],
566
+ qubits: Sequence[cirq.Qid],
568
567
  prng: np.random.RandomState,
569
568
  simulation_options: MPSOptions = MPSOptions(),
570
- grouping: Optional[Dict['cirq.Qid', int]] = None,
569
+ grouping: Optional[Dict[cirq.Qid, int]] = None,
571
570
  initial_state: int = 0,
572
- classical_data: Optional['cirq.ClassicalDataStore'] = None,
571
+ classical_data: Optional[cirq.ClassicalDataStore] = None,
573
572
  ):
574
573
  """Creates and MPSState
575
574
 
@@ -623,7 +622,7 @@ class MPSState(SimulationState[_MPSHandler]):
623
622
  """
624
623
  return self._state.state_vector()
625
624
 
626
- def partial_trace(self, keep_qubits: Set['cirq.Qid']) -> np.ndarray:
625
+ def partial_trace(self, keep_qubits: Set[cirq.Qid]) -> np.ndarray:
627
626
  """Traces out all qubits except keep_qubits.
628
627
 
629
628
  Args:
@@ -642,7 +641,7 @@ class MPSState(SimulationState[_MPSHandler]):
642
641
  return self._state.to_numpy()
643
642
 
644
643
  def _act_on_fallback_(
645
- self, action: Any, qubits: Sequence['cirq.Qid'], allow_decompose: bool = True
644
+ self, action: Any, qubits: Sequence[cirq.Qid], allow_decompose: bool = True
646
645
  ) -> bool:
647
646
  """Delegates the action to self.apply_op"""
648
647
  return self._state.apply_op(action, self.get_axes(qubits), self.prng)
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import itertools
16
18
  from typing import (
17
19
  Callable,
@@ -109,7 +111,7 @@ class _GreedyRouter:
109
111
  op1.qubits
110
112
  )
111
113
  & set(op2.qubits),
112
- random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
114
+ random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
113
115
  ):
114
116
 
115
117
  self.prng = value.parse_random_state(random_state)
@@ -148,12 +150,12 @@ class _GreedyRouter:
148
150
  ]
149
151
  return self.edge_sets[edge_set_size]
150
152
 
151
- def log_to_phys(self, *qubits: 'cirq.Qid') -> Iterable[ops.Qid]:
153
+ def log_to_phys(self, *qubits: cirq.Qid) -> Iterable[ops.Qid]:
152
154
  """Returns an iterator over the physical qubits mapped to by the given
153
155
  logical qubits."""
154
156
  return (self._log_to_phys[q] for q in qubits)
155
157
 
156
- def phys_to_log(self, *qubits: 'cirq.Qid') -> Iterable[Optional[ops.Qid]]:
158
+ def phys_to_log(self, *qubits: cirq.Qid) -> Iterable[Optional[ops.Qid]]:
157
159
  """Returns an iterator over the logical qubits that map to the given
158
160
  physical qubits."""
159
161
  return (self._phys_to_log[q] for q in qubits)
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import itertools
16
18
  from typing import cast, Dict, Hashable, TYPE_CHECKING
17
19
 
@@ -32,7 +34,7 @@ def get_center(graph: nx.Graph) -> Hashable:
32
34
  def get_initial_mapping(
33
35
  logical_graph: nx.Graph,
34
36
  device_graph: nx.Graph,
35
- random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
37
+ random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
36
38
  ) -> Dict[ops.Qid, ops.Qid]:
37
39
  """Gets an initial mapping of logical to physical qubits for routing.
38
40