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,9 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Provides functions for running and analyzing two-qubit XEB experiments."""
16
+
17
+ from __future__ import annotations
18
+
16
19
  import functools
17
20
  import itertools
18
21
  from dataclasses import dataclass
@@ -45,22 +48,22 @@ if TYPE_CHECKING:
45
48
  import cirq
46
49
 
47
50
 
48
- def _grid_qubits_for_sampler(sampler: 'cirq.Sampler') -> Optional[Sequence['cirq.GridQubit']]:
51
+ def _grid_qubits_for_sampler(sampler: cirq.Sampler) -> Optional[Sequence[cirq.GridQubit]]:
49
52
  if hasattr(sampler, 'processor'):
50
53
  device = sampler.processor.get_device()
51
54
  return sorted(device.metadata.qubit_set)
52
55
  return None
53
56
 
54
57
 
55
- def _manhattan_distance(qubit1: 'cirq.GridQubit', qubit2: 'cirq.GridQubit') -> int:
58
+ def _manhattan_distance(qubit1: cirq.GridQubit, qubit2: cirq.GridQubit) -> int:
56
59
  return abs(qubit1.row - qubit2.row) + abs(qubit1.col - qubit2.col)
57
60
 
58
61
 
59
62
  def qubits_and_pairs(
60
- sampler: 'cirq.Sampler',
61
- qubits: Optional[Sequence['cirq.GridQubit']] = None,
62
- pairs: Optional[Sequence[tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None,
63
- ) -> Tuple[Sequence['cirq.GridQubit'], Sequence[tuple['cirq.GridQubit', 'cirq.GridQubit']]]:
63
+ sampler: cirq.Sampler,
64
+ qubits: Optional[Sequence[cirq.GridQubit]] = None,
65
+ pairs: Optional[Sequence[tuple[cirq.GridQubit, cirq.GridQubit]]] = None,
66
+ ) -> Tuple[Sequence[cirq.GridQubit], Sequence[tuple[cirq.GridQubit, cirq.GridQubit]]]:
64
67
  """Extract qubits and pairs from sampler.
65
68
 
66
69
 
@@ -103,14 +106,14 @@ class TwoQubitXEBResult:
103
106
  fidelities: pd.DataFrame
104
107
 
105
108
  @functools.cached_property
106
- def _qubit_pair_map(self) -> Dict[Tuple['cirq.GridQubit', 'cirq.GridQubit'], int]:
109
+ def _qubit_pair_map(self) -> Dict[Tuple[cirq.GridQubit, cirq.GridQubit], int]:
107
110
  return {
108
111
  (min(q0, q1), max(q0, q1)): i
109
112
  for i, (_, _, (q0, q1)) in enumerate(self.fidelities.index)
110
113
  }
111
114
 
112
115
  @functools.cached_property
113
- def all_qubit_pairs(self) -> Tuple[Tuple['cirq.GridQubit', 'cirq.GridQubit'], ...]:
116
+ def all_qubit_pairs(self) -> Tuple[Tuple[cirq.GridQubit, cirq.GridQubit], ...]:
114
117
  return tuple(sorted(self._qubit_pair_map.keys()))
115
118
 
116
119
  def plot_heatmap(self, ax: Optional[plt.Axes] = None, **plot_kwargs) -> plt.Axes:
@@ -127,7 +130,7 @@ class TwoQubitXEBResult:
127
130
  show_plot = not ax
128
131
  if not isinstance(ax, plt.Axes):
129
132
  fig, ax = plt.subplots(1, 1, figsize=(8, 8))
