cirq-core 1.6.0.dev20250501173104__py3-none-any.whl → 1.6.0.dev20250501231232__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 (59) hide show
  1. cirq/_version.py +1 -1
  2. cirq/_version_test.py +1 -1
  3. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +211 -107
  4. cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +347 -3
  5. cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +18 -18
  6. cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +18 -19
  7. cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +8 -10
  8. cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +26 -28
  9. cirq/transformers/drop_empty_moments.py +4 -2
  10. cirq/transformers/drop_negligible_operations.py +6 -4
  11. cirq/transformers/dynamical_decoupling.py +6 -4
  12. cirq/transformers/dynamical_decoupling_test.py +8 -6
  13. cirq/transformers/eject_phased_paulis.py +14 -12
  14. cirq/transformers/eject_z.py +8 -6
  15. cirq/transformers/expand_composite.py +5 -3
  16. cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +3 -1
  17. cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +4 -1
  18. cirq/transformers/insertion_sort.py +6 -4
  19. cirq/transformers/measurement_transformers.py +21 -21
  20. cirq/transformers/merge_k_qubit_gates.py +11 -9
  21. cirq/transformers/merge_k_qubit_gates_test.py +5 -3
  22. cirq/transformers/merge_single_qubit_gates.py +15 -13
  23. cirq/transformers/optimize_for_target_gateset.py +14 -12
  24. cirq/transformers/optimize_for_target_gateset_test.py +7 -3
  25. cirq/transformers/qubit_management_transformers.py +10 -8
  26. cirq/transformers/randomized_measurements.py +9 -7
  27. cirq/transformers/routing/initial_mapper.py +5 -3
  28. cirq/transformers/routing/line_initial_mapper.py +15 -13
  29. cirq/transformers/routing/mapping_manager.py +9 -9
  30. cirq/transformers/routing/route_circuit_cqc.py +17 -15
  31. cirq/transformers/routing/visualize_routed_circuit.py +7 -6
  32. cirq/transformers/stratify.py +13 -11
  33. cirq/transformers/synchronize_terminal_measurements.py +9 -9
  34. cirq/transformers/target_gatesets/compilation_target_gateset.py +19 -17
  35. cirq/transformers/target_gatesets/compilation_target_gateset_test.py +11 -7
  36. cirq/transformers/target_gatesets/cz_gateset.py +4 -2
  37. cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +5 -3
  38. cirq/transformers/transformer_api.py +17 -15
  39. cirq/transformers/transformer_primitives.py +22 -20
  40. cirq/transformers/transformer_primitives_test.py +3 -1
  41. cirq/value/classical_data.py +26 -26
  42. cirq/value/condition.py +23 -21
  43. cirq/value/duration.py +11 -8
  44. cirq/value/linear_dict.py +22 -20
  45. cirq/value/periodic_value.py +4 -4
  46. cirq/value/probability.py +3 -1
  47. cirq/value/product_state.py +14 -12
  48. cirq/work/collector.py +7 -5
  49. cirq/work/observable_measurement.py +24 -22
  50. cirq/work/observable_measurement_data.py +9 -7
  51. cirq/work/observable_readout_calibration.py +4 -1
  52. cirq/work/observable_readout_calibration_test.py +4 -1
  53. cirq/work/observable_settings.py +4 -2
  54. cirq/work/pauli_sum_collector.py +8 -6
  55. {cirq_core-1.6.0.dev20250501173104.dist-info → cirq_core-1.6.0.dev20250501231232.dist-info}/METADATA +1 -1
  56. {cirq_core-1.6.0.dev20250501173104.dist-info → cirq_core-1.6.0.dev20250501231232.dist-info}/RECORD +59 -59
  57. {cirq_core-1.6.0.dev20250501173104.dist-info → cirq_core-1.6.0.dev20250501231232.dist-info}/WHEEL +0 -0
  58. {cirq_core-1.6.0.dev20250501173104.dist-info → cirq_core-1.6.0.dev20250501231232.dist-info}/licenses/LICENSE +0 -0
  59. {cirq_core-1.6.0.dev20250501173104.dist-info → cirq_core-1.6.0.dev20250501231232.dist-info}/top_level.txt +0 -0
@@ -20,6 +20,8 @@ References:
20
20
  https://arxiv.org/abs/2105.06074
