cirq-core 1.6.0.dev20250520054601__py3-none-any.whl → 1.6.0.dev20250520183459__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/linear_dict_test.py +2 -2
- 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.dev20250520183459.dist-info}/METADATA +1 -1
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/RECORD +290 -290
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/WHEEL +1 -1
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.6.0.dev20250520054601.dist-info → cirq_core-1.6.0.dev20250520183459.dist-info}/top_level.txt +0 -0
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
import itertools
|
|
18
|
-
from typing import Any,
|
|
18
|
+
from typing import Any, Iterator, Sequence, TYPE_CHECKING
|
|
19
19
|
|
|
20
20
|
from cirq import ops, value
|
|
21
21
|
from cirq.contrib.acquaintance.permutation import PermutationGate, SwapPermutationGate
|
|
@@ -60,7 +60,7 @@ class CircularShiftGate(PermutationGate):
|
|
|
60
60
|
for k in range(i, j, 2):
|
|
61
61
|
yield swap_gate(*qubits[k : k + 2])
|
|
62
62
|
|
|
63
|
-
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) ->
|
|
63
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> tuple[str, ...]:
|
|
64
64
|
if args.known_qubit_count is None:
|
|
65
65
|
return NotImplemented # pragma: no cover
|
|
66
66
|
direction_symbols = ('╲', '╱') if args.use_unicode_characters else ('\\', '/')
|
|
@@ -72,7 +72,7 @@ class CircularShiftGate(PermutationGate):
|
|
|
72
72
|
)
|
|
73
73
|
return wire_symbols
|
|
74
74
|
|
|
75
|
-
def permutation(self) ->
|
|
75
|
+
def permutation(self) -> dict[int, int]:
|
|
76
76
|
shift = self.shift % self.num_qubits()
|
|
77
77
|
permuted_indices = itertools.chain(range(shift, self.num_qubits()), range(shift))
|
|
78
78
|
return {s: i for i, s in enumerate(permuted_indices)}
|
|
@@ -16,7 +16,7 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
import functools
|
|
18
18
|
import itertools
|
|
19
|
-
from typing import
|
|
19
|
+
from typing import Iterable, Iterator, Sequence, TYPE_CHECKING
|
|
20
20
|
|
|
21
21
|
from cirq import ops
|
|
22
22
|
from cirq.contrib.acquaintance.gates import acquaint
|
|
@@ -93,7 +93,7 @@ class ShiftSwapNetworkGate(PermutationGate):
|
|
|
93
93
|
parts[k] = parts_qubits[: len(right_part)]
|
|
94
94
|
parts[k + 1] = parts_qubits[len(right_part) :]
|
|
95
95
|
|
|
96
|
-
def qubit_count(self, side:
|
|
96
|
+
def qubit_count(self, side: str | None = None) -> int:
|
|
97
97
|
if side is None:
|
|
98
98
|
return sum(self.qubit_count(side) for side in self.part_lens)
|
|
99
99
|
return sum(self.part_lens[side])
|
|
@@ -101,7 +101,7 @@ class ShiftSwapNetworkGate(PermutationGate):
|
|
|
101
101
|
def num_qubits(self) -> int:
|
|
102
102
|
return self.qubit_count()
|
|
103
103
|
|
|
104
|
-
def permutation(self) ->
|
|
104
|
+
def permutation(self) -> dict[int, int]:
|
|
105
105
|
return dict(
|
|
106
106
|
zip(
|
|
107
107
|
range(self.num_qubits()),
|
|
@@ -112,7 +112,7 @@ class ShiftSwapNetworkGate(PermutationGate):
|
|
|
112
112
|
)
|
|
113
113
|
)
|
|
114
114
|
|
|
115
|
-
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) ->
|
|
115
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> tuple[str, ...]:
|
|
116
116
|
qubit_count = self.qubit_count()
|
|
117
117
|
assert args.known_qubit_count in (None, qubit_count)
|
|
118
118
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
import itertools
|
|
18
|
-
from typing import Iterable, Sequence,
|
|
18
|
+
from typing import Iterable, Sequence, TYPE_CHECKING, TypeVar
|
|
19
19
|
|
|
20
20
|
from cirq import circuits, ops
|
|
21
21
|
from cirq.contrib.acquaintance.gates import acquaint
|
|
@@ -27,7 +27,7 @@ if TYPE_CHECKING:
|
|
|
27
27
|
TItem = TypeVar('TItem')
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
def skip_and_wrap_around(items: Sequence[TItem]) ->
|
|
30
|
+
def skip_and_wrap_around(items: Sequence[TItem]) -> tuple[TItem, ...]:
|
|
31
31
|
n_items = len(items)
|
|
32
32
|
positions = {
|
|
33
33
|
p: i
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import cast, Iterable,
|
|
17
|
+
from typing import cast, Iterable, Sequence, TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
from cirq import circuits
|
|
20
20
|
from cirq.contrib.acquaintance.gates import acquaint, SwapNetworkGate
|
|
@@ -24,7 +24,7 @@ if TYPE_CHECKING:
|
|
|
24
24
|
import cirq
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def qubit_pairs_to_qubit_order(qubit_pairs: Sequence[Sequence[cirq.Qid]]) ->
|
|
27
|
+
def qubit_pairs_to_qubit_order(qubit_pairs: Sequence[Sequence[cirq.Qid]]) -> list[cirq.Qid]:
|
|
28
28
|
"""Takes a sequence of qubit pairs and returns a sequence in which every
|
|
29
29
|
pair is at distance two.
|
|
30
30
|
|
|
@@ -35,7 +35,7 @@ def qubit_pairs_to_qubit_order(qubit_pairs: Sequence[Sequence[cirq.Qid]]) -> Lis
|
|
|
35
35
|
if set(len(qubit_pair) for qubit_pair in qubit_pairs) != set((2,)):
|
|
36
36
|
raise ValueError('set(len(qubit_pair) for qubit_pair in qubit_pairs) != set((2,))')
|
|
37
37
|
n_pairs = len(qubit_pairs)
|
|
38
|
-
qubits:
|
|
38
|
+
qubits: list[cirq.Qid] = []
|
|
39
39
|
for i in range(0, 2 * (n_pairs // 2), 2):
|
|
40
40
|
qubits += [
|
|
41
41
|
qubit_pairs[i][0],
|
|
@@ -49,15 +49,15 @@ def qubit_pairs_to_qubit_order(qubit_pairs: Sequence[Sequence[cirq.Qid]]) -> Lis
|
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
def quartic_paired_acquaintance_strategy(
|
|
52
|
-
qubit_pairs: Iterable[
|
|
53
|
-
) ->
|
|
52
|
+
qubit_pairs: Iterable[tuple[cirq.Qid, cirq.Qid]],
|
|
53
|
+
) -> tuple[cirq.Circuit, Sequence[cirq.Qid]]:
|
|
54
54
|
"""Acquaintance strategy for pairs of pairs.
|
|
55
55
|
|
|
56
56
|
Implements UpCCGSD ansatz from arXiv:1810.02327.
|
|
57
57
|
"""
|
|
58
58
|
|
|
59
59
|
qubit_pairs = tuple(
|
|
60
|
-
cast(
|
|
60
|
+
cast(tuple['cirq.Qid', 'cirq.Qid'], tuple(qubit_pair)) for qubit_pair in qubit_pairs
|
|
61
61
|
)
|
|
62
62
|
qubits = qubit_pairs_to_qubit_order(qubit_pairs)
|
|
63
63
|
n_qubits = len(qubits)
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
import math
|
|
18
|
-
from typing import Any, cast,
|
|
18
|
+
from typing import Any, cast, Iterator, Sequence, TYPE_CHECKING
|
|
19
19
|
|
|
20
20
|
from sympy.combinatorics import GrayCode
|
|
21
21
|
|
|
@@ -96,8 +96,8 @@ class BayesianNetworkGate(raw_types.Gate):
|
|
|
96
96
|
|
|
97
97
|
def __init__(
|
|
98
98
|
self,
|
|
99
|
-
init_probs:
|
|
100
|
-
arc_probs:
|
|
99
|
+
init_probs: list[tuple[str, float | None]],
|
|
100
|
+
arc_probs: list[tuple[str, tuple[str], list[float]]],
|
|
101
101
|
):
|
|
102
102
|
"""Builds a BayesianNetworkGate.
|
|
103
103
|
|
|
@@ -175,28 +175,27 @@ class BayesianNetworkGate(raw_types.Gate):
|
|
|
175
175
|
def _has_unitary_(self) -> bool:
|
|
176
176
|
return True
|
|
177
177
|
|
|
178
|
-
def _qid_shape_(self) ->
|
|
178
|
+
def _qid_shape_(self) -> tuple[int, ...]:
|
|
179
179
|
return (2,) * len(self._init_probs)
|
|
180
180
|
|
|
181
181
|
def _value_equality_values_(self):
|
|
182
182
|
return self._init_probs, self._arc_probs
|
|
183
183
|
|
|
184
|
-
def _json_dict_(self) ->
|
|
184
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
185
185
|
return {'init_probs': self._init_probs, 'arc_probs': self._arc_probs}
|
|
186
186
|
|
|
187
187
|
@classmethod
|
|
188
188
|
def _from_json_dict_(
|
|
189
189
|
cls,
|
|
190
|
-
init_probs:
|
|
191
|
-
arc_probs:
|
|
190
|
+
init_probs: list[list[str | float | None]],
|
|
191
|
+
arc_probs: list[list[str | list[str] | list[float]]],
|
|
192
192
|
**kwargs,
|
|
193
193
|
) -> BayesianNetworkGate:
|
|
194
194
|
converted_init_probs = cast(
|
|
195
|
-
|
|
196
|
-
[(param, init_prob) for param, init_prob in init_probs],
|
|
195
|
+
list[tuple[str, float | None]], [(param, init_prob) for param, init_prob in init_probs]
|
|
197
196
|
)
|
|
198
197
|
converted_cond_probs = cast(
|
|
199
|
-
|
|
198
|
+
list[tuple[str, tuple[str], list[float]]],
|
|
200
199
|
[(target, tuple(params), cond_probs) for target, params, cond_probs in arc_probs],
|
|
201
200
|
)
|
|
202
201
|
return cls(converted_init_probs, converted_cond_probs)
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
import functools
|
|
18
|
-
from typing import Any, Callable, cast,
|
|
18
|
+
from typing import Any, Callable, cast, Generic, Iterator, TypeVar
|
|
19
19
|
|
|
20
20
|
import networkx
|
|
21
21
|
|
|
@@ -132,7 +132,7 @@ class CircuitDag(networkx.DiGraph):
|
|
|
132
132
|
for node, attr in g2.nodes(data=True):
|
|
133
133
|
attr['val'] = node.val
|
|
134
134
|
|
|
135
|
-
def node_match(attr1:
|
|
135
|
+
def node_match(attr1: dict[Any, Any], attr2: dict[Any, Any]) -> bool:
|
|
136
136
|
return attr1['val'] == attr2['val']
|
|
137
137
|
|
|
138
138
|
return networkx.is_isomorphic(g1, g2, node_match=node_match)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Any,
|
|
17
|
+
from typing import Any, Generic, Sequence, TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
from cirq import sim
|
|
20
20
|
from cirq.sim.simulation_state import TSimulationState
|
|
@@ -47,7 +47,7 @@ class CustomStateSimulator(
|
|
|
47
47
|
|
|
48
48
|
def __init__(
|
|
49
49
|
self,
|
|
50
|
-
state_type:
|
|
50
|
+
state_type: type[TSimulationState],
|
|
51
51
|
*,
|
|
52
52
|
noise: cirq.NOISE_MODEL_LIKE = None,
|
|
53
53
|
split_untangled_states: bool = False,
|
|
@@ -66,7 +66,7 @@ class CustomStateSimulator(
|
|
|
66
66
|
def _create_simulator_trial_result(
|
|
67
67
|
self,
|
|
68
68
|
params: cirq.ParamResolver,
|
|
69
|
-
measurements:
|
|
69
|
+
measurements: dict[str, np.ndarray],
|
|
70
70
|
final_simulator_state: cirq.SimulationStateBase[TSimulationState],
|
|
71
71
|
) -> CustomStateTrialResult[TSimulationState]:
|
|
72
72
|
return CustomStateTrialResult(
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import
|
|
17
|
+
from typing import Sequence
|
|
18
18
|
|
|
19
19
|
import numpy as np
|
|
20
20
|
import sympy
|
|
@@ -24,7 +24,7 @@ from cirq.contrib.custom_simulators.custom_state_simulator import CustomStateSim
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
class ComputationalBasisState(cirq.qis.QuantumStateRepresentation):
|
|
27
|
-
def __init__(self, initial_state:
|
|
27
|
+
def __init__(self, initial_state: list[int]):
|
|
28
28
|
self.basis = initial_state
|
|
29
29
|
|
|
30
30
|
def copy(self, deep_copy_buffers: bool = True) -> ComputationalBasisState:
|
|
@@ -136,7 +136,7 @@ def test_parameterized_repetitions():
|
|
|
136
136
|
|
|
137
137
|
|
|
138
138
|
class ComputationalBasisProductState(cirq.qis.QuantumStateRepresentation):
|
|
139
|
-
def __init__(self, initial_state:
|
|
139
|
+
def __init__(self, initial_state: list[int]):
|
|
140
140
|
self.basis = initial_state
|
|
141
141
|
|
|
142
142
|
def copy(self, deep_copy_buffers: bool = True) -> ComputationalBasisProductState:
|
|
@@ -150,7 +150,7 @@ class ComputationalBasisProductState(cirq.qis.QuantumStateRepresentation):
|
|
|
150
150
|
|
|
151
151
|
def factor(
|
|
152
152
|
self, axes: Sequence[int], *, validate=True, atol=1e-07
|
|
153
|
-
) ->
|
|
153
|
+
) -> tuple[ComputationalBasisProductState, ComputationalBasisProductState]:
|
|
154
154
|
extracted = ComputationalBasisProductState(
|
|
155
155
|
[self.basis[i] for i in axes]
|
|
156
156
|
) # pragma: no cover
|
|
@@ -16,7 +16,7 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
import abc
|
|
18
18
|
import itertools
|
|
19
|
-
from typing import cast, Iterable,
|
|
19
|
+
from typing import cast, Iterable, TYPE_CHECKING
|
|
20
20
|
|
|
21
21
|
from cirq import devices, ops, value
|
|
22
22
|
from cirq.contrib.graph_device.hypergraph import UndirectedHypergraph
|
|
@@ -122,8 +122,8 @@ class UndirectedGraphDevice(devices.Device):
|
|
|
122
122
|
|
|
123
123
|
def __init__(
|
|
124
124
|
self,
|
|
125
|
-
device_graph:
|
|
126
|
-
crosstalk_graph:
|
|
125
|
+
device_graph: UndirectedHypergraph | None = None,
|
|
126
|
+
crosstalk_graph: UndirectedHypergraph | None = None,
|
|
127
127
|
) -> None:
|
|
128
128
|
"""Inits UndirectedGraphDevice.
|
|
129
129
|
|
|
@@ -152,8 +152,8 @@ class UndirectedGraphDevice(devices.Device):
|
|
|
152
152
|
self.crosstalk_graph = crosstalk_graph
|
|
153
153
|
|
|
154
154
|
@property
|
|
155
|
-
def qubits(self) ->
|
|
156
|
-
return cast(
|
|
155
|
+
def qubits(self) -> tuple[cirq.Qid, ...]:
|
|
156
|
+
return cast(tuple['cirq.Qid', ...], tuple(sorted(self.device_graph.vertices)))
|
|
157
157
|
|
|
158
158
|
@property
|
|
159
159
|
def edges(self):
|
|
@@ -16,17 +16,17 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
import itertools
|
|
18
18
|
import random
|
|
19
|
-
from typing import Any,
|
|
19
|
+
from typing import Any, Hashable, Iterable, Mapping
|
|
20
20
|
|
|
21
|
-
AdjacencyList =
|
|
21
|
+
AdjacencyList = set[frozenset[Hashable]]
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
class UndirectedHypergraph:
|
|
25
25
|
def __init__(
|
|
26
26
|
self,
|
|
27
27
|
*,
|
|
28
|
-
vertices:
|
|
29
|
-
labelled_edges:
|
|
28
|
+
vertices: Iterable[Hashable] | None = None,
|
|
29
|
+
labelled_edges: dict[Iterable[Hashable], Any] | None = None,
|
|
30
30
|
) -> None:
|
|
31
31
|
"""A labelled, undirected hypergraph.
|
|
32
32
|
|
|
@@ -37,23 +37,23 @@ class UndirectedHypergraph:
|
|
|
37
37
|
automatically added.
|
|
38
38
|
"""
|
|
39
39
|
|
|
40
|
-
self._adjacency_lists:
|
|
41
|
-
self._labelled_edges:
|
|
40
|
+
self._adjacency_lists: dict[Hashable, AdjacencyList] = {}
|
|
41
|
+
self._labelled_edges: dict[frozenset[Hashable], Any] = {}
|
|
42
42
|
if vertices is not None:
|
|
43
43
|
self.add_vertices(vertices)
|
|
44
44
|
if labelled_edges is not None:
|
|
45
45
|
self.add_edges(labelled_edges)
|
|
46
46
|
|
|
47
47
|
@property
|
|
48
|
-
def vertices(self) ->
|
|
48
|
+
def vertices(self) -> tuple[Hashable, ...]:
|
|
49
49
|
return tuple(self._adjacency_lists.keys())
|
|
50
50
|
|
|
51
51
|
@property
|
|
52
|
-
def edges(self) ->
|
|
52
|
+
def edges(self) -> tuple[frozenset[Hashable], ...]:
|
|
53
53
|
return tuple(self._labelled_edges.keys())
|
|
54
54
|
|
|
55
55
|
@property
|
|
56
|
-
def labelled_edges(self) ->
|
|
56
|
+
def labelled_edges(self) -> dict[frozenset, Any]:
|
|
57
57
|
return dict(self._labelled_edges)
|
|
58
58
|
|
|
59
59
|
def add_vertex(self, vertex: Hashable) -> None:
|
|
@@ -82,7 +82,7 @@ class UndirectedHypergraph:
|
|
|
82
82
|
self._adjacency_lists[vertex].update((vertices,))
|
|
83
83
|
self._labelled_edges[vertices] = label
|
|
84
84
|
|
|
85
|
-
def add_edges(self, edges:
|
|
85
|
+
def add_edges(self, edges: dict[Iterable[Hashable], Any]):
|
|
86
86
|
for vertices, label in edges.items():
|
|
87
87
|
self.add_edge(vertices, label)
|
|
88
88
|
|
|
@@ -104,7 +104,7 @@ class UndirectedHypergraph:
|
|
|
104
104
|
|
|
105
105
|
@classmethod
|
|
106
106
|
def random(
|
|
107
|
-
cls, vertices:
|
|
107
|
+
cls, vertices: int | Iterable, edge_probs: Mapping[int, float]
|
|
108
108
|
) -> UndirectedHypergraph:
|
|
109
109
|
"""A random hypergraph.
|
|
110
110
|
|
|
@@ -127,5 +127,5 @@ class UndirectedHypergraph:
|
|
|
127
127
|
for potential_edge in itertools.combinations(vertices, edge_size):
|
|
128
128
|
if random.random() < edge_prob:
|
|
129
129
|
edges.append(potential_edge)
|
|
130
|
-
labelled_edges:
|
|
130
|
+
labelled_edges: dict[Iterable[Hashable], Any] = {edge: None for edge in edges}
|
|
131
131
|
return cls(vertices=vertices, labelled_edges=labelled_edges)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Any,
|
|
17
|
+
from typing import Any, Hashable, Iterable, Mapping
|
|
18
18
|
|
|
19
19
|
from cirq import devices, ops
|
|
20
20
|
from cirq.contrib.graph_device.graph_device import UndirectedGraphDevice, UndirectedGraphDeviceEdge
|
|
@@ -22,7 +22,7 @@ from cirq.contrib.graph_device.hypergraph import UndirectedHypergraph
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
def uniform_undirected_graph_device(
|
|
25
|
-
edges: Iterable[Iterable[ops.Qid]], edge_label:
|
|
25
|
+
edges: Iterable[Iterable[ops.Qid]], edge_label: UndirectedGraphDeviceEdge | None = None
|
|
26
26
|
) -> UndirectedGraphDevice:
|
|
27
27
|
"""An undirected graph device all of whose edges are the same.
|
|
28
28
|
|
|
@@ -31,13 +31,13 @@ def uniform_undirected_graph_device(
|
|
|
31
31
|
edge_label: The label to apply to all edges. Defaults to None.
|
|
32
32
|
"""
|
|
33
33
|
|
|
34
|
-
labelled_edges:
|
|
34
|
+
labelled_edges: dict[Iterable[Hashable], Any] = {frozenset(edge): edge_label for edge in edges}
|
|
35
35
|
device_graph = UndirectedHypergraph(labelled_edges=labelled_edges)
|
|
36
36
|
return UndirectedGraphDevice(device_graph=device_graph)
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
def uniform_undirected_linear_device(
|
|
40
|
-
n_qubits: int, edge_labels: Mapping[int,
|
|
40
|
+
n_qubits: int, edge_labels: Mapping[int, UndirectedGraphDeviceEdge | None]
|
|
41
41
|
) -> UndirectedGraphDevice:
|
|
42
42
|
"""A uniform , undirected graph device whose qubits are arranged
|
|
43
43
|
on a line.
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import cast
|
|
17
|
+
from typing import cast
|
|
18
18
|
|
|
19
19
|
from cirq import circuits, ops, protocols, transformers
|
|
20
20
|
from cirq.contrib.paulistring.clifford_target_gateset import CliffordTargetGateset
|
|
@@ -31,7 +31,7 @@ def clifford_optimized_circuit(circuit: circuits.Circuit, atol: float = 1e-8) ->
|
|
|
31
31
|
|
|
32
32
|
def find_merge_point(
|
|
33
33
|
start_i: int, string_op: ops.PauliStringPhasor, stop_at_cz: bool
|
|
34
|
-
) ->
|
|
34
|
+
) -> tuple[int, ops.PauliStringPhasor, int]:
|
|
35
35
|
STOP = 0
|
|
36
36
|
CONTINUE = 1
|
|
37
37
|
SKIP = 2
|
|
@@ -16,7 +16,7 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
from enum import Enum
|
|
18
18
|
from types import NotImplementedType
|
|
19
|
-
from typing import cast,
|
|
19
|
+
from typing import cast, TYPE_CHECKING
|
|
20
20
|
|
|
21
21
|
from cirq import linalg, ops, protocols, transformers
|
|
22
22
|
|
|
@@ -28,7 +28,7 @@ if TYPE_CHECKING:
|
|
|
28
28
|
|
|
29
29
|
def _matrix_to_clifford_op(
|
|
30
30
|
mat: np.ndarray, qubit: cirq.Qid, *, atol: float
|
|
31
|
-
) ->
|
|
31
|
+
) -> ops.Operation | NotImplementedType:
|
|
32
32
|
rotations = transformers.single_qubit_matrix_to_pauli_rotations(mat, atol)
|
|
33
33
|
clifford_gate = ops.SingleQubitCliffordGate.I
|
|
34
34
|
for pauli, half_turns in rotations:
|
|
@@ -48,7 +48,7 @@ def _matrix_to_pauli_string_phasors(
|
|
|
48
48
|
mat: np.ndarray, qubit: cirq.Qid, *, keep_clifford: bool, atol: float
|
|
49
49
|
) -> ops.OP_TREE:
|
|
50
50
|
rotations = transformers.single_qubit_matrix_to_pauli_rotations(mat, atol)
|
|
51
|
-
out_ops:
|
|
51
|
+
out_ops: list[ops.GateOperation] = []
|
|
52
52
|
for pauli, half_turns in rotations:
|
|
53
53
|
if keep_clifford and linalg.all_near_zero_mod(half_turns, 0.5):
|
|
54
54
|
cliff_gate = ops.SingleQubitCliffordGate.from_quarter_turns(
|
|
@@ -97,7 +97,7 @@ class CliffordTargetGateset(transformers.TwoQubitCompilationTargetGateset):
|
|
|
97
97
|
"""
|
|
98
98
|
self.atol = atol
|
|
99
99
|
self.single_qubit_target = single_qubit_target
|
|
100
|
-
gates:
|
|
100
|
+
gates: list[cirq.Gate | type[cirq.Gate]] = [ops.CZ, ops.MeasurementGate]
|
|
101
101
|
if single_qubit_target in [
|
|
102
102
|
self.SingleQubitTarget.SINGLE_QUBIT_CLIFFORDS,
|
|
103
103
|
self.SingleQubitTarget.PAULI_STRING_PHASORS_AND_CLIFFORDS,
|
|
@@ -112,7 +112,7 @@ class CliffordTargetGateset(transformers.TwoQubitCompilationTargetGateset):
|
|
|
112
112
|
|
|
113
113
|
def _decompose_single_qubit_operation(
|
|
114
114
|
self, op: cirq.Operation, _
|
|
115
|
-
) ->
|
|
115
|
+
) -> NotImplementedType | cirq.OP_TREE:
|
|
116
116
|
if not protocols.has_unitary(op):
|
|
117
117
|
return NotImplemented
|
|
118
118
|
mat = protocols.unitary(op)
|
|
@@ -129,7 +129,7 @@ class CliffordTargetGateset(transformers.TwoQubitCompilationTargetGateset):
|
|
|
129
129
|
|
|
130
130
|
def _decompose_two_qubit_operation(
|
|
131
131
|
self, op: cirq.Operation, _
|
|
132
|
-
) ->
|
|
132
|
+
) -> NotImplementedType | cirq.OP_TREE:
|
|
133
133
|
if not protocols.has_unitary(op):
|
|
134
134
|
return NotImplemented
|
|
135
135
|
return transformers.two_qubit_matrix_to_cz_operations(
|
|
@@ -141,7 +141,7 @@ class CliffordTargetGateset(transformers.TwoQubitCompilationTargetGateset):
|
|
|
141
141
|
)
|
|
142
142
|
|
|
143
143
|
@property
|
|
144
|
-
def postprocess_transformers(self) ->
|
|
144
|
+
def postprocess_transformers(self) -> list[cirq.TRANSFORMER]:
|
|
145
145
|
"""List of transformers which should be run after decomposing individual operations."""
|
|
146
146
|
|
|
147
147
|
def rewriter(o: cirq.CircuitOperation):
|
|
@@ -18,7 +18,7 @@ from __future__ import annotations
|
|
|
18
18
|
|
|
19
19
|
import itertools
|
|
20
20
|
import time
|
|
21
|
-
from typing import cast,
|
|
21
|
+
from typing import cast, Sequence, TYPE_CHECKING
|
|
22
22
|
|
|
23
23
|
import attrs
|
|
24
24
|
import numpy as np
|
|
@@ -50,7 +50,7 @@ class PauliStringMeasurementResult:
|
|
|
50
50
|
mitigated_stddev: float
|
|
51
51
|
unmitigated_expectation: float
|
|
52
52
|
unmitigated_stddev: float
|
|
53
|
-
calibration_result:
|
|
53
|
+
calibration_result: SingleQubitReadoutCalibrationResult | None = None
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
@attrs.frozen
|
|
@@ -63,11 +63,11 @@ class CircuitToPauliStringsMeasurementResult:
|
|
|
63
63
|
"""
|
|
64
64
|
|
|
65
65
|
circuit: circuits.FrozenCircuit
|
|
66
|
-
results:
|
|
66
|
+
results: list[PauliStringMeasurementResult]
|
|
67
67
|
|
|
68
68
|
|
|
69
69
|
def _commute_or_identity(
|
|
70
|
-
op1:
|
|
70
|
+
op1: ops.Pauli | ops.IdentityGate, op2: ops.Pauli | ops.IdentityGate
|
|
71
71
|
) -> bool:
|
|
72
72
|
if op1 == ops.I or op2 == ops.I:
|
|
73
73
|
return True
|
|
@@ -77,7 +77,7 @@ def _commute_or_identity(
|
|
|
77
77
|
def _are_two_pauli_strings_qubit_wise_commuting(
|
|
78
78
|
pauli_str1: ops.PauliString,
|
|
79
79
|
pauli_str2: ops.PauliString,
|
|
80
|
-
all_qubits:
|
|
80
|
+
all_qubits: list[ops.Qid] | frozenset[ops.Qid],
|
|
81
81
|
) -> bool:
|
|
82
82
|
for qubit in all_qubits:
|
|
83
83
|
op1 = pauli_str1.get(qubit, default=ops.I)
|
|
@@ -89,7 +89,7 @@ def _are_two_pauli_strings_qubit_wise_commuting(
|
|
|
89
89
|
|
|
90
90
|
|
|
91
91
|
def _validate_group_paulis_qwc(
|
|
92
|
-
pauli_strs: list[ops.PauliString], all_qubits:
|
|
92
|
+
pauli_strs: list[ops.PauliString], all_qubits: list[ops.Qid] | frozenset[ops.Qid]
|
|
93
93
|
):
|
|
94
94
|
"""Checks if a group of Pauli strings are Qubit-Wise Commuting.
|
|
95
95
|
|
|
@@ -130,14 +130,14 @@ def _validate_single_pauli_string(pauli_str: ops.PauliString):
|
|
|
130
130
|
|
|
131
131
|
|
|
132
132
|
def _validate_input(
|
|
133
|
-
circuits_to_pauli:
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
circuits_to_pauli: (
|
|
134
|
+
dict[circuits.FrozenCircuit, list[ops.PauliString]]
|
|
135
|
+
| dict[circuits.FrozenCircuit, list[list[ops.PauliString]]]
|
|
136
|
+
),
|
|
137
137
|
pauli_repetitions: int,
|
|
138
138
|
readout_repetitions: int,
|
|
139
139
|
num_random_bitstrings: int,
|
|
140
|
-
rng_or_seed:
|
|
140
|
+
rng_or_seed: np.random.Generator | int,
|
|
141
141
|
):
|
|
142
142
|
if not circuits_to_pauli:
|
|
143
143
|
raise ValueError("Input circuits must not be empty.")
|
|
@@ -146,7 +146,7 @@ def _validate_input(
|
|
|
146
146
|
if not isinstance(circuit, circuits.FrozenCircuit):
|
|
147
147
|
raise TypeError("All keys in 'circuits_to_pauli' must be FrozenCircuit instances.")
|
|
148
148
|
|
|
149
|
-
first_value:
|
|
149
|
+
first_value: list[ops.PauliString] | list[list[ops.PauliString]] = next(
|
|
150
150
|
iter(circuits_to_pauli.values()) # type: ignore
|
|
151
151
|
)
|
|
152
152
|
for circuit, pauli_strs_list in circuits_to_pauli.items():
|
|
@@ -198,23 +198,23 @@ def _validate_input(
|
|
|
198
198
|
|
|
199
199
|
|
|
200
200
|
def _normalize_input_paulis(
|
|
201
|
-
circuits_to_pauli:
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
) ->
|
|
201
|
+
circuits_to_pauli: (
|
|
202
|
+
dict[circuits.FrozenCircuit, list[ops.PauliString]]
|
|
203
|
+
| dict[circuits.FrozenCircuit, list[list[ops.PauliString]]]
|
|
204
|
+
),
|
|
205
|
+
) -> dict[circuits.FrozenCircuit, list[list[ops.PauliString]]]:
|
|
206
206
|
first_value = next(iter(circuits_to_pauli.values()))
|
|
207
207
|
if (
|
|
208
208
|
first_value
|
|
209
209
|
and isinstance(first_value, list)
|
|
210
210
|
and isinstance(first_value[0], ops.PauliString)
|
|
211
211
|
):
|
|
212
|
-
input_dict = cast(
|
|
213
|
-
normalized_circuits_to_pauli:
|
|
212
|
+
input_dict = cast(dict[circuits.FrozenCircuit, list[ops.PauliString]], circuits_to_pauli)
|
|
213
|
+
normalized_circuits_to_pauli: dict[circuits.FrozenCircuit, list[list[ops.PauliString]]] = {}
|
|
214
214
|
for circuit, paulis in input_dict.items():
|
|
215
215
|
normalized_circuits_to_pauli[circuit] = [[ps] for ps in paulis]
|
|
216
216
|
return normalized_circuits_to_pauli
|
|
217
|
-
return cast(
|
|
217
|
+
return cast(dict[circuits.FrozenCircuit, list[list[ops.PauliString]]], circuits_to_pauli)
|
|
218
218
|
|
|
219
219
|
|
|
220
220
|
def _pauli_strings_to_basis_change_ops(
|
|
@@ -282,7 +282,7 @@ def _process_pauli_measurement_results(
|
|
|
282
282
|
qubits: list[ops.Qid],
|
|
283
283
|
pauli_string_groups: list[list[ops.PauliString]],
|
|
284
284
|
circuit_results: list[ResultDict],
|
|
285
|
-
calibration_results:
|
|
285
|
+
calibration_results: dict[tuple[ops.Qid, ...], SingleQubitReadoutCalibrationResult],
|
|
286
286
|
pauli_repetitions: int,
|
|
287
287
|
timestamp: float,
|
|
288
288
|
disable_readout_mitigation: bool = False,
|
|
@@ -310,7 +310,7 @@ def _process_pauli_measurement_results(
|
|
|
310
310
|
A list of PauliStringMeasurementResult.
|
|
311
311
|
"""
|
|
312
312
|
|
|
313
|
-
pauli_measurement_results:
|
|
313
|
+
pauli_measurement_results: list[PauliStringMeasurementResult] = []
|
|
314
314
|
|
|
315
315
|
for pauli_group_index, circuit_result in enumerate(circuit_results):
|
|
316
316
|
measurement_results = circuit_result.measurements["m"]
|
|
@@ -368,16 +368,16 @@ def _process_pauli_measurement_results(
|
|
|
368
368
|
|
|
369
369
|
|
|
370
370
|
def measure_pauli_strings(
|
|
371
|
-
circuits_to_pauli:
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
371
|
+
circuits_to_pauli: (
|
|
372
|
+
dict[circuits.FrozenCircuit, list[ops.PauliString]]
|
|
373
|
+
| dict[circuits.FrozenCircuit, list[list[ops.PauliString]]]
|
|
374
|
+
),
|
|
375
375
|
sampler: work.Sampler,
|
|
376
376
|
pauli_repetitions: int,
|
|
377
377
|
readout_repetitions: int,
|
|
378
378
|
num_random_bitstrings: int,
|
|
379
|
-
rng_or_seed:
|
|
380
|
-
) ->
|
|
379
|
+
rng_or_seed: np.random.Generator | int,
|
|
380
|
+
) -> list[CircuitToPauliStringsMeasurementResult]:
|
|
381
381
|
"""Measures expectation values of Pauli strings on given circuits with/without
|
|
382
382
|
readout error mitigation.
|
|
383
383
|
|
|
@@ -392,11 +392,11 @@ def measure_pauli_strings(
|
|
|
392
392
|
|
|
393
393
|
Args:
|
|
394
394
|
circuits_to_pauli: A dictionary mapping circuits to either:
|
|
395
|
-
- A list of QWC groups (
|
|
395
|
+
- A list of QWC groups (list[list[ops.PauliString]]). Each QWC group
|
|
396
396
|
is a list of PauliStrings that are mutually Qubit-Wise Commuting.
|
|
397
397
|
Pauli strings within the same group will be calculated using the
|
|
398
398
|
same measurement results.
|
|
399
|
-
- A list of PauliStrings (
|
|
399
|
+
- A list of PauliStrings (list[ops.PauliString]). In this case, each
|
|
400
400
|
PauliString is treated as its own measurement group.
|
|
401
401
|
sampler: The sampler to use.
|
|
402
402
|
pauli_repetitions: The number of repetitions for each circuit when measuring
|
|
@@ -460,7 +460,7 @@ def measure_pauli_strings(
|
|
|
460
460
|
)
|
|
461
461
|
|
|
462
462
|
# Process the results to calculate expectation values
|
|
463
|
-
results:
|
|
463
|
+
results: list[CircuitToPauliStringsMeasurementResult] = []
|
|
464
464
|
circuit_result_index = 0
|
|
465
465
|
for input_circuit, pauli_string_groups in normalized_circuits_to_pauli.items():
|
|
466
466
|
|