cirq-core 1.6.0.dev20250416035400__py3-none-any.whl → 1.6.0.dev20250417204649__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 (58) hide show
  1. cirq/_version.py +1 -1
  2. cirq/_version_test.py +1 -1
  3. cirq/devices/noise_model_test.py +3 -1
  4. cirq/devices/noise_properties.py +6 -4
  5. cirq/devices/noise_utils.py +8 -6
  6. cirq/devices/superconducting_qubits_noise_properties.py +10 -9
  7. cirq/devices/thermal_noise_model.py +12 -12
  8. cirq/devices/unconstrained_device.py +3 -1
  9. cirq/experiments/n_qubit_tomography.py +15 -12
  10. cirq/experiments/qubit_characterizations.py +34 -39
  11. cirq/experiments/random_quantum_circuit_generation.py +38 -38
  12. cirq/experiments/random_quantum_circuit_generation_test.py +7 -4
  13. cirq/experiments/readout_confusion_matrix.py +17 -15
  14. cirq/experiments/single_qubit_readout_calibration.py +9 -5
  15. cirq/experiments/single_qubit_readout_calibration_test.py +5 -2
  16. cirq/experiments/t1_decay_experiment.py +7 -5
  17. cirq/experiments/t2_decay_experiment.py +10 -7
  18. cirq/experiments/two_qubit_xeb.py +42 -43
  19. cirq/experiments/two_qubit_xeb_test.py +1 -1
  20. cirq/experiments/xeb_fitting.py +25 -21
  21. cirq/experiments/xeb_sampling.py +18 -14
  22. cirq/experiments/xeb_simulation.py +11 -7
  23. cirq/experiments/xeb_simulation_test.py +3 -3
  24. cirq/experiments/z_phase_calibration.py +27 -24
  25. cirq/experiments/z_phase_calibration_test.py +1 -4
  26. cirq/interop/quirk/cells/arithmetic_cells.py +11 -10
  27. cirq/interop/quirk/cells/cell.py +18 -15
  28. cirq/interop/quirk/cells/composite_cell.py +8 -8
  29. cirq/interop/quirk/cells/control_cells.py +14 -14
  30. cirq/interop/quirk/cells/frequency_space_cells.py +4 -3
  31. cirq/interop/quirk/cells/input_cells.py +6 -4
  32. cirq/interop/quirk/cells/input_rotation_cells.py +14 -12
  33. cirq/interop/quirk/cells/measurement_cells.py +4 -1
  34. cirq/interop/quirk/cells/qubit_permutation_cells.py +3 -1
  35. cirq/interop/quirk/cells/scalar_cells.py +4 -1
  36. cirq/interop/quirk/cells/single_qubit_rotation_cells.py +5 -2
  37. cirq/interop/quirk/cells/swap_cell.py +7 -5
  38. cirq/interop/quirk/cells/testing.py +1 -1
  39. cirq/interop/quirk/url_to_circuit.py +11 -8
  40. cirq/json_resolver_cache.py +5 -3
  41. cirq/linalg/decompositions.py +5 -4
  42. cirq/linalg/decompositions_test.py +1 -1
  43. cirq/linalg/operator_spaces.py +8 -8
  44. cirq/ops/arithmetic_operation.py +4 -2
  45. cirq/ops/boolean_hamiltonian.py +7 -6
  46. cirq/ops/classically_controlled_operation.py +23 -20
  47. cirq/ops/clifford_gate.py +43 -47
  48. cirq/ops/common_channels.py +16 -14
  49. cirq/ops/common_gates.py +49 -67
  50. cirq/ops/control_values.py +12 -15
  51. cirq/ops/controlled_gate.py +15 -17
  52. cirq/ops/controlled_operation.py +17 -15
  53. cirq/study/resolver.py +1 -1
  54. {cirq_core-1.6.0.dev20250416035400.dist-info → cirq_core-1.6.0.dev20250417204649.dist-info}/METADATA +1 -1
  55. {cirq_core-1.6.0.dev20250416035400.dist-info → cirq_core-1.6.0.dev20250417204649.dist-info}/RECORD +58 -58
  56. {cirq_core-1.6.0.dev20250416035400.dist-info → cirq_core-1.6.0.dev20250417204649.dist-info}/WHEEL +0 -0
  57. {cirq_core-1.6.0.dev20250416035400.dist-info → cirq_core-1.6.0.dev20250417204649.dist-info}/licenses/LICENSE +0 -0
  58. {cirq_core-1.6.0.dev20250416035400.dist-info → cirq_core-1.6.0.dev20250417204649.dist-info}/top_level.txt +0 -0
