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/ops/pauli_string.py
CHANGED
|
@@ -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 cmath
|
|
15
18
|
import math
|
|
16
19
|
import numbers
|
|
@@ -20,18 +23,14 @@ from typing import (
|
|
|
20
23
|
Any,
|
|
21
24
|
Callable,
|
|
22
25
|
cast,
|
|
23
|
-
Dict,
|
|
24
26
|
Generic,
|
|
25
27
|
ItemsView,
|
|
26
28
|
Iterable,
|
|
27
29
|
Iterator,
|
|
28
30
|
KeysView,
|
|
29
|
-
List,
|
|
30
31
|
Mapping,
|
|
31
|
-
Optional,
|
|
32
32
|
overload,
|
|
33
33
|
Sequence,
|
|
34
|
-
Tuple,
|
|
35
34
|
TYPE_CHECKING,
|
|
36
35
|
TypeVar,
|
|
37
36
|
Union,
|
|
@@ -42,6 +41,7 @@ import numpy as np
|
|
|
42
41
|
import sympy
|
|
43
42
|
|
|
44
43
|
from cirq import _compat, linalg, protocols, qis, value
|
|
44
|
+
from cirq._compat import deprecated
|
|
45
45
|
from cirq._doc import document
|
|
46
46
|
from cirq._import import LazyLoader
|
|
47
47
|
from cirq.ops import (
|
|
@@ -159,9 +159,9 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
159
159
|
|
|
160
160
|
def __init__(
|
|
161
161
|
self,
|
|
162
|
-
*contents:
|
|
163
|
-
qubit_pauli_map:
|
|
164
|
-
coefficient:
|
|
162
|
+
*contents: cirq.PAULI_STRING_LIKE,
|
|
163
|
+
qubit_pauli_map: dict[TKey, cirq.Pauli] | None = None,
|
|
164
|
+
coefficient: cirq.TParamValComplex = 1,
|
|
165
165
|
):
|
|
166
166
|
"""Initializes a new `PauliString` operation.
|
|
167
167
|
|
|
@@ -188,8 +188,8 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
188
188
|
if not isinstance(v, pauli_gates.Pauli):
|
|
189
189
|
raise TypeError(f'{v} is not a Pauli')
|
|
190
190
|
|
|
191
|
-
self._qubit_pauli_map:
|
|
192
|
-
self._coefficient:
|
|
191
|
+
self._qubit_pauli_map: dict[TKey, cirq.Pauli] = qubit_pauli_map or {}
|
|
192
|
+
self._coefficient: cirq.TParamValComplex | sympy.Expr = (
|
|
193
193
|
coefficient if isinstance(coefficient, sympy.Expr) else complex(coefficient)
|
|
194
194
|
)
|
|
195
195
|
if contents:
|
|
@@ -198,7 +198,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
198
198
|
self._coefficient = m._coefficient
|
|
199
199
|
|
|
200
200
|
@property
|
|
201
|
-
def coefficient(self) ->
|
|
201
|
+
def coefficient(self) -> cirq.TParamValComplex:
|
|
202
202
|
"""A scalar coefficient or symbol."""
|
|
203
203
|
return self._coefficient
|
|
204
204
|
|
|
@@ -209,7 +209,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
209
209
|
|
|
210
210
|
return (frozenset(self._qubit_pauli_map.items()), self._coefficient)
|
|
211
211
|
|
|
212
|
-
def _json_dict_(self) ->
|
|
212
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
213
213
|
return {
|
|
214
214
|
# JSON requires mappings to have string keys.
|
|
215
215
|
'qubit_pauli_map': list(self._qubit_pauli_map.items()),
|
|
@@ -225,52 +225,45 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
225
225
|
return gate_operation.GateOperation
|
|
226
226
|
return PauliString
|
|
227
227
|
|
|
228
|
-
def equal_up_to_coefficient(self, other:
|
|
228
|
+
def equal_up_to_coefficient(self, other: cirq.PauliString) -> bool:
|
|
229
229
|
"""Returns true of `self` and `other` are equal pauli strings, ignoring the coefficient."""
|
|
230
230
|
return self._qubit_pauli_map == other._qubit_pauli_map
|
|
231
231
|
|
|
232
232
|
def __getitem__(self, key: TKey) -> pauli_gates.Pauli:
|
|
233
233
|
return self._qubit_pauli_map[key]
|
|
234
234
|
|
|
235
|
-
# pylint: disable=function-redefined
|
|
236
235
|
@overload
|
|
237
|
-
def get(self, key: Any, default: None = None) ->
|
|
236
|
+
def get(self, key: Any, default: None = None) -> pauli_gates.Pauli | None:
|
|
238
237
|
pass
|
|
239
238
|
|
|
240
239
|
@overload
|
|
241
|
-
def get(self, key: Any, default: TDefault) ->
|
|
240
|
+
def get(self, key: Any, default: TDefault) -> pauli_gates.Pauli | TDefault:
|
|
242
241
|
pass
|
|
243
242
|
|
|
244
|
-
def get(
|
|
245
|
-
self, key: Any, default: Optional[TDefault] = None
|
|
246
|
-
) -> Union[pauli_gates.Pauli, TDefault, None]:
|
|
243
|
+
def get(self, key: Any, default: TDefault | None = None) -> pauli_gates.Pauli | TDefault | None:
|
|
247
244
|
"""Returns the `cirq.Pauli` operation acting on qubit `key` or `default` if none exists."""
|
|
248
245
|
return self._qubit_pauli_map.get(key, default)
|
|
249
246
|
|
|
250
247
|
@overload
|
|
251
|
-
def __mul__(
|
|
252
|
-
self, other: 'cirq.PauliString[TKeyOther]'
|
|
253
|
-
) -> 'cirq.PauliString[Union[TKey, TKeyOther]]':
|
|
248
|
+
def __mul__(self, other: cirq.PauliString[TKeyOther]) -> cirq.PauliString[TKey | TKeyOther]:
|
|
254
249
|
pass
|
|
255
250
|
|
|
256
251
|
@overload
|
|
257
252
|
def __mul__(
|
|
258
|
-
self, other: Mapping[TKeyOther,
|
|
259
|
-
) ->
|
|
253
|
+
self, other: Mapping[TKeyOther, cirq.PAULI_GATE_LIKE]
|
|
254
|
+
) -> cirq.PauliString[TKey | TKeyOther]:
|
|
260
255
|
pass
|
|
261
256
|
|
|
262
257
|
@overload
|
|
263
|
-
def __mul__(
|
|
264
|
-
self, other: Iterable['cirq.PAULI_STRING_LIKE']
|
|
265
|
-
) -> 'cirq.PauliString[Union[TKey, cirq.Qid]]':
|
|
258
|
+
def __mul__(self, other: Iterable[cirq.PAULI_STRING_LIKE]) -> cirq.PauliString[TKey | cirq.Qid]:
|
|
266
259
|
pass
|
|
267
260
|
|
|
268
261
|
@overload
|
|
269
|
-
def __mul__(self, other:
|
|
262
|
+
def __mul__(self, other: cirq.Operation) -> cirq.PauliString[TKey | cirq.Qid]:
|
|
270
263
|
pass
|
|
271
264
|
|
|
272
265
|
@overload
|
|
273
|
-
def __mul__(self, other: complex) ->
|
|
266
|
+
def __mul__(self, other: complex) -> cirq.PauliString[TKey]:
|
|
274
267
|
pass
|
|
275
268
|
|
|
276
269
|
def __mul__(self, other):
|
|
@@ -287,24 +280,17 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
287
280
|
)
|
|
288
281
|
return NotImplemented
|
|
289
282
|
|
|
290
|
-
# pylint: enable=function-redefined
|
|
291
|
-
|
|
292
283
|
@property
|
|
293
|
-
def gate(self) ->
|
|
284
|
+
def gate(self) -> cirq.DensePauliString:
|
|
294
285
|
"""Returns a `cirq.DensePauliString`"""
|
|
295
|
-
order:
|
|
296
|
-
None,
|
|
297
|
-
pauli_gates.X,
|
|
298
|
-
pauli_gates.Y,
|
|
299
|
-
pauli_gates.Z,
|
|
300
|
-
]
|
|
286
|
+
order: list[pauli_gates.Pauli | None] = [None, pauli_gates.X, pauli_gates.Y, pauli_gates.Z]
|
|
301
287
|
from cirq.ops.dense_pauli_string import DensePauliString
|
|
302
288
|
|
|
303
289
|
return DensePauliString(
|
|
304
290
|
coefficient=self.coefficient, pauli_mask=[order.index(self[q]) for q in self.qubits]
|
|
305
291
|
)
|
|
306
292
|
|
|
307
|
-
def __rmul__(self, other) ->
|
|
293
|
+
def __rmul__(self, other) -> PauliString:
|
|
308
294
|
if isinstance(other, numbers.Complex):
|
|
309
295
|
return PauliString(
|
|
310
296
|
qubit_pauli_map=self._qubit_pauli_map, coefficient=self._coefficient * other
|
|
@@ -355,11 +341,11 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
355
341
|
return self._qubit_pauli_map.keys()
|
|
356
342
|
|
|
357
343
|
@property
|
|
358
|
-
def qubits(self) ->
|
|
344
|
+
def qubits(self) -> tuple[TKey, ...]:
|
|
359
345
|
"""Returns a tuple of qubits on which this pauli string acts."""
|
|
360
346
|
return tuple(self.keys())
|
|
361
347
|
|
|
362
|
-
def _circuit_diagram_info_(self, args:
|
|
348
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> list[str]:
|
|
363
349
|
if not len(self._qubit_pauli_map):
|
|
364
350
|
return NotImplemented
|
|
365
351
|
|
|
@@ -380,7 +366,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
380
366
|
symbols[0] = f'PauliString({prefix}{symbols[0]})'
|
|
381
367
|
return symbols
|
|
382
368
|
|
|
383
|
-
def with_qubits(self, *new_qubits:
|
|
369
|
+
def with_qubits(self, *new_qubits: cirq.Qid) -> PauliString:
|
|
384
370
|
"""Returns a new `PauliString` with `self.qubits` mapped to `new_qubits`.
|
|
385
371
|
|
|
386
372
|
Args:
|
|
@@ -402,7 +388,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
402
388
|
coefficient=self._coefficient,
|
|
403
389
|
)
|
|
404
390
|
|
|
405
|
-
def with_coefficient(self, new_coefficient:
|
|
391
|
+
def with_coefficient(self, new_coefficient: cirq.TParamValComplex) -> PauliString:
|
|
406
392
|
"""Returns a new `PauliString` with `self.coefficient` replaced with `new_coefficient`."""
|
|
407
393
|
return PauliString(qubit_pauli_map=dict(self._qubit_pauli_map), coefficient=new_coefficient)
|
|
408
394
|
|
|
@@ -414,11 +400,11 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
414
400
|
"""Returns (cirq.Qid, cirq.Pauli) pairs representing 1-qubit operations of pauli string."""
|
|
415
401
|
return self._qubit_pauli_map.items()
|
|
416
402
|
|
|
417
|
-
def frozen(self) ->
|
|
403
|
+
def frozen(self) -> cirq.PauliString:
|
|
418
404
|
"""Returns a `cirq.PauliString` with the same contents."""
|
|
419
405
|
return self
|
|
420
406
|
|
|
421
|
-
def mutable_copy(self) ->
|
|
407
|
+
def mutable_copy(self) -> cirq.MutablePauliString:
|
|
422
408
|
"""Returns a new `cirq.MutablePauliString` with the same contents."""
|
|
423
409
|
return MutablePauliString(
|
|
424
410
|
coefficient=self.coefficient,
|
|
@@ -481,7 +467,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
481
467
|
|
|
482
468
|
return prefix + '*'.join(factors)
|
|
483
469
|
|
|
484
|
-
def matrix(self, qubits:
|
|
470
|
+
def matrix(self, qubits: Iterable[TKey] | None = None) -> np.ndarray:
|
|
485
471
|
"""Returns the matrix of self in computational basis of qubits.
|
|
486
472
|
|
|
487
473
|
Args:
|
|
@@ -505,12 +491,12 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
505
491
|
return False
|
|
506
492
|
return abs(1 - abs(cast(complex, self.coefficient))) < 1e-6
|
|
507
493
|
|
|
508
|
-
def _unitary_(self) ->
|
|
494
|
+
def _unitary_(self) -> np.ndarray | None:
|
|
509
495
|
if not self._has_unitary_():
|
|
510
496
|
return None
|
|
511
497
|
return self.matrix()
|
|
512
498
|
|
|
513
|
-
def _apply_unitary_(self, args:
|
|
499
|
+
def _apply_unitary_(self, args: protocols.ApplyUnitaryArgs):
|
|
514
500
|
if not self._has_unitary_():
|
|
515
501
|
return None
|
|
516
502
|
assert isinstance(self.coefficient, numbers.Complex)
|
|
@@ -738,8 +724,8 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
738
724
|
return float(np.real(result * self.coefficient))
|
|
739
725
|
|
|
740
726
|
def zip_items(
|
|
741
|
-
self, other:
|
|
742
|
-
) -> Iterator[
|
|
727
|
+
self, other: cirq.PauliString[TKey]
|
|
728
|
+
) -> Iterator[tuple[TKey, tuple[pauli_gates.Pauli, pauli_gates.Pauli]]]:
|
|
743
729
|
"""Combines pauli operations from pauli strings in a qubit-by-qubit fashion.
|
|
744
730
|
|
|
745
731
|
For every qubit that has a `cirq.Pauli` operation acting on it in both `self` and `other`,
|
|
@@ -757,8 +743,8 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
757
743
|
yield qubit, (pauli0, other[qubit])
|
|
758
744
|
|
|
759
745
|
def zip_paulis(
|
|
760
|
-
self, other:
|
|
761
|
-
) -> Iterator[
|
|
746
|
+
self, other: cirq.PauliString
|
|
747
|
+
) -> Iterator[tuple[pauli_gates.Pauli, pauli_gates.Pauli]]:
|
|
762
748
|
"""Combines pauli operations from pauli strings in a qubit-by-qubit fashion.
|
|
763
749
|
|
|
764
750
|
For every qubit that has a `cirq.Pauli` operation acting on it in both `self` and `other`,
|
|
@@ -773,17 +759,15 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
773
759
|
"""
|
|
774
760
|
return (paulis for qubit, paulis in self.zip_items(other))
|
|
775
761
|
|
|
776
|
-
def _commutes_(
|
|
777
|
-
self, other: Any, *, atol: float = 1e-8
|
|
778
|
-
) -> Union[bool, NotImplementedType, None]:
|
|
762
|
+
def _commutes_(self, other: Any, *, atol: float = 1e-8) -> bool | NotImplementedType | None:
|
|
779
763
|
if not isinstance(other, PauliString):
|
|
780
764
|
return NotImplemented
|
|
781
765
|
return sum(not protocols.commutes(p0, p1) for p0, p1 in self.zip_paulis(other)) % 2 == 0
|
|
782
766
|
|
|
783
|
-
def __neg__(self) ->
|
|
767
|
+
def __neg__(self) -> PauliString:
|
|
784
768
|
return PauliString(qubit_pauli_map=self._qubit_pauli_map, coefficient=-self._coefficient)
|
|
785
769
|
|
|
786
|
-
def __pos__(self) ->
|
|
770
|
+
def __pos__(self) -> PauliString:
|
|
787
771
|
return self
|
|
788
772
|
|
|
789
773
|
def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
|
|
@@ -861,7 +845,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
861
845
|
)
|
|
862
846
|
return NotImplemented
|
|
863
847
|
|
|
864
|
-
def map_qubits(self, qubit_map:
|
|
848
|
+
def map_qubits(self, qubit_map: dict[TKey, TKeyNew]) -> cirq.PauliString[TKeyNew]:
|
|
865
849
|
"""Replaces every qubit `q` in `self.qubits` with `qubit_map[q]`.
|
|
866
850
|
|
|
867
851
|
Args:
|
|
@@ -888,7 +872,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
888
872
|
{pauli: (pauli_gates.Z, False)}
|
|
889
873
|
)(qubit)
|
|
890
874
|
|
|
891
|
-
def dense(self, qubits: Sequence[TKey]) ->
|
|
875
|
+
def dense(self, qubits: Sequence[TKey]) -> cirq.DensePauliString:
|
|
892
876
|
"""Returns a `cirq.DensePauliString` version of this Pauli string.
|
|
893
877
|
|
|
894
878
|
This method satisfies the invariant `P.dense(qubits).on(*qubits) == P`.
|
|
@@ -910,12 +894,10 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
910
894
|
|
|
911
895
|
if not self.keys() <= set(qubits):
|
|
912
896
|
raise ValueError('not self.keys() <= set(qubits)')
|
|
913
|
-
# pylint: disable=too-many-function-args
|
|
914
897
|
pauli_mask = [self.get(q, identity.I) for q in qubits]
|
|
915
|
-
# pylint: enable=too-many-function-args
|
|
916
898
|
return dense_pauli_string.DensePauliString(pauli_mask, coefficient=self.coefficient)
|
|
917
899
|
|
|
918
|
-
def conjugated_by(self, clifford:
|
|
900
|
+
def conjugated_by(self, clifford: cirq.OP_TREE) -> PauliString:
|
|
919
901
|
r"""Returns the Pauli string conjugated by a clifford operation.
|
|
920
902
|
|
|
921
903
|
The product-of-Paulis $P$ conjugated by the Clifford operation $C$ is
|
|
@@ -987,12 +969,12 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
987
969
|
# Then the conjugation = (C^{-1}⊗I·Pc⊗R·C⊗I) = (C^{-1}·Pc·C)⊗R.
|
|
988
970
|
|
|
989
971
|
# Isolate R
|
|
990
|
-
remain:
|
|
972
|
+
remain: cirq.PauliString = PauliString(
|
|
991
973
|
*(pauli(q) for q in all_qubits - set(op.qubits) if (pauli := ps.get(q)) is not None)
|
|
992
974
|
)
|
|
993
975
|
|
|
994
976
|
# Initialize the conjugation of Pc.
|
|
995
|
-
conjugated:
|
|
977
|
+
conjugated: cirq.DensePauliString = (
|
|
996
978
|
dense_pauli_string.DensePauliString(pauli_mask=[identity.I for _ in op.qubits])
|
|
997
979
|
* ps.coefficient
|
|
998
980
|
)
|
|
@@ -1000,7 +982,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
1000
982
|
# Calculate the conjugation via CliffordGate's clifford_tableau.
|
|
1001
983
|
# Note the clifford_tableau in CliffordGate represents C·P·C^-1 instead of C^-1·P·C.
|
|
1002
984
|
# So we take the inverse of the tableau to match the definition of the conjugation here.
|
|
1003
|
-
gate_in_clifford:
|
|
985
|
+
gate_in_clifford: cirq.CliffordGate
|
|
1004
986
|
if isinstance(op.gate, clifford_gate.CliffordGate):
|
|
1005
987
|
gate_in_clifford = op.gate
|
|
1006
988
|
else:
|
|
@@ -1035,7 +1017,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
1035
1017
|
ps = remain * conjugated.on(*op.qubits)
|
|
1036
1018
|
return ps
|
|
1037
1019
|
|
|
1038
|
-
def after(self, ops:
|
|
1020
|
+
def after(self, ops: cirq.OP_TREE) -> cirq.PauliString:
|
|
1039
1021
|
r"""Determines the equivalent pauli string after some operations.
|
|
1040
1022
|
|
|
1041
1023
|
If the PauliString is $P$ and the Clifford operation is $C$, then the
|
|
@@ -1051,7 +1033,7 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
1051
1033
|
"""
|
|
1052
1034
|
return self.conjugated_by(protocols.inverse(ops))
|
|
1053
1035
|
|
|
1054
|
-
def before(self, ops:
|
|
1036
|
+
def before(self, ops: cirq.OP_TREE) -> cirq.PauliString:
|
|
1055
1037
|
r"""Determines the equivalent pauli string before some operations.
|
|
1056
1038
|
|
|
1057
1039
|
If the PauliString is $P$ and the Clifford operation is $C$, then the
|
|
@@ -1067,9 +1049,10 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
1067
1049
|
"""
|
|
1068
1050
|
return self.conjugated_by(ops)
|
|
1069
1051
|
|
|
1052
|
+
@deprecated(deadline="v2.0", fix="Use conjuagetd_by()/before()/after() instead.")
|
|
1070
1053
|
def pass_operations_over(
|
|
1071
|
-
self, ops: Iterable[
|
|
1072
|
-
) ->
|
|
1054
|
+
self, ops: Iterable[cirq.Operation], after_to_before: bool = False
|
|
1055
|
+
) -> PauliString: # pragma: no cover
|
|
1073
1056
|
"""Determines how the Pauli string changes when conjugated by Cliffords.
|
|
1074
1057
|
|
|
1075
1058
|
The output and input pauli strings are related by a circuit equivalence.
|
|
@@ -1096,9 +1079,6 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
1096
1079
|
pauli string, instead of before (and so are moving in the
|
|
1097
1080
|
opposite direction).
|
|
1098
1081
|
"""
|
|
1099
|
-
# TODO(#6946): deprecate this method.
|
|
1100
|
-
# Note: This method is supposed to be replaced by conjugated_by()
|
|
1101
|
-
# (see #2351 for details).
|
|
1102
1082
|
if after_to_before:
|
|
1103
1083
|
return self.after(ops)
|
|
1104
1084
|
|
|
@@ -1115,14 +1095,14 @@ class PauliString(raw_types.Operation, Generic[TKey]):
|
|
|
1115
1095
|
return protocols.parameter_names(self.coefficient)
|
|
1116
1096
|
|
|
1117
1097
|
def _resolve_parameters_(
|
|
1118
|
-
self, resolver:
|
|
1119
|
-
) ->
|
|
1098
|
+
self, resolver: cirq.ParamResolver, recursive: bool
|
|
1099
|
+
) -> cirq.PauliString:
|
|
1120
1100
|
coefficient = protocols.resolve_parameters(self.coefficient, resolver, recursive)
|
|
1121
1101
|
return PauliString(qubit_pauli_map=self._qubit_pauli_map, coefficient=coefficient)
|
|
1122
1102
|
|
|
1123
1103
|
|
|
1124
1104
|
def _validate_qubit_mapping(
|
|
1125
|
-
qubit_map: Mapping[TKey, int], pauli_qubits:
|
|
1105
|
+
qubit_map: Mapping[TKey, int], pauli_qubits: tuple[TKey, ...], num_state_qubits: int
|
|
1126
1106
|
) -> None:
|
|
1127
1107
|
"""Validates that a qubit map is a valid mapping.
|
|
1128
1108
|
|
|
@@ -1189,11 +1169,11 @@ class SingleQubitPauliStringGateOperation( # type: ignore
|
|
|
1189
1169
|
GateOperation(X, [q]).
|
|
1190
1170
|
"""
|
|
1191
1171
|
|
|
1192
|
-
def __init__(self, pauli: pauli_gates.Pauli, qubit:
|
|
1172
|
+
def __init__(self, pauli: pauli_gates.Pauli, qubit: cirq.Qid):
|
|
1193
1173
|
PauliString.__init__(self, qubit_pauli_map={qubit: pauli})
|
|
1194
1174
|
gate_operation.GateOperation.__init__(self, cast(raw_types.Gate, pauli), [qubit])
|
|
1195
1175
|
|
|
1196
|
-
def with_qubits(self, *new_qubits:
|
|
1176
|
+
def with_qubits(self, *new_qubits: cirq.Qid) -> SingleQubitPauliStringGateOperation:
|
|
1197
1177
|
if len(new_qubits) != 1:
|
|
1198
1178
|
raise ValueError("len(new_qubits) != 1")
|
|
1199
1179
|
return SingleQubitPauliStringGateOperation(
|
|
@@ -1231,13 +1211,11 @@ class SingleQubitPauliStringGateOperation( # type: ignore
|
|
|
1231
1211
|
def __neg__(self):
|
|
1232
1212
|
return -self._as_pauli_string()
|
|
1233
1213
|
|
|
1234
|
-
def _json_dict_(self) ->
|
|
1214
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
1235
1215
|
return protocols.obj_to_dict_helper(self, ['pauli', 'qubit'])
|
|
1236
1216
|
|
|
1237
1217
|
@classmethod
|
|
1238
|
-
def _from_json_dict_( # type: ignore
|
|
1239
|
-
cls, pauli: pauli_gates.Pauli, qubit: 'cirq.Qid', **kwargs
|
|
1240
|
-
):
|
|
1218
|
+
def _from_json_dict_(cls, pauli: pauli_gates.Pauli, qubit: cirq.Qid, **kwargs): # type: ignore
|
|
1241
1219
|
# Note, this method is required or else superclasses' deserialization
|
|
1242
1220
|
# would be used
|
|
1243
1221
|
return cls(pauli=pauli, qubit=qubit)
|
|
@@ -1258,9 +1236,9 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1258
1236
|
|
|
1259
1237
|
def __init__(
|
|
1260
1238
|
self,
|
|
1261
|
-
*contents:
|
|
1262
|
-
coefficient:
|
|
1263
|
-
pauli_int_dict:
|
|
1239
|
+
*contents: cirq.PAULI_STRING_LIKE,
|
|
1240
|
+
coefficient: cirq.TParamValComplex = 1,
|
|
1241
|
+
pauli_int_dict: dict[TKey, int] | None = None,
|
|
1264
1242
|
):
|
|
1265
1243
|
"""Initializes a new `MutablePauliString`.
|
|
1266
1244
|
|
|
@@ -1282,14 +1260,14 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1282
1260
|
Raises:
|
|
1283
1261
|
ValueError: If the `pauli_int_dict` has integer values `v` not satisfying `1 <= v <= 3`.
|
|
1284
1262
|
"""
|
|
1285
|
-
self.coefficient:
|
|
1263
|
+
self.coefficient: sympy.Expr | cirq.TParamValComplex = (
|
|
1286
1264
|
coefficient if isinstance(coefficient, sympy.Expr) else complex(coefficient)
|
|
1287
1265
|
)
|
|
1288
1266
|
if pauli_int_dict is not None:
|
|
1289
1267
|
for v in pauli_int_dict.values():
|
|
1290
1268
|
if not 1 <= v <= 3:
|
|
1291
1269
|
raise ValueError(f"Value {v} of pauli_int_dict must be between 1 and 3.")
|
|
1292
|
-
self.pauli_int_dict:
|
|
1270
|
+
self.pauli_int_dict: dict[TKey, int] = {} if pauli_int_dict is None else pauli_int_dict
|
|
1293
1271
|
if contents:
|
|
1294
1272
|
self.inplace_left_multiply_by(contents)
|
|
1295
1273
|
|
|
@@ -1314,7 +1292,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1314
1292
|
"""Returns the sequence of qubits on which this pauli string acts."""
|
|
1315
1293
|
return self.pauli_int_dict.keys()
|
|
1316
1294
|
|
|
1317
|
-
def values(self) -> Iterator[
|
|
1295
|
+
def values(self) -> Iterator[cirq.Pauli]:
|
|
1318
1296
|
"""Ordered sequence of `cirq.Pauli` gates acting on `self.keys()`."""
|
|
1319
1297
|
for v in self.pauli_int_dict.values():
|
|
1320
1298
|
yield _INT_TO_PAULI[v - 1]
|
|
@@ -1328,7 +1306,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1328
1306
|
def __bool__(self) -> bool:
|
|
1329
1307
|
return bool(self.pauli_int_dict)
|
|
1330
1308
|
|
|
1331
|
-
def frozen(self) ->
|
|
1309
|
+
def frozen(self) -> cirq.PauliString:
|
|
1332
1310
|
"""Returns a `cirq.PauliString` with the same contents.
|
|
1333
1311
|
|
|
1334
1312
|
For example, this is useful because `cirq.PauliString` is an operation
|
|
@@ -1339,13 +1317,13 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1339
1317
|
qubit_pauli_map={q: _INT_TO_PAULI[p - 1] for q, p in self.pauli_int_dict.items() if p},
|
|
1340
1318
|
)
|
|
1341
1319
|
|
|
1342
|
-
def mutable_copy(self) ->
|
|
1320
|
+
def mutable_copy(self) -> cirq.MutablePauliString:
|
|
1343
1321
|
"""Returns a new `cirq.MutablePauliString` with the same contents."""
|
|
1344
1322
|
return MutablePauliString(
|
|
1345
1323
|
coefficient=self.coefficient, pauli_int_dict=dict(self.pauli_int_dict)
|
|
1346
1324
|
)
|
|
1347
1325
|
|
|
1348
|
-
def items(self) -> Iterator[
|
|
1326
|
+
def items(self) -> Iterator[tuple[TKey, cirq.Pauli]]:
|
|
1349
1327
|
"""Returns (cirq.Qid, cirq.Pauli) pairs representing 1-qubit operations of pauli string."""
|
|
1350
1328
|
for k, v in self.pauli_int_dict.items():
|
|
1351
1329
|
yield k, _INT_TO_PAULI[v - 1]
|
|
@@ -1353,10 +1331,10 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1353
1331
|
def __contains__(self, item: Any) -> bool:
|
|
1354
1332
|
return item in self.pauli_int_dict
|
|
1355
1333
|
|
|
1356
|
-
def __getitem__(self, item: Any) ->
|
|
1334
|
+
def __getitem__(self, item: Any) -> cirq.Pauli:
|
|
1357
1335
|
return _INT_TO_PAULI[self.pauli_int_dict[item] - 1]
|
|
1358
1336
|
|
|
1359
|
-
def __setitem__(self, key: TKey, value:
|
|
1337
|
+
def __setitem__(self, key: TKey, value: cirq.PAULI_GATE_LIKE):
|
|
1360
1338
|
value = _pauli_like_to_pauli_int(key, value)
|
|
1361
1339
|
if value:
|
|
1362
1340
|
self.pauli_int_dict[key] = _pauli_like_to_pauli_int(key, value)
|
|
@@ -1366,22 +1344,20 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1366
1344
|
def __delitem__(self, key: TKey):
|
|
1367
1345
|
del self.pauli_int_dict[key]
|
|
1368
1346
|
|
|
1369
|
-
# pylint: disable=function-redefined
|
|
1370
1347
|
@overload
|
|
1371
|
-
def get(self, key: TKey, default: None = None) ->
|
|
1348
|
+
def get(self, key: TKey, default: None = None) -> cirq.Pauli | None:
|
|
1372
1349
|
pass
|
|
1373
1350
|
|
|
1374
1351
|
@overload
|
|
1375
|
-
def get(self, key: TKey, default: TDefault) ->
|
|
1352
|
+
def get(self, key: TKey, default: TDefault) -> cirq.Pauli | TDefault:
|
|
1376
1353
|
pass
|
|
1377
1354
|
|
|
1378
|
-
def get(self, key: TKey, default=None) ->
|
|
1355
|
+
def get(self, key: TKey, default=None) -> cirq.Pauli | TDefault | None:
|
|
1379
1356
|
"""Returns the `cirq.Pauli` operation acting on qubit `key` or `default` if none exists."""
|
|
1380
1357
|
result = self.pauli_int_dict.get(key, None)
|
|
1381
1358
|
return default if result is None else _INT_TO_PAULI[result - 1]
|
|
1382
1359
|
|
|
1383
|
-
|
|
1384
|
-
def inplace_before(self, ops: 'cirq.OP_TREE') -> 'cirq.MutablePauliString':
|
|
1360
|
+
def inplace_before(self, ops: cirq.OP_TREE) -> cirq.MutablePauliString:
|
|
1385
1361
|
r"""Propagates the pauli string from after to before a Clifford effect.
|
|
1386
1362
|
|
|
1387
1363
|
If the old value of the MutablePauliString is $P$ and the Clifford
|
|
@@ -1397,7 +1373,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1397
1373
|
"""
|
|
1398
1374
|
return self.inplace_after(protocols.inverse(ops))
|
|
1399
1375
|
|
|
1400
|
-
def inplace_after(self, ops:
|
|
1376
|
+
def inplace_after(self, ops: cirq.OP_TREE) -> cirq.MutablePauliString:
|
|
1401
1377
|
r"""Propagates the pauli string from before to after a Clifford effect.
|
|
1402
1378
|
|
|
1403
1379
|
If the old value of the MutablePauliString is $P$ and the Clifford
|
|
@@ -1453,7 +1429,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1453
1429
|
raise NotImplementedError(f"Unrecognized decomposed Clifford: {op!r}")
|
|
1454
1430
|
return self
|
|
1455
1431
|
|
|
1456
|
-
def _imul_helper(self, other:
|
|
1432
|
+
def _imul_helper(self, other: cirq.PAULI_STRING_LIKE, sign: int):
|
|
1457
1433
|
"""Left-multiplies or right-multiplies by a PAULI_STRING_LIKE.
|
|
1458
1434
|
|
|
1459
1435
|
Args:
|
|
@@ -1492,7 +1468,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1492
1468
|
|
|
1493
1469
|
return self
|
|
1494
1470
|
|
|
1495
|
-
def _imul_helper_checkpoint(self, other:
|
|
1471
|
+
def _imul_helper_checkpoint(self, other: cirq.PAULI_STRING_LIKE, sign: int):
|
|
1496
1472
|
"""Like `_imul_helper` but guarantees no-op on error."""
|
|
1497
1473
|
|
|
1498
1474
|
if not isinstance(other, (numbers.Number, PauliString, MutablePauliString)):
|
|
@@ -1501,9 +1477,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1501
1477
|
return NotImplemented
|
|
1502
1478
|
return self._imul_helper(other, sign)
|
|
1503
1479
|
|
|
1504
|
-
def inplace_left_multiply_by(
|
|
1505
|
-
self, other: 'cirq.PAULI_STRING_LIKE'
|
|
1506
|
-
) -> 'cirq.MutablePauliString':
|
|
1480
|
+
def inplace_left_multiply_by(self, other: cirq.PAULI_STRING_LIKE) -> cirq.MutablePauliString:
|
|
1507
1481
|
"""Left-multiplies a pauli string into this pauli string.
|
|
1508
1482
|
|
|
1509
1483
|
Args:
|
|
@@ -1521,7 +1495,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1521
1495
|
raise TypeError(f"{other!r} is not cirq.PAULI_STRING_LIKE.")
|
|
1522
1496
|
return self
|
|
1523
1497
|
|
|
1524
|
-
def _json_dict_(self) ->
|
|
1498
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
1525
1499
|
return {
|
|
1526
1500
|
# JSON requires mappings to have string keys.
|
|
1527
1501
|
'pauli_int_dict': list(self.pauli_int_dict.items()),
|
|
@@ -1532,9 +1506,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1532
1506
|
def _from_json_dict_(cls, pauli_int_dict, coefficient, **kwargs):
|
|
1533
1507
|
return cls(pauli_int_dict=dict(pauli_int_dict), coefficient=coefficient)
|
|
1534
1508
|
|
|
1535
|
-
def inplace_right_multiply_by(
|
|
1536
|
-
self, other: 'cirq.PAULI_STRING_LIKE'
|
|
1537
|
-
) -> 'cirq.MutablePauliString':
|
|
1509
|
+
def inplace_right_multiply_by(self, other: cirq.PAULI_STRING_LIKE) -> cirq.MutablePauliString:
|
|
1538
1510
|
"""Right-multiplies a pauli string into this pauli string.
|
|
1539
1511
|
|
|
1540
1512
|
Args:
|
|
@@ -1552,17 +1524,17 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1552
1524
|
raise TypeError(f"{other!r} is not cirq.PAULI_STRING_LIKE.")
|
|
1553
1525
|
return self
|
|
1554
1526
|
|
|
1555
|
-
def __neg__(self) ->
|
|
1527
|
+
def __neg__(self) -> cirq.MutablePauliString:
|
|
1556
1528
|
result = self.mutable_copy()
|
|
1557
1529
|
result.coefficient *= -1
|
|
1558
1530
|
return result
|
|
1559
1531
|
|
|
1560
|
-
def __pos__(self) ->
|
|
1532
|
+
def __pos__(self) -> cirq.MutablePauliString:
|
|
1561
1533
|
return self.mutable_copy()
|
|
1562
1534
|
|
|
1563
1535
|
def transform_qubits(
|
|
1564
1536
|
self, func: Callable[[TKey], TKeyNew], *, inplace: bool = False
|
|
1565
|
-
) ->
|
|
1537
|
+
) -> cirq.MutablePauliString[TKeyNew]:
|
|
1566
1538
|
"""Returns a `MutablePauliString` with transformed qubits.
|
|
1567
1539
|
|
|
1568
1540
|
Args:
|
|
@@ -1585,7 +1557,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1585
1557
|
result.pauli_int_dict = new_dict
|
|
1586
1558
|
return result
|
|
1587
1559
|
|
|
1588
|
-
def __imul__(self, other:
|
|
1560
|
+
def __imul__(self, other: cirq.PAULI_STRING_LIKE) -> cirq.MutablePauliString:
|
|
1589
1561
|
"""Left-multiplies a pauli string into this pauli string.
|
|
1590
1562
|
|
|
1591
1563
|
Args:
|
|
@@ -1601,14 +1573,14 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1601
1573
|
"""
|
|
1602
1574
|
return self._imul_helper_checkpoint(other, +1)
|
|
1603
1575
|
|
|
1604
|
-
def __mul__(self, other:
|
|
1576
|
+
def __mul__(self, other: cirq.PAULI_STRING_LIKE) -> cirq.PauliString:
|
|
1605
1577
|
"""Multiplies two pauli-string-likes together.
|
|
1606
1578
|
|
|
1607
1579
|
The result is not mutable.
|
|
1608
1580
|
"""
|
|
1609
1581
|
return self.frozen() * other
|
|
1610
1582
|
|
|
1611
|
-
def __rmul__(self, other:
|
|
1583
|
+
def __rmul__(self, other: cirq.PAULI_STRING_LIKE) -> cirq.PauliString:
|
|
1612
1584
|
"""Multiplies two pauli-string-likes together.
|
|
1613
1585
|
|
|
1614
1586
|
The result is not mutable.
|
|
@@ -1622,7 +1594,7 @@ class MutablePauliString(Generic[TKey]):
|
|
|
1622
1594
|
return f'{self.frozen()!r}.mutable_copy()'
|
|
1623
1595
|
|
|
1624
1596
|
|
|
1625
|
-
def _decompose_into_cliffords(op:
|
|
1597
|
+
def _decompose_into_cliffords(op: cirq.Operation) -> list[cirq.Operation]:
|
|
1626
1598
|
# An operation that can be ignored?
|
|
1627
1599
|
if isinstance(op.gate, global_phase_op.GlobalPhaseGate):
|
|
1628
1600
|
return []
|
|
@@ -1657,7 +1629,7 @@ _x = cast(pauli_gates.Pauli, pauli_gates.X) # type: ignore
|
|
|
1657
1629
|
_y = cast(pauli_gates.Pauli, pauli_gates.Y) # type: ignore
|
|
1658
1630
|
_z = cast(pauli_gates.Pauli, pauli_gates.Z) # type: ignore
|
|
1659
1631
|
|
|
1660
|
-
PAULI_GATE_LIKE_TO_INDEX_MAP:
|
|
1632
|
+
PAULI_GATE_LIKE_TO_INDEX_MAP: dict[cirq.PAULI_GATE_LIKE, int] = {
|
|
1661
1633
|
_i: 0,
|
|
1662
1634
|
_x: 1,
|
|
1663
1635
|
_y: 2,
|
|
@@ -1676,13 +1648,13 @@ PAULI_GATE_LIKE_TO_INDEX_MAP: Dict['cirq.PAULI_GATE_LIKE', int] = {
|
|
|
1676
1648
|
3: 3,
|
|
1677
1649
|
}
|
|
1678
1650
|
|
|
1679
|
-
_INT_TO_PAULI_OR_IDENTITY:
|
|
1680
|
-
_INT_TO_PAULI:
|
|
1651
|
+
_INT_TO_PAULI_OR_IDENTITY: list[cirq.Pauli | cirq.IdentityGate] = [_i, _x, _y, _z]
|
|
1652
|
+
_INT_TO_PAULI: list[cirq.Pauli] = [_x, _y, _z]
|
|
1681
1653
|
|
|
1682
1654
|
|
|
1683
|
-
PAULI_GATE_LIKE_TO_GATE_MAP:
|
|
1684
|
-
|
|
1685
|
-
|
|
1655
|
+
PAULI_GATE_LIKE_TO_GATE_MAP: dict[cirq.PAULI_GATE_LIKE, cirq.Pauli | cirq.IdentityGate] = {
|
|
1656
|
+
k: _INT_TO_PAULI_OR_IDENTITY[v] for k, v in PAULI_GATE_LIKE_TO_INDEX_MAP.items()
|
|
1657
|
+
}
|
|
1686
1658
|
|
|
1687
1659
|
|
|
1688
1660
|
def _pauli_like_to_pauli_int(key: Any, pauli_gate_like: PAULI_GATE_LIKE):
|