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
cirq/protocols/kraus_protocol.py
CHANGED
|
@@ -14,13 +14,16 @@
|
|
|
14
14
|
|
|
15
15
|
"""Protocol and methods for obtaining Kraus representation of quantum channels."""
|
|
16
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
17
19
|
import warnings
|
|
18
20
|
from types import NotImplementedType
|
|
19
|
-
from typing import Any, Sequence,
|
|
21
|
+
from typing import Any, Sequence, TypeVar
|
|
20
22
|
|
|
21
23
|
import numpy as np
|
|
22
24
|
from typing_extensions import Protocol
|
|
23
25
|
|
|
26
|
+
from cirq import protocols, qis
|
|
24
27
|
from cirq._doc import doc_private
|
|
25
28
|
from cirq.protocols.decompose_protocol import _try_decompose_into_operations_and_qubits
|
|
26
29
|
from cirq.protocols.mixture_protocol import has_mixture
|
|
@@ -31,7 +34,7 @@ from cirq.protocols.unitary_protocol import unitary
|
|
|
31
34
|
# Sequence[np.ndarray] to ensure the method has the correct type signature in
|
|
32
35
|
# that case. It is checked for using `is`, so it won't have a false positive
|
|
33
36
|
# if the user provides a different (np.array([]),) value.
|
|
34
|
-
RaiseTypeErrorIfNotProvided:
|
|
37
|
+
RaiseTypeErrorIfNotProvided: tuple[np.ndarray] = (np.array([]),)
|
|
35
38
|
|
|
36
39
|
|
|
37
40
|
TDefault = TypeVar('TDefault')
|
|
@@ -41,7 +44,7 @@ class SupportsKraus(Protocol):
|
|
|
41
44
|
"""An object that may be describable as a quantum channel."""
|
|
42
45
|
|
|
43
46
|
@doc_private
|
|
44
|
-
def _kraus_(self) ->
|
|
47
|
+
def _kraus_(self) -> Sequence[np.ndarray] | NotImplementedType:
|
|
45
48
|
r"""A list of Kraus matrices describing the quantum channel.
|
|
46
49
|
|
|
47
50
|
These matrices are the terms in the operator sum representation of a
|
|
@@ -92,9 +95,40 @@ class SupportsKraus(Protocol):
|
|
|
92
95
|
"""
|
|
93
96
|
|
|
94
97
|
|
|
98
|
+
def _strat_kraus_from_apply_channel(val: Any) -> tuple[np.ndarray, ...] | None:
|
|
99
|
+
"""Attempts to compute a value's Kraus operators via its _apply_channel_ method.
|
|
100
|
+
This is very expensive (O(16^N)), so only do this as a last resort."""
|
|
101
|
+
method = getattr(val, '_apply_channel_', None)
|
|
102
|
+
if method is None:
|
|
103
|
+
return None
|
|
104
|
+
|
|
105
|
+
qid_shape = protocols.qid_shape(val)
|
|
106
|
+
|
|
107
|
+
eye = qis.eye_tensor(qid_shape * 2, dtype=np.complex128)
|
|
108
|
+
buffer = np.empty_like(eye)
|
|
109
|
+
buffer.fill(float('nan'))
|
|
110
|
+
superop = protocols.apply_channel(
|
|
111
|
+
val=val,
|
|
112
|
+
args=protocols.ApplyChannelArgs(
|
|
113
|
+
target_tensor=eye,
|
|
114
|
+
out_buffer=buffer,
|
|
115
|
+
auxiliary_buffer0=buffer.copy(),
|
|
116
|
+
auxiliary_buffer1=buffer.copy(),
|
|
117
|
+
left_axes=list(range(len(qid_shape))),
|
|
118
|
+
right_axes=list(range(len(qid_shape), len(qid_shape) * 2)),
|
|
119
|
+
),
|
|
120
|
+
default=None,
|
|
121
|
+
)
|
|
122
|
+
if superop is None or superop is NotImplemented:
|
|
123
|
+
return None
|
|
124
|
+
n = np.prod(qid_shape) ** 2
|
|
125
|
+
kraus_ops = qis.superoperator_to_kraus(superop.reshape((n, n)))
|
|
126
|
+
return tuple(kraus_ops)
|
|
127
|
+
|
|
128
|
+
|
|
95
129
|
def kraus(
|
|
96
130
|
val: Any, default: Any = RaiseTypeErrorIfNotProvided
|
|
97
|
-
) ->
|
|
131
|
+
) -> tuple[np.ndarray, ...] | TDefault:
|
|
98
132
|
r"""Returns a list of matrices describing the channel for the given value.
|
|
99
133
|
|
|
100
134
|
These matrices are the terms in the operator sum representation of
|
|
@@ -146,9 +180,7 @@ def kraus(
|
|
|
146
180
|
mixture_getter = getattr(val, '_mixture_', None)
|
|
147
181
|
mixture_result = NotImplemented if mixture_getter is None else mixture_getter()
|
|
148
182
|
if mixture_result is not NotImplemented and mixture_result is not None:
|
|
149
|
-
return tuple(
|
|
150
|
-
np.sqrt(p) * (u if isinstance(u, np.ndarray) else unitary(u)) for p, u in mixture_result
|
|
151
|
-
)
|
|
183
|
+
return tuple(np.sqrt(p) * unitary(u) for p, u in mixture_result)
|
|
152
184
|
|
|
153
185
|
unitary_getter = getattr(val, '_unitary_', None)
|
|
154
186
|
unitary_result = NotImplemented if unitary_getter is None else unitary_getter()
|
|
@@ -159,6 +191,14 @@ def kraus(
|
|
|
159
191
|
if channel_result is not NotImplemented:
|
|
160
192
|
return tuple(channel_result) # pragma: no cover
|
|
161
193
|
|
|
194
|
+
# Last-resort fallback: try to derive Kraus from _apply_channel_.
|
|
195
|
+
# Note: _apply_channel can lead to kraus being called again, so if default
|
|
196
|
+
# is None, this can trigger an infinite loop.
|
|
197
|
+
if default is not None:
|
|
198
|
+
result = _strat_kraus_from_apply_channel(val)
|
|
199
|
+
if result is not None:
|
|
200
|
+
return result
|
|
201
|
+
|
|
162
202
|
if default is not RaiseTypeErrorIfNotProvided:
|
|
163
203
|
return default
|
|
164
204
|
|
|
@@ -14,17 +14,20 @@
|
|
|
14
14
|
|
|
15
15
|
"""Tests for kraus_protocol.py."""
|
|
16
16
|
|
|
17
|
-
from
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from typing import Iterable, Sequence
|
|
18
20
|
|
|
19
21
|
import numpy as np
|
|
20
22
|
import pytest
|
|
21
23
|
|
|
22
24
|
import cirq
|
|
25
|
+
from cirq.protocols.apply_channel_protocol import _apply_kraus
|
|
23
26
|
|
|
24
|
-
LOCAL_DEFAULT:
|
|
27
|
+
LOCAL_DEFAULT: list[np.ndarray] = [np.array([])]
|
|
25
28
|
|
|
26
29
|
|
|
27
|
-
def test_kraus_no_methods():
|
|
30
|
+
def test_kraus_no_methods() -> None:
|
|
28
31
|
class NoMethod:
|
|
29
32
|
pass
|
|
30
33
|
|
|
@@ -51,7 +54,7 @@ def assert_not_implemented(val):
|
|
|
51
54
|
assert not cirq.has_kraus(val)
|
|
52
55
|
|
|
53
56
|
|
|
54
|
-
def test_kraus_returns_not_implemented():
|
|
57
|
+
def test_kraus_returns_not_implemented() -> None:
|
|
55
58
|
class ReturnsNotImplemented:
|
|
56
59
|
def _kraus_(self):
|
|
57
60
|
return NotImplemented
|
|
@@ -59,7 +62,7 @@ def test_kraus_returns_not_implemented():
|
|
|
59
62
|
assert_not_implemented(ReturnsNotImplemented())
|
|
60
63
|
|
|
61
64
|
|
|
62
|
-
def test_mixture_returns_not_implemented():
|
|
65
|
+
def test_mixture_returns_not_implemented() -> None:
|
|
63
66
|
class ReturnsNotImplemented:
|
|
64
67
|
def _mixture_(self):
|
|
65
68
|
return NotImplemented
|
|
@@ -67,7 +70,7 @@ def test_mixture_returns_not_implemented():
|
|
|
67
70
|
assert_not_implemented(ReturnsNotImplemented())
|
|
68
71
|
|
|
69
72
|
|
|
70
|
-
def test_unitary_returns_not_implemented():
|
|
73
|
+
def test_unitary_returns_not_implemented() -> None:
|
|
71
74
|
class ReturnsNotImplemented:
|
|
72
75
|
def _unitary_(self):
|
|
73
76
|
return NotImplemented
|
|
@@ -80,7 +83,7 @@ def test_unitary_returns_not_implemented():
|
|
|
80
83
|
assert cirq.kraus(ReturnsNotImplemented(), LOCAL_DEFAULT) is LOCAL_DEFAULT
|
|
81
84
|
|
|
82
85
|
|
|
83
|
-
def test_explicit_kraus():
|
|
86
|
+
def test_explicit_kraus() -> None:
|
|
84
87
|
a0 = np.array([[0, 0], [1, 0]])
|
|
85
88
|
a1 = np.array([[1, 0], [0, 0]])
|
|
86
89
|
c = (a0, a1)
|
|
@@ -98,11 +101,11 @@ def test_explicit_kraus():
|
|
|
98
101
|
assert cirq.has_kraus(ReturnsKraus())
|
|
99
102
|
|
|
100
103
|
|
|
101
|
-
def test_kraus_fallback_to_mixture():
|
|
104
|
+
def test_kraus_fallback_to_mixture() -> None:
|
|
102
105
|
m = ((0.3, cirq.unitary(cirq.X)), (0.4, cirq.unitary(cirq.Y)), (0.3, cirq.unitary(cirq.Z)))
|
|
103
106
|
|
|
104
107
|
class ReturnsMixture:
|
|
105
|
-
def _mixture_(self) -> Iterable[
|
|
108
|
+
def _mixture_(self) -> Iterable[tuple[float, np.ndarray]]:
|
|
106
109
|
return m
|
|
107
110
|
|
|
108
111
|
c = (
|
|
@@ -120,7 +123,7 @@ def test_kraus_fallback_to_mixture():
|
|
|
120
123
|
assert cirq.has_kraus(ReturnsMixture())
|
|
121
124
|
|
|
122
125
|
|
|
123
|
-
def test_kraus_fallback_to_unitary():
|
|
126
|
+
def test_kraus_fallback_to_unitary() -> None:
|
|
124
127
|
u = np.array([[1, 0], [1, 0]])
|
|
125
128
|
|
|
126
129
|
class ReturnsUnitary:
|
|
@@ -160,12 +163,83 @@ class HasKrausWhenDecomposed(cirq.testing.SingleQubitGate):
|
|
|
160
163
|
|
|
161
164
|
|
|
162
165
|
@pytest.mark.parametrize('cls', [HasKraus, HasMixture, HasUnitary])
|
|
163
|
-
def test_has_kraus(cls):
|
|
166
|
+
def test_has_kraus(cls) -> None:
|
|
164
167
|
assert cirq.has_kraus(cls())
|
|
165
168
|
|
|
166
169
|
|
|
167
170
|
@pytest.mark.parametrize('decomposed_cls', [HasKraus, HasMixture, HasUnitary])
|
|
168
|
-
def test_has_kraus_when_decomposed(decomposed_cls):
|
|
171
|
+
def test_has_kraus_when_decomposed(decomposed_cls) -> None:
|
|
169
172
|
op = HasKrausWhenDecomposed(decomposed_cls).on(cirq.NamedQubit('test'))
|
|
170
173
|
assert cirq.has_kraus(op)
|
|
171
174
|
assert not cirq.has_kraus(op, allow_decompose=False)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def test_strat_kraus_from_apply_channel_returns_none():
|
|
178
|
+
# Remove _kraus_ and _apply_channel_ methods
|
|
179
|
+
class NoApplyChannelReset(cirq.ResetChannel):
|
|
180
|
+
def _kraus_(self):
|
|
181
|
+
return NotImplemented
|
|
182
|
+
|
|
183
|
+
def _apply_channel_(self, args):
|
|
184
|
+
return NotImplemented
|
|
185
|
+
|
|
186
|
+
gate_no_apply = NoApplyChannelReset()
|
|
187
|
+
with pytest.raises(
|
|
188
|
+
TypeError,
|
|
189
|
+
match="does have a _kraus_, _mixture_ or _unitary_ method, but it returned NotImplemented",
|
|
190
|
+
):
|
|
191
|
+
cirq.kraus(gate_no_apply)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@pytest.mark.parametrize(
|
|
195
|
+
'channel_cls,params',
|
|
196
|
+
[
|
|
197
|
+
(cirq.BitFlipChannel, (0.5,)),
|
|
198
|
+
(cirq.PhaseFlipChannel, (0.3,)),
|
|
199
|
+
(cirq.DepolarizingChannel, (0.2,)),
|
|
200
|
+
(cirq.AmplitudeDampingChannel, (0.4,)),
|
|
201
|
+
(cirq.PhaseDampingChannel, (0.25,)),
|
|
202
|
+
],
|
|
203
|
+
)
|
|
204
|
+
def test_kraus_fallback_to_apply_channel(channel_cls, params) -> None:
|
|
205
|
+
"""Kraus protocol falls back to _apply_channel_ when no _kraus_, _mixture_, or _unitary_."""
|
|
206
|
+
# Create the expected channel and get its Kraus operators
|
|
207
|
+
expected_channel = channel_cls(*params)
|
|
208
|
+
expected_kraus = cirq.kraus(expected_channel)
|
|
209
|
+
|
|
210
|
+
class TestChannel:
|
|
211
|
+
def __init__(self, channel_cls, params):
|
|
212
|
+
self.channel_cls = channel_cls
|
|
213
|
+
self.params = params
|
|
214
|
+
self.expected_kraus = cirq.kraus(channel_cls(*params))
|
|
215
|
+
|
|
216
|
+
def _num_qubits_(self):
|
|
217
|
+
return 1
|
|
218
|
+
|
|
219
|
+
def _apply_channel_(self, args: cirq.ApplyChannelArgs):
|
|
220
|
+
return _apply_kraus(self.expected_kraus, args)
|
|
221
|
+
|
|
222
|
+
chan = TestChannel(channel_cls, params)
|
|
223
|
+
kraus_ops = cirq.kraus(chan)
|
|
224
|
+
|
|
225
|
+
# Compare the superoperator matrices for equivalence
|
|
226
|
+
expected_super = sum(np.kron(k, k.conj()) for k in expected_kraus)
|
|
227
|
+
actual_super = sum(np.kron(k, k.conj()) for k in kraus_ops)
|
|
228
|
+
np.testing.assert_allclose(actual_super, expected_super, atol=1e-8)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def test_reset_channel_kraus_apply_channel_consistency():
|
|
232
|
+
Reset = cirq.ResetChannel
|
|
233
|
+
# Original gate
|
|
234
|
+
gate = Reset()
|
|
235
|
+
cirq.testing.assert_has_consistent_apply_channel(gate)
|
|
236
|
+
cirq.testing.assert_consistent_channel(gate)
|
|
237
|
+
|
|
238
|
+
# Remove _kraus_ method
|
|
239
|
+
class NoKrausReset(Reset):
|
|
240
|
+
def _kraus_(self):
|
|
241
|
+
return NotImplemented
|
|
242
|
+
|
|
243
|
+
gate_no_kraus = NoKrausReset()
|
|
244
|
+
# Should still match the original superoperator
|
|
245
|
+
np.testing.assert_allclose(cirq.kraus(gate), cirq.kraus(gate_no_kraus), atol=1e-8)
|
|
@@ -11,10 +11,13 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
"""Protocol for object that have measurement keys."""
|
|
15
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
16
19
|
from types import NotImplementedType
|
|
17
|
-
from typing import Any,
|
|
20
|
+
from typing import Any, Mapping, TYPE_CHECKING
|
|
18
21
|
|
|
19
22
|
from typing_extensions import Protocol
|
|
20
23
|
|
|
@@ -60,7 +63,7 @@ class SupportsMeasurementKey(Protocol):
|
|
|
60
63
|
"""Return if this object is (or contains) a measurement."""
|
|
61
64
|
|
|
62
65
|
@doc_private
|
|
63
|
-
def _measurement_key_obj_(self) ->
|
|
66
|
+
def _measurement_key_obj_(self) -> cirq.MeasurementKey:
|
|
64
67
|
"""Return the key object that will be used to identify this measurement.
|
|
65
68
|
|
|
66
69
|
When a measurement occurs, either on hardware, or in a simulation,
|
|
@@ -69,9 +72,7 @@ class SupportsMeasurementKey(Protocol):
|
|
|
69
72
|
"""
|
|
70
73
|
|
|
71
74
|
@doc_private
|
|
72
|
-
def _measurement_key_objs_(
|
|
73
|
-
self,
|
|
74
|
-
) -> Union[FrozenSet['cirq.MeasurementKey'], NotImplementedType, None]:
|
|
75
|
+
def _measurement_key_objs_(self) -> frozenset[cirq.MeasurementKey] | NotImplementedType | None:
|
|
75
76
|
"""Return the key objects for measurements performed by the receiving object.
|
|
76
77
|
|
|
77
78
|
When a measurement occurs, either on hardware, or in a simulation,
|
|
@@ -89,7 +90,7 @@ class SupportsMeasurementKey(Protocol):
|
|
|
89
90
|
"""
|
|
90
91
|
|
|
91
92
|
@doc_private
|
|
92
|
-
def _measurement_key_names_(self) ->
|
|
93
|
+
def _measurement_key_names_(self) -> frozenset[str] | NotImplementedType | None:
|
|
93
94
|
"""Return the string keys for measurements performed by the receiving object.
|
|
94
95
|
|
|
95
96
|
When a measurement occurs, either on hardware, or in a simulation,
|
|
@@ -175,7 +176,7 @@ def measurement_key_name(val: Any, default: Any = RaiseTypeErrorIfNotProvided):
|
|
|
175
176
|
|
|
176
177
|
def _measurement_key_objs_from_magic_methods(
|
|
177
178
|
val: Any,
|
|
178
|
-
) ->
|
|
179
|
+
) -> frozenset[cirq.MeasurementKey] | NotImplementedType | None:
|
|
179
180
|
"""Uses the measurement key related magic methods to get the `MeasurementKey`s for this
|
|
180
181
|
object."""
|
|
181
182
|
|
|
@@ -193,7 +194,7 @@ def _measurement_key_objs_from_magic_methods(
|
|
|
193
194
|
|
|
194
195
|
def _measurement_key_names_from_magic_methods(
|
|
195
196
|
val: Any,
|
|
196
|
-
) ->
|
|
197
|
+
) -> frozenset[str] | NotImplementedType | None:
|
|
197
198
|
"""Uses the measurement key related magic methods to get the key strings for this object."""
|
|
198
199
|
|
|
199
200
|
getter = getattr(val, '_measurement_key_names_', None)
|
|
@@ -209,7 +210,7 @@ def _measurement_key_names_from_magic_methods(
|
|
|
209
210
|
return result
|
|
210
211
|
|
|
211
212
|
|
|
212
|
-
def measurement_key_objs(val: Any) ->
|
|
213
|
+
def measurement_key_objs(val: Any) -> frozenset[cirq.MeasurementKey]:
|
|
213
214
|
"""Gets the measurement key objects of measurements within the given value.
|
|
214
215
|
|
|
215
216
|
Args:
|
|
@@ -228,7 +229,7 @@ def measurement_key_objs(val: Any) -> FrozenSet['cirq.MeasurementKey']:
|
|
|
228
229
|
return frozenset()
|
|
229
230
|
|
|
230
231
|
|
|
231
|
-
def measurement_key_names(val: Any) ->
|
|
232
|
+
def measurement_key_names(val: Any) -> frozenset[str]:
|
|
232
233
|
"""Gets the measurement key strings of measurements within the given value.
|
|
233
234
|
|
|
234
235
|
Args:
|
|
@@ -253,7 +254,7 @@ def measurement_key_names(val: Any) -> FrozenSet[str]:
|
|
|
253
254
|
return frozenset()
|
|
254
255
|
|
|
255
256
|
|
|
256
|
-
def _is_measurement_from_magic_method(val: Any) ->
|
|
257
|
+
def _is_measurement_from_magic_method(val: Any) -> bool | None:
|
|
257
258
|
"""Uses `is_measurement` magic method to determine if this object is a measurement."""
|
|
258
259
|
getter = getattr(val, '_is_measurement_', None)
|
|
259
260
|
return NotImplemented if getter is None else getter()
|
|
@@ -289,7 +290,7 @@ def with_measurement_key_mapping(val: Any, key_map: Mapping[str, str]):
|
|
|
289
290
|
return NotImplemented if getter is None else getter(key_map)
|
|
290
291
|
|
|
291
292
|
|
|
292
|
-
def with_key_path(val: Any, path:
|
|
293
|
+
def with_key_path(val: Any, path: tuple[str, ...]):
|
|
293
294
|
"""Adds the path to the target's measurement keys.
|
|
294
295
|
|
|
295
296
|
The path usually refers to an identifier or a list of identifiers from a subcircuit that
|
|
@@ -300,7 +301,7 @@ def with_key_path(val: Any, path: Tuple[str, ...]):
|
|
|
300
301
|
return NotImplemented if getter is None else getter(path)
|
|
301
302
|
|
|
302
303
|
|
|
303
|
-
def with_key_path_prefix(val: Any, prefix:
|
|
304
|
+
def with_key_path_prefix(val: Any, prefix: tuple[str, ...]):
|
|
304
305
|
"""Prefixes the path to the target's measurement keys.
|
|
305
306
|
|
|
306
307
|
The path usually refers to an identifier or a list of identifiers from a subcircuit that
|
|
@@ -316,9 +317,7 @@ def with_key_path_prefix(val: Any, prefix: Tuple[str, ...]):
|
|
|
316
317
|
|
|
317
318
|
|
|
318
319
|
def with_rescoped_keys(
|
|
319
|
-
val: Any,
|
|
320
|
-
path: Tuple[str, ...],
|
|
321
|
-
bindable_keys: Optional[FrozenSet['cirq.MeasurementKey']] = None,
|
|
320
|
+
val: Any, path: tuple[str, ...], bindable_keys: frozenset[cirq.MeasurementKey] | None = None
|
|
322
321
|
):
|
|
323
322
|
"""Rescopes any measurement and control keys to the provided path, given the existing keys.
|
|
324
323
|
|
|
@@ -12,6 +12,8 @@
|
|
|
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 pytest
|
|
16
18
|
|
|
17
19
|
import cirq
|
|
@@ -28,7 +30,7 @@ class ReturnsObj:
|
|
|
28
30
|
|
|
29
31
|
|
|
30
32
|
@pytest.mark.parametrize('gate', [ReturnsStr(), ReturnsObj()])
|
|
31
|
-
def test_measurement_key_name(gate):
|
|
33
|
+
def test_measurement_key_name(gate) -> None:
|
|
32
34
|
assert isinstance(cirq.measurement_key_name(gate), str)
|
|
33
35
|
assert cirq.measurement_key_name(gate) == 'door locker'
|
|
34
36
|
assert cirq.measurement_key_obj(gate) == cirq.MeasurementKey(name='door locker')
|
|
@@ -39,7 +41,7 @@ def test_measurement_key_name(gate):
|
|
|
39
41
|
|
|
40
42
|
|
|
41
43
|
@pytest.mark.parametrize('gate', [ReturnsStr(), ReturnsObj()])
|
|
42
|
-
def test_measurement_key_obj(gate):
|
|
44
|
+
def test_measurement_key_obj(gate) -> None:
|
|
43
45
|
assert isinstance(cirq.measurement_key_obj(gate), cirq.MeasurementKey)
|
|
44
46
|
assert cirq.measurement_key_obj(gate) == cirq.MeasurementKey(name='door locker')
|
|
45
47
|
assert cirq.measurement_key_obj(gate) == 'door locker'
|
|
@@ -50,7 +52,7 @@ def test_measurement_key_obj(gate):
|
|
|
50
52
|
|
|
51
53
|
|
|
52
54
|
@pytest.mark.parametrize('key_method', [cirq.measurement_key_name, cirq.measurement_key_obj])
|
|
53
|
-
def test_measurement_key_no_method(key_method):
|
|
55
|
+
def test_measurement_key_no_method(key_method) -> None:
|
|
54
56
|
class NoMethod:
|
|
55
57
|
pass
|
|
56
58
|
|
|
@@ -73,7 +75,7 @@ def test_measurement_key_no_method(key_method):
|
|
|
73
75
|
|
|
74
76
|
|
|
75
77
|
@pytest.mark.parametrize('key_method', [cirq.measurement_key_name, cirq.measurement_key_obj])
|
|
76
|
-
def test_measurement_key_not_implemented_default_behavior(key_method):
|
|
78
|
+
def test_measurement_key_not_implemented_default_behavior(key_method) -> None:
|
|
77
79
|
class ReturnsNotImplemented:
|
|
78
80
|
def _measurement_key_name_(self):
|
|
79
81
|
return NotImplemented
|
|
@@ -89,7 +91,7 @@ def test_measurement_key_not_implemented_default_behavior(key_method):
|
|
|
89
91
|
assert key_method(ReturnsNotImplemented(), 'a') == 'a'
|
|
90
92
|
|
|
91
93
|
|
|
92
|
-
def test_is_measurement():
|
|
94
|
+
def test_is_measurement() -> None:
|
|
93
95
|
q = cirq.NamedQubit('q')
|
|
94
96
|
assert cirq.is_measurement(cirq.measure(q))
|
|
95
97
|
assert cirq.is_measurement(cirq.MeasurementGate(num_qubits=1, key='b'))
|
|
@@ -99,7 +101,7 @@ def test_is_measurement():
|
|
|
99
101
|
assert not cirq.is_measurement(cirq.bit_flip(1))
|
|
100
102
|
|
|
101
103
|
class NotImplementedOperation(cirq.Operation):
|
|
102
|
-
def with_qubits(self, *new_qubits) ->
|
|
104
|
+
def with_qubits(self, *new_qubits) -> NotImplementedOperation:
|
|
103
105
|
raise NotImplementedError()
|
|
104
106
|
|
|
105
107
|
@property
|
|
@@ -109,7 +111,7 @@ def test_is_measurement():
|
|
|
109
111
|
assert not cirq.is_measurement(NotImplementedOperation())
|
|
110
112
|
|
|
111
113
|
|
|
112
|
-
def test_measurement_without_key():
|
|
114
|
+
def test_measurement_without_key() -> None:
|
|
113
115
|
class MeasurementWithoutKey:
|
|
114
116
|
def _is_measurement_(self):
|
|
115
117
|
return True
|
|
@@ -120,7 +122,7 @@ def test_measurement_without_key():
|
|
|
120
122
|
assert cirq.is_measurement(MeasurementWithoutKey())
|
|
121
123
|
|
|
122
124
|
|
|
123
|
-
def test_non_measurement_with_key():
|
|
125
|
+
def test_non_measurement_with_key() -> None:
|
|
124
126
|
class NonMeasurementGate(cirq.Gate):
|
|
125
127
|
def _is_measurement_(self):
|
|
126
128
|
return False # pragma: no cover
|
|
@@ -155,7 +157,7 @@ def test_non_measurement_with_key():
|
|
|
155
157
|
('key_method', 'keys'),
|
|
156
158
|
[(cirq.measurement_key_names, {'a', 'b'}), (cirq.measurement_key_objs, {'c', 'd'})],
|
|
157
159
|
)
|
|
158
|
-
def test_measurement_keys(key_method, keys):
|
|
160
|
+
def test_measurement_keys(key_method, keys) -> None:
|
|
159
161
|
class MeasurementKeysGate(cirq.Gate):
|
|
160
162
|
def _measurement_key_names_(self):
|
|
161
163
|
return frozenset(['a', 'b'])
|
|
@@ -180,7 +182,7 @@ def test_measurement_keys(key_method, keys):
|
|
|
180
182
|
assert key_method(MeasurementKeysGate().on(a)) == keys
|
|
181
183
|
|
|
182
184
|
|
|
183
|
-
def test_measurement_key_mapping():
|
|
185
|
+
def test_measurement_key_mapping() -> None:
|
|
184
186
|
class MultiKeyGate:
|
|
185
187
|
def __init__(self, keys):
|
|
186
188
|
self._keys = frozenset(keys)
|
|
@@ -217,7 +219,7 @@ def test_measurement_key_mapping():
|
|
|
217
219
|
assert cirq.measurement_key_names(mkg_cdx) == {'c', 'd'}
|
|
218
220
|
|
|
219
221
|
|
|
220
|
-
def test_measurement_key_path():
|
|
222
|
+
def test_measurement_key_path() -> None:
|
|
221
223
|
class MultiKeyGate:
|
|
222
224
|
def __init__(self, keys):
|
|
223
225
|
self._keys = frozenset(cirq.MeasurementKey.parse_serialized(key) for key in keys)
|
|
@@ -14,8 +14,10 @@
|
|
|
14
14
|
|
|
15
15
|
"""Protocol for objects that are mixtures (probabilistic combinations)."""
|
|
16
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
17
19
|
from types import NotImplementedType
|
|
18
|
-
from typing import Any, Sequence
|
|
20
|
+
from typing import Any, Sequence
|
|
19
21
|
|
|
20
22
|
import numpy as np
|
|
21
23
|
from typing_extensions import Protocol
|
|
@@ -27,14 +29,14 @@ from cirq.protocols.unitary_protocol import unitary
|
|
|
27
29
|
|
|
28
30
|
# This is a special indicator value used by the inverse method to determine
|
|
29
31
|
# whether or not the caller provided a 'default' argument.
|
|
30
|
-
RaiseTypeErrorIfNotProvided: Sequence[
|
|
32
|
+
RaiseTypeErrorIfNotProvided: Sequence[tuple[float, Any]] = ((0.0, []),)
|
|
31
33
|
|
|
32
34
|
|
|
33
35
|
class SupportsMixture(Protocol):
|
|
34
36
|
"""An object that decomposes into a probability distribution of unitaries."""
|
|
35
37
|
|
|
36
38
|
@doc_private
|
|
37
|
-
def _mixture_(self) ->
|
|
39
|
+
def _mixture_(self) -> Sequence[tuple[float, Any]] | NotImplementedType:
|
|
38
40
|
"""Decompose into a probability distribution of unitaries.
|
|
39
41
|
|
|
40
42
|
This method is used by the global `cirq.mixture` method.
|
|
@@ -65,7 +67,7 @@ class SupportsMixture(Protocol):
|
|
|
65
67
|
|
|
66
68
|
def mixture(
|
|
67
69
|
val: Any, default: Any = RaiseTypeErrorIfNotProvided
|
|
68
|
-
) -> Sequence[
|
|
70
|
+
) -> Sequence[tuple[float, np.ndarray]]:
|
|
69
71
|
"""Return a sequence of tuples representing a probabilistic unitary.
|
|
70
72
|
|
|
71
73
|
A mixture is described by an iterable of tuples of the form
|
|
@@ -92,7 +94,7 @@ def mixture(
|
|
|
92
94
|
mixture_getter = getattr(val, '_mixture_', None)
|
|
93
95
|
result = NotImplemented if mixture_getter is None else mixture_getter()
|
|
94
96
|
if result is not NotImplemented and result is not None:
|
|
95
|
-
return tuple((p,
|
|
97
|
+
return tuple((p, unitary(u)) for p, u in result)
|
|
96
98
|
|
|
97
99
|
unitary_getter = getattr(val, '_unitary_', None)
|
|
98
100
|
result = NotImplemented if unitary_getter is None else unitary_getter()
|
|
@@ -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 numpy as np
|
|
16
18
|
import pytest
|
|
17
19
|
|
|
18
20
|
import cirq
|
|
19
21
|
|
|
20
|
-
a = np.array([1])
|
|
21
|
-
b = np.array([1j])
|
|
22
|
+
a = np.array([[1]])
|
|
23
|
+
b = np.array([[1j]])
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
class NoMethod:
|
cirq/protocols/mul_protocol.py
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
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 Any
|
|
16
18
|
|
|
17
19
|
from cirq.protocols.resolve_parameters import is_parameterized
|
|
@@ -69,6 +71,3 @@ def mul(lhs: Any, rhs: Any, default: Any = RaiseTypeErrorIfNotProvided) -> Any:
|
|
|
69
71
|
if default is not RaiseTypeErrorIfNotProvided:
|
|
70
72
|
return default
|
|
71
73
|
raise TypeError(f"unsupported operand type(s) for *: '{type(lhs)}' and '{type(rhs)}'")
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
# pylint: enable=function-redefined, redefined-builtin
|
|
@@ -11,9 +11,12 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
"""Protocol for obtaining expansion of linear operators in Pauli basis."""
|
|
15
16
|
|
|
16
|
-
from
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from typing import Any, TypeVar
|
|
17
20
|
|
|
18
21
|
from typing_extensions import Protocol
|
|
19
22
|
|
|
@@ -45,9 +48,9 @@ class SupportsPauliExpansion(Protocol):
|
|
|
45
48
|
def pauli_expansion(
|
|
46
49
|
val: Any,
|
|
47
50
|
*,
|
|
48
|
-
default:
|
|
51
|
+
default: value.LinearDict[str] | TDefault = RaiseTypeErrorIfNotProvided,
|
|
49
52
|
atol: float = 1e-9,
|
|
50
|
-
) ->
|
|
53
|
+
) -> value.LinearDict[str] | TDefault:
|
|
51
54
|
"""Returns coefficients of the expansion of val in the Pauli basis.
|
|
52
55
|
|
|
53
56
|
Args:
|
|
@@ -12,6 +12,8 @@
|
|
|
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 numpy as np
|
|
16
18
|
import pytest
|
|
17
19
|
|
|
@@ -52,9 +54,9 @@ class HasQuditUnitary:
|
|
|
52
54
|
|
|
53
55
|
|
|
54
56
|
@pytest.mark.parametrize(
|
|
55
|
-
'val', (NoMethod(), ReturnsNotImplemented(), HasQuditUnitary(), 123,
|
|
57
|
+
'val', (NoMethod(), ReturnsNotImplemented(), HasQuditUnitary(), 123, object(), cirq)
|
|
56
58
|
)
|
|
57
|
-
def test_raises_no_pauli_expansion(val):
|
|
59
|
+
def test_raises_no_pauli_expansion(val) -> None:
|
|
58
60
|
assert cirq.pauli_expansion(val, default=None) is None
|
|
59
61
|
with pytest.raises(TypeError, match='No Pauli expansion'):
|
|
60
62
|
cirq.pauli_expansion(val)
|
|
@@ -78,7 +80,7 @@ def test_raises_no_pauli_expansion(val):
|
|
|
78
80
|
),
|
|
79
81
|
),
|
|
80
82
|
)
|
|
81
|
-
def test_pauli_expansion(val, expected_expansion):
|
|
83
|
+
def test_pauli_expansion(val, expected_expansion) -> None:
|
|
82
84
|
actual_expansion = cirq.pauli_expansion(val)
|
|
83
85
|
assert cirq.approx_eq(actual_expansion, expected_expansion, atol=1e-12)
|
|
84
86
|
assert set(actual_expansion.keys()) == set(expected_expansion.keys())
|
cirq/protocols/phase_protocol.py
CHANGED
|
@@ -12,12 +12,14 @@
|
|
|
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 pytest
|
|
16
18
|
|
|
17
19
|
import cirq
|
|
18
20
|
|
|
19
21
|
|
|
20
|
-
def test_phase_by():
|
|
22
|
+
def test_phase_by() -> None:
|
|
21
23
|
class NoMethod:
|
|
22
24
|
pass
|
|
23
25
|
|