@@ -13,6 +13,9 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Provides a method to do z-phase calibration for excitation-preserving gates."""
16
+
17
+ from __future__ import annotations
18
+
16
19
  import multiprocessing
17
20
  import multiprocessing.pool
18
21
  from typing import Any, Dict, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
@@ -32,20 +35,20 @@ if TYPE_CHECKING:
32
35
 
33
36
 
34
37
  def z_phase_calibration_workflow(
35
- sampler: 'cirq.Sampler',
36
- qubits: Optional[Sequence['cirq.GridQubit']] = None,
37
- two_qubit_gate: 'cirq.Gate' = ops.CZ,
38
+ sampler: cirq.Sampler,
39
+ qubits: Optional[Sequence[cirq.GridQubit]] = None,
40
+ two_qubit_gate: cirq.Gate = ops.CZ,
38
41
  options: Optional[xeb_fitting.XEBPhasedFSimCharacterizationOptions] = None,
39
42
  n_repetitions: int = 10**4,
40
43
  n_combinations: int = 10,
41
44
  n_circuits: int = 20,
42
45
  cycle_depths: Sequence[int] = tuple(np.arange(3, 100, 20)),
43
- random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
46
+ random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
44
47
  atol: float = 1e-3,
45
- num_workers_or_pool: Union[int, 'multiprocessing.pool.Pool'] = -1,
46
- pairs: Optional[Sequence[Tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None,
48
+ num_workers_or_pool: Union[int, multiprocessing.pool.Pool] = -1,
49
+ pairs: Optional[Sequence[Tuple[cirq.GridQubit, cirq.GridQubit]]] = None,
47
50
  tags: Sequence[Any] = (),
48
- ) -> Tuple[xeb_fitting.XEBCharacterizationResult, 'pd.DataFrame']:
51
+ ) -> Tuple[xeb_fitting.XEBCharacterizationResult, pd.DataFrame]:
49
52
  """Perform z-phase calibration for excitation-preserving gates.
50
53
 
51
54
  For a given excitation-preserving two-qubit gate we assume an error model that can be described
@@ -88,7 +91,7 @@ def z_phase_calibration_workflow(
88
91
  - A `pd.DataFrame` comparing the before and after fidelities.
89
92
  """
90
93
 
91
- pool: Optional['multiprocessing.pool.Pool'] = None
94
+ pool: Optional[multiprocessing.pool.Pool] = None
92
95
  local_pool = False
93
96
  if isinstance(num_workers_or_pool, multiprocessing.pool.Pool):
94
97
  pool = num_workers_or_pool # pragma: no cover
@@ -145,20 +148,20 @@ def z_phase_calibration_workflow(
145
148
 
146
149
 
147
150
  def calibrate_z_phases(
148
- sampler: 'cirq.Sampler',
149
- qubits: Optional[Sequence['cirq.GridQubit']] = None,
150
- two_qubit_gate: 'cirq.Gate' = ops.CZ,
151
+ sampler: cirq.Sampler,
152
+ qubits: Optional[Sequence[cirq.GridQubit]] = None,
153
+ two_qubit_gate: cirq.Gate = ops.CZ,
151
154
  options: Optional[xeb_fitting.XEBPhasedFSimCharacterizationOptions] = None,
152
155
  n_repetitions: int = 10**4,
153
156
  n_combinations: int = 10,
154
157
  n_circuits: int = 20,
155
158
  cycle_depths: Sequence[int] = tuple(np.arange(3, 100, 20)),
156
- random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
159
+ random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
157
160
  atol: float = 1e-3,
158
- num_workers_or_pool: Union[int, 'multiprocessing.pool.Pool'] = -1,
159
- pairs: Optional[Sequence[Tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None,
161
+ num_workers_or_pool: Union[int, multiprocessing.pool.Pool] = -1,
162
+ pairs: Optional[Sequence[Tuple[cirq.GridQubit, cirq.GridQubit]]] = None,
160
163
  tags: Sequence[Any] = (),
161
- ) -> Dict[Tuple['cirq.Qid', 'cirq.Qid'], 'cirq.PhasedFSimGate']:
164
+ ) -> Dict[Tuple[cirq.Qid, cirq.Qid], cirq.PhasedFSimGate]:
162
165
  """Perform z-phase calibration for excitation-preserving gates.
163
166
 
164
167
  For a given excitation-preserving two-qubit gate we assume an error model that can be described
@@ -238,12 +241,12 @@ def calibrate_z_phases(
238
241
 
239
242
 
240
243
  def plot_z_phase_calibration_result(
241
- before_after_df: 'pd.DataFrame',
242
- axes: Optional[np.ndarray[Sequence[Sequence['plt.Axes']], np.dtype[np.object_]]] = None,
243
- pairs: Optional[Sequence[Tuple['cirq.Qid', 'cirq.Qid']]] = None,
244
+ before_after_df: pd.DataFrame,
245
+ axes: Optional[np.ndarray[Sequence[Sequence[plt.Axes]], np.dtype[np.object_]]] = None,
246
+ pairs: Optional[Sequence[Tuple[cirq.Qid, cirq.Qid]]] = None,
244
247
  *,
245
248
  with_error_bars: bool = False,
246
- ) -> np.ndarray[Sequence[Sequence['plt.Axes']], np.dtype[np.object_]]:
249
+ ) -> np.ndarray[Sequence[Sequence[plt.Axes]], np.dtype[np.object_]]:
247
250
  """A helper method to plot the result of running z-phase calibration.
248
251
 
249
252
  Note that the plotted fidelity is a statistical estimate of the true fidelity and as a result
@@ -301,8 +304,8 @@ class CalibrationTransformer:
301
304
 
302
305
  def __init__(
303
306
  self,
304
- target: 'cirq.Gate',
305
- calibration_map: Dict[Tuple['cirq.Qid', 'cirq.Qid'], 'cirq.PhasedFSimGate'],
307
+ target: cirq.Gate,
308
+ calibration_map: Dict[Tuple[cirq.Qid, cirq.Qid], cirq.PhasedFSimGate],
306
309
  ):
307
310
  """Create a CalibrationTransformer.
308
311
 
@@ -327,10 +330,10 @@ class CalibrationTransformer:
327
330
 
328
331
  def __call__(
329
332
  self,
330
- circuit: 'cirq.AbstractCircuit',
333
+ circuit: cirq.AbstractCircuit,
331
334
  *,
332
335
  context: Optional[transformer_api.TransformerContext] = None,
333
- ) -> 'cirq.Circuit':
336
+ ) -> cirq.Circuit:
334
337
  """Adds 3 ZPowGates around each calibrated gate to cancel the effect of Z phases.
335
338
 
336
339
  Args:
@@ -340,7 +343,7 @@ class CalibrationTransformer:
340
343
  Returns:
341
344
  New circuit with the extra ZPowGates.
342
345
  """
