cirq-core 1.6.0.dev20250520054601__py3-none-any.whl → 1.6.0.dev20250520181654__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.
- cirq/_compat.py +15 -17
- cirq/_compat_test.py +6 -9
- cirq/_doc.py +2 -2
- cirq/_import.py +6 -6
- cirq/_version.py +1 -1
- cirq/_version_test.py +1 -1
- cirq/circuits/_block_diagram_drawer.py +9 -10
- cirq/circuits/_box_drawing_character_data.py +6 -8
- cirq/circuits/_bucket_priority_queue.py +7 -7
- cirq/circuits/circuit.py +118 -125
- cirq/circuits/circuit_operation.py +38 -52
- cirq/circuits/circuit_test.py +4 -4
- cirq/circuits/frozen_circuit.py +13 -23
- cirq/circuits/moment.py +23 -29
- cirq/circuits/optimization_pass.py +4 -4
- cirq/circuits/optimization_pass_test.py +4 -6
- cirq/circuits/qasm_output.py +11 -11
- cirq/circuits/text_diagram_drawer.py +21 -36
- cirq/contrib/acquaintance/bipartite.py +5 -8
- cirq/contrib/acquaintance/executor.py +5 -5
- cirq/contrib/acquaintance/executor_test.py +3 -3
- cirq/contrib/acquaintance/gates.py +16 -26
- cirq/contrib/acquaintance/gates_test.py +3 -3
- cirq/contrib/acquaintance/mutation_utils.py +4 -4
- cirq/contrib/acquaintance/optimizers.py +4 -4
- cirq/contrib/acquaintance/permutation.py +15 -27
- cirq/contrib/acquaintance/shift.py +3 -3
- cirq/contrib/acquaintance/shift_swap_network.py +4 -4
- cirq/contrib/acquaintance/strategies/cubic.py +2 -2
- cirq/contrib/acquaintance/strategies/quartic_paired.py +6 -6
- cirq/contrib/bayesian_network/bayesian_network_gate.py +9 -10
- cirq/contrib/circuitdag/circuit_dag.py +2 -2
- cirq/contrib/custom_simulators/custom_state_simulator.py +3 -3
- cirq/contrib/custom_simulators/custom_state_simulator_test.py +4 -4
- cirq/contrib/graph_device/graph_device.py +5 -5
- cirq/contrib/graph_device/hypergraph.py +12 -12
- cirq/contrib/graph_device/uniform_graph_device.py +4 -4
- cirq/contrib/paulistring/clifford_optimize.py +2 -2
- cirq/contrib/paulistring/clifford_target_gateset.py +7 -7
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +31 -31
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +23 -23
- cirq/contrib/paulistring/recombine.py +3 -3
- cirq/contrib/paulistring/separate.py +2 -2
- cirq/contrib/qasm_import/_parser.py +20 -32
- cirq/contrib/qcircuit/qcircuit_diagram_info.py +3 -5
- cirq/contrib/quantum_volume/quantum_volume.py +24 -24
- cirq/contrib/quimb/density_matrix.py +12 -14
- cirq/contrib/quimb/mps_simulator.py +20 -20
- cirq/contrib/quimb/state_vector.py +6 -10
- cirq/contrib/quirk/export_to_quirk.py +3 -3
- cirq/contrib/quirk/quirk_gate.py +15 -15
- cirq/contrib/routing/device.py +3 -3
- cirq/contrib/routing/greedy.py +10 -21
- cirq/contrib/routing/initialization.py +2 -2
- cirq/contrib/routing/swap_network.py +3 -3
- cirq/contrib/routing/utils.py +2 -2
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +8 -8
- cirq/contrib/svg/svg.py +3 -3
- cirq/devices/grid_device_metadata.py +10 -10
- cirq/devices/grid_qubit.py +20 -20
- cirq/devices/insertion_noise_model.py +5 -5
- cirq/devices/line_qubit.py +13 -13
- cirq/devices/named_topologies.py +18 -29
- cirq/devices/noise_model.py +3 -3
- cirq/devices/noise_properties.py +2 -2
- cirq/devices/noise_properties_test.py +1 -3
- cirq/devices/noise_utils.py +7 -7
- cirq/devices/superconducting_qubits_noise_properties.py +21 -21
- cirq/devices/superconducting_qubits_noise_properties_test.py +5 -7
- cirq/devices/thermal_noise_model.py +14 -14
- cirq/devices/unconstrained_device.py +2 -2
- cirq/experiments/benchmarking/parallel_xeb.py +29 -31
- cirq/experiments/n_qubit_tomography.py +5 -7
- cirq/experiments/qubit_characterizations.py +29 -40
- cirq/experiments/qubit_characterizations_test.py +1 -1
- cirq/experiments/random_quantum_circuit_generation.py +19 -33
- cirq/experiments/random_quantum_circuit_generation_test.py +6 -6
- cirq/experiments/readout_confusion_matrix.py +14 -14
- cirq/experiments/single_qubit_readout_calibration.py +12 -12
- cirq/experiments/t2_decay_experiment.py +7 -7
- cirq/experiments/two_qubit_xeb.py +32 -32
- cirq/experiments/two_qubit_xeb_test.py +5 -5
- cirq/experiments/xeb_fitting.py +25 -25
- cirq/experiments/xeb_sampling.py +22 -33
- cirq/experiments/xeb_simulation.py +5 -5
- cirq/experiments/xeb_simulation_test.py +3 -3
- cirq/experiments/z_phase_calibration.py +19 -19
- cirq/interop/quirk/cells/arithmetic_cells.py +23 -36
- cirq/interop/quirk/cells/cell.py +9 -21
- cirq/interop/quirk/cells/composite_cell.py +7 -22
- cirq/interop/quirk/cells/control_cells.py +8 -8
- cirq/interop/quirk/cells/input_cells.py +4 -4
- cirq/interop/quirk/cells/input_rotation_cells.py +5 -5
- cirq/interop/quirk/cells/parse.py +20 -23
- cirq/interop/quirk/cells/qubit_permutation_cells.py +3 -3
- cirq/interop/quirk/cells/swap_cell.py +3 -3
- cirq/interop/quirk/cells/testing.py +5 -7
- cirq/interop/quirk/url_to_circuit.py +17 -33
- cirq/json_resolver_cache.py +6 -6
- cirq/linalg/decompositions.py +20 -31
- cirq/linalg/diagonalize.py +4 -4
- cirq/linalg/diagonalize_test.py +3 -4
- cirq/linalg/operator_spaces.py +5 -5
- cirq/linalg/predicates.py +7 -7
- cirq/linalg/transformations.py +20 -20
- cirq/ops/arithmetic_operation.py +13 -15
- cirq/ops/boolean_hamiltonian.py +17 -17
- cirq/ops/classically_controlled_operation.py +13 -25
- cirq/ops/clifford_gate.py +31 -35
- cirq/ops/clifford_gate_test.py +2 -3
- cirq/ops/common_channels.py +30 -32
- cirq/ops/common_gates.py +64 -74
- cirq/ops/control_values.py +12 -12
- cirq/ops/controlled_gate.py +15 -30
- cirq/ops/controlled_gate_test.py +5 -5
- cirq/ops/controlled_operation.py +12 -25
- cirq/ops/controlled_operation_test.py +5 -5
- cirq/ops/dense_pauli_string.py +23 -34
- cirq/ops/dense_pauli_string_test.py +1 -2
- cirq/ops/diagonal_gate.py +9 -20
- cirq/ops/diagonal_gate_test.py +1 -3
- cirq/ops/eigen_gate.py +11 -23
- cirq/ops/eigen_gate_test.py +6 -8
- cirq/ops/fourier_transform.py +5 -5
- cirq/ops/fsim_gate.py +14 -14
- cirq/ops/gate_operation.py +23 -44
- cirq/ops/gateset.py +23 -37
- cirq/ops/gateset_test.py +2 -2
- cirq/ops/global_phase_op.py +8 -10
- cirq/ops/greedy_qubit_manager.py +6 -6
- cirq/ops/identity.py +9 -9
- cirq/ops/kraus_channel.py +7 -7
- cirq/ops/linear_combinations.py +29 -48
- cirq/ops/matrix_gates.py +8 -8
- cirq/ops/measure_util.py +13 -14
- cirq/ops/measurement_gate.py +18 -29
- cirq/ops/mixed_unitary_channel.py +8 -8
- cirq/ops/named_qubit.py +10 -10
- cirq/ops/op_tree.py +7 -7
- cirq/ops/parallel_gate.py +5 -5
- cirq/ops/parity_gates.py +14 -14
- cirq/ops/pauli_gates.py +8 -10
- cirq/ops/pauli_interaction_gate.py +6 -6
- cirq/ops/pauli_measurement_gate.py +11 -23
- cirq/ops/pauli_string.py +35 -52
- cirq/ops/pauli_string_phasor.py +4 -14
- cirq/ops/pauli_string_raw_types.py +3 -3
- cirq/ops/pauli_sum_exponential.py +2 -2
- cirq/ops/permutation_gate.py +4 -4
- cirq/ops/phased_iswap_gate.py +9 -9
- cirq/ops/phased_x_gate.py +10 -10
- cirq/ops/phased_x_z_gate.py +11 -11
- cirq/ops/projector.py +6 -6
- cirq/ops/qubit_manager.py +6 -6
- cirq/ops/qubit_order.py +3 -3
- cirq/ops/random_gate_channel.py +4 -4
- cirq/ops/raw_types.py +48 -70
- cirq/ops/state_preparation_channel.py +3 -3
- cirq/ops/swap_gates.py +9 -9
- cirq/ops/tags.py +2 -4
- cirq/ops/three_qubit_gates.py +20 -38
- cirq/ops/two_qubit_diagonal_gate.py +5 -5
- cirq/ops/uniform_superposition_gate.py +2 -2
- cirq/ops/wait_gate.py +5 -5
- cirq/protocols/act_on_protocol_test.py +3 -3
- cirq/protocols/apply_channel_protocol.py +8 -14
- cirq/protocols/apply_mixture_protocol.py +14 -16
- cirq/protocols/apply_mixture_protocol_test.py +5 -6
- cirq/protocols/apply_unitary_protocol.py +17 -19
- cirq/protocols/circuit_diagram_info_protocol.py +19 -30
- cirq/protocols/decompose_protocol.py +30 -34
- cirq/protocols/inverse_protocol.py +7 -7
- cirq/protocols/json_serialization.py +32 -51
- cirq/protocols/json_serialization_test.py +9 -10
- cirq/protocols/kraus_protocol.py +4 -4
- cirq/protocols/kraus_protocol_test.py +3 -3
- cirq/protocols/measurement_key_protocol.py +11 -13
- cirq/protocols/mixture_protocol.py +4 -4
- cirq/protocols/qasm.py +11 -13
- cirq/protocols/qid_shape_protocol.py +6 -8
- cirq/qis/clifford_tableau.py +12 -12
- cirq/qis/measures.py +7 -7
- cirq/qis/quantum_state_representation.py +3 -3
- cirq/qis/states.py +51 -51
- cirq/sim/classical_simulator.py +10 -10
- cirq/sim/clifford/clifford_simulator.py +6 -6
- cirq/sim/clifford/clifford_tableau_simulation_state_test.py +1 -3
- cirq/sim/clifford/stabilizer_sampler.py +4 -4
- cirq/sim/clifford/stabilizer_state_ch_form.py +3 -3
- cirq/sim/density_matrix_simulation_state.py +15 -15
- cirq/sim/density_matrix_simulator.py +11 -11
- cirq/sim/density_matrix_utils.py +9 -9
- cirq/sim/mux.py +9 -9
- cirq/sim/simulation_product_state.py +9 -9
- cirq/sim/simulation_product_state_test.py +2 -2
- cirq/sim/simulation_state.py +14 -27
- cirq/sim/simulation_state_base.py +8 -24
- cirq/sim/simulation_utils.py +3 -4
- cirq/sim/simulator.py +28 -43
- cirq/sim/simulator_base.py +12 -25
- cirq/sim/simulator_base_test.py +6 -6
- cirq/sim/simulator_test.py +7 -7
- cirq/sim/sparse_simulator.py +8 -8
- cirq/sim/state_vector.py +8 -8
- cirq/sim/state_vector_simulation_state.py +17 -17
- cirq/sim/state_vector_simulator.py +4 -4
- cirq/study/flatten_expressions.py +12 -14
- cirq/study/resolver.py +9 -11
- cirq/study/result.py +11 -24
- cirq/study/sweepable.py +5 -5
- cirq/study/sweeps.py +27 -40
- cirq/testing/circuit_compare.py +5 -5
- cirq/testing/consistent_controlled_gate_op_test.py +7 -11
- cirq/testing/consistent_protocols.py +10 -10
- cirq/testing/consistent_protocols_test.py +7 -7
- cirq/testing/consistent_qasm.py +4 -4
- cirq/testing/consistent_qasm_test.py +2 -3
- cirq/testing/devices.py +4 -5
- cirq/testing/equals_tester.py +2 -2
- cirq/testing/equivalent_basis_map.py +4 -4
- cirq/testing/equivalent_repr_eval.py +3 -3
- cirq/testing/json.py +14 -14
- cirq/testing/logs.py +3 -3
- cirq/testing/no_identifier_qubit.py +2 -3
- cirq/testing/random_circuit.py +7 -7
- cirq/testing/random_circuit_test.py +3 -3
- cirq/transformers/analytical_decompositions/clifford_decomposition.py +16 -16
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +13 -13
- cirq/transformers/analytical_decompositions/cphase_to_fsim.py +5 -5
- cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +3 -3
- cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +3 -3
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +4 -4
- cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +6 -7
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +2 -2
- cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +7 -7
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +4 -4
- cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +7 -7
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +11 -11
- cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +5 -5
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +14 -14
- cirq/transformers/dynamical_decoupling.py +13 -13
- cirq/transformers/dynamical_decoupling_test.py +4 -4
- cirq/transformers/eject_phased_paulis.py +16 -16
- cirq/transformers/eject_z.py +5 -7
- cirq/transformers/gauge_compiling/gauge_compiling.py +38 -38
- cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +2 -2
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +8 -8
- cirq/transformers/insertion_sort.py +5 -5
- cirq/transformers/measurement_transformers.py +14 -14
- cirq/transformers/merge_k_qubit_gates_test.py +1 -3
- cirq/transformers/merge_single_qubit_gates_test.py +1 -3
- cirq/transformers/qubit_management_transformers.py +5 -5
- cirq/transformers/routing/initial_mapper.py +4 -4
- cirq/transformers/routing/line_initial_mapper.py +9 -9
- cirq/transformers/routing/mapping_manager.py +7 -7
- cirq/transformers/routing/route_circuit_cqc.py +27 -27
- cirq/transformers/routing/visualize_routed_circuit.py +4 -4
- cirq/transformers/stratify.py +8 -8
- cirq/transformers/synchronize_terminal_measurements.py +6 -6
- cirq/transformers/target_gatesets/compilation_target_gateset.py +8 -8
- cirq/transformers/target_gatesets/compilation_target_gateset_test.py +2 -2
- cirq/transformers/target_gatesets/cz_gateset.py +4 -4
- cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +5 -5
- cirq/transformers/transformer_api.py +11 -26
- cirq/transformers/transformer_primitives.py +24 -36
- cirq/transformers/transformer_primitives_test.py +3 -3
- cirq/value/classical_data.py +18 -18
- cirq/value/condition.py +8 -8
- cirq/value/digits.py +7 -7
- cirq/value/duration.py +12 -12
- cirq/value/linear_dict.py +8 -12
- cirq/value/measurement_key.py +8 -8
- cirq/value/product_state.py +9 -9
- cirq/value/value_equality_attr.py +4 -4
- cirq/vis/heatmap.py +23 -35
- cirq/work/collector.py +9 -17
- cirq/work/observable_grouping.py +4 -7
- cirq/work/observable_measurement.py +29 -41
- cirq/work/observable_measurement_data.py +14 -14
- cirq/work/observable_measurement_test.py +2 -2
- cirq/work/observable_settings.py +9 -10
- cirq/work/pauli_sum_collector.py +5 -5
- cirq/work/sampler.py +17 -17
- cirq/work/zeros_sampler.py +3 -3
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520181654.dist-info}/METADATA +1 -1
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520181654.dist-info}/RECORD +289 -289
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520181654.dist-info}/WHEEL +1 -1
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520181654.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520181654.dist-info}/top_level.txt +0 -0
|
@@ -18,7 +18,7 @@ from __future__ import annotations
|
|
|
18
18
|
|
|
19
19
|
import io
|
|
20
20
|
import itertools
|
|
21
|
-
from typing import
|
|
21
|
+
from typing import Sequence
|
|
22
22
|
|
|
23
23
|
import matplotlib.pyplot as plt
|
|
24
24
|
import networkx as nx
|
|
@@ -90,7 +90,7 @@ def test_parallel_two_qubit_xeb_simulator_without_processor_fails():
|
|
|
90
90
|
),
|
|
91
91
|
],
|
|
92
92
|
)
|
|
93
|
-
def test_parallel_two_qubit_xeb(sampler: cirq.Sampler, qubits:
|
|
93
|
+
def test_parallel_two_qubit_xeb(sampler: cirq.Sampler, qubits: Sequence[cirq.GridQubit] | None):
|
|
94
94
|
res = cirq.experiments.parallel_two_qubit_xeb(
|
|
95
95
|
sampler=sampler,
|
|
96
96
|
qubits=qubits,
|
|
@@ -162,7 +162,7 @@ def test_pauli_error(q0: cirq.GridQubit, q1: cirq.GridQubit, pauli: float):
|
|
|
162
162
|
|
|
163
163
|
|
|
164
164
|
class MockParallelRandomizedBenchmarkingResult(ParallelRandomizedBenchmarkingResult):
|
|
165
|
-
def pauli_error(self) ->
|
|
165
|
+
def pauli_error(self) -> dict[cirq.Qid, float]:
|
|
166
166
|
return {
|
|
167
167
|
cirq.GridQubit(4, 4): 0.01,
|
|
168
168
|
cirq.GridQubit(5, 4): 0.02,
|
|
@@ -294,8 +294,8 @@ def test_inferred_plots(ax, target_error, kind):
|
|
|
294
294
|
)
|
|
295
295
|
def test_run_rb_and_xeb(
|
|
296
296
|
sampler: cirq.Sampler,
|
|
297
|
-
qubits:
|
|
298
|
-
pairs:
|
|
297
|
+
qubits: Sequence[cirq.GridQubit] | None,
|
|
298
|
+
pairs: Sequence[tuple[cirq.GridQubit, cirq.GridQubit]] | None,
|
|
299
299
|
):
|
|
300
300
|
res = cirq.experiments.run_rb_and_xeb(
|
|
301
301
|
sampler=sampler,
|
cirq/experiments/xeb_fitting.py
CHANGED
|
@@ -18,7 +18,7 @@ from __future__ import annotations
|
|
|
18
18
|
|
|
19
19
|
import dataclasses
|
|
20
20
|
from abc import ABC, abstractmethod
|
|
21
|
-
from typing import
|
|
21
|
+
from typing import Iterable, Sequence, TYPE_CHECKING
|
|
22
22
|
|
|
23
23
|
import numpy as np
|
|
24
24
|
import pandas as pd
|
|
@@ -46,9 +46,9 @@ THETA_SYMBOL, ZETA_SYMBOL, CHI_SYMBOL, GAMMA_SYMBOL, PHI_SYMBOL = sympy.symbols(
|
|
|
46
46
|
def benchmark_2q_xeb_fidelities(
|
|
47
47
|
sampled_df: pd.DataFrame,
|
|
48
48
|
circuits: Sequence[cirq.Circuit],
|
|
49
|
-
cycle_depths:
|
|
49
|
+
cycle_depths: Sequence[int] | None = None,
|
|
50
50
|
param_resolver: cirq.ParamResolverOrSimilarType = None,
|
|
51
|
-
pool:
|
|
51
|
+
pool: multiprocessing.pool.Pool | None = None,
|
|
52
52
|
) -> pd.DataFrame:
|
|
53
53
|
"""Simulate and benchmark two-qubit XEB circuits.
|
|
54
54
|
|
|
@@ -158,11 +158,11 @@ class XEBCharacterizationOptions(ABC):
|
|
|
158
158
|
@abstractmethod
|
|
159
159
|
def get_initial_simplex_and_names(
|
|
160
160
|
self, initial_simplex_step_size: float = 0.1
|
|
161
|
-
) ->
|
|
161
|
+
) -> tuple[np.ndarray, list[str]]:
|
|
162
162
|
"""Return an initial Nelder-Mead simplex and the names for each parameter."""
|
|
163
163
|
|
|
164
164
|
|
|
165
|
-
def _try_defaults_from_unitary(gate: cirq.Gate) ->
|
|
165
|
+
def _try_defaults_from_unitary(gate: cirq.Gate) -> dict[str, cirq.TParamVal] | None:
|
|
166
166
|
r"""Try to figure out the PhasedFSim angles from the unitary of the gate.
|
|
167
167
|
|
|
168
168
|
The unitary of a PhasedFSimGate has the form:
|
|
@@ -225,10 +225,10 @@ def _try_defaults_from_unitary(gate: cirq.Gate) -> Optional[Dict[str, cirq.TPara
|
|
|
225
225
|
return None
|
|
226
226
|
|
|
227
227
|
|
|
228
|
-
def phased_fsim_angles_from_gate(gate: cirq.Gate) ->
|
|
228
|
+
def phased_fsim_angles_from_gate(gate: cirq.Gate) -> dict[str, cirq.TParamVal]:
|
|
229
229
|
"""For a given gate, return a dictionary mapping '{angle}_default' to its noiseless value
|
|
230
230
|
for the five PhasedFSim angles."""
|
|
231
|
-
defaults:
|
|
231
|
+
defaults: dict[str, cirq.TParamVal] = {
|
|
232
232
|
'theta_default': 0.0,
|
|
233
233
|
'zeta_default': 0.0,
|
|
234
234
|
'chi_default': 0.0,
|
|
@@ -288,13 +288,13 @@ class XEBPhasedFSimCharacterizationOptions(XEBCharacterizationOptions):
|
|
|
288
288
|
characterize_gamma: bool = True
|
|
289
289
|
characterize_phi: bool = True
|
|
290
290
|
|
|
291
|
-
theta_default:
|
|
292
|
-
zeta_default:
|
|
293
|
-
chi_default:
|
|
294
|
-
gamma_default:
|
|
295
|
-
phi_default:
|
|
291
|
+
theta_default: float | None = None
|
|
292
|
+
zeta_default: float | None = None
|
|
293
|
+
chi_default: float | None = None
|
|
294
|
+
gamma_default: float | None = None
|
|
295
|
+
phi_default: float | None = None
|
|
296
296
|
|
|
297
|
-
def _iter_angles(self) -> Iterable[
|
|
297
|
+
def _iter_angles(self) -> Iterable[tuple[bool, float | None, sympy.Symbol]]:
|
|
298
298
|
yield from (
|
|
299
299
|
(self.characterize_theta, self.theta_default, THETA_SYMBOL),
|
|
300
300
|
(self.characterize_zeta, self.zeta_default, ZETA_SYMBOL),
|
|
@@ -303,7 +303,7 @@ class XEBPhasedFSimCharacterizationOptions(XEBCharacterizationOptions):
|
|
|
303
303
|
(self.characterize_phi, self.phi_default, PHI_SYMBOL),
|
|
304
304
|
)
|
|
305
305
|
|
|
306
|
-
def _iter_angles_for_characterization(self) -> Iterable[
|
|
306
|
+
def _iter_angles_for_characterization(self) -> Iterable[tuple[float | None, sympy.Symbol]]:
|
|
307
307
|
yield from (
|
|
308
308
|
(default, symbol)
|
|
309
309
|
for characterize, default, symbol in self._iter_angles()
|
|
@@ -312,7 +312,7 @@ class XEBPhasedFSimCharacterizationOptions(XEBCharacterizationOptions):
|
|
|
312
312
|
|
|
313
313
|
def get_initial_simplex_and_names(
|
|
314
314
|
self, initial_simplex_step_size: float = 0.1
|
|
315
|
-
) ->
|
|
315
|
+
) -> tuple[np.ndarray, list[str]]:
|
|
316
316
|
"""Get an initial simplex and parameter names for the optimization implied by these options.
|
|
317
317
|
|
|
318
318
|
The initial simplex initiates the Nelder-Mead optimization parameter. We
|
|
@@ -403,7 +403,7 @@ def SqrtISwapXEBOptions(*args, **kwargs):
|
|
|
403
403
|
def parameterize_circuit(
|
|
404
404
|
circuit: cirq.Circuit,
|
|
405
405
|
options: XEBCharacterizationOptions,
|
|
406
|
-
target_gatefamily:
|
|
406
|
+
target_gatefamily: ops.GateFamily | None = None,
|
|
407
407
|
) -> cirq.Circuit:
|
|
408
408
|
"""Parameterize PhasedFSim-like gates in a given circuit according to
|
|
409
409
|
`phased_fsim_options`.
|
|
@@ -421,7 +421,7 @@ def parameterize_circuit(
|
|
|
421
421
|
)
|
|
422
422
|
|
|
423
423
|
|
|
424
|
-
QPair_T =
|
|
424
|
+
QPair_T = tuple['cirq.Qid', 'cirq.Qid']
|
|
425
425
|
|
|
426
426
|
|
|
427
427
|
@dataclasses.dataclass(frozen=True)
|
|
@@ -436,21 +436,21 @@ class XEBCharacterizationResult:
|
|
|
436
436
|
fitting the characterization.
|
|
437
437
|
"""
|
|
438
438
|
|
|
439
|
-
optimization_results:
|
|
440
|
-
final_params:
|
|
439
|
+
optimization_results: dict[QPair_T, scipy.optimize.OptimizeResult]
|
|
440
|
+
final_params: dict[QPair_T, dict[str, float]]
|
|
441
441
|
fidelities_df: pd.DataFrame
|
|
442
442
|
|
|
443
443
|
|
|
444
444
|
def characterize_phased_fsim_parameters_with_xeb(
|
|
445
445
|
sampled_df: pd.DataFrame,
|
|
446
|
-
parameterized_circuits:
|
|
446
|
+
parameterized_circuits: list[cirq.Circuit],
|
|
447
447
|
cycle_depths: Sequence[int],
|
|
448
448
|
options: XEBCharacterizationOptions,
|
|
449
449
|
initial_simplex_step_size: float = 0.1,
|
|
450
450
|
xatol: float = 1e-3,
|
|
451
451
|
fatol: float = 1e-3,
|
|
452
452
|
verbose: bool = True,
|
|
453
|
-
pool:
|
|
453
|
+
pool: multiprocessing.pool.Pool | None = None,
|
|
454
454
|
) -> XEBCharacterizationResult:
|
|
455
455
|
"""Run a classical optimization to fit phased fsim parameters to experimental data, and
|
|
456
456
|
thereby characterize PhasedFSim-like gates.
|
|
@@ -516,7 +516,7 @@ class _CharacterizePhasedFsimParametersWithXebClosure:
|
|
|
516
516
|
"""A closure object to wrap `characterize_phased_fsim_parameters_with_xeb` for use in
|
|
517
517
|
multiprocessing."""
|
|
518
518
|
|
|
519
|
-
parameterized_circuits:
|
|
519
|
+
parameterized_circuits: list[cirq.Circuit]
|
|
520
520
|
cycle_depths: Sequence[int]
|
|
521
521
|
options: XEBCharacterizationOptions
|
|
522
522
|
initial_simplex_step_size: float = 0.1
|
|
@@ -539,13 +539,13 @@ class _CharacterizePhasedFsimParametersWithXebClosure:
|
|
|
539
539
|
|
|
540
540
|
def characterize_phased_fsim_parameters_with_xeb_by_pair(
|
|
541
541
|
sampled_df: pd.DataFrame,
|
|
542
|
-
parameterized_circuits:
|
|
542
|
+
parameterized_circuits: list[cirq.Circuit],
|
|
543
543
|
cycle_depths: Sequence[int],
|
|
544
544
|
options: XEBCharacterizationOptions,
|
|
545
545
|
initial_simplex_step_size: float = 0.1,
|
|
546
546
|
xatol: float = 1e-3,
|
|
547
547
|
fatol: float = 1e-3,
|
|
548
|
-
pool:
|
|
548
|
+
pool: multiprocessing.pool.Pool | None = None,
|
|
549
549
|
) -> XEBCharacterizationResult:
|
|
550
550
|
"""Run a classical optimization to fit phased fsim parameters to experimental data, and
|
|
551
551
|
thereby characterize PhasedFSim-like gates grouped by pairs.
|
|
@@ -618,7 +618,7 @@ def exponential_decay(cycle_depths: np.ndarray, a: float, layer_fid: float) -> n
|
|
|
618
618
|
|
|
619
619
|
def _fit_exponential_decay(
|
|
620
620
|
cycle_depths: np.ndarray, fidelities: np.ndarray
|
|
621
|
-
) ->
|
|
621
|
+
) -> tuple[float, float, float, float]:
|
|
622
622
|
"""Fit an exponential model fidelity = a * layer_fid**x using nonlinear least squares.
|
|
623
623
|
|
|
624
624
|
This uses `exponential_decay` as the function to fit with parameters `a` and `layer_fid`.
|
cirq/experiments/xeb_sampling.py
CHANGED
|
@@ -20,18 +20,7 @@ import os
|
|
|
20
20
|
import time
|
|
21
21
|
import uuid
|
|
22
22
|
from dataclasses import dataclass
|
|
23
|
-
from typing import
|
|
24
|
-
Any,
|
|
25
|
-
Callable,
|
|
26
|
-
ContextManager,
|
|
27
|
-
Dict,
|
|
28
|
-
List,
|
|
29
|
-
Optional,
|
|
30
|
-
Sequence,
|
|
31
|
-
Set,
|
|
32
|
-
Tuple,
|
|
33
|
-
TYPE_CHECKING,
|
|
34
|
-
)
|
|
23
|
+
from typing import Any, Callable, ContextManager, Sequence, TYPE_CHECKING
|
|
35
24
|
|
|
36
25
|
import numpy as np
|
|
37
26
|
import pandas as pd
|
|
@@ -57,7 +46,7 @@ class _Sample2qXEBTask:
|
|
|
57
46
|
layer_i: int
|
|
58
47
|
combination_i: int
|
|
59
48
|
prepared_circuit: cirq.AbstractCircuit
|
|
60
|
-
combination:
|
|
49
|
+
combination: list[int]
|
|
61
50
|
|
|
62
51
|
|
|
63
52
|
class _SampleInBatches:
|
|
@@ -65,7 +54,7 @@ class _SampleInBatches:
|
|
|
65
54
|
self,
|
|
66
55
|
sampler: cirq.Sampler,
|
|
67
56
|
repetitions: int,
|
|
68
|
-
combinations_by_layer:
|
|
57
|
+
combinations_by_layer: list[CircuitLibraryCombination],
|
|
69
58
|
):
|
|
70
59
|
"""This closure will execute a list of `tasks` with one call to
|
|
71
60
|
`run_batch` on the provided sampler for a given number of repetitions.
|
|
@@ -80,7 +69,7 @@ class _SampleInBatches:
|
|
|
80
69
|
self.repetitions = repetitions
|
|
81
70
|
self.combinations_by_layer = combinations_by_layer
|
|
82
71
|
|
|
83
|
-
def __call__(self, tasks:
|
|
72
|
+
def __call__(self, tasks: list[_Sample2qXEBTask]) -> list[dict[str, Any]]:
|
|
84
73
|
prepared_circuits = [task.prepared_circuit for task in tasks]
|
|
85
74
|
results = self.sampler.run_batch(prepared_circuits, repetitions=self.repetitions)
|
|
86
75
|
timestamp = time.time()
|
|
@@ -113,7 +102,7 @@ class _SampleInBatches:
|
|
|
113
102
|
|
|
114
103
|
def _verify_and_get_two_qubits_from_circuits(circuits: Sequence[cirq.Circuit]):
|
|
115
104
|
"""Make sure each of the provided circuits uses the same two qubits and return them."""
|
|
116
|
-
all_qubits_set:
|
|
105
|
+
all_qubits_set: set[cirq.Qid] = set()
|
|
117
106
|
all_qubits_set = all_qubits_set.union(*(circuit.all_qubits() for circuit in circuits))
|
|
118
107
|
all_qubits_list = sorted(all_qubits_set)
|
|
119
108
|
if len(all_qubits_list) != 2:
|
|
@@ -170,15 +159,15 @@ class _ZippedCircuit:
|
|
|
170
159
|
"""
|
|
171
160
|
|
|
172
161
|
wide_circuit: cirq.Circuit
|
|
173
|
-
pairs:
|
|
174
|
-
combination:
|
|
162
|
+
pairs: list[tuple[cirq.Qid, cirq.Qid]]
|
|
163
|
+
combination: list[int]
|
|
175
164
|
layer_i: int
|
|
176
165
|
combination_i: int
|
|
177
166
|
|
|
178
167
|
|
|
179
168
|
def _get_combinations_by_layer_for_isolated_xeb(
|
|
180
169
|
circuits: Sequence[cirq.Circuit],
|
|
181
|
-
) ->
|
|
170
|
+
) -> tuple[list[CircuitLibraryCombination], list[cirq.Circuit]]:
|
|
182
171
|
"""Helper function used in `sample_2q_xeb_circuits`.
|
|
183
172
|
|
|
184
173
|
This creates a CircuitLibraryCombination object for isolated XEB. First, the qubits
|
|
@@ -199,8 +188,8 @@ def _get_combinations_by_layer_for_isolated_xeb(
|
|
|
199
188
|
|
|
200
189
|
|
|
201
190
|
def _zip_circuits(
|
|
202
|
-
circuits: Sequence[cirq.Circuit], combinations_by_layer:
|
|
203
|
-
) ->
|
|
191
|
+
circuits: Sequence[cirq.Circuit], combinations_by_layer: list[CircuitLibraryCombination]
|
|
192
|
+
) -> list[_ZippedCircuit]:
|
|
204
193
|
"""Helper function used in `sample_2q_xeb_circuits` to zip together circuits.
|
|
205
194
|
|
|
206
195
|
This takes a sequence of narrow `circuits` and "zips" them together according to the
|
|
@@ -214,7 +203,7 @@ def _zip_circuits(
|
|
|
214
203
|
):
|
|
215
204
|
raise ValueError("`combinations_by_layer` has invalid indices.")
|
|
216
205
|
|
|
217
|
-
zipped_circuits:
|
|
206
|
+
zipped_circuits: list[_ZippedCircuit] = []
|
|
218
207
|
for layer_i, layer_combinations in enumerate(combinations_by_layer):
|
|
219
208
|
for combination_i, combination in enumerate(layer_combinations.combinations):
|
|
220
209
|
wide_circuit = Circuit.zip(
|
|
@@ -236,10 +225,10 @@ def _zip_circuits(
|
|
|
236
225
|
|
|
237
226
|
|
|
238
227
|
def _generate_sample_2q_xeb_tasks(
|
|
239
|
-
zipped_circuits:
|
|
240
|
-
) ->
|
|
228
|
+
zipped_circuits: list[_ZippedCircuit], cycle_depths: Sequence[int]
|
|
229
|
+
) -> list[_Sample2qXEBTask]:
|
|
241
230
|
"""Helper function used in `sample_2q_xeb_circuits` to prepare circuits in sampling tasks."""
|
|
242
|
-
tasks:
|
|
231
|
+
tasks: list[_Sample2qXEBTask] = []
|
|
243
232
|
for cycle_depth in cycle_depths:
|
|
244
233
|
for zipped_circuit in zipped_circuits:
|
|
245
234
|
circuit_depth = cycle_depth * 2 + 1
|
|
@@ -263,14 +252,14 @@ def _generate_sample_2q_xeb_tasks(
|
|
|
263
252
|
|
|
264
253
|
|
|
265
254
|
def _execute_sample_2q_xeb_tasks_in_batches(
|
|
266
|
-
tasks:
|
|
255
|
+
tasks: list[_Sample2qXEBTask],
|
|
267
256
|
sampler: cirq.Sampler,
|
|
268
|
-
combinations_by_layer:
|
|
257
|
+
combinations_by_layer: list[CircuitLibraryCombination],
|
|
269
258
|
repetitions: int,
|
|
270
259
|
batch_size: int,
|
|
271
260
|
progress_bar: Callable[..., ContextManager],
|
|
272
|
-
dataset_directory:
|
|
273
|
-
) ->
|
|
261
|
+
dataset_directory: str | None = None,
|
|
262
|
+
) -> list[dict[str, Any]]:
|
|
274
263
|
"""Helper function used in `sample_2q_xeb_circuits` to batch and execute sampling tasks."""
|
|
275
264
|
n_tasks = len(tasks)
|
|
276
265
|
batched_tasks = [tasks[i : i + batch_size] for i in range(0, n_tasks, batch_size)]
|
|
@@ -298,10 +287,10 @@ def sample_2q_xeb_circuits(
|
|
|
298
287
|
*,
|
|
299
288
|
repetitions: int = 10_000,
|
|
300
289
|
batch_size: int = 9,
|
|
301
|
-
progress_bar:
|
|
302
|
-
combinations_by_layer:
|
|
303
|
-
shuffle:
|
|
304
|
-
dataset_directory:
|
|
290
|
+
progress_bar: Callable[..., ContextManager] | None = tqdm.tqdm,
|
|
291
|
+
combinations_by_layer: list[CircuitLibraryCombination] | None = None,
|
|
292
|
+
shuffle: cirq.RANDOM_STATE_OR_SEED_LIKE | None = None,
|
|
293
|
+
dataset_directory: str | None = None,
|
|
305
294
|
):
|
|
306
295
|
"""Sample two-qubit XEB circuits given a sampler.
|
|
307
296
|
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
19
|
from dataclasses import dataclass
|
|
20
|
-
from typing import Any,
|
|
20
|
+
from typing import Any, Sequence, TYPE_CHECKING
|
|
21
21
|
|
|
22
22
|
import numpy as np
|
|
23
23
|
import pandas as pd
|
|
@@ -46,7 +46,7 @@ class _Simulate_2q_XEB_Circuit:
|
|
|
46
46
|
def __init__(self, simulator: cirq.SimulatesIntermediateState):
|
|
47
47
|
self.simulator = simulator
|
|
48
48
|
|
|
49
|
-
def __call__(self, task: _Simulate2qXEBTask) ->
|
|
49
|
+
def __call__(self, task: _Simulate2qXEBTask) -> list[dict[str, Any]]:
|
|
50
50
|
"""Helper function for simulating a given (circuit, cycle_depth)."""
|
|
51
51
|
circuit_i = task.circuit_i
|
|
52
52
|
cycle_depths = set(task.cycle_depths)
|
|
@@ -57,7 +57,7 @@ class _Simulate_2q_XEB_Circuit:
|
|
|
57
57
|
if max(cycle_depths) > circuit_max_cycle_depth:
|
|
58
58
|
raise ValueError("`circuit` was not long enough to compute all `cycle_depths`.")
|
|
59
59
|
|
|
60
|
-
records:
|
|
60
|
+
records: list[dict[str, Any]] = []
|
|
61
61
|
for moment_i, step_result in enumerate(
|
|
62
62
|
self.simulator.simulate_moment_steps(circuit=circuit, param_resolver=param_resolver)
|
|
63
63
|
):
|
|
@@ -84,8 +84,8 @@ def simulate_2q_xeb_circuits(
|
|
|
84
84
|
circuits: Sequence[cirq.Circuit],
|
|
85
85
|
cycle_depths: Sequence[int],
|
|
86
86
|
param_resolver: cirq.ParamResolverOrSimilarType = None,
|
|
87
|
-
pool:
|
|
88
|
-
simulator:
|
|
87
|
+
pool: multiprocessing.pool.Pool | None = None,
|
|
88
|
+
simulator: cirq.SimulatesIntermediateState | None = None,
|
|
89
89
|
):
|
|
90
90
|
"""Simulate two-qubit XEB circuits.
|
|
91
91
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
import multiprocessing
|
|
18
|
-
from typing import Any,
|
|
18
|
+
from typing import Any, Iterator, Sequence
|
|
19
19
|
|
|
20
20
|
import numpy as np
|
|
21
21
|
import pandas as pd
|
|
@@ -74,7 +74,7 @@ def test_simulate_circuit_length_validation():
|
|
|
74
74
|
_ = simulate_2q_xeb_circuits(circuits=circuits, cycle_depths=cycle_depths)
|
|
75
75
|
|
|
76
76
|
|
|
77
|
-
def _ref_simulate_2q_xeb_circuit(task:
|
|
77
|
+
def _ref_simulate_2q_xeb_circuit(task: dict[str, Any]):
|
|
78
78
|
"""Helper function for simulating a given (circuit, cycle_depth)."""
|
|
79
79
|
circuit_i = task['circuit_i']
|
|
80
80
|
cycle_depth = task['cycle_depth']
|
|
@@ -98,7 +98,7 @@ def _ref_simulate_2q_xeb_circuits(
|
|
|
98
98
|
circuits: Sequence[cirq.Circuit],
|
|
99
99
|
cycle_depths: Sequence[int],
|
|
100
100
|
param_resolver: cirq.ParamResolverOrSimilarType = None,
|
|
101
|
-
pool:
|
|
101
|
+
pool: multiprocessing.pool.Pool | None = None,
|
|
102
102
|
):
|
|
103
103
|
"""Reference implementation for `simulate_2q_xeb_circuits` that
|
|
104
104
|
does each circuit independently instead of using intermediate states.
|
|
@@ -18,7 +18,7 @@ from __future__ import annotations
|
|
|
18
18
|
|
|
19
19
|
import multiprocessing
|
|
20
20
|
import multiprocessing.pool
|
|
21
|
-
from typing import Any,
|
|
21
|
+
from typing import Any, Sequence, TYPE_CHECKING
|
|
22
22
|
|
|
23
23
|
import matplotlib.pyplot as plt
|
|
24
24
|
import numpy as np
|
|
@@ -36,19 +36,19 @@ if TYPE_CHECKING:
|
|
|
36
36
|
|
|
37
37
|
def z_phase_calibration_workflow(
|
|
38
38
|
sampler: cirq.Sampler,
|
|
39
|
-
qubits:
|
|
39
|
+
qubits: Sequence[cirq.GridQubit] | None = None,
|
|
40
40
|
two_qubit_gate: cirq.Gate = ops.CZ,
|
|
41
|
-
options:
|
|
41
|
+
options: xeb_fitting.XEBPhasedFSimCharacterizationOptions | None = None,
|
|
42
42
|
n_repetitions: int = 10**4,
|
|
43
43
|
n_combinations: int = 10,
|
|
44
44
|
n_circuits: int = 20,
|
|
45
45
|
cycle_depths: Sequence[int] = tuple(np.arange(3, 100, 20)),
|
|
46
46
|
random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
47
47
|
atol: float = 1e-3,
|
|
48
|
-
num_workers_or_pool:
|
|
49
|
-
pairs:
|
|
48
|
+
num_workers_or_pool: int | multiprocessing.pool.Pool = -1,
|
|
49
|
+
pairs: Sequence[tuple[cirq.GridQubit, cirq.GridQubit]] | None = None,
|
|
50
50
|
tags: Sequence[Any] = (),
|
|
51
|
-
) ->
|
|
51
|
+
) -> tuple[xeb_fitting.XEBCharacterizationResult, pd.DataFrame]:
|
|
52
52
|
"""Perform z-phase calibration for excitation-preserving gates.
|
|
53
53
|
|
|
54
54
|
For a given excitation-preserving two-qubit gate we assume an error model that can be described
|
|
@@ -91,7 +91,7 @@ def z_phase_calibration_workflow(
|
|
|
91
91
|
- A `pd.DataFrame` comparing the before and after fidelities.
|
|
92
92
|
"""
|
|
93
93
|
|
|
94
|
-
pool:
|
|
94
|
+
pool: multiprocessing.pool.Pool | None = None
|
|
95
95
|
local_pool = False
|
|
96
96
|
if isinstance(num_workers_or_pool, multiprocessing.pool.Pool):
|
|
97
97
|
pool = num_workers_or_pool # pragma: no cover
|
|
@@ -149,19 +149,19 @@ def z_phase_calibration_workflow(
|
|
|
149
149
|
|
|
150
150
|
def calibrate_z_phases(
|
|
151
151
|
sampler: cirq.Sampler,
|
|
152
|
-
qubits:
|
|
152
|
+
qubits: Sequence[cirq.GridQubit] | None = None,
|
|
153
153
|
two_qubit_gate: cirq.Gate = ops.CZ,
|
|
154
|
-
options:
|
|
154
|
+
options: xeb_fitting.XEBPhasedFSimCharacterizationOptions | None = None,
|
|
155
155
|
n_repetitions: int = 10**4,
|
|
156
156
|
n_combinations: int = 10,
|
|
157
157
|
n_circuits: int = 20,
|
|
158
158
|
cycle_depths: Sequence[int] = tuple(np.arange(3, 100, 20)),
|
|
159
159
|
random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
160
160
|
atol: float = 1e-3,
|
|
161
|
-
num_workers_or_pool:
|
|
162
|
-
pairs:
|
|
161
|
+
num_workers_or_pool: int | multiprocessing.pool.Pool = -1,
|
|
162
|
+
pairs: Sequence[tuple[cirq.GridQubit, cirq.GridQubit]] | None = None,
|
|
163
163
|
tags: Sequence[Any] = (),
|
|
164
|
-
) ->
|
|
164
|
+
) -> dict[tuple[cirq.Qid, cirq.Qid], cirq.PhasedFSimGate]:
|
|
165
165
|
"""Perform z-phase calibration for excitation-preserving gates.
|
|
166
166
|
|
|
167
167
|
For a given excitation-preserving two-qubit gate we assume an error model that can be described
|
|
@@ -242,11 +242,11 @@ def calibrate_z_phases(
|
|
|
242
242
|
|
|
243
243
|
def plot_z_phase_calibration_result(
|
|
244
244
|
before_after_df: pd.DataFrame,
|
|
245
|
-
axes:
|
|
246
|
-
pairs:
|
|
245
|
+
axes: np.ndarray[tuple[int, int], np.dtype[np.object_]] | None = None,
|
|
246
|
+
pairs: Sequence[tuple[cirq.Qid, cirq.Qid]] | None = None,
|
|
247
247
|
*,
|
|
248
248
|
with_error_bars: bool = False,
|
|
249
|
-
) -> np.ndarray[
|
|
249
|
+
) -> np.ndarray[tuple[int, int], np.dtype[np.object_]]:
|
|
250
250
|
"""A helper method to plot the result of running z-phase calibration.
|
|
251
251
|
|
|
252
252
|
Note that the plotted fidelity is a statistical estimate of the true fidelity and as a result
|
|
@@ -290,7 +290,7 @@ def plot_z_phase_calibration_result(
|
|
|
290
290
|
return axes
|
|
291
291
|
|
|
292
292
|
|
|
293
|
-
def _z_angles(old: ops.PhasedFSimGate, new: ops.PhasedFSimGate) ->
|
|
293
|
+
def _z_angles(old: ops.PhasedFSimGate, new: ops.PhasedFSimGate) -> tuple[float, float, float]:
|
|
294
294
|
"""Computes a set of possible 3 z-phases that result in the change in gamma, zeta, and chi."""
|
|
295
295
|
# This procedure is the inverse of PhasedFSimGate.from_fsim_rz
|
|
296
296
|
delta_gamma = new.gamma - old.gamma
|
|
@@ -305,7 +305,7 @@ class CalibrationTransformer:
|
|
|
305
305
|
def __init__(
|
|
306
306
|
self,
|
|
307
307
|
target: cirq.Gate,
|
|
308
|
-
calibration_map:
|
|
308
|
+
calibration_map: dict[tuple[cirq.Qid, cirq.Qid], cirq.PhasedFSimGate],
|
|
309
309
|
):
|
|
310
310
|
"""Create a CalibrationTransformer.
|
|
311
311
|
|
|
@@ -332,7 +332,7 @@ class CalibrationTransformer:
|
|
|
332
332
|
self,
|
|
333
333
|
circuit: cirq.AbstractCircuit,
|
|
334
334
|
*,
|
|
335
|
-
context:
|
|
335
|
+
context: transformer_api.TransformerContext | None = None,
|
|
336
336
|
) -> cirq.Circuit:
|
|
337
337
|
"""Adds 3 ZPowGates around each calibrated gate to cancel the effect of Z phases.
|
|
338
338
|
|
|
@@ -343,7 +343,7 @@ class CalibrationTransformer:
|
|
|
343
343
|
Returns:
|
|
344
344
|
New circuit with the extra ZPowGates.
|
|
345
345
|
"""
|
|
346
|
-
new_moments:
|
|
346
|
+
new_moments: list[list[cirq.Operation] | cirq.Moment] = []
|
|
347
347
|
for moment in circuit:
|
|
348
348
|
before = []
|
|
349
349
|
after = []
|
|
@@ -15,20 +15,7 @@
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
import inspect
|
|
18
|
-
from typing import
|
|
19
|
-
Any,
|
|
20
|
-
Callable,
|
|
21
|
-
cast,
|
|
22
|
-
Dict,
|
|
23
|
-
Iterable,
|
|
24
|
-
Iterator,
|
|
25
|
-
List,
|
|
26
|
-
Optional,
|
|
27
|
-
Sequence,
|
|
28
|
-
Tuple,
|
|
29
|
-
TYPE_CHECKING,
|
|
30
|
-
Union,
|
|
31
|
-
)
|
|
18
|
+
from typing import Any, Callable, cast, Iterable, Iterator, Sequence, TYPE_CHECKING
|
|
32
19
|
|
|
33
20
|
from cirq import ops, value
|
|
34
21
|
from cirq.interop.quirk.cells.cell import Cell, CELL_SIZES, CellMaker
|
|
@@ -52,7 +39,7 @@ class QuirkArithmeticGate(ops.ArithmeticGate):
|
|
|
52
39
|
"""
|
|
53
40
|
|
|
54
41
|
def __init__(
|
|
55
|
-
self, identifier: str, target: Sequence[int], inputs: Sequence[
|
|
42
|
+
self, identifier: str, target: Sequence[int], inputs: Sequence[Sequence[int] | int]
|
|
56
43
|
):
|
|
57
44
|
"""Inits QuirkArithmeticGate.
|
|
58
45
|
|
|
@@ -68,8 +55,8 @@ class QuirkArithmeticGate(ops.ArithmeticGate):
|
|
|
68
55
|
too small modulus.
|
|
69
56
|
"""
|
|
70
57
|
self.identifier = identifier
|
|
71
|
-
self.target:
|
|
72
|
-
self.inputs:
|
|
58
|
+
self.target: tuple[int, ...] = tuple(target)
|
|
59
|
+
self.inputs: tuple[Sequence[int] | int, ...] = tuple(
|
|
73
60
|
e if isinstance(e, int) else tuple(e) for e in inputs
|
|
74
61
|
)
|
|
75
62
|
|
|
@@ -89,10 +76,10 @@ class QuirkArithmeticGate(ops.ArithmeticGate):
|
|
|
89
76
|
def _value_equality_values_(self) -> Any:
|
|
90
77
|
return self.identifier, self.target, self.inputs
|
|
91
78
|
|
|
92
|
-
def registers(self) -> Sequence[
|
|
79
|
+
def registers(self) -> Sequence[int | Sequence[int]]:
|
|
93
80
|
return [self.target, *self.inputs]
|
|
94
81
|
|
|
95
|
-
def with_registers(self, *new_registers:
|
|
82
|
+
def with_registers(self, *new_registers: int | Sequence[int]) -> QuirkArithmeticGate:
|
|
96
83
|
if len(new_registers) != len(self.inputs) + 1:
|
|
97
84
|
raise ValueError(
|
|
98
85
|
'Wrong number of registers.\n'
|
|
@@ -109,13 +96,13 @@ class QuirkArithmeticGate(ops.ArithmeticGate):
|
|
|
109
96
|
|
|
110
97
|
return QuirkArithmeticGate(self.identifier, new_registers[0], new_registers[1:])
|
|
111
98
|
|
|
112
|
-
def apply(self, *registers: int) ->
|
|
99
|
+
def apply(self, *registers: int) -> int | Iterable[int]:
|
|
113
100
|
return self.operation(*registers)
|
|
114
101
|
|
|
115
|
-
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) ->
|
|
102
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> list[str]:
|
|
116
103
|
lettered_args = list(zip(self.operation.letters, self.inputs))
|
|
117
104
|
|
|
118
|
-
result:
|
|
105
|
+
result: list[str] = []
|
|
119
106
|
|
|
120
107
|
# Target register labels.
|
|
121
108
|
consts = ''.join(
|
|
@@ -141,12 +128,12 @@ class QuirkArithmeticGate(ops.ArithmeticGate):
|
|
|
141
128
|
)
|
|
142
129
|
|
|
143
130
|
|
|
144
|
-
_IntsToIntCallable =
|
|
145
|
-
Callable[[int], int]
|
|
146
|
-
Callable[[int, int], int]
|
|
147
|
-
Callable[[int, int, int], int]
|
|
148
|
-
Callable[[int, int, int, int], int]
|
|
149
|
-
|
|
131
|
+
_IntsToIntCallable = (
|
|
132
|
+
Callable[[int], int]
|
|
133
|
+
| Callable[[int, int], int]
|
|
134
|
+
| Callable[[int, int, int], int]
|
|
135
|
+
| Callable[[int, int, int, int], int]
|
|
136
|
+
)
|
|
150
137
|
|
|
151
138
|
|
|
152
139
|
class _QuirkArithmeticCallable:
|
|
@@ -161,7 +148,7 @@ class _QuirkArithmeticCallable:
|
|
|
161
148
|
self.func = func
|
|
162
149
|
|
|
163
150
|
# The lambda parameter names indicate the input letter to match.
|
|
164
|
-
letters:
|
|
151
|
+
letters: list[str] = list(inspect.signature(self.func).parameters)
|
|
165
152
|
# The target is always first, and should be ignored.
|
|
166
153
|
assert letters and letters[0] == 'x'
|
|
167
154
|
self.letters = tuple(letters[1:])
|
|
@@ -187,7 +174,7 @@ class ArithmeticCell(Cell):
|
|
|
187
174
|
self,
|
|
188
175
|
identifier: str,
|
|
189
176
|
target: Sequence[cirq.Qid],
|
|
190
|
-
inputs: Sequence[
|
|
177
|
+
inputs: Sequence[None | Sequence[cirq.Qid] | int],
|
|
191
178
|
):
|
|
192
179
|
self.identifier = identifier
|
|
193
180
|
self.target = tuple(target)
|
|
@@ -207,7 +194,7 @@ class ArithmeticCell(Cell):
|
|
|
207
194
|
f'\n {self.inputs!r})'
|
|
208
195
|
)
|
|
209
196
|
|
|
210
|
-
def with_line_qubits_mapped_to(self, qubits:
|
|
197
|
+
def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
|
|
211
198
|
return ArithmeticCell(
|
|
212
199
|
identifier=self.identifier,
|
|
213
200
|
target=Cell._replace_qubits(self.target, qubits),
|
|
@@ -221,7 +208,7 @@ class ArithmeticCell(Cell):
|
|
|
221
208
|
def operation(self):
|
|
222
209
|
return ARITHMETIC_OP_TABLE[self.identifier]
|
|
223
210
|
|
|
224
|
-
def with_input(self, letter: str, register:
|
|
211
|
+
def with_input(self, letter: str, register: Sequence[cirq.Qid] | int) -> ArithmeticCell:
|
|
225
212
|
new_inputs = [
|
|
226
213
|
reg if letter != reg_letter else register
|
|
227
214
|
for reg, reg_letter in zip(self.inputs, self.operation.letters)
|
|
@@ -235,7 +222,7 @@ class ArithmeticCell(Cell):
|
|
|
235
222
|
if missing_inputs:
|
|
236
223
|
raise ValueError(f'Missing input: {sorted(missing_inputs)}')
|
|
237
224
|
|
|
238
|
-
inputs = cast(Sequence[
|
|
225
|
+
inputs = cast(Sequence[Sequence['cirq.Qid'] | int], self.inputs)
|
|
239
226
|
qubits = self.target + tuple(q for i in self.inputs if isinstance(i, Sequence) for q in i)
|
|
240
227
|
return QuirkArithmeticGate(
|
|
241
228
|
self.identifier,
|
|
@@ -304,7 +291,7 @@ def _generate_helper() -> Iterator[CellMaker]:
|
|
|
304
291
|
)
|
|
305
292
|
|
|
306
293
|
|
|
307
|
-
def _extended_gcd(a: int, b: int) ->
|
|
294
|
+
def _extended_gcd(a: int, b: int) -> tuple[int, int, int]:
|
|
308
295
|
if a == 0:
|
|
309
296
|
return b, 0, 1
|
|
310
297
|
gcd, y, x = _extended_gcd(b % a, a)
|
|
@@ -360,9 +347,9 @@ def _arithmetic_gate(identifier: str, size: int, func: _IntsToIntCallable) -> Ce
|
|
|
360
347
|
)
|
|
361
348
|
|
|
362
349
|
|
|
363
|
-
ARITHMETIC_OP_TABLE:
|
|
350
|
+
ARITHMETIC_OP_TABLE: dict[str, _QuirkArithmeticCallable] = {}
|
|
364
351
|
# Caching is necessary in order to avoid overwriting entries in the table.
|
|
365
|
-
_cached_cells:
|
|
352
|
+
_cached_cells: tuple[CellMaker, ...] | None = None
|
|
366
353
|
|
|
367
354
|
|
|
368
355
|
def generate_all_arithmetic_cell_makers() -> Iterable[CellMaker]:
|