cirq-core 1.6.0.dev20250416221104__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 (57) 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_core-1.6.0.dev20250416221104.dist-info → cirq_core-1.6.0.dev20250417204649.dist-info}/METADATA +1 -1
  54. {cirq_core-1.6.0.dev20250416221104.dist-info → cirq_core-1.6.0.dev20250417204649.dist-info}/RECORD +57 -57
  55. {cirq_core-1.6.0.dev20250416221104.dist-info → cirq_core-1.6.0.dev20250417204649.dist-info}/WHEEL +0 -0
  56. {cirq_core-1.6.0.dev20250416221104.dist-info → cirq_core-1.6.0.dev20250417204649.dist-info}/licenses/LICENSE +0 -0
  57. {cirq_core-1.6.0.dev20250416221104.dist-info → cirq_core-1.6.0.dev20250417204649.dist-info}/top_level.txt +0 -0
@@ -13,6 +13,8 @@
13
13
  # limitations under the License.
14
14
  """Code for generating random quantum circuits."""
15
15
 
16
+ from __future__ import annotations
17
+
16
18
  import dataclasses
17
19
  import itertools
18
20
  from typing import (
@@ -179,20 +181,20 @@ document(
179
181
 
180
182
 
181
183
  def random_rotations_between_two_qubit_circuit(
182
- q0: 'cirq.Qid',
183
- q1: 'cirq.Qid',
184
+ q0: cirq.Qid,
185
+ q1: cirq.Qid,
184
186
  depth: int,
185
187
  two_qubit_op_factory: Callable[
186
- ['cirq.Qid', 'cirq.Qid', 'np.random.RandomState'], 'cirq.OP_TREE'
188
+ [cirq.Qid, cirq.Qid, np.random.RandomState], cirq.OP_TREE
187
189
  ] = lambda a, b, _: ops.CZPowGate()(a, b),
188
- single_qubit_gates: Sequence['cirq.Gate'] = (
190
+ single_qubit_gates: Sequence[cirq.Gate] = (
189
191
  ops.X**0.5,
190
192
  ops.Y**0.5,
191
193
  ops.PhasedXPowGate(phase_exponent=0.25, exponent=0.5),
192
194
  ),
193
195
  add_final_single_qubit_layer: bool = True,
194
- seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
195
- ) -> 'cirq.Circuit':
196
+ seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
197
+ ) -> cirq.Circuit:
196
198
  """Generate a random two-qubit quantum circuit.
197
199
 
198
200
  This construction uses a similar structure to those in the paper
@@ -243,14 +245,14 @@ def random_rotations_between_two_qubit_circuit(
243
245
 
244
246
  def generate_library_of_2q_circuits(
245
247
  n_library_circuits: int,
246
- two_qubit_gate: 'cirq.Gate',
248
+ two_qubit_gate: cirq.Gate,
247
249
  *,
248
250
  max_cycle_depth: int = 100,
249
- q0: 'cirq.Qid' = devices.LineQubit(0),
250
- q1: 'cirq.Qid' = devices.LineQubit(1),
251
- random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
251
+ q0: cirq.Qid = devices.LineQubit(0),
252
+ q1: cirq.Qid = devices.LineQubit(1),
253
+ random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
252
254
  tags: Sequence[Any] = (),
253
- ) -> List['cirq.Circuit']:
255
+ ) -> List[cirq.Circuit]:
254
256
  """Generate a library of two-qubit Circuits.
255
257
 
256
258
  For single-qubit gates, this uses PhasedXZGates where the axis-in-XY-plane is one
@@ -316,7 +318,7 @@ def _get_random_combinations(
316
318
  n_combinations: int,
317
319
  *,
318
320
  pair_gen: Iterator[Tuple[List[QidPairT], Any]],
319
- random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
321
+ random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
320
322
  ) -> List[CircuitLibraryCombination]:
321
323
  """For qubit pairs, prepare a set of combinations to efficiently sample
322
324
  parallel two-qubit XEB circuits.
@@ -366,7 +368,7 @@ def get_random_combinations_for_device(
366
368
  device_graph: nx.Graph,
367
369
  *,
368
370
  pattern: Sequence[GridInteractionLayer] = HALF_GRID_STAGGERED_PATTERN,
369
- random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
371
+ random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
370
372
  ) -> List[CircuitLibraryCombination]:
371
373
  """For a given device, prepare a set of combinations to efficiently sample
372
374
  parallel two-qubit XEB circuits.
@@ -420,7 +422,7 @@ def get_random_combinations_for_pairs(
420
422
  n_library_circuits: int,
421
423
  n_combinations: int,
422
424
  all_pairs: List[List[QidPairT]],
423
- random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
425
+ random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
424
426
  ) -> List[CircuitLibraryCombination]:
425
427
  """For an explicit nested list of pairs, prepare a set of combinations to efficiently sample
426
428
  parallel two-qubit XEB circuits.
@@ -460,7 +462,7 @@ def get_random_combinations_for_pairs(
460
462
  )
461
463
 
462
464
 
463
- def _pairs_from_moment(moment: 'cirq.Moment') -> List[QidPairT]:
465
+ def _pairs_from_moment(moment: cirq.Moment) -> List[QidPairT]:
464
466
  """Helper function in `get_random_combinations_for_layer_circuit` pair generator.
465
467
 
466
468
  The moment should contain only two qubit operations, which define a list of qubit pairs.
@@ -477,8 +479,8 @@ def _pairs_from_moment(moment: 'cirq.Moment') -> List[QidPairT]:
477
479
  def get_random_combinations_for_layer_circuit(
478
480
  n_library_circuits: int,
479
481
  n_combinations: int,
480
- layer_circuit: 'cirq.Circuit',
481
- random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
482
+ layer_circuit: cirq.Circuit,
483
+ random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
482
484
  ) -> List[CircuitLibraryCombination]:
483
485
  """For a layer circuit, prepare a set of combinations to efficiently sample
484
486
  parallel two-qubit XEB circuits.
@@ -523,7 +525,7 @@ def get_grid_interaction_layer_circuit(
523
525
  device_graph: nx.Graph,
524
526
  pattern: Sequence[GridInteractionLayer] = HALF_GRID_STAGGERED_PATTERN,
525
527
  two_qubit_gate=ops.ISWAP**0.5,
526
- ) -> 'cirq.Circuit':
528
+ ) -> cirq.Circuit:
527
529
  """Create a circuit representation of a grid interaction pattern on a given device topology.
528
530
 
529
531
  The resulting circuit is deterministic, of depth len(pattern), and consists of `two_qubit_gate`
@@ -547,21 +549,21 @@ def get_grid_interaction_layer_circuit(
547
549
 
548
550
 
549
551
  def random_rotations_between_grid_interaction_layers_circuit(
550
- qubits: Iterable['cirq.GridQubit'],
552
+ qubits: Iterable[cirq.GridQubit],
551
553
  depth: int,
552
554
  *, # forces keyword arguments
553
555
  two_qubit_op_factory: Callable[
554
- ['cirq.GridQubit', 'cirq.GridQubit', 'np.random.RandomState'], 'cirq.OP_TREE'
556
+ [cirq.GridQubit, cirq.GridQubit, np.random.RandomState], cirq.OP_TREE
555
557
  ] = lambda a, b, _: ops.CZPowGate()(a, b),
556
558
  pattern: Sequence[GridInteractionLayer] = GRID_STAGGERED_PATTERN,
557
- single_qubit_gates: Sequence['cirq.Gate'] = (
559
+ single_qubit_gates: Sequence[cirq.Gate] = (
558
560
  ops.X**0.5,
559
561
  ops.Y**0.5,
560
562
  ops.PhasedXPowGate(phase_exponent=0.25, exponent=0.5),
561
563
  ),
562
564
  add_final_single_qubit_layer: bool = True,
563
- seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
564
- ) -> 'cirq.Circuit':
565
+ seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
566
+ ) -> cirq.Circuit:
565
567
  """Generate a random quantum circuit of a particular form.
566
568
 
567
569
  This construction is based on the circuits used in the paper
@@ -619,12 +621,12 @@ def random_rotations_between_grid_interaction_layers_circuit(
619
621
  return circuit
620
622
 
621
623
 
622
- def _coupled_qubit_pairs(qubits: List['cirq.GridQubit']) -> List[GridQubitPairT]:
624
+ def _coupled_qubit_pairs(qubits: List[cirq.GridQubit]) -> List[GridQubitPairT]:
623
625
  pairs = []
624
626
  qubit_set = set(qubits)
625
627
  for qubit in qubits:
626
628
 
627
- def add_pair(neighbor: 'cirq.GridQubit'):
629
+ def add_pair(neighbor: cirq.GridQubit):
628
630
  if neighbor in qubit_set:
629
631
  pairs.append((qubit, neighbor))
630
632
 
@@ -637,16 +639,16 @@ def _coupled_qubit_pairs(qubits: List['cirq.GridQubit']) -> List[GridQubitPairT]
637
639
  class _RandomSingleQubitLayerFactory:
638
640
  def __init__(
639
641
  self,
640
- qubits: Sequence['cirq.Qid'],
641
- single_qubit_gates: Sequence['cirq.Gate'],
642
- prng: 'np.random.RandomState',
642
+ qubits: Sequence[cirq.Qid],
643
+ single_qubit_gates: Sequence[cirq.Gate],
644
+ prng: np.random.RandomState,
643
645
  ) -> None:
644
646
  self.qubits = qubits
645
647
  self.single_qubit_gates = single_qubit_gates
646
648
  self.prng = prng
647
649
 
648
- def new_layer(self, previous_single_qubit_layer: 'cirq.Moment') -> 'cirq.Moment':
649
- def random_gate(qubit: 'cirq.Qid') -> 'cirq.Gate':
650
+ def new_layer(self, previous_single_qubit_layer: cirq.Moment) -> cirq.Moment:
651
+ def random_gate(qubit: cirq.Qid) -> cirq.Gate:
650
652
  excluded_op = previous_single_qubit_layer.operation_at(qubit)
651
653
  excluded_gate = excluded_op.gate if excluded_op is not None else None
652
654
  g = self.single_qubit_gates[self.prng.randint(0, len(self.single_qubit_gates))]
@@ -658,10 +660,10 @@ class _RandomSingleQubitLayerFactory:
658
660
 
659
661
 
660
662
  class _FixedSingleQubitLayerFactory:
661
- def __init__(self, fixed_single_qubit_layer: Dict['cirq.Qid', 'cirq.Gate']) -> None:
663
+ def __init__(self, fixed_single_qubit_layer: Dict[cirq.Qid, cirq.Gate]) -> None:
662
664
  self.fixed_single_qubit_layer = fixed_single_qubit_layer
663
665
 
664
- def new_layer(self, previous_single_qubit_layer: 'cirq.Moment') -> 'cirq.Moment':
666
+ def new_layer(self, previous_single_qubit_layer: cirq.Moment) -> cirq.Moment:
665
667
  return circuits.Moment(v.on(q) for q, v in self.fixed_single_qubit_layer.items())
666
668
 
667
669
 
@@ -669,9 +671,7 @@ _SingleQubitLayerFactory = Union[_FixedSingleQubitLayerFactory, _RandomSingleQub
669
671
 
670
672
 
671
673
  def _single_qubit_gates_arg_to_factory(
672
- single_qubit_gates: Sequence['cirq.Gate'],
673
- qubits: Sequence['cirq.Qid'],
674
- prng: 'np.random.RandomState',
674
+ single_qubit_gates: Sequence[cirq.Gate], qubits: Sequence[cirq.Qid], prng: np.random.RandomState
675
675
  ) -> _SingleQubitLayerFactory:
676
676
  """Parse the `single_qubit_gates` argument for circuit generation functions.
677
677
 
@@ -688,11 +688,11 @@ def _single_qubit_gates_arg_to_factory(
688
688
  def _two_qubit_layer(
689
689
  coupled_qubit_pairs: List[GridQubitPairT],
690
690
  two_qubit_op_factory: Callable[
691
- ['cirq.GridQubit', 'cirq.GridQubit', 'np.random.RandomState'], 'cirq.OP_TREE'
691
+ [cirq.GridQubit, cirq.GridQubit, np.random.RandomState], cirq.OP_TREE
692
692
  ],
693
693
  layer: GridInteractionLayer,
694
- prng: 'np.random.RandomState',
695
- ) -> Iterator['cirq.OP_TREE']:
694
+ prng: np.random.RandomState,
695
+ ) -> Iterator[cirq.OP_TREE]:
696
696
  for a, b in coupled_qubit_pairs:
697
697
  if (a, b) in layer or (b, a) in layer:
698
698
  yield two_qubit_op_factory(a, b, prng)
@@ -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 itertools
15
18
  from typing import Callable, cast, Dict, Iterable, List, Optional, Sequence, Set, Tuple
16
19
 
@@ -366,7 +369,7 @@ def test_random_rotations_between_grid_interaction_layers(
366
369
  pattern: Sequence[GridInteractionLayer],
367
370
  single_qubit_gates: Sequence[cirq.Gate],
368
371
  add_final_single_qubit_layer: bool,
369
- seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE',
372
+ seed: cirq.RANDOM_STATE_OR_SEED_LIKE,
370
373
  expected_circuit_length: int,
371
374
  single_qubit_layers_slice: slice,
372
375
  two_qubit_layers_slice: slice,
@@ -444,12 +447,12 @@ def _validate_two_qubit_layers(
444
447
 
445
448
 
446
449
  def _coupled_qubit_pairs(
447
- qubits: Set['cirq.GridQubit'],
448
- ) -> List[Tuple['cirq.GridQubit', 'cirq.GridQubit']]:
450
+ qubits: Set[cirq.GridQubit],
451
+ ) -> List[Tuple[cirq.GridQubit, cirq.GridQubit]]:
449
452
  pairs = []
450
453
  for qubit in qubits:
451
454
 
452
- def add_pair(neighbor: 'cirq.GridQubit'):
455
+ def add_pair(neighbor: cirq.GridQubit):
453
456
  if neighbor in qubits:
454
457
  pairs.append((qubit, neighbor))
455
458
 
@@ -14,6 +14,8 @@
14
14
 
15
15
  """Utilities to compute readout confusion matrix and use it for readout error mitigation."""
16
16
 
17
+ from __future__ import annotations
18
+
17
19
  import time
18
20
  from typing import Any, cast, Dict, List, Optional, Sequence, Tuple, TYPE_CHECKING, Union
19
21
 
@@ -60,7 +62,7 @@ class TensoredConfusionMatrices:
60
62
  def __init__(
61
63
  self,
62
64
  confusion_matrices: Union[np.ndarray, Sequence[np.ndarray]],
63
- measure_qubits: Union[Sequence['cirq.Qid'], Sequence[Sequence['cirq.Qid']]],
65
+ measure_qubits: Union[Sequence[cirq.Qid], Sequence[Sequence[cirq.Qid]]],
64
66
  *,
65
67
  repetitions: int,
66
68
  timestamp: float,
@@ -112,14 +114,14 @@ class TensoredConfusionMatrices:
112
114
  self._measure_qubits = tuple(tuple(q) for q in measure_qubits)
113
115
  self._qubits = tuple(sorted(set(q for ql in measure_qubits for q in ql)))
114
116
  self._qubits_to_idx = {q: i for i, q in enumerate(self._qubits)}
115
- self._cache: Dict[Tuple['cirq.Qid', ...], np.ndarray] = {}
117
+ self._cache: Dict[Tuple[cirq.Qid, ...], np.ndarray] = {}
116
118
  if sum(len(q) for q in self._measure_qubits) != len(self._qubits):
117
119
  raise ValueError(f"Repeated qubits not allowed in measure_qubits: {measure_qubits}.")
118
120
 
119
121
  @classmethod
120
122
  def from_measurement(
121
- cls, gate: ops.MeasurementGate, qubits: Sequence['cirq.Qid']
122
- ) -> 'TensoredConfusionMatrices':
123
+ cls, gate: ops.MeasurementGate, qubits: Sequence[cirq.Qid]
124
+ ) -> TensoredConfusionMatrices:
123
125
  """Generates TCM for the confusion map in a MeasurementGate.
124
126
 
125
127
  This ignores any invert_mask defined for the gate - it only replicates the confusion map.
@@ -160,21 +162,21 @@ class TensoredConfusionMatrices:
160
162
  return self._confusion_matrices
161
163
 
162
164
  @property
163
- def measure_qubits(self) -> Tuple[Tuple['cirq.Qid', ...], ...]:
165
+ def measure_qubits(self) -> Tuple[Tuple[cirq.Qid, ...], ...]:
164
166
  """Calibrated qubit pattern for which individual confusion matrices were computed."""
165
167
  return self._measure_qubits
166
168
 
167
169
  @property
168
- def qubits(self) -> Tuple['cirq.Qid', ...]:
170
+ def qubits(self) -> Tuple[cirq.Qid, ...]:
169
171
  """Sorted list of all calibrated qubits."""
170
172
  return self._qubits
171
173
 
172
- def _get_vars(self, qubit_pattern: Sequence['cirq.Qid']) -> List[int]:
174
+ def _get_vars(self, qubit_pattern: Sequence[cirq.Qid]) -> List[int]:
173
175
  in_vars = [2 * self._qubits_to_idx[q] for q in qubit_pattern]
174
176
  out_vars = [2 * self._qubits_to_idx[q] + 1 for q in qubit_pattern]
175
177
  return in_vars + out_vars
176
178
 
177
- def _confusion_matrix(self, qubits: Sequence['cirq.Qid']) -> np.ndarray:
179
+ def _confusion_matrix(self, qubits: Sequence[cirq.Qid]) -> np.ndarray:
178
180
  ein_input: List[np.ndarray | List[int]] = []
179
181
  for qs, cm in zip(self.measure_qubits, self.confusion_matrices):
180
182
  ein_input.extend([cm.reshape((2, 2) * len(qs)), self._get_vars(qs)])
@@ -183,7 +185,7 @@ class TensoredConfusionMatrices:
183
185
  ret = np.einsum(*ein_input, ein_out).reshape((2 ** len(qubits),) * 2)
184
186
  return ret / ret.sum(axis=1)
185
187
 
186
- def confusion_matrix(self, qubits: Optional[Sequence['cirq.Qid']] = None) -> np.ndarray:
188
+ def confusion_matrix(self, qubits: Optional[Sequence[cirq.Qid]] = None) -> np.ndarray:
187
189
  """Returns a single confusion matrix constructed for the given set of qubits.
188
190
 
189
191
  The single `2 ** len(qubits) x 2 ** len(qubits)` confusion matrix is constructed
@@ -211,7 +213,7 @@ class TensoredConfusionMatrices:
211
213
  self._cache[key] = self._confusion_matrix(qubits)
212
214
  return self._cache[key]
213
215
 
214
- def correction_matrix(self, qubits: Optional[Sequence['cirq.Qid']] = None) -> np.ndarray:
216
+ def correction_matrix(self, qubits: Optional[Sequence[cirq.Qid]] = None) -> np.ndarray:
215
217
  """Returns a single correction matrix constructed for the given set of qubits.
216
218
 
217
219
  A correction matrix is the inverse of confusion matrix and can be used to apply corrections
@@ -240,7 +242,7 @@ class TensoredConfusionMatrices:
240
242
  def apply(
241
243
  self,
242
244
  result: np.ndarray,
243
- qubits: Optional[Sequence['cirq.Qid']] = None,
245
+ qubits: Optional[Sequence[cirq.Qid]] = None,
244
246
  *,
245
247
  method='least_squares',
246
248
  ) -> np.ndarray:
@@ -300,7 +302,7 @@ class TensoredConfusionMatrices:
300
302
  return res.x
301
303
 
302
304
  def readout_mitigation_pauli_uncorrelated(
303
- self, qubits: Sequence['cirq.Qid'], measured_bitstrings: np.ndarray
305
+ self, qubits: Sequence[cirq.Qid], measured_bitstrings: np.ndarray
304
306
  ) -> tuple[float, float]:
305
307
  r"""Uncorrelated readout error mitigation for a multi-qubit Pauli operator.
306
308
 
@@ -384,7 +386,7 @@ class TensoredConfusionMatrices:
384
386
  @classmethod
385
387
  def _from_json_dict_(
386
388
  cls, confusion_matrices, measure_qubits, repetitions, timestamp, **kwargs
387
- ) -> 'TensoredConfusionMatrices':
389
+ ) -> TensoredConfusionMatrices:
388
390
  return cls(
389
391
  [np.asarray(cm) for cm in confusion_matrices],
390
392
  measure_qubits,
@@ -423,8 +425,8 @@ class TensoredConfusionMatrices:
423
425
 
424
426
 
425
427
  def measure_confusion_matrix(
426
- sampler: 'cirq.Sampler',
427
- qubits: Union[Sequence['cirq.Qid'], Sequence[Sequence['cirq.Qid']]],
428
+ sampler: cirq.Sampler,
429
+ qubits: Union[Sequence[cirq.Qid], Sequence[Sequence[cirq.Qid]]],
428
430
  repetitions: int = 1000,
429
431
  ) -> TensoredConfusionMatrices:
430
432
  """Prepares `TensoredConfusionMatrices` for the n qubits in the input.
@@ -11,7 +11,11 @@
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
+
14
15
  """Single qubit readout experiments using parallel or isolated statistics."""
16
+
17
+ from __future__ import annotations
18
+
15
19
  import dataclasses
16
20
  import time
17
21
  from typing import Any, cast, Dict, Iterable, List, Optional, TYPE_CHECKING
@@ -43,8 +47,8 @@ class SingleQubitReadoutCalibrationResult:
43
47
  timestamp: The time the data was taken, in seconds since the epoch.
44
48
  """
45
49
 
46
- zero_state_errors: Dict['cirq.Qid', float]
47
- one_state_errors: Dict['cirq.Qid', float]
50
+ zero_state_errors: Dict[cirq.Qid, float]
51
+ one_state_errors: Dict[cirq.Qid, float]
48
52
  repetitions: int
49
53
  timestamp: float
50
54
 
@@ -197,7 +201,7 @@ class SingleQubitReadoutCalibrationResult:
197
201
 
198
202
 
199
203
  def estimate_single_qubit_readout_errors(
200
- sampler: 'cirq.Sampler', *, qubits: Iterable['cirq.Qid'], repetitions: int = 1000
204
+ sampler: cirq.Sampler, *, qubits: Iterable[cirq.Qid], repetitions: int = 1000
201
205
  ) -> SingleQubitReadoutCalibrationResult:
202
206
  """Estimate single-qubit readout error.
203
207
 
@@ -229,9 +233,9 @@ def estimate_single_qubit_readout_errors(
229
233
 
230
234
 
231
235
  def estimate_parallel_single_qubit_readout_errors(
232
- sampler: 'cirq.Sampler',
236
+ sampler: cirq.Sampler,
233
237
  *,
234
- qubits: Iterable['cirq.Qid'],
238
+ qubits: Iterable[cirq.Qid],
235
239
  trials: int = 20,
236
240
  repetitions: int = 1000,
237
241
  trials_per_batch: Optional[int] = None,
@@ -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 Sequence
15
18
 
16
19
  import numpy as np
@@ -30,7 +33,7 @@ def test_single_qubit_readout_result_repr():
30
33
 
31
34
 
32
35
  class NoisySingleQubitReadoutSampler(cirq.Sampler):
33
- def __init__(self, p0: float, p1: float, seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None):
36
+ def __init__(self, p0: float, p1: float, seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None):
34
37
  """Sampler that flips some bits upon readout.
35
38
 
36
39
  Args:
@@ -44,7 +47,7 @@ class NoisySingleQubitReadoutSampler(cirq.Sampler):
44
47
  self.simulator = cirq.Simulator(seed=self.prng, split_untangled_states=False)
45
48
 
46
49
  def run_sweep(
47
- self, program: 'cirq.AbstractCircuit', params: cirq.Sweepable, repetitions: int = 1
50
+ self, program: cirq.AbstractCircuit, params: cirq.Sweepable, repetitions: int = 1
48
51
  ) -> Sequence[cirq.Result]:
49
52
  results = self.simulator.run_sweep(program, params, repetitions)
50
53
  for result in results:
@@ -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 warnings
16
18
  from typing import Any, cast, Optional, Sequence, TYPE_CHECKING
17
19
 
@@ -31,14 +33,14 @@ optimize = _import.LazyLoader("optimize", globals(), "scipy.optimize")
31
33
 
32
34
 
33
35
  def t1_decay(
34
- sampler: 'cirq.Sampler',
36
+ sampler: cirq.Sampler,
35
37
  *,
36
- qubit: 'cirq.Qid',
38
+ qubit: cirq.Qid,
37
39
  num_points: int,
38
- max_delay: 'cirq.DURATION_LIKE',
39
- min_delay: 'cirq.DURATION_LIKE' = None,
40
+ max_delay: cirq.DURATION_LIKE,
41
+ min_delay: cirq.DURATION_LIKE = None,
40
42
  repetitions: int = 1000,
41
- ) -> 'cirq.experiments.T1DecayResult':
43
+ ) -> cirq.experiments.T1DecayResult:
42
44
  """Runs a t1 decay experiment.
43
45
 
44
46
  Initializes a qubit into the |1⟩ state, waits for a variable amount of time,
@@ -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 enum
15
18
  from typing import Any, List, Optional, TYPE_CHECKING, Union
16
19
 
@@ -35,17 +38,17 @@ _T2_COLUMNS = ['delay_ns', 0, 1]
35
38
 
36
39
 
37
40
  def t2_decay(
38
- sampler: 'cirq.Sampler',
41
+ sampler: cirq.Sampler,
39
42
  *,
40
- qubit: 'cirq.Qid',
41
- experiment_type: 'ExperimentType' = ExperimentType.RAMSEY,
43
+ qubit: cirq.Qid,
44
+ experiment_type: ExperimentType = ExperimentType.RAMSEY,
42
45
  num_points: int,
43
- max_delay: 'cirq.DURATION_LIKE',
44
- min_delay: 'cirq.DURATION_LIKE' = None,
46
+ max_delay: cirq.DURATION_LIKE,
47
+ min_delay: cirq.DURATION_LIKE = None,
45
48
  repetitions: int = 1000,
46
49
  delay_sweep: Optional[study.Sweep] = None,
47
50
  num_pulses: Optional[List[int]] = None,
48
- ) -> Union['cirq.experiments.T2DecayResult', List['cirq.experiments.T2DecayResult']]:
51
+ ) -> Union[cirq.experiments.T2DecayResult, List[cirq.experiments.T2DecayResult]]:
49
52
  """Runs a t2 transverse relaxation experiment.
50
53
 
51
54
  Initializes a qubit into a superposition state, evolves the system using
@@ -234,7 +237,7 @@ def _create_tabulation(measurements: pd.DataFrame) -> pd.DataFrame:
234
237
  return tabulation
235
238
 
236
239
 
237
- def _cpmg_circuit(qubit: 'cirq.Qid', delay_var: sympy.Symbol, max_pulses: int) -> 'cirq.Circuit':
240
+ def _cpmg_circuit(qubit: cirq.Qid, delay_var: sympy.Symbol, max_pulses: int) -> cirq.Circuit:
238
241
  """Creates a CPMG circuit for a given qubit.
239
242
 
240
243
  The circuit will look like: