cirq-core 1.4.0.dev20240529225110__py3-none-any.whl → 1.5.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 +587 -569
- cirq/_compat.py +9 -0
- cirq/_compat_test.py +11 -9
- cirq/_import.py +7 -8
- cirq/_version.py +31 -1
- cirq/_version_test.py +1 -1
- cirq/circuits/__init__.py +15 -9
- cirq/circuits/_block_diagram_drawer.py +1 -2
- cirq/circuits/_block_diagram_drawer_test.py +3 -3
- cirq/circuits/_box_drawing_character_data.py +0 -1
- cirq/circuits/_box_drawing_character_data_test.py +2 -2
- cirq/circuits/_bucket_priority_queue.py +0 -1
- cirq/circuits/_bucket_priority_queue_test.py +1 -1
- cirq/circuits/circuit.py +336 -234
- cirq/circuits/circuit_operation.py +102 -52
- cirq/circuits/circuit_operation_test.py +85 -4
- cirq/circuits/circuit_test.py +101 -32
- cirq/circuits/frozen_circuit.py +36 -32
- cirq/circuits/insert_strategy.py +10 -0
- cirq/circuits/insert_strategy_test.py +20 -0
- cirq/circuits/moment.py +79 -80
- cirq/circuits/moment_test.py +105 -2
- cirq/circuits/optimization_pass.py +15 -15
- cirq/circuits/optimization_pass_test.py +8 -9
- cirq/circuits/qasm_output.py +64 -33
- cirq/circuits/qasm_output_test.py +63 -2
- cirq/circuits/text_diagram_drawer.py +26 -56
- cirq/circuits/text_diagram_drawer_test.py +5 -4
- cirq/contrib/__init__.py +2 -2
- cirq/contrib/acquaintance/__init__.py +44 -29
- cirq/contrib/acquaintance/bipartite.py +8 -7
- cirq/contrib/acquaintance/bipartite_test.py +11 -1
- cirq/contrib/acquaintance/devices.py +5 -4
- cirq/contrib/acquaintance/devices_test.py +5 -1
- cirq/contrib/acquaintance/executor.py +18 -21
- cirq/contrib/acquaintance/executor_test.py +3 -2
- cirq/contrib/acquaintance/gates.py +36 -27
- cirq/contrib/acquaintance/gates_test.py +1 -1
- cirq/contrib/acquaintance/inspection_utils.py +10 -9
- cirq/contrib/acquaintance/inspection_utils_test.py +6 -1
- cirq/contrib/acquaintance/mutation_utils.py +10 -10
- cirq/contrib/acquaintance/optimizers.py +7 -6
- cirq/contrib/acquaintance/optimizers_test.py +1 -1
- cirq/contrib/acquaintance/permutation.py +22 -21
- cirq/contrib/acquaintance/permutation_test.py +1 -1
- cirq/contrib/acquaintance/shift.py +8 -6
- cirq/contrib/acquaintance/shift_swap_network.py +6 -4
- cirq/contrib/acquaintance/strategies/__init__.py +9 -3
- cirq/contrib/acquaintance/strategies/complete.py +4 -3
- cirq/contrib/acquaintance/strategies/cubic.py +5 -3
- cirq/contrib/acquaintance/strategies/quartic_paired.py +8 -6
- cirq/contrib/acquaintance/topological_sort.py +4 -2
- cirq/contrib/bayesian_network/__init__.py +3 -1
- cirq/contrib/bayesian_network/bayesian_network_gate.py +5 -3
- cirq/contrib/circuitdag/__init__.py +1 -1
- cirq/contrib/circuitdag/circuit_dag.py +24 -24
- cirq/contrib/circuitdag/circuit_dag_test.py +1 -1
- cirq/contrib/custom_simulators/custom_state_simulator.py +10 -8
- cirq/contrib/custom_simulators/custom_state_simulator_test.py +15 -11
- cirq/contrib/graph_device/__init__.py +8 -8
- cirq/contrib/graph_device/graph_device.py +8 -8
- cirq/contrib/graph_device/graph_device_test.py +0 -1
- cirq/contrib/graph_device/hypergraph_test.py +1 -0
- cirq/contrib/json.py +1 -2
- cirq/contrib/json_test.py +2 -2
- cirq/contrib/noise_models/__init__.py +5 -6
- cirq/contrib/noise_models/noise_models.py +8 -6
- cirq/contrib/paulistring/__init__.py +22 -10
- cirq/contrib/paulistring/clifford_optimize.py +1 -1
- cirq/contrib/paulistring/clifford_optimize_test.py +0 -1
- cirq/contrib/paulistring/clifford_target_gateset.py +15 -12
- cirq/contrib/paulistring/optimize.py +2 -2
- cirq/contrib/paulistring/optimize_test.py +0 -1
- cirq/contrib/paulistring/pauli_string_dag_test.py +0 -1
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +379 -0
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +523 -0
- cirq/contrib/paulistring/pauli_string_optimize.py +3 -1
- cirq/contrib/paulistring/pauli_string_optimize_test.py +1 -3
- cirq/contrib/paulistring/recombine.py +2 -2
- cirq/contrib/paulistring/recombine_test.py +2 -2
- cirq/contrib/paulistring/separate.py +3 -4
- cirq/contrib/qasm_import/__init__.py +2 -2
- cirq/contrib/qasm_import/_lexer.py +21 -26
- cirq/contrib/qasm_import/_lexer_test.py +90 -6
- cirq/contrib/qasm_import/_parser.py +238 -47
- cirq/contrib/qasm_import/_parser_test.py +514 -59
- cirq/contrib/qasm_import/qasm_test.py +1 -1
- cirq/contrib/qcircuit/__init__.py +6 -4
- cirq/contrib/qcircuit/qcircuit_diagram.py +5 -2
- cirq/contrib/qcircuit/qcircuit_pdf.py +1 -2
- cirq/{experiments/grid_parallel_two_qubit_xeb_test.py → contrib/qcircuit/qcircuit_pdf_test.py} +13 -12
- cirq/contrib/qcircuit/qcircuit_test.py +1 -1
- cirq/contrib/quantum_volume/__init__.py +7 -7
- cirq/contrib/quantum_volume/quantum_volume.py +6 -11
- cirq/contrib/quantum_volume/quantum_volume_test.py +3 -1
- cirq/contrib/quimb/__init__.py +16 -13
- cirq/contrib/quimb/density_matrix.py +1 -1
- cirq/contrib/quimb/mps_simulator.py +27 -28
- cirq/contrib/quimb/mps_simulator_test.py +5 -0
- cirq/contrib/quimb/state_vector.py +3 -10
- cirq/contrib/quirk/__init__.py +1 -1
- cirq/contrib/quirk/export_to_quirk.py +3 -3
- cirq/contrib/routing/__init__.py +12 -9
- cirq/contrib/routing/device.py +1 -1
- cirq/contrib/routing/device_test.py +1 -2
- cirq/contrib/routing/greedy.py +7 -5
- cirq/contrib/routing/greedy_test.py +5 -3
- cirq/contrib/routing/initialization.py +3 -1
- cirq/contrib/routing/initialization_test.py +1 -1
- cirq/contrib/routing/swap_network.py +6 -6
- cirq/contrib/routing/utils.py +6 -4
- cirq/contrib/routing/utils_test.py +1 -2
- cirq/{type_workarounds.py → contrib/shuffle_circuits/__init__.py} +5 -10
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +250 -0
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +363 -0
- cirq/contrib/svg/__init__.py +1 -1
- cirq/contrib/svg/svg.py +12 -10
- cirq/contrib/svg/svg_test.py +3 -2
- cirq/devices/__init__.py +34 -25
- cirq/devices/device.py +16 -12
- cirq/devices/device_test.py +1 -0
- cirq/devices/grid_device_metadata.py +16 -12
- cirq/devices/grid_device_metadata_test.py +2 -1
- cirq/devices/grid_qubit.py +31 -26
- cirq/devices/grid_qubit_test.py +30 -1
- cirq/devices/insertion_noise_model.py +6 -6
- cirq/devices/insertion_noise_model_test.py +1 -1
- cirq/devices/line_qubit.py +28 -20
- cirq/devices/line_qubit_test.py +26 -0
- cirq/devices/named_topologies.py +12 -10
- cirq/devices/named_topologies_test.py +5 -4
- cirq/devices/noise_model.py +29 -33
- cirq/devices/noise_properties.py +2 -2
- cirq/devices/noise_properties_test.py +2 -2
- cirq/devices/noise_utils.py +3 -3
- cirq/devices/superconducting_qubits_noise_properties.py +2 -2
- cirq/devices/superconducting_qubits_noise_properties_test.py +3 -3
- cirq/devices/thermal_noise_model.py +2 -1
- cirq/devices/unconstrained_device.py +1 -1
- cirq/devices/unconstrained_device_test.py +6 -0
- cirq/experiments/__init__.py +51 -34
- cirq/experiments/qubit_characterizations.py +17 -15
- cirq/experiments/qubit_characterizations_test.py +4 -6
- cirq/experiments/random_quantum_circuit_generation.py +10 -9
- cirq/experiments/random_quantum_circuit_generation_test.py +21 -4
- cirq/experiments/readout_confusion_matrix.py +73 -8
- cirq/experiments/readout_confusion_matrix_test.py +104 -1
- cirq/experiments/single_qubit_readout_calibration.py +8 -6
- cirq/experiments/single_qubit_readout_calibration_test.py +1 -1
- cirq/experiments/t1_decay_experiment.py +4 -5
- cirq/experiments/t1_decay_experiment_test.py +1 -2
- cirq/experiments/t2_decay_experiment.py +0 -1
- cirq/experiments/t2_decay_experiment_test.py +1 -2
- cirq/experiments/two_qubit_xeb.py +157 -33
- cirq/experiments/two_qubit_xeb_test.py +38 -22
- cirq/experiments/xeb_fitting.py +99 -19
- cirq/experiments/xeb_fitting_test.py +64 -25
- cirq/experiments/xeb_sampling.py +14 -18
- cirq/experiments/xeb_simulation.py +4 -3
- cirq/experiments/xeb_simulation_test.py +20 -14
- cirq/experiments/z_phase_calibration.py +368 -0
- cirq/experiments/z_phase_calibration_test.py +241 -0
- cirq/interop/__init__.py +4 -1
- cirq/interop/quirk/__init__.py +7 -4
- cirq/interop/quirk/cells/__init__.py +17 -6
- cirq/interop/quirk/cells/arithmetic_cells.py +8 -8
- cirq/interop/quirk/cells/arithmetic_cells_test.py +1 -1
- cirq/interop/quirk/cells/cell.py +6 -6
- cirq/interop/quirk/cells/composite_cell.py +5 -5
- cirq/interop/quirk/cells/composite_cell_test.py +1 -1
- cirq/interop/quirk/cells/control_cells.py +1 -1
- cirq/interop/quirk/cells/frequency_space_cells.py +2 -2
- cirq/interop/quirk/cells/ignored_cells.py +1 -1
- cirq/interop/quirk/cells/input_cells.py +1 -1
- cirq/interop/quirk/cells/input_cells_test.py +1 -1
- cirq/interop/quirk/cells/input_rotation_cells.py +1 -1
- cirq/interop/quirk/cells/input_rotation_cells_test.py +1 -1
- cirq/interop/quirk/cells/measurement_cells.py +1 -1
- cirq/interop/quirk/cells/parse.py +8 -7
- cirq/interop/quirk/cells/parse_test.py +2 -2
- cirq/interop/quirk/cells/single_qubit_rotation_cells.py +1 -1
- cirq/interop/quirk/cells/swap_cell_test.py +1 -1
- cirq/interop/quirk/cells/unsupported_cells.py +1 -1
- cirq/interop/quirk/url_to_circuit.py +7 -7
- cirq/interop/quirk/url_to_circuit_test.py +1 -1
- cirq/ion/__init__.py +4 -2
- cirq/json_resolver_cache.py +15 -7
- cirq/linalg/__init__.py +62 -51
- cirq/linalg/combinators.py +4 -4
- cirq/linalg/combinators_test.py +4 -1
- cirq/linalg/decompositions.py +15 -40
- cirq/linalg/decompositions_test.py +16 -22
- cirq/linalg/diagonalize.py +1 -1
- cirq/linalg/diagonalize_test.py +1 -1
- cirq/linalg/operator_spaces.py +20 -4
- cirq/linalg/operator_spaces_test.py +15 -2
- cirq/linalg/predicates.py +3 -3
- cirq/linalg/predicates_test.py +1 -0
- cirq/linalg/tolerance.py +2 -2
- cirq/linalg/transformations.py +30 -12
- cirq/linalg/transformations_test.py +13 -0
- cirq/neutral_atoms/__init__.py +2 -2
- cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +0 -1
- cirq/ops/__init__.py +172 -132
- cirq/ops/arithmetic_operation.py +2 -2
- cirq/ops/arithmetic_operation_test.py +2 -2
- cirq/ops/boolean_hamiltonian.py +3 -2
- cirq/ops/classically_controlled_operation.py +39 -12
- cirq/ops/classically_controlled_operation_test.py +147 -1
- cirq/ops/clifford_gate.py +38 -36
- cirq/ops/clifford_gate_test.py +75 -1
- cirq/ops/common_channels.py +16 -45
- cirq/ops/common_channels_test.py +10 -0
- cirq/ops/common_gate_families.py +1 -1
- cirq/ops/common_gate_families_test.py +1 -0
- cirq/ops/common_gates.py +48 -49
- cirq/ops/common_gates_test.py +18 -2
- cirq/ops/control_values.py +3 -3
- cirq/ops/control_values_test.py +2 -1
- cirq/ops/controlled_gate.py +36 -23
- cirq/ops/controlled_gate_test.py +70 -3
- cirq/ops/controlled_operation.py +6 -5
- cirq/ops/controlled_operation_test.py +7 -3
- cirq/ops/dense_pauli_string.py +11 -11
- cirq/ops/diagonal_gate.py +2 -2
- cirq/ops/diagonal_gate_test.py +1 -0
- cirq/ops/eigen_gate.py +16 -36
- cirq/ops/eigen_gate_test.py +60 -10
- cirq/ops/fourier_transform.py +1 -3
- cirq/ops/fourier_transform_test.py +2 -1
- cirq/ops/fsim_gate.py +42 -3
- cirq/ops/fsim_gate_test.py +21 -0
- cirq/ops/gate_operation.py +8 -8
- cirq/ops/gate_operation_test.py +4 -2
- cirq/ops/gateset_test.py +11 -2
- cirq/ops/global_phase_op.py +8 -7
- cirq/ops/global_phase_op_test.py +1 -1
- cirq/ops/greedy_qubit_manager_test.py +5 -0
- cirq/ops/identity.py +14 -4
- cirq/ops/identity_test.py +24 -0
- cirq/ops/kraus_channel.py +1 -0
- cirq/ops/kraus_channel_test.py +3 -1
- cirq/ops/linear_combinations.py +27 -21
- cirq/ops/linear_combinations_test.py +23 -4
- cirq/ops/matrix_gates.py +24 -8
- cirq/ops/measure_util.py +2 -2
- cirq/ops/measurement_gate.py +7 -4
- cirq/ops/measurement_gate_test.py +2 -1
- cirq/ops/mixed_unitary_channel.py +1 -0
- cirq/ops/mixed_unitary_channel_test.py +3 -1
- cirq/ops/named_qubit.py +8 -1
- cirq/ops/op_tree.py +3 -30
- cirq/ops/op_tree_test.py +4 -0
- cirq/ops/parallel_gate.py +2 -3
- cirq/ops/parallel_gate_test.py +2 -1
- cirq/ops/parity_gates.py +7 -8
- cirq/ops/parity_gates_test.py +1 -0
- cirq/ops/pauli_gates.py +5 -11
- cirq/ops/pauli_gates_test.py +1 -0
- cirq/ops/pauli_interaction_gate.py +11 -5
- cirq/ops/pauli_interaction_gate_test.py +2 -3
- cirq/ops/pauli_measurement_gate.py +6 -5
- cirq/ops/pauli_measurement_gate_test.py +1 -0
- cirq/ops/pauli_string.py +115 -130
- cirq/ops/pauli_string_phasor.py +21 -20
- cirq/ops/pauli_string_phasor_test.py +13 -3
- cirq/ops/pauli_string_raw_types.py +1 -0
- cirq/ops/pauli_string_test.py +192 -55
- cirq/ops/pauli_sum_exponential.py +3 -4
- cirq/ops/pauli_sum_exponential_test.py +0 -1
- cirq/ops/permutation_gate.py +2 -2
- cirq/ops/permutation_gate_test.py +1 -1
- cirq/ops/phased_iswap_gate.py +6 -7
- cirq/ops/phased_iswap_gate_test.py +21 -5
- cirq/ops/phased_x_gate.py +11 -25
- cirq/ops/phased_x_gate_test.py +19 -3
- cirq/ops/phased_x_z_gate.py +12 -11
- cirq/ops/projector.py +4 -5
- cirq/ops/qubit_manager.py +2 -1
- cirq/ops/qubit_manager_test.py +2 -1
- cirq/ops/qubit_order.py +1 -1
- cirq/ops/random_gate_channel.py +1 -1
- cirq/ops/random_gate_channel_test.py +0 -6
- cirq/ops/raw_types.py +146 -50
- cirq/ops/raw_types_test.py +37 -3
- cirq/ops/state_preparation_channel.py +2 -2
- cirq/ops/state_preparation_channel_test.py +2 -1
- cirq/ops/swap_gates.py +9 -4
- cirq/ops/three_qubit_gates.py +8 -8
- cirq/ops/three_qubit_gates_test.py +1 -0
- cirq/ops/two_qubit_diagonal_gate.py +4 -3
- cirq/ops/uniform_superposition_gate.py +4 -4
- cirq/ops/uniform_superposition_gate_test.py +1 -0
- cirq/ops/wait_gate.py +6 -8
- cirq/protocols/__init__.py +135 -83
- cirq/protocols/act_on_protocol.py +1 -1
- cirq/protocols/act_on_protocol_test.py +1 -1
- cirq/protocols/apply_channel_protocol.py +3 -3
- cirq/protocols/apply_mixture_protocol.py +15 -9
- cirq/protocols/apply_mixture_protocol_test.py +11 -0
- cirq/protocols/apply_unitary_protocol.py +2 -2
- cirq/protocols/apply_unitary_protocol_test.py +2 -1
- cirq/protocols/approximate_equality_protocol.py +7 -8
- cirq/protocols/approximate_equality_protocol_test.py +3 -1
- cirq/protocols/circuit_diagram_info_protocol.py +8 -6
- cirq/protocols/circuit_diagram_info_protocol_test.py +5 -0
- cirq/protocols/commutes_protocol.py +6 -6
- cirq/protocols/control_key_protocol.py +1 -1
- cirq/protocols/decompose_protocol.py +4 -5
- cirq/protocols/decompose_protocol_test.py +2 -1
- cirq/protocols/equal_up_to_global_phase_protocol.py +3 -3
- cirq/protocols/equal_up_to_global_phase_protocol_test.py +7 -0
- cirq/protocols/has_stabilizer_effect_protocol.py +5 -5
- cirq/protocols/has_unitary_protocol.py +1 -1
- cirq/protocols/has_unitary_protocol_test.py +8 -7
- cirq/protocols/hash_from_pickle_test.py +120 -0
- cirq/protocols/inverse_protocol.py +1 -1
- cirq/protocols/json_serialization.py +14 -1
- cirq/protocols/json_serialization_test.py +28 -7
- cirq/protocols/json_test_data/BitMaskKeyCondition.json +86 -0
- cirq/protocols/json_test_data/BitMaskKeyCondition.repr +7 -0
- cirq/protocols/json_test_data/Concat.json +19 -0
- cirq/protocols/json_test_data/Concat.repr +1 -0
- cirq/protocols/json_test_data/README.md +4 -2
- cirq/protocols/json_test_data/SympyCondition.json +60 -15
- cirq/protocols/json_test_data/SympyCondition.repr +4 -1
- cirq/protocols/json_test_data/_InverseCompositeGate.json +10 -0
- cirq/protocols/json_test_data/_InverseCompositeGate.repr +1 -0
- cirq/protocols/json_test_data/__init__.py +1 -1
- cirq/protocols/json_test_data/sympy.And.json +13 -0
- cirq/protocols/json_test_data/sympy.And.repr +1 -0
- cirq/protocols/json_test_data/sympy.Indexed.json +18 -0
- cirq/protocols/json_test_data/sympy.Indexed.repr +1 -0
- cirq/protocols/json_test_data/sympy.IndexedBase.json +9 -0
- cirq/protocols/json_test_data/sympy.IndexedBase.repr +1 -0
- cirq/protocols/json_test_data/sympy.Not.json +9 -0
- cirq/protocols/json_test_data/sympy.Not.repr +1 -0
- cirq/protocols/json_test_data/sympy.Or.json +13 -0
- cirq/protocols/json_test_data/sympy.Or.repr +1 -0
- cirq/protocols/json_test_data/sympy.Xor.json +13 -0
- cirq/protocols/json_test_data/sympy.Xor.repr +1 -0
- cirq/protocols/kraus_protocol.py +8 -8
- cirq/protocols/kraus_protocol_test.py +0 -1
- cirq/protocols/measurement_key_protocol.py +1 -1
- cirq/protocols/measurement_key_protocol_test.py +7 -7
- cirq/protocols/mixture_protocol.py +6 -4
- cirq/protocols/mixture_protocol_test.py +21 -13
- cirq/protocols/pauli_expansion_protocol.py +1 -0
- cirq/protocols/pow_protocol.py +1 -1
- cirq/protocols/qasm.py +25 -6
- cirq/protocols/qasm_test.py +17 -0
- cirq/protocols/qid_shape_protocol.py +2 -2
- cirq/protocols/resolve_parameters.py +2 -3
- cirq/protocols/resolve_parameters_test.py +2 -1
- cirq/protocols/trace_distance_bound.py +1 -1
- cirq/protocols/trace_distance_bound_test.py +1 -0
- cirq/protocols/unitary_protocol.py +3 -3
- cirq/protocols/unitary_protocol_test.py +1 -1
- cirq/qis/__init__.py +48 -35
- cirq/qis/channels_test.py +0 -9
- cirq/qis/clifford_tableau.py +46 -26
- cirq/qis/clifford_tableau_test.py +2 -1
- cirq/qis/entropy.py +115 -0
- cirq/qis/entropy_test.py +43 -0
- cirq/qis/measures.py +5 -4
- cirq/qis/measures_test.py +7 -0
- cirq/qis/noise_utils_test.py +4 -4
- cirq/qis/quantum_state_representation.py +1 -1
- cirq/qis/states.py +7 -7
- cirq/sim/__init__.py +55 -37
- cirq/sim/classical_simulator.py +7 -6
- cirq/sim/classical_simulator_test.py +3 -1
- cirq/sim/clifford/__init__.py +17 -9
- cirq/sim/clifford/clifford_simulator.py +5 -4
- cirq/sim/clifford/clifford_simulator_test.py +32 -9
- cirq/sim/clifford/clifford_tableau_simulation_state.py +1 -1
- cirq/sim/clifford/stabilizer_simulation_state.py +1 -1
- cirq/sim/clifford/stabilizer_state_ch_form.py +4 -3
- cirq/sim/density_matrix_simulator.py +3 -2
- cirq/sim/density_matrix_simulator_test.py +12 -4
- cirq/sim/density_matrix_utils.py +1 -1
- cirq/sim/mux.py +2 -2
- cirq/sim/simulation_state.py +4 -5
- cirq/sim/simulation_state_base.py +2 -2
- cirq/sim/simulation_state_test.py +1 -1
- cirq/sim/simulation_utils.py +3 -1
- cirq/sim/simulation_utils_test.py +2 -3
- cirq/sim/simulator.py +7 -6
- cirq/sim/simulator_base.py +5 -5
- cirq/sim/simulator_test.py +14 -3
- cirq/sim/sparse_simulator.py +4 -3
- cirq/sim/sparse_simulator_test.py +17 -9
- cirq/sim/state_vector.py +2 -2
- cirq/sim/state_vector_simulation_state_test.py +1 -1
- cirq/sim/state_vector_simulator.py +4 -4
- cirq/sim/state_vector_test.py +27 -32
- cirq/study/__init__.py +27 -21
- cirq/study/flatten_expressions.py +5 -6
- cirq/study/flatten_expressions_test.py +1 -1
- cirq/study/resolver.py +14 -11
- cirq/study/resolver_test.py +10 -1
- cirq/study/result.py +3 -3
- cirq/study/sweepable.py +15 -9
- cirq/study/sweepable_test.py +27 -0
- cirq/study/sweeps.py +65 -10
- cirq/study/sweeps_test.py +123 -0
- cirq/testing/__init__.py +86 -57
- cirq/testing/_compat_test_data/module_a/__init__.py +2 -2
- cirq/testing/_compat_test_data/module_a/sub/subsub/__init__.py +1 -1
- cirq/testing/circuit_compare.py +3 -4
- cirq/testing/circuit_compare_test.py +7 -8
- cirq/testing/consistent_act_on.py +3 -3
- cirq/testing/consistent_channels_test.py +2 -1
- cirq/testing/consistent_controlled_gate_op.py +3 -2
- cirq/testing/consistent_controlled_gate_op_test.py +2 -3
- cirq/testing/consistent_decomposition.py +1 -1
- cirq/testing/consistent_decomposition_test.py +1 -2
- cirq/testing/consistent_pauli_expansion_test.py +1 -1
- cirq/testing/consistent_phase_by.py +1 -1
- cirq/testing/consistent_phase_by_test.py +1 -2
- cirq/testing/consistent_protocols.py +11 -11
- cirq/testing/consistent_protocols_test.py +4 -5
- cirq/testing/consistent_qasm.py +8 -12
- cirq/testing/consistent_qasm_test.py +1 -1
- cirq/testing/consistent_resolve_parameters.py +2 -1
- cirq/testing/consistent_specified_has_unitary_test.py +1 -1
- cirq/testing/consistent_unitary.py +3 -1
- cirq/testing/consistent_unitary_test.py +3 -3
- cirq/testing/devices.py +1 -1
- cirq/testing/devices_test.py +1 -0
- cirq/testing/equals_tester.py +2 -4
- cirq/testing/equals_tester_test.py +6 -5
- cirq/testing/equivalent_basis_map.py +1 -0
- cirq/testing/equivalent_basis_map_test.py +0 -1
- cirq/testing/gate_features_test.py +5 -0
- cirq/testing/json.py +4 -4
- cirq/testing/lin_alg_utils_test.py +1 -1
- cirq/testing/order_tester.py +1 -1
- cirq/testing/order_tester_test.py +1 -1
- cirq/testing/pytest_utils.py +57 -0
- cirq/testing/pytest_utils_test.py +35 -0
- cirq/testing/random_circuit.py +2 -2
- cirq/testing/random_circuit_test.py +2 -2
- cirq/testing/routing_devices_test.py +2 -1
- cirq/testing/sample_circuits.py +1 -1
- cirq/testing/sample_gates.py +5 -4
- cirq/testing/sample_gates_test.py +2 -2
- cirq/transformers/__init__.py +101 -82
- cirq/transformers/align.py +12 -1
- cirq/transformers/align_test.py +13 -0
- cirq/transformers/analytical_decompositions/__init__.py +27 -24
- cirq/transformers/analytical_decompositions/clifford_decomposition.py +2 -1
- cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +1 -1
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +1 -1
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
- cirq/transformers/analytical_decompositions/cphase_to_fsim.py +1 -1
- cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +1 -1
- cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +2 -2
- cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +4 -4
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +99 -24
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +105 -14
- cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +1 -1
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +1 -1
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +1 -0
- cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +3 -4
- cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +1 -1
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +2 -1
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +5 -6
- cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +1 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +1 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -1
- cirq/transformers/drop_empty_moments.py +1 -0
- cirq/transformers/drop_negligible_operations.py +1 -0
- cirq/transformers/dynamical_decoupling.py +255 -43
- cirq/transformers/dynamical_decoupling_test.py +730 -17
- cirq/transformers/eject_phased_paulis.py +29 -15
- cirq/transformers/eject_phased_paulis_test.py +3 -8
- cirq/transformers/eject_z.py +3 -2
- cirq/transformers/eject_z_test.py +3 -3
- cirq/transformers/gauge_compiling/__init__.py +25 -9
- cirq/transformers/gauge_compiling/cphase_gauge.py +146 -0
- cirq/transformers/gauge_compiling/cphase_gauge_test.py +42 -0
- cirq/transformers/gauge_compiling/cz_gauge.py +4 -4
- cirq/transformers/gauge_compiling/gauge_compiling.py +245 -6
- cirq/transformers/gauge_compiling/gauge_compiling_test.py +107 -2
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +39 -2
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +10 -1
- cirq/transformers/gauge_compiling/iswap_gauge.py +2 -2
- cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -2
- cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +23 -5
- cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +3 -2
- cirq/transformers/heuristic_decompositions/__init__.py +3 -3
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +2 -1
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +1 -1
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +4 -4
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +4 -4
- cirq/transformers/insertion_sort.py +64 -0
- cirq/transformers/insertion_sort_test.py +34 -0
- cirq/transformers/measurement_transformers.py +14 -1
- cirq/transformers/measurement_transformers_test.py +35 -0
- cirq/transformers/merge_k_qubit_gates.py +2 -2
- cirq/transformers/merge_single_qubit_gates.py +1 -1
- cirq/transformers/merge_single_qubit_gates_test.py +1 -1
- cirq/transformers/noise_adding.py +115 -0
- cirq/transformers/noise_adding_test.py +54 -0
- cirq/transformers/optimize_for_target_gateset.py +1 -1
- cirq/transformers/optimize_for_target_gateset_test.py +3 -2
- cirq/transformers/qubit_management_transformers.py +1 -1
- cirq/transformers/randomized_measurements.py +171 -0
- cirq/transformers/randomized_measurements_test.py +68 -0
- cirq/transformers/routing/__init__.py +14 -5
- cirq/transformers/routing/initial_mapper.py +1 -1
- cirq/transformers/routing/initial_mapper_test.py +1 -0
- cirq/transformers/routing/line_initial_mapper.py +3 -2
- cirq/transformers/routing/mapping_manager.py +2 -2
- cirq/transformers/routing/mapping_manager_test.py +2 -2
- cirq/transformers/routing/route_circuit_cqc.py +3 -2
- cirq/transformers/routing/route_circuit_cqc_test.py +2 -1
- cirq/transformers/routing/visualize_routed_circuit.py +1 -0
- cirq/transformers/routing/visualize_routed_circuit_test.py +1 -0
- cirq/transformers/stratify.py +2 -2
- cirq/transformers/synchronize_terminal_measurements.py +2 -1
- cirq/transformers/target_gatesets/__init__.py +7 -5
- cirq/transformers/target_gatesets/compilation_target_gateset.py +16 -3
- cirq/transformers/target_gatesets/compilation_target_gateset_test.py +2 -0
- cirq/transformers/target_gatesets/cz_gateset.py +5 -1
- cirq/transformers/target_gatesets/cz_gateset_test.py +23 -2
- cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +1 -1
- cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +3 -2
- cirq/transformers/transformer_api.py +5 -4
- cirq/transformers/transformer_api_test.py +11 -3
- cirq/transformers/transformer_primitives.py +9 -31
- cirq/transformers/transformer_primitives_test.py +6 -5
- cirq/value/__init__.py +51 -30
- cirq/value/abc_alt.py +1 -2
- cirq/value/angle.py +2 -0
- cirq/value/classical_data.py +1 -0
- cirq/value/condition.py +149 -3
- cirq/value/condition_test.py +254 -0
- cirq/value/digits.py +1 -1
- cirq/value/duration.py +4 -4
- cirq/value/duration_test.py +2 -1
- cirq/value/linear_dict.py +85 -24
- cirq/value/linear_dict_test.py +94 -3
- cirq/value/measurement_key.py +9 -2
- cirq/value/periodic_value.py +2 -3
- cirq/value/periodic_value_test.py +5 -0
- cirq/value/probability.py +1 -0
- cirq/value/random_state.py +1 -1
- cirq/value/timestamp.py +2 -4
- cirq/value/timestamp_test.py +2 -1
- cirq/value/type_alias.py +2 -2
- cirq/value/value_equality_attr.py +14 -2
- cirq/value/value_equality_attr_test.py +1 -1
- cirq/vis/__init__.py +9 -6
- cirq/vis/density_matrix.py +1 -1
- cirq/vis/density_matrix_test.py +2 -5
- cirq/vis/heatmap.py +49 -12
- cirq/vis/heatmap_test.py +168 -4
- cirq/vis/histogram.py +1 -1
- cirq/vis/histogram_test.py +1 -2
- cirq/vis/state_histogram.py +7 -5
- cirq/vis/state_histogram_test.py +2 -2
- cirq/work/__init__.py +19 -13
- cirq/work/collector.py +2 -2
- cirq/work/observable_grouping.py +2 -2
- cirq/work/observable_measurement.py +3 -3
- cirq/work/observable_measurement_data.py +5 -2
- cirq/work/observable_measurement_test.py +8 -8
- cirq/work/observable_readout_calibration.py +2 -2
- cirq/work/observable_readout_calibration_test.py +2 -1
- cirq/work/observable_settings.py +8 -7
- cirq/work/observable_settings_test.py +3 -2
- cirq/work/pauli_sum_collector.py +1 -1
- cirq/work/sampler.py +8 -20
- cirq/work/sampler_test.py +4 -3
- cirq/work/zeros_sampler.py +1 -1
- cirq_core-1.5.0.dist-info/METADATA +125 -0
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/RECORD +586 -552
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/WHEEL +1 -1
- cirq/experiments/grid_parallel_two_qubit_xeb.py +0 -62
- cirq/protocols/json_test_data/GridParallelXEBMetadata.json +0 -119
- cirq/protocols/json_test_data/GridParallelXEBMetadata.repr +0 -1
- cirq_core-1.4.0.dev20240529225110.dist-info/METADATA +0 -50
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/LICENSE +0 -0
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/top_level.txt +0 -0
|
@@ -12,10 +12,12 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
from typing import Dict, Iterable, TYPE_CHECKING
|
|
16
18
|
|
|
17
|
-
from cirq import ops
|
|
18
19
|
import cirq.contrib.acquaintance as cca
|
|
20
|
+
from cirq import ops
|
|
19
21
|
|
|
20
22
|
if TYPE_CHECKING:
|
|
21
23
|
import cirq
|
|
@@ -35,20 +37,18 @@ class SwapNetwork:
|
|
|
35
37
|
initial_mapping: The initial mapping from physical to logical qubits.
|
|
36
38
|
"""
|
|
37
39
|
|
|
38
|
-
def __init__(
|
|
39
|
-
self, circuit: 'cirq.Circuit', initial_mapping: Dict['cirq.Qid', 'cirq.Qid']
|
|
40
|
-
) -> None:
|
|
40
|
+
def __init__(self, circuit: cirq.Circuit, initial_mapping: Dict[cirq.Qid, cirq.Qid]) -> None:
|
|
41
41
|
if not all(isinstance(i, ops.Qid) for I in initial_mapping.items() for i in I):
|
|
42
42
|
raise ValueError('Mapping must be from Qids to Qids.')
|
|
43
43
|
self.circuit = circuit
|
|
44
44
|
self.initial_mapping = initial_mapping
|
|
45
45
|
|
|
46
|
-
def final_mapping(self) -> Dict[
|
|
46
|
+
def final_mapping(self) -> Dict[cirq.Qid, cirq.Qid]:
|
|
47
47
|
mapping = dict(self.initial_mapping)
|
|
48
48
|
cca.update_mapping(mapping, self.circuit.all_operations())
|
|
49
49
|
return mapping
|
|
50
50
|
|
|
51
|
-
def get_logical_operations(self) -> Iterable[
|
|
51
|
+
def get_logical_operations(self) -> Iterable[cirq.Operation]:
|
|
52
52
|
return cca.get_logical_operations(self.circuit.all_operations(), self.initial_mapping)
|
|
53
53
|
|
|
54
54
|
def __eq__(self, other) -> bool:
|
cirq/contrib/routing/utils.py
CHANGED
|
@@ -12,19 +12,21 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import operator
|
|
16
|
-
from typing import Callable, Iterable, List, TYPE_CHECKING
|
|
17
18
|
import re
|
|
19
|
+
from typing import Callable, Iterable, List, TYPE_CHECKING
|
|
18
20
|
|
|
19
21
|
import networkx as nx
|
|
20
22
|
|
|
21
|
-
from cirq import circuits, ops
|
|
22
23
|
import cirq.contrib.acquaintance as cca
|
|
24
|
+
from cirq import circuits, ops
|
|
23
25
|
from cirq.contrib.circuitdag import CircuitDag
|
|
24
|
-
from cirq.contrib.routing.swap_network import SwapNetwork
|
|
25
26
|
|
|
26
27
|
if TYPE_CHECKING:
|
|
27
28
|
import cirq
|
|
29
|
+
from cirq.contrib.routing import SwapNetwork
|
|
28
30
|
|
|
29
31
|
BINARY_OP_PREDICATE = Callable[[ops.Operation, ops.Operation], bool]
|
|
30
32
|
|
|
@@ -86,7 +88,7 @@ def is_valid_routing(
|
|
|
86
88
|
raise
|
|
87
89
|
|
|
88
90
|
|
|
89
|
-
def get_circuit_connectivity(circuit:
|
|
91
|
+
def get_circuit_connectivity(circuit: cirq.Circuit) -> nx.Graph:
|
|
90
92
|
"""Return a graph of all 2q interactions in a circuit.
|
|
91
93
|
|
|
92
94
|
Nodes are qubits and undirected edges correspond to any two-qubit
|
|
@@ -11,9 +11,8 @@
|
|
|
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
|
-
import pytest
|
|
15
|
-
|
|
16
14
|
import networkx as nx
|
|
15
|
+
import pytest
|
|
17
16
|
|
|
18
17
|
import cirq
|
|
19
18
|
import cirq.contrib.routing as ccr
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2025 The Cirq Developers
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -11,13 +11,8 @@
|
|
|
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
|
+
"""Utility for shuffling circuits and do readout error benchmarking."""
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
# At the moment there's no reliable way to say 'NotImplementedType'.
|
|
20
|
-
# - type(NotImplemented) causes mypy to error.
|
|
21
|
-
# - Just NotImplemented causes runtime errors (it's not a type).
|
|
22
|
-
# - The string "NotImplemented" causes runtime errors (in some python versions).
|
|
23
|
-
NotImplementedType = Any
|
|
16
|
+
from cirq.contrib.shuffle_circuits.shuffle_circuits_with_readout_benchmarking import (
|
|
17
|
+
run_shuffled_with_readout_benchmarking as run_shuffled_with_readout_benchmarking,
|
|
18
|
+
)
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# Copyright 2025 The Cirq Developers
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
"""Tools for running circuits in a shuffled order with readout error benchmarking."""
|
|
15
|
+
import time
|
|
16
|
+
from typing import Dict, List, Optional, Tuple, Union
|
|
17
|
+
|
|
18
|
+
import numpy as np
|
|
19
|
+
|
|
20
|
+
from cirq import circuits, ops, protocols, work
|
|
21
|
+
from cirq.experiments import SingleQubitReadoutCalibrationResult
|
|
22
|
+
from cirq.study import ResultDict
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _validate_input(
|
|
26
|
+
input_circuits: list[circuits.Circuit],
|
|
27
|
+
circuit_repetitions: Union[int, list[int]],
|
|
28
|
+
rng_or_seed: Union[np.random.Generator, int],
|
|
29
|
+
num_random_bitstrings: int,
|
|
30
|
+
readout_repetitions: int,
|
|
31
|
+
):
|
|
32
|
+
if not input_circuits:
|
|
33
|
+
raise ValueError("Input circuits must not be empty.")
|
|
34
|
+
# Check input_circuits type is cirq.circuits
|
|
35
|
+
if not all(isinstance(circuit, circuits.Circuit) for circuit in input_circuits):
|
|
36
|
+
raise ValueError("Input circuits must be of type cirq.Circuit.")
|
|
37
|
+
# Check input_circuits have measurements
|
|
38
|
+
for circuit in input_circuits:
|
|
39
|
+
if not any(protocols.is_measurement(circuit) for op in circuit.all_operations()):
|
|
40
|
+
raise ValueError("Input circuits must have measurements.")
|
|
41
|
+
|
|
42
|
+
# Check circuit_repetitions
|
|
43
|
+
if isinstance(circuit_repetitions, int):
|
|
44
|
+
if circuit_repetitions <= 0:
|
|
45
|
+
raise ValueError("Must provide non-zero circuit_repetitions.")
|
|
46
|
+
if isinstance(circuit_repetitions, list) and len(circuit_repetitions) != len(input_circuits):
|
|
47
|
+
raise ValueError("Number of circuit_repetitions must match the number of input circuits.")
|
|
48
|
+
|
|
49
|
+
# Check rng is a numpy random generator
|
|
50
|
+
if not isinstance(rng_or_seed, np.random.Generator) and not isinstance(rng_or_seed, int):
|
|
51
|
+
raise ValueError("Must provide a numpy random generator or a seed")
|
|
52
|
+
|
|
53
|
+
# Check num_random_bitstrings is bigger than or equal to 0
|
|
54
|
+
if num_random_bitstrings < 0:
|
|
55
|
+
raise ValueError("Must provide zero or more num_random_bitstrings.")
|
|
56
|
+
|
|
57
|
+
# Check readout_repetitions is bigger than 0
|
|
58
|
+
if readout_repetitions <= 0:
|
|
59
|
+
raise ValueError("Must provide non-zero readout_repetitions for readout calibration.")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _generate_readout_calibration_circuits(
|
|
63
|
+
qubits: list[ops.Qid], rng: np.random.Generator, num_random_bitstrings: int
|
|
64
|
+
) -> tuple[list[circuits.Circuit], np.ndarray]:
|
|
65
|
+
"""Generates the readout calibration circuits with random bitstrings."""
|
|
66
|
+
bit_to_gate = (ops.I, ops.X)
|
|
67
|
+
|
|
68
|
+
random_bitstrings = rng.integers(0, 2, size=(num_random_bitstrings, len(qubits)))
|
|
69
|
+
|
|
70
|
+
readout_calibration_circuits = []
|
|
71
|
+
for bitstr in random_bitstrings:
|
|
72
|
+
readout_calibration_circuits.append(
|
|
73
|
+
circuits.Circuit(
|
|
74
|
+
[bit_to_gate[bit](qubit) for bit, qubit in zip(bitstr, qubits)]
|
|
75
|
+
+ [ops.M(qubits, key="m")]
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
return readout_calibration_circuits, random_bitstrings
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _shuffle_circuits(
|
|
82
|
+
all_circuits: list[circuits.Circuit], all_repetitions: list[int], rng: np.random.Generator
|
|
83
|
+
) -> tuple[list[circuits.Circuit], list[int], np.ndarray]:
|
|
84
|
+
"""Shuffles the input circuits and readout calibration circuits."""
|
|
85
|
+
shuf_order = rng.permutation(len(all_circuits))
|
|
86
|
+
unshuf_order = np.zeros_like(shuf_order) # Inverse permutation
|
|
87
|
+
unshuf_order[shuf_order] = np.arange(len(all_circuits))
|
|
88
|
+
shuffled_circuits = [all_circuits[i] for i in shuf_order]
|
|
89
|
+
all_repetitions = [all_repetitions[i] for i in shuf_order]
|
|
90
|
+
return shuffled_circuits, all_repetitions, unshuf_order
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _analyze_readout_results(
|
|
94
|
+
unshuffled_readout_measurements: list[ResultDict],
|
|
95
|
+
random_bitstrings: np.ndarray,
|
|
96
|
+
readout_repetitions: int,
|
|
97
|
+
qubits: list[ops.Qid],
|
|
98
|
+
timestamp: float,
|
|
99
|
+
) -> SingleQubitReadoutCalibrationResult:
|
|
100
|
+
"""Analyzes the readout error rates from the unshuffled measurements.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
readout_measurements: A list of dictionaries containing the measurement results
|
|
104
|
+
for each readout calibration circuit.
|
|
105
|
+
random_bitstrings: A numpy array of random bitstrings used for measuring readout.
|
|
106
|
+
readout_repetitions: The number of repetitions for each readout bitstring.
|
|
107
|
+
qubits: The list of qubits for which the readout error rates are to be calculated.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
A dictionary mapping each qubit to a tuple of readout error rates(e0 and e1),
|
|
111
|
+
where e0 is the 0->1 readout error rate and e1 is the 1->0 readout error rate.
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
zero_state_trials = np.zeros((1, len(qubits)), dtype=np.int64)
|
|
115
|
+
one_state_trials = np.zeros((1, len(qubits)), dtype=np.int64)
|
|
116
|
+
zero_state_totals = np.zeros((1, len(qubits)), dtype=np.int64)
|
|
117
|
+
one_state_totals = np.zeros((1, len(qubits)), dtype=np.int64)
|
|
118
|
+
for measurement_result, bitstr in zip(unshuffled_readout_measurements, random_bitstrings):
|
|
119
|
+
for _, trial_result in measurement_result.measurements.items():
|
|
120
|
+
trial_result = trial_result.astype(np.int64) # Cast to int64
|
|
121
|
+
sample_counts = np.sum(trial_result, axis=0)
|
|
122
|
+
|
|
123
|
+
zero_state_trials += sample_counts * (1 - bitstr)
|
|
124
|
+
zero_state_totals += readout_repetitions * (1 - bitstr)
|
|
125
|
+
one_state_trials += (readout_repetitions - sample_counts) * bitstr
|
|
126
|
+
one_state_totals += readout_repetitions * bitstr
|
|
127
|
+
|
|
128
|
+
zero_state_errors = {
|
|
129
|
+
q: (
|
|
130
|
+
zero_state_trials[0][qubit_idx] / zero_state_totals[0][qubit_idx]
|
|
131
|
+
if zero_state_totals[0][qubit_idx] > 0
|
|
132
|
+
else np.nan
|
|
133
|
+
)
|
|
134
|
+
for qubit_idx, q in enumerate(qubits)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
one_state_errors = {
|
|
138
|
+
q: (
|
|
139
|
+
one_state_trials[0][qubit_idx] / one_state_totals[0][qubit_idx]
|
|
140
|
+
if one_state_totals[0][qubit_idx] > 0
|
|
141
|
+
else np.nan
|
|
142
|
+
)
|
|
143
|
+
for qubit_idx, q in enumerate(qubits)
|
|
144
|
+
}
|
|
145
|
+
return SingleQubitReadoutCalibrationResult(
|
|
146
|
+
zero_state_errors=zero_state_errors,
|
|
147
|
+
one_state_errors=one_state_errors,
|
|
148
|
+
repetitions=readout_repetitions,
|
|
149
|
+
timestamp=timestamp,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def run_shuffled_with_readout_benchmarking(
|
|
154
|
+
input_circuits: list[circuits.Circuit],
|
|
155
|
+
sampler: work.Sampler,
|
|
156
|
+
circuit_repetitions: Union[int, list[int]],
|
|
157
|
+
rng_or_seed: Union[np.random.Generator, int],
|
|
158
|
+
num_random_bitstrings: int = 100,
|
|
159
|
+
readout_repetitions: int = 1000,
|
|
160
|
+
qubits: Optional[Union[List[ops.Qid], List[List[ops.Qid]]]] = None,
|
|
161
|
+
) -> tuple[list[ResultDict], Dict[Tuple[ops.Qid, ...], SingleQubitReadoutCalibrationResult]]:
|
|
162
|
+
"""Run the circuits in a shuffled order with readout error benchmarking.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
input_circuits: The circuits to run.
|
|
166
|
+
sampler: The sampler to use.
|
|
167
|
+
circuit_repetitions: The repetitions for `circuits`.
|
|
168
|
+
rng_or_seed: A random number generator used to generate readout circuits.
|
|
169
|
+
Or an integer seed.
|
|
170
|
+
num_random_bitstrings: The number of random bitstrings for measuring readout.
|
|
171
|
+
If set to 0, no readout calibration circuits are generated.
|
|
172
|
+
readout_repetitions: The number of repetitions for each readout bitstring.
|
|
173
|
+
qubits: The qubits to benchmark readout errors. If None, all qubits in the
|
|
174
|
+
input_circuits are used. Can be a list of qubits or a list of tuples
|
|
175
|
+
of qubits.
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
A tuple containing:
|
|
179
|
+
- A list of dictionaries with the unshuffled measurement results.
|
|
180
|
+
- A dictionary mapping each tuple of qubits to a SingleQubitReadoutCalibrationResult.
|
|
181
|
+
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
_validate_input(
|
|
185
|
+
input_circuits, circuit_repetitions, rng_or_seed, num_random_bitstrings, readout_repetitions
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
# If input qubits is None, extract qubits from input circuits
|
|
189
|
+
qubits_to_measure: List[List[ops.Qid]] = []
|
|
190
|
+
if qubits is None:
|
|
191
|
+
qubits_set: set[ops.Qid] = set()
|
|
192
|
+
for circuit in input_circuits:
|
|
193
|
+
qubits_set.update(circuit.all_qubits())
|
|
194
|
+
qubits_to_measure = [sorted(qubits_set)]
|
|
195
|
+
elif isinstance(qubits[0], ops.Qid):
|
|
196
|
+
qubits_to_measure = [qubits] # type: ignore
|
|
197
|
+
else:
|
|
198
|
+
qubits_to_measure = qubits # type: ignore
|
|
199
|
+
|
|
200
|
+
# Generate the readout calibration circuits if num_random_bitstrings>0
|
|
201
|
+
# Else all_readout_calibration_circuits and all_random_bitstrings are empty
|
|
202
|
+
all_readout_calibration_circuits = []
|
|
203
|
+
all_random_bitstrings = []
|
|
204
|
+
|
|
205
|
+
rng = (
|
|
206
|
+
rng_or_seed
|
|
207
|
+
if isinstance(rng_or_seed, np.random.Generator)
|
|
208
|
+
else np.random.default_rng(rng_or_seed)
|
|
209
|
+
)
|
|
210
|
+
if num_random_bitstrings > 0:
|
|
211
|
+
for qubit_group in qubits_to_measure:
|
|
212
|
+
readout_calibration_circuits, random_bitstrings = (
|
|
213
|
+
_generate_readout_calibration_circuits(qubit_group, rng, num_random_bitstrings)
|
|
214
|
+
)
|
|
215
|
+
all_readout_calibration_circuits.extend(readout_calibration_circuits)
|
|
216
|
+
all_random_bitstrings.append(random_bitstrings)
|
|
217
|
+
|
|
218
|
+
# Shuffle the circuits
|
|
219
|
+
if isinstance(circuit_repetitions, int):
|
|
220
|
+
circuit_repetitions = [circuit_repetitions] * len(input_circuits)
|
|
221
|
+
all_repetitions = circuit_repetitions + [readout_repetitions] * len(
|
|
222
|
+
all_readout_calibration_circuits
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
shuffled_circuits, all_repetitions, unshuf_order = _shuffle_circuits(
|
|
226
|
+
input_circuits + all_readout_calibration_circuits, all_repetitions, rng
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
# Run the shuffled circuits and measure
|
|
230
|
+
results = sampler.run_batch(shuffled_circuits, repetitions=all_repetitions)
|
|
231
|
+
timestamp = time.time()
|
|
232
|
+
shuffled_measurements = [res[0] for res in results]
|
|
233
|
+
unshuffled_measurements = [shuffled_measurements[i] for i in unshuf_order]
|
|
234
|
+
|
|
235
|
+
unshuffled_input_circuits_measiurements = unshuffled_measurements[: len(input_circuits)]
|
|
236
|
+
unshuffled_readout_measurements = unshuffled_measurements[len(input_circuits) :]
|
|
237
|
+
|
|
238
|
+
# Analyze results
|
|
239
|
+
readout_calibration_results = {}
|
|
240
|
+
start_idx = 0
|
|
241
|
+
for qubit_group, random_bitstrings in zip(qubits_to_measure, all_random_bitstrings):
|
|
242
|
+
end_idx = start_idx + len(random_bitstrings)
|
|
243
|
+
group_measurements = unshuffled_readout_measurements[start_idx:end_idx]
|
|
244
|
+
calibration_result = _analyze_readout_results(
|
|
245
|
+
group_measurements, random_bitstrings, readout_repetitions, qubit_group, timestamp
|
|
246
|
+
)
|
|
247
|
+
readout_calibration_results[tuple(qubit_group)] = calibration_result
|
|
248
|
+
start_idx = end_idx
|
|
249
|
+
|
|
250
|
+
return unshuffled_input_circuits_measiurements, readout_calibration_results
|