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/circuits/frozen_circuit.py
CHANGED
|
@@ -18,25 +18,15 @@ from __future__ import annotations
|
|
|
18
18
|
|
|
19
19
|
from functools import cached_property
|
|
20
20
|
from types import NotImplementedType
|
|
21
|
-
from typing import
|
|
22
|
-
AbstractSet,
|
|
23
|
-
FrozenSet,
|
|
24
|
-
Hashable,
|
|
25
|
-
Iterable,
|
|
26
|
-
Iterator,
|
|
27
|
-
Sequence,
|
|
28
|
-
Tuple,
|
|
29
|
-
TYPE_CHECKING,
|
|
30
|
-
Union,
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
import numpy as np
|
|
21
|
+
from typing import AbstractSet, Hashable, Iterable, Iterator, Sequence, TYPE_CHECKING
|
|
34
22
|
|
|
35
23
|
from cirq import _compat, protocols
|
|
36
24
|
from cirq.circuits import AbstractCircuit, Alignment, Circuit
|
|
37
25
|
from cirq.circuits.insert_strategy import InsertStrategy
|
|
38
26
|
|
|
39
27
|
if TYPE_CHECKING:
|
|
28
|
+
import numpy as np
|
|
29
|
+
|
|
40
30
|
import cirq
|
|
41
31
|
|
|
42
32
|
|
|
@@ -75,9 +65,12 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
75
65
|
self._tags = tuple(tags)
|
|
76
66
|
|
|
77
67
|
@classmethod
|
|
78
|
-
def _from_moments(
|
|
68
|
+
def _from_moments(
|
|
69
|
+
cls, moments: Iterable[cirq.Moment], tags: Sequence[Hashable]
|
|
70
|
+
) -> FrozenCircuit:
|
|
79
71
|
new_circuit = FrozenCircuit()
|
|
80
72
|
new_circuit._moments = tuple(moments)
|
|
73
|
+
new_circuit._tags = tuple(tags)
|
|
81
74
|
return new_circuit
|
|
82
75
|
|
|
83
76
|
@property
|
|
@@ -88,17 +81,16 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
88
81
|
return self
|
|
89
82
|
|
|
90
83
|
def unfreeze(self, copy: bool = True) -> cirq.Circuit:
|
|
91
|
-
return Circuit._from_moments(self._moments)
|
|
84
|
+
return Circuit._from_moments(self._moments, tags=self.tags)
|
|
92
85
|
|
|
93
86
|
@property
|
|
94
|
-
def tags(self) ->
|
|
87
|
+
def tags(self) -> tuple[Hashable, ...]:
|
|
95
88
|
"""Returns a tuple of the Circuit's tags."""
|
|
96
89
|
return self._tags
|
|
97
90
|
|
|
98
91
|
@cached_property
|
|
99
92
|
def untagged(self) -> cirq.FrozenCircuit:
|
|
100
|
-
|
|
101
|
-
return self._from_moments(self._moments) if self.tags else self
|
|
93
|
+
return super().untagged
|
|
102
94
|
|
|
103
95
|
def with_tags(self, *new_tags: Hashable) -> cirq.FrozenCircuit:
|
|
104
96
|
"""Creates a new tagged `FrozenCircuit` with `self.tags` and `new_tags` combined."""
|
|
@@ -113,13 +105,6 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
113
105
|
# Explicitly cached for performance
|
|
114
106
|
return hash((self.moments, self.tags))
|
|
115
107
|
|
|
116
|
-
def __eq__(self, other):
|
|
117
|
-
super_eq = super().__eq__(other)
|
|
118
|
-
if super_eq is not True:
|
|
119
|
-
return super_eq
|
|
120
|
-
other_tags = other.tags if isinstance(other, FrozenCircuit) else ()
|
|
121
|
-
return self.tags == other_tags
|
|
122
|
-
|
|
123
108
|
def __getstate__(self):
|
|
124
109
|
# Don't save hash when pickling; see #3777.
|
|
125
110
|
state = self.__dict__
|
|
@@ -134,7 +119,7 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
134
119
|
return len(self.all_qubits())
|
|
135
120
|
|
|
136
121
|
@_compat.cached_method
|
|
137
|
-
def _qid_shape_(self) ->
|
|
122
|
+
def _qid_shape_(self) -> tuple[int, ...]:
|
|
138
123
|
return super()._qid_shape_()
|
|
139
124
|
|
|
140
125
|
@_compat.cached_method
|
|
@@ -142,7 +127,7 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
142
127
|
return super()._has_unitary_()
|
|
143
128
|
|
|
144
129
|
@_compat.cached_method
|
|
145
|
-
def _unitary_(self) ->
|
|
130
|
+
def _unitary_(self) -> np.ndarray | NotImplementedType:
|
|
146
131
|
return super()._unitary_()
|
|
147
132
|
|
|
148
133
|
@_compat.cached_method
|
|
@@ -150,11 +135,11 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
150
135
|
return protocols.is_measurement(self.unfreeze())
|
|
151
136
|
|
|
152
137
|
@_compat.cached_method
|
|
153
|
-
def all_qubits(self) ->
|
|
138
|
+
def all_qubits(self) -> frozenset[cirq.Qid]:
|
|
154
139
|
return super().all_qubits()
|
|
155
140
|
|
|
156
141
|
@cached_property
|
|
157
|
-
def _all_operations(self) ->
|
|
142
|
+
def _all_operations(self) -> tuple[cirq.Operation, ...]:
|
|
158
143
|
return tuple(super().all_operations())
|
|
159
144
|
|
|
160
145
|
def all_operations(self) -> Iterator[cirq.Operation]:
|
|
@@ -164,14 +149,14 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
164
149
|
return self._is_measurement_()
|
|
165
150
|
|
|
166
151
|
@_compat.cached_method
|
|
167
|
-
def all_measurement_key_objs(self) ->
|
|
152
|
+
def all_measurement_key_objs(self) -> frozenset[cirq.MeasurementKey]:
|
|
168
153
|
return super().all_measurement_key_objs()
|
|
169
154
|
|
|
170
|
-
def _measurement_key_objs_(self) ->
|
|
155
|
+
def _measurement_key_objs_(self) -> frozenset[cirq.MeasurementKey]:
|
|
171
156
|
return self.all_measurement_key_objs()
|
|
172
157
|
|
|
173
158
|
@_compat.cached_method
|
|
174
|
-
def _control_keys_(self) ->
|
|
159
|
+
def _control_keys_(self) -> frozenset[cirq.MeasurementKey]:
|
|
175
160
|
return super()._control_keys_()
|
|
176
161
|
|
|
177
162
|
@_compat.cached_method
|
|
@@ -179,30 +164,18 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
179
164
|
return super().are_all_measurements_terminal()
|
|
180
165
|
|
|
181
166
|
@_compat.cached_method
|
|
182
|
-
def all_measurement_key_names(self) ->
|
|
167
|
+
def all_measurement_key_names(self) -> frozenset[str]:
|
|
183
168
|
return frozenset(str(key) for key in self.all_measurement_key_objs())
|
|
184
169
|
|
|
185
170
|
@_compat.cached_method
|
|
186
171
|
def _is_parameterized_(self) -> bool:
|
|
187
|
-
return super()._is_parameterized_()
|
|
188
|
-
protocols.is_parameterized(tag) for tag in self.tags
|
|
189
|
-
)
|
|
172
|
+
return super()._is_parameterized_()
|
|
190
173
|
|
|
191
174
|
@_compat.cached_method
|
|
192
175
|
def _parameter_names_(self) -> AbstractSet[str]:
|
|
193
|
-
|
|
194
|
-
return super()._parameter_names_() | tag_params
|
|
195
|
-
|
|
196
|
-
def _resolve_parameters_(
|
|
197
|
-
self, resolver: cirq.ParamResolver, recursive: bool
|
|
198
|
-
) -> cirq.FrozenCircuit:
|
|
199
|
-
resolved_circuit = super()._resolve_parameters_(resolver, recursive)
|
|
200
|
-
resolved_tags = [
|
|
201
|
-
protocols.resolve_parameters(tag, resolver, recursive) for tag in self.tags
|
|
202
|
-
]
|
|
203
|
-
return resolved_circuit.with_tags(*resolved_tags)
|
|
176
|
+
return super()._parameter_names_()
|
|
204
177
|
|
|
205
|
-
def _measurement_key_names_(self) ->
|
|
178
|
+
def _measurement_key_names_(self) -> frozenset[str]:
|
|
206
179
|
return self.all_measurement_key_names()
|
|
207
180
|
|
|
208
181
|
def __add__(self, other) -> cirq.FrozenCircuit:
|
|
@@ -227,29 +200,19 @@ class FrozenCircuit(AbstractCircuit, protocols.SerializableByKey):
|
|
|
227
200
|
except:
|
|
228
201
|
return NotImplemented
|
|
229
202
|
|
|
230
|
-
def _repr_args(self) -> str:
|
|
231
|
-
moments_repr = super()._repr_args()
|
|
232
|
-
tag_repr = ','.join(_compat.proper_repr(t) for t in self._tags)
|
|
233
|
-
return f'{moments_repr}, tags=[{tag_repr}]' if self.tags else moments_repr
|
|
234
|
-
|
|
235
|
-
def _json_dict_(self):
|
|
236
|
-
attribute_names = ['moments', 'tags'] if self.tags else ['moments']
|
|
237
|
-
ret = protocols.obj_to_dict_helper(self, attribute_names)
|
|
238
|
-
return ret
|
|
239
|
-
|
|
240
203
|
@classmethod
|
|
241
204
|
def _from_json_dict_(cls, moments, *, tags=(), **kwargs):
|
|
242
205
|
return cls(moments, strategy=InsertStrategy.EARLIEST, tags=tags)
|
|
243
206
|
|
|
244
207
|
def concat_ragged(
|
|
245
|
-
*circuits: cirq.AbstractCircuit, align:
|
|
208
|
+
*circuits: cirq.AbstractCircuit, align: cirq.Alignment | str = Alignment.LEFT
|
|
246
209
|
) -> cirq.FrozenCircuit:
|
|
247
210
|
return AbstractCircuit.concat_ragged(*circuits, align=align).freeze()
|
|
248
211
|
|
|
249
212
|
concat_ragged.__doc__ = AbstractCircuit.concat_ragged.__doc__
|
|
250
213
|
|
|
251
214
|
def zip(
|
|
252
|
-
*circuits: cirq.AbstractCircuit, align:
|
|
215
|
+
*circuits: cirq.AbstractCircuit, align: cirq.Alignment | str = Alignment.LEFT
|
|
253
216
|
) -> cirq.FrozenCircuit:
|
|
254
217
|
return AbstractCircuit.zip(*circuits, align=align).freeze()
|
|
255
218
|
|
|
@@ -16,13 +16,15 @@
|
|
|
16
16
|
Behavior shared with Circuit is tested with parameters in circuit_test.py.
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
19
21
|
import pytest
|
|
20
22
|
import sympy
|
|
21
23
|
|
|
22
24
|
import cirq
|
|
23
25
|
|
|
24
26
|
|
|
25
|
-
def test_from_moments():
|
|
27
|
+
def test_from_moments() -> None:
|
|
26
28
|
a, b, c, d = cirq.LineQubit.range(4)
|
|
27
29
|
moment = cirq.Moment(cirq.Z(a), cirq.Z(b))
|
|
28
30
|
subcircuit = cirq.FrozenCircuit.from_moments(cirq.X(c), cirq.Y(d))
|
|
@@ -49,10 +51,11 @@ def test_from_moments():
|
|
|
49
51
|
cirq.Moment(cirq.measure(a, b, key='ab'), cirq.measure(c, d, key='cd')),
|
|
50
52
|
)
|
|
51
53
|
assert circuit[0] is moment
|
|
54
|
+
assert isinstance(circuit[1].operations[0], cirq.CircuitOperation)
|
|
52
55
|
assert circuit[1].operations[0].circuit is subcircuit
|
|
53
56
|
|
|
54
57
|
|
|
55
|
-
def test_freeze_and_unfreeze():
|
|
58
|
+
def test_freeze_and_unfreeze() -> None:
|
|
56
59
|
a, b = cirq.LineQubit.range(2)
|
|
57
60
|
c = cirq.Circuit(cirq.X(a), cirq.H(b))
|
|
58
61
|
|
|
@@ -78,7 +81,7 @@ def test_freeze_and_unfreeze():
|
|
|
78
81
|
assert fcc is not f
|
|
79
82
|
|
|
80
83
|
|
|
81
|
-
def test_immutable():
|
|
84
|
+
def test_immutable() -> None:
|
|
82
85
|
q = cirq.LineQubit(0)
|
|
83
86
|
c = cirq.FrozenCircuit(cirq.X(q), cirq.H(q))
|
|
84
87
|
|
|
@@ -87,21 +90,21 @@ def test_immutable():
|
|
|
87
90
|
AttributeError,
|
|
88
91
|
match="(can't set attribute)|(property 'moments' of 'FrozenCircuit' object has no setter)",
|
|
89
92
|
):
|
|
90
|
-
c.moments = (cirq.Moment(cirq.H(q)), cirq.Moment(cirq.X(q)))
|
|
93
|
+
c.moments = (cirq.Moment(cirq.H(q)), cirq.Moment(cirq.X(q))) # type: ignore[misc]
|
|
91
94
|
|
|
92
95
|
|
|
93
|
-
def test_tagged_circuits():
|
|
96
|
+
def test_tagged_circuits() -> None:
|
|
94
97
|
q = cirq.LineQubit(0)
|
|
95
98
|
ops = [cirq.X(q), cirq.H(q)]
|
|
96
|
-
tags =
|
|
99
|
+
tags = (sympy.Symbol("a"), "b")
|
|
97
100
|
circuit = cirq.Circuit(ops)
|
|
98
101
|
frozen_circuit = cirq.FrozenCircuit(ops)
|
|
99
102
|
tagged_circuit = cirq.FrozenCircuit(ops, tags=tags)
|
|
100
103
|
# Test equality
|
|
101
|
-
assert tagged_circuit.tags ==
|
|
104
|
+
assert tagged_circuit.tags == tags
|
|
102
105
|
assert circuit == frozen_circuit != tagged_circuit
|
|
106
|
+
assert not cirq.approx_eq(frozen_circuit, tagged_circuit)
|
|
103
107
|
assert cirq.approx_eq(circuit, frozen_circuit)
|
|
104
|
-
assert cirq.approx_eq(frozen_circuit, tagged_circuit)
|
|
105
108
|
# Test hash
|
|
106
109
|
assert hash(frozen_circuit) != hash(tagged_circuit)
|
|
107
110
|
# Test _repr_ and _json_ round trips.
|
|
@@ -113,9 +116,29 @@ def test_tagged_circuits():
|
|
|
113
116
|
assert tagged_circuit.with_tags("c") == cirq.FrozenCircuit(ops, tags=[*tags, "c"])
|
|
114
117
|
assert tagged_circuit.untagged == frozen_circuit
|
|
115
118
|
assert frozen_circuit.untagged is frozen_circuit
|
|
119
|
+
assert tagged_circuit.unfreeze(copy=True).tags == tags
|
|
120
|
+
assert tagged_circuit.unfreeze(copy=False).tags == tags
|
|
116
121
|
# Test parameterized protocols
|
|
117
122
|
assert cirq.is_parameterized(frozen_circuit) is False
|
|
118
123
|
assert cirq.is_parameterized(tagged_circuit) is True
|
|
119
124
|
assert cirq.parameter_names(tagged_circuit) == {"a"}
|
|
125
|
+
assert cirq.resolve_parameters(tagged_circuit, {"a": 1}).tags == (1, "b")
|
|
120
126
|
# Tags are not propagated to diagrams yet.
|
|
121
127
|
assert str(frozen_circuit) == str(tagged_circuit)
|
|
128
|
+
# Test tags are preserved through operations
|
|
129
|
+
assert (tagged_circuit + circuit).tags == tags
|
|
130
|
+
assert (circuit + tagged_circuit).tags == () # We only preserve the tags for the first one
|
|
131
|
+
assert (2 * tagged_circuit).tags == tags
|
|
132
|
+
assert (tagged_circuit * 2).tags == tags
|
|
133
|
+
assert (tagged_circuit**-1).tags == tags
|
|
134
|
+
for c in tagged_circuit.factorize():
|
|
135
|
+
assert tagged_circuit.tags == tags
|
|
136
|
+
|
|
137
|
+
q2 = cirq.LineQubit(1)
|
|
138
|
+
circuit2 = cirq.Circuit(cirq.X(q2), cirq.H(q2))
|
|
139
|
+
assert tagged_circuit.zip(circuit2).tags == tags
|
|
140
|
+
assert circuit2.zip(tagged_circuit).tags == () # We only preserve the tags for the first one
|
|
141
|
+
assert tagged_circuit.concat_ragged(circuit2).tags == tags
|
|
142
|
+
assert (
|
|
143
|
+
circuit2.concat_ragged(tagged_circuit).tags == ()
|
|
144
|
+
) # We only preserve the tags for the first one
|
cirq/circuits/insert_strategy.py
CHANGED
|
@@ -14,16 +14,18 @@
|
|
|
14
14
|
|
|
15
15
|
"""Hard-coded options for adding multiple operations to a circuit."""
|
|
16
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
17
19
|
|
|
18
20
|
class InsertStrategy:
|
|
19
21
|
"""Indicates preferences on how to add multiple operations to a circuit."""
|
|
20
22
|
|
|
21
|
-
NEW:
|
|
22
|
-
NEW_THEN_INLINE:
|
|
23
|
-
INLINE:
|
|
24
|
-
EARLIEST:
|
|
23
|
+
NEW: InsertStrategy
|
|
24
|
+
NEW_THEN_INLINE: InsertStrategy
|
|
25
|
+
INLINE: InsertStrategy
|
|
26
|
+
EARLIEST: InsertStrategy
|
|
25
27
|
|
|
26
|
-
def __new__(cls, name: str, doc: str) ->
|
|
28
|
+
def __new__(cls, name: str, doc: str) -> InsertStrategy:
|
|
27
29
|
inst = getattr(cls, name, None)
|
|
28
30
|
if not inst or not isinstance(inst, cls):
|
|
29
31
|
inst = super().__new__(cls)
|
|
@@ -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 pickle
|
|
16
18
|
|
|
17
19
|
import pytest
|
|
@@ -19,7 +21,7 @@ import pytest
|
|
|
19
21
|
import cirq
|
|
20
22
|
|
|
21
23
|
|
|
22
|
-
def test_repr():
|
|
24
|
+
def test_repr() -> None:
|
|
23
25
|
assert repr(cirq.InsertStrategy.NEW) == 'cirq.InsertStrategy.NEW'
|
|
24
26
|
assert str(cirq.InsertStrategy.NEW) == 'NEW'
|
|
25
27
|
|
|
@@ -34,6 +36,6 @@ def test_repr():
|
|
|
34
36
|
],
|
|
35
37
|
ids=lambda strategy: strategy.name,
|
|
36
38
|
)
|
|
37
|
-
def test_identity_after_pickling(strategy: cirq.InsertStrategy):
|
|
39
|
+
def test_identity_after_pickling(strategy: cirq.InsertStrategy) -> None:
|
|
38
40
|
unpickled_strategy = pickle.loads(pickle.dumps(strategy))
|
|
39
41
|
assert unpickled_strategy is strategy
|
cirq/circuits/moment.py
CHANGED
|
@@ -24,18 +24,13 @@ from typing import (
|
|
|
24
24
|
Any,
|
|
25
25
|
Callable,
|
|
26
26
|
cast,
|
|
27
|
-
|
|
28
|
-
FrozenSet,
|
|
27
|
+
Hashable,
|
|
29
28
|
Iterable,
|
|
30
29
|
Iterator,
|
|
31
|
-
List,
|
|
32
30
|
Mapping,
|
|
33
|
-
Optional,
|
|
34
31
|
overload,
|
|
35
32
|
Sequence,
|
|
36
|
-
Tuple,
|
|
37
33
|
TYPE_CHECKING,
|
|
38
|
-
Union,
|
|
39
34
|
)
|
|
40
35
|
|
|
41
36
|
import numpy as np
|
|
@@ -51,13 +46,12 @@ if TYPE_CHECKING:
|
|
|
51
46
|
|
|
52
47
|
# Lazy imports to break circular dependencies.
|
|
53
48
|
circuit = LazyLoader("circuit", globals(), "cirq.circuits.circuit")
|
|
54
|
-
op_tree = LazyLoader("op_tree", globals(), "cirq.ops.op_tree")
|
|
55
49
|
text_diagram_drawer = LazyLoader(
|
|
56
50
|
"text_diagram_drawer", globals(), "cirq.circuits.text_diagram_drawer"
|
|
57
51
|
)
|
|
58
52
|
|
|
59
53
|
|
|
60
|
-
def _default_breakdown(qid: cirq.Qid) ->
|
|
54
|
+
def _default_breakdown(qid: cirq.Qid) -> tuple[Any, Any]:
|
|
61
55
|
# Attempt to convert into a position on the complex plane.
|
|
62
56
|
try:
|
|
63
57
|
plane_pos = complex(qid) # type: ignore
|
|
@@ -84,7 +78,12 @@ class Moment:
|
|
|
84
78
|
are no such operations, returns an empty Moment.
|
|
85
79
|
"""
|
|
86
80
|
|
|
87
|
-
def __init__(
|
|
81
|
+
def __init__(
|
|
82
|
+
self,
|
|
83
|
+
*contents: cirq.OP_TREE,
|
|
84
|
+
_flatten_contents: bool = True,
|
|
85
|
+
tags: tuple[Hashable, ...] = (),
|
|
86
|
+
) -> None:
|
|
88
87
|
"""Constructs a moment with the given operations.
|
|
89
88
|
|
|
90
89
|
Args:
|
|
@@ -95,6 +94,12 @@ class Moment:
|
|
|
95
94
|
we skip flattening and assume that contents already consists
|
|
96
95
|
of individual operations. This is used internally by helper
|
|
97
96
|
methods to avoid unnecessary validation.
|
|
97
|
+
tags: Optional tags to denote specific Moment objects with meta-data.
|
|
98
|
+
These are a tuple of any Hashable object. Typically, a class
|
|
99
|
+
will be passed. Tags apply only to this specific set of operations
|
|
100
|
+
and will be lost on any transformation of the
|
|
101
|
+
Moment. For instance, if operations are added to the Moment, tags
|
|
102
|
+
will be dropped unless explicitly added back in by the user.
|
|
98
103
|
|
|
99
104
|
Raises:
|
|
100
105
|
ValueError: A qubit appears more than once.
|
|
@@ -102,12 +107,12 @@ class Moment:
|
|
|
102
107
|
self._operations = (
|
|
103
108
|
tuple(op_tree.flatten_to_ops(contents))
|
|
104
109
|
if _flatten_contents
|
|
105
|
-
else cast(
|
|
110
|
+
else cast(tuple['cirq.Operation'], contents)
|
|
106
111
|
)
|
|
107
|
-
self._sorted_operations:
|
|
112
|
+
self._sorted_operations: tuple[cirq.Operation, ...] | None = None
|
|
108
113
|
|
|
109
114
|
# An internal dictionary to support efficient operation access by qubit.
|
|
110
|
-
self._qubit_to_op:
|
|
115
|
+
self._qubit_to_op: dict[cirq.Qid, cirq.Operation] = {}
|
|
111
116
|
for op in self.operations:
|
|
112
117
|
for q in op.qubits:
|
|
113
118
|
# Check that operations don't overlap.
|
|
@@ -115,11 +120,12 @@ class Moment:
|
|
|
115
120
|
raise ValueError(f'Overlapping operations: {self.operations}')
|
|
116
121
|
self._qubit_to_op[q] = op
|
|
117
122
|
|
|
118
|
-
self._measurement_key_objs:
|
|
119
|
-
self._control_keys:
|
|
123
|
+
self._measurement_key_objs: frozenset[cirq.MeasurementKey] | None = None
|
|
124
|
+
self._control_keys: frozenset[cirq.MeasurementKey] | None = None
|
|
125
|
+
self._tags = tags
|
|
120
126
|
|
|
121
127
|
@classmethod
|
|
122
|
-
def from_ops(cls, *ops: cirq.Operation) -> cirq.Moment:
|
|
128
|
+
def from_ops(cls, *ops: cirq.Operation, tags: tuple[Hashable, ...] = ()) -> cirq.Moment:
|
|
123
129
|
"""Construct a Moment from the given operations.
|
|
124
130
|
|
|
125
131
|
This avoids calling `flatten_to_ops` in the moment constructor, which
|
|
@@ -129,17 +135,48 @@ class Moment:
|
|
|
129
135
|
|
|
130
136
|
Args:
|
|
131
137
|
*ops: Operations to include in the Moment.
|
|
138
|
+
tags: Optional tags to denote specific Moment objects with meta-data.
|
|
139
|
+
These are a tuple of any Hashable object. Tags will be dropped if
|
|
140
|
+
the operations in the Moment are modified or transformed.
|
|
132
141
|
"""
|
|
133
|
-
return cls(*ops, _flatten_contents=False)
|
|
142
|
+
return cls(*ops, _flatten_contents=False, tags=tags)
|
|
134
143
|
|
|
135
144
|
@property
|
|
136
|
-
def operations(self) ->
|
|
145
|
+
def operations(self) -> tuple[cirq.Operation, ...]:
|
|
137
146
|
return self._operations
|
|
138
147
|
|
|
139
148
|
@cached_property
|
|
140
|
-
def qubits(self) ->
|
|
149
|
+
def qubits(self) -> frozenset[cirq.Qid]:
|
|
141
150
|
return frozenset(self._qubit_to_op)
|
|
142
151
|
|
|
152
|
+
@property
|
|
153
|
+
def tags(self) -> tuple[Hashable, ...]:
|
|
154
|
+
"""Returns a tuple of the operation's tags."""
|
|
155
|
+
return self._tags
|
|
156
|
+
|
|
157
|
+
def with_tags(self, *new_tags: Hashable) -> cirq.Moment:
|
|
158
|
+
"""Creates a new Moment with the current ops and the specified tags.
|
|
159
|
+
|
|
160
|
+
If the moment already has tags, this will add the new_tags to the
|
|
161
|
+
preexisting tags.
|
|
162
|
+
|
|
163
|
+
This method can be used to attach meta-data to moments
|
|
164
|
+
without affecting their functionality. The intended usage is to
|
|
165
|
+
attach classes intended for this purpose or strings to mark operations
|
|
166
|
+
for specific usage that will be recognized by consumers.
|
|
167
|
+
|
|
168
|
+
Tags can be a list of any type of object that is useful to identify
|
|
169
|
+
this operation as long as the type is hashable. If you wish the
|
|
170
|
+
resulting operation to be eventually serialized into JSON, you should
|
|
171
|
+
also restrict the operation to be JSON serializable.
|
|
172
|
+
|
|
173
|
+
Please note that tags should be instantiated if classes are
|
|
174
|
+
used. Raw types are not allowed.
|
|
175
|
+
"""
|
|
176
|
+
if not new_tags:
|
|
177
|
+
return self
|
|
178
|
+
return Moment(*self._operations, _flatten_contents=False, tags=(*self._tags, *new_tags))
|
|
179
|
+
|
|
143
180
|
def operates_on_single_qubit(self, qubit: cirq.Qid) -> bool:
|
|
144
181
|
"""Determines if the moment has operations touching the given qubit.
|
|
145
182
|
Args:
|
|
@@ -160,7 +197,7 @@ class Moment:
|
|
|
160
197
|
"""
|
|
161
198
|
return not self._qubit_to_op.keys().isdisjoint(qubits)
|
|
162
199
|
|
|
163
|
-
def operation_at(self, qubit: raw_types.Qid) ->
|
|
200
|
+
def operation_at(self, qubit: raw_types.Qid) -> cirq.Operation | None:
|
|
164
201
|
"""Returns the operation on a certain qubit for the moment.
|
|
165
202
|
|
|
166
203
|
Args:
|
|
@@ -177,6 +214,8 @@ class Moment:
|
|
|
177
214
|
def with_operation(self, operation: cirq.Operation) -> cirq.Moment:
|
|
178
215
|
"""Returns an equal moment, but with the given op added.
|
|
179
216
|
|
|
217
|
+
Any tags on the Moment will be dropped.
|
|
218
|
+
|
|
180
219
|
Args:
|
|
181
220
|
operation: The operation to append.
|
|
182
221
|
|
|
@@ -205,6 +244,9 @@ class Moment:
|
|
|
205
244
|
def with_operations(self, *contents: cirq.OP_TREE) -> cirq.Moment:
|
|
206
245
|
"""Returns a new moment with the given contents added.
|
|
207
246
|
|
|
247
|
+
Any tags on the original Moment object are dropped if the Moment
|
|
248
|
+
is changed.
|
|
249
|
+
|
|
208
250
|
Args:
|
|
209
251
|
*contents: New operations to add to this moment.
|
|
210
252
|
|
|
@@ -242,6 +284,9 @@ class Moment:
|
|
|
242
284
|
def without_operations_touching(self, qubits: Iterable[cirq.Qid]) -> cirq.Moment:
|
|
243
285
|
"""Returns an equal moment, but without ops on the given qubits.
|
|
244
286
|
|
|
287
|
+
Any tags on the original Moment object are dropped if the Moment
|
|
288
|
+
is changed.
|
|
289
|
+
|
|
245
290
|
Args:
|
|
246
291
|
qubits: Operations that touch these will be removed.
|
|
247
292
|
|
|
@@ -267,7 +312,7 @@ class Moment:
|
|
|
267
312
|
|
|
268
313
|
def _resolve_parameters_(self, resolver: cirq.ParamResolver, recursive: bool) -> cirq.Moment:
|
|
269
314
|
changed = False
|
|
270
|
-
resolved_ops:
|
|
315
|
+
resolved_ops: list[cirq.Operation] = []
|
|
271
316
|
for op in self:
|
|
272
317
|
resolved_op = protocols.resolve_parameters(op, resolver, recursive)
|
|
273
318
|
changed = (
|
|
@@ -291,35 +336,35 @@ class Moment:
|
|
|
291
336
|
)
|
|
292
337
|
|
|
293
338
|
@_compat.cached_method()
|
|
294
|
-
def _measurement_key_names_(self) ->
|
|
339
|
+
def _measurement_key_names_(self) -> frozenset[str]:
|
|
295
340
|
return frozenset(str(key) for key in self._measurement_key_objs_())
|
|
296
341
|
|
|
297
|
-
def _measurement_key_objs_(self) ->
|
|
342
|
+
def _measurement_key_objs_(self) -> frozenset[cirq.MeasurementKey]:
|
|
298
343
|
if self._measurement_key_objs is None:
|
|
299
344
|
self._measurement_key_objs = frozenset(
|
|
300
345
|
key for op in self.operations for key in protocols.measurement_key_objs(op)
|
|
301
346
|
)
|
|
302
347
|
return self._measurement_key_objs
|
|
303
348
|
|
|
304
|
-
def _control_keys_(self) ->
|
|
349
|
+
def _control_keys_(self) -> frozenset[cirq.MeasurementKey]:
|
|
305
350
|
if self._control_keys is None:
|
|
306
351
|
self._control_keys = frozenset(
|
|
307
352
|
k for op in self.operations for k in protocols.control_keys(op)
|
|
308
353
|
)
|
|
309
354
|
return self._control_keys
|
|
310
355
|
|
|
311
|
-
def _sorted_operations_(self) ->
|
|
356
|
+
def _sorted_operations_(self) -> tuple[cirq.Operation, ...]:
|
|
312
357
|
if self._sorted_operations is None:
|
|
313
358
|
self._sorted_operations = tuple(sorted(self._operations, key=lambda op: op.qubits))
|
|
314
359
|
return self._sorted_operations
|
|
315
360
|
|
|
316
|
-
def _with_key_path_(self, path:
|
|
361
|
+
def _with_key_path_(self, path: tuple[str, ...]):
|
|
317
362
|
return Moment(
|
|
318
363
|
protocols.with_key_path(op, path) if protocols.is_measurement(op) else op
|
|
319
364
|
for op in self.operations
|
|
320
365
|
)
|
|
321
366
|
|
|
322
|
-
def _with_key_path_prefix_(self, prefix:
|
|
367
|
+
def _with_key_path_prefix_(self, prefix: tuple[str, ...]):
|
|
323
368
|
return Moment(
|
|
324
369
|
(
|
|
325
370
|
protocols.with_key_path_prefix(op, prefix)
|
|
@@ -330,7 +375,7 @@ class Moment:
|
|
|
330
375
|
)
|
|
331
376
|
|
|
332
377
|
def _with_rescoped_keys_(
|
|
333
|
-
self, path:
|
|
378
|
+
self, path: tuple[str, ...], bindable_keys: frozenset[cirq.MeasurementKey]
|
|
334
379
|
):
|
|
335
380
|
return Moment(
|
|
336
381
|
protocols.with_rescoped_keys(op, path, bindable_keys) for op in self.operations
|
|
@@ -364,7 +409,7 @@ class Moment:
|
|
|
364
409
|
def __hash__(self):
|
|
365
410
|
return hash((Moment, self._sorted_operations_()))
|
|
366
411
|
|
|
367
|
-
def __getstate__(self) ->
|
|
412
|
+
def __getstate__(self) -> dict[str, Any]:
|
|
368
413
|
# clear cached hash value when pickling, see #6674
|
|
369
414
|
state = self.__dict__
|
|
370
415
|
hash_attr = _compat._method_cache_name(self.__hash__)
|
|
@@ -407,7 +452,7 @@ class Moment:
|
|
|
407
452
|
return self._operations
|
|
408
453
|
|
|
409
454
|
def transform_qubits(
|
|
410
|
-
self, qubit_map:
|
|
455
|
+
self, qubit_map: dict[cirq.Qid, cirq.Qid] | Callable[[cirq.Qid], cirq.Qid]
|
|
411
456
|
) -> Self:
|
|
412
457
|
"""Returns the same moment, but with different qubits.
|
|
413
458
|
|
|
@@ -516,12 +561,14 @@ class Moment:
|
|
|
516
561
|
return NotImplemented
|
|
517
562
|
return qis.kraus_to_superoperator(self._kraus_())
|
|
518
563
|
|
|
519
|
-
def _json_dict_(self) ->
|
|
520
|
-
|
|
564
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
565
|
+
# For backwards compatibility, only output tags if they exist.
|
|
566
|
+
args = ['operations', 'tags'] if self._tags else ['operations']
|
|
567
|
+
return protocols.obj_to_dict_helper(self, args)
|
|
521
568
|
|
|
522
569
|
@classmethod
|
|
523
|
-
def _from_json_dict_(cls, operations, **kwargs):
|
|
524
|
-
return cls
|
|
570
|
+
def _from_json_dict_(cls, operations, tags=(), **kwargs):
|
|
571
|
+
return cls(*operations, tags=tags)
|
|
525
572
|
|
|
526
573
|
def __add__(self, other: cirq.OP_TREE) -> cirq.Moment:
|
|
527
574
|
if isinstance(other, circuit.AbstractCircuit):
|
|
@@ -544,7 +591,6 @@ class Moment:
|
|
|
544
591
|
)
|
|
545
592
|
return Moment(new_ops)
|
|
546
593
|
|
|
547
|
-
# pylint: disable=function-redefined
|
|
548
594
|
@overload
|
|
549
595
|
def __getitem__(self, key: raw_types.Qid) -> cirq.Operation:
|
|
550
596
|
pass
|
|
@@ -569,11 +615,11 @@ class Moment:
|
|
|
569
615
|
def to_text_diagram(
|
|
570
616
|
self: cirq.Moment,
|
|
571
617
|
*,
|
|
572
|
-
xy_breakdown_func: Callable[[cirq.Qid],
|
|
618
|
+
xy_breakdown_func: Callable[[cirq.Qid], tuple[Any, Any]] = _default_breakdown,
|
|
573
619
|
extra_qubits: Iterable[cirq.Qid] = (),
|
|
574
620
|
use_unicode_characters: bool = True,
|
|
575
|
-
precision:
|
|
576
|
-
include_tags: bool = True,
|
|
621
|
+
precision: int | None = None,
|
|
622
|
+
include_tags: bool | Iterable[type] = True,
|
|
577
623
|
) -> str:
|
|
578
624
|
"""Create a text diagram for the moment.
|
|
579
625
|
|
|
@@ -591,8 +637,10 @@ class Moment:
|
|
|
591
637
|
precision: How precise numbers, such as angles, should be. Use None
|
|
592
638
|
for infinite precision, or an integer for a certain number of
|
|
593
639
|
digits of precision.
|
|
594
|
-
include_tags:
|
|
595
|
-
|
|
640
|
+
include_tags: Controls which tags attached to operations are
|
|
641
|
+
included. ``True`` includes all tags, ``False`` includes none,
|
|
642
|
+
or a collection of tag classes may be specified to include only
|
|
643
|
+
those tags.
|
|
596
644
|
|
|
597
645
|
Returns:
|
|
598
646
|
The text diagram rendered into text.
|
|
@@ -657,7 +705,7 @@ class Moment:
|
|
|
657
705
|
|
|
658
706
|
return diagram.render()
|
|
659
707
|
|
|
660
|
-
def _commutes_(self, other: Any, *, atol: float = 1e-8) ->
|
|
708
|
+
def _commutes_(self, other: Any, *, atol: float = 1e-8) -> bool | NotImplementedType:
|
|
661
709
|
"""Determines whether Moment commutes with the other Moment or Operation.
|
|
662
710
|
|
|
663
711
|
Args:
|