130
- heatmap_data: Dict[Tuple['cirq.GridQubit', ...], float] = {
133
+ heatmap_data: Dict[Tuple[cirq.GridQubit, ...], float] = {
131
134
  pair: self.xeb_error(*pair) for pair in self.all_qubit_pairs
132
135
  }
133
136
 
@@ -139,11 +142,7 @@ class TwoQubitXEBResult:
139
142
  return ax
140
143
 
141
144
  def plot_fitted_exponential(
142
- self,
143
- q0: 'cirq.GridQubit',
144
- q1: 'cirq.GridQubit',
145
- ax: Optional[plt.Axes] = None,
146
- **plot_kwargs,
145
+ self, q0: cirq.GridQubit, q1: cirq.GridQubit, ax: Optional[plt.Axes] = None, **plot_kwargs
147
146
  ) -> plt.Axes:
148
147
  """plot the fitted model to for xeb error of a qubit pair.
149
148
 
@@ -185,17 +184,17 @@ class TwoQubitXEBResult:
185
184
  q0, q1 = q1, q0
186
185
  return self.fidelities.iloc[self._qubit_pair_map[(q0, q1)]]
187
186
 
188
- def xeb_fidelity(self, q0: 'cirq.GridQubit', q1: 'cirq.GridQubit') -> float:
187
+ def xeb_fidelity(self, q0: cirq.GridQubit, q1: cirq.GridQubit) -> float:
189
188
  """Return the XEB fidelity of a qubit pair."""
190
189
  return noise_utils.decay_constant_to_xeb_fidelity(
191
190
  self._record(q0, q1).layer_fid, num_qubits=2
192
191
  )
193
192
 
194
- def xeb_error(self, q0: 'cirq.GridQubit', q1: 'cirq.GridQubit') -> float:
193
+ def xeb_error(self, q0: cirq.GridQubit, q1: cirq.GridQubit) -> float:
195
194
  """Return the XEB error of a qubit pair."""
196
195
  return 1 - self.xeb_fidelity(q0, q1)
197
196
 
198
- def all_errors(self) -> Dict[Tuple['cirq.GridQubit', 'cirq.GridQubit'], float]:
197
+ def all_errors(self) -> Dict[Tuple[cirq.GridQubit, cirq.GridQubit], float]:
199
198
  """Return the XEB error of all qubit pairs."""
200
199
  return {(q0, q1): self.xeb_error(q0, q1) for q0, q1 in self.all_qubit_pairs}
201
200
 
@@ -219,7 +218,7 @@ class TwoQubitXEBResult:
219
218
  return ax
220
219
 
221
220
  @cached_method
222
- def pauli_error(self) -> Dict[Tuple['cirq.GridQubit', 'cirq.GridQubit'], float]:
221
+ def pauli_error(self) -> Dict[Tuple[cirq.GridQubit, cirq.GridQubit], float]:
223
222
  """Return the Pauli error of all qubit pairs."""
224
223
  return {
225
224
  pair: noise_utils.decay_constant_to_pauli_error(
@@ -242,33 +241,33 @@ class InferredXEBResult:
242
241
  xeb_result: TwoQubitXEBResult
243
242
 
244
243
  @property
245
- def all_qubit_pairs(self) -> Sequence[Tuple['cirq.GridQubit', 'cirq.GridQubit']]:
244
+ def all_qubit_pairs(self) -> Sequence[Tuple[cirq.GridQubit, cirq.GridQubit]]:
246
245
  return self.xeb_result.all_qubit_pairs
247
246
 
248
247
  @cached_method
249
- def single_qubit_pauli_error(self) -> Mapping['cirq.Qid', float]:
248
+ def single_qubit_pauli_error(self) -> Mapping[cirq.Qid, float]:
250
249
  """Return the single-qubit Pauli error for all qubits (RB results)."""
251
250
  return self.rb_result.pauli_error()
252
251
 
253
252
  @cached_method
254
- def two_qubit_pauli_error(self) -> Mapping[Tuple['cirq.GridQubit', 'cirq.GridQubit'], float]:
253
+ def two_qubit_pauli_error(self) -> Mapping[Tuple[cirq.GridQubit, cirq.GridQubit], float]:
255
254
  """Return the two-qubit Pauli error for all pairs."""
256
255
  return MappingProxyType(self.xeb_result.pauli_error())
257
256
 
258
257
  @cached_method
259
- def inferred_pauli_error(self) -> Mapping[Tuple['cirq.GridQubit', 'cirq.GridQubit'], float]:
258
+ def inferred_pauli_error(self) -> Mapping[Tuple[cirq.GridQubit, cirq.GridQubit], float]:
260
259
  """Return the inferred Pauli error for all pairs."""
261
260
  single_q_paulis = self.rb_result.pauli_error()
262
261
  xeb = self.xeb_result.pauli_error()
263
262
 
264
- def _pauli_error(q0: 'cirq.GridQubit', q1: 'cirq.GridQubit') -> float:
263
+ def _pauli_error(q0: cirq.GridQubit, q1: cirq.GridQubit) -> float:
265
264
  q0, q1 = sorted([q0, q1])
266
265
  return xeb[(q0, q1)] - single_q_paulis[q0] - single_q_paulis[q1]
267
266
 
268
267
  return MappingProxyType({pair: _pauli_error(*pair) for pair in self.all_qubit_pairs})
269
268
 
270
269
  @cached_method
271
- def inferred_decay_constant(self) -> Mapping[Tuple['cirq.GridQubit', 'cirq.GridQubit'], float]:
270
+ def inferred_decay_constant(self) -> Mapping[Tuple[cirq.GridQubit, cirq.GridQubit], float]:
272
271
  """Return the inferred decay constant for all pairs."""
273
272
  return MappingProxyType(
274
273
  {
@@ -278,7 +277,7 @@ class InferredXEBResult:
278
277
  )
279
278
 
280
279
  @cached_method
281
- def inferred_xeb_error(self) -> Mapping[Tuple['cirq.GridQubit', 'cirq.GridQubit'], float]:
280
+ def inferred_xeb_error(self) -> Mapping[Tuple[cirq.GridQubit, cirq.GridQubit], float]:
282
281
  """Return the inferred XEB error for all pairs."""
283
282
  return MappingProxyType(
284
283
  {
@@ -289,7 +288,7 @@ class InferredXEBResult:
289
288
 
290
289
  def _target_errors(
291
290
  self, target_error: str
292
- ) -> Mapping[Tuple['cirq.GridQubit', 'cirq.GridQubit'], float]:
291
+ ) -> Mapping[Tuple[cirq.GridQubit, cirq.GridQubit], float]:
293
292
  """Returns requested error.
294
293
 
295
294
  The requested error must be one of 'pauli', 'decay_constant', or 'xeb'.
@@ -393,21 +392,21 @@ class InferredXEBResult:
393
392
 
394
393
 
395
394
  def parallel_xeb_workflow(
396
- sampler: 'cirq.Sampler',
397
- qubits: Optional[Sequence['cirq.GridQubit']] = None,
398
- entangling_gate: 'cirq.Gate' = ops.CZ,
395
+ sampler: cirq.Sampler,
396
+ qubits: Optional[Sequence[cirq.GridQubit]] = None,
397
+ entangling_gate: cirq.Gate = ops.CZ,
399
398
  n_repetitions: int = 10**4,
400
399
  n_combinations: int = 10,
401
400
  n_circuits: int = 20,
402
401
  cycle_depths: Sequence[int] = (5, 25, 50, 100, 200, 300),
403
- random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
402
+ random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
404
403
  ax: Optional[plt.Axes] = None,
405
- pairs: Optional[Sequence[tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None,
406
- pool: Optional['multiprocessing.pool.Pool'] = None,
404
+ pairs: Optional[Sequence[tuple[cirq.GridQubit, cirq.GridQubit]]] = None,
405
+ pool: Optional[multiprocessing.pool.Pool] = None,
407
406
  batch_size: int = 9,
408
407
  tags: Sequence[Any] = (),
409
408
  **plot_kwargs,
410
- ) -> Tuple[pd.DataFrame, Sequence['cirq.Circuit'], pd.DataFrame]:
409
+ ) -> Tuple[pd.DataFrame, Sequence[cirq.Circuit], pd.DataFrame]:
411
410
  """A utility method that runs the full XEB workflow.
412
411
 
413
412
  Args:
@@ -483,16 +482,16 @@ def parallel_xeb_workflow(
483
482
 
484
483
 
485
484
  def parallel_two_qubit_xeb(
486
- sampler: 'cirq.Sampler',
487
- qubits: Optional[Sequence['cirq.GridQubit']] = None,
488
- entangling_gate: 'cirq.Gate' = ops.CZ,
485
+ sampler: cirq.Sampler,
486
+ qubits: Optional[Sequence[cirq.GridQubit]] = None,
487
+ entangling_gate: cirq.Gate = ops.CZ,
489
488
  n_repetitions: int = 10**4,
490
489
  n_combinations: int = 10,
491
490
  n_circuits: int = 20,
492
491
  cycle_depths: Sequence[int] = (5, 25, 50, 100, 200, 300),
493
- random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
492
+ random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
494
493
  ax: Optional[plt.Axes] = None,
495
- pairs: Optional[Sequence[tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None,
494
+ pairs: Optional[Sequence[tuple[cirq.GridQubit, cirq.GridQubit]]] = None,
496
495
  batch_size: int = 9,
497
496
  tags: Sequence[Any] = (),
498
497
  **plot_kwargs,
@@ -540,18 +539,18 @@ def parallel_two_qubit_xeb(
540
539
 
541
540
 
542
541
  def run_rb_and_xeb(
543
- sampler: 'cirq.Sampler',
544
- qubits: Optional[Sequence['cirq.GridQubit']] = None,
542
+ sampler: cirq.Sampler,
543
+ qubits: Optional[Sequence[cirq.GridQubit]] = None,
545
544
  repetitions: int = 10**3,
546
545
  num_circuits: int = 20,
547
546
  num_clifford_range: Sequence[int] = tuple(
548
547
  np.logspace(np.log10(5), np.log10(1000), 5, dtype=int)
549
548
  ),
550
- entangling_gate: 'cirq.Gate' = ops.CZ,
549
+ entangling_gate: cirq.Gate = ops.CZ,
551
550
  depths_xeb: Sequence[int] = (5, 25, 50, 100, 200, 300),
552
551
  xeb_combinations: int = 10,
553
- random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
554
- pairs: Optional[Sequence[tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None,
552
+ random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
553
+ pairs: Optional[Sequence[tuple[cirq.GridQubit, cirq.GridQubit]]] = None,
555
554
  batch_size: int = 9,
556
555
  tags: Sequence[Any] = (),
557
556
  ) -> InferredXEBResult:
@@ -26,7 +26,7 @@ import cirq
26
26
  from cirq.experiments.qubit_characterizations import ParallelRandomizedBenchmarkingResult
27
27
 
28
28
 
29
- def _manhattan_distance(qubit1: 'cirq.GridQubit', qubit2: 'cirq.GridQubit') -> int:
29
+ def _manhattan_distance(qubit1: cirq.GridQubit, qubit2: cirq.GridQubit) -> int:
30
30
  return abs(qubit1.row - qubit2.row) + abs(qubit1.col - qubit2.col)
31
31
 
32
32
 
@@ -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
  """Estimation of fidelity associated with experimental circuit executions."""
16
+
17
+ from __future__ import annotations
18
+
15
19
  import dataclasses
16
20
  from abc import ABC, abstractmethod
17
21
  from typing import Dict, Iterable, List, Optional, Sequence, Tuple, TYPE_CHECKING
@@ -41,10 +45,10 @@ THETA_SYMBOL, ZETA_SYMBOL, CHI_SYMBOL, GAMMA_SYMBOL, PHI_SYMBOL = sympy.symbols(
41
45
 
42
46
  def benchmark_2q_xeb_fidelities(
43
47
  sampled_df: pd.DataFrame,
44
- circuits: Sequence['cirq.Circuit'],
48
+ circuits: Sequence[cirq.Circuit],
45
49
  cycle_depths: Optional[Sequence[int]] = None,
46
- param_resolver: 'cirq.ParamResolverOrSimilarType' = None,
47
- pool: Optional['multiprocessing.pool.Pool'] = None,
50
+ param_resolver: cirq.ParamResolverOrSimilarType = None,
51
+ pool: Optional[multiprocessing.pool.Pool] = None,
48
52
  ) -> pd.DataFrame:
49
53
  """Simulate and benchmark two-qubit XEB circuits.
50
54
 
@@ -144,11 +148,11 @@ def benchmark_2q_xeb_fidelities(
144
148
  class XEBCharacterizationOptions(ABC):
145
149
  @staticmethod
146
150
  @abstractmethod
147
- def should_parameterize(op: 'cirq.Operation') -> bool:
151
+ def should_parameterize(op: cirq.Operation) -> bool:
148
152
  """Whether to replace `op` with a parameterized version."""
149
153
 
150
154
  @abstractmethod
151
- def get_parameterized_gate(self) -> 'cirq.Gate':
155
+ def get_parameterized_gate(self) -> cirq.Gate:
152
156
  """The parameterized gate to use."""
153
157
 
154
158
  @abstractmethod
@@ -158,7 +162,7 @@ class XEBCharacterizationOptions(ABC):
158
162
  """Return an initial Nelder-Mead simplex and the names for each parameter."""
159
163
 
160
164
 
161
- def _try_defaults_from_unitary(gate: 'cirq.Gate') -> Optional[Dict[str, 'cirq.TParamVal']]:
165
+ def _try_defaults_from_unitary(gate: cirq.Gate) -> Optional[Dict[str, cirq.TParamVal]]:
162
166
  r"""Try to figure out the PhasedFSim angles from the unitary of the gate.
163
167
 
164
168
  The unitary of a PhasedFSimGate has the form:
@@ -221,10 +225,10 @@ def _try_defaults_from_unitary(gate: 'cirq.Gate') -> Optional[Dict[str, 'cirq.TP
221
225
  return None
222
226
 
223
227
 
224
- def phased_fsim_angles_from_gate(gate: 'cirq.Gate') -> Dict[str, 'cirq.TParamVal']:
228
+ def phased_fsim_angles_from_gate(gate: cirq.Gate) -> Dict[str, cirq.TParamVal]:
225
229
  """For a given gate, return a dictionary mapping '{angle}_default' to its noiseless value
226
230
  for the five PhasedFSim angles."""
227
- defaults: Dict[str, 'cirq.TParamVal'] = {
231
+ defaults: Dict[str, cirq.TParamVal] = {
228
232
  'theta_default': 0.0,
229
233
  'zeta_default': 0.0,
230
234
  'chi_default': 0.0,
@@ -290,7 +294,7 @@ class XEBPhasedFSimCharacterizationOptions(XEBCharacterizationOptions):
290
294
  gamma_default: Optional[float] = None
291
295
  phi_default: Optional[float] = None
292
296
 
293
- def _iter_angles(self) -> Iterable[Tuple[bool, Optional[float], 'sympy.Symbol']]:
297
+ def _iter_angles(self) -> Iterable[Tuple[bool, Optional[float], sympy.Symbol]]:
294
298
  yield from (
295
299
  (self.characterize_theta, self.theta_default, THETA_SYMBOL),
296
300
  (self.characterize_zeta, self.zeta_default, ZETA_SYMBOL),
@@ -299,7 +303,7 @@ class XEBPhasedFSimCharacterizationOptions(XEBCharacterizationOptions):
299
303
  (self.characterize_phi, self.phi_default, PHI_SYMBOL),
300
304
  )
301
305
 
302
- def _iter_angles_for_characterization(self) -> Iterable[Tuple[Optional[float], 'sympy.Symbol']]:
306
+ def _iter_angles_for_characterization(self) -> Iterable[Tuple[Optional[float], sympy.Symbol]]:
303
307
  yield from (
304
308
  (default, symbol)
305
309
  for characterize, default, symbol in self._iter_angles()
@@ -347,7 +351,7 @@ class XEBPhasedFSimCharacterizationOptions(XEBCharacterizationOptions):
347
351
  return ops.PhasedFSimGate(theta=theta, zeta=zeta, chi=chi, gamma=gamma, phi=phi)
348
352
 
349
353
  @staticmethod
350
- def should_parameterize(op: 'cirq.Operation') -> bool:
354
+ def should_parameterize(op: cirq.Operation) -> bool:
351
355
  return isinstance(op.gate, (ops.PhasedFSimGate, ops.ISwapPowGate, ops.FSimGate))
352
356
 
353
357
  def defaults_set(self) -> bool:
@@ -369,7 +373,7 @@ class XEBPhasedFSimCharacterizationOptions(XEBCharacterizationOptions):
369
373
  return False
370
374
 
371
375
  def with_defaults_from_gate(
372
- self, gate: 'cirq.Gate', gate_to_angles_func=phased_fsim_angles_from_gate
376
+ self, gate: cirq.Gate, gate_to_angles_func=phased_fsim_angles_from_gate
373
377
  ):
374
378
  """A new Options class with {angle}_defaults inferred from `gate`.
375
379
 
@@ -397,10 +401,10 @@ def SqrtISwapXEBOptions(*args, **kwargs):
397
401
 
398
402
 
399
403
  def parameterize_circuit(
400
- circuit: 'cirq.Circuit',
404
+ circuit: cirq.Circuit,
401
405
  options: XEBCharacterizationOptions,
402
406
  target_gatefamily: Optional[ops.GateFamily] = None,
403
- ) -> 'cirq.Circuit':
407
+ ) -> cirq.Circuit:
404
408
  """Parameterize PhasedFSim-like gates in a given circuit according to
405
409
  `phased_fsim_options`.
406
410
  """
@@ -432,21 +436,21 @@ class XEBCharacterizationResult:
432
436
  fitting the characterization.
433
437
  """
434
438
 
435
- optimization_results: Dict[QPair_T, 'scipy.optimize.OptimizeResult']
439
+ optimization_results: Dict[QPair_T, scipy.optimize.OptimizeResult]
436
440
  final_params: Dict[QPair_T, Dict[str, float]]
437
441
  fidelities_df: pd.DataFrame
438
442
 
439
443
 
440
444
  def characterize_phased_fsim_parameters_with_xeb(
441
445
  sampled_df: pd.DataFrame,
442
- parameterized_circuits: List['cirq.Circuit'],
446
+ parameterized_circuits: List[cirq.Circuit],
443
447
  cycle_depths: Sequence[int],
444
448
  options: XEBCharacterizationOptions,
445
449
  initial_simplex_step_size: float = 0.1,
446
450
  xatol: float = 1e-3,
447
451
  fatol: float = 1e-3,
448
452
  verbose: bool = True,
449
- pool: Optional['multiprocessing.pool.Pool'] = None,
453
+ pool: Optional[multiprocessing.pool.Pool] = None,
450
454
  ) -> XEBCharacterizationResult:
451
455
  """Run a classical optimization to fit phased fsim parameters to experimental data, and
452
456
  thereby characterize PhasedFSim-like gates.
@@ -496,7 +500,7 @@ def characterize_phased_fsim_parameters_with_xeb(
496
500
  method='nelder-mead',
497
501
  )
498
502
 
499
- final_params: 'cirq.ParamDictType' = dict(zip(names, optimization_result.x))
503
+ final_params: cirq.ParamDictType = dict(zip(names, optimization_result.x))
500
504
  fidelities_df = benchmark_2q_xeb_fidelities(
501
505
  sampled_df, parameterized_circuits, cycle_depths, param_resolver=final_params
502
506
  )
@@ -512,7 +516,7 @@ class _CharacterizePhasedFsimParametersWithXebClosure:
512
516
  """A closure object to wrap `characterize_phased_fsim_parameters_with_xeb` for use in
513
517
  multiprocessing."""
514
518
 
515
- parameterized_circuits: List['cirq.Circuit']
519
+ parameterized_circuits: List[cirq.Circuit]
516
520
  cycle_depths: Sequence[int]
517
521
  options: XEBCharacterizationOptions
518
522
  initial_simplex_step_size: float = 0.1
@@ -535,13 +539,13 @@ class _CharacterizePhasedFsimParametersWithXebClosure:
535
539
 
536
540
  def characterize_phased_fsim_parameters_with_xeb_by_pair(
537
541
  sampled_df: pd.DataFrame,
538
- parameterized_circuits: List['cirq.Circuit'],
542
+ parameterized_circuits: List[cirq.Circuit],
539
543
  cycle_depths: Sequence[int],
540
544
  options: XEBCharacterizationOptions,
541
545
  initial_simplex_step_size: float = 0.1,
542
546
  xatol: float = 1e-3,
543
547
  fatol: float = 1e-3,
544
- pool: Optional['multiprocessing.pool.Pool'] = None,
548
+ pool: Optional[multiprocessing.pool.Pool] = None,
545
549
  ) -> XEBCharacterizationResult:
546
550
  """Run a classical optimization to fit phased fsim parameters to experimental data, and
547
551
  thereby characterize PhasedFSim-like gates grouped by pairs.
@@ -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
  """Estimation of fidelity associated with experimental circuit executions."""
16
+
17
+ from __future__ import annotations
18
+
15
19
  import os
16
20
  import time
17
21
  import uuid
@@ -52,14 +56,14 @@ class _Sample2qXEBTask:
52
56
  cycle_depth: int
53
57
  layer_i: int
54
58
  combination_i: int
55
- prepared_circuit: 'cirq.AbstractCircuit'
59
+ prepared_circuit: cirq.AbstractCircuit
56
60
  combination: List[int]
57
61
 
58
62
 
59
63
  class _SampleInBatches:
60
64
  def __init__(
61
65
  self,
62
- sampler: 'cirq.Sampler',
66
+ sampler: cirq.Sampler,
63
67
  repetitions: int,
64
68
  combinations_by_layer: List[CircuitLibraryCombination],
65
69
  ):
@@ -107,9 +111,9 @@ class _SampleInBatches:
107
111
  return records
108
112
 
109
113
 
110
- def _verify_and_get_two_qubits_from_circuits(circuits: Sequence['cirq.Circuit']):
114
+ def _verify_and_get_two_qubits_from_circuits(circuits: Sequence[cirq.Circuit]):
111
115
  """Make sure each of the provided circuits uses the same two qubits and return them."""
112
- all_qubits_set: Set['cirq.Qid'] = set()
116
+ all_qubits_set: Set[cirq.Qid] = set()
113
117
  all_qubits_set = all_qubits_set.union(*(circuit.all_qubits() for circuit in circuits))
114
118
  all_qubits_list = sorted(all_qubits_set)
115
119
  if len(all_qubits_list) != 2:
@@ -119,7 +123,7 @@ def _verify_and_get_two_qubits_from_circuits(circuits: Sequence['cirq.Circuit'])
119
123
  return all_qubits_list
120
124
 
121
125
 
122
- def _verify_two_line_qubits_from_circuits(circuits: Sequence['cirq.Circuit']):
126
+ def _verify_two_line_qubits_from_circuits(circuits: Sequence[cirq.Circuit]):
123
127
  if _verify_and_get_two_qubits_from_circuits(circuits) != devices.LineQubit.range(2):
124
128
  raise ValueError(
125
129
  "`circuits` should be a sequence of circuits each operating "
@@ -165,16 +169,16 @@ class _ZippedCircuit:
165
169
  any behavior. It is propagated to the output result object.
166
170
  """
167
171
 
168
- wide_circuit: 'cirq.Circuit'
169
- pairs: List[Tuple['cirq.Qid', 'cirq.Qid']]
172
+ wide_circuit: cirq.Circuit
173
+ pairs: List[Tuple[cirq.Qid, cirq.Qid]]
170
174
  combination: List[int]
171
175
  layer_i: int
172
176
  combination_i: int
173
177
 
174
178
 
175
179
  def _get_combinations_by_layer_for_isolated_xeb(
176
- circuits: Sequence['cirq.Circuit'],
177
- ) -> Tuple[List[CircuitLibraryCombination], List['cirq.Circuit']]:
180
+ circuits: Sequence[cirq.Circuit],
181
+ ) -> Tuple[List[CircuitLibraryCombination], List[cirq.Circuit]]:
178
182
  """Helper function used in `sample_2q_xeb_circuits`.
179
183
 
180
184
  This creates a CircuitLibraryCombination object for isolated XEB. First, the qubits
@@ -195,7 +199,7 @@ def _get_combinations_by_layer_for_isolated_xeb(
195
199
 
196
200
 
197
201
  def _zip_circuits(
198
- circuits: Sequence['cirq.Circuit'], combinations_by_layer: List[CircuitLibraryCombination]
202
+ circuits: Sequence[cirq.Circuit], combinations_by_layer: List[CircuitLibraryCombination]
199
203
  ) -> List[_ZippedCircuit]:
200
204
  """Helper function used in `sample_2q_xeb_circuits` to zip together circuits.
201
205
 
@@ -260,7 +264,7 @@ def _generate_sample_2q_xeb_tasks(
260
264
 
261
265
  def _execute_sample_2q_xeb_tasks_in_batches(
262
266
  tasks: List[_Sample2qXEBTask],
263
- sampler: 'cirq.Sampler',
267
+ sampler: cirq.Sampler,
264
268
  combinations_by_layer: List[CircuitLibraryCombination],
265
269
  repetitions: int,
266
270
  batch_size: int,
@@ -288,15 +292,15 @@ def _execute_sample_2q_xeb_tasks_in_batches(
288
292
 
289
293
 
290
294
  def sample_2q_xeb_circuits(
291
- sampler: 'cirq.Sampler',
292
- circuits: Sequence['cirq.Circuit'],
295
+ sampler: cirq.Sampler,
296
+ circuits: Sequence[cirq.Circuit],
293
297
  cycle_depths: Sequence[int],
294
298
  *,
295
299
  repetitions: int = 10_000,
296
300
  batch_size: int = 9,
297
301
  progress_bar: Optional[Callable[..., ContextManager]] = tqdm.tqdm,
298
302
  combinations_by_layer: Optional[List[CircuitLibraryCombination]] = None,
299
- shuffle: Optional['cirq.RANDOM_STATE_OR_SEED_LIKE'] = None,
303
+ shuffle: Optional[cirq.RANDOM_STATE_OR_SEED_LIKE] = None,
300
304
  dataset_directory: Optional[str] = None,
301
305
  ):
302
306
  """Sample two-qubit XEB circuits given a sampler.
@@ -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
  """Estimation of fidelity associated with experimental circuit executions."""
16
+
17
+ from __future__ import annotations
18
+
15
19
  from dataclasses import dataclass
16
20
  from typing import Any, Dict, List, Optional, Sequence, TYPE_CHECKING
17
21
 
@@ -32,14 +36,14 @@ class _Simulate2qXEBTask:
32
36
 
33
37
  circuit_i: int
34
38
  cycle_depths: Sequence[int]
35
- circuit: 'cirq.Circuit'
36
- param_resolver: 'cirq.ParamResolverOrSimilarType'
39
+ circuit: cirq.Circuit
40
+ param_resolver: cirq.ParamResolverOrSimilarType
37
41
 
38
42
 
39
43
  class _Simulate_2q_XEB_Circuit:
40
44
  """Closure used in `simulate_2q_xeb_circuits` so it works with multiprocessing."""
41
45
 
42
- def __init__(self, simulator: 'cirq.SimulatesIntermediateState'):
46
+ def __init__(self, simulator: cirq.SimulatesIntermediateState):
43
47
  self.simulator = simulator
44
48
 
45
49
  def __call__(self, task: _Simulate2qXEBTask) -> List[Dict[str, Any]]:
@@ -77,11 +81,11 @@ class _Simulate_2q_XEB_Circuit:
77
81
 
78
82
 
79
83
  def simulate_2q_xeb_circuits(
80
- circuits: Sequence['cirq.Circuit'],
84
+ circuits: Sequence[cirq.Circuit],
81
85
  cycle_depths: Sequence[int],
82
- param_resolver: 'cirq.ParamResolverOrSimilarType' = None,
83
- pool: Optional['multiprocessing.pool.Pool'] = None,
84
- simulator: Optional['cirq.SimulatesIntermediateState'] = None,
86
+ param_resolver: cirq.ParamResolverOrSimilarType = None,
87
+ pool: Optional[multiprocessing.pool.Pool] = None,
88
+ simulator: Optional[cirq.SimulatesIntermediateState] = None,
85
89
  ):
86
90
  """Simulate two-qubit XEB circuits.
87
91
 
@@ -95,10 +95,10 @@ def _ref_simulate_2q_xeb_circuit(task: Dict[str, Any]):
95
95
 
96
96
 
97
97
  def _ref_simulate_2q_xeb_circuits(
98
- circuits: Sequence['cirq.Circuit'],
98
+ circuits: Sequence[cirq.Circuit],
99
99
  cycle_depths: Sequence[int],
100
- param_resolver: 'cirq.ParamResolverOrSimilarType' = None,
101
- pool: Optional['multiprocessing.pool.Pool'] = None,
100
+ param_resolver: cirq.ParamResolverOrSimilarType = None,
101
+ pool: Optional[multiprocessing.pool.Pool] = None,
102
102
  ):
103
103
  """Reference implementation for `simulate_2q_xeb_circuits` that
104
104
  does each circuit independently instead of using intermediate states.