cirq-core 1.5.0.dev20250409225226__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.dev20250409225226.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.dev20250409225226.dist-info → cirq_core-1.6.0.dist-info}/WHEEL +1 -1
- cirq_core-1.5.0.dev20250409225226.dist-info/RECORD +0 -1216
- {cirq_core-1.5.0.dev20250409225226.dist-info → cirq_core-1.6.0.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.5.0.dev20250409225226.dist-info → cirq_core-1.6.0.dist-info}/top_level.txt +0 -0
cirq/ops/pauli_string_phasor.py
CHANGED
|
@@ -12,23 +12,13 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
import
|
|
16
|
-
from typing import (
|
|
17
|
-
AbstractSet,
|
|
18
|
-
cast,
|
|
19
|
-
Dict,
|
|
20
|
-
Iterable,
|
|
21
|
-
Iterator,
|
|
22
|
-
Optional,
|
|
23
|
-
Sequence,
|
|
24
|
-
TYPE_CHECKING,
|
|
25
|
-
Union,
|
|
26
|
-
)
|
|
15
|
+
from __future__ import annotations
|
|
27
16
|
|
|
28
|
-
import
|
|
17
|
+
import numbers
|
|
18
|
+
from typing import AbstractSet, cast, Iterable, Iterator, Sequence, TYPE_CHECKING
|
|
29
19
|
|
|
30
20
|
from cirq import protocols, value
|
|
31
|
-
from cirq._compat import proper_repr
|
|
21
|
+
from cirq._compat import deprecated, proper_repr
|
|
32
22
|
from cirq.ops import (
|
|
33
23
|
common_gates,
|
|
34
24
|
dense_pauli_string as dps,
|
|
@@ -40,6 +30,8 @@ from cirq.ops import (
|
|
|
40
30
|
)
|
|
41
31
|
|
|
42
32
|
if TYPE_CHECKING:
|
|
33
|
+
import sympy
|
|
34
|
+
|
|
43
35
|
import cirq
|
|
44
36
|
|
|
45
37
|
|
|
@@ -63,10 +55,10 @@ class PauliStringPhasor(gate_operation.GateOperation):
|
|
|
63
55
|
def __init__(
|
|
64
56
|
self,
|
|
65
57
|
pauli_string: ps.PauliString,
|
|
66
|
-
qubits:
|
|
58
|
+
qubits: Sequence[cirq.Qid] | None = None,
|
|
67
59
|
*,
|
|
68
|
-
exponent_neg:
|
|
69
|
-
exponent_pos:
|
|
60
|
+
exponent_neg: cirq.TParamVal = 1,
|
|
61
|
+
exponent_pos: cirq.TParamVal = 0,
|
|
70
62
|
) -> None:
|
|
71
63
|
"""Initializes the operation.
|
|
72
64
|
|
|
@@ -106,34 +98,34 @@ class PauliStringPhasor(gate_operation.GateOperation):
|
|
|
106
98
|
self._pauli_string = gate.dense_pauli_string.on(*self.qubits)
|
|
107
99
|
|
|
108
100
|
@property
|
|
109
|
-
def gate(self) ->
|
|
101
|
+
def gate(self) -> cirq.PauliStringPhasorGate:
|
|
110
102
|
"""The gate applied by the operation."""
|
|
111
103
|
return cast(PauliStringPhasorGate, self._gate)
|
|
112
104
|
|
|
113
105
|
@property
|
|
114
|
-
def exponent_neg(self) ->
|
|
106
|
+
def exponent_neg(self) -> cirq.TParamVal:
|
|
115
107
|
"""The negative exponent."""
|
|
116
108
|
return self.gate.exponent_neg
|
|
117
109
|
|
|
118
110
|
@property
|
|
119
|
-
def exponent_pos(self) ->
|
|
111
|
+
def exponent_pos(self) -> cirq.TParamVal:
|
|
120
112
|
"""The positive exponent."""
|
|
121
113
|
return self.gate.exponent_pos
|
|
122
114
|
|
|
123
115
|
@property
|
|
124
|
-
def pauli_string(self) ->
|
|
116
|
+
def pauli_string(self) -> cirq.PauliString:
|
|
125
117
|
"""The underlying pauli string."""
|
|
126
118
|
return self._pauli_string
|
|
127
119
|
|
|
128
120
|
@property
|
|
129
|
-
def exponent_relative(self) ->
|
|
121
|
+
def exponent_relative(self) -> cirq.TParamVal:
|
|
130
122
|
"""The relative exponent between negative and positive exponents."""
|
|
131
123
|
return self.gate.exponent_relative
|
|
132
124
|
|
|
133
125
|
def _value_equality_values_(self):
|
|
134
126
|
return (self.pauli_string, self.qubits, self.exponent_neg, self.exponent_pos)
|
|
135
127
|
|
|
136
|
-
def equal_up_to_global_phase(self, other:
|
|
128
|
+
def equal_up_to_global_phase(self, other: PauliStringPhasor) -> bool:
|
|
137
129
|
"""Checks equality of two PauliStringPhasors, up to global phase."""
|
|
138
130
|
if isinstance(other, PauliStringPhasor):
|
|
139
131
|
return (
|
|
@@ -143,7 +135,7 @@ class PauliStringPhasor(gate_operation.GateOperation):
|
|
|
143
135
|
)
|
|
144
136
|
return False
|
|
145
137
|
|
|
146
|
-
def map_qubits(self, qubit_map:
|
|
138
|
+
def map_qubits(self, qubit_map: dict[raw_types.Qid, raw_types.Qid]) -> PauliStringPhasor:
|
|
147
139
|
"""Maps the qubits inside the PauliStringPhasor.
|
|
148
140
|
|
|
149
141
|
Args:
|
|
@@ -168,13 +160,13 @@ class PauliStringPhasor(gate_operation.GateOperation):
|
|
|
168
160
|
exponent_pos=self.exponent_pos,
|
|
169
161
|
)
|
|
170
162
|
|
|
171
|
-
def can_merge_with(self, op:
|
|
163
|
+
def can_merge_with(self, op: PauliStringPhasor) -> bool:
|
|
172
164
|
"""Checks whether the underlying PauliStrings can be merged."""
|
|
173
165
|
return (
|
|
174
166
|
self.pauli_string.equal_up_to_coefficient(op.pauli_string) and self.qubits == op.qubits
|
|
175
167
|
)
|
|
176
168
|
|
|
177
|
-
def merged_with(self, op:
|
|
169
|
+
def merged_with(self, op: PauliStringPhasor) -> PauliStringPhasor:
|
|
178
170
|
"""Merges two PauliStringPhasors."""
|
|
179
171
|
if not self.can_merge_with(op):
|
|
180
172
|
raise ValueError(f'Cannot merge operations: {self}, {op}')
|
|
@@ -184,9 +176,7 @@ class PauliStringPhasor(gate_operation.GateOperation):
|
|
|
184
176
|
self.pauli_string, qubits=self.qubits, exponent_pos=pp, exponent_neg=pn
|
|
185
177
|
)
|
|
186
178
|
|
|
187
|
-
def _circuit_diagram_info_(
|
|
188
|
-
self, args: 'cirq.CircuitDiagramInfoArgs'
|
|
189
|
-
) -> 'cirq.CircuitDiagramInfo':
|
|
179
|
+
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
190
180
|
qubits = self.qubits if args.known_qubits is None else args.known_qubits
|
|
191
181
|
if not qubits:
|
|
192
182
|
return NotImplemented
|
|
@@ -199,9 +189,21 @@ class PauliStringPhasor(gate_operation.GateOperation):
|
|
|
199
189
|
syms = tuple(sym(qubit) for qubit in qubits)
|
|
200
190
|
return protocols.CircuitDiagramInfo(wire_symbols=syms, exponent=self.exponent_relative)
|
|
201
191
|
|
|
192
|
+
def conjugated_by(self, clifford: cirq.OP_TREE) -> PauliStringPhasor:
|
|
193
|
+
r"""Returns the Pauli string conjugated by a clifford operation.
|
|
194
|
+
|
|
195
|
+
The PauliStringPhasor $P$ conjugated by the Clifford operation $C$ is
|
|
196
|
+
$C^\dagger P C$.
|
|
197
|
+
"""
|
|
198
|
+
new_pauli_string: ps.PauliString = self.pauli_string.conjugated_by(clifford)
|
|
199
|
+
pp = self.exponent_pos
|
|
200
|
+
pn = self.exponent_neg
|
|
201
|
+
return PauliStringPhasor(new_pauli_string, exponent_pos=pp, exponent_neg=pn)
|
|
202
|
+
|
|
203
|
+
@deprecated(deadline="v2.0", fix="Use conjuagetd_by() instead.")
|
|
202
204
|
def pass_operations_over(
|
|
203
205
|
self, ops: Iterable[raw_types.Operation], after_to_before: bool = False
|
|
204
|
-
) ->
|
|
206
|
+
) -> PauliStringPhasor: # pragma: no cover
|
|
205
207
|
"""Determines how the Pauli phasor changes when conjugated by Cliffords.
|
|
206
208
|
|
|
207
209
|
The output and input pauli phasors are related by a circuit equivalence.
|
|
@@ -228,7 +230,12 @@ class PauliStringPhasor(gate_operation.GateOperation):
|
|
|
228
230
|
pauli string, instead of before (and so are moving in the
|
|
229
231
|
opposite direction).
|
|
230
232
|
"""
|
|
231
|
-
new_pauli_string =
|
|
233
|
+
new_pauli_string: ps.PauliString = ps.PauliString()
|
|
234
|
+
if after_to_before:
|
|
235
|
+
new_pauli_string = self.pauli_string.after(ops)
|
|
236
|
+
else:
|
|
237
|
+
all_ops = list(op_tree.flatten_to_ops(ops))
|
|
238
|
+
new_pauli_string = self.pauli_string.before(all_ops[::-1])
|
|
232
239
|
pp = self.exponent_pos
|
|
233
240
|
pn = self.exponent_neg
|
|
234
241
|
return PauliStringPhasor(new_pauli_string, exponent_pos=pp, exponent_neg=pn)
|
|
@@ -277,8 +284,8 @@ class PauliStringPhasorGate(raw_types.Gate):
|
|
|
277
284
|
self,
|
|
278
285
|
dense_pauli_string: dps.DensePauliString,
|
|
279
286
|
*,
|
|
280
|
-
exponent_neg:
|
|
281
|
-
exponent_pos:
|
|
287
|
+
exponent_neg: cirq.TParamVal = 1,
|
|
288
|
+
exponent_pos: cirq.TParamVal = 0,
|
|
282
289
|
) -> None:
|
|
283
290
|
"""Initializes the PauliStringPhasorGate.
|
|
284
291
|
|
|
@@ -308,29 +315,29 @@ class PauliStringPhasorGate(raw_types.Gate):
|
|
|
308
315
|
self._exponent_pos = value.canonicalize_half_turns(exponent_pos)
|
|
309
316
|
|
|
310
317
|
@property
|
|
311
|
-
def exponent_relative(self) ->
|
|
318
|
+
def exponent_relative(self) -> cirq.TParamVal:
|
|
312
319
|
"""The relative exponent between negative and positive exponents."""
|
|
313
320
|
return value.canonicalize_half_turns(self.exponent_neg - self.exponent_pos)
|
|
314
321
|
|
|
315
322
|
@property
|
|
316
|
-
def exponent_neg(self) ->
|
|
323
|
+
def exponent_neg(self) -> cirq.TParamVal:
|
|
317
324
|
"""The negative exponent."""
|
|
318
325
|
return self._exponent_neg
|
|
319
326
|
|
|
320
327
|
@property
|
|
321
|
-
def exponent_pos(self) ->
|
|
328
|
+
def exponent_pos(self) -> cirq.TParamVal:
|
|
322
329
|
"""The positive exponent."""
|
|
323
330
|
return self._exponent_pos
|
|
324
331
|
|
|
325
332
|
@property
|
|
326
|
-
def dense_pauli_string(self) ->
|
|
333
|
+
def dense_pauli_string(self) -> cirq.DensePauliString:
|
|
327
334
|
"""The underlying DensePauliString."""
|
|
328
335
|
return self._dense_pauli_string
|
|
329
336
|
|
|
330
337
|
def _value_equality_values_(self):
|
|
331
338
|
return (self.dense_pauli_string, self.exponent_neg, self.exponent_pos)
|
|
332
339
|
|
|
333
|
-
def equal_up_to_global_phase(self, other:
|
|
340
|
+
def equal_up_to_global_phase(self, other: cirq.PauliStringPhasorGate) -> bool:
|
|
334
341
|
"""Checks equality of two PauliStringPhasors, up to global phase."""
|
|
335
342
|
if isinstance(other, PauliStringPhasorGate):
|
|
336
343
|
rel1 = self.exponent_relative
|
|
@@ -338,7 +345,7 @@ class PauliStringPhasorGate(raw_types.Gate):
|
|
|
338
345
|
return rel1 == rel2 and self.dense_pauli_string == other.dense_pauli_string
|
|
339
346
|
return False
|
|
340
347
|
|
|
341
|
-
def __pow__(self, exponent:
|
|
348
|
+
def __pow__(self, exponent: float | sympy.Symbol) -> PauliStringPhasorGate:
|
|
342
349
|
pn = protocols.mul(self.exponent_neg, exponent, None)
|
|
343
350
|
pp = protocols.mul(self.exponent_pos, exponent, None)
|
|
344
351
|
if pn is None or pp is None:
|
|
@@ -348,11 +355,11 @@ class PauliStringPhasorGate(raw_types.Gate):
|
|
|
348
355
|
def _has_unitary_(self) -> bool:
|
|
349
356
|
return not self._is_parameterized_()
|
|
350
357
|
|
|
351
|
-
def _to_z_basis_ops(self, qubits: Sequence[
|
|
358
|
+
def _to_z_basis_ops(self, qubits: Sequence[cirq.Qid]) -> Iterator[raw_types.Operation]:
|
|
352
359
|
"""Returns operations to convert the qubits to the computational basis."""
|
|
353
360
|
return self.dense_pauli_string.on(*qubits).to_z_basis_ops()
|
|
354
361
|
|
|
355
|
-
def _decompose_(self, qubits: Sequence[
|
|
362
|
+
def _decompose_(self, qubits: Sequence[cirq.Qid]) -> Iterator[cirq.OP_TREE]:
|
|
356
363
|
if len(self.dense_pauli_string) <= 0:
|
|
357
364
|
return
|
|
358
365
|
any_qubit = qubits[0]
|
|
@@ -387,8 +394,8 @@ class PauliStringPhasorGate(raw_types.Gate):
|
|
|
387
394
|
)
|
|
388
395
|
|
|
389
396
|
def _resolve_parameters_(
|
|
390
|
-
self, resolver:
|
|
391
|
-
) ->
|
|
397
|
+
self, resolver: cirq.ParamResolver, recursive: bool
|
|
398
|
+
) -> PauliStringPhasorGate:
|
|
392
399
|
exponent_neg = resolver.value_of(self.exponent_neg, recursive)
|
|
393
400
|
exponent_pos = resolver.value_of(self.exponent_pos, recursive)
|
|
394
401
|
if isinstance(exponent_neg, numbers.Complex):
|
|
@@ -427,7 +434,7 @@ class PauliStringPhasorGate(raw_types.Gate):
|
|
|
427
434
|
"""The number of qubits for the gate."""
|
|
428
435
|
return len(self.dense_pauli_string)
|
|
429
436
|
|
|
430
|
-
def on(self, *qubits:
|
|
437
|
+
def on(self, *qubits: cirq.Qid) -> cirq.PauliStringPhasor:
|
|
431
438
|
"""Creates a PauliStringPhasor on the qubits."""
|
|
432
439
|
return PauliStringPhasor(
|
|
433
440
|
self.dense_pauli_string.on(*qubits),
|
|
@@ -443,7 +450,7 @@ class PauliStringPhasorGate(raw_types.Gate):
|
|
|
443
450
|
|
|
444
451
|
|
|
445
452
|
def xor_nonlocal_decompose(
|
|
446
|
-
qubits: Iterable[raw_types.Qid], onto_qubit:
|
|
453
|
+
qubits: Iterable[raw_types.Qid], onto_qubit: cirq.Qid
|
|
447
454
|
) -> Iterable[raw_types.Operation]:
|
|
448
455
|
"""Decomposition ignores connectivity."""
|
|
449
456
|
for qubit in qubits:
|
|
@@ -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 itertools
|
|
16
18
|
|
|
17
19
|
import numpy as np
|
|
@@ -155,7 +157,7 @@ def test_consistent():
|
|
|
155
157
|
cirq.testing.assert_implements_consistent_protocols(p)
|
|
156
158
|
|
|
157
159
|
|
|
158
|
-
def
|
|
160
|
+
def test_conjugated_by():
|
|
159
161
|
q0, q1 = _make_qubits(2)
|
|
160
162
|
op = cirq.SingleQubitCliffordGate.from_double_map(
|
|
161
163
|
{cirq.Z: (cirq.X, False), cirq.X: (cirq.Z, False)}
|
|
@@ -164,10 +166,7 @@ def test_pass_operations_over():
|
|
|
164
166
|
ps_after = cirq.PauliString({q0: cirq.Z, q1: cirq.Y}, -1)
|
|
165
167
|
before = cirq.PauliStringPhasor(ps_before, exponent_neg=0.1)
|
|
166
168
|
after = cirq.PauliStringPhasor(ps_after, exponent_neg=0.1)
|
|
167
|
-
assert before.
|
|
168
|
-
assert (
|
|
169
|
-
after.pass_operations_over([op], after_to_before=True).pauli_string == before.pauli_string
|
|
170
|
-
)
|
|
169
|
+
assert before.conjugated_by(op).pauli_string == after.pauli_string
|
|
171
170
|
|
|
172
171
|
|
|
173
172
|
def test_extrapolate_effect():
|
|
@@ -12,8 +12,10 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import abc
|
|
16
|
-
from typing import Any,
|
|
18
|
+
from typing import Any, Sequence, TYPE_CHECKING
|
|
17
19
|
|
|
18
20
|
from typing_extensions import Self
|
|
19
21
|
|
|
@@ -29,19 +31,19 @@ class PauliStringGateOperation(raw_types.Operation, metaclass=abc.ABCMeta):
|
|
|
29
31
|
self._pauli_string = pauli_string
|
|
30
32
|
|
|
31
33
|
@property
|
|
32
|
-
def pauli_string(self) ->
|
|
34
|
+
def pauli_string(self) -> cirq.PauliString:
|
|
33
35
|
return self._pauli_string
|
|
34
36
|
|
|
35
37
|
def validate_args(self, qubits: Sequence[raw_types.Qid]) -> None:
|
|
36
38
|
if len(qubits) != len(self.pauli_string):
|
|
37
39
|
raise ValueError('Incorrect number of qubits for gate')
|
|
38
40
|
|
|
39
|
-
def with_qubits(self, *new_qubits:
|
|
41
|
+
def with_qubits(self, *new_qubits: cirq.Qid) -> Self:
|
|
40
42
|
self.validate_args(new_qubits)
|
|
41
43
|
return self.map_qubits(dict(zip(self.pauli_string.qubits, new_qubits)))
|
|
42
44
|
|
|
43
45
|
@abc.abstractmethod
|
|
44
|
-
def map_qubits(self, qubit_map:
|
|
46
|
+
def map_qubits(self, qubit_map: dict[raw_types.Qid, raw_types.Qid]) -> Self:
|
|
45
47
|
"""Return an equivalent operation on new qubits with its Pauli string
|
|
46
48
|
mapped to new qubits.
|
|
47
49
|
|
|
@@ -49,12 +51,12 @@ class PauliStringGateOperation(raw_types.Operation, metaclass=abc.ABCMeta):
|
|
|
49
51
|
"""
|
|
50
52
|
|
|
51
53
|
@property
|
|
52
|
-
def qubits(self) ->
|
|
54
|
+
def qubits(self) -> tuple[raw_types.Qid, ...]:
|
|
53
55
|
return tuple(self.pauli_string)
|
|
54
56
|
|
|
55
57
|
def _pauli_string_diagram_info(
|
|
56
|
-
self, args:
|
|
57
|
-
) ->
|
|
58
|
+
self, args: protocols.CircuitDiagramInfoArgs, exponent: Any = 1
|
|
59
|
+
) -> cirq.CircuitDiagramInfo:
|
|
58
60
|
qubits = self.qubits if args.known_qubits is None else args.known_qubits
|
|
59
61
|
syms = tuple(f'[{self.pauli_string[qubit]}]' for qubit in qubits)
|
|
60
62
|
return protocols.CircuitDiagramInfo(wire_symbols=syms, exponent=exponent)
|
cirq/ops/pauli_string_test.py
CHANGED
|
@@ -12,9 +12,10 @@
|
|
|
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 itertools
|
|
16
18
|
import math
|
|
17
|
-
from typing import List
|
|
18
19
|
|
|
19
20
|
import numpy as np
|
|
20
21
|
import pytest
|
|
@@ -336,9 +337,7 @@ def test_get(qubit_pauli_map):
|
|
|
336
337
|
assert qubit_pauli_map.get(key) == pauli_string.get(key)
|
|
337
338
|
assert qubit_pauli_map.get(other) is None
|
|
338
339
|
assert pauli_string.get(other) is None
|
|
339
|
-
# pylint: disable=too-many-function-args
|
|
340
340
|
assert qubit_pauli_map.get(other, 5) == pauli_string.get(other, 5) == 5
|
|
341
|
-
# pylint: enable=too-many-function-args
|
|
342
341
|
|
|
343
342
|
|
|
344
343
|
@pytest.mark.parametrize('qubit_pauli_map', _sample_qubit_pauli_maps())
|
|
@@ -723,118 +722,6 @@ def test_to_z_basis_ops_product_state():
|
|
|
723
722
|
)
|
|
724
723
|
|
|
725
724
|
|
|
726
|
-
def _assert_pass_over(ops: List[cirq.Operation], before: cirq.PauliString, after: cirq.PauliString):
|
|
727
|
-
assert before.pass_operations_over(ops[::-1]) == after
|
|
728
|
-
assert after.pass_operations_over(ops, after_to_before=True) == before
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
@pytest.mark.parametrize('shift,sign', itertools.product(range(3), (-1, +1)))
|
|
732
|
-
def test_pass_operations_over_single(shift: int, sign: int):
|
|
733
|
-
q0, q1 = _make_qubits(2)
|
|
734
|
-
X, Y, Z = (cirq.Pauli.by_relative_index(pauli, shift) for pauli in (cirq.X, cirq.Y, cirq.Z))
|
|
735
|
-
|
|
736
|
-
op0 = cirq.SingleQubitCliffordGate.from_pauli(Y)(q1)
|
|
737
|
-
ps_before: cirq.PauliString[cirq.Qid] = cirq.PauliString({q0: X}, sign)
|
|
738
|
-
ps_after = ps_before
|
|
739
|
-
_assert_pass_over([op0], ps_before, ps_after)
|
|
740
|
-
|
|
741
|
-
op0 = cirq.SingleQubitCliffordGate.from_pauli(X)(q0)
|
|
742
|
-
op1 = cirq.SingleQubitCliffordGate.from_pauli(Y)(q1)
|
|
743
|
-
ps_before = cirq.PauliString({q0: X, q1: Y}, sign)
|
|
744
|
-
ps_after = ps_before
|
|
745
|
-
_assert_pass_over([op0, op1], ps_before, ps_after)
|
|
746
|
-
|
|
747
|
-
op0 = cirq.SingleQubitCliffordGate.from_double_map({Z: (X, False), X: (Z, False)})(q0)
|
|
748
|
-
ps_before = cirq.PauliString({q0: X, q1: Y}, sign)
|
|
749
|
-
ps_after = cirq.PauliString({q0: Z, q1: Y}, sign)
|
|
750
|
-
_assert_pass_over([op0], ps_before, ps_after)
|
|
751
|
-
|
|
752
|
-
op1 = cirq.SingleQubitCliffordGate.from_pauli(X)(q1)
|
|
753
|
-
ps_before = cirq.PauliString({q0: X, q1: Y}, sign)
|
|
754
|
-
ps_after = -ps_before
|
|
755
|
-
_assert_pass_over([op1], ps_before, ps_after)
|
|
756
|
-
|
|
757
|
-
ps_after = cirq.PauliString({q0: Z, q1: Y}, -sign)
|
|
758
|
-
_assert_pass_over([op0, op1], ps_before, ps_after)
|
|
759
|
-
|
|
760
|
-
op0 = cirq.SingleQubitCliffordGate.from_pauli(Z, True)(q0)
|
|
761
|
-
op1 = cirq.SingleQubitCliffordGate.from_pauli(X, True)(q0)
|
|
762
|
-
ps_before = cirq.PauliString({q0: X}, sign)
|
|
763
|
-
ps_after = cirq.PauliString({q0: Y}, -sign)
|
|
764
|
-
_assert_pass_over([op0, op1], ps_before, ps_after)
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
@pytest.mark.parametrize(
|
|
768
|
-
'shift,t_or_f1, t_or_f2,neg', itertools.product(range(3), *((True, False),) * 3)
|
|
769
|
-
)
|
|
770
|
-
def test_pass_operations_over_double(shift: int, t_or_f1: bool, t_or_f2: bool, neg: bool):
|
|
771
|
-
sign = -1 if neg else +1
|
|
772
|
-
q0, q1, q2 = _make_qubits(3)
|
|
773
|
-
X, Y, Z = (cirq.Pauli.by_relative_index(pauli, shift) for pauli in (cirq.X, cirq.Y, cirq.Z))
|
|
774
|
-
|
|
775
|
-
op0 = cirq.PauliInteractionGate(Z, t_or_f1, X, t_or_f2)(q0, q1)
|
|
776
|
-
ps_before = cirq.PauliString(qubit_pauli_map={q0: Z, q2: Y}, coefficient=sign)
|
|
777
|
-
ps_after = cirq.PauliString(qubit_pauli_map={q0: Z, q2: Y}, coefficient=sign)
|
|
778
|
-
assert_conjugation(ps_before, op0, ps_after, True)
|
|
779
|
-
_assert_pass_over([op0], ps_before, ps_after)
|
|
780
|
-
|
|
781
|
-
op0 = cirq.PauliInteractionGate(Y, t_or_f1, X, t_or_f2)(q0, q1)
|
|
782
|
-
ps_before = cirq.PauliString({q0: Z, q2: Y}, sign)
|
|
783
|
-
ps_after = cirq.PauliString({q0: Z, q2: Y, q1: X}, -sign if t_or_f2 else sign)
|
|
784
|
-
assert_conjugation(ps_before, op0, ps_after, True)
|
|
785
|
-
_assert_pass_over([op0], ps_before, ps_after)
|
|
786
|
-
|
|
787
|
-
op0 = cirq.PauliInteractionGate(Z, t_or_f1, X, t_or_f2)(q0, q1)
|
|
788
|
-
ps_before = cirq.PauliString({q0: Z, q1: Y}, sign)
|
|
789
|
-
ps_after = cirq.PauliString({q1: Y}, -sign if t_or_f1 else sign)
|
|
790
|
-
assert_conjugation(ps_before, op0, ps_after, True)
|
|
791
|
-
_assert_pass_over([op0], ps_before, ps_after)
|
|
792
|
-
|
|
793
|
-
op0 = cirq.PauliInteractionGate(Y, t_or_f1, X, t_or_f2)(q0, q1)
|
|
794
|
-
ps_before = cirq.PauliString({q0: Z, q1: Y}, sign)
|
|
795
|
-
ps_after = cirq.PauliString({q0: X, q1: Z}, -1 if neg ^ t_or_f1 ^ t_or_f2 else +1)
|
|
796
|
-
assert_conjugation(ps_before, op0, ps_after, True)
|
|
797
|
-
_assert_pass_over([op0], ps_before, ps_after)
|
|
798
|
-
|
|
799
|
-
op0 = cirq.PauliInteractionGate(X, t_or_f1, X, t_or_f2)(q0, q1)
|
|
800
|
-
ps_before = cirq.PauliString({q0: Z, q1: Y}, sign)
|
|
801
|
-
ps_after = cirq.PauliString({q0: Y, q1: Z}, +1 if neg ^ t_or_f1 ^ t_or_f2 else -1)
|
|
802
|
-
assert_conjugation(ps_before, op0, ps_after, True)
|
|
803
|
-
_assert_pass_over([op0], ps_before, ps_after)
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
def test_pass_operations_over_cz():
|
|
807
|
-
q0, q1 = _make_qubits(2)
|
|
808
|
-
op0 = cirq.CZ(q0, q1)
|
|
809
|
-
ps_before = cirq.PauliString({q0: cirq.Z, q1: cirq.Y})
|
|
810
|
-
ps_after = cirq.PauliString({q1: cirq.Y})
|
|
811
|
-
_assert_pass_over([op0], ps_before, ps_after)
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
def test_pass_operations_over_no_common_qubits():
|
|
815
|
-
class ExampleGate(cirq.testing.SingleQubitGate):
|
|
816
|
-
|
|
817
|
-
def _decompose_(self, qubits):
|
|
818
|
-
return cirq.X(qubits[0])
|
|
819
|
-
|
|
820
|
-
q0, q1 = _make_qubits(2)
|
|
821
|
-
op0 = ExampleGate()(q1)
|
|
822
|
-
ps_before = cirq.PauliString({q0: cirq.Z})
|
|
823
|
-
ps_after = cirq.PauliString({q0: cirq.Z})
|
|
824
|
-
_assert_pass_over([op0], ps_before, ps_after)
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
def test_pass_unsupported_operations_over():
|
|
828
|
-
(q0,) = _make_qubits(1)
|
|
829
|
-
pauli_string = cirq.PauliString({q0: cirq.X})
|
|
830
|
-
with pytest.raises(
|
|
831
|
-
ValueError,
|
|
832
|
-
match='Clifford Gate can only be constructed from the operations'
|
|
833
|
-
' that has stabilizer effect.',
|
|
834
|
-
):
|
|
835
|
-
pauli_string.pass_operations_over([cirq.T(q0)])
|
|
836
|
-
|
|
837
|
-
|
|
838
725
|
def test_with_qubits():
|
|
839
726
|
old_qubits = cirq.LineQubit.range(9)
|
|
840
727
|
new_qubits = cirq.LineQubit.range(9, 18)
|
|
@@ -1637,40 +1524,6 @@ def test_conjugated_by_ordering():
|
|
|
1637
1524
|
assert out1 == out2 == cirq.X(a) * cirq.Z(b)
|
|
1638
1525
|
|
|
1639
1526
|
|
|
1640
|
-
def test_pass_operations_over_ordering():
|
|
1641
|
-
class OrderSensitiveGate(cirq.Gate):
|
|
1642
|
-
def num_qubits(self):
|
|
1643
|
-
return 2
|
|
1644
|
-
|
|
1645
|
-
def _decompose_(self, qubits):
|
|
1646
|
-
return [cirq.Y(qubits[0]) ** -0.5, cirq.CNOT(*qubits)]
|
|
1647
|
-
|
|
1648
|
-
a, b = cirq.LineQubit.range(2)
|
|
1649
|
-
inp = cirq.Z(b)
|
|
1650
|
-
out1 = inp.pass_operations_over(OrderSensitiveGate().on(a, b))
|
|
1651
|
-
out2 = inp.pass_operations_over([cirq.CNOT(a, b), cirq.Y(a) ** -0.5])
|
|
1652
|
-
out3 = inp.pass_operations_over([cirq.CNOT(a, b)]).pass_operations_over([cirq.Y(a) ** -0.5])
|
|
1653
|
-
assert out1 == out2 == out3 == cirq.X(a) * cirq.Z(b)
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
def test_pass_operations_over_ordering_reversed():
|
|
1657
|
-
class OrderSensitiveGate(cirq.Gate):
|
|
1658
|
-
def num_qubits(self):
|
|
1659
|
-
return 2
|
|
1660
|
-
|
|
1661
|
-
def _decompose_(self, qubits):
|
|
1662
|
-
return [cirq.Y(qubits[0]) ** -0.5, cirq.CNOT(*qubits)]
|
|
1663
|
-
|
|
1664
|
-
a, b = cirq.LineQubit.range(2)
|
|
1665
|
-
inp = cirq.X(a) * cirq.Z(b)
|
|
1666
|
-
out1 = inp.pass_operations_over(OrderSensitiveGate().on(a, b), after_to_before=True)
|
|
1667
|
-
out2 = inp.pass_operations_over([cirq.Y(a) ** -0.5, cirq.CNOT(a, b)], after_to_before=True)
|
|
1668
|
-
out3 = inp.pass_operations_over([cirq.Y(a) ** -0.5], after_to_before=True).pass_operations_over(
|
|
1669
|
-
[cirq.CNOT(a, b)], after_to_before=True
|
|
1670
|
-
)
|
|
1671
|
-
assert out1 == out2 == out3 == cirq.Z(b)
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
1527
|
def test_pretty_print():
|
|
1675
1528
|
a, b, c = cirq.LineQubit.range(3)
|
|
1676
1529
|
result = cirq.PauliString({a: 'x', b: 'y', c: 'z'})
|
|
@@ -1693,7 +1546,6 @@ def test_pretty_print():
|
|
|
1693
1546
|
assert p.text_pretty == 'cirq.PauliString(...)'
|
|
1694
1547
|
|
|
1695
1548
|
|
|
1696
|
-
# pylint: disable=line-too-long
|
|
1697
1549
|
def test_circuit_diagram_info():
|
|
1698
1550
|
a, b, c = cirq.LineQubit.range(3)
|
|
1699
1551
|
|
|
@@ -1714,13 +1566,10 @@ def test_circuit_diagram_info():
|
|
|
1714
1566
|
1: ───────────────────────────────────────┼─────────────────Y─────────────────PauliString(-iY)───Y───────────────────────────────
|
|
1715
1567
|
│
|
|
1716
1568
|
2: ───────────────────────────────────────Z──────────────────────────────────────────────────────────────────────────────────────
|
|
1717
|
-
""",
|
|
1569
|
+
""", # noqa: E501
|
|
1718
1570
|
)
|
|
1719
1571
|
|
|
1720
1572
|
|
|
1721
|
-
# pylint: enable=line-too-long
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
1573
|
def test_mutable_pauli_string_init_raises():
|
|
1725
1574
|
q = cirq.LineQubit.range(3)
|
|
1726
1575
|
with pytest.raises(ValueError, match='must be between 1 and 3'):
|
|
@@ -2137,3 +1986,31 @@ def test_resolve(resolve_fn):
|
|
|
2137
1986
|
pst = cirq.PauliString({q: 'x'}, coefficient=t)
|
|
2138
1987
|
ps1 = cirq.PauliString({q: 'x'}, coefficient=1j)
|
|
2139
1988
|
assert resolve_fn(pst, {'t': 1j}) == ps1
|
|
1989
|
+
|
|
1990
|
+
|
|
1991
|
+
@pytest.mark.parametrize(
|
|
1992
|
+
'gate1,gate2',
|
|
1993
|
+
[
|
|
1994
|
+
(cirq.I, cirq.I),
|
|
1995
|
+
(cirq.I, cirq.X),
|
|
1996
|
+
(cirq.I, cirq.Y),
|
|
1997
|
+
(cirq.I, cirq.Z),
|
|
1998
|
+
(cirq.X, cirq.I),
|
|
1999
|
+
(cirq.Y, cirq.I),
|
|
2000
|
+
(cirq.Z, cirq.I),
|
|
2001
|
+
],
|
|
2002
|
+
ids=str,
|
|
2003
|
+
)
|
|
2004
|
+
def test_pauli_ops_identity_gate_operation(gate1: cirq.Pauli, gate2: cirq.Pauli) -> None:
|
|
2005
|
+
# TODO: Issue #7280 - Support addition and subtraction of identity gate operations.
|
|
2006
|
+
if gate1 == gate2 == cirq.I:
|
|
2007
|
+
pytest.skip('Not yet implemented per #7280')
|
|
2008
|
+
q = cirq.LineQubit(0)
|
|
2009
|
+
pauli1, pauli2 = gate1.on(q), gate2.on(q)
|
|
2010
|
+
unitary1, unitary2 = cirq.unitary(gate1), cirq.unitary(gate2)
|
|
2011
|
+
addition = pauli1 + pauli2
|
|
2012
|
+
assert isinstance(addition, cirq.PauliSum)
|
|
2013
|
+
assert np.array_equal(addition.matrix(), unitary1 + unitary2)
|
|
2014
|
+
subtraction = pauli1 - pauli2
|
|
2015
|
+
assert isinstance(subtraction, cirq.PauliSum)
|
|
2016
|
+
assert np.array_equal(subtraction.matrix(), unitary1 - unitary2)
|
|
@@ -11,7 +11,10 @@
|
|
|
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
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from typing import Any, Iterator, TYPE_CHECKING
|
|
15
18
|
|
|
16
19
|
import numpy as np
|
|
17
20
|
|
|
@@ -22,7 +25,7 @@ if TYPE_CHECKING:
|
|
|
22
25
|
import cirq
|
|
23
26
|
|
|
24
27
|
|
|
25
|
-
def _all_pauli_strings_commute(pauli_sum:
|
|
28
|
+
def _all_pauli_strings_commute(pauli_sum: cirq.PauliSum) -> bool:
|
|
26
29
|
for x in pauli_sum:
|
|
27
30
|
for y in pauli_sum:
|
|
28
31
|
if not protocols.commutes(x, y):
|
|
@@ -42,10 +45,7 @@ class PauliSumExponential:
|
|
|
42
45
|
"""
|
|
43
46
|
|
|
44
47
|
def __init__(
|
|
45
|
-
self,
|
|
46
|
-
pauli_sum_like: 'cirq.PauliSumLike',
|
|
47
|
-
exponent: 'cirq.TParamVal' = 1,
|
|
48
|
-
atol: float = 1e-8,
|
|
48
|
+
self, pauli_sum_like: cirq.PauliSumLike, exponent: cirq.TParamVal = 1, atol: float = 1e-8
|
|
49
49
|
):
|
|
50
50
|
pauli_sum = linear_combinations.PauliSum.wrap(pauli_sum_like)
|
|
51
51
|
if not _all_pauli_strings_commute(pauli_sum):
|
|
@@ -68,13 +68,13 @@ class PauliSumExponential:
|
|
|
68
68
|
self._pauli_sum = pauli_sum
|
|
69
69
|
|
|
70
70
|
@property
|
|
71
|
-
def qubits(self) ->
|
|
71
|
+
def qubits(self) -> tuple[cirq.Qid, ...]:
|
|
72
72
|
return self._pauli_sum.qubits
|
|
73
73
|
|
|
74
74
|
def _value_equality_values_(self) -> Any:
|
|
75
75
|
return (self._pauli_sum, self._exponent)
|
|
76
76
|
|
|
77
|
-
def with_qubits(self, *new_qubits:
|
|
77
|
+
def with_qubits(self, *new_qubits: cirq.Qid) -> PauliSumExponential:
|
|
78
78
|
return PauliSumExponential(self._pauli_sum.with_qubits(*new_qubits), self._exponent)
|
|
79
79
|
|
|
80
80
|
@_compat.cached_method
|
|
@@ -82,14 +82,14 @@ class PauliSumExponential:
|
|
|
82
82
|
return protocols.is_parameterized(self._exponent)
|
|
83
83
|
|
|
84
84
|
def _resolve_parameters_(
|
|
85
|
-
self, resolver:
|
|
86
|
-
) ->
|
|
85
|
+
self, resolver: cirq.ParamResolver, recursive: bool
|
|
86
|
+
) -> PauliSumExponential:
|
|
87
87
|
return PauliSumExponential(
|
|
88
88
|
self._pauli_sum,
|
|
89
89
|
exponent=protocols.resolve_parameters(self._exponent, resolver, recursive),
|
|
90
90
|
)
|
|
91
91
|
|
|
92
|
-
def __iter__(self) -> Iterator[
|
|
92
|
+
def __iter__(self) -> Iterator[cirq.PauliStringPhasor]:
|
|
93
93
|
for pauli_string in self._pauli_sum:
|
|
94
94
|
theta = pauli_string.coefficient * self._multiplier
|
|
95
95
|
theta *= self._exponent / np.pi
|
|
@@ -119,7 +119,7 @@ class PauliSumExponential:
|
|
|
119
119
|
def _unitary_(self) -> np.ndarray:
|
|
120
120
|
return self.matrix()
|
|
121
121
|
|
|
122
|
-
def __pow__(self, exponent: int) ->
|
|
122
|
+
def __pow__(self, exponent: int) -> PauliSumExponential:
|
|
123
123
|
return PauliSumExponential(self._pauli_sum, self._exponent * exponent)
|
|
124
124
|
|
|
125
125
|
def __repr__(self) -> str:
|