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
cirq/ops/identity.py
CHANGED
|
@@ -17,7 +17,7 @@ from __future__ import annotations
|
|
|
17
17
|
|
|
18
18
|
import numbers
|
|
19
19
|
from types import NotImplementedType
|
|
20
|
-
from typing import Any,
|
|
20
|
+
from typing import Any, Sequence, TYPE_CHECKING
|
|
21
21
|
|
|
22
22
|
import numpy as np
|
|
23
23
|
import sympy
|
|
@@ -41,7 +41,7 @@ class IdentityGate(raw_types.Gate):
|
|
|
41
41
|
"""
|
|
42
42
|
|
|
43
43
|
def __init__(
|
|
44
|
-
self, num_qubits:
|
|
44
|
+
self, num_qubits: int | None = None, qid_shape: tuple[int, ...] | None = None
|
|
45
45
|
) -> None:
|
|
46
46
|
"""Inits IdentityGate.
|
|
47
47
|
|
|
@@ -68,7 +68,7 @@ class IdentityGate(raw_types.Gate):
|
|
|
68
68
|
def _act_on_(self, sim_state: cirq.SimulationStateBase, qubits: Sequence[cirq.Qid]):
|
|
69
69
|
return True
|
|
70
70
|
|
|
71
|
-
def _qid_shape_(self) ->
|
|
71
|
+
def _qid_shape_(self) -> tuple[int, ...]:
|
|
72
72
|
return self._qid_shape
|
|
73
73
|
|
|
74
74
|
def num_qubits(self) -> int:
|
|
@@ -79,7 +79,7 @@ class IdentityGate(raw_types.Gate):
|
|
|
79
79
|
return self
|
|
80
80
|
return NotImplemented
|
|
81
81
|
|
|
82
|
-
def _commutes_(self, other: Any, *, atol: float = 1e-8) ->
|
|
82
|
+
def _commutes_(self, other: Any, *, atol: float = 1e-8) -> bool | NotImplementedType:
|
|
83
83
|
"""The identity gate commutes with all other gates."""
|
|
84
84
|
if not isinstance(other, raw_types.Gate):
|
|
85
85
|
return NotImplemented
|
|
@@ -91,7 +91,7 @@ class IdentityGate(raw_types.Gate):
|
|
|
91
91
|
def _unitary_(self) -> np.ndarray:
|
|
92
92
|
return np.identity(np.prod(self._qid_shape, dtype=np.int64).item())
|
|
93
93
|
|
|
94
|
-
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) ->
|
|
94
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs) -> np.ndarray | None:
|
|
95
95
|
return args.target_tensor
|
|
96
96
|
|
|
97
97
|
def _pauli_expansion_(self) -> value.LinearDict[str]:
|
|
@@ -120,13 +120,13 @@ class IdentityGate(raw_types.Gate):
|
|
|
120
120
|
def _trace_distance_bound_(self) -> float:
|
|
121
121
|
return 0.0
|
|
122
122
|
|
|
123
|
-
def _json_dict_(self) ->
|
|
123
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
124
124
|
other = {}
|
|
125
125
|
if not all(d == 2 for d in self._qid_shape):
|
|
126
126
|
other['qid_shape'] = self._qid_shape
|
|
127
127
|
return {'num_qubits': len(self._qid_shape), **other}
|
|
128
128
|
|
|
129
|
-
def _mul_with_qubits(self, qubits:
|
|
129
|
+
def _mul_with_qubits(self, qubits: tuple[cirq.Qid, ...], other):
|
|
130
130
|
if isinstance(other, raw_types.Operation):
|
|
131
131
|
return other
|
|
132
132
|
if isinstance(other, numbers.Complex):
|
|
@@ -137,12 +137,12 @@ class IdentityGate(raw_types.Gate):
|
|
|
137
137
|
|
|
138
138
|
_rmul_with_qubits = _mul_with_qubits
|
|
139
139
|
|
|
140
|
-
def _circuit_diagram_info_(self, args) ->
|
|
140
|
+
def _circuit_diagram_info_(self, args) -> tuple[str, ...]:
|
|
141
141
|
if self.num_qubits() <= 0:
|
|
142
142
|
return NotImplemented
|
|
143
143
|
return ('I',) * self.num_qubits()
|
|
144
144
|
|
|
145
|
-
def _qasm_(self, args: cirq.QasmArgs, qubits:
|
|
145
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: tuple[cirq.Qid, ...]) -> str | None:
|
|
146
146
|
args.validate_version('2.0', '3.0')
|
|
147
147
|
return ''.join([args.format('id {0};\n', qubit) for qubit in qubits])
|
|
148
148
|
|
cirq/ops/kraus_channel.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from typing import Any,
|
|
5
|
+
from typing import Any, Iterable, Mapping, TYPE_CHECKING
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
|
|
@@ -32,7 +32,7 @@ class KrausChannel(raw_types.Gate):
|
|
|
32
32
|
def __init__(
|
|
33
33
|
self,
|
|
34
34
|
kraus_ops: Iterable[np.ndarray],
|
|
35
|
-
key:
|
|
35
|
+
key: str | cirq.MeasurementKey | None = None,
|
|
36
36
|
validate: bool = False,
|
|
37
37
|
):
|
|
38
38
|
kraus_ops = list(kraus_ops)
|
|
@@ -59,7 +59,7 @@ class KrausChannel(raw_types.Gate):
|
|
|
59
59
|
self._key = key
|
|
60
60
|
|
|
61
61
|
@staticmethod
|
|
62
|
-
def from_channel(channel: cirq.Gate, key:
|
|
62
|
+
def from_channel(channel: cirq.Gate, key: str | cirq.MeasurementKey | None = None):
|
|
63
63
|
"""Creates a copy of a channel with the given measurement key."""
|
|
64
64
|
return KrausChannel(kraus_ops=list(protocols.kraus(channel)), key=key)
|
|
65
65
|
|
|
@@ -95,16 +95,16 @@ class KrausChannel(raw_types.Gate):
|
|
|
95
95
|
return self
|
|
96
96
|
return KrausChannel(kraus_ops=self._kraus_ops, key=key_map[str(self._key)])
|
|
97
97
|
|
|
98
|
-
def _with_key_path_(self, path:
|
|
98
|
+
def _with_key_path_(self, path: tuple[str, ...]):
|
|
99
99
|
return KrausChannel(kraus_ops=self._kraus_ops, key=protocols.with_key_path(self._key, path))
|
|
100
100
|
|
|
101
|
-
def _with_key_path_prefix_(self, prefix:
|
|
101
|
+
def _with_key_path_prefix_(self, prefix: tuple[str, ...]):
|
|
102
102
|
return KrausChannel(
|
|
103
103
|
kraus_ops=self._kraus_ops, key=protocols.with_key_path_prefix(self._key, prefix)
|
|
104
104
|
)
|
|
105
105
|
|
|
106
106
|
def _with_rescoped_keys_(
|
|
107
|
-
self, path:
|
|
107
|
+
self, path: tuple[str, ...], bindable_keys: frozenset[cirq.MeasurementKey]
|
|
108
108
|
):
|
|
109
109
|
return KrausChannel(
|
|
110
110
|
kraus_ops=self._kraus_ops,
|
|
@@ -122,7 +122,7 @@ class KrausChannel(raw_types.Gate):
|
|
|
122
122
|
args.append(f'key=\'{self._key}\'')
|
|
123
123
|
return f'cirq.KrausChannel({", ".join(args)})'
|
|
124
124
|
|
|
125
|
-
def _json_dict_(self) ->
|
|
125
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
126
126
|
return protocols.obj_to_dict_helper(self, ['_kraus_ops', '_key'])
|
|
127
127
|
|
|
128
128
|
@classmethod
|
cirq/ops/linear_combinations.py
CHANGED
|
@@ -16,20 +16,7 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
import numbers
|
|
18
18
|
from collections import defaultdict
|
|
19
|
-
from typing import
|
|
20
|
-
AbstractSet,
|
|
21
|
-
Any,
|
|
22
|
-
DefaultDict,
|
|
23
|
-
Dict,
|
|
24
|
-
FrozenSet,
|
|
25
|
-
Iterable,
|
|
26
|
-
List,
|
|
27
|
-
Mapping,
|
|
28
|
-
Optional,
|
|
29
|
-
Tuple,
|
|
30
|
-
TYPE_CHECKING,
|
|
31
|
-
Union,
|
|
32
|
-
)
|
|
19
|
+
from typing import AbstractSet, Any, Iterable, Mapping, TYPE_CHECKING, Union
|
|
33
20
|
|
|
34
21
|
import numpy as np
|
|
35
22
|
import sympy
|
|
@@ -48,7 +35,7 @@ if TYPE_CHECKING:
|
|
|
48
35
|
|
|
49
36
|
import cirq
|
|
50
37
|
|
|
51
|
-
UnitPauliStringT =
|
|
38
|
+
UnitPauliStringT = frozenset[tuple[raw_types.Qid, pauli_gates.Pauli]]
|
|
52
39
|
PauliSumLike = Union[
|
|
53
40
|
complex, PauliString, 'PauliSum', pauli_string.SingleQubitPauliStringGateOperation
|
|
54
41
|
]
|
|
@@ -92,7 +79,7 @@ class LinearCombinationOfGates(value.LinearDict[raw_types.Gate]):
|
|
|
92
79
|
"""
|
|
93
80
|
super().__init__(terms, validator=self._is_compatible)
|
|
94
81
|
|
|
95
|
-
def num_qubits(self) ->
|
|
82
|
+
def num_qubits(self) -> int | None:
|
|
96
83
|
"""Returns number of qubits in the domain if known, None if unknown."""
|
|
97
84
|
if not self:
|
|
98
85
|
return None
|
|
@@ -102,29 +89,25 @@ class LinearCombinationOfGates(value.LinearDict[raw_types.Gate]):
|
|
|
102
89
|
def _is_compatible(self, gate: cirq.Gate) -> bool:
|
|
103
90
|
return self.num_qubits() is None or self.num_qubits() == gate.num_qubits()
|
|
104
91
|
|
|
105
|
-
def __add__(
|
|
106
|
-
self, other: Union[raw_types.Gate, LinearCombinationOfGates]
|
|
107
|
-
) -> LinearCombinationOfGates:
|
|
92
|
+
def __add__(self, other: raw_types.Gate | LinearCombinationOfGates) -> LinearCombinationOfGates:
|
|
108
93
|
if not isinstance(other, LinearCombinationOfGates):
|
|
109
94
|
other = other.wrap_in_linear_combination()
|
|
110
95
|
return super().__add__(other)
|
|
111
96
|
|
|
112
97
|
def __iadd__(
|
|
113
|
-
self, other:
|
|
98
|
+
self, other: raw_types.Gate | LinearCombinationOfGates
|
|
114
99
|
) -> LinearCombinationOfGates:
|
|
115
100
|
if not isinstance(other, LinearCombinationOfGates):
|
|
116
101
|
other = other.wrap_in_linear_combination()
|
|
117
102
|
return super().__iadd__(other)
|
|
118
103
|
|
|
119
|
-
def __sub__(
|
|
120
|
-
self, other: Union[raw_types.Gate, LinearCombinationOfGates]
|
|
121
|
-
) -> LinearCombinationOfGates:
|
|
104
|
+
def __sub__(self, other: raw_types.Gate | LinearCombinationOfGates) -> LinearCombinationOfGates:
|
|
122
105
|
if not isinstance(other, LinearCombinationOfGates):
|
|
123
106
|
other = other.wrap_in_linear_combination()
|
|
124
107
|
return super().__sub__(other)
|
|
125
108
|
|
|
126
109
|
def __isub__(
|
|
127
|
-
self, other:
|
|
110
|
+
self, other: raw_types.Gate | LinearCombinationOfGates
|
|
128
111
|
) -> LinearCombinationOfGates:
|
|
129
112
|
if not isinstance(other, LinearCombinationOfGates):
|
|
130
113
|
other = other.wrap_in_linear_combination()
|
|
@@ -239,7 +222,7 @@ class LinearCombinationOfOperations(value.LinearDict[raw_types.Operation]):
|
|
|
239
222
|
return isinstance(operation, raw_types.Operation)
|
|
240
223
|
|
|
241
224
|
@property
|
|
242
|
-
def qubits(self) ->
|
|
225
|
+
def qubits(self) -> tuple[raw_types.Qid, ...]:
|
|
243
226
|
"""Returns qubits acted on self."""
|
|
244
227
|
if not self:
|
|
245
228
|
return ()
|
|
@@ -319,7 +302,7 @@ class LinearCombinationOfOperations(value.LinearDict[raw_types.Operation]):
|
|
|
319
302
|
"""Computes Pauli expansion of self from Pauli expansions of terms."""
|
|
320
303
|
|
|
321
304
|
def extend_term(
|
|
322
|
-
pauli_names: str, qubits:
|
|
305
|
+
pauli_names: str, qubits: tuple[cirq.Qid, ...], all_qubits: tuple[cirq.Qid, ...]
|
|
323
306
|
) -> str:
|
|
324
307
|
"""Extends Pauli product on qubits to product on all_qubits."""
|
|
325
308
|
assert len(pauli_names) == len(qubits)
|
|
@@ -328,8 +311,8 @@ class LinearCombinationOfOperations(value.LinearDict[raw_types.Operation]):
|
|
|
328
311
|
|
|
329
312
|
def extend(
|
|
330
313
|
expansion: value.LinearDict[str],
|
|
331
|
-
qubits:
|
|
332
|
-
all_qubits:
|
|
314
|
+
qubits: tuple[cirq.Qid, ...],
|
|
315
|
+
all_qubits: tuple[cirq.Qid, ...],
|
|
333
316
|
) -> value.LinearDict[str]:
|
|
334
317
|
"""Extends Pauli expansion on qubits to expansion on all_qubits."""
|
|
335
318
|
return value.LinearDict(
|
|
@@ -360,7 +343,7 @@ def _is_linear_dict_of_unit_pauli_string(linear_dict: value.LinearDict[UnitPauli
|
|
|
360
343
|
|
|
361
344
|
|
|
362
345
|
def _pauli_string_from_unit(
|
|
363
|
-
unit: UnitPauliStringT, coefficient:
|
|
346
|
+
unit: UnitPauliStringT, coefficient: int | float | cirq.TParamValComplex = 1
|
|
364
347
|
):
|
|
365
348
|
return PauliString(qubit_pauli_map=dict(unit), coefficient=coefficient)
|
|
366
349
|
|
|
@@ -418,7 +401,7 @@ class PauliSum:
|
|
|
418
401
|
4.0+0.0j
|
|
419
402
|
"""
|
|
420
403
|
|
|
421
|
-
def __init__(self, linear_dict:
|
|
404
|
+
def __init__(self, linear_dict: value.LinearDict[UnitPauliStringT] | None = None):
|
|
422
405
|
"""Construct a PauliSum from a linear dictionary.
|
|
423
406
|
|
|
424
407
|
Note, the preferred method of constructing PauliSum objects is either implicitly
|
|
@@ -470,7 +453,7 @@ class PauliSum:
|
|
|
470
453
|
return PauliSum() + val
|
|
471
454
|
|
|
472
455
|
@classmethod
|
|
473
|
-
def from_pauli_strings(cls, terms:
|
|
456
|
+
def from_pauli_strings(cls, terms: PauliString | list[PauliString]) -> PauliSum:
|
|
474
457
|
"""Returns a PauliSum by combining `cirq.PauliString` terms.
|
|
475
458
|
|
|
476
459
|
Args:
|
|
@@ -482,7 +465,7 @@ class PauliSum:
|
|
|
482
465
|
"""
|
|
483
466
|
if isinstance(terms, PauliString):
|
|
484
467
|
terms = [terms]
|
|
485
|
-
termdict:
|
|
468
|
+
termdict: defaultdict[UnitPauliStringT, value.Scalar] = defaultdict(lambda: 0)
|
|
486
469
|
for pstring in terms:
|
|
487
470
|
key = frozenset(pstring._qubit_pauli_map.items())
|
|
488
471
|
termdict[key] += pstring.coefficient
|
|
@@ -490,7 +473,7 @@ class PauliSum:
|
|
|
490
473
|
|
|
491
474
|
@classmethod
|
|
492
475
|
def from_boolean_expression(
|
|
493
|
-
cls, boolean_expr: sympy.Expr, qubit_map:
|
|
476
|
+
cls, boolean_expr: sympy.Expr, qubit_map: dict[str, cirq.Qid]
|
|
494
477
|
) -> PauliSum:
|
|
495
478
|
"""Builds the Hamiltonian representation of a Boolean expression.
|
|
496
479
|
|
|
@@ -542,7 +525,7 @@ class PauliSum:
|
|
|
542
525
|
raise ValueError(f'Unsupported type: {type(boolean_expr)}')
|
|
543
526
|
|
|
544
527
|
@property
|
|
545
|
-
def qubits(self) ->
|
|
528
|
+
def qubits(self) -> tuple[raw_types.Qid, ...]:
|
|
546
529
|
"""The sorted list of qubits used in this PauliSum."""
|
|
547
530
|
qs = {q for k in self._linear_dict.keys() for q, _ in k}
|
|
548
531
|
return tuple(sorted(qs))
|
|
@@ -579,7 +562,7 @@ class PauliSum:
|
|
|
579
562
|
factory = type(self)
|
|
580
563
|
return factory(self._linear_dict.copy())
|
|
581
564
|
|
|
582
|
-
def matrix(self, qubits:
|
|
565
|
+
def matrix(self, qubits: Iterable[raw_types.Qid] | None = None) -> np.ndarray:
|
|
583
566
|
"""Returns the matrix of this PauliSum in computational basis of qubits.
|
|
584
567
|
|
|
585
568
|
Args:
|
|
@@ -883,7 +866,7 @@ class ProjectorSum:
|
|
|
883
866
|
"""List of mappings representing a sum of projector operators."""
|
|
884
867
|
|
|
885
868
|
def __init__(
|
|
886
|
-
self, linear_dict:
|
|
869
|
+
self, linear_dict: value.LinearDict[frozenset[tuple[raw_types.Qid, int]]] | None = None
|
|
887
870
|
):
|
|
888
871
|
"""Constructor for ProjectorSum
|
|
889
872
|
|
|
@@ -892,7 +875,7 @@ class ProjectorSum:
|
|
|
892
875
|
number. The tuple is a projector onto the qubit and the complex number is the
|
|
893
876
|
weight of these projections.
|
|
894
877
|
"""
|
|
895
|
-
self._linear_dict: value.LinearDict[
|
|
878
|
+
self._linear_dict: value.LinearDict[frozenset[tuple[raw_types.Qid, int]]] = (
|
|
896
879
|
linear_dict if linear_dict is not None else value.LinearDict({})
|
|
897
880
|
)
|
|
898
881
|
|
|
@@ -900,11 +883,11 @@ class ProjectorSum:
|
|
|
900
883
|
return self._linear_dict
|
|
901
884
|
|
|
902
885
|
@property
|
|
903
|
-
def qubits(self) ->
|
|
886
|
+
def qubits(self) -> tuple[raw_types.Qid, ...]:
|
|
904
887
|
qs = {q for k in self._linear_dict.keys() for q, _ in k}
|
|
905
888
|
return tuple(sorted(qs))
|
|
906
889
|
|
|
907
|
-
def _json_dict_(self) ->
|
|
890
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
908
891
|
linear_dict = []
|
|
909
892
|
for projector_dict, scalar in dict(self._linear_dict).items():
|
|
910
893
|
key = [[k, v] for k, v in dict(projector_dict).items()]
|
|
@@ -922,9 +905,7 @@ class ProjectorSum:
|
|
|
922
905
|
return cls(linear_dict=value.LinearDict(converted_dict))
|
|
923
906
|
|
|
924
907
|
@classmethod
|
|
925
|
-
def from_projector_strings(
|
|
926
|
-
cls, terms: Union[ProjectorString, List[ProjectorString]]
|
|
927
|
-
) -> ProjectorSum:
|
|
908
|
+
def from_projector_strings(cls, terms: ProjectorString | list[ProjectorString]) -> ProjectorSum:
|
|
928
909
|
"""Builds a ProjectorSum from one or more ProjectorString(s).
|
|
929
910
|
|
|
930
911
|
Args:
|
|
@@ -935,7 +916,7 @@ class ProjectorSum:
|
|
|
935
916
|
"""
|
|
936
917
|
if isinstance(terms, ProjectorString):
|
|
937
918
|
terms = [terms]
|
|
938
|
-
termdict:
|
|
919
|
+
termdict: defaultdict[frozenset[tuple[raw_types.Qid, int]], value.Scalar] = defaultdict(
|
|
939
920
|
lambda: 0.0
|
|
940
921
|
)
|
|
941
922
|
for pstring in terms:
|
|
@@ -946,7 +927,7 @@ class ProjectorSum:
|
|
|
946
927
|
def copy(self) -> ProjectorSum:
|
|
947
928
|
return ProjectorSum(self._linear_dict.copy())
|
|
948
929
|
|
|
949
|
-
def matrix(self, projector_qids:
|
|
930
|
+
def matrix(self, projector_qids: Iterable[raw_types.Qid] | None = None) -> csr_matrix:
|
|
950
931
|
"""Returns the matrix of self in computational basis of qubits.
|
|
951
932
|
|
|
952
933
|
Args:
|
|
@@ -1024,7 +1005,7 @@ class ProjectorSum:
|
|
|
1024
1005
|
def __bool__(self) -> bool:
|
|
1025
1006
|
return bool(self._linear_dict)
|
|
1026
1007
|
|
|
1027
|
-
def __iadd__(self, other:
|
|
1008
|
+
def __iadd__(self, other: ProjectorString | ProjectorSum):
|
|
1028
1009
|
if isinstance(other, ProjectorString):
|
|
1029
1010
|
other = ProjectorSum.from_projector_strings(other)
|
|
1030
1011
|
elif not isinstance(other, ProjectorSum):
|
|
@@ -1032,7 +1013,7 @@ class ProjectorSum:
|
|
|
1032
1013
|
self._linear_dict += other._linear_dict
|
|
1033
1014
|
return self
|
|
1034
1015
|
|
|
1035
|
-
def __add__(self, other:
|
|
1016
|
+
def __add__(self, other: ProjectorString | ProjectorSum):
|
|
1036
1017
|
if isinstance(other, ProjectorString):
|
|
1037
1018
|
other = ProjectorSum.from_projector_strings(other)
|
|
1038
1019
|
elif not isinstance(other, ProjectorSum):
|
|
@@ -1041,7 +1022,7 @@ class ProjectorSum:
|
|
|
1041
1022
|
result += other
|
|
1042
1023
|
return result
|
|
1043
1024
|
|
|
1044
|
-
def __isub__(self, other:
|
|
1025
|
+
def __isub__(self, other: ProjectorString | ProjectorSum):
|
|
1045
1026
|
if isinstance(other, ProjectorString):
|
|
1046
1027
|
other = ProjectorSum.from_projector_strings(other)
|
|
1047
1028
|
elif not isinstance(other, ProjectorSum):
|
|
@@ -1049,7 +1030,7 @@ class ProjectorSum:
|
|
|
1049
1030
|
self._linear_dict -= other._linear_dict
|
|
1050
1031
|
return self
|
|
1051
1032
|
|
|
1052
|
-
def __sub__(self, other:
|
|
1033
|
+
def __sub__(self, other: ProjectorString | ProjectorSum):
|
|
1053
1034
|
if isinstance(other, ProjectorString):
|
|
1054
1035
|
other = ProjectorSum.from_projector_strings(other)
|
|
1055
1036
|
elif not isinstance(other, ProjectorSum):
|
cirq/ops/matrix_gates.py
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
|
-
from typing import Any,
|
|
19
|
+
from typing import Any, Iterable, TYPE_CHECKING
|
|
20
20
|
|
|
21
21
|
import numpy as np
|
|
22
22
|
|
|
@@ -55,8 +55,8 @@ class MatrixGate(raw_types.Gate):
|
|
|
55
55
|
self,
|
|
56
56
|
matrix: np.ndarray,
|
|
57
57
|
*,
|
|
58
|
-
name:
|
|
59
|
-
qid_shape:
|
|
58
|
+
name: str | None = None,
|
|
59
|
+
qid_shape: Iterable[int] | None = None,
|
|
60
60
|
unitary_check: bool = True,
|
|
61
61
|
unitary_check_rtol: float = 1e-5,
|
|
62
62
|
unitary_check_atol: float = 1e-8,
|
|
@@ -115,7 +115,7 @@ class MatrixGate(raw_types.Gate):
|
|
|
115
115
|
"""Creates a new MatrixGate with the same matrix and a new name."""
|
|
116
116
|
return MatrixGate(self._matrix, name=name, qid_shape=self._qid_shape, unitary_check=False)
|
|
117
117
|
|
|
118
|
-
def _json_dict_(self) ->
|
|
118
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
119
119
|
return {
|
|
120
120
|
'matrix': self._matrix.tolist(),
|
|
121
121
|
'qid_shape': self._qid_shape,
|
|
@@ -126,7 +126,7 @@ class MatrixGate(raw_types.Gate):
|
|
|
126
126
|
def _from_json_dict_(cls, matrix, qid_shape, name=None, **kwargs):
|
|
127
127
|
return cls(matrix=np.array(matrix), qid_shape=qid_shape, name=name)
|
|
128
128
|
|
|
129
|
-
def _qid_shape_(self) ->
|
|
129
|
+
def _qid_shape_(self) -> tuple[int, ...]:
|
|
130
130
|
return self._qid_shape
|
|
131
131
|
|
|
132
132
|
def __pow__(self, exponent: Any) -> MatrixGate:
|
|
@@ -149,10 +149,10 @@ class MatrixGate(raw_types.Gate):
|
|
|
149
149
|
result[linalg.slice_for_qubits_equal_to([j], 1)] *= np.conj(p)
|
|
150
150
|
return MatrixGate(matrix=result.reshape(self._matrix.shape), qid_shape=self._qid_shape)
|
|
151
151
|
|
|
152
|
-
def _decompose_(self, qubits:
|
|
152
|
+
def _decompose_(self, qubits: tuple[cirq.Qid, ...]) -> cirq.OP_TREE:
|
|
153
153
|
from cirq.circuits import Circuit
|
|
154
154
|
|
|
155
|
-
decomposed:
|
|
155
|
+
decomposed: list[cirq.Operation] = NotImplemented
|
|
156
156
|
if self._qid_shape == (2,):
|
|
157
157
|
decomposed = [
|
|
158
158
|
g.on(qubits[0])
|
|
@@ -199,7 +199,7 @@ class MatrixGate(raw_types.Gate):
|
|
|
199
199
|
rest = [f'#{i+1}' for i in range(1, n_qubits)]
|
|
200
200
|
return protocols.CircuitDiagramInfo(wire_symbols=[main, *rest])
|
|
201
201
|
|
|
202
|
-
def _qasm_(self, args: cirq.QasmArgs, qubits:
|
|
202
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: tuple[cirq.Qid, ...]) -> str | None:
|
|
203
203
|
args.validate_version('2.0', '3.0')
|
|
204
204
|
if self._qid_shape == (2,):
|
|
205
205
|
return protocols.qasm(
|
cirq/ops/measure_util.py
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Callable,
|
|
17
|
+
from typing import Callable, Iterable, overload, TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
import numpy as np
|
|
20
20
|
|
|
@@ -32,8 +32,7 @@ def _default_measurement_key(qubits: Iterable[raw_types.Qid]) -> str:
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
def measure_single_paulistring(
|
|
35
|
-
pauli_observable: pauli_string.PauliString,
|
|
36
|
-
key: Optional[Union[str, cirq.MeasurementKey]] = None,
|
|
35
|
+
pauli_observable: pauli_string.PauliString, key: str | cirq.MeasurementKey | None = None
|
|
37
36
|
) -> raw_types.Operation:
|
|
38
37
|
"""Returns a single PauliMeasurementGate which measures the pauli observable
|
|
39
38
|
|
|
@@ -68,7 +67,7 @@ def measure_single_paulistring(
|
|
|
68
67
|
|
|
69
68
|
def measure_paulistring_terms(
|
|
70
69
|
pauli_basis: pauli_string.PauliString, key_func: Callable[[raw_types.Qid], str] = str
|
|
71
|
-
) ->
|
|
70
|
+
) -> list[raw_types.Operation]:
|
|
72
71
|
"""Returns a list of operations individually measuring qubits in the pauli basis.
|
|
73
72
|
|
|
74
73
|
Args:
|
|
@@ -97,8 +96,8 @@ def measure_paulistring_terms(
|
|
|
97
96
|
@overload
|
|
98
97
|
def measure(
|
|
99
98
|
*target: raw_types.Qid,
|
|
100
|
-
key:
|
|
101
|
-
invert_mask:
|
|
99
|
+
key: str | cirq.MeasurementKey | None = None,
|
|
100
|
+
invert_mask: tuple[bool, ...] = (),
|
|
102
101
|
) -> raw_types.Operation:
|
|
103
102
|
pass
|
|
104
103
|
|
|
@@ -107,17 +106,17 @@ def measure(
|
|
|
107
106
|
def measure(
|
|
108
107
|
__target: Iterable[raw_types.Qid],
|
|
109
108
|
*,
|
|
110
|
-
key:
|
|
111
|
-
invert_mask:
|
|
109
|
+
key: str | cirq.MeasurementKey | None = None,
|
|
110
|
+
invert_mask: tuple[bool, ...] = (),
|
|
112
111
|
) -> raw_types.Operation:
|
|
113
112
|
pass
|
|
114
113
|
|
|
115
114
|
|
|
116
115
|
def measure(
|
|
117
116
|
*target,
|
|
118
|
-
key:
|
|
119
|
-
invert_mask:
|
|
120
|
-
confusion_map:
|
|
117
|
+
key: str | cirq.MeasurementKey | None = None,
|
|
118
|
+
invert_mask: tuple[bool, ...] = (),
|
|
119
|
+
confusion_map: dict[tuple[int, ...], np.ndarray] | None = None,
|
|
121
120
|
) -> raw_types.Operation:
|
|
122
121
|
"""Returns a single MeasurementGate applied to all the given qubits.
|
|
123
122
|
|
|
@@ -172,20 +171,20 @@ M = measure
|
|
|
172
171
|
@overload
|
|
173
172
|
def measure_each(
|
|
174
173
|
*qubits: raw_types.Qid, key_func: Callable[[raw_types.Qid], str] = str
|
|
175
|
-
) ->
|
|
174
|
+
) -> list[raw_types.Operation]:
|
|
176
175
|
pass
|
|
177
176
|
|
|
178
177
|
|
|
179
178
|
@overload
|
|
180
179
|
def measure_each(
|
|
181
180
|
__qubits: Iterable[raw_types.Qid], *, key_func: Callable[[raw_types.Qid], str] = str
|
|
182
|
-
) ->
|
|
181
|
+
) -> list[raw_types.Operation]:
|
|
183
182
|
pass
|
|
184
183
|
|
|
185
184
|
|
|
186
185
|
def measure_each(
|
|
187
186
|
*qubits, key_func: Callable[[raw_types.Qid], str] = str
|
|
188
|
-
) ->
|
|
187
|
+
) -> list[raw_types.Operation]:
|
|
189
188
|
"""Returns a list of operations individually measuring the given qubits.
|
|
190
189
|
|
|
191
190
|
The qubits are measured in the computational basis.
|
cirq/ops/measurement_gate.py
CHANGED
|
@@ -14,18 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import
|
|
18
|
-
Any,
|
|
19
|
-
Dict,
|
|
20
|
-
FrozenSet,
|
|
21
|
-
Iterable,
|
|
22
|
-
Mapping,
|
|
23
|
-
Optional,
|
|
24
|
-
Sequence,
|
|
25
|
-
Tuple,
|
|
26
|
-
TYPE_CHECKING,
|
|
27
|
-
Union,
|
|
28
|
-
)
|
|
17
|
+
from typing import Any, Iterable, Mapping, Sequence, TYPE_CHECKING
|
|
29
18
|
|
|
30
19
|
import numpy as np
|
|
31
20
|
|
|
@@ -49,11 +38,11 @@ class MeasurementGate(raw_types.Gate):
|
|
|
49
38
|
|
|
50
39
|
def __init__(
|
|
51
40
|
self,
|
|
52
|
-
num_qubits:
|
|
53
|
-
key:
|
|
54
|
-
invert_mask:
|
|
55
|
-
qid_shape:
|
|
56
|
-
confusion_map:
|
|
41
|
+
num_qubits: int | None = None,
|
|
42
|
+
key: str | cirq.MeasurementKey = '',
|
|
43
|
+
invert_mask: tuple[bool, ...] = (),
|
|
44
|
+
qid_shape: tuple[int, ...] | None = None,
|
|
45
|
+
confusion_map: dict[tuple[int, ...], np.ndarray] | None = None,
|
|
57
46
|
) -> None:
|
|
58
47
|
"""Inits MeasurementGate.
|
|
59
48
|
|
|
@@ -106,20 +95,20 @@ class MeasurementGate(raw_types.Gate):
|
|
|
106
95
|
return self._mkey
|
|
107
96
|
|
|
108
97
|
@property
|
|
109
|
-
def invert_mask(self) ->
|
|
98
|
+
def invert_mask(self) -> tuple[bool, ...]:
|
|
110
99
|
return self._invert_mask
|
|
111
100
|
|
|
112
101
|
@property
|
|
113
|
-
def confusion_map(self) ->
|
|
102
|
+
def confusion_map(self) -> dict[tuple[int, ...], np.ndarray]:
|
|
114
103
|
return self._confusion_map
|
|
115
104
|
|
|
116
|
-
def _qid_shape_(self) ->
|
|
105
|
+
def _qid_shape_(self) -> tuple[int, ...]:
|
|
117
106
|
return self._qid_shape
|
|
118
107
|
|
|
119
108
|
def _has_unitary_(self) -> bool:
|
|
120
109
|
return False
|
|
121
110
|
|
|
122
|
-
def with_key(self, key:
|
|
111
|
+
def with_key(self, key: str | cirq.MeasurementKey) -> MeasurementGate:
|
|
123
112
|
"""Creates a measurement gate with a new key but otherwise identical."""
|
|
124
113
|
if key == self.key:
|
|
125
114
|
return self
|
|
@@ -131,14 +120,14 @@ class MeasurementGate(raw_types.Gate):
|
|
|
131
120
|
confusion_map=self.confusion_map,
|
|
132
121
|
)
|
|
133
122
|
|
|
134
|
-
def _with_key_path_(self, path:
|
|
123
|
+
def _with_key_path_(self, path: tuple[str, ...]):
|
|
135
124
|
return self.with_key(self.mkey._with_key_path_(path))
|
|
136
125
|
|
|
137
|
-
def _with_key_path_prefix_(self, prefix:
|
|
126
|
+
def _with_key_path_prefix_(self, prefix: tuple[str, ...]):
|
|
138
127
|
return self.with_key(self.mkey._with_key_path_prefix_(prefix))
|
|
139
128
|
|
|
140
129
|
def _with_rescoped_keys_(
|
|
141
|
-
self, path:
|
|
130
|
+
self, path: tuple[str, ...], bindable_keys: frozenset[cirq.MeasurementKey]
|
|
142
131
|
):
|
|
143
132
|
return self.with_key(protocols.with_rescoped_keys(self.mkey, path, bindable_keys))
|
|
144
133
|
|
|
@@ -164,7 +153,7 @@ class MeasurementGate(raw_types.Gate):
|
|
|
164
153
|
confusion_map=self.confusion_map,
|
|
165
154
|
)
|
|
166
155
|
|
|
167
|
-
def full_invert_mask(self) ->
|
|
156
|
+
def full_invert_mask(self) -> tuple[bool, ...]:
|
|
168
157
|
"""Returns the invert mask for all qubits.
|
|
169
158
|
|
|
170
159
|
If the user supplies a partial invert_mask, this returns that mask
|
|
@@ -224,7 +213,7 @@ class MeasurementGate(raw_types.Gate):
|
|
|
224
213
|
|
|
225
214
|
return protocols.CircuitDiagramInfo(symbols)
|
|
226
215
|
|
|
227
|
-
def _qasm_(self, args: cirq.QasmArgs, qubits:
|
|
216
|
+
def _qasm_(self, args: cirq.QasmArgs, qubits: tuple[cirq.Qid, ...]) -> str | None:
|
|
228
217
|
if self.confusion_map or not all(d == 2 for d in self._qid_shape):
|
|
229
218
|
return NotImplemented
|
|
230
219
|
args.validate_version('2.0', '3.0')
|
|
@@ -275,8 +264,8 @@ class MeasurementGate(raw_types.Gate):
|
|
|
275
264
|
)
|
|
276
265
|
return self.key, self.full_invert_mask(), self._qid_shape, hashable_cmap
|
|
277
266
|
|
|
278
|
-
def _json_dict_(self) ->
|
|
279
|
-
other:
|
|
267
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
268
|
+
other: dict[str, Any] = {}
|
|
280
269
|
if not all(d == 2 for d in self._qid_shape):
|
|
281
270
|
other['qid_shape'] = self._qid_shape
|
|
282
271
|
if self.confusion_map:
|
|
@@ -301,7 +290,7 @@ class MeasurementGate(raw_types.Gate):
|
|
|
301
290
|
confusion_map={tuple(k): np.array(v) for k, v in confusion_map or []},
|
|
302
291
|
)
|
|
303
292
|
|
|
304
|
-
def _has_stabilizer_effect_(self) ->
|
|
293
|
+
def _has_stabilizer_effect_(self) -> bool | None:
|
|
305
294
|
return True
|
|
306
295
|
|
|
307
296
|
def _act_on_(self, sim_state: cirq.SimulationStateBase, qubits: Sequence[cirq.Qid]) -> bool:
|