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
|
@@ -14,13 +14,14 @@
|
|
|
14
14
|
|
|
15
15
|
"""A protocol for implementing high performance mixture evolutions."""
|
|
16
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
17
19
|
from types import NotImplementedType
|
|
18
|
-
from typing import Any, cast, Iterable,
|
|
20
|
+
from typing import Any, cast, Iterable, TypeVar
|
|
19
21
|
|
|
20
22
|
import numpy as np
|
|
21
23
|
from typing_extensions import Protocol
|
|
22
24
|
|
|
23
|
-
from cirq import linalg
|
|
24
25
|
from cirq._doc import doc_private
|
|
25
26
|
from cirq.protocols import qid_shape_protocol
|
|
26
27
|
from cirq.protocols.apply_unitary_protocol import apply_unitary, ApplyUnitaryArgs
|
|
@@ -73,7 +74,7 @@ class ApplyMixtureArgs:
|
|
|
73
74
|
auxiliary_buffer0: np.ndarray,
|
|
74
75
|
auxiliary_buffer1: np.ndarray,
|
|
75
76
|
left_axes: Iterable[int],
|
|
76
|
-
right_axes:
|
|
77
|
+
right_axes: Iterable[int] | None = None,
|
|
77
78
|
):
|
|
78
79
|
"""Args for apply mixture.
|
|
79
80
|
|
|
@@ -112,9 +113,7 @@ class SupportsApplyMixture(Protocol):
|
|
|
112
113
|
"""An object that can efficiently implement a mixture."""
|
|
113
114
|
|
|
114
115
|
@doc_private
|
|
115
|
-
def _apply_mixture_(
|
|
116
|
-
self, args: ApplyMixtureArgs
|
|
117
|
-
) -> Union[np.ndarray, None, NotImplementedType]:
|
|
116
|
+
def _apply_mixture_(self, args: ApplyMixtureArgs) -> np.ndarray | None | NotImplementedType:
|
|
118
117
|
"""Efficiently applies a mixture.
|
|
119
118
|
|
|
120
119
|
This method is given both the target tensor and workspace of the same
|
|
@@ -157,8 +156,8 @@ def apply_mixture(
|
|
|
157
156
|
val: Any,
|
|
158
157
|
args: ApplyMixtureArgs,
|
|
159
158
|
*,
|
|
160
|
-
default:
|
|
161
|
-
) ->
|
|
159
|
+
default: np.ndarray | TDefault = RaiseTypeErrorIfNotProvided,
|
|
160
|
+
) -> np.ndarray | TDefault:
|
|
162
161
|
"""High performance evolution under a mixture of unitaries evolution.
|
|
163
162
|
|
|
164
163
|
Follows the steps below to attempt to apply a mixture:
|
|
@@ -273,7 +272,7 @@ def apply_mixture(
|
|
|
273
272
|
)
|
|
274
273
|
|
|
275
274
|
|
|
276
|
-
def _validate_input(val: Any, args:
|
|
275
|
+
def _validate_input(val: Any, args: ApplyMixtureArgs) -> tuple[Any, ApplyMixtureArgs, bool]:
|
|
277
276
|
"""Validate args input and determine if we are operating on a
|
|
278
277
|
density matrix or a state vector.
|
|
279
278
|
"""
|
|
@@ -303,8 +302,8 @@ def _validate_input(val: Any, args: 'ApplyMixtureArgs') -> Tuple[Any, 'ApplyMixt
|
|
|
303
302
|
|
|
304
303
|
|
|
305
304
|
def _apply_unitary_strat(
|
|
306
|
-
val: Any, args:
|
|
307
|
-
) ->
|
|
305
|
+
val: Any, args: ApplyMixtureArgs, is_density_matrix: bool
|
|
306
|
+
) -> np.ndarray | None:
|
|
308
307
|
"""Attempt to use `apply_unitary` and return the result.
|
|
309
308
|
|
|
310
309
|
If `val` does not support `apply_unitary` returns None.
|
|
@@ -325,42 +324,16 @@ def _apply_unitary_strat(
|
|
|
325
324
|
right_args = ApplyUnitaryArgs(
|
|
326
325
|
target_tensor=np.conjugate(left_result),
|
|
327
326
|
available_buffer=args.auxiliary_buffer0,
|
|
328
|
-
axes=cast(
|
|
327
|
+
axes=cast(tuple[int], args.right_axes),
|
|
329
328
|
)
|
|
330
329
|
right_result = apply_unitary(val, right_args)
|
|
331
330
|
np.conjugate(right_result, out=right_result)
|
|
332
331
|
return right_result
|
|
333
332
|
|
|
334
333
|
|
|
335
|
-
def _apply_unitary_from_matrix_strat(
|
|
336
|
-
val: np.ndarray, args: 'ApplyMixtureArgs', is_density_matrix: bool
|
|
337
|
-
) -> Optional[np.ndarray]:
|
|
338
|
-
"""Used to enact mixture tuples that are given as (probability, np.ndarray)
|
|
339
|
-
|
|
340
|
-
If `val` does not support `apply_unitary` returns None.
|
|
341
|
-
"""
|
|
342
|
-
qid_shape = tuple(args.target_tensor.shape[i] for i in args.left_axes)
|
|
343
|
-
matrix_tensor = np.reshape(val.astype(args.target_tensor.dtype), qid_shape * 2)
|
|
344
|
-
linalg.targeted_left_multiply(
|
|
345
|
-
matrix_tensor, args.target_tensor, args.left_axes, out=args.auxiliary_buffer0
|
|
346
|
-
)
|
|
347
|
-
|
|
348
|
-
if not is_density_matrix:
|
|
349
|
-
return args.auxiliary_buffer0
|
|
350
|
-
# No need to transpose as we are acting on the tensor
|
|
351
|
-
# representation of matrix, so transpose is done for us.
|
|
352
|
-
linalg.targeted_left_multiply(
|
|
353
|
-
np.conjugate(matrix_tensor),
|
|
354
|
-
args.auxiliary_buffer0,
|
|
355
|
-
cast(Tuple[int], args.right_axes),
|
|
356
|
-
out=args.target_tensor,
|
|
357
|
-
)
|
|
358
|
-
return args.target_tensor
|
|
359
|
-
|
|
360
|
-
|
|
361
334
|
def _apply_mixture_from_mixture_strat(
|
|
362
|
-
val: Any, args:
|
|
363
|
-
) ->
|
|
335
|
+
val: Any, args: ApplyMixtureArgs, is_density_matrix: bool
|
|
336
|
+
) -> np.ndarray | None:
|
|
364
337
|
"""Attempt to use unitary matrices in _mixture_ and return the result."""
|
|
365
338
|
method = getattr(val, '_mixture_', None)
|
|
366
339
|
if method is None:
|
|
@@ -373,8 +346,6 @@ def _apply_mixture_from_mixture_strat(
|
|
|
373
346
|
for prob, op in prob_mix:
|
|
374
347
|
np.copyto(dst=args.target_tensor, src=args.auxiliary_buffer1)
|
|
375
348
|
right_result = _apply_unitary_strat(op, args, is_density_matrix)
|
|
376
|
-
if right_result is None:
|
|
377
|
-
right_result = _apply_unitary_from_matrix_strat(op, args, is_density_matrix)
|
|
378
349
|
|
|
379
350
|
args.out_buffer += prob * right_result
|
|
380
351
|
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
from
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from typing import Any, cast, Iterable
|
|
15
17
|
|
|
16
18
|
import numpy as np
|
|
17
19
|
import pytest
|
|
@@ -31,9 +33,9 @@ def assert_apply_mixture_returns(
|
|
|
31
33
|
val: Any,
|
|
32
34
|
rho: np.ndarray,
|
|
33
35
|
left_axes: Iterable[int],
|
|
34
|
-
right_axes:
|
|
36
|
+
right_axes: Iterable[int] | None,
|
|
35
37
|
assert_result_is_out_buf: bool = False,
|
|
36
|
-
expected_result:
|
|
38
|
+
expected_result: np.ndarray | None = None,
|
|
37
39
|
):
|
|
38
40
|
out_buf, buf0, buf1 = make_buffers(rho.shape, rho.dtype)
|
|
39
41
|
result = cirq.apply_mixture(
|
|
@@ -94,8 +96,8 @@ def test_apply_mixture_simple():
|
|
|
94
96
|
def _apply_mixture_(self, args: cirq.ApplyMixtureArgs):
|
|
95
97
|
zero_left = cirq.slice_for_qubits_equal_to(args.left_axes, 0)
|
|
96
98
|
one_left = cirq.slice_for_qubits_equal_to(args.left_axes, 1)
|
|
97
|
-
zero_right = cirq.slice_for_qubits_equal_to(cast(
|
|
98
|
-
one_right = cirq.slice_for_qubits_equal_to(cast(
|
|
99
|
+
zero_right = cirq.slice_for_qubits_equal_to(cast(tuple[int], args.right_axes), 0)
|
|
100
|
+
one_right = cirq.slice_for_qubits_equal_to(cast(tuple[int], args.right_axes), 1)
|
|
99
101
|
args.out_buffer[:] = 0
|
|
100
102
|
np.copyto(dst=args.auxiliary_buffer0, src=args.target_tensor)
|
|
101
103
|
for kraus_op in [np.sqrt(0.5) * np.eye(2, dtype=np.complex128), np.sqrt(0.5) * x]:
|
|
@@ -14,9 +14,11 @@
|
|
|
14
14
|
|
|
15
15
|
"""A protocol for implementing high performance unitary left-multiplies."""
|
|
16
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
17
19
|
import warnings
|
|
18
|
-
from types import NotImplementedType
|
|
19
|
-
from typing import Any, cast, Iterable,
|
|
20
|
+
from types import EllipsisType, NotImplementedType
|
|
21
|
+
from typing import Any, cast, Iterable, Sequence, TYPE_CHECKING, TypeVar
|
|
20
22
|
|
|
21
23
|
import numpy as np
|
|
22
24
|
from typing_extensions import Protocol
|
|
@@ -73,7 +75,7 @@ class ApplyUnitaryArgs:
|
|
|
73
75
|
target_tensor: np.ndarray,
|
|
74
76
|
available_buffer: np.ndarray,
|
|
75
77
|
axes: Iterable[int],
|
|
76
|
-
subspaces:
|
|
78
|
+
subspaces: Sequence[tuple[int, ...]] | None = None,
|
|
77
79
|
):
|
|
78
80
|
"""Inits ApplyUnitaryArgs.
|
|
79
81
|
|
|
@@ -111,8 +113,8 @@ class ApplyUnitaryArgs:
|
|
|
111
113
|
|
|
112
114
|
@staticmethod
|
|
113
115
|
def default(
|
|
114
|
-
num_qubits:
|
|
115
|
-
) ->
|
|
116
|
+
num_qubits: int | None = None, *, qid_shape: tuple[int, ...] | None = None
|
|
117
|
+
) -> ApplyUnitaryArgs:
|
|
116
118
|
"""A default instance starting in state |0⟩.
|
|
117
119
|
|
|
118
120
|
Specify exactly one argument.
|
|
@@ -130,15 +132,15 @@ class ApplyUnitaryArgs:
|
|
|
130
132
|
raise TypeError('Specify exactly one of num_qubits or qid_shape.')
|
|
131
133
|
if num_qubits is not None:
|
|
132
134
|
qid_shape = (2,) * num_qubits
|
|
133
|
-
qid_shape = cast(
|
|
135
|
+
qid_shape = cast(tuple[int, ...], qid_shape) # Satisfy mypy
|
|
134
136
|
num_qubits = len(qid_shape)
|
|
135
137
|
state = qis.one_hot(index=(0,) * num_qubits, shape=qid_shape, dtype=np.complex128)
|
|
136
138
|
return ApplyUnitaryArgs(state, np.empty_like(state), range(num_qubits))
|
|
137
139
|
|
|
138
140
|
@classmethod
|
|
139
141
|
def for_unitary(
|
|
140
|
-
cls, num_qubits:
|
|
141
|
-
) ->
|
|
142
|
+
cls, num_qubits: int | None = None, *, qid_shape: tuple[int, ...] | None = None
|
|
143
|
+
) -> ApplyUnitaryArgs:
|
|
142
144
|
"""A default instance corresponding to an identity matrix.
|
|
143
145
|
|
|
144
146
|
Specify exactly one argument.
|
|
@@ -157,12 +159,12 @@ class ApplyUnitaryArgs:
|
|
|
157
159
|
raise TypeError('Specify exactly one of num_qubits or qid_shape.')
|
|
158
160
|
if num_qubits is not None:
|
|
159
161
|
qid_shape = (2,) * num_qubits
|
|
160
|
-
qid_shape = cast(
|
|
162
|
+
qid_shape = cast(tuple[int, ...], qid_shape) # Satisfy mypy
|
|
161
163
|
num_qubits = len(qid_shape)
|
|
162
164
|
state = qis.eye_tensor(qid_shape, dtype=np.complex128)
|
|
163
165
|
return ApplyUnitaryArgs(state, np.empty_like(state), range(num_qubits))
|
|
164
166
|
|
|
165
|
-
def with_axes_transposed_to_start(self) ->
|
|
167
|
+
def with_axes_transposed_to_start(self) -> ApplyUnitaryArgs:
|
|
166
168
|
"""Returns a transposed view of the same arguments.
|
|
167
169
|
|
|
168
170
|
Returns:
|
|
@@ -180,8 +182,8 @@ class ApplyUnitaryArgs:
|
|
|
180
182
|
return ApplyUnitaryArgs(target_tensor, available_buffer, range(len(self.axes)))
|
|
181
183
|
|
|
182
184
|
def _for_operation_with_qid_shape(
|
|
183
|
-
self, indices: Iterable[int], slices:
|
|
184
|
-
) ->
|
|
185
|
+
self, indices: Iterable[int], slices: tuple[int | slice, ...]
|
|
186
|
+
) -> ApplyUnitaryArgs:
|
|
185
187
|
"""Creates a sliced and transposed view of `self` appropriate for an
|
|
186
188
|
operation with shape `qid_shape` on qubits with the given indices.
|
|
187
189
|
|
|
@@ -213,7 +215,7 @@ class ApplyUnitaryArgs:
|
|
|
213
215
|
|
|
214
216
|
def subspace_index(
|
|
215
217
|
self, little_endian_bits_int: int = 0, *, big_endian_bits_int: int = 0
|
|
216
|
-
) ->
|
|
218
|
+
) -> tuple[slice | int | EllipsisType, ...]:
|
|
217
219
|
"""An index for the subspace where the target axes equal a value.
|
|
218
220
|
|
|
219
221
|
Args:
|
|
@@ -258,9 +260,7 @@ class SupportsConsistentApplyUnitary(Protocol):
|
|
|
258
260
|
"""An object that can be efficiently left-multiplied into tensors."""
|
|
259
261
|
|
|
260
262
|
@doc_private
|
|
261
|
-
def _apply_unitary_(
|
|
262
|
-
self, args: ApplyUnitaryArgs
|
|
263
|
-
) -> Union[np.ndarray, None, NotImplementedType]:
|
|
263
|
+
def _apply_unitary_(self, args: ApplyUnitaryArgs) -> np.ndarray | None | NotImplementedType:
|
|
264
264
|
"""Left-multiplies a unitary effect onto a tensor with good performance.
|
|
265
265
|
|
|
266
266
|
This method is given both the target tensor and workspace of the same
|
|
@@ -306,10 +306,10 @@ class SupportsConsistentApplyUnitary(Protocol):
|
|
|
306
306
|
def apply_unitary(
|
|
307
307
|
unitary_value: Any,
|
|
308
308
|
args: ApplyUnitaryArgs,
|
|
309
|
-
default:
|
|
309
|
+
default: np.ndarray | TDefault = RaiseTypeErrorIfNotProvided,
|
|
310
310
|
*,
|
|
311
311
|
allow_decompose: bool = True,
|
|
312
|
-
) ->
|
|
312
|
+
) -> np.ndarray | TDefault:
|
|
313
313
|
"""High performance left-multiplication of a unitary effect onto a tensor.
|
|
314
314
|
|
|
315
315
|
Applies the unitary effect of `unitary_value` to the tensor specified in
|
|
@@ -420,7 +420,7 @@ def apply_unitary(
|
|
|
420
420
|
|
|
421
421
|
def _strat_apply_unitary_from_apply_unitary(
|
|
422
422
|
unitary_value: Any, args: ApplyUnitaryArgs
|
|
423
|
-
) ->
|
|
423
|
+
) -> np.ndarray | None:
|
|
424
424
|
# Check for magic method.
|
|
425
425
|
func = getattr(unitary_value, '_apply_unitary_', None)
|
|
426
426
|
if func is None:
|
|
@@ -468,21 +468,26 @@ def _apply_unitary_from_matrix(matrix: np.ndarray, unitary_value: Any, args: App
|
|
|
468
468
|
|
|
469
469
|
def _strat_apply_unitary_from_unitary(
|
|
470
470
|
unitary_value: Any, args: ApplyUnitaryArgs
|
|
471
|
-
) ->
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
471
|
+
) -> np.ndarray | None:
|
|
472
|
+
if isinstance(unitary_value, np.ndarray):
|
|
473
|
+
matrix = unitary_value
|
|
474
|
+
if not linalg.is_unitary(matrix):
|
|
475
|
+
return None
|
|
476
|
+
else:
|
|
477
|
+
# Check for magic method.
|
|
478
|
+
method = getattr(unitary_value, '_unitary_', None)
|
|
479
|
+
if method is None:
|
|
480
|
+
return NotImplemented
|
|
476
481
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
482
|
+
# Attempt to get the unitary matrix.
|
|
483
|
+
matrix = method()
|
|
484
|
+
if matrix is NotImplemented or matrix is None:
|
|
485
|
+
return matrix
|
|
481
486
|
|
|
482
487
|
return _apply_unitary_from_matrix(matrix, unitary_value, args)
|
|
483
488
|
|
|
484
489
|
|
|
485
|
-
def _strat_apply_unitary_from_decompose(val: Any, args: ApplyUnitaryArgs) ->
|
|
490
|
+
def _strat_apply_unitary_from_decompose(val: Any, args: ApplyUnitaryArgs) -> np.ndarray | None:
|
|
486
491
|
operations, qubits, _ = _try_decompose_into_operations_and_qubits(val)
|
|
487
492
|
if operations is None:
|
|
488
493
|
return NotImplemented
|
|
@@ -506,10 +511,10 @@ def _strat_apply_unitary_from_decompose(val: Any, args: ApplyUnitaryArgs) -> Opt
|
|
|
506
511
|
|
|
507
512
|
def apply_unitaries(
|
|
508
513
|
unitary_values: Iterable[Any],
|
|
509
|
-
qubits: Sequence[
|
|
510
|
-
args:
|
|
514
|
+
qubits: Sequence[cirq.Qid],
|
|
515
|
+
args: ApplyUnitaryArgs | None = None,
|
|
511
516
|
default: Any = RaiseTypeErrorIfNotProvided,
|
|
512
|
-
) ->
|
|
517
|
+
) -> np.ndarray | None:
|
|
513
518
|
"""Apply a series of unitaries onto a state tensor.
|
|
514
519
|
|
|
515
520
|
Uses `cirq.apply_unitary` on each of the unitary values, to apply them to
|
|
@@ -589,7 +594,7 @@ def apply_unitaries(
|
|
|
589
594
|
|
|
590
595
|
|
|
591
596
|
def _incorporate_result_into_target(
|
|
592
|
-
args:
|
|
597
|
+
args: ApplyUnitaryArgs, sub_args: ApplyUnitaryArgs, sub_result: np.ndarray
|
|
593
598
|
):
|
|
594
599
|
"""Takes the result of calling `_apply_unitary_` on `sub_args` and
|
|
595
600
|
copies it back into `args.target_tensor` or `args.available_buffer` as
|
|
@@ -645,7 +650,7 @@ def _incorporate_result_into_target(
|
|
|
645
650
|
return args.target_tensor
|
|
646
651
|
|
|
647
652
|
|
|
648
|
-
def _to_slice(subspace_def:
|
|
653
|
+
def _to_slice(subspace_def: tuple[int, ...]):
|
|
649
654
|
if len(subspace_def) < 1:
|
|
650
655
|
raise ValueError(f'Subspace {subspace_def} has zero dimensions.')
|
|
651
656
|
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import numpy as np
|
|
16
18
|
import pytest
|
|
17
19
|
|
|
@@ -54,12 +56,13 @@ def test_apply_unitary_presence_absence():
|
|
|
54
56
|
args.target_tensor[one] *= -1
|
|
55
57
|
return args.target_tensor
|
|
56
58
|
|
|
57
|
-
fails = [NoUnitaryEffect(), HasApplyReturnsNotImplemented()]
|
|
59
|
+
fails = [NoUnitaryEffect(), HasApplyReturnsNotImplemented(), m * 2]
|
|
58
60
|
passes = [
|
|
59
61
|
HasUnitary(),
|
|
60
62
|
HasApplyReturnsNotImplementedButHasUnitary(),
|
|
61
63
|
HasApplyOutputInBuffer(),
|
|
62
64
|
HasApplyMutateInline(),
|
|
65
|
+
m,
|
|
63
66
|
]
|
|
64
67
|
|
|
65
68
|
def make_input():
|
|
@@ -12,20 +12,11 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import re
|
|
16
18
|
from fractions import Fraction
|
|
17
|
-
from typing import
|
|
18
|
-
Any,
|
|
19
|
-
Dict,
|
|
20
|
-
Iterable,
|
|
21
|
-
List,
|
|
22
|
-
Optional,
|
|
23
|
-
overload,
|
|
24
|
-
Sequence,
|
|
25
|
-
TYPE_CHECKING,
|
|
26
|
-
TypeVar,
|
|
27
|
-
Union,
|
|
28
|
-
)
|
|
19
|
+
from typing import Any, Iterable, overload, Sequence, TYPE_CHECKING, TypeVar, Union
|
|
29
20
|
|
|
30
21
|
import numpy as np
|
|
31
22
|
import sympy
|
|
@@ -50,7 +41,7 @@ class CircuitDiagramInfo:
|
|
|
50
41
|
wire_symbols: Iterable[str],
|
|
51
42
|
exponent: Any = 1,
|
|
52
43
|
connected: bool = True,
|
|
53
|
-
exponent_qubit_index:
|
|
44
|
+
exponent_qubit_index: int | None = None,
|
|
54
45
|
auto_exponent_parens: bool = True,
|
|
55
46
|
) -> None:
|
|
56
47
|
"""Inits CircuitDiagramInfo.
|
|
@@ -104,8 +95,8 @@ class CircuitDiagramInfo:
|
|
|
104
95
|
)
|
|
105
96
|
|
|
106
97
|
def _wire_symbols_including_formatted_exponent(
|
|
107
|
-
self, args:
|
|
108
|
-
) ->
|
|
98
|
+
self, args: cirq.CircuitDiagramInfoArgs, *, preferred_exponent_index: int | None = None
|
|
99
|
+
) -> list[str]:
|
|
109
100
|
result = list(self.wire_symbols)
|
|
110
101
|
exponent = self._formatted_exponent(args)
|
|
111
102
|
if exponent is not None:
|
|
@@ -122,7 +113,7 @@ class CircuitDiagramInfo:
|
|
|
122
113
|
result[k] += f"^{exponent}"
|
|
123
114
|
return result
|
|
124
115
|
|
|
125
|
-
def _formatted_exponent(self, args:
|
|
116
|
+
def _formatted_exponent(self, args: cirq.CircuitDiagramInfoArgs) -> str | None:
|
|
126
117
|
if protocols.is_parameterized(self.exponent):
|
|
127
118
|
name = str(self.exponent)
|
|
128
119
|
return f'({name})' if _is_exposed_formula(name) else name
|
|
@@ -190,21 +181,24 @@ class CircuitDiagramInfoArgs:
|
|
|
190
181
|
precision: The number of digits after the decimal to show for numbers in
|
|
191
182
|
the text diagram. None means use full precision.
|
|
192
183
|
label_map: The map from label entities to diagram positions.
|
|
193
|
-
include_tags:
|
|
184
|
+
include_tags: If ``True`` all tags from ``TaggedOperations`` will be
|
|
185
|
+
printed. If ``False`` no tags will be printed. Alternatively a
|
|
186
|
+
collection of tag classes can be provided. In this case only tags
|
|
187
|
+
whose type is contained in the collection will be shown.
|
|
194
188
|
transpose: Whether the circuit is to be drawn with time from left to
|
|
195
189
|
right (transpose is False), or from top to bottom.
|
|
196
190
|
"""
|
|
197
191
|
|
|
198
|
-
UNINFORMED_DEFAULT:
|
|
192
|
+
UNINFORMED_DEFAULT: CircuitDiagramInfoArgs
|
|
199
193
|
|
|
200
194
|
def __init__(
|
|
201
195
|
self,
|
|
202
|
-
known_qubits:
|
|
203
|
-
known_qubit_count:
|
|
196
|
+
known_qubits: Iterable[cirq.Qid] | None,
|
|
197
|
+
known_qubit_count: int | None,
|
|
204
198
|
use_unicode_characters: bool,
|
|
205
|
-
precision:
|
|
206
|
-
label_map:
|
|
207
|
-
include_tags: bool = True,
|
|
199
|
+
precision: int | None,
|
|
200
|
+
label_map: dict[LabelEntity, int] | None,
|
|
201
|
+
include_tags: bool | Iterable[type] = True,
|
|
208
202
|
transpose: bool = False,
|
|
209
203
|
) -> None:
|
|
210
204
|
self.known_qubits = None if known_qubits is None else tuple(known_qubits)
|
|
@@ -212,7 +206,11 @@ class CircuitDiagramInfoArgs:
|
|
|
212
206
|
self.use_unicode_characters = use_unicode_characters
|
|
213
207
|
self.precision = precision
|
|
214
208
|
self.label_map = label_map
|
|
215
|
-
self.include_tags
|
|
209
|
+
self.include_tags: bool | frozenset[type]
|
|
210
|
+
if isinstance(include_tags, bool):
|
|
211
|
+
self.include_tags = include_tags
|
|
212
|
+
else:
|
|
213
|
+
self.include_tags = frozenset(include_tags)
|
|
216
214
|
self.transpose = transpose
|
|
217
215
|
|
|
218
216
|
def _value_equality_values_(self) -> Any:
|
|
@@ -226,7 +224,11 @@ class CircuitDiagramInfoArgs:
|
|
|
226
224
|
if self.label_map is None
|
|
227
225
|
else tuple(sorted(self.label_map.items(), key=lambda e: e[0]))
|
|
228
226
|
),
|
|
229
|
-
|
|
227
|
+
(
|
|
228
|
+
self.include_tags
|
|
229
|
+
if isinstance(self.include_tags, bool)
|
|
230
|
+
else tuple(sorted(self.include_tags, key=lambda c: c.__name__))
|
|
231
|
+
),
|
|
230
232
|
self.transpose,
|
|
231
233
|
)
|
|
232
234
|
|
|
@@ -238,11 +240,28 @@ class CircuitDiagramInfoArgs:
|
|
|
238
240
|
f'use_unicode_characters={self.use_unicode_characters!r}, '
|
|
239
241
|
f'precision={self.precision!r}, '
|
|
240
242
|
f'label_map={self.label_map!r}, '
|
|
241
|
-
f'include_tags={self.
|
|
243
|
+
f'include_tags={self._include_tags_repr()}, '
|
|
242
244
|
f'transpose={self.transpose!r})'
|
|
243
245
|
)
|
|
244
246
|
|
|
245
|
-
def
|
|
247
|
+
def _include_tags_repr(self) -> str:
|
|
248
|
+
if isinstance(self.include_tags, bool):
|
|
249
|
+
return repr(self.include_tags)
|
|
250
|
+
items = []
|
|
251
|
+
for cls in self.include_tags:
|
|
252
|
+
if cls.__module__ == 'builtins':
|
|
253
|
+
items.append(cls.__qualname__)
|
|
254
|
+
else:
|
|
255
|
+
items.append(f"{cls.__module__}.{cls.__qualname__}")
|
|
256
|
+
joined = ', '.join(items)
|
|
257
|
+
return f'frozenset({{{joined}}})'
|
|
258
|
+
|
|
259
|
+
def tags_to_include(self, tags: Iterable[Any]) -> list[Any]:
|
|
260
|
+
if isinstance(self.include_tags, bool):
|
|
261
|
+
return list(tags) if self.include_tags else []
|
|
262
|
+
return [t for t in tags if any(isinstance(t, cls) for cls in self.include_tags)]
|
|
263
|
+
|
|
264
|
+
def format_real(self, val: sympy.Basic | int | float) -> str:
|
|
246
265
|
if isinstance(val, sympy.Basic):
|
|
247
266
|
return str(val)
|
|
248
267
|
if val == int(val):
|
|
@@ -251,7 +270,7 @@ class CircuitDiagramInfoArgs:
|
|
|
251
270
|
return str(val)
|
|
252
271
|
return f'{float(val):.{self.precision}}'
|
|
253
272
|
|
|
254
|
-
def format_complex(self, val:
|
|
273
|
+
def format_complex(self, val: sympy.Basic | int | float | cirq.TParamValComplex) -> str:
|
|
255
274
|
if isinstance(val, sympy.Basic):
|
|
256
275
|
return str(val)
|
|
257
276
|
c = complex(val)
|
|
@@ -263,7 +282,7 @@ class CircuitDiagramInfoArgs:
|
|
|
263
282
|
imag_str = '' if abs_imag == 1 else self.format_real(abs_imag)
|
|
264
283
|
return f'{self.format_real(c.real)}{joiner}{imag_str}i'
|
|
265
284
|
|
|
266
|
-
def format_radians(self, radians:
|
|
285
|
+
def format_radians(self, radians: sympy.Basic | int | float) -> str:
|
|
267
286
|
"""Returns angle in radians as a human-readable string."""
|
|
268
287
|
if protocols.is_parameterized(radians):
|
|
269
288
|
return str(radians)
|
|
@@ -288,6 +307,7 @@ class CircuitDiagramInfoArgs:
|
|
|
288
307
|
use_unicode_characters=self.use_unicode_characters,
|
|
289
308
|
precision=self.precision,
|
|
290
309
|
label_map=self.label_map,
|
|
310
|
+
include_tags=self.include_tags,
|
|
291
311
|
transpose=self.transpose,
|
|
292
312
|
)
|
|
293
313
|
|
|
@@ -314,7 +334,7 @@ class SupportsCircuitDiagramInfo(Protocol):
|
|
|
314
334
|
@doc_private
|
|
315
335
|
def _circuit_diagram_info_(
|
|
316
336
|
self, args: CircuitDiagramInfoArgs
|
|
317
|
-
) ->
|
|
337
|
+
) -> str | Iterable[str] | CircuitDiagramInfo:
|
|
318
338
|
"""Describes how to draw an operation in a circuit diagram.
|
|
319
339
|
|
|
320
340
|
This method is used by the global `cirq.diagram_info` method. If this
|
|
@@ -336,10 +356,10 @@ RaiseTypeErrorIfNotProvided = CircuitDiagramInfo(())
|
|
|
336
356
|
|
|
337
357
|
|
|
338
358
|
def _op_info_with_fallback(
|
|
339
|
-
op:
|
|
340
|
-
) ->
|
|
359
|
+
op: cirq.Operation, args: cirq.CircuitDiagramInfoArgs
|
|
360
|
+
) -> cirq.CircuitDiagramInfo:
|
|
341
361
|
info = protocols.circuit_diagram_info(op, args, None)
|
|
342
|
-
rows:
|
|
362
|
+
rows: list[LabelEntity] = list(op.qubits)
|
|
343
363
|
if args.label_map is not None:
|
|
344
364
|
rows += protocols.measurement_keys_touched(op) & args.label_map.keys()
|
|
345
365
|
if info is not None and info.wire_symbols:
|
|
@@ -366,28 +386,27 @@ def _op_info_with_fallback(
|
|
|
366
386
|
return protocols.CircuitDiagramInfo(wire_symbols=symbols)
|
|
367
387
|
|
|
368
388
|
|
|
369
|
-
# pylint: disable=function-redefined
|
|
370
389
|
@overload
|
|
371
390
|
def circuit_diagram_info(
|
|
372
|
-
val: Any, args:
|
|
391
|
+
val: Any, args: CircuitDiagramInfoArgs | None = None
|
|
373
392
|
) -> CircuitDiagramInfo:
|
|
374
393
|
pass
|
|
375
394
|
|
|
376
395
|
|
|
377
396
|
@overload
|
|
378
397
|
def circuit_diagram_info(
|
|
379
|
-
val: Any, args:
|
|
380
|
-
) ->
|
|
398
|
+
val: Any, args: CircuitDiagramInfoArgs | None, default: TDefault
|
|
399
|
+
) -> CircuitDiagramInfo | TDefault:
|
|
381
400
|
pass
|
|
382
401
|
|
|
383
402
|
|
|
384
403
|
@overload
|
|
385
|
-
def circuit_diagram_info(val: Any, *, default: TDefault) ->
|
|
404
|
+
def circuit_diagram_info(val: Any, *, default: TDefault) -> CircuitDiagramInfo | TDefault:
|
|
386
405
|
pass
|
|
387
406
|
|
|
388
407
|
|
|
389
408
|
def circuit_diagram_info(
|
|
390
|
-
val: Any, args:
|
|
409
|
+
val: Any, args: CircuitDiagramInfoArgs | None = None, default=RaiseTypeErrorIfNotProvided
|
|
391
410
|
):
|
|
392
411
|
"""Requests information on drawing an operation in a circuit diagram.
|
|
393
412
|
|
|
@@ -438,6 +457,3 @@ def circuit_diagram_info(
|
|
|
438
457
|
f"object of type '{type(val)}' does have a _circuit_diagram_info_ "
|
|
439
458
|
"method, but it returned NotImplemented."
|
|
440
459
|
)
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
# pylint: enable=function-redefined
|