343
- new_moments: List[Union[List[cirq.Operation], 'cirq.Moment']] = []
346
+ new_moments: List[Union[List[cirq.Operation], cirq.Moment]] = []
344
347
  for moment in circuit:
345
348
  before = []
346
349
  after = []
@@ -72,10 +72,7 @@ class _TestSimulator(cirq.Simulator):
72
72
  self.replacement = replacement
73
73
 
74
74
  def _core_iterator(
75
- self,
76
- circuit: 'cirq.AbstractCircuit',
77
- sim_state,
78
- all_measurements_are_terminal: bool = False,
75
+ self, circuit: cirq.AbstractCircuit, sim_state, all_measurements_are_terminal: bool = False
79
76
  ):
80
77
  new_circuit = cirq.Circuit(
81
78
  [
@@ -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
  import inspect
15
18
  from typing import (
16
19
  Any,
@@ -80,7 +83,7 @@ class QuirkArithmeticGate(ops.ArithmeticGate):
80
83
  raise ValueError(f'Target too small for modulus.\nTarget: {target}\nModulus: {r}')
81
84
 
82
85
  @property
83
- def operation(self) -> '_QuirkArithmeticCallable':
86
+ def operation(self) -> _QuirkArithmeticCallable:
84
87
  return ARITHMETIC_OP_TABLE[self.identifier]
85
88
 
86
89
  def _value_equality_values_(self) -> Any:
@@ -89,7 +92,7 @@ class QuirkArithmeticGate(ops.ArithmeticGate):
89
92
  def registers(self) -> Sequence[Union[int, Sequence[int]]]:
90
93
  return [self.target, *self.inputs]
91
94
 
92
- def with_registers(self, *new_registers: Union[int, Sequence[int]]) -> 'QuirkArithmeticGate':
95
+ def with_registers(self, *new_registers: Union[int, Sequence[int]]) -> QuirkArithmeticGate:
93
96
  if len(new_registers) != len(self.inputs) + 1:
94
97
  raise ValueError(
95
98
  'Wrong number of registers.\n'
@@ -109,7 +112,7 @@ class QuirkArithmeticGate(ops.ArithmeticGate):
109
112
  def apply(self, *registers: int) -> Union[int, Iterable[int]]:
110
113
  return self.operation(*registers)
111
114
 
112
- def _circuit_diagram_info_(self, args: 'cirq.CircuitDiagramInfoArgs') -> List[str]:
115
+ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> List[str]:
113
116
  lettered_args = list(zip(self.operation.letters, self.inputs))
114
117
 
115
118
  result: List[str] = []
@@ -183,8 +186,8 @@ class ArithmeticCell(Cell):
183
186
  def __init__(
184
187
  self,
185
188
  identifier: str,
186
- target: Sequence['cirq.Qid'],
187
- inputs: Sequence[Union[None, Sequence['cirq.Qid'], int]],
189
+ target: Sequence[cirq.Qid],
190
+ inputs: Sequence[Union[None, Sequence[cirq.Qid], int]],
188
191
  ):
189
192
  self.identifier = identifier
190
193
  self.target = tuple(target)
@@ -204,7 +207,7 @@ class ArithmeticCell(Cell):
204
207
  f'\n {self.inputs!r})'
205
208
  )
206
209
 
207
- def with_line_qubits_mapped_to(self, qubits: List['cirq.Qid']) -> 'Cell':
210
+ def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
208
211
  return ArithmeticCell(
209
212
  identifier=self.identifier,
210
213
  target=Cell._replace_qubits(self.target, qubits),
@@ -218,16 +221,14 @@ class ArithmeticCell(Cell):
218
221
  def operation(self):
219
222
  return ARITHMETIC_OP_TABLE[self.identifier]
220
223
 
221
- def with_input(
222
- self, letter: str, register: Union[Sequence['cirq.Qid'], int]
223
- ) -> 'ArithmeticCell':
224
+ def with_input(self, letter: str, register: Union[Sequence[cirq.Qid], int]) -> ArithmeticCell:
224
225
  new_inputs = [
225
226
  reg if letter != reg_letter else register
226
227
  for reg, reg_letter in zip(self.inputs, self.operation.letters)
227
228
  ]
228
229
  return ArithmeticCell(self.identifier, self.target, new_inputs)
229
230
 
230
- def operations(self) -> 'cirq.OP_TREE':
231
+ def operations(self) -> cirq.OP_TREE:
231
232
  missing_inputs = [
232
233
  letter for reg, letter in zip(self.inputs, self.operation.letters) if reg is None
233
234
  ]
@@ -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
  import abc
15
18
  from typing import (
16
19
  Any,
@@ -41,7 +44,7 @@ class Cell(metaclass=abc.ABCMeta):
41
44
  """
42
45
 
43
46
  @classmethod
44
- def _replace_qubit(cls, old_qubit: 'cirq.Qid', qubits: List['cirq.Qid']) -> 'cirq.Qid':
47
+ def _replace_qubit(cls, old_qubit: cirq.Qid, qubits: List[cirq.Qid]) -> cirq.Qid:
45
48
  if not isinstance(old_qubit, devices.LineQubit):
46
49
  raise ValueError(f'Can only map from line qubits, but got {old_qubit!r}.')
47
50
  if not 0 <= old_qubit.x < len(qubits):
@@ -50,12 +53,12 @@ class Cell(metaclass=abc.ABCMeta):
50
53
 
51
54
  @classmethod
52
55
  def _replace_qubits(
53
- cls, old_qubits: Iterable['cirq.Qid'], qubits: List['cirq.Qid']
54
- ) -> Tuple['cirq.Qid', ...]:
56
+ cls, old_qubits: Iterable[cirq.Qid], qubits: List[cirq.Qid]
57
+ ) -> Tuple[cirq.Qid, ...]:
55
58
  return tuple(Cell._replace_qubit(e, qubits) for e in old_qubits)
56
59
 
57
60
  @abc.abstractmethod
58
- def with_line_qubits_mapped_to(self, qubits: List['cirq.Qid']) -> 'Cell':
61
+ def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
59
62
  """Returns the same cell, but targeting different qubits.
60
63
 
61
64
  It is assumed that the cell is currently targeting `LineQubit`
@@ -84,7 +87,7 @@ class Cell(metaclass=abc.ABCMeta):
84
87
  extremely adversarial conditions.
85
88
  """
86
89
 
87
- def with_input(self, letter: str, register: Union[Sequence['cirq.Qid'], int]) -> 'Cell':
90
+ def with_input(self, letter: str, register: Union[Sequence[cirq.Qid], int]) -> Cell:
88
91
  """The same cell, but linked to an explicit input register or constant.
89
92
 
90
93
  If the cell doesn't need the input, it is returned unchanged.
@@ -99,7 +102,7 @@ class Cell(metaclass=abc.ABCMeta):
99
102
  """
100
103
  return self
101
104
 
102
- def controlled_by(self, qubit: 'cirq.Qid') -> 'Cell':
105
+ def controlled_by(self, qubit: cirq.Qid) -> Cell:
103
106
  """The same cell, but with an explicit control on its main operations.
104
107
 
105
108
  Cells with effects that do not need to be controlled are permitted to
@@ -113,7 +116,7 @@ class Cell(metaclass=abc.ABCMeta):
113
116
  """
114
117
  return self
115
118
 
116
- def operations(self) -> 'cirq.OP_TREE':
119
+ def operations(self) -> cirq.OP_TREE:
117
120
  """Returns operations that implement the cell's main action.
118
121
 
119
122
  Returns:
@@ -126,7 +129,7 @@ class Cell(metaclass=abc.ABCMeta):
126
129
  """
127
130
  return ()
128
131
 
129
- def basis_change(self) -> 'cirq.OP_TREE':
132
+ def basis_change(self) -> cirq.OP_TREE:
130
133
  """Operations to conjugate a column with.
131
134
 
132
135
  The main distinctions between operations performed during the body of a
@@ -143,7 +146,7 @@ class Cell(metaclass=abc.ABCMeta):
143
146
  """
144
147
  return ()
145
148
 
146
- def modify_column(self, column: List[Optional['Cell']]) -> None:
149
+ def modify_column(self, column: List[Optional[Cell]]) -> None:
147
150
  """Applies this cell's modification to its column.
148
151
 
149
152
  For example, a control cell will add a control qubit to other operations
@@ -159,7 +162,7 @@ class Cell(metaclass=abc.ABCMeta):
159
162
  Nothing. The `column` argument is mutated in place.
160
163
  """
161
164
 
162
- def persistent_modifiers(self) -> Dict[str, Callable[['Cell'], 'Cell']]:
165
+ def persistent_modifiers(self) -> Dict[str, Callable[[Cell], Cell]]:
163
166
  """Overridable modifications to apply to the rest of the circuit.
164
167
 
165
168
  Persistent modifiers apply to all cells in the same column and also to
@@ -186,7 +189,7 @@ class ExplicitOperationsCell(Cell):
186
189
  def gate_count(self) -> int:
187
190
  return len(self._operations) + 2 * len(self._basis_change)
188
191
 
189
- def with_line_qubits_mapped_to(self, qubits: List['cirq.Qid']) -> 'Cell':
192
+ def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
190
193
  return ExplicitOperationsCell(
191
194
  operations=tuple(
192
195
  op.with_qubits(*Cell._replace_qubits(op.qubits, qubits)) for op in self._operations
@@ -200,13 +203,13 @@ class ExplicitOperationsCell(Cell):
200
203
  def _value_equality_values_(self):
201
204
  return self._operations, self._basis_change
202
205
 
203
- def basis_change(self) -> 'cirq.OP_TREE':
206
+ def basis_change(self) -> cirq.OP_TREE:
204
207
  return self._basis_change
205
208
 
206
- def operations(self) -> 'cirq.OP_TREE':
209
+ def operations(self) -> cirq.OP_TREE:
207
210
  return self._operations
208
211
 
209
- def controlled_by(self, qubit: 'cirq.Qid') -> 'ExplicitOperationsCell':
212
+ def controlled_by(self, qubit: cirq.Qid) -> ExplicitOperationsCell:
210
213
  return ExplicitOperationsCell(
211
214
  [op.controlled_by(qubit) for op in self._operations], self._basis_change
212
215
  )
@@ -223,7 +226,7 @@ CellMaker = NamedTuple(
223
226
  [
224
227
  ('identifier', str),
225
228
  ('size', int),
226
- ('maker', Callable[[CellMakerArgs], Union[None, 'Cell', 'cirq.Operation']]),
229
+ ('maker', Callable[[CellMakerArgs], Union[None, Cell, 'cirq.Operation']]),
227
230
  ],
228
231
  )
229
232
  CellMaker.__doc__ = """Turns Quirk identifiers into Cirq operations.
@@ -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 (
16
18
  Callable,
17
19
  cast,
@@ -79,7 +81,7 @@ class CompositeCell(Cell):
79
81
  def gate_count(self) -> int:
80
82
  return self._gate_count
81
83
 
82
- def _transform_cells(self, func: Callable[[Cell], Cell]) -> 'CompositeCell':
84
+ def _transform_cells(self, func: Callable[[Cell], Cell]) -> CompositeCell:
83
85
  return CompositeCell(
84
86
  height=self.height,
85
87
  # It is important that this is a generator instead of a list!
@@ -96,18 +98,16 @@ class CompositeCell(Cell):
96
98
  self._sub_cell_cols_generator = list(self._sub_cell_cols_generator)
97
99
  return cast(List[List[Optional[Cell]]], self._sub_cell_cols_generator)
98
100
 
99
- def with_line_qubits_mapped_to(self, qubits: List['cirq.Qid']) -> 'Cell':
101
+ def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
100
102
  return self._transform_cells(lambda cell: cell.with_line_qubits_mapped_to(qubits))
101
103
 
102
- def with_input(
103
- self, letter: str, register: Union[Sequence['cirq.Qid'], int]
104
- ) -> 'CompositeCell':
104
+ def with_input(self, letter: str, register: Union[Sequence[cirq.Qid], int]) -> CompositeCell:
105
105
  return self._transform_cells(lambda cell: cell.with_input(letter, register))
106
106
 
107
- def controlled_by(self, qubit: 'cirq.Qid') -> 'CompositeCell':
107
+ def controlled_by(self, qubit: cirq.Qid) -> CompositeCell:
108
108
  return self._transform_cells(lambda cell: cell.controlled_by(qubit))
109
109
 
110
- def circuit(self) -> 'cirq.Circuit':
110
+ def circuit(self) -> cirq.Circuit:
111
111
  result = circuits.Circuit()
112
112
  for col in self._sub_cell_cols_sealed():
113
113
  body = circuits.Circuit(cell.operations() for cell in col if cell is not None)
@@ -120,7 +120,7 @@ class CompositeCell(Cell):
120
120
  result += basis_change**-1
121
121
  return result
122
122
 
123
- def operations(self) -> 'cirq.OP_TREE':
123
+ def operations(self) -> cirq.OP_TREE:
124
124
  return self.circuit()
125
125
 
126
126
 
@@ -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, Iterable, Iterator, List, Optional, TYPE_CHECKING, Union
16
18
 
17
19
  from cirq import ops, value
@@ -25,7 +27,7 @@ if TYPE_CHECKING:
25
27
  class ControlCell(Cell):
26
28
  """A modifier that adds controls to other cells in the column."""
27
29
 
28
- def __init__(self, qubit: 'cirq.Qid', basis_change: Iterable['cirq.Operation']):
30
+ def __init__(self, qubit: cirq.Qid, basis_change: Iterable[cirq.Operation]):
29
31
  self.qubit = qubit
30
32
  self._basis_change = tuple(basis_change)
31
33
 
@@ -42,7 +44,7 @@ class ControlCell(Cell):
42
44
  def gate_count(self) -> int:
43
45
  return 0
44
46
 
45
- def with_line_qubits_mapped_to(self, qubits: List['cirq.Qid']) -> 'Cell':
47
+ def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
46
48
  return ControlCell(
47
49
  qubit=Cell._replace_qubit(self.qubit, qubits),
48
50
  basis_change=tuple(
@@ -51,13 +53,13 @@ class ControlCell(Cell):
51
53
  ),
52
54
  )
53
55
 
54
- def modify_column(self, column: List[Optional['Cell']]):
56
+ def modify_column(self, column: List[Optional[Cell]]):
55
57
  for i in range(len(column)):
56
58
  gate = column[i]
57
59
  if gate is not None:
58
60
  column[i] = gate.controlled_by(self.qubit)
59
61
 
60
- def basis_change(self) -> 'cirq.OP_TREE':
62
+ def basis_change(self) -> cirq.OP_TREE:
61
63
  return self._basis_change
62
64
 
63
65
 
@@ -69,7 +71,7 @@ class ParityControlCell(Cell):
69
71
  of them are individually satisfied.
70
72
  """
71
73
 
72
- def __init__(self, qubits: Iterable['cirq.Qid'], basis_change: Iterable['cirq.Operation']):
74
+ def __init__(self, qubits: Iterable[cirq.Qid], basis_change: Iterable[cirq.Operation]):
73
75
  self.qubits = list(qubits)
74
76
  self._basis_change = list(basis_change)
75
77
 
@@ -86,7 +88,7 @@ class ParityControlCell(Cell):
86
88
  def gate_count(self) -> int:
87
89
  return 0
88
90
 
89
- def with_line_qubits_mapped_to(self, qubits: List['cirq.Qid']) -> 'Cell':
91
+ def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
90
92
  return ParityControlCell(
91
93
  qubits=Cell._replace_qubits(self.qubits, qubits),
92
94
  basis_change=tuple(
@@ -95,7 +97,7 @@ class ParityControlCell(Cell):
95
97
  ),
96
98
  )
97
99
 
98
- def modify_column(self, column: List[Optional['Cell']]):
100
+ def modify_column(self, column: List[Optional[Cell]]):
99
101
  for i in range(len(column)):
100
102
  gate = column[i]
101
103
  if gate is self:
@@ -109,7 +111,7 @@ class ParityControlCell(Cell):
109
111
  elif gate is not None:
110
112
  column[i] = gate.controlled_by(self.qubits[0])
111
113
 
112
- def basis_change(self) -> Iterator['cirq.OP_TREE']:
114
+ def basis_change(self) -> Iterator[cirq.OP_TREE]:
113
115
  yield from self._basis_change
114
116
 
115
117
  # Temporarily move the ZZZ..Z parity observable onto a single qubit.
@@ -132,7 +134,7 @@ def generate_all_control_cell_makers() -> Iterator[CellMaker]:
132
134
  yield _reg_parity_control("zpar", basis_change=None)
133
135
 
134
136
 
135
- def _reg_control(identifier: str, *, basis_change: Optional['cirq.Gate']) -> CellMaker:
137
+ def _reg_control(identifier: str, *, basis_change: Optional[cirq.Gate]) -> CellMaker:
136
138
  return CellMaker(
137
139
  identifier=identifier,
138
140
  size=1,
@@ -142,9 +144,7 @@ def _reg_control(identifier: str, *, basis_change: Optional['cirq.Gate']) -> Cel
142
144
  )
143
145
 
144
146
 
145
- def _reg_parity_control(
146
- identifier: str, *, basis_change: Optional['cirq.Gate'] = None
147
- ) -> CellMaker:
147
+ def _reg_parity_control(identifier: str, *, basis_change: Optional[cirq.Gate] = None) -> CellMaker:
148
148
  return CellMaker(
149
149
  identifier=identifier,
150
150
  size=1,
@@ -155,8 +155,8 @@ def _reg_parity_control(
155
155
 
156
156
 
157
157
  def _basis_else_empty(
158
- basis_change: Optional['cirq.Gate'], qureg: Union['cirq.Qid', Iterable['cirq.Qid']]
159
- ) -> Iterable['cirq.Operation']:
158
+ basis_change: Optional[cirq.Gate], qureg: Union[cirq.Qid, Iterable[cirq.Qid]]
159
+ ) -> Iterable[cirq.Operation]:
160
160
  if basis_change is None:
161
161
  return ()
162
162
  return basis_change.on_each(qureg)
@@ -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 Callable, Iterator
15
18
 
16
19
  import sympy
@@ -41,9 +44,7 @@ def generate_all_frequency_space_cell_makers() -> Iterator[CellMaker]:
41
44
  )
42
45
 
43
46
 
44
- def _family(
45
- identifier_prefix: str, gate_maker: Callable[[int], 'cirq.Gate']
46
- ) -> Iterator[CellMaker]:
47
+ def _family(identifier_prefix: str, gate_maker: Callable[[int], cirq.Gate]) -> Iterator[CellMaker]:
47
48
  f = lambda args: ExplicitOperationsCell([gate_maker(len(args.qubits)).on(*args.qubits)])
48
49
  yield CellMaker(identifier_prefix, 1, f)
49
50
  for i in CELL_SIZES:
@@ -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 Iterable, Iterator, List, Optional, TYPE_CHECKING
16
18
 
17
19
  from cirq.interop.quirk.cells.cell import Cell, CELL_SIZES, CellMaker
@@ -23,17 +25,17 @@ if TYPE_CHECKING:
23
25
  class InputCell(Cell):
24
26
  """A modifier that provides a quantum input to gates in the same column."""
25
27
 
26
- def __init__(self, qubits: Iterable['cirq.Qid'], letter: str):
28
+ def __init__(self, qubits: Iterable[cirq.Qid], letter: str):
27
29
  self.qubits = tuple(qubits)
28
30
  self.letter = letter
29
31
 
30
32
  def gate_count(self) -> int:
31
33
  return 0
32
34
 
33
- def with_line_qubits_mapped_to(self, qubits: List['cirq.Qid']) -> 'Cell':
35
+ def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
34
36
  return InputCell(qubits=Cell._replace_qubits(self.qubits, qubits), letter=self.letter)
35
37
 
36
- def modify_column(self, column: List[Optional['Cell']]):
38
+ def modify_column(self, column: List[Optional[Cell]]):
37
39
  for i in range(len(column)):
38
40
  cell = column[i]
39
41
  if cell is not None:
@@ -50,7 +52,7 @@ class SetDefaultInputCell(Cell):
50
52
  def gate_count(self) -> int:
51
53
  return 0
52
54
 
53
- def with_line_qubits_mapped_to(self, qubits: List['cirq.Qid']) -> 'Cell':
55
+ def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
54
56
  return self
55
57
 
56
58
  def persistent_modifiers(self):
@@ -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, Iterable, Iterator, List, Optional, Sequence, Tuple, Union
16
18
 
17
19
  import numpy as np
@@ -28,8 +30,8 @@ class InputRotationCell(Cell):
28
30
  def __init__(
29
31
  self,
30
32
  identifier: str,
31
- register: Optional[Sequence['cirq.Qid']],
32
- base_operation: 'cirq.Operation',
33
+ register: Optional[Sequence[cirq.Qid]],
34
+ base_operation: cirq.Operation,
33
35
  exponent_sign: int,
34
36
  ):
35
37
  self.identifier = identifier
@@ -52,7 +54,7 @@ class InputRotationCell(Cell):
52
54
  def gate_count(self) -> int:
53
55
  return 1
54
56
 
55
- def with_line_qubits_mapped_to(self, qubits: List['cirq.Qid']) -> 'Cell':
57
+ def with_line_qubits_mapped_to(self, qubits: List[cirq.Qid]) -> Cell:
56
58
  return InputRotationCell(
57
59
  self.identifier,
58
60
  None if self.register is None else Cell._replace_qubits(self.register, qubits),
@@ -62,7 +64,7 @@ class InputRotationCell(Cell):
62
64
  exponent_sign=self.exponent_sign,
63
65
  )
64
66
 
65
- def with_input(self, letter: str, register: Union[Sequence['cirq.Qid'], int]) -> 'Cell':
67
+ def with_input(self, letter: str, register: Union[Sequence[cirq.Qid], int]) -> Cell:
66
68
  # Parameterized rotations use input A as their parameter.
67
69
  if self.register is None and letter == 'a':
68
70
  if isinstance(register, int):
@@ -75,7 +77,7 @@ class InputRotationCell(Cell):
75
77
  )
76
78
  return self
77
79
 
78
- def controlled_by(self, qubit: 'cirq.Qid'):
80
+ def controlled_by(self, qubit: cirq.Qid):
79
81
  return InputRotationCell(
80
82
  self.identifier,
81
83
  self.register,
@@ -83,7 +85,7 @@ class InputRotationCell(Cell):
83
85
  self.exponent_sign,
84
86
  )
85
87
 
86
- def operations(self) -> 'cirq.OP_TREE':
88
+ def operations(self) -> cirq.OP_TREE:
87
89
  if self.register is None:
88
90
  raise ValueError("Missing input 'a'")
89
91
  return QuirkInputRotationOperation(
@@ -98,8 +100,8 @@ class QuirkInputRotationOperation(ops.Operation):
98
100
  def __init__(
99
101
  self,
100
102
  identifier: str,
101
- register: Iterable['cirq.Qid'],
102
- base_operation: 'cirq.Operation',
103
+ register: Iterable[cirq.Qid],
104
+ base_operation: cirq.Operation,
103
105
  exponent_sign: int,
104
106
  ):
105
107
  if exponent_sign not in [-1, +1]:
@@ -113,7 +115,7 @@ class QuirkInputRotationOperation(ops.Operation):
113
115
  return (self.identifier, self.register, self.base_operation, self.exponent_sign)
114
116
 
115
117
  @property
116
- def qubits(self) -> Tuple['cirq.Qid', ...]:
118
+ def qubits(self) -> Tuple[cirq.Qid, ...]:
117
119
  return tuple(self.base_operation.qubits) + self.register
118
120
 
119
121
  def with_qubits(self, *new_qubits):
@@ -127,7 +129,7 @@ class QuirkInputRotationOperation(ops.Operation):
127
129
  self.exponent_sign,
128
130
  )
129
131
 
130
- def _circuit_diagram_info_(self, args: 'cirq.CircuitDiagramInfoArgs'):
132
+ def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs):
131
133
  sub_result = cirq.circuit_diagram_info(self.base_operation)
132
134
  sign_char = '-' if self.exponent_sign == -1 else ''
133
135
  symbols = list(sub_result.wire_symbols)
@@ -142,7 +144,7 @@ class QuirkInputRotationOperation(ops.Operation):
142
144
  def _has_unitary_(self) -> bool:
143
145
  return True
144
146
 
145
- def _apply_unitary_(self, args: 'cirq.ApplyUnitaryArgs'):
147
+ def _apply_unitary_(self, args: cirq.ApplyUnitaryArgs):
146
148
  transposed_args = args.with_axes_transposed_to_start()
147
149
 
148
150
  target_axes = transposed_args.axes[: len(self.base_operation.qubits)]
@@ -184,7 +186,7 @@ def generate_all_input_rotation_cell_makers() -> Iterator[CellMaker]:
184
186
  yield _input_rotation_gate("Z^(-A/2^n)", ops.Z, -1)
185
187
 
186
188
 
187
- def _input_rotation_gate(identifier: str, gate: 'cirq.Gate', exponent_sign: int) -> CellMaker:
189
+ def _input_rotation_gate(identifier: str, gate: cirq.Gate, exponent_sign: int) -> CellMaker:
188
190
  return CellMaker(
189
191
  identifier,
190
192
  gate.num_qubits(),
@@ -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 cast, Iterable, Iterator, Optional, TYPE_CHECKING
15
18
 
16
19
  from cirq import ops
@@ -27,7 +30,7 @@ def generate_all_measurement_cell_makers() -> Iterator[CellMaker]:
27
30
  yield _measurement("XDetector", basis_change=ops.Y**0.5)
28
31
 
29
32
 
30
- def _measurement(identifier: str, basis_change: Optional['cirq.Gate'] = None) -> CellMaker:
33
+ def _measurement(identifier: str, basis_change: Optional[cirq.Gate] = None) -> CellMaker:
31
34
  return CellMaker(
32
35
  identifier=identifier,
33
36
  size=1,