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
|
@@ -12,13 +12,15 @@
|
|
|
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 abc
|
|
16
18
|
import dataclasses
|
|
17
19
|
import itertools
|
|
18
20
|
import os
|
|
19
21
|
import tempfile
|
|
20
22
|
import warnings
|
|
21
|
-
from typing import Any,
|
|
23
|
+
from typing import Any, Iterable, Mapping, Sequence, TYPE_CHECKING
|
|
22
24
|
|
|
23
25
|
import numpy as np
|
|
24
26
|
import pandas as pd
|
|
@@ -50,8 +52,8 @@ document(
|
|
|
50
52
|
|
|
51
53
|
|
|
52
54
|
def _with_parameterized_layers(
|
|
53
|
-
circuit:
|
|
54
|
-
) ->
|
|
55
|
+
circuit: cirq.AbstractCircuit, qubits: Sequence[cirq.Qid], needs_init_layer: bool
|
|
56
|
+
) -> cirq.Circuit:
|
|
55
57
|
"""Return a copy of the input circuit with parameterized single-qubit rotations.
|
|
56
58
|
|
|
57
59
|
These rotations flank the circuit: the initial two layers of X and Y gates
|
|
@@ -136,7 +138,7 @@ class RepetitionsStoppingCriteria(StoppingCriteria):
|
|
|
136
138
|
return protocols.dataclass_json_dict(self)
|
|
137
139
|
|
|
138
140
|
|
|
139
|
-
_OBS_TO_PARAM_VAL:
|
|
141
|
+
_OBS_TO_PARAM_VAL: dict[tuple[cirq.Pauli, bool], tuple[float, float]] = {
|
|
140
142
|
(ops.X, False): (0, -1 / 2),
|
|
141
143
|
(ops.X, True): (0, +1 / 2),
|
|
142
144
|
(ops.Y, False): (1 / 2, 0),
|
|
@@ -148,7 +150,7 @@ _OBS_TO_PARAM_VAL: Dict[Tuple['cirq.Pauli', bool], Tuple[float, float]] = {
|
|
|
148
150
|
second element in the key is whether to measure in the positive or negative (flipped) basis
|
|
149
151
|
for readout symmetrization."""
|
|
150
152
|
|
|
151
|
-
_STATE_TO_PARAM_VAL:
|
|
153
|
+
_STATE_TO_PARAM_VAL: dict[_NamedOneQubitState, tuple[float, float]] = {
|
|
152
154
|
value.KET_PLUS: (0, +1 / 2),
|
|
153
155
|
value.KET_MINUS: (0, -1 / 2),
|
|
154
156
|
value.KET_IMAG: (-1 / 2, 0),
|
|
@@ -162,9 +164,9 @@ _STATE_TO_PARAM_VAL: Dict['_NamedOneQubitState', Tuple[float, float]] = {
|
|
|
162
164
|
def _get_params_for_setting(
|
|
163
165
|
setting: InitObsSetting,
|
|
164
166
|
flips: Iterable[bool],
|
|
165
|
-
qubits: Sequence[
|
|
167
|
+
qubits: Sequence[cirq.Qid],
|
|
166
168
|
needs_init_layer: bool,
|
|
167
|
-
) ->
|
|
169
|
+
) -> dict[str, float]:
|
|
168
170
|
"""Return the parameter dictionary for the given setting.
|
|
169
171
|
|
|
170
172
|
This must be used in conjunction with a circuit generated by
|
|
@@ -204,9 +206,9 @@ def _get_params_for_setting(
|
|
|
204
206
|
|
|
205
207
|
def _pad_setting(
|
|
206
208
|
max_setting: InitObsSetting,
|
|
207
|
-
qubits: Sequence[
|
|
209
|
+
qubits: Sequence[cirq.Qid],
|
|
208
210
|
pad_init_state_with=value.KET_ZERO,
|
|
209
|
-
pad_obs_with:
|
|
211
|
+
pad_obs_with: cirq.Gate = ops.Z,
|
|
210
212
|
) -> InitObsSetting:
|
|
211
213
|
"""Pad `max_setting`'s `init_state` and `observable` with `pad_xx_with` operations
|
|
212
214
|
(defaults: |0> and Z) so each max_setting has the same qubits. We need this
|
|
@@ -227,7 +229,7 @@ def _pad_setting(
|
|
|
227
229
|
return InitObsSetting(init_state=init_state, observable=obs)
|
|
228
230
|
|
|
229
231
|
|
|
230
|
-
def _aggregate_n_repetitions(next_chunk_repetitions:
|
|
232
|
+
def _aggregate_n_repetitions(next_chunk_repetitions: set[int]) -> int:
|
|
231
233
|
"""A stopping criteria can request a different number of more_repetitions for each
|
|
232
234
|
measurement spec. For batching efficiency, we take the max and issue a warning in this case."""
|
|
233
235
|
if len(next_chunk_repetitions) == 1:
|
|
@@ -243,10 +245,10 @@ def _aggregate_n_repetitions(next_chunk_repetitions: Set[int]) -> int:
|
|
|
243
245
|
|
|
244
246
|
|
|
245
247
|
def _check_meas_specs_still_todo(
|
|
246
|
-
meas_specs:
|
|
247
|
-
accumulators:
|
|
248
|
+
meas_specs: list[_MeasurementSpec],
|
|
249
|
+
accumulators: Mapping[_MeasurementSpec, BitstringAccumulator],
|
|
248
250
|
stopping_criteria: StoppingCriteria,
|
|
249
|
-
) ->
|
|
251
|
+
) -> tuple[list[_MeasurementSpec], int]:
|
|
250
252
|
"""Filter `meas_specs` in case some are done.
|
|
251
253
|
|
|
252
254
|
In the sampling loop in `measure_grouped_settings`, we submit
|
|
@@ -254,7 +256,7 @@ def _check_meas_specs_still_todo(
|
|
|
254
256
|
removing `meas_spec`s from the loop if they are done.
|
|
255
257
|
"""
|
|
256
258
|
still_todo = []
|
|
257
|
-
repetitions_set:
|
|
259
|
+
repetitions_set: set[int] = set()
|
|
258
260
|
for meas_spec in meas_specs:
|
|
259
261
|
accumulator = accumulators[meas_spec]
|
|
260
262
|
more_repetitions = stopping_criteria.more_repetitions(accumulator)
|
|
@@ -303,7 +305,7 @@ class _FlippyMeasSpec:
|
|
|
303
305
|
|
|
304
306
|
meas_spec: _MeasurementSpec
|
|
305
307
|
flips: np.ndarray
|
|
306
|
-
qubits: Sequence[
|
|
308
|
+
qubits: Sequence[cirq.Qid]
|
|
307
309
|
|
|
308
310
|
def param_tuples(self, *, needs_init_layer=True):
|
|
309
311
|
yield from _get_params_for_setting(
|
|
@@ -318,9 +320,9 @@ class _FlippyMeasSpec:
|
|
|
318
320
|
def _subdivide_meas_specs(
|
|
319
321
|
meas_specs: Iterable[_MeasurementSpec],
|
|
320
322
|
repetitions: int,
|
|
321
|
-
qubits: Sequence[
|
|
323
|
+
qubits: Sequence[cirq.Qid],
|
|
322
324
|
readout_symmetrization: bool,
|
|
323
|
-
) ->
|
|
325
|
+
) -> tuple[list[_FlippyMeasSpec], int]:
|
|
324
326
|
"""Split measurement specs into sub-jobs for readout symmetrization
|
|
325
327
|
|
|
326
328
|
In readout symmetrization, we first run the "normal" circuit followed
|
|
@@ -354,8 +356,8 @@ def _to_sweep(param_tuples):
|
|
|
354
356
|
|
|
355
357
|
|
|
356
358
|
def _parse_checkpoint_options(
|
|
357
|
-
checkpoint: bool, checkpoint_fn:
|
|
358
|
-
) ->
|
|
359
|
+
checkpoint: bool, checkpoint_fn: str | None, checkpoint_other_fn: str | None
|
|
360
|
+
) -> tuple[str | None, str | None]:
|
|
359
361
|
"""Parse the checkpoint-oriented options in `measure_grouped_settings`.
|
|
360
362
|
|
|
361
363
|
This function contains the validation and defaults logic. Please see
|
|
@@ -433,8 +435,8 @@ class CheckpointFileOptions:
|
|
|
433
435
|
"""
|
|
434
436
|
|
|
435
437
|
checkpoint: bool = False
|
|
436
|
-
checkpoint_fn:
|
|
437
|
-
checkpoint_other_fn:
|
|
438
|
+
checkpoint_fn: str | None = None
|
|
439
|
+
checkpoint_other_fn: str | None = None
|
|
438
440
|
|
|
439
441
|
def __post_init__(self):
|
|
440
442
|
fn, other_fn = _parse_checkpoint_options(
|
|
@@ -458,7 +460,7 @@ class CheckpointFileOptions:
|
|
|
458
460
|
protocols.to_json(obj, self.checkpoint_fn)
|
|
459
461
|
|
|
460
462
|
|
|
461
|
-
def _needs_init_layer(grouped_settings:
|
|
463
|
+
def _needs_init_layer(grouped_settings: dict[InitObsSetting, list[InitObsSetting]]) -> bool:
|
|
462
464
|
"""Helper function to go through init_states and determine if any of them need an
|
|
463
465
|
initialization layer of single-qubit gates."""
|
|
464
466
|
for max_setting in grouped_settings.keys():
|
|
@@ -468,16 +470,16 @@ def _needs_init_layer(grouped_settings: Dict[InitObsSetting, List[InitObsSetting
|
|
|
468
470
|
|
|
469
471
|
|
|
470
472
|
def measure_grouped_settings(
|
|
471
|
-
circuit:
|
|
472
|
-
grouped_settings:
|
|
473
|
-
sampler:
|
|
473
|
+
circuit: cirq.AbstractCircuit,
|
|
474
|
+
grouped_settings: dict[InitObsSetting, list[InitObsSetting]],
|
|
475
|
+
sampler: cirq.Sampler,
|
|
474
476
|
stopping_criteria: StoppingCriteria,
|
|
475
477
|
*,
|
|
476
478
|
readout_symmetrization: bool = False,
|
|
477
|
-
circuit_sweep:
|
|
478
|
-
readout_calibrations:
|
|
479
|
+
circuit_sweep: cirq.Sweepable = None,
|
|
480
|
+
readout_calibrations: BitstringAccumulator | None = None,
|
|
479
481
|
checkpoint: CheckpointFileOptions = CheckpointFileOptions(),
|
|
480
|
-
) ->
|
|
482
|
+
) -> list[BitstringAccumulator]:
|
|
481
483
|
"""Measure a suite of grouped InitObsSetting settings.
|
|
482
484
|
|
|
483
485
|
This is a low-level API for accessing the observable measurement
|
|
@@ -582,10 +584,10 @@ def measure_grouped_settings(
|
|
|
582
584
|
return list(accumulators.values())
|
|
583
585
|
|
|
584
586
|
|
|
585
|
-
_GROUPING_FUNCS:
|
|
587
|
+
_GROUPING_FUNCS: dict[str, GROUPER_T] = {'greedy': group_settings_greedy}
|
|
586
588
|
|
|
587
589
|
|
|
588
|
-
def _parse_grouper(grouper:
|
|
590
|
+
def _parse_grouper(grouper: str | GROUPER_T = group_settings_greedy) -> GROUPER_T:
|
|
589
591
|
"""Logic for turning a named grouper into one of the build-in groupers in support of the
|
|
590
592
|
high-level `measure_observables` API."""
|
|
591
593
|
if isinstance(grouper, str):
|
|
@@ -597,8 +599,8 @@ def _parse_grouper(grouper: Union[str, GROUPER_T] = group_settings_greedy) -> GR
|
|
|
597
599
|
|
|
598
600
|
|
|
599
601
|
def _get_all_qubits(
|
|
600
|
-
circuit:
|
|
601
|
-
) ->
|
|
602
|
+
circuit: cirq.AbstractCircuit, observables: Iterable[cirq.PauliString]
|
|
603
|
+
) -> list[cirq.Qid]:
|
|
602
604
|
"""Helper function for `measure_observables` to get all qubits from a circuit and a
|
|
603
605
|
collection of observables."""
|
|
604
606
|
qubit_set = set()
|
|
@@ -609,17 +611,17 @@ def _get_all_qubits(
|
|
|
609
611
|
|
|
610
612
|
|
|
611
613
|
def measure_observables(
|
|
612
|
-
circuit:
|
|
613
|
-
observables: Iterable[
|
|
614
|
-
sampler:
|
|
614
|
+
circuit: cirq.AbstractCircuit,
|
|
615
|
+
observables: Iterable[cirq.PauliString],
|
|
616
|
+
sampler: cirq.Simulator | cirq.Sampler,
|
|
615
617
|
stopping_criteria: StoppingCriteria,
|
|
616
618
|
*,
|
|
617
619
|
readout_symmetrization: bool = False,
|
|
618
|
-
circuit_sweep:
|
|
619
|
-
grouper:
|
|
620
|
-
readout_calibrations:
|
|
620
|
+
circuit_sweep: cirq.Sweepable | None = None,
|
|
621
|
+
grouper: str | GROUPER_T = group_settings_greedy,
|
|
622
|
+
readout_calibrations: BitstringAccumulator | None = None,
|
|
621
623
|
checkpoint: CheckpointFileOptions = CheckpointFileOptions(),
|
|
622
|
-
) ->
|
|
624
|
+
) -> list[ObservableMeasuredResult]:
|
|
623
625
|
"""Measure a collection of PauliString observables for a state prepared by a Circuit.
|
|
624
626
|
|
|
625
627
|
If you need more control over the process, please see `measure_grouped_settings` for a
|
|
@@ -671,15 +673,15 @@ def measure_observables(
|
|
|
671
673
|
|
|
672
674
|
|
|
673
675
|
def measure_observables_df(
|
|
674
|
-
circuit:
|
|
675
|
-
observables: Iterable[
|
|
676
|
-
sampler:
|
|
676
|
+
circuit: cirq.AbstractCircuit,
|
|
677
|
+
observables: Iterable[cirq.PauliString],
|
|
678
|
+
sampler: cirq.Simulator | cirq.Sampler,
|
|
677
679
|
stopping_criteria: StoppingCriteria,
|
|
678
680
|
*,
|
|
679
681
|
readout_symmetrization: bool = False,
|
|
680
|
-
circuit_sweep:
|
|
681
|
-
grouper:
|
|
682
|
-
readout_calibrations:
|
|
682
|
+
circuit_sweep: cirq.Sweepable | None = None,
|
|
683
|
+
grouper: str | GROUPER_T = group_settings_greedy,
|
|
684
|
+
readout_calibrations: BitstringAccumulator | None = None,
|
|
683
685
|
checkpoint: CheckpointFileOptions = CheckpointFileOptions(),
|
|
684
686
|
):
|
|
685
687
|
"""Measure observables and return resulting data as a Pandas dataframe.
|
|
@@ -12,9 +12,11 @@
|
|
|
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 dataclasses
|
|
16
18
|
import datetime
|
|
17
|
-
from typing import Any,
|
|
19
|
+
from typing import Any, Iterable, Mapping, TYPE_CHECKING
|
|
18
20
|
|
|
19
21
|
import numpy as np
|
|
20
22
|
import sympy
|
|
@@ -33,7 +35,7 @@ if TYPE_CHECKING:
|
|
|
33
35
|
import cirq
|
|
34
36
|
|
|
35
37
|
|
|
36
|
-
def _check_and_get_real_coef(observable:
|
|
38
|
+
def _check_and_get_real_coef(observable: cirq.PauliString, atol: float):
|
|
37
39
|
"""Assert that a PauliString has a real coefficient and return it."""
|
|
38
40
|
coef = observable.coefficient
|
|
39
41
|
if isinstance(coef, sympy.Expr) or not np.isclose(coef.imag, 0, atol=atol):
|
|
@@ -43,8 +45,8 @@ def _check_and_get_real_coef(observable: 'cirq.PauliString', atol: float):
|
|
|
43
45
|
|
|
44
46
|
def _obs_vals_from_measurements(
|
|
45
47
|
bitstrings: np.ndarray,
|
|
46
|
-
qubit_to_index:
|
|
47
|
-
observable:
|
|
48
|
+
qubit_to_index: Mapping[cirq.Qid, int],
|
|
49
|
+
observable: cirq.PauliString,
|
|
48
50
|
atol: float,
|
|
49
51
|
):
|
|
50
52
|
"""Multiply together bitstrings to get observed values of operators."""
|
|
@@ -61,10 +63,10 @@ def _obs_vals_from_measurements(
|
|
|
61
63
|
|
|
62
64
|
def _stats_from_measurements(
|
|
63
65
|
bitstrings: np.ndarray,
|
|
64
|
-
qubit_to_index:
|
|
65
|
-
observable:
|
|
66
|
+
qubit_to_index: Mapping[cirq.Qid, int],
|
|
67
|
+
observable: cirq.PauliString,
|
|
66
68
|
atol: float,
|
|
67
|
-
) ->
|
|
69
|
+
) -> tuple[float, float]:
|
|
68
70
|
"""Return the mean and squared standard error of the mean for the given
|
|
69
71
|
observable according to the measurements in `bitstrings`."""
|
|
70
72
|
obs_vals = _obs_vals_from_measurements(bitstrings, qubit_to_index, observable, atol=atol)
|
|
@@ -107,7 +109,7 @@ class ObservableMeasuredResult:
|
|
|
107
109
|
mean: float
|
|
108
110
|
variance: float
|
|
109
111
|
repetitions: int
|
|
110
|
-
circuit_params: Mapping[
|
|
112
|
+
circuit_params: Mapping[str | sympy.Expr, value.Scalar | sympy.Expr]
|
|
111
113
|
|
|
112
114
|
# unhashable because of the mapping-type circuit_params attribute
|
|
113
115
|
__hash__ = None # type: ignore
|
|
@@ -136,7 +138,7 @@ class ObservableMeasuredResult:
|
|
|
136
138
|
def stddev(self):
|
|
137
139
|
return np.sqrt(self.variance)
|
|
138
140
|
|
|
139
|
-
def as_dict(self) ->
|
|
141
|
+
def as_dict(self) -> dict[str, Any]:
|
|
140
142
|
"""Return the contents of this class as a dictionary.
|
|
141
143
|
|
|
142
144
|
This makes records suitable for construction of a Pandas dataframe. The circuit parameters
|
|
@@ -213,29 +215,32 @@ class BitstringAccumulator:
|
|
|
213
215
|
def __init__(
|
|
214
216
|
self,
|
|
215
217
|
meas_spec: _MeasurementSpec,
|
|
216
|
-
simul_settings:
|
|
217
|
-
qubit_to_index:
|
|
218
|
-
bitstrings:
|
|
219
|
-
chunksizes:
|
|
220
|
-
timestamps:
|
|
221
|
-
readout_calibration:
|
|
218
|
+
simul_settings: list[InitObsSetting],
|
|
219
|
+
qubit_to_index: Mapping[cirq.Qid, int],
|
|
220
|
+
bitstrings: np.ndarray | None = None,
|
|
221
|
+
chunksizes: np.ndarray | None = None,
|
|
222
|
+
timestamps: np.ndarray | None = None,
|
|
223
|
+
readout_calibration: BitstringAccumulator | None = None,
|
|
222
224
|
):
|
|
223
225
|
self._meas_spec = meas_spec
|
|
224
226
|
self._simul_settings = simul_settings
|
|
225
227
|
self._qubit_to_index = qubit_to_index
|
|
226
228
|
self._readout_calibration = readout_calibration
|
|
227
229
|
|
|
230
|
+
self.bitstrings: np.ndarray[tuple[int, ...], np.dtype[np.uint8]]
|
|
228
231
|
if bitstrings is None:
|
|
229
232
|
n_bits = len(qubit_to_index)
|
|
230
233
|
self.bitstrings = np.zeros((0, n_bits), dtype=np.uint8)
|
|
231
234
|
else:
|
|
232
235
|
self.bitstrings = np.asarray(bitstrings, dtype=np.uint8)
|
|
233
236
|
|
|
237
|
+
self.chunksizes: np.ndarray[tuple[int, ...], np.dtype[np.int64]]
|
|
234
238
|
if chunksizes is None:
|
|
235
239
|
self.chunksizes = np.zeros((0,), dtype=np.int64)
|
|
236
240
|
else:
|
|
237
241
|
self.chunksizes = np.asarray(chunksizes, dtype=np.int64)
|
|
238
242
|
|
|
243
|
+
self.timestamps: np.ndarray[tuple[int, ...], np.dtype[np.datetime64]]
|
|
239
244
|
if timestamps is None:
|
|
240
245
|
self.timestamps = np.zeros((0,), dtype='datetime64[us]')
|
|
241
246
|
else:
|
|
@@ -523,8 +528,8 @@ class BitstringAccumulator:
|
|
|
523
528
|
|
|
524
529
|
|
|
525
530
|
def flatten_grouped_results(
|
|
526
|
-
grouped_results:
|
|
527
|
-
) ->
|
|
531
|
+
grouped_results: list[BitstringAccumulator],
|
|
532
|
+
) -> list[ObservableMeasuredResult]:
|
|
528
533
|
"""Flatten a collection of BitstringAccumulators into a list of ObservableMeasuredResult.
|
|
529
534
|
|
|
530
535
|
Raw results are contained in BitstringAccumulator which contains
|
|
@@ -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
|
import dataclasses
|
|
15
18
|
import datetime
|
|
16
19
|
import time
|
|
@@ -113,7 +116,7 @@ def test_observable_measured_result():
|
|
|
113
116
|
|
|
114
117
|
|
|
115
118
|
@pytest.fixture
|
|
116
|
-
def example_bsa() ->
|
|
119
|
+
def example_bsa() -> cw.BitstringAccumulator:
|
|
117
120
|
"""Test fixture to create an (empty) example BitstringAccumulator"""
|
|
118
121
|
q0, q1 = cirq.LineQubit.range(2)
|
|
119
122
|
setting = cw.InitObsSetting(
|
|
@@ -11,11 +11,15 @@
|
|
|
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 tempfile
|
|
15
|
-
from typing import
|
|
18
|
+
from typing import Iterable
|
|
16
19
|
|
|
17
20
|
import numpy as np
|
|
18
21
|
import pytest
|
|
22
|
+
import sympy
|
|
19
23
|
|
|
20
24
|
import cirq
|
|
21
25
|
import cirq.work as cw
|
|
@@ -37,7 +41,7 @@ from cirq.work.observable_measurement import (
|
|
|
37
41
|
)
|
|
38
42
|
|
|
39
43
|
|
|
40
|
-
def test_with_parameterized_layers():
|
|
44
|
+
def test_with_parameterized_layers() -> None:
|
|
41
45
|
qs = cirq.LineQubit.range(3)
|
|
42
46
|
circuit = cirq.Circuit([cirq.H.on_each(*qs), cirq.CZ(qs[0], qs[1]), cirq.CZ(qs[1], qs[2])])
|
|
43
47
|
circuit2 = _with_parameterized_layers(circuit, qubits=qs, needs_init_layer=False)
|
|
@@ -46,9 +50,11 @@ def test_with_parameterized_layers():
|
|
|
46
50
|
*_, xlayer, ylayer, measurelayer = circuit2.moments
|
|
47
51
|
for op in xlayer.operations:
|
|
48
52
|
assert isinstance(op.gate, cirq.XPowGate)
|
|
53
|
+
assert isinstance(op.gate.exponent, sympy.Symbol)
|
|
49
54
|
assert op.gate.exponent.name.endswith('-Xf')
|
|
50
55
|
for op in ylayer.operations:
|
|
51
56
|
assert isinstance(op.gate, cirq.YPowGate)
|
|
57
|
+
assert isinstance(op.gate.exponent, sympy.Symbol)
|
|
52
58
|
assert op.gate.exponent.name.endswith('-Yf')
|
|
53
59
|
for op in measurelayer:
|
|
54
60
|
assert isinstance(op.gate, cirq.MeasurementGate)
|
|
@@ -60,13 +66,15 @@ def test_with_parameterized_layers():
|
|
|
60
66
|
xlayer, ylayer, *_ = circuit3.moments
|
|
61
67
|
for op in xlayer.operations:
|
|
62
68
|
assert isinstance(op.gate, cirq.XPowGate)
|
|
69
|
+
assert isinstance(op.gate.exponent, sympy.Symbol)
|
|
63
70
|
assert op.gate.exponent.name.endswith('-Xi')
|
|
64
71
|
for op in ylayer.operations:
|
|
65
72
|
assert isinstance(op.gate, cirq.YPowGate)
|
|
73
|
+
assert isinstance(op.gate.exponent, sympy.Symbol)
|
|
66
74
|
assert op.gate.exponent.name.endswith('-Yi')
|
|
67
75
|
|
|
68
76
|
|
|
69
|
-
def test_get_params_for_setting():
|
|
77
|
+
def test_get_params_for_setting() -> None:
|
|
70
78
|
qubits = cirq.LineQubit.range(3)
|
|
71
79
|
a, b, c = qubits
|
|
72
80
|
|
|
@@ -82,10 +90,10 @@ def test_get_params_for_setting():
|
|
|
82
90
|
needs_init_layer = True
|
|
83
91
|
with pytest.raises(ValueError):
|
|
84
92
|
_get_params_for_setting(
|
|
85
|
-
padded_setting, flips=[
|
|
93
|
+
padded_setting, flips=[False, False], qubits=qubits, needs_init_layer=needs_init_layer
|
|
86
94
|
)
|
|
87
95
|
params = _get_params_for_setting(
|
|
88
|
-
padded_setting, flips=[
|
|
96
|
+
padded_setting, flips=[False, False, True], qubits=qubits, needs_init_layer=needs_init_layer
|
|
89
97
|
)
|
|
90
98
|
assert all(
|
|
91
99
|
x in params
|
|
@@ -116,7 +124,7 @@ def test_get_params_for_setting():
|
|
|
116
124
|
np.testing.assert_allclose([ma, mb, mc], [1, 0, -1])
|
|
117
125
|
|
|
118
126
|
|
|
119
|
-
def test_params_and_settings():
|
|
127
|
+
def test_params_and_settings() -> None:
|
|
120
128
|
qubits = cirq.LineQubit.range(1)
|
|
121
129
|
(q,) = qubits
|
|
122
130
|
tests = [
|
|
@@ -143,7 +151,7 @@ def test_params_and_settings():
|
|
|
143
151
|
assert np.abs(coef - z) < 1e-2, f'{init} {obs} {coef}'
|
|
144
152
|
|
|
145
153
|
|
|
146
|
-
def test_subdivide_meas_specs():
|
|
154
|
+
def test_subdivide_meas_specs() -> None:
|
|
147
155
|
qubits = cirq.LineQubit.range(2)
|
|
148
156
|
q0, q1 = qubits
|
|
149
157
|
setting = cw.InitObsSetting(
|
|
@@ -177,7 +185,7 @@ def test_subdivide_meas_specs():
|
|
|
177
185
|
]
|
|
178
186
|
|
|
179
187
|
|
|
180
|
-
def test_aggregate_n_repetitions():
|
|
188
|
+
def test_aggregate_n_repetitions() -> None:
|
|
181
189
|
with pytest.warns(UserWarning):
|
|
182
190
|
reps = _aggregate_n_repetitions({5, 6})
|
|
183
191
|
assert reps == 6
|
|
@@ -197,7 +205,7 @@ class _MockBitstringAccumulator(BitstringAccumulator):
|
|
|
197
205
|
return cov / len(self.bitstrings)
|
|
198
206
|
|
|
199
207
|
|
|
200
|
-
def test_variance_stopping_criteria():
|
|
208
|
+
def test_variance_stopping_criteria() -> None:
|
|
201
209
|
stop = cw.VarianceStoppingCriteria(variance_bound=1e-6)
|
|
202
210
|
acc = _MockBitstringAccumulator()
|
|
203
211
|
assert stop.more_repetitions(acc) == 10_000
|
|
@@ -222,22 +230,30 @@ class _WildVarianceStoppingCriteria(StoppingCriteria):
|
|
|
222
230
|
return [5, 6][self._state % 2]
|
|
223
231
|
|
|
224
232
|
|
|
225
|
-
def test_variance_stopping_criteria_aggregate_n_repetitions():
|
|
233
|
+
def test_variance_stopping_criteria_aggregate_n_repetitions() -> None:
|
|
234
|
+
q0, q1 = cirq.LineQubit.range(2)
|
|
226
235
|
stop = _WildVarianceStoppingCriteria()
|
|
227
236
|
acc1 = _MockBitstringAccumulator()
|
|
228
237
|
acc2 = _MockBitstringAccumulator()
|
|
229
|
-
|
|
238
|
+
setting = InitObsSetting(
|
|
239
|
+
init_state=cirq.KET_ZERO(q0) * cirq.KET_ZERO(q1), observable=cirq.X(q0) * cirq.Y(q1)
|
|
240
|
+
)
|
|
241
|
+
meas_spec = _MeasurementSpec(
|
|
242
|
+
max_setting=setting, circuit_params={'beta': 0.123, 'gamma': 0.456}
|
|
243
|
+
)
|
|
244
|
+
meas_spec2 = _MeasurementSpec(
|
|
245
|
+
max_setting=setting, circuit_params={'beta': 0.123, 'gamma': 0.456}
|
|
246
|
+
)
|
|
247
|
+
accumulators = {meas_spec: acc1, meas_spec2: acc2}
|
|
230
248
|
with pytest.warns(UserWarning, match='the largest value will be used: 6.'):
|
|
231
249
|
still_todo, reps = _check_meas_specs_still_todo(
|
|
232
|
-
meas_specs=
|
|
233
|
-
accumulators=accumulators,
|
|
234
|
-
stopping_criteria=stop,
|
|
250
|
+
meas_specs=[meas_spec, meas_spec2], accumulators=accumulators, stopping_criteria=stop
|
|
235
251
|
)
|
|
236
|
-
assert still_todo == [
|
|
252
|
+
assert still_todo == [meas_spec, meas_spec2]
|
|
237
253
|
assert reps == 6
|
|
238
254
|
|
|
239
255
|
|
|
240
|
-
def test_repetitions_stopping_criteria():
|
|
256
|
+
def test_repetitions_stopping_criteria() -> None:
|
|
241
257
|
stop = cw.RepetitionsStoppingCriteria(total_repetitions=50_000)
|
|
242
258
|
acc = _MockBitstringAccumulator()
|
|
243
259
|
|
|
@@ -248,7 +264,7 @@ def test_repetitions_stopping_criteria():
|
|
|
248
264
|
assert todos == [10_000] * 5 + [0, 0]
|
|
249
265
|
|
|
250
266
|
|
|
251
|
-
def test_repetitions_stopping_criteria_partial():
|
|
267
|
+
def test_repetitions_stopping_criteria_partial() -> None:
|
|
252
268
|
stop = cw.RepetitionsStoppingCriteria(total_repetitions=5_000, repetitions_per_chunk=1_000_000)
|
|
253
269
|
acc = _MockBitstringAccumulator()
|
|
254
270
|
assert stop.more_repetitions(acc) == 5_000
|
|
@@ -268,7 +284,7 @@ def _set_up_meas_specs_for_testing():
|
|
|
268
284
|
return bsa, meas_spec
|
|
269
285
|
|
|
270
286
|
|
|
271
|
-
def test_meas_specs_still_todo():
|
|
287
|
+
def test_meas_specs_still_todo() -> None:
|
|
272
288
|
bsa, meas_spec = _set_up_meas_specs_for_testing()
|
|
273
289
|
stop = cw.RepetitionsStoppingCriteria(1_000)
|
|
274
290
|
|
|
@@ -296,7 +312,7 @@ def test_meas_specs_still_todo():
|
|
|
296
312
|
assert reps == 0
|
|
297
313
|
|
|
298
314
|
|
|
299
|
-
def test_meas_spec_still_todo_bad_spec():
|
|
315
|
+
def test_meas_spec_still_todo_bad_spec() -> None:
|
|
300
316
|
bsa, meas_spec = _set_up_meas_specs_for_testing()
|
|
301
317
|
|
|
302
318
|
class BadStopping(StoppingCriteria):
|
|
@@ -310,7 +326,7 @@ def test_meas_spec_still_todo_bad_spec():
|
|
|
310
326
|
)
|
|
311
327
|
|
|
312
328
|
|
|
313
|
-
def test_meas_spec_still_todo_too_many_params(monkeypatch):
|
|
329
|
+
def test_meas_spec_still_todo_too_many_params(monkeypatch) -> None:
|
|
314
330
|
monkeypatch.setattr(cw.observable_measurement, 'MAX_REPETITIONS_PER_JOB', 30_000)
|
|
315
331
|
bsa, meas_spec = _set_up_meas_specs_for_testing()
|
|
316
332
|
lots_of_meas_spec = [meas_spec] * 3_001
|
|
@@ -321,7 +337,7 @@ def test_meas_spec_still_todo_too_many_params(monkeypatch):
|
|
|
321
337
|
)
|
|
322
338
|
|
|
323
339
|
|
|
324
|
-
def test_meas_spec_still_todo_lots_of_params(monkeypatch):
|
|
340
|
+
def test_meas_spec_still_todo_lots_of_params(monkeypatch) -> None:
|
|
325
341
|
monkeypatch.setattr(cw.observable_measurement, 'MAX_REPETITIONS_PER_JOB', 30_000)
|
|
326
342
|
bsa, meas_spec = _set_up_meas_specs_for_testing()
|
|
327
343
|
lots_of_meas_spec = [meas_spec] * 4
|
|
@@ -332,7 +348,7 @@ def test_meas_spec_still_todo_lots_of_params(monkeypatch):
|
|
|
332
348
|
)
|
|
333
349
|
|
|
334
350
|
|
|
335
|
-
def test_checkpoint_options():
|
|
351
|
+
def test_checkpoint_options() -> None:
|
|
336
352
|
# There are three ~binary options (the latter two can be either specified or `None`. We
|
|
337
353
|
# test those 2^3 cases.
|
|
338
354
|
|
|
@@ -345,12 +361,15 @@ def test_checkpoint_options():
|
|
|
345
361
|
_parse_checkpoint_options(False, 'test1', 'test2')
|
|
346
362
|
|
|
347
363
|
chk, chkprev = _parse_checkpoint_options(True, None, None)
|
|
364
|
+
assert chk is not None
|
|
365
|
+
assert chkprev is not None
|
|
348
366
|
assert chk.startswith(tempfile.gettempdir())
|
|
349
367
|
assert chk.endswith('observables.json')
|
|
350
368
|
assert chkprev.startswith(tempfile.gettempdir())
|
|
351
369
|
assert chkprev.endswith('observables.prev.json')
|
|
352
370
|
|
|
353
371
|
chk, chkprev = _parse_checkpoint_options(True, None, 'prev.json')
|
|
372
|
+
assert chk is not None
|
|
354
373
|
assert chk.startswith(tempfile.gettempdir())
|
|
355
374
|
assert chk.endswith('observables.json')
|
|
356
375
|
assert chkprev == 'prev.json'
|
|
@@ -381,7 +400,7 @@ def test_checkpoint_options():
|
|
|
381
400
|
|
|
382
401
|
|
|
383
402
|
@pytest.mark.parametrize(('with_circuit_sweep', 'checkpoint'), [(True, True), (False, False)])
|
|
384
|
-
def test_measure_grouped_settings(with_circuit_sweep, checkpoint, tmpdir):
|
|
403
|
+
def test_measure_grouped_settings(with_circuit_sweep, checkpoint, tmpdir) -> None:
|
|
385
404
|
qubits = cirq.LineQubit.range(1)
|
|
386
405
|
(q,) = qubits
|
|
387
406
|
tests = [
|
|
@@ -431,7 +450,7 @@ def _get_some_grouped_settings():
|
|
|
431
450
|
return grouped_settings, qubits
|
|
432
451
|
|
|
433
452
|
|
|
434
|
-
def test_measure_grouped_settings_calibration_validation():
|
|
453
|
+
def test_measure_grouped_settings_calibration_validation() -> None:
|
|
435
454
|
mock_ro_calib = _MockBitstringAccumulator()
|
|
436
455
|
grouped_settings, qubits = _get_some_grouped_settings()
|
|
437
456
|
|
|
@@ -448,7 +467,7 @@ def test_measure_grouped_settings_calibration_validation():
|
|
|
448
467
|
)
|
|
449
468
|
|
|
450
469
|
|
|
451
|
-
def test_measure_grouped_settings_read_checkpoint(tmpdir):
|
|
470
|
+
def test_measure_grouped_settings_read_checkpoint(tmpdir) -> None:
|
|
452
471
|
qubits = cirq.LineQubit.range(1)
|
|
453
472
|
(q,) = qubits
|
|
454
473
|
|
|
@@ -495,7 +514,7 @@ Q = cirq.NamedQubit('q')
|
|
|
495
514
|
(cirq.Circuit(cirq.Y(Q) ** 0.5, cirq.Z(Q) ** 0.2), cirq.X(Q)),
|
|
496
515
|
],
|
|
497
516
|
)
|
|
498
|
-
def test_XYZ_point8(circuit, observable):
|
|
517
|
+
def test_XYZ_point8(circuit, observable) -> None:
|
|
499
518
|
# each circuit, observable combination should result in the observable value of 0.8
|
|
500
519
|
df = measure_observables_df(
|
|
501
520
|
circuit,
|
|
@@ -510,14 +529,14 @@ def test_XYZ_point8(circuit, observable):
|
|
|
510
529
|
|
|
511
530
|
def _each_in_its_own_group_grouper(
|
|
512
531
|
settings: Iterable[InitObsSetting],
|
|
513
|
-
) ->
|
|
532
|
+
) -> dict[InitObsSetting, list[InitObsSetting]]:
|
|
514
533
|
return {setting: [setting] for setting in settings}
|
|
515
534
|
|
|
516
535
|
|
|
517
536
|
@pytest.mark.parametrize(
|
|
518
537
|
'grouper', ['greedy', group_settings_greedy, _each_in_its_own_group_grouper]
|
|
519
538
|
)
|
|
520
|
-
def test_measure_observable_grouper(grouper):
|
|
539
|
+
def test_measure_observable_grouper(grouper) -> None:
|
|
521
540
|
circuit = cirq.Circuit(cirq.X(Q) ** 0.2)
|
|
522
541
|
observables = [cirq.Z(Q), cirq.Z(cirq.NamedQubit('q2'))]
|
|
523
542
|
results = measure_observables(
|
|
@@ -532,7 +551,7 @@ def test_measure_observable_grouper(grouper):
|
|
|
532
551
|
np.testing.assert_allclose(1, results[1].mean, atol=1e-9)
|
|
533
552
|
|
|
534
553
|
|
|
535
|
-
def test_measure_observable_bad_grouper():
|
|
554
|
+
def test_measure_observable_bad_grouper() -> None:
|
|
536
555
|
circuit = cirq.Circuit(cirq.X(Q) ** 0.2)
|
|
537
556
|
observables = [cirq.Z(Q), cirq.Z(cirq.NamedQubit('q2'))]
|
|
538
557
|
with pytest.raises(ValueError, match=r'Unknown grouping function'):
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# pylint: disable=wrong-or-nonexistent-copyright-notice
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
2
5
|
import dataclasses
|
|
3
|
-
from typing import Iterable, TYPE_CHECKING
|
|
6
|
+
from typing import Iterable, TYPE_CHECKING
|
|
4
7
|
|
|
5
8
|
from cirq import circuits, ops, study
|
|
6
9
|
from cirq.work.observable_measurement import measure_grouped_settings, StoppingCriteria
|
|
@@ -12,7 +15,7 @@ if TYPE_CHECKING:
|
|
|
12
15
|
|
|
13
16
|
def calibrate_readout_error(
|
|
14
17
|
qubits: Iterable[ops.Qid],
|
|
15
|
-
sampler:
|
|
18
|
+
sampler: cirq.Simulator | cirq.Sampler,
|
|
16
19
|
stopping_criteria: StoppingCriteria,
|
|
17
20
|
):
|
|
18
21
|
# We know there won't be any fancy sweeps or observables so we can
|