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/interop/quirk/cells/cell.py
CHANGED
|
@@ -15,19 +15,7 @@
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
import abc
|
|
18
|
-
from typing import
|
|
19
|
-
Any,
|
|
20
|
-
Callable,
|
|
21
|
-
Dict,
|
|
22
|
-
Iterable,
|
|
23
|
-
List,
|
|
24
|
-
NamedTuple,
|
|
25
|
-
Optional,
|
|
26
|
-
Sequence,
|
|
27
|
-
Tuple,
|
|
28
|
-
TYPE_CHECKING,
|
|
29
|
-
Union,
|
|
30
|
-
)
|
|
18
|
+
from typing import Any, Callable, Iterable, NamedTuple, Sequence, TYPE_CHECKING, Union
|
|
31
19
|
|
|
32
20
|
from cirq import devices, ops, value
|
|
33
21
|
|
|
@@ -44,7 +32,7 @@ class Cell(metaclass=abc.ABCMeta):
|
|
|
44
32
|
"""
|
|
45
33
|
|
|
46
34
|
@classmethod
|
|
47
|
-
def _replace_qubit(cls, old_qubit: cirq.Qid, qubits:
|
|
35
|
+
def _replace_qubit(cls, old_qubit: cirq.Qid, qubits: list[cirq.Qid]) -> cirq.Qid:
|
|
48
36
|
if not isinstance(old_qubit, devices.LineQubit):
|
|
49
37
|
raise ValueError(f'Can only map from line qubits, but got {old_qubit!r}.')
|
|
50
38
|
if not 0 <= old_qubit.x < len(qubits):
|
|
@@ -53,12 +41,12 @@ class Cell(metaclass=abc.ABCMeta):
|
|
|
53
41
|
|
|
54
42
|
@classmethod
|
|
55
43
|
def _replace_qubits(
|
|
56
|
-
cls, old_qubits: Iterable[cirq.Qid], qubits:
|
|
57
|
-
) ->
|
|
44
|
+
cls, old_qubits: Iterable[cirq.Qid], qubits: list[cirq.Qid]
|
|
45
|
+
) -> tuple[cirq.Qid, ...]:
|
|
58
46
|
return tuple(Cell._replace_qubit(e, qubits) for e in old_qubits)
|
|
59
47
|
|
|
60
48
|
@abc.abstractmethod
|
|
61
|
-
def with_line_qubits_mapped_to(self, qubits:
|
|
49
|
+
def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
|
|
62
50
|
"""Returns the same cell, but targeting different qubits.
|
|
63
51
|
|
|
64
52
|
It is assumed that the cell is currently targeting `LineQubit`
|
|
@@ -87,7 +75,7 @@ class Cell(metaclass=abc.ABCMeta):
|
|
|
87
75
|
extremely adversarial conditions.
|
|
88
76
|
"""
|
|
89
77
|
|
|
90
|
-
def with_input(self, letter: str, register:
|
|
78
|
+
def with_input(self, letter: str, register: Sequence[cirq.Qid] | int) -> Cell:
|
|
91
79
|
"""The same cell, but linked to an explicit input register or constant.
|
|
92
80
|
|
|
93
81
|
If the cell doesn't need the input, it is returned unchanged.
|
|
@@ -146,7 +134,7 @@ class Cell(metaclass=abc.ABCMeta):
|
|
|
146
134
|
"""
|
|
147
135
|
return ()
|
|
148
136
|
|
|
149
|
-
def modify_column(self, column:
|
|
137
|
+
def modify_column(self, column: list[Cell | None]) -> None:
|
|
150
138
|
"""Applies this cell's modification to its column.
|
|
151
139
|
|
|
152
140
|
For example, a control cell will add a control qubit to other operations
|
|
@@ -162,7 +150,7 @@ class Cell(metaclass=abc.ABCMeta):
|
|
|
162
150
|
Nothing. The `column` argument is mutated in place.
|
|
163
151
|
"""
|
|
164
152
|
|
|
165
|
-
def persistent_modifiers(self) ->
|
|
153
|
+
def persistent_modifiers(self) -> dict[str, Callable[[Cell], Cell]]:
|
|
166
154
|
"""Overridable modifications to apply to the rest of the circuit.
|
|
167
155
|
|
|
168
156
|
Persistent modifiers apply to all cells in the same column and also to
|
|
@@ -189,7 +177,7 @@ class ExplicitOperationsCell(Cell):
|
|
|
189
177
|
def gate_count(self) -> int:
|
|
190
178
|
return len(self._operations) + 2 * len(self._basis_change)
|
|
191
179
|
|
|
192
|
-
def with_line_qubits_mapped_to(self, qubits:
|
|
180
|
+
def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
|
|
193
181
|
return ExplicitOperationsCell(
|
|
194
182
|
operations=tuple(
|
|
195
183
|
op.with_qubits(*Cell._replace_qubits(op.qubits, qubits)) for op in self._operations
|
|
@@ -14,18 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import
|
|
18
|
-
Callable,
|
|
19
|
-
cast,
|
|
20
|
-
Iterable,
|
|
21
|
-
Iterator,
|
|
22
|
-
List,
|
|
23
|
-
Optional,
|
|
24
|
-
Sequence,
|
|
25
|
-
TYPE_CHECKING,
|
|
26
|
-
TypeVar,
|
|
27
|
-
Union,
|
|
28
|
-
)
|
|
17
|
+
from typing import Callable, cast, Iterable, Iterator, Sequence, TYPE_CHECKING, TypeVar
|
|
29
18
|
|
|
30
19
|
from cirq import circuits
|
|
31
20
|
from cirq.interop.quirk.cells.cell import Cell
|
|
@@ -41,11 +30,7 @@ class CompositeCell(Cell):
|
|
|
41
30
|
"""
|
|
42
31
|
|
|
43
32
|
def __init__(
|
|
44
|
-
self,
|
|
45
|
-
height: int,
|
|
46
|
-
sub_cell_cols_generator: Iterable[List[Optional[Cell]]],
|
|
47
|
-
*,
|
|
48
|
-
gate_count: int,
|
|
33
|
+
self, height: int, sub_cell_cols_generator: Iterable[list[Cell | None]], *, gate_count: int
|
|
49
34
|
):
|
|
50
35
|
"""Inits CompositeCell.
|
|
51
36
|
|
|
@@ -93,15 +78,15 @@ class CompositeCell(Cell):
|
|
|
93
78
|
gate_count=self._gate_count,
|
|
94
79
|
)
|
|
95
80
|
|
|
96
|
-
def _sub_cell_cols_sealed(self) ->
|
|
81
|
+
def _sub_cell_cols_sealed(self) -> list[list[Cell | None]]:
|
|
97
82
|
if not isinstance(self._sub_cell_cols_generator, list):
|
|
98
83
|
self._sub_cell_cols_generator = list(self._sub_cell_cols_generator)
|
|
99
|
-
return cast(
|
|
84
|
+
return cast(list[list[Cell | None]], self._sub_cell_cols_generator)
|
|
100
85
|
|
|
101
|
-
def with_line_qubits_mapped_to(self, qubits:
|
|
86
|
+
def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
|
|
102
87
|
return self._transform_cells(lambda cell: cell.with_line_qubits_mapped_to(qubits))
|
|
103
88
|
|
|
104
|
-
def with_input(self, letter: str, register:
|
|
89
|
+
def with_input(self, letter: str, register: Sequence[cirq.Qid] | int) -> CompositeCell:
|
|
105
90
|
return self._transform_cells(lambda cell: cell.with_input(letter, register))
|
|
106
91
|
|
|
107
92
|
def controlled_by(self, qubit: cirq.Qid) -> CompositeCell:
|
|
@@ -129,7 +114,7 @@ T = TypeVar('T')
|
|
|
129
114
|
|
|
130
115
|
def _iterator_to_iterable(iterator: Iterator[T]) -> Iterable[T]:
|
|
131
116
|
done = False
|
|
132
|
-
items:
|
|
117
|
+
items: list[T] = []
|
|
133
118
|
|
|
134
119
|
class IterIntoItems:
|
|
135
120
|
def __iter__(self):
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Any, Iterable, Iterator,
|
|
17
|
+
from typing import Any, Iterable, Iterator, TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
from cirq import ops, value
|
|
20
20
|
from cirq.interop.quirk.cells.cell import Cell, CellMaker
|
|
@@ -44,7 +44,7 @@ class ControlCell(Cell):
|
|
|
44
44
|
def gate_count(self) -> int:
|
|
45
45
|
return 0
|
|
46
46
|
|
|
47
|
-
def with_line_qubits_mapped_to(self, qubits:
|
|
47
|
+
def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
|
|
48
48
|
return ControlCell(
|
|
49
49
|
qubit=Cell._replace_qubit(self.qubit, qubits),
|
|
50
50
|
basis_change=tuple(
|
|
@@ -53,7 +53,7 @@ class ControlCell(Cell):
|
|
|
53
53
|
),
|
|
54
54
|
)
|
|
55
55
|
|
|
56
|
-
def modify_column(self, column:
|
|
56
|
+
def modify_column(self, column: list[Cell | None]):
|
|
57
57
|
for i in range(len(column)):
|
|
58
58
|
gate = column[i]
|
|
59
59
|
if gate is not None:
|
|
@@ -88,7 +88,7 @@ class ParityControlCell(Cell):
|
|
|
88
88
|
def gate_count(self) -> int:
|
|
89
89
|
return 0
|
|
90
90
|
|
|
91
|
-
def with_line_qubits_mapped_to(self, qubits:
|
|
91
|
+
def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
|
|
92
92
|
return ParityControlCell(
|
|
93
93
|
qubits=Cell._replace_qubits(self.qubits, qubits),
|
|
94
94
|
basis_change=tuple(
|
|
@@ -97,7 +97,7 @@ class ParityControlCell(Cell):
|
|
|
97
97
|
),
|
|
98
98
|
)
|
|
99
99
|
|
|
100
|
-
def modify_column(self, column:
|
|
100
|
+
def modify_column(self, column: list[Cell | None]):
|
|
101
101
|
for i in range(len(column)):
|
|
102
102
|
gate = column[i]
|
|
103
103
|
if gate is self:
|
|
@@ -134,7 +134,7 @@ def generate_all_control_cell_makers() -> Iterator[CellMaker]:
|
|
|
134
134
|
yield _reg_parity_control("zpar", basis_change=None)
|
|
135
135
|
|
|
136
136
|
|
|
137
|
-
def _reg_control(identifier: str, *, basis_change:
|
|
137
|
+
def _reg_control(identifier: str, *, basis_change: cirq.Gate | None) -> CellMaker:
|
|
138
138
|
return CellMaker(
|
|
139
139
|
identifier=identifier,
|
|
140
140
|
size=1,
|
|
@@ -144,7 +144,7 @@ def _reg_control(identifier: str, *, basis_change: Optional[cirq.Gate]) -> CellM
|
|
|
144
144
|
)
|
|
145
145
|
|
|
146
146
|
|
|
147
|
-
def _reg_parity_control(identifier: str, *, basis_change:
|
|
147
|
+
def _reg_parity_control(identifier: str, *, basis_change: cirq.Gate | None = None) -> CellMaker:
|
|
148
148
|
return CellMaker(
|
|
149
149
|
identifier=identifier,
|
|
150
150
|
size=1,
|
|
@@ -155,7 +155,7 @@ def _reg_parity_control(identifier: str, *, basis_change: Optional[cirq.Gate] =
|
|
|
155
155
|
|
|
156
156
|
|
|
157
157
|
def _basis_else_empty(
|
|
158
|
-
basis_change:
|
|
158
|
+
basis_change: cirq.Gate | None, qureg: cirq.Qid | Iterable[cirq.Qid]
|
|
159
159
|
) -> Iterable[cirq.Operation]:
|
|
160
160
|
if basis_change is None:
|
|
161
161
|
return ()
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Iterable, Iterator,
|
|
17
|
+
from typing import Iterable, Iterator, TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
from cirq.interop.quirk.cells.cell import Cell, CELL_SIZES, CellMaker
|
|
20
20
|
|
|
@@ -32,10 +32,10 @@ class InputCell(Cell):
|
|
|
32
32
|
def gate_count(self) -> int:
|
|
33
33
|
return 0
|
|
34
34
|
|
|
35
|
-
def with_line_qubits_mapped_to(self, qubits:
|
|
35
|
+
def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
|
|
36
36
|
return InputCell(qubits=Cell._replace_qubits(self.qubits, qubits), letter=self.letter)
|
|
37
37
|
|
|
38
|
-
def modify_column(self, column:
|
|
38
|
+
def modify_column(self, column: list[Cell | None]):
|
|
39
39
|
for i in range(len(column)):
|
|
40
40
|
cell = column[i]
|
|
41
41
|
if cell is not None:
|
|
@@ -52,7 +52,7 @@ class SetDefaultInputCell(Cell):
|
|
|
52
52
|
def gate_count(self) -> int:
|
|
53
53
|
return 0
|
|
54
54
|
|
|
55
|
-
def with_line_qubits_mapped_to(self, qubits:
|
|
55
|
+
def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
|
|
56
56
|
return self
|
|
57
57
|
|
|
58
58
|
def persistent_modifiers(self):
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Any, Iterable, Iterator,
|
|
17
|
+
from typing import Any, Iterable, Iterator, Sequence
|
|
18
18
|
|
|
19
19
|
import numpy as np
|
|
20
20
|
|
|
@@ -30,7 +30,7 @@ class InputRotationCell(Cell):
|
|
|
30
30
|
def __init__(
|
|
31
31
|
self,
|
|
32
32
|
identifier: str,
|
|
33
|
-
register:
|
|
33
|
+
register: Sequence[cirq.Qid] | None,
|
|
34
34
|
base_operation: cirq.Operation,
|
|
35
35
|
exponent_sign: int,
|
|
36
36
|
):
|
|
@@ -54,7 +54,7 @@ class InputRotationCell(Cell):
|
|
|
54
54
|
def gate_count(self) -> int:
|
|
55
55
|
return 1
|
|
56
56
|
|
|
57
|
-
def with_line_qubits_mapped_to(self, qubits:
|
|
57
|
+
def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
|
|
58
58
|
return InputRotationCell(
|
|
59
59
|
self.identifier,
|
|
60
60
|
None if self.register is None else Cell._replace_qubits(self.register, qubits),
|
|
@@ -64,7 +64,7 @@ class InputRotationCell(Cell):
|
|
|
64
64
|
exponent_sign=self.exponent_sign,
|
|
65
65
|
)
|
|
66
66
|
|
|
67
|
-
def with_input(self, letter: str, register:
|
|
67
|
+
def with_input(self, letter: str, register: Sequence[cirq.Qid] | int) -> Cell:
|
|
68
68
|
# Parameterized rotations use input A as their parameter.
|
|
69
69
|
if self.register is None and letter == 'a':
|
|
70
70
|
if isinstance(register, int):
|
|
@@ -115,7 +115,7 @@ class QuirkInputRotationOperation(ops.Operation):
|
|
|
115
115
|
return (self.identifier, self.register, self.base_operation, self.exponent_sign)
|
|
116
116
|
|
|
117
117
|
@property
|
|
118
|
-
def qubits(self) ->
|
|
118
|
+
def qubits(self) -> tuple[cirq.Qid, ...]:
|
|
119
119
|
return tuple(self.base_operation.qubits) + self.register
|
|
120
120
|
|
|
121
121
|
def with_qubits(self, *new_qubits):
|
|
@@ -20,22 +20,19 @@ from typing import (
|
|
|
20
20
|
Any,
|
|
21
21
|
Callable,
|
|
22
22
|
cast,
|
|
23
|
-
Dict,
|
|
24
23
|
Iterable,
|
|
25
24
|
Iterator,
|
|
26
|
-
List,
|
|
27
25
|
Mapping,
|
|
28
|
-
Optional,
|
|
29
26
|
SupportsFloat,
|
|
27
|
+
TypeAlias,
|
|
30
28
|
TypeVar,
|
|
31
|
-
Union,
|
|
32
29
|
)
|
|
33
30
|
|
|
34
31
|
import numpy as np
|
|
35
32
|
import sympy
|
|
36
33
|
|
|
37
34
|
|
|
38
|
-
def _merge_scientific_float_tokens(tokens: Iterable[str]) ->
|
|
35
|
+
def _merge_scientific_float_tokens(tokens: Iterable[str]) -> list[str]:
|
|
39
36
|
tokens = list(tokens)
|
|
40
37
|
i = 0
|
|
41
38
|
while 'e' in tokens[i + 1 :]:
|
|
@@ -56,8 +53,8 @@ def _merge_scientific_float_tokens(tokens: Iterable[str]) -> List[str]:
|
|
|
56
53
|
T = TypeVar('T')
|
|
57
54
|
|
|
58
55
|
|
|
59
|
-
def _segment_by(seq: Iterable[T], *, key: Callable[[T], Any]) -> Iterator[
|
|
60
|
-
group:
|
|
56
|
+
def _segment_by(seq: Iterable[T], *, key: Callable[[T], Any]) -> Iterator[list[T]]:
|
|
57
|
+
group: list[T] = []
|
|
61
58
|
last_key = None
|
|
62
59
|
for item in seq:
|
|
63
60
|
item_key = key(item)
|
|
@@ -70,8 +67,8 @@ def _segment_by(seq: Iterable[T], *, key: Callable[[T], Any]) -> Iterator[List[T
|
|
|
70
67
|
yield group
|
|
71
68
|
|
|
72
69
|
|
|
73
|
-
def _tokenize(text: str) ->
|
|
74
|
-
def classify(e: str) ->
|
|
70
|
+
def _tokenize(text: str) -> list[str]:
|
|
71
|
+
def classify(e: str) -> str | float:
|
|
75
72
|
assert e.strip() != '' # Because _segment_by drops empty entries.
|
|
76
73
|
if re.match(r'[.0-9]', e):
|
|
77
74
|
return "#"
|
|
@@ -87,14 +84,14 @@ def _tokenize(text: str) -> List[str]:
|
|
|
87
84
|
return _merge_scientific_float_tokens(g for g in result if g.strip())
|
|
88
85
|
|
|
89
86
|
|
|
90
|
-
_ResolvedToken =
|
|
87
|
+
_ResolvedToken: TypeAlias = sympy.Expr | complex
|
|
91
88
|
|
|
92
89
|
|
|
93
90
|
class _CustomQuirkOperationToken:
|
|
94
91
|
def __init__(
|
|
95
92
|
self,
|
|
96
|
-
unary_action:
|
|
97
|
-
binary_action:
|
|
93
|
+
unary_action: Callable[[_ResolvedToken], _ResolvedToken] | None,
|
|
94
|
+
binary_action: Callable[[_ResolvedToken, _ResolvedToken], _ResolvedToken] | None,
|
|
98
95
|
priority: float,
|
|
99
96
|
):
|
|
100
97
|
self.unary_action = unary_action
|
|
@@ -110,7 +107,7 @@ class _HangingNode:
|
|
|
110
107
|
self.weight = weight
|
|
111
108
|
|
|
112
109
|
|
|
113
|
-
_HangingToken =
|
|
110
|
+
_HangingToken: TypeAlias = _ResolvedToken | str | _CustomQuirkOperationToken
|
|
114
111
|
|
|
115
112
|
|
|
116
113
|
def _translate_token(token_id: str, token_map: Mapping[str, _HangingToken]) -> _HangingToken:
|
|
@@ -124,10 +121,10 @@ def _translate_token(token_id: str, token_map: Mapping[str, _HangingToken]) -> _
|
|
|
124
121
|
|
|
125
122
|
|
|
126
123
|
def _parse_formula_using_token_map(
|
|
127
|
-
text: str, token_map:
|
|
124
|
+
text: str, token_map: dict[str, _HangingToken]
|
|
128
125
|
) -> _ResolvedToken:
|
|
129
126
|
"""Parses a value from an infix arithmetic expression."""
|
|
130
|
-
tokens:
|
|
127
|
+
tokens: list[_HangingToken] = [_translate_token(e, token_map) for e in _tokenize(text)]
|
|
131
128
|
|
|
132
129
|
# Cut off trailing operation, so parse fails less often as users are typing.
|
|
133
130
|
if (
|
|
@@ -137,8 +134,8 @@ def _parse_formula_using_token_map(
|
|
|
137
134
|
):
|
|
138
135
|
tokens = tokens[:-1]
|
|
139
136
|
|
|
140
|
-
ops:
|
|
141
|
-
vals:
|
|
137
|
+
ops: list[str | _HangingNode] = []
|
|
138
|
+
vals: list[_HangingToken | None] = []
|
|
142
139
|
|
|
143
140
|
# Hack: use the 'priority' field as a signal of 'is an operation'
|
|
144
141
|
def is_valid_end_token(tok: _HangingToken) -> bool:
|
|
@@ -147,7 +144,7 @@ def _parse_formula_using_token_map(
|
|
|
147
144
|
def is_valid_end_state() -> bool:
|
|
148
145
|
return len(vals) == 1 and len(ops) == 0
|
|
149
146
|
|
|
150
|
-
def apply(op:
|
|
147
|
+
def apply(op: str | _HangingNode) -> None:
|
|
151
148
|
assert isinstance(op, _HangingNode)
|
|
152
149
|
if len(vals) < 2:
|
|
153
150
|
raise ValueError("Bad expression: operated on nothing.\ntext={text!r}")
|
|
@@ -239,7 +236,7 @@ UNICODE_FRACTIONS = {
|
|
|
239
236
|
"⅒": 1 / 10,
|
|
240
237
|
}
|
|
241
238
|
|
|
242
|
-
PARSE_COMPLEX_TOKEN_MAP_ALL:
|
|
239
|
+
PARSE_COMPLEX_TOKEN_MAP_ALL: dict[str, _HangingToken] = {
|
|
243
240
|
**UNICODE_FRACTIONS,
|
|
244
241
|
'i': 1j,
|
|
245
242
|
'e': sympy.E,
|
|
@@ -267,7 +264,7 @@ PARSE_COMPLEX_TOKEN_MAP_ALL: Dict[str, _HangingToken] = {
|
|
|
267
264
|
}
|
|
268
265
|
PARSE_COMPLEX_TOKEN_MAP_ALL["√"] = PARSE_COMPLEX_TOKEN_MAP_ALL["sqrt"]
|
|
269
266
|
|
|
270
|
-
PARSE_COMPLEX_TOKEN_MAP_DEG:
|
|
267
|
+
PARSE_COMPLEX_TOKEN_MAP_DEG: dict[str, _HangingToken] = {
|
|
271
268
|
**PARSE_COMPLEX_TOKEN_MAP_ALL,
|
|
272
269
|
"cos": _CustomQuirkOperationToken(
|
|
273
270
|
unary_action=lambda e: sympy.cos(e * sympy.pi / 180), binary_action=None, priority=4
|
|
@@ -285,7 +282,7 @@ PARSE_COMPLEX_TOKEN_MAP_DEG: Dict[str, _HangingToken] = {
|
|
|
285
282
|
PARSE_COMPLEX_TOKEN_MAP_DEG["arccos"] = PARSE_COMPLEX_TOKEN_MAP_DEG["acos"]
|
|
286
283
|
PARSE_COMPLEX_TOKEN_MAP_DEG["arcsin"] = PARSE_COMPLEX_TOKEN_MAP_DEG["asin"]
|
|
287
284
|
|
|
288
|
-
PARSE_COMPLEX_TOKEN_MAP_RAD:
|
|
285
|
+
PARSE_COMPLEX_TOKEN_MAP_RAD: dict[str, _HangingToken] = {
|
|
289
286
|
**PARSE_COMPLEX_TOKEN_MAP_ALL,
|
|
290
287
|
"cos": _CustomQuirkOperationToken(
|
|
291
288
|
unary_action=lambda e: sympy.cos(e) if isinstance(e, sympy.Basic) else cmath.cos(e),
|
|
@@ -339,12 +336,12 @@ def parse_complex(text: str) -> complex:
|
|
|
339
336
|
raise ValueError(f'Failed to parse complex from {text!r}') from ex
|
|
340
337
|
|
|
341
338
|
|
|
342
|
-
def parse_formula(formula: str) ->
|
|
339
|
+
def parse_formula(formula: str) -> float | sympy.Expr:
|
|
343
340
|
"""Attempts to parse formula text in exactly the same way as Quirk."""
|
|
344
341
|
if not isinstance(formula, str):
|
|
345
342
|
raise TypeError('formula must be a string')
|
|
346
343
|
|
|
347
|
-
token_map:
|
|
344
|
+
token_map: dict[str, _HangingToken] = {**PARSE_COMPLEX_TOKEN_MAP_RAD, 't': sympy.Symbol('t')}
|
|
348
345
|
result = _parse_formula_using_token_map(formula, token_map)
|
|
349
346
|
|
|
350
347
|
if isinstance(result, sympy.Basic):
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Callable, Iterator, Sequence,
|
|
17
|
+
from typing import Callable, Iterator, Sequence, TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
from cirq import ops, value
|
|
20
20
|
from cirq.interop.quirk.cells.cell import CELL_SIZES, CellMaker
|
|
@@ -44,7 +44,7 @@ class QuirkQubitPermutationGate(ops.QubitPermutationGate):
|
|
|
44
44
|
def _value_equality_values_(self):
|
|
45
45
|
return self.identifier, self.name, self.permutation
|
|
46
46
|
|
|
47
|
-
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) ->
|
|
47
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> tuple[str, ...]:
|
|
48
48
|
return tuple(
|
|
49
49
|
f'{self.name}[{i}>{self.permutation[i]}]' for i in range(len(self.permutation))
|
|
50
50
|
)
|
|
@@ -74,7 +74,7 @@ def _permutation_family(
|
|
|
74
74
|
yield _permutation(identifier_prefix + str(n), name, permutation)
|
|
75
75
|
|
|
76
76
|
|
|
77
|
-
def _permutation(identifier: str, name: str, permutation:
|
|
77
|
+
def _permutation(identifier: str, name: str, permutation: tuple[int, ...]) -> CellMaker:
|
|
78
78
|
return CellMaker(
|
|
79
79
|
identifier,
|
|
80
80
|
size=len(permutation),
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Any, Iterable, Iterator,
|
|
17
|
+
from typing import Any, Iterable, Iterator, TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
from cirq import ops, value
|
|
20
20
|
from cirq.interop.quirk.cells.cell import Cell, CellMaker
|
|
@@ -32,13 +32,13 @@ class SwapCell(Cell):
|
|
|
32
32
|
def gate_count(self) -> int:
|
|
33
33
|
return 1
|
|
34
34
|
|
|
35
|
-
def with_line_qubits_mapped_to(self, qubits:
|
|
35
|
+
def with_line_qubits_mapped_to(self, qubits: list[cirq.Qid]) -> Cell:
|
|
36
36
|
return SwapCell(
|
|
37
37
|
qubits=Cell._replace_qubits(self._qubits, qubits),
|
|
38
38
|
controls=Cell._replace_qubits(self._controls, qubits),
|
|
39
39
|
)
|
|
40
40
|
|
|
41
|
-
def modify_column(self, column:
|
|
41
|
+
def modify_column(self, column: list[Cell | None]):
|
|
42
42
|
# Swallow other swap cells.
|
|
43
43
|
for i in range(len(column)):
|
|
44
44
|
gate = column[i]
|
|
@@ -14,8 +14,6 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Dict, List, Optional
|
|
18
|
-
|
|
19
17
|
import numpy as np
|
|
20
18
|
|
|
21
19
|
import cirq
|
|
@@ -24,12 +22,12 @@ from cirq import quirk_url_to_circuit
|
|
|
24
22
|
|
|
25
23
|
def assert_url_to_circuit_returns(
|
|
26
24
|
json_text: str,
|
|
27
|
-
circuit:
|
|
25
|
+
circuit: cirq.Circuit | None = None,
|
|
28
26
|
*,
|
|
29
|
-
unitary:
|
|
30
|
-
diagram:
|
|
31
|
-
output_amplitudes_from_quirk:
|
|
32
|
-
maps:
|
|
27
|
+
unitary: np.ndarray | None = None,
|
|
28
|
+
diagram: str | None = None,
|
|
29
|
+
output_amplitudes_from_quirk: list[dict[str, float]] | None = None,
|
|
30
|
+
maps: dict[int, int] | None = None,
|
|
33
31
|
):
|
|
34
32
|
"""Assert that `quirk_url_to_circuit` functions correctly.
|
|
35
33
|
|
|
@@ -16,19 +16,7 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
import json
|
|
18
18
|
import urllib.parse
|
|
19
|
-
from typing import
|
|
20
|
-
Any,
|
|
21
|
-
cast,
|
|
22
|
-
Dict,
|
|
23
|
-
Iterable,
|
|
24
|
-
List,
|
|
25
|
-
Mapping,
|
|
26
|
-
Optional,
|
|
27
|
-
Sequence,
|
|
28
|
-
Tuple,
|
|
29
|
-
TYPE_CHECKING,
|
|
30
|
-
Union,
|
|
31
|
-
)
|
|
19
|
+
from typing import Any, cast, Iterable, Mapping, Sequence, TYPE_CHECKING
|
|
32
20
|
|
|
33
21
|
import numpy as np
|
|
34
22
|
|
|
@@ -50,10 +38,8 @@ if TYPE_CHECKING:
|
|
|
50
38
|
def quirk_url_to_circuit(
|
|
51
39
|
quirk_url: str,
|
|
52
40
|
*,
|
|
53
|
-
qubits:
|
|
54
|
-
extra_cell_makers:
|
|
55
|
-
Dict[str, cirq.Gate], Iterable[cirq.interop.quirk.cells.CellMaker]
|
|
56
|
-
] = (),
|
|
41
|
+
qubits: Sequence[cirq.Qid] | None = None,
|
|
42
|
+
extra_cell_makers: dict[str, cirq.Gate] | Iterable[cirq.interop.quirk.cells.CellMaker] = (),
|
|
57
43
|
max_operation_count: int = 10**6,
|
|
58
44
|
) -> cirq.Circuit:
|
|
59
45
|
"""Parses a Cirq circuit out of a Quirk URL.
|
|
@@ -153,11 +139,9 @@ def quirk_url_to_circuit(
|
|
|
153
139
|
def quirk_json_to_circuit(
|
|
154
140
|
data: dict,
|
|
155
141
|
*,
|
|
156
|
-
qubits:
|
|
157
|
-
extra_cell_makers:
|
|
158
|
-
|
|
159
|
-
] = (),
|
|
160
|
-
quirk_url: Optional[str] = None,
|
|
142
|
+
qubits: Sequence[cirq.Qid] | None = None,
|
|
143
|
+
extra_cell_makers: dict[str, cirq.Gate] | Iterable[cirq.interop.quirk.cells.CellMaker] = (),
|
|
144
|
+
quirk_url: str | None = None,
|
|
161
145
|
max_operation_count: int = 10**6,
|
|
162
146
|
) -> cirq.Circuit:
|
|
163
147
|
"""Constructs a Cirq circuit from Quirk's JSON format.
|
|
@@ -258,9 +242,9 @@ def quirk_json_to_circuit(
|
|
|
258
242
|
|
|
259
243
|
|
|
260
244
|
def _parse_cols_into_composite_cell(
|
|
261
|
-
data:
|
|
245
|
+
data: dict[str, Any], registry: dict[str, CellMaker]
|
|
262
246
|
) -> CompositeCell:
|
|
263
|
-
if not isinstance(data,
|
|
247
|
+
if not isinstance(data, dict):
|
|
264
248
|
raise ValueError('Circuit JSON must be a dictionary.')
|
|
265
249
|
if 'cols' not in data:
|
|
266
250
|
raise ValueError(f'Circuit JSON dict must have a "cols" entry.\nJSON={data}')
|
|
@@ -269,7 +253,7 @@ def _parse_cols_into_composite_cell(
|
|
|
269
253
|
raise ValueError(f'Circuit JSON cols must be a list.\nJSON={data}')
|
|
270
254
|
|
|
271
255
|
# Parse column json into cells.
|
|
272
|
-
parsed_cols:
|
|
256
|
+
parsed_cols: list[list[Cell | None]] = []
|
|
273
257
|
height = 0
|
|
274
258
|
for i, col in enumerate(cols):
|
|
275
259
|
parsed_col, h = _parse_col_cells_with_height(registry, i, col)
|
|
@@ -303,8 +287,8 @@ def _parse_cols_into_composite_cell(
|
|
|
303
287
|
return CompositeCell(height, parsed_cols, gate_count=gate_count)
|
|
304
288
|
|
|
305
289
|
|
|
306
|
-
def _register_custom_gate(gate_json: Any, registry:
|
|
307
|
-
if not isinstance(gate_json,
|
|
290
|
+
def _register_custom_gate(gate_json: Any, registry: dict[str, CellMaker]):
|
|
291
|
+
if not isinstance(gate_json, dict):
|
|
308
292
|
raise ValueError(f'Custom gate json must be a dictionary.\nCustom gate json={gate_json!r}.')
|
|
309
293
|
|
|
310
294
|
if 'id' not in gate_json:
|
|
@@ -346,11 +330,11 @@ def _register_custom_gate(gate_json: Any, registry: Dict[str, CellMaker]):
|
|
|
346
330
|
)
|
|
347
331
|
|
|
348
332
|
|
|
349
|
-
def _init_ops(data:
|
|
333
|
+
def _init_ops(data: dict[str, Any]) -> cirq.OP_TREE:
|
|
350
334
|
if 'init' not in data:
|
|
351
335
|
return []
|
|
352
336
|
init = data['init']
|
|
353
|
-
if not isinstance(init,
|
|
337
|
+
if not isinstance(init, list):
|
|
354
338
|
raise ValueError(f'Circuit JSON init must be a list but was {init!r}.')
|
|
355
339
|
init_ops = []
|
|
356
340
|
for i in range(len(init)):
|
|
@@ -374,8 +358,8 @@ def _init_ops(data: Dict[str, Any]) -> cirq.OP_TREE:
|
|
|
374
358
|
|
|
375
359
|
|
|
376
360
|
def _parse_col_cells_with_height(
|
|
377
|
-
registry:
|
|
378
|
-
) ->
|
|
361
|
+
registry: dict[str, CellMaker], col: int, col_data: Any
|
|
362
|
+
) -> tuple[list[Cell | None], int]:
|
|
379
363
|
if not isinstance(col_data, list):
|
|
380
364
|
raise ValueError(f'col must be a list.\ncol: {col_data!r}')
|
|
381
365
|
result = []
|
|
@@ -388,8 +372,8 @@ def _parse_col_cells_with_height(
|
|
|
388
372
|
|
|
389
373
|
|
|
390
374
|
def _parse_cell_with_height(
|
|
391
|
-
registry:
|
|
392
|
-
) ->
|
|
375
|
+
registry: dict[str, CellMaker], row: int, col: int, entry: Any
|
|
376
|
+
) -> tuple[Cell | None, int]:
|
|
393
377
|
if entry == 1:
|
|
394
378
|
return None, 0
|
|
395
379
|
|
cirq/json_resolver_cache.py
CHANGED
|
@@ -17,7 +17,7 @@ from __future__ import annotations
|
|
|
17
17
|
|
|
18
18
|
import datetime
|
|
19
19
|
import functools
|
|
20
|
-
from typing import
|
|
20
|
+
from typing import NamedTuple, TYPE_CHECKING
|
|
21
21
|
|
|
22
22
|
if TYPE_CHECKING:
|
|
23
23
|
import cirq
|
|
@@ -32,18 +32,18 @@ SpecklePurityPair = NamedTuple('SpecklePurityPair', [('num_cycle', int), ('purit
|
|
|
32
32
|
CrossEntropyResult = NamedTuple(
|
|
33
33
|
'CrossEntropyResult',
|
|
34
34
|
[
|
|
35
|
-
('data',
|
|
35
|
+
('data', list[CrossEntropyPair]),
|
|
36
36
|
('repetitions', int),
|
|
37
|
-
('purity_data',
|
|
37
|
+
('purity_data', list[SpecklePurityPair] | None),
|
|
38
38
|
],
|
|
39
39
|
)
|
|
40
40
|
CrossEntropyResultDict = NamedTuple(
|
|
41
|
-
'CrossEntropyResultDict', [('results',
|
|
41
|
+
'CrossEntropyResultDict', [('results', dict[tuple['cirq.Qid', ...], CrossEntropyResult])]
|
|
42
42
|
)
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
@functools.lru_cache()
|
|
46
|
-
def _class_resolver_dictionary() ->
|
|
46
|
+
def _class_resolver_dictionary() -> dict[str, ObjectFactory]:
|
|
47
47
|
import numpy as np
|
|
48
48
|
import pandas as pd
|
|
49
49
|
|
|
@@ -82,7 +82,7 @@ def _class_resolver_dictionary() -> Dict[str, ObjectFactory]:
|
|
|
82
82
|
)
|
|
83
83
|
|
|
84
84
|
def _cross_entropy_result_dict(
|
|
85
|
-
results:
|
|
85
|
+
results: list[tuple[list[cirq.Qid], CrossEntropyResult]], **kwargs
|
|
86
86
|
) -> CrossEntropyResultDict:
|
|
87
87
|
return CrossEntropyResultDict(results={tuple(qubits): result for qubits, result in results})
|
|
88
88
|
|