cirq-core 1.5.0.dev20250409222543__py3-none-any.whl → 1.6.0__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/__init__.py +16 -17
- cirq/_compat.py +21 -20
- cirq/_compat_test.py +14 -34
- cirq/_doc.py +4 -2
- cirq/_import.py +8 -6
- cirq/_import_test.py +4 -2
- cirq/_version.py +6 -6
- cirq/_version_test.py +2 -2
- cirq/circuits/_block_diagram_drawer.py +11 -10
- cirq/circuits/_block_diagram_drawer_test.py +8 -6
- cirq/circuits/_box_drawing_character_data.py +8 -8
- cirq/circuits/_box_drawing_character_data_test.py +3 -1
- cirq/circuits/_bucket_priority_queue.py +9 -7
- cirq/circuits/_bucket_priority_queue_test.py +22 -20
- cirq/circuits/circuit.py +248 -172
- cirq/circuits/circuit_operation.py +73 -83
- cirq/circuits/circuit_operation_test.py +128 -90
- cirq/circuits/circuit_test.py +211 -151
- cirq/circuits/frozen_circuit.py +23 -60
- cirq/circuits/frozen_circuit_test.py +31 -8
- cirq/circuits/insert_strategy.py +7 -5
- cirq/circuits/insert_strategy_test.py +4 -2
- cirq/circuits/moment.py +88 -40
- cirq/circuits/moment_test.py +128 -51
- cirq/circuits/optimization_pass.py +5 -5
- cirq/circuits/optimization_pass_test.py +10 -10
- cirq/circuits/qasm_output.py +11 -11
- cirq/circuits/qasm_output_test.py +25 -22
- cirq/circuits/text_diagram_drawer.py +23 -38
- cirq/circuits/text_diagram_drawer_test.py +19 -17
- cirq/conftest.py +4 -3
- cirq/contrib/__init__.py +4 -4
- cirq/contrib/acquaintance/__init__.py +1 -1
- cirq/contrib/acquaintance/bipartite.py +5 -8
- cirq/contrib/acquaintance/bipartite_test.py +18 -13
- cirq/contrib/acquaintance/devices.py +2 -2
- cirq/contrib/acquaintance/devices_test.py +5 -3
- cirq/contrib/acquaintance/executor.py +5 -5
- cirq/contrib/acquaintance/executor_test.py +13 -9
- cirq/contrib/acquaintance/gates.py +18 -28
- cirq/contrib/acquaintance/gates_test.py +24 -20
- cirq/contrib/acquaintance/inspection_utils.py +8 -4
- cirq/contrib/acquaintance/inspection_utils_test.py +4 -2
- cirq/contrib/acquaintance/mutation_utils.py +4 -4
- cirq/contrib/acquaintance/mutation_utils_test.py +4 -2
- cirq/contrib/acquaintance/optimizers.py +4 -4
- cirq/contrib/acquaintance/optimizers_test.py +4 -1
- cirq/contrib/acquaintance/permutation.py +15 -27
- cirq/contrib/acquaintance/permutation_test.py +26 -17
- cirq/contrib/acquaintance/shift.py +4 -4
- cirq/contrib/acquaintance/shift_swap_network.py +4 -4
- cirq/contrib/acquaintance/shift_swap_network_test.py +9 -6
- cirq/contrib/acquaintance/shift_test.py +8 -6
- cirq/contrib/acquaintance/strategies/cubic.py +2 -2
- cirq/contrib/acquaintance/strategies/cubic_test.py +4 -2
- cirq/contrib/acquaintance/strategies/quartic_paired.py +6 -6
- cirq/contrib/acquaintance/strategies/quartic_paired_test.py +10 -6
- cirq/contrib/acquaintance/testing.py +2 -0
- cirq/contrib/acquaintance/topological_sort.py +2 -2
- cirq/contrib/acquaintance/topological_sort_test.py +3 -1
- cirq/contrib/bayesian_network/bayesian_network_gate.py +9 -10
- cirq/contrib/bayesian_network/bayesian_network_gate_test.py +14 -9
- cirq/contrib/circuitdag/circuit_dag.py +4 -4
- cirq/contrib/circuitdag/circuit_dag_test.py +17 -15
- cirq/contrib/custom_simulators/custom_state_simulator.py +5 -5
- cirq/contrib/custom_simulators/custom_state_simulator_test.py +22 -17
- cirq/contrib/graph_device/graph_device.py +12 -11
- cirq/contrib/graph_device/graph_device_test.py +18 -14
- cirq/contrib/graph_device/hypergraph.py +16 -14
- cirq/contrib/graph_device/hypergraph_test.py +13 -11
- cirq/contrib/graph_device/uniform_graph_device.py +6 -4
- cirq/contrib/graph_device/uniform_graph_device_test.py +11 -3
- cirq/contrib/hacks/disable_validation.py +6 -1
- cirq/contrib/hacks/disable_validation_test.py +3 -1
- cirq/contrib/json.py +31 -5
- cirq/contrib/json_test.py +6 -3
- cirq/contrib/json_test_data/DampedReadoutNoiseModel.json +12 -0
- cirq/contrib/json_test_data/DampedReadoutNoiseModel.repr +4 -0
- cirq/contrib/json_test_data/DepolarizingNoiseModel.json +12 -0
- cirq/contrib/json_test_data/DepolarizingNoiseModel.repr +4 -0
- cirq/contrib/json_test_data/DepolarizingWithDampedReadoutNoiseModel.json +6 -0
- cirq/contrib/json_test_data/DepolarizingWithDampedReadoutNoiseModel.repr +1 -0
- cirq/contrib/json_test_data/DepolarizingWithReadoutNoiseModel.json +5 -0
- cirq/contrib/json_test_data/DepolarizingWithReadoutNoiseModel.repr +1 -0
- cirq/contrib/json_test_data/ReadoutNoiseModel.json +12 -0
- cirq/contrib/json_test_data/ReadoutNoiseModel.repr +4 -0
- cirq/contrib/json_test_data/__init__.py +17 -0
- cirq/contrib/json_test_data/spec.py +32 -0
- cirq/contrib/noise_models/noise_models.py +119 -5
- cirq/contrib/noise_models/noise_models_test.py +37 -9
- cirq/contrib/paulistring/clifford_optimize.py +6 -4
- cirq/contrib/paulistring/clifford_optimize_test.py +6 -5
- cirq/contrib/paulistring/clifford_target_gateset.py +10 -10
- cirq/contrib/paulistring/clifford_target_gateset_test.py +13 -11
- cirq/contrib/paulistring/optimize.py +2 -0
- cirq/contrib/paulistring/optimize_test.py +4 -3
- cirq/contrib/paulistring/pauli_string_dag.py +2 -0
- cirq/contrib/paulistring/pauli_string_dag_test.py +3 -1
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +255 -120
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +398 -19
- cirq/contrib/paulistring/pauli_string_optimize.py +7 -1
- cirq/contrib/paulistring/pauli_string_optimize_test.py +5 -3
- cirq/contrib/paulistring/recombine.py +6 -4
- cirq/contrib/paulistring/recombine_test.py +3 -1
- cirq/contrib/paulistring/separate.py +9 -6
- cirq/contrib/paulistring/separate_test.py +3 -1
- cirq/contrib/qasm_import/_lexer.py +3 -2
- cirq/contrib/qasm_import/_lexer_test.py +49 -13
- cirq/contrib/qasm_import/_parser.py +547 -83
- cirq/contrib/qasm_import/_parser_test.py +988 -97
- cirq/contrib/qasm_import/exception.py +2 -0
- cirq/contrib/qasm_import/qasm.py +8 -2
- cirq/contrib/qasm_import/qasm_test.py +7 -4
- cirq/contrib/qcircuit/qcircuit_diagram_info.py +5 -5
- cirq/contrib/qcircuit/qcircuit_diagram_info_test.py +4 -1
- cirq/contrib/qcircuit/qcircuit_pdf.py +7 -3
- cirq/contrib/qcircuit/qcircuit_pdf_test.py +3 -1
- cirq/contrib/qcircuit/qcircuit_test.py +10 -8
- cirq/contrib/quantum_volume/quantum_volume.py +31 -27
- cirq/contrib/quantum_volume/quantum_volume_test.py +19 -16
- cirq/contrib/quimb/density_matrix.py +15 -14
- cirq/contrib/quimb/density_matrix_test.py +10 -7
- cirq/contrib/quimb/grid_circuits.py +5 -2
- cirq/contrib/quimb/grid_circuits_test.py +3 -0
- cirq/contrib/quimb/mps_simulator.py +20 -20
- cirq/contrib/quimb/mps_simulator_test.py +3 -0
- cirq/contrib/quimb/state_vector.py +12 -11
- cirq/contrib/quimb/state_vector_test.py +3 -0
- cirq/contrib/quirk/export_to_quirk.py +5 -3
- cirq/contrib/quirk/export_to_quirk_test.py +18 -16
- cirq/contrib/quirk/linearize_circuit.py +2 -0
- cirq/contrib/quirk/quirk_gate.py +18 -17
- cirq/contrib/routing/device.py +5 -3
- cirq/contrib/routing/device_test.py +2 -0
- cirq/contrib/routing/greedy.py +10 -21
- cirq/contrib/routing/greedy_test.py +4 -2
- cirq/contrib/routing/initialization.py +2 -2
- cirq/contrib/routing/initialization_test.py +5 -3
- cirq/contrib/routing/router.py +9 -5
- cirq/contrib/routing/router_test.py +2 -0
- cirq/contrib/routing/swap_network.py +3 -3
- cirq/contrib/routing/swap_network_test.py +3 -1
- cirq/contrib/routing/utils.py +2 -2
- cirq/contrib/routing/utils_test.py +3 -0
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +15 -9
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +3 -0
- cirq/contrib/svg/svg.py +3 -3
- cirq/contrib/svg/svg_test.py +8 -5
- cirq/devices/device.py +4 -4
- cirq/devices/device_test.py +7 -4
- cirq/devices/grid_device_metadata.py +10 -10
- cirq/devices/grid_device_metadata_test.py +3 -0
- cirq/devices/grid_qubit.py +29 -21
- cirq/devices/grid_qubit_test.py +3 -0
- cirq/devices/insertion_noise_model.py +7 -7
- cirq/devices/insertion_noise_model_test.py +7 -5
- cirq/devices/line_qubit.py +13 -13
- cirq/devices/line_qubit_test.py +2 -0
- cirq/devices/named_topologies.py +18 -29
- cirq/devices/named_topologies_test.py +13 -10
- cirq/devices/noise_model.py +3 -3
- cirq/devices/noise_model_test.py +19 -15
- cirq/devices/noise_properties.py +15 -6
- cirq/devices/noise_properties_test.py +34 -3
- cirq/devices/noise_utils.py +11 -9
- cirq/devices/noise_utils_test.py +2 -0
- cirq/devices/superconducting_qubits_noise_properties.py +23 -22
- cirq/devices/superconducting_qubits_noise_properties_test.py +6 -6
- cirq/devices/thermal_noise_model.py +107 -37
- cirq/devices/thermal_noise_model_test.py +21 -0
- cirq/devices/unconstrained_device.py +5 -3
- cirq/devices/unconstrained_device_test.py +2 -0
- cirq/experiments/__init__.py +4 -2
- cirq/experiments/benchmarking/__init__.py +17 -0
- cirq/experiments/benchmarking/parallel_xeb.py +677 -0
- cirq/experiments/benchmarking/parallel_xeb_test.py +447 -0
- cirq/experiments/fidelity_estimation.py +14 -8
- cirq/experiments/fidelity_estimation_test.py +3 -0
- cirq/experiments/n_qubit_tomography.py +17 -16
- cirq/experiments/n_qubit_tomography_test.py +8 -5
- cirq/experiments/purity_estimation.py +2 -0
- cirq/experiments/purity_estimation_test.py +2 -0
- cirq/experiments/qubit_characterizations.py +207 -103
- cirq/experiments/qubit_characterizations_test.py +40 -12
- cirq/experiments/random_quantum_circuit_generation.py +56 -70
- cirq/experiments/random_quantum_circuit_generation_test.py +11 -8
- cirq/experiments/readout_confusion_matrix.py +24 -22
- cirq/experiments/readout_confusion_matrix_test.py +2 -0
- cirq/experiments/single_qubit_readout_calibration.py +30 -15
- cirq/experiments/single_qubit_readout_calibration_test.py +5 -2
- cirq/experiments/t1_decay_experiment.py +9 -7
- cirq/experiments/t1_decay_experiment_test.py +13 -11
- cirq/experiments/t2_decay_experiment.py +16 -13
- cirq/experiments/t2_decay_experiment_test.py +2 -0
- cirq/experiments/two_qubit_xeb.py +64 -57
- cirq/experiments/two_qubit_xeb_test.py +10 -6
- cirq/experiments/xeb_fitting.py +39 -35
- cirq/experiments/xeb_sampling.py +37 -44
- cirq/experiments/xeb_sampling_test.py +3 -0
- cirq/experiments/xeb_simulation.py +14 -10
- cirq/experiments/xeb_simulation_test.py +5 -5
- cirq/experiments/z_phase_calibration.py +32 -29
- cirq/experiments/z_phase_calibration_test.py +3 -4
- cirq/interop/quirk/cells/__init__.py +1 -1
- cirq/interop/quirk/cells/all_cells.py +7 -2
- cirq/interop/quirk/cells/arithmetic_cells.py +29 -41
- cirq/interop/quirk/cells/arithmetic_cells_test.py +17 -14
- cirq/interop/quirk/cells/cell.py +19 -28
- cirq/interop/quirk/cells/cell_test.py +3 -0
- cirq/interop/quirk/cells/composite_cell.py +13 -28
- cirq/interop/quirk/cells/composite_cell_test.py +2 -0
- cirq/interop/quirk/cells/control_cells.py +15 -15
- cirq/interop/quirk/cells/control_cells_test.py +7 -5
- cirq/interop/quirk/cells/frequency_space_cells.py +4 -3
- cirq/interop/quirk/cells/frequency_space_cells_test.py +3 -1
- cirq/interop/quirk/cells/ignored_cells.py +3 -0
- cirq/interop/quirk/cells/ignored_cells_test.py +3 -1
- cirq/interop/quirk/cells/input_cells.py +7 -5
- cirq/interop/quirk/cells/input_cells_test.py +7 -5
- cirq/interop/quirk/cells/input_rotation_cells.py +15 -13
- cirq/interop/quirk/cells/input_rotation_cells_test.py +9 -7
- cirq/interop/quirk/cells/measurement_cells.py +5 -2
- cirq/interop/quirk/cells/measurement_cells_test.py +3 -1
- cirq/interop/quirk/cells/parse.py +22 -23
- cirq/interop/quirk/cells/parse_test.py +12 -10
- cirq/interop/quirk/cells/qubit_permutation_cells.py +5 -3
- cirq/interop/quirk/cells/qubit_permutation_cells_test.py +9 -7
- cirq/interop/quirk/cells/scalar_cells.py +4 -1
- cirq/interop/quirk/cells/scalar_cells_test.py +3 -1
- cirq/interop/quirk/cells/single_qubit_rotation_cells.py +5 -2
- cirq/interop/quirk/cells/single_qubit_rotation_cells_test.py +5 -3
- cirq/interop/quirk/cells/swap_cell.py +8 -6
- cirq/interop/quirk/cells/swap_cell_test.py +6 -4
- cirq/interop/quirk/cells/testing.py +6 -6
- cirq/interop/quirk/cells/testing_test.py +8 -6
- cirq/interop/quirk/cells/unsupported_cells.py +3 -0
- cirq/interop/quirk/cells/unsupported_cells_test.py +4 -2
- cirq/interop/quirk/url_to_circuit.py +23 -36
- cirq/interop/quirk/url_to_circuit_test.py +4 -1
- cirq/json_resolver_cache.py +14 -12
- cirq/linalg/__init__.py +4 -6
- cirq/linalg/combinators.py +7 -5
- cirq/linalg/combinators_test.py +10 -7
- cirq/linalg/decompositions.py +24 -35
- cirq/linalg/decompositions_test.py +3 -1
- cirq/linalg/diagonalize.py +6 -4
- cirq/linalg/diagonalize_test.py +15 -14
- cirq/linalg/operator_spaces.py +14 -14
- cirq/linalg/operator_spaces_test.py +13 -11
- cirq/linalg/predicates.py +18 -9
- cirq/linalg/predicates_test.py +5 -0
- cirq/linalg/tolerance.py +6 -3
- cirq/linalg/tolerance_test.py +6 -4
- cirq/linalg/transformations.py +23 -20
- cirq/linalg/transformations_test.py +73 -43
- cirq/neutral_atoms/convert_to_neutral_atom_gates.py +9 -3
- cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +3 -1
- cirq/neutral_atoms/neutral_atom_devices.py +2 -0
- cirq/ops/__init__.py +2 -0
- cirq/ops/arithmetic_operation.py +21 -21
- cirq/ops/arithmetic_operation_test.py +7 -8
- cirq/ops/boolean_hamiltonian.py +23 -22
- cirq/ops/boolean_hamiltonian_test.py +12 -9
- cirq/ops/classically_controlled_operation.py +31 -36
- cirq/ops/classically_controlled_operation_test.py +121 -117
- cirq/ops/clifford_gate.py +98 -81
- cirq/ops/clifford_gate_test.py +72 -57
- cirq/ops/common_channels.py +44 -44
- cirq/ops/common_channels_test.py +83 -81
- cirq/ops/common_gate_families.py +9 -7
- cirq/ops/common_gate_families_test.py +11 -7
- cirq/ops/common_gates.py +164 -183
- cirq/ops/common_gates_test.py +135 -95
- cirq/ops/control_values.py +23 -26
- cirq/ops/control_values_test.py +22 -20
- cirq/ops/controlled_gate.py +64 -112
- cirq/ops/controlled_gate_test.py +130 -35
- cirq/ops/controlled_operation.py +24 -35
- cirq/ops/controlled_operation_test.py +8 -6
- cirq/ops/dense_pauli_string.py +38 -49
- cirq/ops/dense_pauli_string_test.py +4 -2
- cirq/ops/diagonal_gate.py +18 -31
- cirq/ops/diagonal_gate_test.py +13 -13
- cirq/ops/eigen_gate.py +29 -29
- cirq/ops/eigen_gate_test.py +45 -28
- cirq/ops/fourier_transform.py +14 -20
- cirq/ops/fourier_transform_test.py +15 -12
- cirq/ops/fsim_gate.py +43 -42
- cirq/ops/fsim_gate_test.py +29 -29
- cirq/ops/gate_features.py +2 -0
- cirq/ops/gate_features_test.py +5 -3
- cirq/ops/gate_operation.py +43 -65
- cirq/ops/gate_operation_test.py +46 -42
- cirq/ops/gateset.py +28 -40
- cirq/ops/gateset_test.py +4 -2
- cirq/ops/global_phase_op.py +45 -20
- cirq/ops/global_phase_op_test.py +44 -20
- cirq/ops/greedy_qubit_manager.py +10 -8
- cirq/ops/greedy_qubit_manager_test.py +5 -3
- cirq/ops/identity.py +14 -12
- cirq/ops/identity_test.py +24 -20
- cirq/ops/kraus_channel.py +11 -8
- cirq/ops/kraus_channel_test.py +14 -11
- cirq/ops/linear_combinations.py +65 -77
- cirq/ops/linear_combinations_test.py +14 -9
- cirq/ops/matrix_gates.py +21 -18
- cirq/ops/matrix_gates_test.py +16 -0
- cirq/ops/measure_util.py +15 -20
- cirq/ops/measure_util_test.py +2 -0
- cirq/ops/measurement_gate.py +26 -37
- cirq/ops/measurement_gate_test.py +2 -0
- cirq/ops/mixed_unitary_channel.py +12 -9
- cirq/ops/mixed_unitary_channel_test.py +14 -11
- cirq/ops/named_qubit.py +16 -13
- cirq/ops/named_qubit_test.py +15 -13
- cirq/ops/op_tree.py +9 -7
- cirq/ops/op_tree_test.py +22 -19
- cirq/ops/parallel_gate.py +15 -17
- cirq/ops/parallel_gate_test.py +18 -16
- cirq/ops/parity_gates.py +23 -25
- cirq/ops/parity_gates_test.py +36 -32
- cirq/ops/pauli_gates.py +22 -21
- cirq/ops/pauli_gates_test.py +29 -20
- cirq/ops/pauli_interaction_gate.py +15 -19
- cirq/ops/pauli_interaction_gate_test.py +10 -8
- cirq/ops/pauli_measurement_gate.py +23 -35
- cirq/ops/pauli_measurement_gate_test.py +2 -0
- cirq/ops/pauli_string.py +92 -120
- cirq/ops/pauli_string_phasor.py +52 -45
- cirq/ops/pauli_string_phasor_test.py +4 -5
- cirq/ops/pauli_string_raw_types.py +9 -7
- cirq/ops/pauli_string_raw_types_test.py +2 -0
- cirq/ops/pauli_string_test.py +31 -154
- cirq/ops/pauli_sum_exponential.py +12 -12
- cirq/ops/pauli_sum_exponential_test.py +12 -10
- cirq/ops/permutation_gate.py +8 -6
- cirq/ops/permutation_gate_test.py +10 -8
- cirq/ops/phased_iswap_gate.py +16 -16
- cirq/ops/phased_iswap_gate_test.py +17 -15
- cirq/ops/phased_x_gate.py +16 -17
- cirq/ops/phased_x_gate_test.py +18 -16
- cirq/ops/phased_x_z_gate.py +24 -22
- cirq/ops/phased_x_z_gate_test.py +17 -11
- cirq/ops/projector.py +16 -11
- cirq/ops/projector_test.py +19 -16
- cirq/ops/qid_util.py +7 -5
- cirq/ops/qid_util_test.py +2 -0
- cirq/ops/qubit_manager.py +11 -9
- cirq/ops/qubit_manager_test.py +6 -4
- cirq/ops/qubit_order.py +11 -14
- cirq/ops/qubit_order_or_list.py +4 -2
- cirq/ops/qubit_order_test.py +12 -10
- cirq/ops/random_gate_channel.py +12 -10
- cirq/ops/random_gate_channel_test.py +14 -11
- cirq/ops/raw_types.py +109 -129
- cirq/ops/raw_types_test.py +63 -57
- cirq/ops/state_preparation_channel.py +7 -7
- cirq/ops/state_preparation_channel_test.py +11 -9
- cirq/ops/swap_gates.py +13 -15
- cirq/ops/swap_gates_test.py +19 -17
- cirq/ops/tags.py +5 -3
- cirq/ops/tags_test.py +4 -2
- cirq/ops/three_qubit_gates.py +43 -76
- cirq/ops/three_qubit_gates_test.py +19 -17
- cirq/ops/two_qubit_diagonal_gate.py +13 -13
- cirq/ops/two_qubit_diagonal_gate_test.py +10 -8
- cirq/ops/uniform_superposition_gate.py +5 -3
- cirq/ops/uniform_superposition_gate_test.py +5 -3
- cirq/ops/wait_gate.py +17 -14
- cirq/ops/wait_gate_test.py +9 -6
- cirq/protocols/__init__.py +0 -3
- cirq/protocols/act_on_protocol.py +8 -6
- cirq/protocols/act_on_protocol_test.py +15 -12
- cirq/protocols/apply_channel_protocol.py +10 -14
- cirq/protocols/apply_channel_protocol_test.py +2 -0
- cirq/protocols/apply_mixture_protocol.py +13 -42
- cirq/protocols/apply_mixture_protocol_test.py +7 -5
- cirq/protocols/apply_unitary_protocol.py +39 -34
- cirq/protocols/apply_unitary_protocol_test.py +4 -1
- cirq/protocols/approximate_equality_protocol.py +2 -0
- cirq/protocols/approximate_equality_protocol_test.py +2 -0
- cirq/protocols/circuit_diagram_info_protocol.py +58 -42
- cirq/protocols/circuit_diagram_info_protocol_test.py +70 -12
- cirq/protocols/commutes_protocol.py +8 -7
- cirq/protocols/commutes_protocol_test.py +2 -0
- cirq/protocols/control_key_protocol.py +6 -4
- cirq/protocols/control_key_protocol_test.py +3 -1
- cirq/protocols/decompose_protocol.py +49 -48
- cirq/protocols/decompose_protocol_test.py +27 -16
- cirq/protocols/equal_up_to_global_phase_protocol.py +2 -0
- cirq/protocols/equal_up_to_global_phase_protocol_test.py +9 -6
- cirq/protocols/has_stabilizer_effect_protocol.py +7 -5
- cirq/protocols/has_stabilizer_effect_protocol_test.py +7 -5
- cirq/protocols/has_unitary_protocol.py +10 -6
- cirq/protocols/has_unitary_protocol_test.py +13 -8
- cirq/protocols/hash_from_pickle_test.py +2 -11
- cirq/protocols/inverse_protocol.py +13 -16
- cirq/protocols/inverse_protocol_test.py +5 -3
- cirq/protocols/json_serialization.py +35 -54
- cirq/protocols/json_serialization_test.py +14 -21
- cirq/protocols/json_test_data/CXSWAP.json +46 -0
- cirq/protocols/json_test_data/CXSWAP.repr +13 -0
- cirq/protocols/json_test_data/CZSWAP.json +46 -0
- cirq/protocols/json_test_data/CZSWAP.repr +13 -0
- cirq/protocols/json_test_data/CircuitOperation.json +6 -3
- cirq/protocols/json_test_data/CircuitOperation.repr_inward +4 -2
- cirq/protocols/json_test_data/Moment.json +24 -1
- cirq/protocols/json_test_data/Moment.repr +6 -1
- cirq/protocols/json_test_data/ThermalNoiseModel.json +32 -0
- cirq/protocols/json_test_data/ThermalNoiseModel.repr +1 -0
- cirq/protocols/json_test_data/spec.py +6 -2
- cirq/protocols/kraus_protocol.py +47 -7
- cirq/protocols/kraus_protocol_test.py +86 -12
- cirq/protocols/measurement_key_protocol.py +15 -16
- cirq/protocols/measurement_key_protocol_test.py +13 -11
- cirq/protocols/mixture_protocol.py +7 -5
- cirq/protocols/mixture_protocol_test.py +4 -2
- cirq/protocols/mul_protocol.py +2 -3
- cirq/protocols/mul_protocol_test.py +2 -0
- cirq/protocols/pauli_expansion_protocol.py +6 -3
- cirq/protocols/pauli_expansion_protocol_test.py +5 -3
- cirq/protocols/phase_protocol.py +2 -0
- cirq/protocols/phase_protocol_test.py +3 -1
- cirq/protocols/pow_protocol.py +11 -16
- cirq/protocols/pow_protocol_test.py +2 -0
- cirq/protocols/qasm.py +14 -20
- cirq/protocols/qasm_test.py +6 -3
- cirq/protocols/qid_shape_protocol.py +8 -8
- cirq/protocols/qid_shape_protocol_test.py +3 -1
- cirq/protocols/resolve_parameters.py +5 -3
- cirq/protocols/resolve_parameters_test.py +8 -7
- cirq/protocols/trace_distance_bound.py +6 -4
- cirq/protocols/trace_distance_bound_test.py +3 -1
- cirq/protocols/unitary_protocol.py +17 -7
- cirq/protocols/unitary_protocol_test.py +12 -2
- cirq/qis/channels.py +6 -2
- cirq/qis/channels_test.py +20 -16
- cirq/qis/clifford_tableau.py +21 -19
- cirq/qis/clifford_tableau_test.py +2 -2
- cirq/qis/entropy.py +14 -3
- cirq/qis/entropy_test.py +3 -1
- cirq/qis/measures.py +13 -13
- cirq/qis/measures_test.py +20 -14
- cirq/qis/noise_utils.py +2 -0
- cirq/qis/noise_utils_test.py +9 -7
- cirq/qis/quantum_state_representation.py +7 -8
- cirq/qis/states.py +58 -56
- cirq/qis/states_test.py +2 -0
- cirq/sim/classical_simulator.py +23 -22
- cirq/sim/classical_simulator_test.py +2 -0
- cirq/sim/clifford/clifford_simulator.py +23 -21
- cirq/sim/clifford/clifford_simulator_test.py +7 -4
- cirq/sim/clifford/clifford_tableau_simulation_state.py +10 -7
- cirq/sim/clifford/clifford_tableau_simulation_state_test.py +5 -5
- cirq/sim/clifford/stabilizer_ch_form_simulation_state.py +8 -6
- cirq/sim/clifford/stabilizer_ch_form_simulation_state_test.py +8 -6
- cirq/sim/clifford/stabilizer_sampler.py +9 -7
- cirq/sim/clifford/stabilizer_sampler_test.py +4 -2
- cirq/sim/clifford/stabilizer_simulation_state.py +14 -13
- cirq/sim/clifford/stabilizer_simulation_state_test.py +6 -4
- cirq/sim/clifford/stabilizer_state_ch_form.py +13 -11
- cirq/sim/clifford/stabilizer_state_ch_form_test.py +4 -2
- cirq/sim/density_matrix_simulation_state.py +26 -27
- cirq/sim/density_matrix_simulation_state_test.py +10 -8
- cirq/sim/density_matrix_simulator.py +30 -28
- cirq/sim/density_matrix_simulator_test.py +48 -48
- cirq/sim/density_matrix_utils.py +13 -11
- cirq/sim/density_matrix_utils_test.py +38 -36
- cirq/sim/mux.py +33 -31
- cirq/sim/mux_test.py +3 -0
- cirq/sim/simulation_product_state.py +15 -15
- cirq/sim/simulation_product_state_test.py +29 -26
- cirq/sim/simulation_state.py +29 -38
- cirq/sim/simulation_state_base.py +21 -32
- cirq/sim/simulation_state_test.py +15 -13
- cirq/sim/simulation_utils.py +5 -2
- cirq/sim/simulation_utils_test.py +5 -2
- cirq/sim/simulator.py +90 -106
- cirq/sim/simulator_base.py +33 -45
- cirq/sim/simulator_base_test.py +20 -15
- cirq/sim/simulator_test.py +23 -14
- cirq/sim/sparse_simulator.py +19 -17
- cirq/sim/sparse_simulator_test.py +41 -40
- cirq/sim/state_vector.py +15 -12
- cirq/sim/state_vector_simulation_state.py +31 -31
- cirq/sim/state_vector_simulation_state_test.py +16 -14
- cirq/sim/state_vector_simulator.py +17 -14
- cirq/sim/state_vector_simulator_test.py +2 -0
- cirq/sim/state_vector_test.py +6 -3
- cirq/study/flatten_expressions.py +16 -15
- cirq/study/flatten_expressions_test.py +13 -11
- cirq/study/resolver.py +18 -17
- cirq/study/resolver_test.py +22 -20
- cirq/study/result.py +17 -27
- cirq/study/result_test.py +2 -0
- cirq/study/sweepable.py +12 -10
- cirq/study/sweepable_test.py +3 -0
- cirq/study/sweeps.py +42 -61
- cirq/study/sweeps_test.py +33 -0
- cirq/testing/__init__.py +7 -11
- cirq/testing/_compat_test_data/module_a/__init__.py +1 -0
- cirq/testing/_compat_test_data/module_a/module_b/__init__.py +1 -0
- cirq/testing/_compat_test_data/module_a/sub/__init__.py +1 -0
- cirq/testing/circuit_compare.py +8 -17
- cirq/testing/circuit_compare_test.py +2 -0
- cirq/testing/consistent_act_on.py +13 -11
- cirq/testing/consistent_act_on_test.py +5 -3
- cirq/testing/consistent_channels.py +2 -0
- cirq/testing/consistent_channels_test.py +10 -8
- cirq/testing/consistent_controlled_gate_op.py +5 -5
- cirq/testing/consistent_controlled_gate_op_test.py +18 -18
- cirq/testing/consistent_decomposition.py +2 -2
- cirq/testing/consistent_decomposition_test.py +4 -2
- cirq/testing/consistent_pauli_expansion.py +2 -0
- cirq/testing/consistent_pauli_expansion_test.py +3 -1
- cirq/testing/consistent_phase_by.py +2 -0
- cirq/testing/consistent_phase_by_test.py +3 -1
- cirq/testing/consistent_protocols.py +14 -20
- cirq/testing/consistent_protocols_test.py +13 -11
- cirq/testing/consistent_qasm.py +6 -4
- cirq/testing/consistent_qasm_test.py +7 -7
- cirq/testing/consistent_resolve_parameters.py +2 -0
- cirq/testing/consistent_specified_has_unitary.py +2 -2
- cirq/testing/consistent_specified_has_unitary_test.py +6 -4
- cirq/testing/consistent_unitary.py +1 -0
- cirq/testing/consistent_unitary_test.py +4 -2
- cirq/testing/deprecation.py +5 -2
- cirq/testing/deprecation_test.py +5 -2
- cirq/testing/devices.py +7 -4
- cirq/testing/devices_test.py +7 -4
- cirq/testing/equals_tester.py +4 -2
- cirq/testing/equals_tester_test.py +21 -17
- cirq/testing/equivalent_basis_map.py +6 -4
- cirq/testing/equivalent_basis_map_test.py +6 -4
- cirq/testing/equivalent_repr_eval.py +6 -4
- cirq/testing/equivalent_repr_eval_test.py +5 -3
- cirq/testing/gate_features.py +2 -0
- cirq/testing/gate_features_test.py +7 -5
- cirq/testing/json.py +19 -15
- cirq/testing/json_test.py +5 -3
- cirq/testing/lin_alg_utils.py +10 -11
- cirq/testing/lin_alg_utils_test.py +14 -12
- cirq/testing/logs.py +7 -6
- cirq/testing/logs_test.py +9 -7
- cirq/testing/no_identifier_qubit.py +4 -2
- cirq/testing/no_identifier_qubit_test.py +5 -3
- cirq/testing/op_tree.py +2 -0
- cirq/testing/op_tree_test.py +4 -1
- cirq/testing/order_tester.py +2 -0
- cirq/testing/order_tester_test.py +8 -6
- cirq/testing/pytest_utils.py +2 -0
- cirq/testing/pytest_utils_test.py +4 -2
- cirq/testing/random_circuit.py +21 -20
- cirq/testing/random_circuit_test.py +12 -9
- cirq/testing/repr_pretty_tester.py +1 -0
- cirq/testing/repr_pretty_tester_test.py +5 -3
- cirq/testing/routing_devices.py +4 -1
- cirq/testing/routing_devices_test.py +9 -6
- cirq/testing/sample_circuits.py +4 -1
- cirq/testing/sample_circuits_test.py +3 -1
- cirq/testing/sample_gates.py +3 -0
- cirq/testing/sample_gates_test.py +5 -2
- cirq/transformers/__init__.py +11 -4
- cirq/transformers/align.py +9 -7
- cirq/transformers/align_test.py +2 -0
- cirq/transformers/analytical_decompositions/__init__.py +3 -6
- cirq/transformers/analytical_decompositions/clifford_decomposition.py +18 -16
- cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +2 -0
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +19 -16
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
- cirq/transformers/analytical_decompositions/cphase_to_fsim.py +11 -9
- cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +5 -3
- cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +5 -3
- cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +5 -3
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +141 -44
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +35 -1
- cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +8 -7
- cirq/transformers/analytical_decompositions/single_qubit_decompositions_test.py +2 -0
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +7 -4
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +3 -0
- cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +11 -19
- cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +8 -33
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +9 -11
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -0
- cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +91 -27
- cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +36 -7
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +20 -21
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +8 -6
- cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +13 -15
- cirq/transformers/analytical_decompositions/two_qubit_to_ms_test.py +3 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +39 -41
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -0
- cirq/transformers/drop_empty_moments.py +5 -3
- cirq/transformers/drop_empty_moments_test.py +4 -2
- cirq/transformers/drop_negligible_operations.py +7 -5
- cirq/transformers/drop_negligible_operations_test.py +2 -0
- cirq/transformers/dynamical_decoupling.py +49 -42
- cirq/transformers/dynamical_decoupling_test.py +223 -205
- cirq/transformers/eject_phased_paulis.py +28 -26
- cirq/transformers/eject_phased_paulis_test.py +12 -9
- cirq/transformers/eject_z.py +12 -12
- cirq/transformers/eject_z_test.py +2 -2
- cirq/transformers/expand_composite.py +6 -4
- cirq/transformers/expand_composite_test.py +3 -1
- cirq/transformers/gauge_compiling/__init__.py +3 -1
- cirq/transformers/gauge_compiling/cphase_gauge.py +2 -0
- cirq/transformers/gauge_compiling/cphase_gauge_test.py +2 -0
- cirq/transformers/gauge_compiling/cz_gauge.py +2 -0
- cirq/transformers/gauge_compiling/cz_gauge_test.py +1 -0
- cirq/transformers/gauge_compiling/gauge_compiling.py +45 -41
- cirq/transformers/gauge_compiling/gauge_compiling_test.py +2 -0
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +1 -0
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +5 -1
- cirq/transformers/gauge_compiling/iswap_gauge.py +2 -0
- cirq/transformers/gauge_compiling/iswap_gauge_test.py +1 -0
- cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -0
- cirq/transformers/gauge_compiling/spin_inversion_gauge_test.py +2 -0
- cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +7 -6
- cirq/transformers/gauge_compiling/sqrt_cz_gauge_test.py +2 -0
- cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +2 -0
- cirq/transformers/gauge_compiling/sqrt_iswap_gauge_test.py +2 -0
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +6 -3
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +3 -0
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +12 -9
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +9 -7
- cirq/transformers/insertion_sort.py +8 -6
- cirq/transformers/insertion_sort_test.py +3 -1
- cirq/transformers/measurement_transformers.py +29 -29
- cirq/transformers/measurement_transformers_test.py +2 -0
- cirq/transformers/merge_k_qubit_gates.py +12 -10
- cirq/transformers/merge_k_qubit_gates_test.py +18 -18
- cirq/transformers/merge_single_qubit_gates.py +197 -20
- cirq/transformers/merge_single_qubit_gates_test.py +177 -5
- cirq/transformers/noise_adding.py +5 -3
- cirq/transformers/noise_adding_test.py +2 -0
- cirq/transformers/optimize_for_target_gateset.py +19 -17
- cirq/transformers/optimize_for_target_gateset_test.py +11 -8
- cirq/transformers/qubit_management_transformers.py +13 -11
- cirq/transformers/qubit_management_transformers_test.py +5 -3
- cirq/transformers/randomized_measurements.py +16 -14
- cirq/transformers/randomized_measurements_test.py +10 -4
- cirq/transformers/routing/initial_mapper.py +6 -4
- cirq/transformers/routing/initial_mapper_test.py +2 -0
- cirq/transformers/routing/line_initial_mapper.py +16 -14
- cirq/transformers/routing/line_initial_mapper_test.py +9 -7
- cirq/transformers/routing/mapping_manager.py +10 -10
- cirq/transformers/routing/mapping_manager_test.py +2 -0
- cirq/transformers/routing/route_circuit_cqc.py +33 -31
- cirq/transformers/routing/route_circuit_cqc_test.py +15 -13
- cirq/transformers/routing/visualize_routed_circuit.py +8 -7
- cirq/transformers/routing/visualize_routed_circuit_test.py +4 -2
- cirq/transformers/stratify.py +17 -15
- cirq/transformers/stratify_test.py +3 -0
- cirq/transformers/symbolize.py +103 -0
- cirq/transformers/symbolize_test.py +62 -0
- cirq/transformers/synchronize_terminal_measurements.py +10 -10
- cirq/transformers/synchronize_terminal_measurements_test.py +12 -10
- cirq/transformers/tag_transformers.py +97 -0
- cirq/transformers/tag_transformers_test.py +103 -0
- cirq/transformers/target_gatesets/compilation_target_gateset.py +21 -19
- cirq/transformers/target_gatesets/compilation_target_gateset_test.py +20 -16
- cirq/transformers/target_gatesets/cz_gateset.py +7 -5
- cirq/transformers/target_gatesets/cz_gateset_test.py +21 -19
- cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +9 -7
- cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +25 -25
- cirq/transformers/transformer_api.py +34 -47
- cirq/transformers/transformer_api_test.py +9 -8
- cirq/transformers/transformer_primitives.py +39 -49
- cirq/transformers/transformer_primitives_test.py +10 -17
- cirq/value/abc_alt.py +6 -4
- cirq/value/abc_alt_test.py +5 -3
- cirq/value/angle.py +11 -12
- cirq/value/angle_test.py +5 -3
- cirq/value/classical_data.py +27 -27
- cirq/value/classical_data_test.py +11 -8
- cirq/value/condition.py +26 -24
- cirq/value/condition_test.py +2 -0
- cirq/value/digits.py +14 -11
- cirq/value/digits_test.py +2 -0
- cirq/value/duration.py +23 -20
- cirq/value/duration_test.py +2 -0
- cirq/value/linear_dict.py +25 -30
- cirq/value/linear_dict_test.py +10 -8
- cirq/value/measurement_key.py +12 -12
- cirq/value/measurement_key_test.py +2 -0
- cirq/value/periodic_value.py +4 -4
- cirq/value/periodic_value_test.py +11 -7
- cirq/value/probability.py +3 -1
- cirq/value/probability_test.py +4 -2
- cirq/value/product_state.py +15 -13
- cirq/value/product_state_test.py +4 -1
- cirq/value/random_state.py +2 -0
- cirq/value/random_state_test.py +5 -3
- cirq/value/timestamp.py +11 -7
- cirq/value/timestamp_test.py +14 -12
- cirq/value/type_alias.py +4 -4
- cirq/value/value_equality_attr.py +8 -9
- cirq/value/value_equality_attr_test.py +14 -11
- cirq/vis/density_matrix.py +3 -3
- cirq/vis/density_matrix_test.py +20 -17
- cirq/vis/heatmap.py +24 -37
- cirq/vis/heatmap_test.py +3 -0
- cirq/vis/histogram.py +9 -6
- cirq/vis/histogram_test.py +5 -2
- cirq/vis/state_histogram.py +10 -8
- cirq/vis/state_histogram_test.py +7 -5
- cirq/vis/vis_utils.py +4 -1
- cirq/vis/vis_utils_test.py +4 -1
- cirq/work/collector.py +12 -18
- cirq/work/collector_test.py +15 -10
- cirq/work/observable_grouping.py +6 -7
- cirq/work/observable_grouping_test.py +10 -9
- cirq/work/observable_measurement.py +47 -45
- cirq/work/observable_measurement_data.py +22 -17
- cirq/work/observable_measurement_data_test.py +4 -1
- cirq/work/observable_measurement_test.py +48 -29
- cirq/work/observable_readout_calibration.py +5 -2
- cirq/work/observable_readout_calibration_test.py +5 -2
- cirq/work/observable_settings.py +13 -22
- cirq/work/observable_settings_test.py +9 -7
- cirq/work/pauli_sum_collector.py +12 -10
- cirq/work/pauli_sum_collector_test.py +9 -9
- cirq/work/sampler.py +42 -43
- cirq/work/sampler_test.py +31 -24
- cirq/work/zeros_sampler.py +6 -4
- cirq/work/zeros_sampler_test.py +7 -5
- {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/METADATA +7 -8
- cirq_core-1.6.0.dist-info/RECORD +1241 -0
- {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/WHEEL +1 -1
- cirq_core-1.5.0.dev20250409222543.dist-info/RECORD +0 -1216
- {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/top_level.txt +0 -0
|
@@ -13,35 +13,24 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
"""Code for generating random quantum circuits."""
|
|
15
15
|
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
16
18
|
import dataclasses
|
|
17
19
|
import itertools
|
|
18
|
-
from typing import
|
|
19
|
-
Any,
|
|
20
|
-
Callable,
|
|
21
|
-
cast,
|
|
22
|
-
Container,
|
|
23
|
-
Dict,
|
|
24
|
-
Iterable,
|
|
25
|
-
Iterator,
|
|
26
|
-
List,
|
|
27
|
-
Optional,
|
|
28
|
-
Sequence,
|
|
29
|
-
Tuple,
|
|
30
|
-
TYPE_CHECKING,
|
|
31
|
-
Union,
|
|
32
|
-
)
|
|
20
|
+
from typing import Any, Callable, Container, Iterable, Iterator, Sequence, TYPE_CHECKING
|
|
33
21
|
|
|
34
|
-
import networkx as nx
|
|
35
22
|
import numpy as np
|
|
36
23
|
|
|
37
24
|
from cirq import circuits, devices, ops, protocols, value
|
|
38
25
|
from cirq._doc import document
|
|
39
26
|
|
|
40
27
|
if TYPE_CHECKING:
|
|
28
|
+
import networkx as nx
|
|
29
|
+
|
|
41
30
|
import cirq
|
|
42
31
|
|
|
43
|
-
QidPairT =
|
|
44
|
-
GridQubitPairT =
|
|
32
|
+
QidPairT = tuple['cirq.Qid', 'cirq.Qid']
|
|
33
|
+
GridQubitPairT = tuple['cirq.GridQubit', 'cirq.GridQubit']
|
|
45
34
|
|
|
46
35
|
|
|
47
36
|
@dataclasses.dataclass(frozen=True)
|
|
@@ -114,7 +103,7 @@ class GridInteractionLayer(Container[GridQubitPairT]):
|
|
|
114
103
|
pos = a.row % 2, (a.col - self.col_offset) % 2
|
|
115
104
|
return pos == (0, 0) or pos == (1, self.stagger)
|
|
116
105
|
|
|
117
|
-
def _json_dict_(self) ->
|
|
106
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
118
107
|
return protocols.obj_to_dict_helper(self, ['col_offset', 'vertical', 'stagger'])
|
|
119
108
|
|
|
120
109
|
def __repr__(self) -> str:
|
|
@@ -179,20 +168,20 @@ document(
|
|
|
179
168
|
|
|
180
169
|
|
|
181
170
|
def random_rotations_between_two_qubit_circuit(
|
|
182
|
-
q0:
|
|
183
|
-
q1:
|
|
171
|
+
q0: cirq.Qid,
|
|
172
|
+
q1: cirq.Qid,
|
|
184
173
|
depth: int,
|
|
185
174
|
two_qubit_op_factory: Callable[
|
|
186
|
-
[
|
|
175
|
+
[cirq.Qid, cirq.Qid, np.random.RandomState], cirq.OP_TREE
|
|
187
176
|
] = lambda a, b, _: ops.CZPowGate()(a, b),
|
|
188
|
-
single_qubit_gates: Sequence[
|
|
177
|
+
single_qubit_gates: Sequence[cirq.Gate] = (
|
|
189
178
|
ops.X**0.5,
|
|
190
179
|
ops.Y**0.5,
|
|
191
180
|
ops.PhasedXPowGate(phase_exponent=0.25, exponent=0.5),
|
|
192
181
|
),
|
|
193
182
|
add_final_single_qubit_layer: bool = True,
|
|
194
|
-
seed:
|
|
195
|
-
) ->
|
|
183
|
+
seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
184
|
+
) -> cirq.Circuit:
|
|
196
185
|
"""Generate a random two-qubit quantum circuit.
|
|
197
186
|
|
|
198
187
|
This construction uses a similar structure to those in the paper
|
|
@@ -243,14 +232,14 @@ def random_rotations_between_two_qubit_circuit(
|
|
|
243
232
|
|
|
244
233
|
def generate_library_of_2q_circuits(
|
|
245
234
|
n_library_circuits: int,
|
|
246
|
-
two_qubit_gate:
|
|
235
|
+
two_qubit_gate: cirq.Gate,
|
|
247
236
|
*,
|
|
248
237
|
max_cycle_depth: int = 100,
|
|
249
|
-
q0:
|
|
250
|
-
q1:
|
|
251
|
-
random_state:
|
|
238
|
+
q0: cirq.Qid = devices.LineQubit(0),
|
|
239
|
+
q1: cirq.Qid = devices.LineQubit(1),
|
|
240
|
+
random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
252
241
|
tags: Sequence[Any] = (),
|
|
253
|
-
) ->
|
|
242
|
+
) -> list[cirq.Circuit]:
|
|
254
243
|
"""Generate a library of two-qubit Circuits.
|
|
255
244
|
|
|
256
245
|
For single-qubit gates, this uses PhasedXZGates where the axis-in-XY-plane is one
|
|
@@ -306,18 +295,18 @@ class CircuitLibraryCombination:
|
|
|
306
295
|
`get_random_combinations_for_pairs`.
|
|
307
296
|
"""
|
|
308
297
|
|
|
309
|
-
layer:
|
|
298
|
+
layer: Any | None
|
|
310
299
|
combinations: np.ndarray
|
|
311
|
-
pairs:
|
|
300
|
+
pairs: list[QidPairT]
|
|
312
301
|
|
|
313
302
|
|
|
314
303
|
def _get_random_combinations(
|
|
315
304
|
n_library_circuits: int,
|
|
316
305
|
n_combinations: int,
|
|
317
306
|
*,
|
|
318
|
-
pair_gen: Iterator[
|
|
319
|
-
random_state:
|
|
320
|
-
) ->
|
|
307
|
+
pair_gen: Iterator[tuple[list[QidPairT], Any]],
|
|
308
|
+
random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
309
|
+
) -> list[CircuitLibraryCombination]:
|
|
321
310
|
"""For qubit pairs, prepare a set of combinations to efficiently sample
|
|
322
311
|
parallel two-qubit XEB circuits.
|
|
323
312
|
|
|
@@ -366,8 +355,8 @@ def get_random_combinations_for_device(
|
|
|
366
355
|
device_graph: nx.Graph,
|
|
367
356
|
*,
|
|
368
357
|
pattern: Sequence[GridInteractionLayer] = HALF_GRID_STAGGERED_PATTERN,
|
|
369
|
-
random_state:
|
|
370
|
-
) ->
|
|
358
|
+
random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
359
|
+
) -> list[CircuitLibraryCombination]:
|
|
371
360
|
"""For a given device, prepare a set of combinations to efficiently sample
|
|
372
361
|
parallel two-qubit XEB circuits.
|
|
373
362
|
|
|
@@ -419,9 +408,9 @@ def get_random_combinations_for_device(
|
|
|
419
408
|
def get_random_combinations_for_pairs(
|
|
420
409
|
n_library_circuits: int,
|
|
421
410
|
n_combinations: int,
|
|
422
|
-
all_pairs:
|
|
423
|
-
random_state:
|
|
424
|
-
) ->
|
|
411
|
+
all_pairs: list[list[QidPairT]],
|
|
412
|
+
random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
413
|
+
) -> list[CircuitLibraryCombination]:
|
|
425
414
|
"""For an explicit nested list of pairs, prepare a set of combinations to efficiently sample
|
|
426
415
|
parallel two-qubit XEB circuits.
|
|
427
416
|
|
|
@@ -460,26 +449,25 @@ def get_random_combinations_for_pairs(
|
|
|
460
449
|
)
|
|
461
450
|
|
|
462
451
|
|
|
463
|
-
def _pairs_from_moment(moment:
|
|
452
|
+
def _pairs_from_moment(moment: cirq.Moment) -> list[QidPairT]:
|
|
464
453
|
"""Helper function in `get_random_combinations_for_layer_circuit` pair generator.
|
|
465
454
|
|
|
466
455
|
The moment should contain only two qubit operations, which define a list of qubit pairs.
|
|
467
456
|
"""
|
|
468
|
-
pairs:
|
|
457
|
+
pairs: list[QidPairT] = []
|
|
469
458
|
for op in moment.operations:
|
|
470
459
|
if len(op.qubits) != 2:
|
|
471
460
|
raise ValueError("Layer circuit contains non-2-qubit operations.")
|
|
472
|
-
|
|
473
|
-
pairs.append(qpair)
|
|
461
|
+
pairs.append(op.qubits)
|
|
474
462
|
return pairs
|
|
475
463
|
|
|
476
464
|
|
|
477
465
|
def get_random_combinations_for_layer_circuit(
|
|
478
466
|
n_library_circuits: int,
|
|
479
467
|
n_combinations: int,
|
|
480
|
-
layer_circuit:
|
|
481
|
-
random_state:
|
|
482
|
-
) ->
|
|
468
|
+
layer_circuit: cirq.Circuit,
|
|
469
|
+
random_state: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
470
|
+
) -> list[CircuitLibraryCombination]:
|
|
483
471
|
"""For a layer circuit, prepare a set of combinations to efficiently sample
|
|
484
472
|
parallel two-qubit XEB circuits.
|
|
485
473
|
|
|
@@ -523,7 +511,7 @@ def get_grid_interaction_layer_circuit(
|
|
|
523
511
|
device_graph: nx.Graph,
|
|
524
512
|
pattern: Sequence[GridInteractionLayer] = HALF_GRID_STAGGERED_PATTERN,
|
|
525
513
|
two_qubit_gate=ops.ISWAP**0.5,
|
|
526
|
-
) ->
|
|
514
|
+
) -> cirq.Circuit:
|
|
527
515
|
"""Create a circuit representation of a grid interaction pattern on a given device topology.
|
|
528
516
|
|
|
529
517
|
The resulting circuit is deterministic, of depth len(pattern), and consists of `two_qubit_gate`
|
|
@@ -547,21 +535,21 @@ def get_grid_interaction_layer_circuit(
|
|
|
547
535
|
|
|
548
536
|
|
|
549
537
|
def random_rotations_between_grid_interaction_layers_circuit(
|
|
550
|
-
qubits: Iterable[
|
|
538
|
+
qubits: Iterable[cirq.GridQubit],
|
|
551
539
|
depth: int,
|
|
552
540
|
*, # forces keyword arguments
|
|
553
541
|
two_qubit_op_factory: Callable[
|
|
554
|
-
[
|
|
542
|
+
[cirq.GridQubit, cirq.GridQubit, np.random.RandomState], cirq.OP_TREE
|
|
555
543
|
] = lambda a, b, _: ops.CZPowGate()(a, b),
|
|
556
544
|
pattern: Sequence[GridInteractionLayer] = GRID_STAGGERED_PATTERN,
|
|
557
|
-
single_qubit_gates: Sequence[
|
|
545
|
+
single_qubit_gates: Sequence[cirq.Gate] = (
|
|
558
546
|
ops.X**0.5,
|
|
559
547
|
ops.Y**0.5,
|
|
560
548
|
ops.PhasedXPowGate(phase_exponent=0.25, exponent=0.5),
|
|
561
549
|
),
|
|
562
550
|
add_final_single_qubit_layer: bool = True,
|
|
563
|
-
seed:
|
|
564
|
-
) ->
|
|
551
|
+
seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None,
|
|
552
|
+
) -> cirq.Circuit:
|
|
565
553
|
"""Generate a random quantum circuit of a particular form.
|
|
566
554
|
|
|
567
555
|
This construction is based on the circuits used in the paper
|
|
@@ -619,12 +607,12 @@ def random_rotations_between_grid_interaction_layers_circuit(
|
|
|
619
607
|
return circuit
|
|
620
608
|
|
|
621
609
|
|
|
622
|
-
def _coupled_qubit_pairs(qubits:
|
|
610
|
+
def _coupled_qubit_pairs(qubits: list[cirq.GridQubit]) -> list[GridQubitPairT]:
|
|
623
611
|
pairs = []
|
|
624
612
|
qubit_set = set(qubits)
|
|
625
613
|
for qubit in qubits:
|
|
626
614
|
|
|
627
|
-
def add_pair(neighbor:
|
|
615
|
+
def add_pair(neighbor: cirq.GridQubit):
|
|
628
616
|
if neighbor in qubit_set:
|
|
629
617
|
pairs.append((qubit, neighbor))
|
|
630
618
|
|
|
@@ -637,16 +625,16 @@ def _coupled_qubit_pairs(qubits: List['cirq.GridQubit']) -> List[GridQubitPairT]
|
|
|
637
625
|
class _RandomSingleQubitLayerFactory:
|
|
638
626
|
def __init__(
|
|
639
627
|
self,
|
|
640
|
-
qubits: Sequence[
|
|
641
|
-
single_qubit_gates: Sequence[
|
|
642
|
-
prng:
|
|
628
|
+
qubits: Sequence[cirq.Qid],
|
|
629
|
+
single_qubit_gates: Sequence[cirq.Gate],
|
|
630
|
+
prng: np.random.RandomState,
|
|
643
631
|
) -> None:
|
|
644
632
|
self.qubits = qubits
|
|
645
633
|
self.single_qubit_gates = single_qubit_gates
|
|
646
634
|
self.prng = prng
|
|
647
635
|
|
|
648
|
-
def new_layer(self, previous_single_qubit_layer:
|
|
649
|
-
def random_gate(qubit:
|
|
636
|
+
def new_layer(self, previous_single_qubit_layer: cirq.Moment) -> cirq.Moment:
|
|
637
|
+
def random_gate(qubit: cirq.Qid) -> cirq.Gate:
|
|
650
638
|
excluded_op = previous_single_qubit_layer.operation_at(qubit)
|
|
651
639
|
excluded_gate = excluded_op.gate if excluded_op is not None else None
|
|
652
640
|
g = self.single_qubit_gates[self.prng.randint(0, len(self.single_qubit_gates))]
|
|
@@ -658,20 +646,18 @@ class _RandomSingleQubitLayerFactory:
|
|
|
658
646
|
|
|
659
647
|
|
|
660
648
|
class _FixedSingleQubitLayerFactory:
|
|
661
|
-
def __init__(self, fixed_single_qubit_layer:
|
|
649
|
+
def __init__(self, fixed_single_qubit_layer: dict[cirq.Qid, cirq.Gate]) -> None:
|
|
662
650
|
self.fixed_single_qubit_layer = fixed_single_qubit_layer
|
|
663
651
|
|
|
664
|
-
def new_layer(self, previous_single_qubit_layer:
|
|
652
|
+
def new_layer(self, previous_single_qubit_layer: cirq.Moment) -> cirq.Moment:
|
|
665
653
|
return circuits.Moment(v.on(q) for q, v in self.fixed_single_qubit_layer.items())
|
|
666
654
|
|
|
667
655
|
|
|
668
|
-
_SingleQubitLayerFactory =
|
|
656
|
+
_SingleQubitLayerFactory = _FixedSingleQubitLayerFactory | _RandomSingleQubitLayerFactory
|
|
669
657
|
|
|
670
658
|
|
|
671
659
|
def _single_qubit_gates_arg_to_factory(
|
|
672
|
-
single_qubit_gates: Sequence[
|
|
673
|
-
qubits: Sequence['cirq.Qid'],
|
|
674
|
-
prng: 'np.random.RandomState',
|
|
660
|
+
single_qubit_gates: Sequence[cirq.Gate], qubits: Sequence[cirq.Qid], prng: np.random.RandomState
|
|
675
661
|
) -> _SingleQubitLayerFactory:
|
|
676
662
|
"""Parse the `single_qubit_gates` argument for circuit generation functions.
|
|
677
663
|
|
|
@@ -686,13 +672,13 @@ def _single_qubit_gates_arg_to_factory(
|
|
|
686
672
|
|
|
687
673
|
|
|
688
674
|
def _two_qubit_layer(
|
|
689
|
-
coupled_qubit_pairs:
|
|
675
|
+
coupled_qubit_pairs: list[GridQubitPairT],
|
|
690
676
|
two_qubit_op_factory: Callable[
|
|
691
|
-
[
|
|
677
|
+
[cirq.GridQubit, cirq.GridQubit, np.random.RandomState], cirq.OP_TREE
|
|
692
678
|
],
|
|
693
679
|
layer: GridInteractionLayer,
|
|
694
|
-
prng:
|
|
695
|
-
) -> Iterator[
|
|
680
|
+
prng: np.random.RandomState,
|
|
681
|
+
) -> Iterator[cirq.OP_TREE]:
|
|
696
682
|
for a, b in coupled_qubit_pairs:
|
|
697
683
|
if (a, b) in layer or (b, a) in layer:
|
|
698
684
|
yield two_qubit_op_factory(a, b, prng)
|
|
@@ -11,8 +11,11 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
14
17
|
import itertools
|
|
15
|
-
from typing import Callable, cast,
|
|
18
|
+
from typing import Callable, cast, Iterable, Sequence
|
|
16
19
|
|
|
17
20
|
import networkx as nx
|
|
18
21
|
import numpy as np
|
|
@@ -32,7 +35,7 @@ from cirq.experiments.random_quantum_circuit_generation import (
|
|
|
32
35
|
random_rotations_between_two_qubit_circuit,
|
|
33
36
|
)
|
|
34
37
|
|
|
35
|
-
SINGLE_QUBIT_LAYER =
|
|
38
|
+
SINGLE_QUBIT_LAYER = dict[cirq.GridQubit, cirq.Gate | None]
|
|
36
39
|
|
|
37
40
|
|
|
38
41
|
def test_random_rotation_between_two_qubit_circuit():
|
|
@@ -366,7 +369,7 @@ def test_random_rotations_between_grid_interaction_layers(
|
|
|
366
369
|
pattern: Sequence[GridInteractionLayer],
|
|
367
370
|
single_qubit_gates: Sequence[cirq.Gate],
|
|
368
371
|
add_final_single_qubit_layer: bool,
|
|
369
|
-
seed:
|
|
372
|
+
seed: cirq.RANDOM_STATE_OR_SEED_LIKE,
|
|
370
373
|
expected_circuit_length: int,
|
|
371
374
|
single_qubit_layers_slice: slice,
|
|
372
375
|
two_qubit_layers_slice: slice,
|
|
@@ -401,7 +404,7 @@ def test_grid_interaction_layer_repr():
|
|
|
401
404
|
|
|
402
405
|
|
|
403
406
|
def _validate_single_qubit_layers(
|
|
404
|
-
qubits:
|
|
407
|
+
qubits: set[cirq.GridQubit], moments: Sequence[cirq.Moment], non_repeating_layers: bool = True
|
|
405
408
|
) -> None:
|
|
406
409
|
previous_single_qubit_gates: SINGLE_QUBIT_LAYER = {q: None for q in qubits}
|
|
407
410
|
|
|
@@ -419,7 +422,7 @@ def _validate_single_qubit_layers(
|
|
|
419
422
|
|
|
420
423
|
|
|
421
424
|
def _validate_two_qubit_layers(
|
|
422
|
-
qubits:
|
|
425
|
+
qubits: set[cirq.GridQubit],
|
|
423
426
|
moments: Sequence[cirq.Moment],
|
|
424
427
|
pattern: Sequence[cirq.experiments.GridInteractionLayer],
|
|
425
428
|
) -> None:
|
|
@@ -444,12 +447,12 @@ def _validate_two_qubit_layers(
|
|
|
444
447
|
|
|
445
448
|
|
|
446
449
|
def _coupled_qubit_pairs(
|
|
447
|
-
qubits:
|
|
448
|
-
) ->
|
|
450
|
+
qubits: set[cirq.GridQubit],
|
|
451
|
+
) -> list[tuple[cirq.GridQubit, cirq.GridQubit]]:
|
|
449
452
|
pairs = []
|
|
450
453
|
for qubit in qubits:
|
|
451
454
|
|
|
452
|
-
def add_pair(neighbor:
|
|
455
|
+
def add_pair(neighbor: cirq.GridQubit):
|
|
453
456
|
if neighbor in qubits:
|
|
454
457
|
pairs.append((qubit, neighbor))
|
|
455
458
|
|
|
@@ -14,8 +14,10 @@
|
|
|
14
14
|
|
|
15
15
|
"""Utilities to compute readout confusion matrix and use it for readout error mitigation."""
|
|
16
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
17
19
|
import time
|
|
18
|
-
from typing import Any, cast,
|
|
20
|
+
from typing import Any, cast, Sequence, TYPE_CHECKING
|
|
19
21
|
|
|
20
22
|
import numpy as np
|
|
21
23
|
import scipy.optimize
|
|
@@ -59,8 +61,8 @@ class TensoredConfusionMatrices:
|
|
|
59
61
|
|
|
60
62
|
def __init__(
|
|
61
63
|
self,
|
|
62
|
-
confusion_matrices:
|
|
63
|
-
measure_qubits:
|
|
64
|
+
confusion_matrices: np.ndarray | Sequence[np.ndarray],
|
|
65
|
+
measure_qubits: Sequence[cirq.Qid] | Sequence[Sequence[cirq.Qid]],
|
|
64
66
|
*,
|
|
65
67
|
repetitions: int,
|
|
66
68
|
timestamp: float,
|
|
@@ -112,14 +114,14 @@ class TensoredConfusionMatrices:
|
|
|
112
114
|
self._measure_qubits = tuple(tuple(q) for q in measure_qubits)
|
|
113
115
|
self._qubits = tuple(sorted(set(q for ql in measure_qubits for q in ql)))
|
|
114
116
|
self._qubits_to_idx = {q: i for i, q in enumerate(self._qubits)}
|
|
115
|
-
self._cache:
|
|
117
|
+
self._cache: dict[tuple[cirq.Qid, ...], np.ndarray] = {}
|
|
116
118
|
if sum(len(q) for q in self._measure_qubits) != len(self._qubits):
|
|
117
119
|
raise ValueError(f"Repeated qubits not allowed in measure_qubits: {measure_qubits}.")
|
|
118
120
|
|
|
119
121
|
@classmethod
|
|
120
122
|
def from_measurement(
|
|
121
|
-
cls, gate: ops.MeasurementGate, qubits: Sequence[
|
|
122
|
-
) ->
|
|
123
|
+
cls, gate: ops.MeasurementGate, qubits: Sequence[cirq.Qid]
|
|
124
|
+
) -> TensoredConfusionMatrices:
|
|
123
125
|
"""Generates TCM for the confusion map in a MeasurementGate.
|
|
124
126
|
|
|
125
127
|
This ignores any invert_mask defined for the gate - it only replicates the confusion map.
|
|
@@ -155,27 +157,27 @@ class TensoredConfusionMatrices:
|
|
|
155
157
|
return self._timestamp
|
|
156
158
|
|
|
157
159
|
@property
|
|
158
|
-
def confusion_matrices(self) ->
|
|
160
|
+
def confusion_matrices(self) -> tuple[np.ndarray, ...]:
|
|
159
161
|
"""List of confusion matrices corresponding to `measure_qubits` qubit pattern."""
|
|
160
162
|
return self._confusion_matrices
|
|
161
163
|
|
|
162
164
|
@property
|
|
163
|
-
def measure_qubits(self) ->
|
|
165
|
+
def measure_qubits(self) -> tuple[tuple[cirq.Qid, ...], ...]:
|
|
164
166
|
"""Calibrated qubit pattern for which individual confusion matrices were computed."""
|
|
165
167
|
return self._measure_qubits
|
|
166
168
|
|
|
167
169
|
@property
|
|
168
|
-
def qubits(self) ->
|
|
170
|
+
def qubits(self) -> tuple[cirq.Qid, ...]:
|
|
169
171
|
"""Sorted list of all calibrated qubits."""
|
|
170
172
|
return self._qubits
|
|
171
173
|
|
|
172
|
-
def _get_vars(self, qubit_pattern: Sequence[
|
|
174
|
+
def _get_vars(self, qubit_pattern: Sequence[cirq.Qid]) -> list[int]:
|
|
173
175
|
in_vars = [2 * self._qubits_to_idx[q] for q in qubit_pattern]
|
|
174
176
|
out_vars = [2 * self._qubits_to_idx[q] + 1 for q in qubit_pattern]
|
|
175
177
|
return in_vars + out_vars
|
|
176
178
|
|
|
177
|
-
def _confusion_matrix(self, qubits: Sequence[
|
|
178
|
-
ein_input:
|
|
179
|
+
def _confusion_matrix(self, qubits: Sequence[cirq.Qid]) -> np.ndarray:
|
|
180
|
+
ein_input: list[np.ndarray | list[int]] = []
|
|
179
181
|
for qs, cm in zip(self.measure_qubits, self.confusion_matrices):
|
|
180
182
|
ein_input.extend([cm.reshape((2, 2) * len(qs)), self._get_vars(qs)])
|
|
181
183
|
ein_out = self._get_vars(qubits)
|
|
@@ -183,7 +185,7 @@ class TensoredConfusionMatrices:
|
|
|
183
185
|
ret = np.einsum(*ein_input, ein_out).reshape((2 ** len(qubits),) * 2)
|
|
184
186
|
return ret / ret.sum(axis=1)
|
|
185
187
|
|
|
186
|
-
def confusion_matrix(self, qubits:
|
|
188
|
+
def confusion_matrix(self, qubits: Sequence[cirq.Qid] | None = None) -> np.ndarray:
|
|
187
189
|
"""Returns a single confusion matrix constructed for the given set of qubits.
|
|
188
190
|
|
|
189
191
|
The single `2 ** len(qubits) x 2 ** len(qubits)` confusion matrix is constructed
|
|
@@ -211,7 +213,7 @@ class TensoredConfusionMatrices:
|
|
|
211
213
|
self._cache[key] = self._confusion_matrix(qubits)
|
|
212
214
|
return self._cache[key]
|
|
213
215
|
|
|
214
|
-
def correction_matrix(self, qubits:
|
|
216
|
+
def correction_matrix(self, qubits: Sequence[cirq.Qid] | None = None) -> np.ndarray:
|
|
215
217
|
"""Returns a single correction matrix constructed for the given set of qubits.
|
|
216
218
|
|
|
217
219
|
A correction matrix is the inverse of confusion matrix and can be used to apply corrections
|
|
@@ -240,7 +242,7 @@ class TensoredConfusionMatrices:
|
|
|
240
242
|
def apply(
|
|
241
243
|
self,
|
|
242
244
|
result: np.ndarray,
|
|
243
|
-
qubits:
|
|
245
|
+
qubits: Sequence[cirq.Qid] | None = None,
|
|
244
246
|
*,
|
|
245
247
|
method='least_squares',
|
|
246
248
|
) -> np.ndarray:
|
|
@@ -300,7 +302,7 @@ class TensoredConfusionMatrices:
|
|
|
300
302
|
return res.x
|
|
301
303
|
|
|
302
304
|
def readout_mitigation_pauli_uncorrelated(
|
|
303
|
-
self, qubits: Sequence[
|
|
305
|
+
self, qubits: Sequence[cirq.Qid], measured_bitstrings: np.ndarray
|
|
304
306
|
) -> tuple[float, float]:
|
|
305
307
|
r"""Uncorrelated readout error mitigation for a multi-qubit Pauli operator.
|
|
306
308
|
|
|
@@ -345,8 +347,8 @@ class TensoredConfusionMatrices:
|
|
|
345
347
|
idx = self.measure_qubits.index((qubit,))
|
|
346
348
|
except: # pragma: no cover
|
|
347
349
|
raise NotImplementedError(
|
|
348
|
-
"The response matrix must be a tensor product of single-
|
|
349
|
-
|
|
350
|
+
"The response matrix must be a tensor product of single-qubit "
|
|
351
|
+
f"response matrices, including that of qubit {qubit}."
|
|
350
352
|
)
|
|
351
353
|
cm_all.append(self.confusion_matrices[idx])
|
|
352
354
|
|
|
@@ -373,7 +375,7 @@ class TensoredConfusionMatrices:
|
|
|
373
375
|
f")"
|
|
374
376
|
)
|
|
375
377
|
|
|
376
|
-
def _json_dict_(self) ->
|
|
378
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
377
379
|
return {
|
|
378
380
|
'confusion_matrices': self.confusion_matrices,
|
|
379
381
|
'measure_qubits': self.measure_qubits,
|
|
@@ -384,7 +386,7 @@ class TensoredConfusionMatrices:
|
|
|
384
386
|
@classmethod
|
|
385
387
|
def _from_json_dict_(
|
|
386
388
|
cls, confusion_matrices, measure_qubits, repetitions, timestamp, **kwargs
|
|
387
|
-
) ->
|
|
389
|
+
) -> TensoredConfusionMatrices:
|
|
388
390
|
return cls(
|
|
389
391
|
[np.asarray(cm) for cm in confusion_matrices],
|
|
390
392
|
measure_qubits,
|
|
@@ -423,8 +425,8 @@ class TensoredConfusionMatrices:
|
|
|
423
425
|
|
|
424
426
|
|
|
425
427
|
def measure_confusion_matrix(
|
|
426
|
-
sampler:
|
|
427
|
-
qubits:
|
|
428
|
+
sampler: cirq.Sampler,
|
|
429
|
+
qubits: Sequence[cirq.Qid] | Sequence[Sequence[cirq.Qid]],
|
|
428
430
|
repetitions: int = 1000,
|
|
429
431
|
) -> TensoredConfusionMatrices:
|
|
430
432
|
"""Prepares `TensoredConfusionMatrices` for the n qubits in the input.
|
|
@@ -11,10 +11,14 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
"""Single qubit readout experiments using parallel or isolated statistics."""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
15
19
|
import dataclasses
|
|
16
20
|
import time
|
|
17
|
-
from typing import Any, cast,
|
|
21
|
+
from typing import Any, cast, Iterable, TYPE_CHECKING
|
|
18
22
|
|
|
19
23
|
import matplotlib.pyplot as plt
|
|
20
24
|
import numpy as np
|
|
@@ -43,12 +47,12 @@ class SingleQubitReadoutCalibrationResult:
|
|
|
43
47
|
timestamp: The time the data was taken, in seconds since the epoch.
|
|
44
48
|
"""
|
|
45
49
|
|
|
46
|
-
zero_state_errors:
|
|
47
|
-
one_state_errors:
|
|
50
|
+
zero_state_errors: dict[cirq.Qid, float]
|
|
51
|
+
one_state_errors: dict[cirq.Qid, float]
|
|
48
52
|
repetitions: int
|
|
49
53
|
timestamp: float
|
|
50
54
|
|
|
51
|
-
def _json_dict_(self) ->
|
|
55
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
52
56
|
return {
|
|
53
57
|
'zero_state_errors': list(self.zero_state_errors.items()),
|
|
54
58
|
'one_state_errors': list(self.one_state_errors.items()),
|
|
@@ -58,7 +62,7 @@ class SingleQubitReadoutCalibrationResult:
|
|
|
58
62
|
|
|
59
63
|
def plot_heatmap(
|
|
60
64
|
self,
|
|
61
|
-
axs:
|
|
65
|
+
axs: tuple[plt.Axes, plt.Axes] | None = None,
|
|
62
66
|
annotation_format: str = '0.1%',
|
|
63
67
|
**plot_kwargs: Any,
|
|
64
68
|
) -> tuple[plt.Axes, plt.Axes]:
|
|
@@ -106,16 +110,16 @@ class SingleQubitReadoutCalibrationResult:
|
|
|
106
110
|
|
|
107
111
|
def plot_integrated_histogram(
|
|
108
112
|
self,
|
|
109
|
-
ax:
|
|
113
|
+
ax: plt.Axes | None = None,
|
|
110
114
|
cdf_on_x: bool = False,
|
|
111
115
|
axis_label: str = 'Readout error rate',
|
|
112
116
|
semilog: bool = True,
|
|
113
117
|
median_line: bool = True,
|
|
114
|
-
median_label:
|
|
118
|
+
median_label: str | None = 'median',
|
|
115
119
|
mean_line: bool = False,
|
|
116
|
-
mean_label:
|
|
120
|
+
mean_label: str | None = 'mean',
|
|
117
121
|
show_zero: bool = False,
|
|
118
|
-
title:
|
|
122
|
+
title: str | None = None,
|
|
119
123
|
**kwargs,
|
|
120
124
|
) -> plt.Axes:
|
|
121
125
|
"""Plot the readout errors using cirq.integrated_histogram().
|
|
@@ -175,6 +179,17 @@ class SingleQubitReadoutCalibrationResult:
|
|
|
175
179
|
ax.set_ylabel('Percentile')
|
|
176
180
|
return ax
|
|
177
181
|
|
|
182
|
+
def readout_result_for_qubits(
|
|
183
|
+
self, readout_qubits: list[ops.Qid]
|
|
184
|
+
) -> SingleQubitReadoutCalibrationResult:
|
|
185
|
+
"""Builds a calibration result for the specific readout qubits."""
|
|
186
|
+
return SingleQubitReadoutCalibrationResult(
|
|
187
|
+
zero_state_errors={qubit: self.zero_state_errors[qubit] for qubit in readout_qubits},
|
|
188
|
+
one_state_errors={qubit: self.one_state_errors[qubit] for qubit in readout_qubits},
|
|
189
|
+
timestamp=self.timestamp,
|
|
190
|
+
repetitions=self.repetitions,
|
|
191
|
+
)
|
|
192
|
+
|
|
178
193
|
@classmethod
|
|
179
194
|
def _from_json_dict_(
|
|
180
195
|
cls, zero_state_errors, one_state_errors, repetitions, timestamp, **kwargs
|
|
@@ -197,7 +212,7 @@ class SingleQubitReadoutCalibrationResult:
|
|
|
197
212
|
|
|
198
213
|
|
|
199
214
|
def estimate_single_qubit_readout_errors(
|
|
200
|
-
sampler:
|
|
215
|
+
sampler: cirq.Sampler, *, qubits: Iterable[cirq.Qid], repetitions: int = 1000
|
|
201
216
|
) -> SingleQubitReadoutCalibrationResult:
|
|
202
217
|
"""Estimate single-qubit readout error.
|
|
203
218
|
|
|
@@ -229,13 +244,13 @@ def estimate_single_qubit_readout_errors(
|
|
|
229
244
|
|
|
230
245
|
|
|
231
246
|
def estimate_parallel_single_qubit_readout_errors(
|
|
232
|
-
sampler:
|
|
247
|
+
sampler: cirq.Sampler,
|
|
233
248
|
*,
|
|
234
|
-
qubits: Iterable[
|
|
249
|
+
qubits: Iterable[cirq.Qid],
|
|
235
250
|
trials: int = 20,
|
|
236
251
|
repetitions: int = 1000,
|
|
237
|
-
trials_per_batch:
|
|
238
|
-
bit_strings:
|
|
252
|
+
trials_per_batch: int | None = None,
|
|
253
|
+
bit_strings: np.ndarray | None = None,
|
|
239
254
|
) -> SingleQubitReadoutCalibrationResult:
|
|
240
255
|
"""Estimate single qubit readout error using parallel operations.
|
|
241
256
|
|
|
@@ -296,7 +311,7 @@ def estimate_parallel_single_qubit_readout_errors(
|
|
|
296
311
|
if trials_per_batch <= 0:
|
|
297
312
|
raise ValueError("Must provide non-zero trials_per_batch for readout calibration.")
|
|
298
313
|
|
|
299
|
-
all_sweeps:
|
|
314
|
+
all_sweeps: list[study.Sweepable] = []
|
|
300
315
|
num_batches = (trials + trials_per_batch - 1) // trials_per_batch
|
|
301
316
|
|
|
302
317
|
# Initialize circuits
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
14
17
|
from typing import Sequence
|
|
15
18
|
|
|
16
19
|
import numpy as np
|
|
@@ -30,7 +33,7 @@ def test_single_qubit_readout_result_repr():
|
|
|
30
33
|
|
|
31
34
|
|
|
32
35
|
class NoisySingleQubitReadoutSampler(cirq.Sampler):
|
|
33
|
-
def __init__(self, p0: float, p1: float, seed:
|
|
36
|
+
def __init__(self, p0: float, p1: float, seed: cirq.RANDOM_STATE_OR_SEED_LIKE = None):
|
|
34
37
|
"""Sampler that flips some bits upon readout.
|
|
35
38
|
|
|
36
39
|
Args:
|
|
@@ -44,7 +47,7 @@ class NoisySingleQubitReadoutSampler(cirq.Sampler):
|
|
|
44
47
|
self.simulator = cirq.Simulator(seed=self.prng, split_untangled_states=False)
|
|
45
48
|
|
|
46
49
|
def run_sweep(
|
|
47
|
-
self, program:
|
|
50
|
+
self, program: cirq.AbstractCircuit, params: cirq.Sweepable, repetitions: int = 1
|
|
48
51
|
) -> Sequence[cirq.Result]:
|
|
49
52
|
results = self.simulator.run_sweep(program, params, repetitions)
|
|
50
53
|
for result in results:
|