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
|
@@ -16,7 +16,7 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
import itertools
|
|
18
18
|
import random
|
|
19
|
-
from typing import
|
|
19
|
+
from typing import Sequence
|
|
20
20
|
|
|
21
21
|
import numpy as np
|
|
22
22
|
import pytest
|
|
@@ -112,7 +112,7 @@ def test_pauli_string_measurement_errors_no_noise() -> None:
|
|
|
112
112
|
circuit = cirq.FrozenCircuit(_create_ghz(5, qubits))
|
|
113
113
|
sampler = cirq.Simulator()
|
|
114
114
|
|
|
115
|
-
circuits_to_pauli:
|
|
115
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
|
|
116
116
|
circuits_to_pauli[circuit] = [_generate_random_pauli_string(qubits) for _ in range(3)]
|
|
117
117
|
|
|
118
118
|
circuits_with_pauli_expectations = measure_pauli_strings(
|
|
@@ -160,7 +160,7 @@ def test_pauli_string_measurement_errors_with_coefficient_no_noise() -> None:
|
|
|
160
160
|
circuit = cirq.FrozenCircuit(_create_ghz(5, qubits))
|
|
161
161
|
sampler = cirq.Simulator()
|
|
162
162
|
|
|
163
|
-
circuits_to_pauli:
|
|
163
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
|
|
164
164
|
circuits_to_pauli[circuit] = [_generate_random_pauli_string(qubits, True) for _ in range(3)]
|
|
165
165
|
|
|
166
166
|
circuits_with_pauli_expectations = measure_pauli_strings(
|
|
@@ -208,7 +208,7 @@ def test_group_pauli_string_measurement_errors_no_noise_with_coefficient() -> No
|
|
|
208
208
|
circuit = cirq.FrozenCircuit(_create_ghz(5, qubits))
|
|
209
209
|
sampler = cirq.Simulator()
|
|
210
210
|
|
|
211
|
-
circuits_to_pauli:
|
|
211
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[list[cirq.PauliString]]] = {}
|
|
212
212
|
circuits_to_pauli[circuit] = [
|
|
213
213
|
_generate_qwc_paulis(
|
|
214
214
|
_generate_random_pauli_string(qubits, enable_coeff=True, allow_pauli_i=False), 100, True
|
|
@@ -262,7 +262,7 @@ def test_pauli_string_measurement_errors_with_noise() -> None:
|
|
|
262
262
|
sampler = NoisySingleQubitReadoutSampler(p0=0.1, p1=0.005, seed=1234)
|
|
263
263
|
simulator = cirq.Simulator()
|
|
264
264
|
|
|
265
|
-
circuits_to_pauli:
|
|
265
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
|
|
266
266
|
circuits_to_pauli[circuit] = [_generate_random_pauli_string(qubits) for _ in range(3)]
|
|
267
267
|
|
|
268
268
|
circuits_with_pauli_expectations = measure_pauli_strings(
|
|
@@ -309,7 +309,7 @@ def test_group_pauli_string_measurement_errors_with_noise() -> None:
|
|
|
309
309
|
sampler = NoisySingleQubitReadoutSampler(p0=0.1, p1=0.005, seed=1234)
|
|
310
310
|
simulator = cirq.Simulator()
|
|
311
311
|
|
|
312
|
-
circuits_to_pauli:
|
|
312
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[list[cirq.PauliString]]] = {}
|
|
313
313
|
circuits_to_pauli[circuit] = [
|
|
314
314
|
_generate_qwc_paulis(
|
|
315
315
|
_generate_random_pauli_string(qubits, enable_coeff=True, allow_pauli_i=False), 5
|
|
@@ -369,7 +369,7 @@ def test_many_circuits_input_measurement_with_noise() -> None:
|
|
|
369
369
|
circuit_2 = cirq.FrozenCircuit(_create_ghz(5, qubits_2))
|
|
370
370
|
circuit_3 = cirq.FrozenCircuit(_create_ghz(8, qubits_3))
|
|
371
371
|
|
|
372
|
-
circuits_to_pauli:
|
|
372
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
|
|
373
373
|
circuits_to_pauli[circuit_1] = [_generate_random_pauli_string(qubits_1) for _ in range(3)]
|
|
374
374
|
circuits_to_pauli[circuit_2] = [_generate_random_pauli_string(qubits_2) for _ in range(3)]
|
|
375
375
|
circuits_to_pauli[circuit_3] = [_generate_random_pauli_string(qubits_3) for _ in range(3)]
|
|
@@ -417,7 +417,7 @@ def test_allow_measurement_without_readout_mitigation() -> None:
|
|
|
417
417
|
circuit = cirq.FrozenCircuit(_create_ghz(7, qubits))
|
|
418
418
|
sampler = NoisySingleQubitReadoutSampler(p0=0.1, p1=0.005, seed=1234)
|
|
419
419
|
|
|
420
|
-
circuits_to_pauli:
|
|
420
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
|
|
421
421
|
circuits_to_pauli[circuit] = [
|
|
422
422
|
_generate_random_pauli_string(qubits, True),
|
|
423
423
|
_generate_random_pauli_string(qubits),
|
|
@@ -447,7 +447,7 @@ def test_allow_group_pauli_measurement_without_readout_mitigation() -> None:
|
|
|
447
447
|
circuit = cirq.FrozenCircuit(_create_ghz(7, qubits))
|
|
448
448
|
sampler = NoisySingleQubitReadoutSampler(p0=0.1, p1=0.005, seed=1234)
|
|
449
449
|
|
|
450
|
-
circuits_to_pauli:
|
|
450
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[list[cirq.PauliString]]] = {}
|
|
451
451
|
circuits_to_pauli[circuit] = [
|
|
452
452
|
_generate_qwc_paulis(_generate_random_pauli_string(qubits, True), 2, True),
|
|
453
453
|
_generate_qwc_paulis(_generate_random_pauli_string(qubits), 4),
|
|
@@ -488,7 +488,7 @@ def test_many_circuits_with_coefficient() -> None:
|
|
|
488
488
|
circuit_2 = cirq.FrozenCircuit(_create_ghz(5, qubits_2))
|
|
489
489
|
circuit_3 = cirq.FrozenCircuit(_create_ghz(8, qubits_3))
|
|
490
490
|
|
|
491
|
-
circuits_to_pauli:
|
|
491
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
|
|
492
492
|
circuits_to_pauli[circuit_1] = [_generate_random_pauli_string(qubits_1, True) for _ in range(3)]
|
|
493
493
|
circuits_to_pauli[circuit_2] = [_generate_random_pauli_string(qubits_2, True) for _ in range(3)]
|
|
494
494
|
circuits_to_pauli[circuit_3] = [_generate_random_pauli_string(qubits_3, True) for _ in range(3)]
|
|
@@ -547,7 +547,7 @@ def test_many_group_pauli_in_circuits_with_coefficient() -> None:
|
|
|
547
547
|
circuit_2 = cirq.FrozenCircuit(_create_ghz(5, qubits_2))
|
|
548
548
|
circuit_3 = cirq.FrozenCircuit(_create_ghz(8, qubits_3))
|
|
549
549
|
|
|
550
|
-
circuits_to_pauli:
|
|
550
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[list[cirq.PauliString]]] = {}
|
|
551
551
|
circuits_to_pauli[circuit_1] = [
|
|
552
552
|
_generate_qwc_paulis(
|
|
553
553
|
_generate_random_pauli_string(qubits_1, enable_coeff=True, allow_pauli_i=False), 4
|
|
@@ -608,7 +608,7 @@ def test_coefficient_not_real_number() -> None:
|
|
|
608
608
|
random_pauli_string = _generate_random_pauli_string(qubits_1, True) * (3 + 4j)
|
|
609
609
|
circuit_1 = cirq.FrozenCircuit(_create_ghz(3, qubits_1))
|
|
610
610
|
|
|
611
|
-
circuits_to_pauli:
|
|
611
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
|
|
612
612
|
circuits_to_pauli[circuit_1] = [
|
|
613
613
|
random_pauli_string,
|
|
614
614
|
_generate_random_pauli_string(qubits_1, True),
|
|
@@ -643,7 +643,7 @@ def test_invalid_input_circuit_type() -> None:
|
|
|
643
643
|
"""Test that the input circuit type is not frozen circuit"""
|
|
644
644
|
qubits = cirq.LineQubit.range(5)
|
|
645
645
|
|
|
646
|
-
qubits_to_pauli:
|
|
646
|
+
qubits_to_pauli: dict[tuple, list[cirq.PauliString]] = {}
|
|
647
647
|
qubits_to_pauli[tuple(qubits)] = [cirq.PauliString({q: cirq.X for q in qubits})]
|
|
648
648
|
with pytest.raises(
|
|
649
649
|
TypeError, match="All keys in 'circuits_to_pauli' must be FrozenCircuit instances."
|
|
@@ -672,7 +672,7 @@ def test_invalid_input_pauli_string_type() -> None:
|
|
|
672
672
|
circuit_1 = cirq.FrozenCircuit(_create_ghz(5, qubits_1))
|
|
673
673
|
circuit_2 = cirq.FrozenCircuit(_create_ghz(5, qubits_2))
|
|
674
674
|
|
|
675
|
-
circuits_to_pauli:
|
|
675
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, cirq.FrozenCircuit] = {}
|
|
676
676
|
circuits_to_pauli[circuit_1] = [_generate_random_pauli_string(qubits_1)] # type: ignore
|
|
677
677
|
circuits_to_pauli[circuit_2] = [circuit_1, circuit_2] # type: ignore
|
|
678
678
|
|
|
@@ -705,7 +705,7 @@ def test_all_pauli_strings_are_pauli_i() -> None:
|
|
|
705
705
|
circuit_1 = cirq.FrozenCircuit(_create_ghz(5, qubits_1))
|
|
706
706
|
circuit_2 = cirq.FrozenCircuit(_create_ghz(5, qubits_2))
|
|
707
707
|
|
|
708
|
-
circuits_to_pauli:
|
|
708
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
|
|
709
709
|
circuits_to_pauli[circuit_1] = [
|
|
710
710
|
cirq.PauliString({q: cirq.I for q in qubits_1}),
|
|
711
711
|
cirq.PauliString({q: cirq.X for q in qubits_1}),
|
|
@@ -729,7 +729,7 @@ def test_zero_pauli_repetitions() -> None:
|
|
|
729
729
|
|
|
730
730
|
circuit = cirq.FrozenCircuit(_create_ghz(5, qubits))
|
|
731
731
|
|
|
732
|
-
circuits_to_pauli:
|
|
732
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
|
|
733
733
|
circuits_to_pauli[circuit] = [cirq.PauliString({q: cirq.X for q in qubits})]
|
|
734
734
|
with pytest.raises(ValueError, match="Must provide non-zero pauli_repetitions."):
|
|
735
735
|
measure_pauli_strings(
|
|
@@ -743,7 +743,7 @@ def test_negative_num_random_bitstrings() -> None:
|
|
|
743
743
|
|
|
744
744
|
circuit = cirq.FrozenCircuit(_create_ghz(5, qubits))
|
|
745
745
|
|
|
746
|
-
circuits_to_pauli:
|
|
746
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
|
|
747
747
|
circuits_to_pauli[circuit] = [cirq.PauliString({q: cirq.X for q in qubits})]
|
|
748
748
|
with pytest.raises(ValueError, match="Must provide zero or more num_random_bitstrings."):
|
|
749
749
|
measure_pauli_strings(
|
|
@@ -757,7 +757,7 @@ def test_zero_readout_repetitions() -> None:
|
|
|
757
757
|
|
|
758
758
|
circuit = cirq.FrozenCircuit(_create_ghz(5, qubits))
|
|
759
759
|
|
|
760
|
-
circuits_to_pauli:
|
|
760
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
|
|
761
761
|
circuits_to_pauli[circuit] = [cirq.PauliString({q: cirq.X for q in qubits})]
|
|
762
762
|
with pytest.raises(
|
|
763
763
|
ValueError, match="Must provide non-zero readout_repetitions for readout" + " calibration."
|
|
@@ -773,7 +773,7 @@ def test_rng_type_mismatch() -> None:
|
|
|
773
773
|
|
|
774
774
|
circuit = cirq.FrozenCircuit(_create_ghz(5, qubits))
|
|
775
775
|
|
|
776
|
-
circuits_to_pauli:
|
|
776
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
|
|
777
777
|
circuits_to_pauli[circuit] = [cirq.PauliString({q: cirq.X for q in qubits})]
|
|
778
778
|
with pytest.raises(ValueError, match="Must provide a numpy random generator or a seed"):
|
|
779
779
|
measure_pauli_strings(
|
|
@@ -787,7 +787,7 @@ def test_pauli_type_mismatch() -> None:
|
|
|
787
787
|
|
|
788
788
|
circuit = cirq.FrozenCircuit(_create_ghz(5, qubits))
|
|
789
789
|
|
|
790
|
-
circuits_to_pauli:
|
|
790
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, int] = {}
|
|
791
791
|
circuits_to_pauli[circuit] = 1
|
|
792
792
|
with pytest.raises(
|
|
793
793
|
TypeError,
|
|
@@ -808,7 +808,7 @@ def test_group_paulis_are_not_qwc() -> None:
|
|
|
808
808
|
pauli_str1: cirq.PauliString = cirq.PauliString({qubits[0]: cirq.X, qubits[1]: cirq.Y})
|
|
809
809
|
pauli_str2: cirq.PauliString = cirq.PauliString({qubits[0]: cirq.Y})
|
|
810
810
|
|
|
811
|
-
circuits_to_pauli:
|
|
811
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
|
|
812
812
|
circuits_to_pauli[circuit] = [[pauli_str1, pauli_str2]] # type: ignore
|
|
813
813
|
with pytest.raises(
|
|
814
814
|
ValueError,
|
|
@@ -825,7 +825,7 @@ def test_empty_group_paulis_not_allowed() -> None:
|
|
|
825
825
|
|
|
826
826
|
circuit = cirq.FrozenCircuit(_create_ghz(5, qubits))
|
|
827
827
|
|
|
828
|
-
circuits_to_pauli:
|
|
828
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[cirq.PauliString]] = {}
|
|
829
829
|
circuits_to_pauli[circuit] = [[]] # type: ignore
|
|
830
830
|
with pytest.raises(ValueError, match="Empty group of Pauli strings is not allowed"):
|
|
831
831
|
measure_pauli_strings(
|
|
@@ -849,7 +849,7 @@ def test_group_paulis_type_mismatch() -> None:
|
|
|
849
849
|
circuit_2 = cirq.FrozenCircuit(_create_ghz(5, qubits_2))
|
|
850
850
|
circuit_3 = cirq.FrozenCircuit(_create_ghz(8, qubits_3))
|
|
851
851
|
|
|
852
|
-
circuits_to_pauli:
|
|
852
|
+
circuits_to_pauli: dict[cirq.FrozenCircuit, list[list[cirq.PauliString]]] = {}
|
|
853
853
|
circuits_to_pauli[circuit_1] = [
|
|
854
854
|
_generate_qwc_paulis(
|
|
855
855
|
_generate_random_pauli_string(qubits_1, enable_coeff=True, allow_pauli_i=False), 6
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Any, Callable, cast, Iterable,
|
|
17
|
+
from typing import Any, Callable, cast, Iterable, Sequence
|
|
18
18
|
|
|
19
19
|
from cirq import circuits, ops, protocols
|
|
20
20
|
from cirq.contrib import circuitdag
|
|
@@ -28,7 +28,7 @@ def _sorted_best_string_placements(
|
|
|
28
28
|
possible_nodes: Iterable[Any],
|
|
29
29
|
output_ops: Sequence[ops.Operation],
|
|
30
30
|
key: Callable[[Any], ops.PauliStringPhasor] = lambda node: node.val,
|
|
31
|
-
) ->
|
|
31
|
+
) -> list[tuple[ops.PauliStringPhasor, int, circuitdag.Unique[ops.PauliStringPhasor]]]:
|
|
32
32
|
sort_key = lambda placement: (-len(placement[0].pauli_string), placement[1])
|
|
33
33
|
|
|
34
34
|
node_maxes = []
|
|
@@ -66,7 +66,7 @@ def _sorted_best_string_placements(
|
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
def move_pauli_strings_into_circuit(
|
|
69
|
-
circuit_left:
|
|
69
|
+
circuit_left: circuits.Circuit | circuitdag.CircuitDag, circuit_right: circuits.Circuit
|
|
70
70
|
) -> circuits.Circuit:
|
|
71
71
|
if isinstance(circuit_left, circuitdag.CircuitDag):
|
|
72
72
|
string_dag = circuitdag.CircuitDag(pauli_string_reorder_pred, circuit_left)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Iterator
|
|
17
|
+
from typing import Iterator
|
|
18
18
|
|
|
19
19
|
from cirq import circuits, ops, transformers
|
|
20
20
|
from cirq.contrib.paulistring.clifford_target_gateset import CliffordTargetGateset
|
|
@@ -22,7 +22,7 @@ from cirq.contrib.paulistring.clifford_target_gateset import CliffordTargetGates
|
|
|
22
22
|
|
|
23
23
|
def convert_and_separate_circuit(
|
|
24
24
|
circuit: circuits.Circuit, leave_cliffords: bool = True, atol: float = 1e-8
|
|
25
|
-
) ->
|
|
25
|
+
) -> tuple[circuits.Circuit, circuits.Circuit]:
|
|
26
26
|
"""Converts a circuit into two, one made of PauliStringPhasor and the other Clifford gates.
|
|
27
27
|
|
|
28
28
|
Args:
|
|
@@ -17,19 +17,7 @@ from __future__ import annotations
|
|
|
17
17
|
import dataclasses
|
|
18
18
|
import functools
|
|
19
19
|
import operator
|
|
20
|
-
from typing import
|
|
21
|
-
Any,
|
|
22
|
-
Callable,
|
|
23
|
-
cast,
|
|
24
|
-
Dict,
|
|
25
|
-
Iterable,
|
|
26
|
-
List,
|
|
27
|
-
Optional,
|
|
28
|
-
Set,
|
|
29
|
-
Tuple,
|
|
30
|
-
TYPE_CHECKING,
|
|
31
|
-
Union,
|
|
32
|
-
)
|
|
20
|
+
from typing import Any, Callable, cast, Iterable, TYPE_CHECKING
|
|
33
21
|
|
|
34
22
|
import numpy as np
|
|
35
23
|
import sympy
|
|
@@ -61,7 +49,7 @@ class Qasm:
|
|
|
61
49
|
self.circuit = c
|
|
62
50
|
|
|
63
51
|
|
|
64
|
-
def _generate_op_qubits(args:
|
|
52
|
+
def _generate_op_qubits(args: list[list[ops.Qid]], lineno: int) -> list[list[ops.Qid]]:
|
|
65
53
|
"""Generates the Cirq qubits for an operation from the OpenQASM qregs.
|
|
66
54
|
|
|
67
55
|
OpenQASM gates can be applied on single qubits and qubit registers.
|
|
@@ -78,7 +66,7 @@ def _generate_op_qubits(args: List[List[ops.Qid]], lineno: int) -> List[List[ops
|
|
|
78
66
|
f"Non matching quantum registers of length {reg_sizes} at line {lineno}"
|
|
79
67
|
)
|
|
80
68
|
op_qubits_gen = functools.reduce(
|
|
81
|
-
cast(Callable[[
|
|
69
|
+
cast(Callable[[list['cirq.Qid'], list['cirq.Qid']], list['cirq.Qid']], np.broadcast), args
|
|
82
70
|
)
|
|
83
71
|
op_qubits = [[q] if isinstance(q, ops.Qid) else q for q in op_qubits_gen]
|
|
84
72
|
if any(len(set(q)) < len(q) for q in op_qubits):
|
|
@@ -98,7 +86,7 @@ class QasmGateStatement:
|
|
|
98
86
|
def __init__(
|
|
99
87
|
self,
|
|
100
88
|
qasm_gate: str,
|
|
101
|
-
cirq_gate:
|
|
89
|
+
cirq_gate: ops.Gate | Callable[[list[float]], ops.Gate],
|
|
102
90
|
num_params: int,
|
|
103
91
|
num_args: int,
|
|
104
92
|
):
|
|
@@ -119,14 +107,14 @@ class QasmGateStatement:
|
|
|
119
107
|
assert num_args >= 1
|
|
120
108
|
self.num_args = num_args
|
|
121
109
|
|
|
122
|
-
def _validate_args(self, args:
|
|
110
|
+
def _validate_args(self, args: list[list[ops.Qid]], lineno: int):
|
|
123
111
|
if len(args) != self.num_args:
|
|
124
112
|
raise QasmException(
|
|
125
113
|
f"{self.qasm_gate} only takes {self.num_args} arg(s) (qubits and/or registers), "
|
|
126
114
|
f"got: {len(args)}, at line {lineno}"
|
|
127
115
|
)
|
|
128
116
|
|
|
129
|
-
def _validate_params(self, params:
|
|
117
|
+
def _validate_params(self, params: list[value.TParamVal], lineno: int):
|
|
130
118
|
if len(params) != self.num_params:
|
|
131
119
|
raise QasmException(
|
|
132
120
|
f"{self.qasm_gate} takes {self.num_params} parameter(s), "
|
|
@@ -134,7 +122,7 @@ class QasmGateStatement:
|
|
|
134
122
|
)
|
|
135
123
|
|
|
136
124
|
def on(
|
|
137
|
-
self, params:
|
|
125
|
+
self, params: list[value.TParamVal], args: list[list[ops.Qid]], lineno: int
|
|
138
126
|
) -> Iterable[ops.Operation]:
|
|
139
127
|
self._validate_args(args, lineno)
|
|
140
128
|
self._validate_params(params, lineno)
|
|
@@ -159,11 +147,11 @@ class CustomGate:
|
|
|
159
147
|
|
|
160
148
|
name: str
|
|
161
149
|
circuit: FrozenCircuit
|
|
162
|
-
params:
|
|
163
|
-
qubits:
|
|
150
|
+
params: tuple[str, ...]
|
|
151
|
+
qubits: tuple[ops.Qid, ...]
|
|
164
152
|
|
|
165
153
|
def on(
|
|
166
|
-
self, params:
|
|
154
|
+
self, params: list[value.TParamVal], args: list[list[ops.Qid]], lineno: int
|
|
167
155
|
) -> Iterable[ops.Operation]:
|
|
168
156
|
if len(params) != len(self.params):
|
|
169
157
|
raise QasmException(f"Wrong number of params for '{self.name}' at line {lineno}")
|
|
@@ -189,25 +177,25 @@ class QasmParser:
|
|
|
189
177
|
def __init__(self) -> None:
|
|
190
178
|
self.parser = yacc.yacc(module=self, debug=False, write_tables=False)
|
|
191
179
|
self.circuit = Circuit()
|
|
192
|
-
self.qregs:
|
|
193
|
-
self.cregs:
|
|
194
|
-
self.gate_set:
|
|
180
|
+
self.qregs: dict[str, int] = {}
|
|
181
|
+
self.cregs: dict[str, int] = {}
|
|
182
|
+
self.gate_set: dict[str, CustomGate | QasmGateStatement] = {**self.basic_gates}
|
|
195
183
|
"""The gates available to use in the circuit, including those from libraries, and
|
|
196
184
|
user-defined ones."""
|
|
197
185
|
self.in_custom_gate_scope = False
|
|
198
186
|
"""This is set to True when the parser is in the middle of parsing a custom gate
|
|
199
187
|
definition."""
|
|
200
|
-
self.custom_gate_scoped_params:
|
|
188
|
+
self.custom_gate_scoped_params: set[str] = set()
|
|
201
189
|
"""The params declared within the current custom gate definition. Empty if not in
|
|
202
190
|
custom gate scope."""
|
|
203
|
-
self.custom_gate_scoped_qubits:
|
|
191
|
+
self.custom_gate_scoped_qubits: dict[str, ops.Qid] = {}
|
|
204
192
|
"""The qubits declared within the current custom gate definition. Empty if not in
|
|
205
193
|
custom gate scope."""
|
|
206
194
|
self.qelibinc = False
|
|
207
195
|
self.lexer = QasmLexer()
|
|
208
196
|
self.supported_format = False
|
|
209
|
-
self.parsedQasm:
|
|
210
|
-
self.qubits:
|
|
197
|
+
self.parsedQasm: Qasm | None = None
|
|
198
|
+
self.qubits: dict[str, ops.Qid] = {}
|
|
211
199
|
self.functions = {
|
|
212
200
|
'sin': np.sin,
|
|
213
201
|
'cos': np.cos,
|
|
@@ -228,7 +216,7 @@ class QasmParser:
|
|
|
228
216
|
'^': operator.pow,
|
|
229
217
|
}
|
|
230
218
|
|
|
231
|
-
basic_gates:
|
|
219
|
+
basic_gates: dict[str, QasmGateStatement] = {
|
|
232
220
|
'CX': QasmGateStatement(qasm_gate='CX', cirq_gate=CX, num_params=0, num_args=2),
|
|
233
221
|
'U': QasmGateStatement(
|
|
234
222
|
qasm_gate='U',
|
|
@@ -443,7 +431,7 @@ class QasmParser:
|
|
|
443
431
|
self._resolve_gate_operation(args=p[5], gate=p[1], p=p, params=p[3])
|
|
444
432
|
|
|
445
433
|
def _resolve_gate_operation(
|
|
446
|
-
self, args:
|
|
434
|
+
self, args: list[list[ops.Qid]], gate: str, p: Any, params: list[value.TParamVal]
|
|
447
435
|
):
|
|
448
436
|
if gate not in self.gate_set:
|
|
449
437
|
tip = ", did you forget to include qelib1.inc?" if not self.qelibinc else ""
|
|
@@ -693,7 +681,7 @@ class QasmParser:
|
|
|
693
681
|
"""gate_def : GATE ID gate_qubits '{' gate_ops '}'"""
|
|
694
682
|
self._gate_def(p, has_params=False)
|
|
695
683
|
|
|
696
|
-
def _gate_def(self, p:
|
|
684
|
+
def _gate_def(self, p: list[Any], *, has_params: bool):
|
|
697
685
|
name = p[2]
|
|
698
686
|
gate_params = tuple(p[4]) if has_params else ()
|
|
699
687
|
offset = 3 if has_params else 0
|
|
@@ -14,8 +14,6 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Optional, Tuple
|
|
18
|
-
|
|
19
17
|
from cirq import ops, protocols
|
|
20
18
|
|
|
21
19
|
|
|
@@ -35,7 +33,7 @@ def escape_text_for_latex(text):
|
|
|
35
33
|
return r'\text{' + escaped + '}'
|
|
36
34
|
|
|
37
35
|
|
|
38
|
-
def get_multigate_parameters(args: protocols.CircuitDiagramInfoArgs) ->
|
|
36
|
+
def get_multigate_parameters(args: protocols.CircuitDiagramInfoArgs) -> tuple[int, int] | None:
|
|
39
37
|
if (args.label_map is None) or (args.known_qubits is None):
|
|
40
38
|
return None
|
|
41
39
|
|
|
@@ -47,7 +45,7 @@ def get_multigate_parameters(args: protocols.CircuitDiagramInfoArgs) -> Optional
|
|
|
47
45
|
return min_index, n_qubits
|
|
48
46
|
|
|
49
47
|
|
|
50
|
-
def hardcoded_qcircuit_diagram_info(op: ops.Operation) ->
|
|
48
|
+
def hardcoded_qcircuit_diagram_info(op: ops.Operation) -> protocols.CircuitDiagramInfo | None:
|
|
51
49
|
if not isinstance(op, ops.GateOperation):
|
|
52
50
|
return None
|
|
53
51
|
symbols = (
|
|
@@ -78,7 +76,7 @@ def convert_text_diagram_info_to_qcircuit_diagram_info(
|
|
|
78
76
|
|
|
79
77
|
def multigate_qcircuit_diagram_info(
|
|
80
78
|
op: ops.Operation, args: protocols.CircuitDiagramInfoArgs
|
|
81
|
-
) ->
|
|
79
|
+
) -> protocols.CircuitDiagramInfo | None:
|
|
82
80
|
if not (
|
|
83
81
|
isinstance(op, ops.GateOperation) and isinstance(op.gate, ops.InterchangeableQubitsGate)
|
|
84
82
|
):
|
|
@@ -6,7 +6,7 @@ https://arxiv.org/abs/1811.12926.
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
8
|
from dataclasses import dataclass
|
|
9
|
-
from typing import Callable,
|
|
9
|
+
from typing import Callable, TYPE_CHECKING
|
|
10
10
|
|
|
11
11
|
import numpy as np
|
|
12
12
|
|
|
@@ -64,7 +64,7 @@ def generate_model_circuit(
|
|
|
64
64
|
return circuit
|
|
65
65
|
|
|
66
66
|
|
|
67
|
-
def compute_heavy_set(circuit: cirq.Circuit) ->
|
|
67
|
+
def compute_heavy_set(circuit: cirq.Circuit) -> list[int]:
|
|
68
68
|
"""Classically compute the heavy set of the given circuit.
|
|
69
69
|
|
|
70
70
|
The heavy set is defined as the output bit-strings that have a greater than
|
|
@@ -96,13 +96,13 @@ def compute_heavy_set(circuit: cirq.Circuit) -> List[int]:
|
|
|
96
96
|
@dataclass
|
|
97
97
|
class CompilationResult:
|
|
98
98
|
circuit: cirq.Circuit
|
|
99
|
-
mapping:
|
|
100
|
-
parity_map:
|
|
99
|
+
mapping: dict[cirq.Qid, cirq.Qid]
|
|
100
|
+
parity_map: dict[cirq.Qid, cirq.Qid]
|
|
101
101
|
|
|
102
102
|
|
|
103
103
|
def sample_heavy_set(
|
|
104
104
|
compilation_result: CompilationResult,
|
|
105
|
-
heavy_set:
|
|
105
|
+
heavy_set: list[int],
|
|
106
106
|
*,
|
|
107
107
|
repetitions=10_000,
|
|
108
108
|
sampler: cirq.Sampler = cirq.Simulator(),
|
|
@@ -158,8 +158,8 @@ def sample_heavy_set(
|
|
|
158
158
|
|
|
159
159
|
|
|
160
160
|
def process_results(
|
|
161
|
-
mapping:
|
|
162
|
-
parity_mapping:
|
|
161
|
+
mapping: dict[cirq.Qid, cirq.Qid],
|
|
162
|
+
parity_mapping: dict[cirq.Qid, cirq.Qid],
|
|
163
163
|
trial_result: cirq.Result,
|
|
164
164
|
) -> pd.DataFrame:
|
|
165
165
|
"""Checks the given results for parity and throws away all of the runs that
|
|
@@ -176,11 +176,11 @@ def process_results(
|
|
|
176
176
|
|
|
177
177
|
"""
|
|
178
178
|
# The circuit's mapping from physical qubit to logical qubit.
|
|
179
|
-
inverse_mapping:
|
|
179
|
+
inverse_mapping: dict[cirq.Qid, cirq.Qid] = {v: k for k, v in mapping.items()}
|
|
180
180
|
|
|
181
181
|
# Calculate all the invalid parity pairs.
|
|
182
182
|
data = trial_result.data
|
|
183
|
-
bad_measurements:
|
|
183
|
+
bad_measurements: set[int] = set()
|
|
184
184
|
for final_qubit, original_qubit in mapping.items():
|
|
185
185
|
if original_qubit in parity_mapping:
|
|
186
186
|
final_parity_qubit = inverse_mapping[parity_mapping[original_qubit]]
|
|
@@ -204,9 +204,9 @@ def compile_circuit(
|
|
|
204
204
|
*,
|
|
205
205
|
device_graph: nx.Graph,
|
|
206
206
|
routing_attempts: int,
|
|
207
|
-
compiler:
|
|
208
|
-
routing_algo_name:
|
|
209
|
-
router:
|
|
207
|
+
compiler: Callable[[cirq.Circuit], cirq.Circuit] | None = None,
|
|
208
|
+
routing_algo_name: str | None = None,
|
|
209
|
+
router: Callable[..., ccr.SwapNetwork] | None = None,
|
|
210
210
|
add_readout_error_correction=False,
|
|
211
211
|
) -> CompilationResult:
|
|
212
212
|
"""Compile the given model circuit onto the given device graph. This uses a
|
|
@@ -237,7 +237,7 @@ def compile_circuit(
|
|
|
237
237
|
compiled_circuit = circuit.copy()
|
|
238
238
|
|
|
239
239
|
# Optionally add some the parity check bits.
|
|
240
|
-
parity_map:
|
|
240
|
+
parity_map: dict[cirq.Qid, cirq.Qid] = {} # original -> parity
|
|
241
241
|
if add_readout_error_correction:
|
|
242
242
|
num_qubits = len(compiled_circuit.all_qubits())
|
|
243
243
|
# Sort just to make it deterministic.
|
|
@@ -262,7 +262,7 @@ def compile_circuit(
|
|
|
262
262
|
# Github issue: https://github.com/quantumlib/Cirq/issues/2967
|
|
263
263
|
routing_algo_name = 'greedy'
|
|
264
264
|
|
|
265
|
-
swap_networks:
|
|
265
|
+
swap_networks: list[ccr.SwapNetwork] = []
|
|
266
266
|
for _ in range(routing_attempts):
|
|
267
267
|
swap_network = ccr.route_circuit(
|
|
268
268
|
compiled_circuit, device_graph, router=router, algo_name=routing_algo_name
|
|
@@ -313,7 +313,7 @@ class QuantumVolumeResult:
|
|
|
313
313
|
# The model circuit used.
|
|
314
314
|
model_circuit: cirq.Circuit
|
|
315
315
|
# The heavy set computed from the above model circuit.
|
|
316
|
-
heavy_set:
|
|
316
|
+
heavy_set: list[int]
|
|
317
317
|
# The model circuit after being compiled.
|
|
318
318
|
compiled_circuit: cirq.Circuit
|
|
319
319
|
# The percentage of outputs that this sampler had that were in the heavy
|
|
@@ -332,7 +332,7 @@ def prepare_circuits(
|
|
|
332
332
|
depth: int,
|
|
333
333
|
num_circuits: int,
|
|
334
334
|
random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
335
|
-
) ->
|
|
335
|
+
) -> list[tuple[cirq.Circuit, list[int]]]:
|
|
336
336
|
"""Generates circuits and computes their heavy set.
|
|
337
337
|
|
|
338
338
|
Args:
|
|
@@ -358,13 +358,13 @@ def prepare_circuits(
|
|
|
358
358
|
def execute_circuits(
|
|
359
359
|
*,
|
|
360
360
|
device_graph: nx.Graph,
|
|
361
|
-
samplers:
|
|
362
|
-
circuits:
|
|
361
|
+
samplers: list[cirq.Sampler],
|
|
362
|
+
circuits: list[tuple[cirq.Circuit, list[int]]],
|
|
363
363
|
routing_attempts: int,
|
|
364
|
-
compiler:
|
|
364
|
+
compiler: Callable[[cirq.Circuit], cirq.Circuit] | None = None,
|
|
365
365
|
repetitions: int = 10_000,
|
|
366
366
|
add_readout_error_correction=False,
|
|
367
|
-
) ->
|
|
367
|
+
) -> list[QuantumVolumeResult]:
|
|
368
368
|
"""Executes the given circuits on the given samplers.
|
|
369
369
|
|
|
370
370
|
Args
|
|
@@ -385,7 +385,7 @@ def execute_circuits(
|
|
|
385
385
|
"""
|
|
386
386
|
# First, compile all of the model circuits.
|
|
387
387
|
print("Compiling model circuits")
|
|
388
|
-
compiled_circuits:
|
|
388
|
+
compiled_circuits: list[CompilationResult] = []
|
|
389
389
|
for idx, (model_circuit, heavy_set) in enumerate(circuits):
|
|
390
390
|
print(f" Compiling model circuit #{idx + 1}")
|
|
391
391
|
compiled_circuits.append(
|
|
@@ -426,13 +426,13 @@ def calculate_quantum_volume(
|
|
|
426
426
|
depth: int,
|
|
427
427
|
num_circuits: int,
|
|
428
428
|
device_graph: nx.Graph,
|
|
429
|
-
samplers:
|
|
429
|
+
samplers: list[cirq.Sampler],
|
|
430
430
|
random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
431
|
-
compiler:
|
|
431
|
+
compiler: Callable[[cirq.Circuit], cirq.Circuit] | None = None,
|
|
432
432
|
repetitions=10_000,
|
|
433
433
|
routing_attempts=30,
|
|
434
434
|
add_readout_error_correction=False,
|
|
435
|
-
) ->
|
|
435
|
+
) -> list[QuantumVolumeResult]:
|
|
436
436
|
"""Run the quantum volume algorithm.
|
|
437
437
|
|
|
438
438
|
This algorithm should compute the same values as Algorithm 1 in
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from functools import lru_cache
|
|
6
|
-
from typing import
|
|
6
|
+
from typing import Sequence
|
|
7
7
|
|
|
8
8
|
import numpy as np
|
|
9
9
|
import quimb
|
|
@@ -13,7 +13,7 @@ import cirq
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
@lru_cache()
|
|
16
|
-
def _qpos_tag(qubits:
|
|
16
|
+
def _qpos_tag(qubits: cirq.Qid | tuple[cirq.Qid]):
|
|
17
17
|
"""Given a qubit or qubits, return a "position tag" (used for drawing).
|
|
18
18
|
|
|
19
19
|
For multiple qubits, the tag is for the first qubit.
|
|
@@ -25,9 +25,7 @@ def _qpos_tag(qubits: Union[cirq.Qid, Tuple[cirq.Qid]]):
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
@lru_cache()
|
|
28
|
-
def _qpos_y(
|
|
29
|
-
qubits: Union[cirq.Qid, Tuple[cirq.Qid, ...]], all_qubits: Tuple[cirq.Qid, ...]
|
|
30
|
-
) -> float:
|
|
28
|
+
def _qpos_y(qubits: cirq.Qid | tuple[cirq.Qid, ...], all_qubits: tuple[cirq.Qid, ...]) -> float:
|
|
31
29
|
"""Given a qubit or qubits, return the position y value (used for drawing).
|
|
32
30
|
|
|
33
31
|
For multiple qubits, the position is the mean of the qubit indices.
|
|
@@ -47,11 +45,11 @@ def _qpos_y(
|
|
|
47
45
|
|
|
48
46
|
|
|
49
47
|
def _add_to_positions(
|
|
50
|
-
positions:
|
|
48
|
+
positions: dict[tuple[str, str], tuple[float, float]],
|
|
51
49
|
mi: int,
|
|
52
|
-
qubits:
|
|
50
|
+
qubits: cirq.Qid | tuple[cirq.Qid],
|
|
53
51
|
*,
|
|
54
|
-
all_qubits:
|
|
52
|
+
all_qubits: tuple[cirq.Qid, ...],
|
|
55
53
|
x_scale,
|
|
56
54
|
y_scale,
|
|
57
55
|
x_nudge,
|
|
@@ -79,8 +77,8 @@ def _add_to_positions(
|
|
|
79
77
|
|
|
80
78
|
|
|
81
79
|
def circuit_to_density_matrix_tensors(
|
|
82
|
-
circuit: cirq.Circuit, qubits:
|
|
83
|
-
) ->
|
|
80
|
+
circuit: cirq.Circuit, qubits: Sequence[cirq.Qid] | None = None
|
|
81
|
+
) -> tuple[list[qtn.Tensor], dict[cirq.Qid, int], dict[tuple[str, str], tuple[float, float]]]:
|
|
84
82
|
"""Given a circuit with mixtures or channels, construct a tensor network
|
|
85
83
|
representation of the density matrix.
|
|
86
84
|
|
|
@@ -112,10 +110,10 @@ def circuit_to_density_matrix_tensors(
|
|
|
112
110
|
qubits = sorted(circuit.all_qubits()) # pragma: no cover
|
|
113
111
|
qubits = tuple(qubits)
|
|
114
112
|
|
|
115
|
-
qubit_frontier:
|
|
113
|
+
qubit_frontier: dict[cirq.Qid, int] = {q: 0 for q in qubits}
|
|
116
114
|
kraus_frontier = 0
|
|
117
|
-
positions:
|
|
118
|
-
tensors:
|
|
115
|
+
positions: dict[tuple[str, str], tuple[float, float]] = {}
|
|
116
|
+
tensors: list[qtn.Tensor] = []
|
|
119
117
|
|
|
120
118
|
x_scale = 2
|
|
121
119
|
y_scale = 3
|
|
@@ -199,7 +197,7 @@ def circuit_to_density_matrix_tensors(
|
|
|
199
197
|
|
|
200
198
|
|
|
201
199
|
def tensor_density_matrix(
|
|
202
|
-
circuit: cirq.Circuit, qubits:
|
|
200
|
+
circuit: cirq.Circuit, qubits: list[cirq.Qid] | None = None
|
|
203
201
|
) -> np.ndarray:
|
|
204
202
|
"""Given a circuit with mixtures or channels, contract a tensor network
|
|
205
203
|
representing the resultant density matrix.
|