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
cirq/devices/grid_qubit.py
CHANGED
|
@@ -17,7 +17,7 @@ from __future__ import annotations
|
|
|
17
17
|
import abc
|
|
18
18
|
import functools
|
|
19
19
|
import weakref
|
|
20
|
-
from typing import Any,
|
|
20
|
+
from typing import Any, Iterable, TYPE_CHECKING
|
|
21
21
|
|
|
22
22
|
import numpy as np
|
|
23
23
|
from typing_extensions import Self
|
|
@@ -35,7 +35,7 @@ class _BaseGridQid(ops.Qid):
|
|
|
35
35
|
_row: int
|
|
36
36
|
_col: int
|
|
37
37
|
_dimension: int
|
|
38
|
-
_comp_key:
|
|
38
|
+
_comp_key: tuple[int, int] | None = None
|
|
39
39
|
_hash: int
|
|
40
40
|
|
|
41
41
|
def __hash__(self) -> int:
|
|
@@ -116,7 +116,7 @@ class _BaseGridQid(ops.Qid):
|
|
|
116
116
|
and abs(self._row - other._row) + abs(self._col - other._col) == 1
|
|
117
117
|
)
|
|
118
118
|
|
|
119
|
-
def neighbors(self, qids:
|
|
119
|
+
def neighbors(self, qids: Iterable[ops.Qid] | None = None) -> set[_BaseGridQid]:
|
|
120
120
|
"""Returns qubits that are potential neighbors to this GridQid
|
|
121
121
|
|
|
122
122
|
Args:
|
|
@@ -135,7 +135,7 @@ class _BaseGridQid(ops.Qid):
|
|
|
135
135
|
def __complex__(self) -> complex:
|
|
136
136
|
return self._col + 1j * self._row
|
|
137
137
|
|
|
138
|
-
def __add__(self, other:
|
|
138
|
+
def __add__(self, other: tuple[int, int] | Self) -> Self:
|
|
139
139
|
if isinstance(other, _BaseGridQid):
|
|
140
140
|
if self.dimension != other.dimension:
|
|
141
141
|
raise TypeError(
|
|
@@ -154,7 +154,7 @@ class _BaseGridQid(ops.Qid):
|
|
|
154
154
|
)
|
|
155
155
|
return self._with_row_col(row=self._row + other[0], col=self._col + other[1])
|
|
156
156
|
|
|
157
|
-
def __sub__(self, other:
|
|
157
|
+
def __sub__(self, other: tuple[int, int] | Self) -> Self:
|
|
158
158
|
if isinstance(other, _BaseGridQid):
|
|
159
159
|
if self.dimension != other.dimension:
|
|
160
160
|
raise TypeError(
|
|
@@ -173,10 +173,10 @@ class _BaseGridQid(ops.Qid):
|
|
|
173
173
|
)
|
|
174
174
|
return self._with_row_col(row=self._row - other[0], col=self._col - other[1])
|
|
175
175
|
|
|
176
|
-
def __radd__(self, other:
|
|
176
|
+
def __radd__(self, other: tuple[int, int]) -> Self:
|
|
177
177
|
return self + other
|
|
178
178
|
|
|
179
|
-
def __rsub__(self, other:
|
|
179
|
+
def __rsub__(self, other: tuple[int, int]) -> Self:
|
|
180
180
|
return -self + other
|
|
181
181
|
|
|
182
182
|
def __neg__(self) -> Self:
|
|
@@ -204,7 +204,7 @@ class GridQid(_BaseGridQid):
|
|
|
204
204
|
|
|
205
205
|
# Cache of existing GridQid instances, returned by __new__ if available.
|
|
206
206
|
# Holds weak references so instances can still be garbage collected.
|
|
207
|
-
_cache = weakref.WeakValueDictionary[
|
|
207
|
+
_cache = weakref.WeakValueDictionary[tuple[int, int, int], 'cirq.GridQid']()
|
|
208
208
|
|
|
209
209
|
def __new__(cls, row: int, col: int, *, dimension: int) -> cirq.GridQid:
|
|
210
210
|
"""Creates a grid qid at the given row, col coordinate
|
|
@@ -233,14 +233,14 @@ class GridQid(_BaseGridQid):
|
|
|
233
233
|
return (self._row, self._col), {"dimension": self._dimension}
|
|
234
234
|
|
|
235
235
|
# avoid pickling the _hash value, attributes are already stored with __getnewargs_ex__
|
|
236
|
-
def __getstate__(self) ->
|
|
236
|
+
def __getstate__(self) -> dict[str, Any]:
|
|
237
237
|
return {}
|
|
238
238
|
|
|
239
239
|
def _with_row_col(self, row: int, col: int) -> GridQid:
|
|
240
240
|
return GridQid(row, col, dimension=self._dimension)
|
|
241
241
|
|
|
242
242
|
@staticmethod
|
|
243
|
-
def square(diameter: int, top: int = 0, left: int = 0, *, dimension: int) ->
|
|
243
|
+
def square(diameter: int, top: int = 0, left: int = 0, *, dimension: int) -> list[GridQid]:
|
|
244
244
|
"""Returns a square of GridQid.
|
|
245
245
|
|
|
246
246
|
Args:
|
|
@@ -256,7 +256,7 @@ class GridQid(_BaseGridQid):
|
|
|
256
256
|
return GridQid.rect(diameter, diameter, top=top, left=left, dimension=dimension)
|
|
257
257
|
|
|
258
258
|
@staticmethod
|
|
259
|
-
def rect(rows: int, cols: int, top: int = 0, left: int = 0, *, dimension: int) ->
|
|
259
|
+
def rect(rows: int, cols: int, top: int = 0, left: int = 0, *, dimension: int) -> list[GridQid]:
|
|
260
260
|
"""Returns a rectangle of GridQid.
|
|
261
261
|
|
|
262
262
|
Args:
|
|
@@ -277,7 +277,7 @@ class GridQid(_BaseGridQid):
|
|
|
277
277
|
]
|
|
278
278
|
|
|
279
279
|
@staticmethod
|
|
280
|
-
def from_diagram(diagram: str, dimension: int) ->
|
|
280
|
+
def from_diagram(diagram: str, dimension: int) -> list[GridQid]:
|
|
281
281
|
"""Parse ASCII art device layout into a device.
|
|
282
282
|
|
|
283
283
|
As an example, the below diagram will create a list of GridQid in a
|
|
@@ -342,7 +342,7 @@ class GridQid(_BaseGridQid):
|
|
|
342
342
|
wire_symbols=(f"({self._row}, {self._col}) (d={self._dimension})",)
|
|
343
343
|
)
|
|
344
344
|
|
|
345
|
-
def _json_dict_(self) ->
|
|
345
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
346
346
|
return protocols.obj_to_dict_helper(self, ['row', 'col', 'dimension'])
|
|
347
347
|
|
|
348
348
|
|
|
@@ -367,7 +367,7 @@ class GridQubit(_BaseGridQid):
|
|
|
367
367
|
|
|
368
368
|
# Cache of existing GridQubit instances, returned by __new__ if available.
|
|
369
369
|
# Holds weak references so instances can still be garbage collected.
|
|
370
|
-
_cache = weakref.WeakValueDictionary[
|
|
370
|
+
_cache = weakref.WeakValueDictionary[tuple[int, int], 'cirq.GridQubit']()
|
|
371
371
|
|
|
372
372
|
def __new__(cls, row: int, col: int) -> cirq.GridQubit:
|
|
373
373
|
"""Creates a grid qubit at the given row, col coordinate
|
|
@@ -391,14 +391,14 @@ class GridQubit(_BaseGridQid):
|
|
|
391
391
|
return (self._row, self._col)
|
|
392
392
|
|
|
393
393
|
# avoid pickling the _hash value, attributes are already stored with __getnewargs__
|
|
394
|
-
def __getstate__(self) ->
|
|
394
|
+
def __getstate__(self) -> dict[str, Any]:
|
|
395
395
|
return {}
|
|
396
396
|
|
|
397
397
|
def _with_row_col(self, row: int, col: int) -> GridQubit:
|
|
398
398
|
return GridQubit(row, col)
|
|
399
399
|
|
|
400
400
|
@staticmethod
|
|
401
|
-
def square(diameter: int, top: int = 0, left: int = 0) ->
|
|
401
|
+
def square(diameter: int, top: int = 0, left: int = 0) -> list[GridQubit]:
|
|
402
402
|
"""Returns a square of GridQubits.
|
|
403
403
|
|
|
404
404
|
Args:
|
|
@@ -412,7 +412,7 @@ class GridQubit(_BaseGridQid):
|
|
|
412
412
|
return GridQubit.rect(diameter, diameter, top=top, left=left)
|
|
413
413
|
|
|
414
414
|
@staticmethod
|
|
415
|
-
def rect(rows: int, cols: int, top: int = 0, left: int = 0) ->
|
|
415
|
+
def rect(rows: int, cols: int, top: int = 0, left: int = 0) -> list[GridQubit]:
|
|
416
416
|
"""Returns a rectangle of GridQubits.
|
|
417
417
|
|
|
418
418
|
Args:
|
|
@@ -431,7 +431,7 @@ class GridQubit(_BaseGridQid):
|
|
|
431
431
|
]
|
|
432
432
|
|
|
433
433
|
@staticmethod
|
|
434
|
-
def from_diagram(diagram: str) ->
|
|
434
|
+
def from_diagram(diagram: str) -> list[GridQubit]:
|
|
435
435
|
"""Parse ASCII art into device layout info.
|
|
436
436
|
|
|
437
437
|
As an example, the below diagram will create a list of
|
|
@@ -491,11 +491,11 @@ class GridQubit(_BaseGridQid):
|
|
|
491
491
|
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
492
492
|
return protocols.CircuitDiagramInfo(wire_symbols=(f"({self._row}, {self._col})",))
|
|
493
493
|
|
|
494
|
-
def _json_dict_(self) ->
|
|
494
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
495
495
|
return protocols.obj_to_dict_helper(self, ['row', 'col'])
|
|
496
496
|
|
|
497
497
|
|
|
498
|
-
def _ascii_diagram_to_coords(diagram: str) ->
|
|
498
|
+
def _ascii_diagram_to_coords(diagram: str) -> list[tuple[int, int]]:
|
|
499
499
|
"""Parse ASCII art device layout into info about qids coordinates
|
|
500
500
|
|
|
501
501
|
Args:
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
import dataclasses
|
|
18
|
-
from typing import Any,
|
|
18
|
+
from typing import Any, Sequence, TYPE_CHECKING
|
|
19
19
|
|
|
20
20
|
from cirq import devices
|
|
21
21
|
from cirq.devices import noise_utils
|
|
@@ -44,21 +44,21 @@ class InsertionNoiseModel(devices.NoiseModel):
|
|
|
44
44
|
with PHYSICAL_GATE_TAG.
|
|
45
45
|
"""
|
|
46
46
|
|
|
47
|
-
ops_added:
|
|
47
|
+
ops_added: dict[noise_utils.OpIdentifier, cirq.Operation] = dataclasses.field(
|
|
48
48
|
default_factory=dict
|
|
49
49
|
)
|
|
50
50
|
prepend: bool = False
|
|
51
51
|
require_physical_tag: bool = True
|
|
52
52
|
|
|
53
53
|
def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]) -> cirq.OP_TREE:
|
|
54
|
-
noise_ops:
|
|
54
|
+
noise_ops: list[cirq.Operation] = []
|
|
55
55
|
candidate_ops = [
|
|
56
56
|
op
|
|
57
57
|
for op in moment
|
|
58
58
|
if (not self.require_physical_tag) or noise_utils.PHYSICAL_GATE_TAG in op.tags
|
|
59
59
|
]
|
|
60
60
|
for op in candidate_ops:
|
|
61
|
-
match_id:
|
|
61
|
+
match_id: noise_utils.OpIdentifier | None = None
|
|
62
62
|
candidate_ids = [op_id for op_id in self.ops_added if op in op_id]
|
|
63
63
|
for op_id in candidate_ids:
|
|
64
64
|
if match_id is None or op_id.is_proper_subtype_of(match_id):
|
|
@@ -82,7 +82,7 @@ class InsertionNoiseModel(devices.NoiseModel):
|
|
|
82
82
|
+ f' require_physical_tag={self.require_physical_tag})'
|
|
83
83
|
)
|
|
84
84
|
|
|
85
|
-
def _json_dict_(self) ->
|
|
85
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
86
86
|
return {
|
|
87
87
|
'ops_added': list(self.ops_added.items()),
|
|
88
88
|
'prepend': self.prepend,
|
cirq/devices/line_qubit.py
CHANGED
|
@@ -17,7 +17,7 @@ from __future__ import annotations
|
|
|
17
17
|
import abc
|
|
18
18
|
import functools
|
|
19
19
|
import weakref
|
|
20
|
-
from typing import Any,
|
|
20
|
+
from typing import Any, Iterable, Sequence, TYPE_CHECKING
|
|
21
21
|
|
|
22
22
|
from typing_extensions import Self
|
|
23
23
|
|
|
@@ -108,7 +108,7 @@ class _BaseLineQid(ops.Qid):
|
|
|
108
108
|
"""
|
|
109
109
|
return isinstance(other, _BaseLineQid) and abs(self._x - other._x) == 1
|
|
110
110
|
|
|
111
|
-
def neighbors(self, qids:
|
|
111
|
+
def neighbors(self, qids: Iterable[ops.Qid] | None = None) -> set[_BaseLineQid]:
|
|
112
112
|
"""Returns qubits that are potential neighbors to this LineQubit
|
|
113
113
|
|
|
114
114
|
Args:
|
|
@@ -120,7 +120,7 @@ class _BaseLineQid(ops.Qid):
|
|
|
120
120
|
def _with_x(self, x: int) -> Self:
|
|
121
121
|
"""Returns a qubit with the same type but a different value of `x`."""
|
|
122
122
|
|
|
123
|
-
def __add__(self, other:
|
|
123
|
+
def __add__(self, other: int | Self) -> Self:
|
|
124
124
|
if isinstance(other, _BaseLineQid):
|
|
125
125
|
if self._dimension != other._dimension:
|
|
126
126
|
raise TypeError(
|
|
@@ -132,7 +132,7 @@ class _BaseLineQid(ops.Qid):
|
|
|
132
132
|
raise TypeError(f"Can only add ints and {type(self).__name__}. Instead was {other}")
|
|
133
133
|
return self._with_x(self._x + other)
|
|
134
134
|
|
|
135
|
-
def __sub__(self, other:
|
|
135
|
+
def __sub__(self, other: int | Self) -> Self:
|
|
136
136
|
if isinstance(other, _BaseLineQid):
|
|
137
137
|
if self._dimension != other._dimension:
|
|
138
138
|
raise TypeError(
|
|
@@ -184,7 +184,7 @@ class LineQid(_BaseLineQid):
|
|
|
184
184
|
|
|
185
185
|
# Cache of existing LineQid instances, returned by __new__ if available.
|
|
186
186
|
# Holds weak references so instances can still be garbage collected.
|
|
187
|
-
_cache = weakref.WeakValueDictionary[
|
|
187
|
+
_cache = weakref.WeakValueDictionary[tuple[int, int], 'cirq.LineQid']()
|
|
188
188
|
|
|
189
189
|
def __new__(cls, x: int, dimension: int) -> cirq.LineQid:
|
|
190
190
|
"""Initializes a line qid at the given x coordinate.
|
|
@@ -211,14 +211,14 @@ class LineQid(_BaseLineQid):
|
|
|
211
211
|
return (self._x, self._dimension)
|
|
212
212
|
|
|
213
213
|
# avoid pickling the _hash value, attributes are already stored with __getnewargs__
|
|
214
|
-
def __getstate__(self) ->
|
|
214
|
+
def __getstate__(self) -> dict[str, Any]:
|
|
215
215
|
return {}
|
|
216
216
|
|
|
217
217
|
def _with_x(self, x: int) -> LineQid:
|
|
218
218
|
return LineQid(x, dimension=self._dimension)
|
|
219
219
|
|
|
220
220
|
@staticmethod
|
|
221
|
-
def range(*range_args, dimension: int) ->
|
|
221
|
+
def range(*range_args, dimension: int) -> list[LineQid]:
|
|
222
222
|
"""Returns a range of line qids.
|
|
223
223
|
|
|
224
224
|
Args:
|
|
@@ -232,7 +232,7 @@ class LineQid(_BaseLineQid):
|
|
|
232
232
|
return [LineQid(i, dimension=dimension) for i in range(*range_args)]
|
|
233
233
|
|
|
234
234
|
@staticmethod
|
|
235
|
-
def for_qid_shape(qid_shape: Sequence[int], start: int = 0, step: int = 1) ->
|
|
235
|
+
def for_qid_shape(qid_shape: Sequence[int], start: int = 0, step: int = 1) -> list[LineQid]:
|
|
236
236
|
"""Returns a range of line qids for each entry in `qid_shape` with
|
|
237
237
|
matching dimension.
|
|
238
238
|
|
|
@@ -246,7 +246,7 @@ class LineQid(_BaseLineQid):
|
|
|
246
246
|
]
|
|
247
247
|
|
|
248
248
|
@staticmethod
|
|
249
|
-
def for_gate(val: Any, start: int = 0, step: int = 1) ->
|
|
249
|
+
def for_gate(val: Any, start: int = 0, step: int = 1) -> list[LineQid]:
|
|
250
250
|
"""Returns a range of line qids with the same qid shape as the gate.
|
|
251
251
|
|
|
252
252
|
Args:
|
|
@@ -269,7 +269,7 @@ class LineQid(_BaseLineQid):
|
|
|
269
269
|
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
270
270
|
return protocols.CircuitDiagramInfo(wire_symbols=(f"{self._x} (d={self._dimension})",))
|
|
271
271
|
|
|
272
|
-
def _json_dict_(self) ->
|
|
272
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
273
273
|
return protocols.obj_to_dict_helper(self, ['x', 'dimension'])
|
|
274
274
|
|
|
275
275
|
|
|
@@ -315,14 +315,14 @@ class LineQubit(_BaseLineQid):
|
|
|
315
315
|
return (self._x,)
|
|
316
316
|
|
|
317
317
|
# avoid pickling the _hash value, attributes are already stored with __getnewargs__
|
|
318
|
-
def __getstate__(self) ->
|
|
318
|
+
def __getstate__(self) -> dict[str, Any]:
|
|
319
319
|
return {}
|
|
320
320
|
|
|
321
321
|
def _with_x(self, x: int) -> LineQubit:
|
|
322
322
|
return LineQubit(x)
|
|
323
323
|
|
|
324
324
|
@staticmethod
|
|
325
|
-
def range(*range_args) ->
|
|
325
|
+
def range(*range_args) -> list[LineQubit]:
|
|
326
326
|
"""Returns a range of line qubits.
|
|
327
327
|
|
|
328
328
|
Args:
|
|
@@ -342,5 +342,5 @@ class LineQubit(_BaseLineQid):
|
|
|
342
342
|
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
343
343
|
return protocols.CircuitDiagramInfo(wire_symbols=(f"{self._x}",))
|
|
344
344
|
|
|
345
|
-
def _json_dict_(self) ->
|
|
345
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
346
346
|
return protocols.obj_to_dict_helper(self, ['x'])
|
cirq/devices/named_topologies.py
CHANGED
|
@@ -17,18 +17,7 @@ from __future__ import annotations
|
|
|
17
17
|
import abc
|
|
18
18
|
import warnings
|
|
19
19
|
from dataclasses import dataclass
|
|
20
|
-
from typing import
|
|
21
|
-
Any,
|
|
22
|
-
Callable,
|
|
23
|
-
Dict,
|
|
24
|
-
Iterable,
|
|
25
|
-
List,
|
|
26
|
-
Optional,
|
|
27
|
-
Sequence,
|
|
28
|
-
Tuple,
|
|
29
|
-
TYPE_CHECKING,
|
|
30
|
-
Union,
|
|
31
|
-
)
|
|
20
|
+
from typing import Any, Callable, Iterable, Sequence, TYPE_CHECKING, Union
|
|
32
21
|
|
|
33
22
|
import networkx as nx
|
|
34
23
|
from matplotlib import pyplot as plt
|
|
@@ -59,12 +48,12 @@ class NamedTopology(metaclass=abc.ABCMeta):
|
|
|
59
48
|
"""A networkx graph representation of the topology."""
|
|
60
49
|
|
|
61
50
|
|
|
62
|
-
_GRIDLIKE_NODE = Union['cirq.GridQubit',
|
|
51
|
+
_GRIDLIKE_NODE = Union['cirq.GridQubit', tuple[int, int]]
|
|
63
52
|
|
|
64
53
|
|
|
65
54
|
def _node_and_coordinates(
|
|
66
55
|
nodes: Iterable[_GRIDLIKE_NODE],
|
|
67
|
-
) -> Iterable[
|
|
56
|
+
) -> Iterable[tuple[_GRIDLIKE_NODE, tuple[int, int]]]:
|
|
68
57
|
"""Yield tuples whose first element is the input node and the second is guaranteed to be a tuple
|
|
69
58
|
of two integers. The input node can be a tuple of ints or a GridQubit."""
|
|
70
59
|
for node in nodes:
|
|
@@ -76,8 +65,8 @@ def _node_and_coordinates(
|
|
|
76
65
|
|
|
77
66
|
|
|
78
67
|
def draw_gridlike(
|
|
79
|
-
graph: nx.Graph, ax:
|
|
80
|
-
) ->
|
|
68
|
+
graph: nx.Graph, ax: plt.Axes | None = None, tilted: bool = True, **kwargs
|
|
69
|
+
) -> dict[Any, tuple[int, int]]:
|
|
81
70
|
"""Draw a grid-like graph using Matplotlib.
|
|
82
71
|
|
|
83
72
|
This wraps nx.draw_networkx to produce a matplotlib drawing of the graph. Nodes
|
|
@@ -129,11 +118,11 @@ class LineTopology(NamedTopology):
|
|
|
129
118
|
)
|
|
130
119
|
object.__setattr__(self, 'graph', graph)
|
|
131
120
|
|
|
132
|
-
def nodes_as_linequbits(self) ->
|
|
121
|
+
def nodes_as_linequbits(self) -> list[cirq.LineQubit]:
|
|
133
122
|
"""Get the graph nodes as cirq.LineQubit"""
|
|
134
123
|
return [LineQubit(x) for x in sorted(self.graph.nodes)]
|
|
135
124
|
|
|
136
|
-
def draw(self, ax=None, tilted: bool = True, **kwargs) ->
|
|
125
|
+
def draw(self, ax=None, tilted: bool = True, **kwargs) -> dict[Any, tuple[int, int]]:
|
|
137
126
|
"""Draw this graph using Matplotlib.
|
|
138
127
|
|
|
139
128
|
Args:
|
|
@@ -144,7 +133,7 @@ class LineTopology(NamedTopology):
|
|
|
144
133
|
g2 = nx.relabel_nodes(self.graph, {n: (n, 1) for n in self.graph.nodes})
|
|
145
134
|
return draw_gridlike(g2, ax=ax, tilted=tilted, **kwargs)
|
|
146
135
|
|
|
147
|
-
def nodes_to_linequbits(self, offset: int = 0) ->
|
|
136
|
+
def nodes_to_linequbits(self, offset: int = 0) -> dict[int, cirq.LineQubit]:
|
|
148
137
|
"""Return a mapping from graph nodes to `cirq.LineQubit`
|
|
149
138
|
|
|
150
139
|
Args:
|
|
@@ -152,7 +141,7 @@ class LineTopology(NamedTopology):
|
|
|
152
141
|
"""
|
|
153
142
|
return dict(enumerate(LineQubit.range(offset, offset + self.n_nodes)))
|
|
154
143
|
|
|
155
|
-
def _json_dict_(self) ->
|
|
144
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
156
145
|
return dataclass_json_dict(self)
|
|
157
146
|
|
|
158
147
|
def __repr__(self) -> str:
|
|
@@ -242,11 +231,11 @@ class TiltedSquareLattice(NamedTopology):
|
|
|
242
231
|
"""
|
|
243
232
|
return draw_gridlike(self.graph, ax=ax, tilted=tilted, **kwargs)
|
|
244
233
|
|
|
245
|
-
def nodes_as_gridqubits(self) ->
|
|
234
|
+
def nodes_as_gridqubits(self) -> list[cirq.GridQubit]:
|
|
246
235
|
"""Get the graph nodes as cirq.GridQubit"""
|
|
247
236
|
return [GridQubit(r, c) for r, c in sorted(self.graph.nodes)]
|
|
248
237
|
|
|
249
|
-
def nodes_to_gridqubits(self, offset=(0, 0)) ->
|
|
238
|
+
def nodes_to_gridqubits(self, offset=(0, 0)) -> dict[tuple[int, int], cirq.GridQubit]:
|
|
250
239
|
"""Return a mapping from graph nodes to `cirq.GridQubit`
|
|
251
240
|
|
|
252
241
|
Args:
|
|
@@ -255,7 +244,7 @@ class TiltedSquareLattice(NamedTopology):
|
|
|
255
244
|
"""
|
|
256
245
|
return {(r, c): GridQubit(r, c) + offset for r, c in self.graph.nodes}
|
|
257
246
|
|
|
258
|
-
def _json_dict_(self) ->
|
|
247
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
259
248
|
return dataclass_json_dict(self)
|
|
260
249
|
|
|
261
250
|
def __repr__(self) -> str:
|
|
@@ -264,7 +253,7 @@ class TiltedSquareLattice(NamedTopology):
|
|
|
264
253
|
|
|
265
254
|
def get_placements(
|
|
266
255
|
big_graph: nx.Graph, small_graph: nx.Graph, max_placements=100_000
|
|
267
|
-
) ->
|
|
256
|
+
) -> list[dict]:
|
|
268
257
|
"""Get 'placements' mapping small_graph nodes onto those of `big_graph`.
|
|
269
258
|
|
|
270
259
|
This function considers monomorphisms with a restriction: we restrict only to unique set
|
|
@@ -311,7 +300,7 @@ def get_placements(
|
|
|
311
300
|
|
|
312
301
|
|
|
313
302
|
def _is_valid_placement_helper(
|
|
314
|
-
big_graph: nx.Graph, small_mapped: nx.Graph, small_to_big_mapping:
|
|
303
|
+
big_graph: nx.Graph, small_mapped: nx.Graph, small_to_big_mapping: dict
|
|
315
304
|
):
|
|
316
305
|
"""Helper function for `is_valid_placement` that assumes the mapping of `small_graph` has
|
|
317
306
|
already occurred.
|
|
@@ -322,7 +311,7 @@ def _is_valid_placement_helper(
|
|
|
322
311
|
return (subgraph.nodes == small_mapped.nodes) and (subgraph.edges == small_mapped.edges)
|
|
323
312
|
|
|
324
313
|
|
|
325
|
-
def is_valid_placement(big_graph: nx.Graph, small_graph: nx.Graph, small_to_big_mapping:
|
|
314
|
+
def is_valid_placement(big_graph: nx.Graph, small_graph: nx.Graph, small_to_big_mapping: dict):
|
|
326
315
|
"""Return whether the given placement is a valid placement of small_graph onto big_graph.
|
|
327
316
|
|
|
328
317
|
This is done by making sure all the nodes and edges on the mapped version of `small_graph`
|
|
@@ -344,11 +333,11 @@ def is_valid_placement(big_graph: nx.Graph, small_graph: nx.Graph, small_to_big_
|
|
|
344
333
|
def draw_placements(
|
|
345
334
|
big_graph: nx.Graph,
|
|
346
335
|
small_graph: nx.Graph,
|
|
347
|
-
small_to_big_mappings: Sequence[
|
|
336
|
+
small_to_big_mappings: Sequence[dict],
|
|
348
337
|
max_plots: int = 20,
|
|
349
|
-
axes:
|
|
338
|
+
axes: Sequence[plt.Axes] | None = None,
|
|
350
339
|
tilted: bool = True,
|
|
351
|
-
bad_placement_callback:
|
|
340
|
+
bad_placement_callback: Callable[[plt.Axes, int], None] | None = None,
|
|
352
341
|
):
|
|
353
342
|
"""Draw a visualization of placements from small_graph onto big_graph using Matplotlib.
|
|
354
343
|
|
cirq/devices/noise_model.py
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Any, Callable,
|
|
17
|
+
from typing import Any, Callable, Iterable, Sequence, TYPE_CHECKING, Union
|
|
18
18
|
|
|
19
19
|
from cirq import ops, protocols, value
|
|
20
20
|
from cirq._doc import document
|
|
@@ -196,7 +196,7 @@ class _NoNoiseModel(NoiseModel):
|
|
|
196
196
|
def __repr__(self) -> str:
|
|
197
197
|
return 'cirq.NO_NOISE'
|
|
198
198
|
|
|
199
|
-
def _json_dict_(self) ->
|
|
199
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
200
200
|
return protocols.obj_to_dict_helper(self, [])
|
|
201
201
|
|
|
202
202
|
def _has_unitary_(self) -> bool:
|
|
@@ -247,7 +247,7 @@ class ConstantQubitNoiseModel(NoiseModel):
|
|
|
247
247
|
]
|
|
248
248
|
return output[::-1] if self._prepend else output
|
|
249
249
|
|
|
250
|
-
def _json_dict_(self) ->
|
|
250
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
251
251
|
return protocols.obj_to_dict_helper(self, ['qubit_noise_gate'])
|
|
252
252
|
|
|
253
253
|
def _has_unitary_(self) -> bool:
|
cirq/devices/noise_properties.py
CHANGED
|
@@ -22,7 +22,7 @@ noise models to produce a single noise model which replicates device noise.
|
|
|
22
22
|
from __future__ import annotations
|
|
23
23
|
|
|
24
24
|
import abc
|
|
25
|
-
from typing import Iterable,
|
|
25
|
+
from typing import Iterable, Sequence, TYPE_CHECKING
|
|
26
26
|
|
|
27
27
|
from cirq import _import, devices, ops, protocols
|
|
28
28
|
from cirq.devices.noise_utils import PHYSICAL_GATE_TAG
|
|
@@ -37,7 +37,7 @@ class NoiseProperties(abc.ABC):
|
|
|
37
37
|
"""Noise-defining properties for a quantum device."""
|
|
38
38
|
|
|
39
39
|
@abc.abstractmethod
|
|
40
|
-
def build_noise_models(self) ->
|
|
40
|
+
def build_noise_models(self) -> list[cirq.NoiseModel]:
|
|
41
41
|
"""Construct all NoiseModels associated with this NoiseProperties."""
|
|
42
42
|
|
|
43
43
|
|
|
@@ -14,8 +14,6 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import List, Tuple
|
|
18
|
-
|
|
19
17
|
import cirq
|
|
20
18
|
from cirq.devices.insertion_noise_model import InsertionNoiseModel
|
|
21
19
|
from cirq.devices.noise_properties import NoiseModelFromNoiseProperties, NoiseProperties
|
|
@@ -25,7 +23,7 @@ from cirq.devices.noise_utils import OpIdentifier, PHYSICAL_GATE_TAG
|
|
|
25
23
|
# These properties are for testing purposes only - they are not representative
|
|
26
24
|
# of device behavior for any existing hardware.
|
|
27
25
|
class SampleNoiseProperties(NoiseProperties):
|
|
28
|
-
def __init__(self, system_qubits:
|
|
26
|
+
def __init__(self, system_qubits: list[cirq.Qid], qubit_pairs: list[tuple[cirq.Qid, cirq.Qid]]):
|
|
29
27
|
self.qubits = system_qubits
|
|
30
28
|
self.qubit_pairs = qubit_pairs
|
|
31
29
|
|
cirq/devices/noise_utils.py
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Any,
|
|
17
|
+
from typing import Any, TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
from cirq import ops, protocols, qis, value
|
|
20
20
|
from cirq._compat import deprecated, proper_repr
|
|
@@ -31,18 +31,18 @@ PHYSICAL_GATE_TAG = 'physical_gate'
|
|
|
31
31
|
class OpIdentifier:
|
|
32
32
|
"""Identifies an operation by gate and (optionally) target qubits."""
|
|
33
33
|
|
|
34
|
-
def __init__(self, gate_type:
|
|
34
|
+
def __init__(self, gate_type: type[cirq.Gate], *qubits: cirq.Qid):
|
|
35
35
|
self._gate_type = gate_type
|
|
36
36
|
self._gate_family = ops.GateFamily(gate_type)
|
|
37
|
-
self._qubits:
|
|
37
|
+
self._qubits: tuple[cirq.Qid, ...] = tuple(qubits)
|
|
38
38
|
|
|
39
39
|
@property
|
|
40
|
-
def gate_type(self) ->
|
|
40
|
+
def gate_type(self) -> type[cirq.Gate]:
|
|
41
41
|
# set to a type during initialization, never modified
|
|
42
42
|
return self._gate_type
|
|
43
43
|
|
|
44
44
|
@property
|
|
45
|
-
def qubits(self) ->
|
|
45
|
+
def qubits(self) -> tuple[cirq.Qid, ...]:
|
|
46
46
|
return self._qubits
|
|
47
47
|
|
|
48
48
|
def _predicate(self, *args, **kwargs):
|
|
@@ -67,7 +67,7 @@ class OpIdentifier:
|
|
|
67
67
|
else:
|
|
68
68
|
return False
|
|
69
69
|
|
|
70
|
-
def __contains__(self, item:
|
|
70
|
+
def __contains__(self, item: ops.Gate | ops.Operation) -> bool:
|
|
71
71
|
if isinstance(item, ops.Gate):
|
|
72
72
|
return (not self._qubits) and self._predicate(item)
|
|
73
73
|
return (
|
|
@@ -86,7 +86,7 @@ class OpIdentifier:
|
|
|
86
86
|
def _value_equality_values_(self) -> Any:
|
|
87
87
|
return (self.gate_type, self.qubits)
|
|
88
88
|
|
|
89
|
-
def _json_dict_(self) ->
|
|
89
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
90
90
|
if hasattr(self.gate_type, '__name__'):
|
|
91
91
|
return {'gate_type': protocols.json_cirq_type(self._gate_type), 'qubits': self._qubits}
|
|
92
92
|
return {'gate_type': self._gate_type, 'qubits': self._qubits}
|