21
21
  """
22
22
 
23
+ from __future__ import annotations
24
+
23
25
  from typing import Optional, Sequence, Tuple, TYPE_CHECKING
24
26
 
25
27
  import numpy as np
@@ -34,7 +36,7 @@ if TYPE_CHECKING:
34
36
 
35
37
 
36
38
  def parameterized_2q_op_to_sqrt_iswap_operations(
37
- op: 'cirq.Operation', *, use_sqrt_iswap_inv: bool = False
39
+ op: cirq.Operation, *, use_sqrt_iswap_inv: bool = False
38
40
  ) -> protocols.decompose_protocol.DecomposeResult:
39
41
  """Tries to decompose a parameterized 2q operation into √iSWAP's + parameterized 1q rotations.
40
42
 
@@ -68,9 +70,7 @@ def parameterized_2q_op_to_sqrt_iswap_operations(
68
70
  return NotImplemented
69
71
 
70
72
 
71
- def _sqrt_iswap_inv(
72
- a: 'cirq.Qid', b: 'cirq.Qid', use_sqrt_iswap_inv: bool = True
73
- ) -> 'cirq.OP_TREE':
73
+ def _sqrt_iswap_inv(a: cirq.Qid, b: cirq.Qid, use_sqrt_iswap_inv: bool = True) -> cirq.OP_TREE:
74
74
  """Optree implementing `cirq.SQRT_ISWAP_INV(a, b)` using √iSWAPs.
75
75
 
76
76
  Args:
@@ -89,7 +89,7 @@ def _sqrt_iswap_inv(
89
89
 
90
90
 
91
91
  def _cphase_symbols_to_sqrt_iswap(
92
- a: 'cirq.Qid', b: 'cirq.Qid', turns: 'cirq.TParamVal', use_sqrt_iswap_inv: bool = True
92
+ a: cirq.Qid, b: cirq.Qid, turns: cirq.TParamVal, use_sqrt_iswap_inv: bool = True
93
93
  ):
94
94
  """Implements `cirq.CZ(a, b) ** turns` using two √iSWAPs and single qubit rotations.
95
95
 
@@ -136,7 +136,7 @@ def _cphase_symbols_to_sqrt_iswap(
136
136
 
137
137
 
138
138
  def _swap_symbols_to_sqrt_iswap(
139
- a: 'cirq.Qid', b: 'cirq.Qid', turns: 'cirq.TParamVal', use_sqrt_iswap_inv: bool = True
139
+ a: cirq.Qid, b: cirq.Qid, turns: cirq.TParamVal, use_sqrt_iswap_inv: bool = True
140
140
  ):
141
141
  """Implements `cirq.SWAP(a, b) ** turns` using two √iSWAPs and single qubit rotations.
142
142
 
@@ -170,7 +170,7 @@ def _swap_symbols_to_sqrt_iswap(
170
170
 
171
171
 
172
172
  def _iswap_symbols_to_sqrt_iswap(
173
- a: 'cirq.Qid', b: 'cirq.Qid', turns: 'cirq.TParamVal', use_sqrt_iswap_inv: bool = True
173
+ a: cirq.Qid, b: cirq.Qid, turns: cirq.TParamVal, use_sqrt_iswap_inv: bool = True
174
174
  ):
175
175
  """Implements `cirq.ISWAP(a, b) ** turns` using two √iSWAPs and single qubit rotations.
176
176
 
@@ -202,10 +202,10 @@ def _iswap_symbols_to_sqrt_iswap(
202
202
 
203
203
 
204
204
  def _fsim_symbols_to_sqrt_iswap(
205
- a: 'cirq.Qid',
206
- b: 'cirq.Qid',
207
- theta: 'cirq.TParamVal',
208
- phi: 'cirq.TParamVal',
205
+ a: cirq.Qid,
206
+ b: cirq.Qid,
207
+ theta: cirq.TParamVal,
208
+ phi: cirq.TParamVal,
209
209
  use_sqrt_iswap_inv: bool = True,
210
210
  ):
211
211
  """Implements `cirq.FSimGate(theta, phi)(a, b)` using two √iSWAPs and single qubit rotations.
@@ -229,8 +229,8 @@ def _fsim_symbols_to_sqrt_iswap(
229
229
 
230
230
 
231
231
  def two_qubit_matrix_to_sqrt_iswap_operations(
232
- q0: 'cirq.Qid',
233
- q1: 'cirq.Qid',
232
+ q0: cirq.Qid,
233
+ q1: cirq.Qid,
234
234
  mat: np.ndarray,
235
235
  *,
236
236
  required_sqrt_iswap_count: Optional[int] = None,
@@ -238,7 +238,7 @@ def two_qubit_matrix_to_sqrt_iswap_operations(
238
238
  atol: float = 1e-8,
239
239
  check_preconditions: bool = True,
240
240
  clean_operations: bool = False,
241
- ) -> Sequence['cirq.Operation']:
241
+ ) -> Sequence[cirq.Operation]:
242
242
  """Decomposes a two-qubit operation into ZPow/XPow/YPow/sqrt-iSWAP gates.
243
243
 
244
244
  This method uses the KAK decomposition of the matrix to determine how many
@@ -300,13 +300,13 @@ def two_qubit_matrix_to_sqrt_iswap_operations(
300
300
 
301
301
 
302
302
  def _kak_decomposition_to_sqrt_iswap_operations(
303
- q0: 'cirq.Qid',
304
- q1: 'cirq.Qid',
303
+ q0: cirq.Qid,
304
+ q1: cirq.Qid,
305
305
  kak: linalg.KakDecomposition,
306
306
  required_sqrt_iswap_count: Optional[int] = None,
307
307
  use_sqrt_iswap_inv: bool = False,
308
308
  atol: float = 1e-8,
309
- ) -> Sequence['cirq.Operation']:
309
+ ) -> Sequence[cirq.Operation]:
310
310
  single_qubit_operations, _ = _single_qubit_matrices_with_sqrt_iswap(
311
311
  kak, required_sqrt_iswap_count, atol=atol
312
312
  )
@@ -325,14 +325,14 @@ def _kak_decomposition_to_sqrt_iswap_operations(
325
325
 
326
326
 
327
327
  def _decomp_to_operations(
328
- q0: 'cirq.Qid',
329
- q1: 'cirq.Qid',
330
- two_qubit_gate: 'cirq.Gate',
328
+ q0: cirq.Qid,
329
+ q1: cirq.Qid,
330
+ two_qubit_gate: cirq.Gate,
331
331
  single_qubit_operations: Sequence[Tuple[np.ndarray, np.ndarray]],
332
332
  u0_before: np.ndarray = np.eye(2),
333
333
  u0_after: np.ndarray = np.eye(2),
334
334
  atol: float = 1e-8,
335
- ) -> Sequence['cirq.Operation']:
335
+ ) -> Sequence[cirq.Operation]:
336
336
  """Converts a sequence of single-qubit unitary matrices on two qubits into a
337
337
  list of operations with interleaved two-qubit gates."""
338
338
  two_qubit_op = two_qubit_gate(q0, q1)
@@ -401,9 +401,7 @@ def _decomp_to_operations(
401
401
 
402
402
 
403
403
  def _single_qubit_matrices_with_sqrt_iswap(
404
- kak: 'cirq.KakDecomposition',
405
- required_sqrt_iswap_count: Optional[int] = None,
406
- atol: float = 1e-8,
404
+ kak: cirq.KakDecomposition, required_sqrt_iswap_count: Optional[int] = None, atol: float = 1e-8
407
405
  ) -> Tuple[Sequence[Tuple[np.ndarray, np.ndarray]], complex]:
408
406
  """Computes the sequence of interleaved single-qubit unitary matrices in the
409
407
  sqrt-iSWAP decomposition."""
@@ -476,7 +474,7 @@ def _in_3sqrt_iswap_region(
476
474
 
477
475
 
478
476
  def _decomp_0_matrices(
479
- kak: 'cirq.KakDecomposition', atol: float = 1e-8
477
+ kak: cirq.KakDecomposition, atol: float = 1e-8
480
478
  ) -> Tuple[Sequence[Tuple[np.ndarray, np.ndarray]], complex]:
481
479
  """Returns the single-qubit matrices for the 0-SQRT_ISWAP decomposition.
482
480
 
@@ -494,7 +492,7 @@ def _decomp_0_matrices(
494
492
 
495
493
 
496
494
  def _decomp_1sqrt_iswap_matrices(
497
- kak: 'cirq.KakDecomposition', atol: float = 1e-8
495
+ kak: cirq.KakDecomposition, atol: float = 1e-8
498
496
  ) -> Tuple[Sequence[Tuple[np.ndarray, np.ndarray]], complex]:
499
497
  """Returns the single-qubit matrices for the 1-SQRT_ISWAP decomposition.
500
498
 
@@ -507,7 +505,7 @@ def _decomp_1sqrt_iswap_matrices(
507
505
 
508
506
 
509
507
  def _decomp_2sqrt_iswap_matrices(
510
- kak: 'cirq.KakDecomposition', atol: float = 1e-8
508
+ kak: cirq.KakDecomposition, atol: float = 1e-8
511
509
  ) -> Tuple[Sequence[Tuple[np.ndarray, np.ndarray]], complex]:
512
510
  """Returns the single-qubit matrices for the 2-SQRT_ISWAP decomposition.
513
511
 
@@ -570,7 +568,7 @@ def _decomp_2sqrt_iswap_matrices(
570
568
 
571
569
 
572
570
  def _decomp_3sqrt_iswap_matrices(
573
- kak: 'cirq.KakDecomposition', atol: float = 1e-8
571
+ kak: cirq.KakDecomposition, atol: float = 1e-8
574
572
  ) -> Tuple[Sequence[Tuple[np.ndarray, np.ndarray]], complex]:
575
573
  """Returns the single-qubit matrices for the 3-SQRT_ISWAP decomposition.
576
574
 
@@ -14,6 +14,8 @@
14
14
 
15
15
  """Transformer pass that removes empty moments from a circuit."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  from typing import Optional, TYPE_CHECKING
18
20
 
19
21
  from cirq.transformers import transformer_api, transformer_primitives
@@ -24,8 +26,8 @@ if TYPE_CHECKING:
24
26
 
25
27
  @transformer_api.transformer
26
28
  def drop_empty_moments(
27
- circuit: 'cirq.AbstractCircuit', *, context: Optional['cirq.TransformerContext'] = None
28
- ) -> 'cirq.Circuit':
29
+ circuit: cirq.AbstractCircuit, *, context: Optional[cirq.TransformerContext] = None
30
+ ) -> cirq.Circuit:
29
31
  """Removes empty moments from a circuit.
30
32
 
31
33
  Args:
@@ -14,6 +14,8 @@
14
14
 
15
15
  """Transformer pass that removes operations with tiny effects."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  from typing import Optional, TYPE_CHECKING
18
20
 
19
21
  from cirq import protocols
@@ -25,11 +27,11 @@ if TYPE_CHECKING:
25
27
 
26
28
  @transformer_api.transformer
27
29
  def drop_negligible_operations(
28
- circuit: 'cirq.AbstractCircuit',
30
+ circuit: cirq.AbstractCircuit,
29
31
  *,
30
- context: Optional['cirq.TransformerContext'] = None,
32
+ context: Optional[cirq.TransformerContext] = None,
31
33
  atol: float = 1e-8,
32
- ) -> 'cirq.Circuit':
34
+ ) -> cirq.Circuit:
33
35
  """Removes operations with tiny effects.
34
36
 
35
37
  An operation `op` is considered to have a tiny effect if
@@ -47,7 +49,7 @@ def drop_negligible_operations(
47
49
  if context is None:
48
50
  context = transformer_api.TransformerContext()
49
51
 
50
- def map_func(op: 'cirq.Operation', _: int) -> 'cirq.OP_TREE':
52
+ def map_func(op: cirq.Operation, _: int) -> cirq.OP_TREE:
51
53
  return (
52
54
  op
53
55
  if protocols.num_qubits(op) > 10
@@ -14,6 +14,8 @@
14
14
 
15
15
  """Transformer pass that adds dynamical decoupling operations to a circuit."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  from functools import reduce
18
20
  from itertools import cycle
19
21
  from typing import Dict, Optional, Tuple, TYPE_CHECKING, Union
@@ -204,12 +206,12 @@ def _need_merge_pulled_through(op_at_q: ops.Operation, is_at_last_busy_moment: b
204
206
 
205
207
  @transformer_api.transformer
206
208
  def add_dynamical_decoupling(
207
- circuit: 'cirq.AbstractCircuit',
209
+ circuit: cirq.AbstractCircuit,
208
210
  *,
209
- context: Optional['cirq.TransformerContext'] = None,
211
+ context: Optional[cirq.TransformerContext] = None,
210
212
  schema: Union[str, Tuple[ops.Gate, ...]] = 'DEFAULT',
211
213
  single_qubit_gate_moments_only: bool = True,
212
- ) -> 'cirq.Circuit':
214
+ ) -> cirq.Circuit:
213
215
  """Adds dynamical decoupling gate operations to a given circuit.
214
216
  This transformer might add new moments thus change structure of the original circuit.
215
217
 
@@ -284,7 +286,7 @@ def add_dynamical_decoupling(
284
286
  transformed_moments.extend(moments_to_be_appended)
285
287
 
286
288
  # Step 2, calc updated_moment with insertions / merges.
287
- updated_moment_ops: set['cirq.Operation'] = set()
289
+ updated_moment_ops: set[cirq.Operation] = set()
288
290
  for q in orig_circuit.all_qubits():
289
291
  op_at_q = moment.operation_at(q)
290
292
  remaining_pulled_through_gate = pulled_through.get(q)
@@ -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, Tuple, Union
16
18
 
17
19
  import numpy as np
@@ -21,7 +23,7 @@ import cirq
21
23
  from cirq import add_dynamical_decoupling
22
24
 
23
25
 
24
- def assert_sim_eq(circuit1: 'cirq.AbstractCircuit', circuit2: 'cirq.AbstractCircuit'):
26
+ def assert_sim_eq(circuit1: cirq.AbstractCircuit, circuit2: cirq.AbstractCircuit):
25
27
  # Simulate 2 circuits and compare final states.
26
28
  sampler = cirq.Simulator(dtype=np.complex128)
27
29
  psi0 = sampler.simulate(cirq.drop_terminal_measurements(circuit1)).final_state_vector
@@ -31,9 +33,9 @@ def assert_sim_eq(circuit1: 'cirq.AbstractCircuit', circuit2: 'cirq.AbstractCirc
31
33
 
32
34
 
33
35
  def assert_dd(
34
- input_circuit: 'cirq.AbstractCircuit',
35
- expected_circuit: Union[str, 'cirq.AbstractCircuit'],
36
- schema: Union[str, Tuple['cirq.Gate', ...]] = 'DEFAULT',
36
+ input_circuit: cirq.AbstractCircuit,
37
+ expected_circuit: Union[str, cirq.AbstractCircuit],
38
+ schema: Union[str, Tuple[cirq.Gate, ...]] = 'DEFAULT',
37
39
  single_qubit_gate_moments_only: bool = True,
38
40
  ):
39
41
  transformed_circuit = add_dynamical_decoupling(
@@ -86,7 +88,7 @@ def test_no_insertion():
86
88
  ('Y_YINV', (cirq.Y, cirq.Y**-1)),
87
89
  ],
88
90
  )
89
- def test_insert_provided_schema(schema: str, inserted_gates: Sequence['cirq.Gate']):
91
+ def test_insert_provided_schema(schema: str, inserted_gates: Sequence[cirq.Gate]):
90
92
  """Test case diagrams.
91
93
  Input:
92
94
  a: ───H───@───────────M───
@@ -252,7 +254,7 @@ def test_pull_through_h_gate_case2(single_qubit_gate_moments_only: bool):
252
254
  ),
253
255
  ],
254
256
  )
255
- def test_invalid_dd_schema(schema: Union[str, Tuple['cirq.Gate', ...]], error_msg_regex):
257
+ def test_invalid_dd_schema(schema: Union[str, Tuple[cirq.Gate, ...]], error_msg_regex):
256
258
  a = cirq.NamedQubit('a')
257
259
  input_circuit = cirq.Circuit(cirq.H(a))
258
260
  with pytest.raises(ValueError, match=error_msg_regex):
@@ -14,6 +14,8 @@
14
14
 
15
15
  """Transformer pass that pushes 180° rotations around axes in the XY plane later in the circuit."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  from typing import cast, Dict, Iterable, Iterator, Optional, Tuple, TYPE_CHECKING, Union
18
20
 
19
21
  import numpy as np
@@ -29,12 +31,12 @@ if TYPE_CHECKING:
29
31
 
30
32
  @transformer_api.transformer(add_deep_support=True)
31
33
  def eject_phased_paulis(
32
- circuit: 'cirq.AbstractCircuit',
34
+ circuit: cirq.AbstractCircuit,
33
35
  *,
34
- context: Optional['cirq.TransformerContext'] = None,
36
+ context: Optional[cirq.TransformerContext] = None,
35
37
  atol: float = 1e-8,
36
38
  eject_parameterized: bool = False,
37
- ) -> 'cirq.Circuit':
39
+ ) -> cirq.Circuit:
38
40
  """Transformer pass to push X, Y, PhasedX & (certain) PhasedXZ gates to the end of the circuit.
39
41
 
40
42
  As the gates get pushed, they may absorb Z gates, cancel against other
@@ -60,7 +62,7 @@ def eject_phased_paulis(
60
62
  held_w_phases: Dict[ops.Qid, value.TParamVal] = {}
61
63
  tags_to_ignore = set(context.tags_to_ignore) if context else set()
62
64
 
63
- def map_func(op: 'cirq.Operation', _: int) -> 'cirq.OP_TREE':
65
+ def map_func(op: cirq.Operation, _: int) -> cirq.OP_TREE:
64
66
  # Dump if `op` marked with a no compile tag.
65
67
  if set(op.tags) & tags_to_ignore:
66
68
  return [_dump_held(op.qubits, held_w_phases, atol), op]
@@ -107,7 +109,7 @@ def eject_phased_paulis(
107
109
 
108
110
  def _absorb_z_into_w(
109
111
  op: ops.Operation, held_w_phases: Dict[ops.Qid, value.TParamVal]
110
- ) -> 'cirq.OP_TREE':
112
+ ) -> cirq.OP_TREE:
111
113
  """Absorbs a Z^t gate into a W(a) flip.
112
114
 
113
115
  [Where W(a) is shorthand for PhasedX(phase_exponent=a).]
@@ -128,7 +130,7 @@ def _absorb_z_into_w(
128
130
 
129
131
  def _dump_held(
130
132
  qubits: Iterable[ops.Qid], held_w_phases: Dict[ops.Qid, value.TParamVal], atol: float
131
- ) -> Iterator['cirq.OP_TREE']:
133
+ ) -> Iterator[cirq.OP_TREE]:
132
134
  # Note: sorting is to avoid non-determinism in the insertion order.
133
135
  for q in sorted(qubits):
134
136
  p = held_w_phases.get(q)
@@ -140,7 +142,7 @@ def _dump_held(
140
142
 
141
143
  def _dump_into_measurement(
142
144
  op: ops.Operation, held_w_phases: Dict[ops.Qid, value.TParamVal]
143
- ) -> 'cirq.OP_TREE':
145
+ ) -> cirq.OP_TREE:
144
146
  measurement = cast(ops.MeasurementGate, cast(ops.GateOperation, op).gate)
145
147
  new_measurement = measurement.with_bits_flipped(
146
148
  *[i for i, q in enumerate(op.qubits) if q in held_w_phases]
@@ -152,7 +154,7 @@ def _dump_into_measurement(
152
154
 
153
155
  def _potential_cross_whole_w(
154
156
  op: ops.Operation, atol: float, held_w_phases: Dict[ops.Qid, value.TParamVal]
155
- ) -> 'cirq.OP_TREE':
157
+ ) -> cirq.OP_TREE:
156
158
  """Grabs or cancels a held W gate against an existing W gate.
157
159
 
158
160
  [Where W(a) is shorthand for PhasedX(phase_exponent=a).]
@@ -185,7 +187,7 @@ def _potential_cross_whole_w(
185
187
 
186
188
  def _potential_cross_partial_w(
187
189
  op: ops.Operation, held_w_phases: Dict[ops.Qid, value.TParamVal], atol: float
188
- ) -> 'cirq.OP_TREE':
190
+ ) -> cirq.OP_TREE:
189
191
  """Cross the held W over a partial W gate.
190
192
 
191
193
  [Where W(a) is shorthand for PhasedX(phase_exponent=a).]
@@ -210,7 +212,7 @@ def _potential_cross_partial_w(
210
212
  return gate.on(op.qubits[0])
211
213
 
212
214
 
213
- def _single_cross_over_cz(op: ops.Operation, qubit_with_w: 'cirq.Qid') -> 'cirq.OP_TREE':
215
+ def _single_cross_over_cz(op: ops.Operation, qubit_with_w: cirq.Qid) -> cirq.OP_TREE:
214
216
  """Crosses exactly one W flip over a partial CZ.
215
217
 
216
218
  [Where W(a) is shorthand for PhasedX(phase_exponent=a).]
@@ -251,7 +253,7 @@ def _single_cross_over_cz(op: ops.Operation, qubit_with_w: 'cirq.Qid') -> 'cirq.
251
253
 
252
254
  def _double_cross_over_cz(
253
255
  op: ops.Operation, held_w_phases: Dict[ops.Qid, value.TParamVal]
254
- ) -> 'cirq.OP_TREE':
256
+ ) -> cirq.OP_TREE:
255
257
  """Crosses two W flips over a partial CZ.
256
258
 
257
259
  [Where W(a) is shorthand for PhasedX(phase_exponent=a).]
@@ -355,7 +357,7 @@ def _try_get_known_z_half_turns(
355
357
 
356
358
  def _phased_x_or_pauli_gate(
357
359
  exponent: Union[float, sympy.Expr], phase_exponent: Union[float, sympy.Expr], atol: float
358
- ) -> Union['cirq.PhasedXPowGate', 'cirq.XPowGate', 'cirq.YPowGate']:
360
+ ) -> Union[cirq.PhasedXPowGate, cirq.XPowGate, cirq.YPowGate]:
359
361
  """Return PhasedXPowGate or X or Y gate if equivalent within atol in z-axis turns."""
360
362
  if not isinstance(phase_exponent, sympy.Expr) or phase_exponent.is_constant():
361
363
  half_turns = value.canonicalize_half_turns(float(phase_exponent))
@@ -14,6 +14,8 @@
14
14
 
15
15
  """Transformer pass that pushes Z gates later and later in the circuit."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  from collections import defaultdict
18
20
  from typing import Dict, Iterable, Iterator, Optional, Tuple, TYPE_CHECKING
19
21
 
@@ -31,7 +33,7 @@ def _is_integer(n):
31
33
  return np.isclose(n, np.round(n))
32
34
 
33
35
 
34
- def _is_swaplike(gate: 'cirq.Gate'):
36
+ def _is_swaplike(gate: cirq.Gate):
35
37
  if isinstance(gate, ops.SwapPowGate):
36
38
  return gate.exponent == 1
37
39
 
@@ -46,12 +48,12 @@ def _is_swaplike(gate: 'cirq.Gate'):
46
48
 
47
49
  @transformer_api.transformer(add_deep_support=True)
48
50
  def eject_z(
49
- circuit: 'cirq.AbstractCircuit',
51
+ circuit: cirq.AbstractCircuit,
50
52
  *,
51
- context: Optional['cirq.TransformerContext'] = None,
53
+ context: Optional[cirq.TransformerContext] = None,
52
54
  atol: float = 0.0,
53
55
  eject_parameterized: bool = False,
54
- ) -> 'cirq.Circuit':
56
+ ) -> cirq.Circuit:
55
57
  """Pushes Z gates towards the end of the circuit.
56
58
 
57
59
  As the Z gates get pushed they may absorb other Z gates, get absorbed into
@@ -77,7 +79,7 @@ def eject_z(
77
79
  lambda: None
78
80
  )
79
81
 
80
- def dump_tracked_phase(qubits: Iterable[ops.Qid]) -> Iterator['cirq.OP_TREE']:
82
+ def dump_tracked_phase(qubits: Iterable[ops.Qid]) -> Iterator[cirq.OP_TREE]:
81
83
  """Zeroes qubit_phase entries by emitting Z gates."""
82
84
  for q in qubits:
83
85
  p, key = qubit_phase[q], last_phased_xz_op[q]
@@ -87,7 +89,7 @@ def eject_z(
87
89
  elif key:
88
90
  phased_xz_replacements[key] = phased_xz_replacements[key].with_z_exponent(p * 2)
89
91
 
90
- def map_func(op: 'cirq.Operation', moment_index: int) -> 'cirq.OP_TREE':
92
+ def map_func(op: cirq.Operation, moment_index: int) -> cirq.OP_TREE:
91
93
  last_phased_xz_op.update({q: None for q in op.qubits})
92
94
 
93
95
  if tags_to_ignore & set(op.tags):
@@ -14,6 +14,8 @@
14
14
 
15
15
  """Transformer pass that expands composite operations via `cirq.decompose`."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  from typing import Callable, Optional, TYPE_CHECKING
18
20
 
19
21
  from cirq import circuits, ops, protocols
@@ -25,9 +27,9 @@ if TYPE_CHECKING:
25
27
 
26
28
  @transformer_api.transformer
27
29
  def expand_composite(
28
- circuit: 'cirq.AbstractCircuit',
30
+ circuit: cirq.AbstractCircuit,
29
31
  *,
30
- context: Optional['cirq.TransformerContext'] = None,
32
+ context: Optional[cirq.TransformerContext] = None,
31
33
  no_decomp: Callable[[ops.Operation], bool] = (lambda _: False),
32
34
  ):
33
35
  """A transformer that expands composite operations via `cirq.decompose`.
@@ -48,7 +50,7 @@ def expand_composite(
48
50
  Copy of the transformed input circuit.
49
51
  """
50
52
 
51
- def map_func(op: 'cirq.Operation', _) -> 'cirq.OP_TREE':
53
+ def map_func(op: cirq.Operation, _) -> cirq.OP_TREE:
52
54
  if context and context.deep and isinstance(op.untagged, circuits.CircuitOperation):
53
55
  return op
54
56
  return protocols.decompose(op, keep=no_decomp, on_stuck_raise=None)
@@ -15,6 +15,8 @@
15
15
  """A Gauge transformer for CZ**0.5 and CZ**-0.5 gates."""
16
16
 
17
17
 
18
+ from __future__ import annotations
19
+
18
20
  from numbers import Real
19
21
  from typing import Dict, Sequence, Tuple, TYPE_CHECKING
20
22
 
@@ -42,7 +44,7 @@ class SqrtCZGauge(Gauge):
42
44
  def weight(self) -> float:
43
45
  return 3.0
44
46
 
45
- def sample(self, gate: 'cirq.Gate', prng: np.random.Generator) -> ConstantGauge:
47
+ def sample(self, gate: cirq.Gate, prng: np.random.Generator) -> ConstantGauge:
46
48
  if prng.choice([True, False]):
47
49
  return ConstantGauge(two_qubit_gate=gate)
48
50
  swap_qubits = prng.choice([True, False])
@@ -14,6 +14,9 @@
14
14
 
15
15
  """Attempt to tabulate single qubit gates required to generate a target 2Q gate
16
16
  with a product A k A."""
17
+
18
+ from __future__ import annotations
19
+
17
20
  from dataclasses import dataclass
18
21
  from functools import reduce
19
22
  from typing import List, NamedTuple, Sequence, Tuple
@@ -316,7 +319,7 @@ def two_qubit_gate_product_tabulation(
316
319
  *,
317
320
  sample_scaling: int = 50,
318
321
  allow_missed_points: bool = True,
319
- random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
322
+ random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
320
323
  ) -> TwoQubitGateTabulation:
321
324
  r"""Generate a TwoQubitGateTabulation for a base two qubit unitary.
322
325
 
@@ -14,6 +14,8 @@
14
14
 
15
15
  """Transformer that sorts commuting operations in increasing order of their `.qubits` tuple."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  from typing import Dict, List, Optional, TYPE_CHECKING
18
20
 
19
21
  from cirq import circuits, protocols
@@ -25,8 +27,8 @@ if TYPE_CHECKING:
25
27
 
26
28
  @transformer_api.transformer(add_deep_support=True)
27
29
  def insertion_sort_transformer(
28
- circuit: 'cirq.AbstractCircuit', *, context: Optional['cirq.TransformerContext'] = None
29
- ) -> 'cirq.Circuit':
30
+ circuit: cirq.AbstractCircuit, *, context: Optional[cirq.TransformerContext] = None
31
+ ) -> cirq.Circuit:
30
32
  """Sorts the operations using their sorted `.qubits` property as comparison key.
31
33
 
32
34
  Operations are swapped only if they commute.
@@ -35,8 +37,8 @@ def insertion_sort_transformer(
35
37
  circuit: input circuit.
36
38
  context: optional TransformerContext (not used),
37
39
  """
38
- final_operations: List['cirq.Operation'] = []
39
- qubit_index: Dict['cirq.Qid', int] = {
40
+ final_operations: List[cirq.Operation] = []
41
+ qubit_index: Dict[cirq.Qid, int] = {
40
42
  q: idx for idx, q in enumerate(sorted(circuit.all_qubits()))
41
43
  }
42
44
  cached_qubit_indices: Dict[int, List[int]] = {}