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
|
@@ -20,7 +20,9 @@ References:
|
|
|
20
20
|
https://arxiv.org/abs/2105.06074
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
|
-
from
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
from typing import Sequence, TYPE_CHECKING
|
|
24
26
|
|
|
25
27
|
import numpy as np
|
|
26
28
|
import sympy
|
|
@@ -34,7 +36,7 @@ if TYPE_CHECKING:
|
|
|
34
36
|
|
|
35
37
|
|
|
36
38
|
def parameterized_2q_op_to_sqrt_iswap_operations(
|
|
37
|
-
op:
|
|
39
|
+
op: cirq.Operation, *, use_sqrt_iswap_inv: bool = False
|
|
38
40
|
) -> protocols.decompose_protocol.DecomposeResult:
|
|
39
41
|
"""Tries to decompose a parameterized 2q operation into √iSWAP's + parameterized 1q rotations.
|
|
40
42
|
|
|
@@ -68,9 +70,7 @@ def parameterized_2q_op_to_sqrt_iswap_operations(
|
|
|
68
70
|
return NotImplemented
|
|
69
71
|
|
|
70
72
|
|
|
71
|
-
def _sqrt_iswap_inv(
|
|
72
|
-
a: 'cirq.Qid', b: 'cirq.Qid', use_sqrt_iswap_inv: bool = True
|
|
73
|
-
) -> 'cirq.OP_TREE':
|
|
73
|
+
def _sqrt_iswap_inv(a: cirq.Qid, b: cirq.Qid, use_sqrt_iswap_inv: bool = True) -> cirq.OP_TREE:
|
|
74
74
|
"""Optree implementing `cirq.SQRT_ISWAP_INV(a, b)` using √iSWAPs.
|
|
75
75
|
|
|
76
76
|
Args:
|
|
@@ -89,7 +89,7 @@ def _sqrt_iswap_inv(
|
|
|
89
89
|
|
|
90
90
|
|
|
91
91
|
def _cphase_symbols_to_sqrt_iswap(
|
|
92
|
-
a:
|
|
92
|
+
a: cirq.Qid, b: cirq.Qid, turns: cirq.TParamVal, use_sqrt_iswap_inv: bool = True
|
|
93
93
|
):
|
|
94
94
|
"""Implements `cirq.CZ(a, b) ** turns` using two √iSWAPs and single qubit rotations.
|
|
95
95
|
|
|
@@ -136,7 +136,7 @@ def _cphase_symbols_to_sqrt_iswap(
|
|
|
136
136
|
|
|
137
137
|
|
|
138
138
|
def _swap_symbols_to_sqrt_iswap(
|
|
139
|
-
a:
|
|
139
|
+
a: cirq.Qid, b: cirq.Qid, turns: cirq.TParamVal, use_sqrt_iswap_inv: bool = True
|
|
140
140
|
):
|
|
141
141
|
"""Implements `cirq.SWAP(a, b) ** turns` using two √iSWAPs and single qubit rotations.
|
|
142
142
|
|
|
@@ -170,7 +170,7 @@ def _swap_symbols_to_sqrt_iswap(
|
|
|
170
170
|
|
|
171
171
|
|
|
172
172
|
def _iswap_symbols_to_sqrt_iswap(
|
|
173
|
-
a:
|
|
173
|
+
a: cirq.Qid, b: cirq.Qid, turns: cirq.TParamVal, use_sqrt_iswap_inv: bool = True
|
|
174
174
|
):
|
|
175
175
|
"""Implements `cirq.ISWAP(a, b) ** turns` using two √iSWAPs and single qubit rotations.
|
|
176
176
|
|
|
@@ -202,10 +202,10 @@ def _iswap_symbols_to_sqrt_iswap(
|
|
|
202
202
|
|
|
203
203
|
|
|
204
204
|
def _fsim_symbols_to_sqrt_iswap(
|
|
205
|
-
a:
|
|
206
|
-
b:
|
|
207
|
-
theta:
|
|
208
|
-
phi:
|
|
205
|
+
a: cirq.Qid,
|
|
206
|
+
b: cirq.Qid,
|
|
207
|
+
theta: cirq.TParamVal,
|
|
208
|
+
phi: cirq.TParamVal,
|
|
209
209
|
use_sqrt_iswap_inv: bool = True,
|
|
210
210
|
):
|
|
211
211
|
"""Implements `cirq.FSimGate(theta, phi)(a, b)` using two √iSWAPs and single qubit rotations.
|
|
@@ -229,16 +229,16 @@ def _fsim_symbols_to_sqrt_iswap(
|
|
|
229
229
|
|
|
230
230
|
|
|
231
231
|
def two_qubit_matrix_to_sqrt_iswap_operations(
|
|
232
|
-
q0:
|
|
233
|
-
q1:
|
|
232
|
+
q0: cirq.Qid,
|
|
233
|
+
q1: cirq.Qid,
|
|
234
234
|
mat: np.ndarray,
|
|
235
235
|
*,
|
|
236
|
-
required_sqrt_iswap_count:
|
|
236
|
+
required_sqrt_iswap_count: int | None = None,
|
|
237
237
|
use_sqrt_iswap_inv: bool = False,
|
|
238
238
|
atol: float = 1e-8,
|
|
239
239
|
check_preconditions: bool = True,
|
|
240
240
|
clean_operations: bool = False,
|
|
241
|
-
) -> Sequence[
|
|
241
|
+
) -> Sequence[cirq.Operation]:
|
|
242
242
|
"""Decomposes a two-qubit operation into ZPow/XPow/YPow/sqrt-iSWAP gates.
|
|
243
243
|
|
|
244
244
|
This method uses the KAK decomposition of the matrix to determine how many
|
|
@@ -300,13 +300,13 @@ def two_qubit_matrix_to_sqrt_iswap_operations(
|
|
|
300
300
|
|
|
301
301
|
|
|
302
302
|
def _kak_decomposition_to_sqrt_iswap_operations(
|
|
303
|
-
q0:
|
|
304
|
-
q1:
|
|
303
|
+
q0: cirq.Qid,
|
|
304
|
+
q1: cirq.Qid,
|
|
305
305
|
kak: linalg.KakDecomposition,
|
|
306
|
-
required_sqrt_iswap_count:
|
|
306
|
+
required_sqrt_iswap_count: int | None = None,
|
|
307
307
|
use_sqrt_iswap_inv: bool = False,
|
|
308
308
|
atol: float = 1e-8,
|
|
309
|
-
) -> Sequence[
|
|
309
|
+
) -> Sequence[cirq.Operation]:
|
|
310
310
|
single_qubit_operations, _ = _single_qubit_matrices_with_sqrt_iswap(
|
|
311
311
|
kak, required_sqrt_iswap_count, atol=atol
|
|
312
312
|
)
|
|
@@ -325,14 +325,14 @@ def _kak_decomposition_to_sqrt_iswap_operations(
|
|
|
325
325
|
|
|
326
326
|
|
|
327
327
|
def _decomp_to_operations(
|
|
328
|
-
q0:
|
|
329
|
-
q1:
|
|
330
|
-
two_qubit_gate:
|
|
331
|
-
single_qubit_operations: Sequence[
|
|
328
|
+
q0: cirq.Qid,
|
|
329
|
+
q1: cirq.Qid,
|
|
330
|
+
two_qubit_gate: cirq.Gate,
|
|
331
|
+
single_qubit_operations: Sequence[tuple[np.ndarray, np.ndarray]],
|
|
332
332
|
u0_before: np.ndarray = np.eye(2),
|
|
333
333
|
u0_after: np.ndarray = np.eye(2),
|
|
334
334
|
atol: float = 1e-8,
|
|
335
|
-
) -> Sequence[
|
|
335
|
+
) -> Sequence[cirq.Operation]:
|
|
336
336
|
"""Converts a sequence of single-qubit unitary matrices on two qubits into a
|
|
337
337
|
list of operations with interleaved two-qubit gates."""
|
|
338
338
|
two_qubit_op = two_qubit_gate(q0, q1)
|
|
@@ -401,10 +401,8 @@ def _decomp_to_operations(
|
|
|
401
401
|
|
|
402
402
|
|
|
403
403
|
def _single_qubit_matrices_with_sqrt_iswap(
|
|
404
|
-
kak:
|
|
405
|
-
|
|
406
|
-
atol: float = 1e-8,
|
|
407
|
-
) -> Tuple[Sequence[Tuple[np.ndarray, np.ndarray]], complex]:
|
|
404
|
+
kak: cirq.KakDecomposition, required_sqrt_iswap_count: int | None = None, atol: float = 1e-8
|
|
405
|
+
) -> tuple[Sequence[tuple[np.ndarray, np.ndarray]], complex]:
|
|
408
406
|
"""Computes the sequence of interleaved single-qubit unitary matrices in the
|
|
409
407
|
sqrt-iSWAP decomposition."""
|
|
410
408
|
decomposers = [
|
|
@@ -430,7 +428,7 @@ def _single_qubit_matrices_with_sqrt_iswap(
|
|
|
430
428
|
|
|
431
429
|
|
|
432
430
|
def _in_0_region(
|
|
433
|
-
interaction_coefficients:
|
|
431
|
+
interaction_coefficients: tuple[float, float, float], weyl_tol: float = 1e-8
|
|
434
432
|
) -> bool:
|
|
435
433
|
"""Tests if (x, y, z) ~= (0, 0, 0) assuming x, y, z are canonical."""
|
|
436
434
|
x, y, z = interaction_coefficients
|
|
@@ -438,7 +436,7 @@ def _in_0_region(
|
|
|
438
436
|
|
|
439
437
|
|
|
440
438
|
def _in_1sqrt_iswap_region(
|
|
441
|
-
interaction_coefficients:
|
|
439
|
+
interaction_coefficients: tuple[float, float, float], weyl_tol: float = 1e-8
|
|
442
440
|
) -> bool:
|
|
443
441
|
"""Tests if (x, y, z) ~= (π/8, π/8, 0), assuming x, y, z are canonical."""
|
|
444
442
|
x, y, z = interaction_coefficients
|
|
@@ -446,7 +444,7 @@ def _in_1sqrt_iswap_region(
|
|
|
446
444
|
|
|
447
445
|
|
|
448
446
|
def _in_2sqrt_iswap_region(
|
|
449
|
-
interaction_coefficients:
|
|
447
|
+
interaction_coefficients: tuple[float, float, float], weyl_tol: float = 1e-8
|
|
450
448
|
) -> bool:
|
|
451
449
|
"""Tests if (x, y, z) is inside or within weyl_tol of the volume
|
|
452
450
|
x >= y + |z| assuming x, y, z are canonical.
|
|
@@ -463,7 +461,7 @@ def _in_2sqrt_iswap_region(
|
|
|
463
461
|
|
|
464
462
|
|
|
465
463
|
def _in_3sqrt_iswap_region(
|
|
466
|
-
interaction_coefficients:
|
|
464
|
+
interaction_coefficients: tuple[float, float, float], weyl_tol: float = 1e-8
|
|
467
465
|
) -> bool:
|
|
468
466
|
"""Any two-qubit operation is decomposable into three SQRT_ISWAP gates.
|
|
469
467
|
|
|
@@ -476,8 +474,8 @@ def _in_3sqrt_iswap_region(
|
|
|
476
474
|
|
|
477
475
|
|
|
478
476
|
def _decomp_0_matrices(
|
|
479
|
-
kak:
|
|
480
|
-
) ->
|
|
477
|
+
kak: cirq.KakDecomposition, atol: float = 1e-8
|
|
478
|
+
) -> tuple[Sequence[tuple[np.ndarray, np.ndarray]], complex]:
|
|
481
479
|
"""Returns the single-qubit matrices for the 0-SQRT_ISWAP decomposition.
|
|
482
480
|
|
|
483
481
|
Assumes canonical x, y, z and (x, y, z) = (0, 0, 0) within tolerance.
|
|
@@ -494,8 +492,8 @@ def _decomp_0_matrices(
|
|
|
494
492
|
|
|
495
493
|
|
|
496
494
|
def _decomp_1sqrt_iswap_matrices(
|
|
497
|
-
kak:
|
|
498
|
-
) ->
|
|
495
|
+
kak: cirq.KakDecomposition, atol: float = 1e-8
|
|
496
|
+
) -> tuple[Sequence[tuple[np.ndarray, np.ndarray]], complex]:
|
|
499
497
|
"""Returns the single-qubit matrices for the 1-SQRT_ISWAP decomposition.
|
|
500
498
|
|
|
501
499
|
Assumes canonical x, y, z and (x, y, z) = (π/8, π/8, 0) within tolerance.
|
|
@@ -507,8 +505,8 @@ def _decomp_1sqrt_iswap_matrices(
|
|
|
507
505
|
|
|
508
506
|
|
|
509
507
|
def _decomp_2sqrt_iswap_matrices(
|
|
510
|
-
kak:
|
|
511
|
-
) ->
|
|
508
|
+
kak: cirq.KakDecomposition, atol: float = 1e-8
|
|
509
|
+
) -> tuple[Sequence[tuple[np.ndarray, np.ndarray]], complex]:
|
|
512
510
|
"""Returns the single-qubit matrices for the 2-SQRT_ISWAP decomposition.
|
|
513
511
|
|
|
514
512
|
Assumes canonical x, y, z and x >= y + |z| within tolerance. For x, y, z
|
|
@@ -570,8 +568,8 @@ def _decomp_2sqrt_iswap_matrices(
|
|
|
570
568
|
|
|
571
569
|
|
|
572
570
|
def _decomp_3sqrt_iswap_matrices(
|
|
573
|
-
kak:
|
|
574
|
-
) ->
|
|
571
|
+
kak: cirq.KakDecomposition, atol: float = 1e-8
|
|
572
|
+
) -> tuple[Sequence[tuple[np.ndarray, np.ndarray]], complex]:
|
|
575
573
|
"""Returns the single-qubit matrices for the 3-SQRT_ISWAP decomposition.
|
|
576
574
|
|
|
577
575
|
Assumes any canonical x, y, z. Three sqrt-iSWAP gates are only needed if
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
"""Transformer pass that removes empty moments from a circuit."""
|
|
16
16
|
|
|
17
|
-
from
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from typing import TYPE_CHECKING
|
|
18
20
|
|
|
19
21
|
from cirq.transformers import transformer_api, transformer_primitives
|
|
20
22
|
|
|
@@ -24,8 +26,8 @@ if TYPE_CHECKING:
|
|
|
24
26
|
|
|
25
27
|
@transformer_api.transformer
|
|
26
28
|
def drop_empty_moments(
|
|
27
|
-
circuit:
|
|
28
|
-
) ->
|
|
29
|
+
circuit: cirq.AbstractCircuit, *, context: cirq.TransformerContext | None = None
|
|
30
|
+
) -> cirq.Circuit:
|
|
29
31
|
"""Removes empty moments from a circuit.
|
|
30
32
|
|
|
31
33
|
Args:
|
|
@@ -12,10 +12,12 @@
|
|
|
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 cirq
|
|
16
18
|
|
|
17
19
|
|
|
18
|
-
def test_drop():
|
|
20
|
+
def test_drop() -> None:
|
|
19
21
|
q1 = cirq.NamedQubit('q1')
|
|
20
22
|
q2 = cirq.NamedQubit('q2')
|
|
21
23
|
cirq.testing.assert_same_circuits(
|
|
@@ -28,7 +30,7 @@ def test_drop():
|
|
|
28
30
|
)
|
|
29
31
|
|
|
30
32
|
|
|
31
|
-
def test_drop_empty_moments():
|
|
33
|
+
def test_drop_empty_moments() -> None:
|
|
32
34
|
q1, q2 = cirq.LineQubit.range(2)
|
|
33
35
|
c_nested = cirq.FrozenCircuit(
|
|
34
36
|
cirq.Moment(), cirq.Moment(), cirq.Moment([cirq.CNOT(q1, q2)]), cirq.Moment()
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
"""Transformer pass that removes operations with tiny effects."""
|
|
16
16
|
|
|
17
|
-
from
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from typing import TYPE_CHECKING
|
|
18
20
|
|
|
19
21
|
from cirq import protocols
|
|
20
22
|
from cirq.transformers import transformer_api, transformer_primitives
|
|
@@ -25,11 +27,11 @@ if TYPE_CHECKING:
|
|
|
25
27
|
|
|
26
28
|
@transformer_api.transformer
|
|
27
29
|
def drop_negligible_operations(
|
|
28
|
-
circuit:
|
|
30
|
+
circuit: cirq.AbstractCircuit,
|
|
29
31
|
*,
|
|
30
|
-
context:
|
|
32
|
+
context: cirq.TransformerContext | None = None,
|
|
31
33
|
atol: float = 1e-8,
|
|
32
|
-
) ->
|
|
34
|
+
) -> cirq.Circuit:
|
|
33
35
|
"""Removes operations with tiny effects.
|
|
34
36
|
|
|
35
37
|
An operation `op` is considered to have a tiny effect if
|
|
@@ -47,7 +49,7 @@ def drop_negligible_operations(
|
|
|
47
49
|
if context is None:
|
|
48
50
|
context = transformer_api.TransformerContext()
|
|
49
51
|
|
|
50
|
-
def map_func(op:
|
|
52
|
+
def map_func(op: cirq.Operation, _: int) -> cirq.OP_TREE:
|
|
51
53
|
return (
|
|
52
54
|
op
|
|
53
55
|
if protocols.num_qubits(op) > 10
|
|
@@ -14,13 +14,16 @@
|
|
|
14
14
|
|
|
15
15
|
"""Transformer pass that adds dynamical decoupling operations to a circuit."""
|
|
16
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
17
19
|
from functools import reduce
|
|
18
20
|
from itertools import cycle
|
|
19
|
-
from typing import
|
|
21
|
+
from typing import TYPE_CHECKING
|
|
20
22
|
|
|
21
23
|
import numpy as np
|
|
22
24
|
|
|
23
|
-
from cirq import
|
|
25
|
+
from cirq import ops, protocols
|
|
26
|
+
from cirq.circuits import Circuit, FrozenCircuit, Moment
|
|
24
27
|
from cirq.protocols import unitary_protocol
|
|
25
28
|
from cirq.protocols.has_stabilizer_effect_protocol import has_stabilizer_effect
|
|
26
29
|
from cirq.protocols.has_unitary_protocol import has_unitary
|
|
@@ -31,7 +34,7 @@ if TYPE_CHECKING:
|
|
|
31
34
|
import cirq
|
|
32
35
|
|
|
33
36
|
|
|
34
|
-
def _get_dd_sequence_from_schema_name(schema: str) ->
|
|
37
|
+
def _get_dd_sequence_from_schema_name(schema: str) -> tuple[ops.Gate, ...]:
|
|
35
38
|
"""Gets dynamical decoupling sequence from a schema name."""
|
|
36
39
|
match schema:
|
|
37
40
|
case 'DEFAULT':
|
|
@@ -48,17 +51,17 @@ def _get_dd_sequence_from_schema_name(schema: str) -> Tuple[ops.Gate, ...]:
|
|
|
48
51
|
raise ValueError('Invalid schema name.')
|
|
49
52
|
|
|
50
53
|
|
|
51
|
-
def _pauli_up_to_global_phase(gate: ops.Gate) ->
|
|
54
|
+
def _pauli_up_to_global_phase(gate: ops.Gate) -> ops.Pauli | None:
|
|
52
55
|
for pauli_gate in [ops.X, ops.Y, ops.Z]:
|
|
53
56
|
if protocols.equal_up_to_global_phase(gate, pauli_gate):
|
|
54
57
|
return pauli_gate
|
|
55
58
|
return None
|
|
56
59
|
|
|
57
60
|
|
|
58
|
-
def _validate_dd_sequence(dd_sequence:
|
|
61
|
+
def _validate_dd_sequence(dd_sequence: tuple[ops.Gate, ...]) -> None:
|
|
59
62
|
"""Validates a given dynamical decoupling sequence.
|
|
60
63
|
|
|
61
|
-
The sequence should only
|
|
64
|
+
The sequence should only consist of Pauli gates and is essentially an identity gate.
|
|
62
65
|
|
|
63
66
|
Args:
|
|
64
67
|
dd_sequence: Input dynamical sequence to be validated.
|
|
@@ -79,14 +82,14 @@ def _validate_dd_sequence(dd_sequence: Tuple[ops.Gate, ...]) -> None:
|
|
|
79
82
|
|
|
80
83
|
if not protocols.equal_up_to_global_phase(product, np.eye(2)):
|
|
81
84
|
raise ValueError(
|
|
82
|
-
'Invalid dynamical decoupling sequence. Expect sequence
|
|
85
|
+
'Invalid dynamical decoupling sequence. Expect sequence product equals'
|
|
83
86
|
f' identity up to a global phase, got {product}.'.replace('\n', ' ')
|
|
84
87
|
)
|
|
85
88
|
|
|
86
89
|
|
|
87
90
|
def _parse_dd_sequence(
|
|
88
|
-
schema:
|
|
89
|
-
) ->
|
|
91
|
+
schema: str | tuple[ops.Gate, ...],
|
|
92
|
+
) -> tuple[tuple[ops.Gate, ...], dict[ops.Gate, ops.Pauli]]:
|
|
90
93
|
"""Parses and returns dynamical decoupling sequence and its associated pauli map from schema."""
|
|
91
94
|
dd_sequence = None
|
|
92
95
|
if isinstance(schema, str):
|
|
@@ -96,7 +99,7 @@ def _parse_dd_sequence(
|
|
|
96
99
|
dd_sequence = schema
|
|
97
100
|
|
|
98
101
|
# Map gate to Pauli gate. This is necessary as dd sequence might contain gates like X^-1.
|
|
99
|
-
pauli_map:
|
|
102
|
+
pauli_map: dict[ops.Gate, ops.Pauli] = {}
|
|
100
103
|
for gate in dd_sequence:
|
|
101
104
|
pauli_gate = _pauli_up_to_global_phase(gate)
|
|
102
105
|
if pauli_gate is not None:
|
|
@@ -111,7 +114,7 @@ def _is_single_qubit_operation(operation: ops.Operation) -> bool:
|
|
|
111
114
|
return len(operation.qubits) == 1
|
|
112
115
|
|
|
113
116
|
|
|
114
|
-
def _is_single_qubit_gate_moment(moment:
|
|
117
|
+
def _is_single_qubit_gate_moment(moment: Moment) -> bool:
|
|
115
118
|
return all(_is_single_qubit_operation(op) for op in moment)
|
|
116
119
|
|
|
117
120
|
|
|
@@ -119,10 +122,8 @@ def _is_clifford_op(op: ops.Operation) -> bool:
|
|
|
119
122
|
return has_unitary(op) and has_stabilizer_effect(op)
|
|
120
123
|
|
|
121
124
|
|
|
122
|
-
def _calc_busy_moment_range_of_each_qubit(
|
|
123
|
-
|
|
124
|
-
) -> Dict[ops.Qid, list[int]]:
|
|
125
|
-
busy_moment_range_by_qubit: Dict[ops.Qid, list[int]] = {
|
|
125
|
+
def _calc_busy_moment_range_of_each_qubit(circuit: FrozenCircuit) -> dict[ops.Qid, list[int]]:
|
|
126
|
+
busy_moment_range_by_qubit: dict[ops.Qid, list[int]] = {
|
|
126
127
|
q: [len(circuit), -1] for q in circuit.all_qubits()
|
|
127
128
|
}
|
|
128
129
|
for moment_id, moment in enumerate(circuit):
|
|
@@ -132,12 +133,12 @@ def _calc_busy_moment_range_of_each_qubit(
|
|
|
132
133
|
return busy_moment_range_by_qubit
|
|
133
134
|
|
|
134
135
|
|
|
135
|
-
def _is_insertable_moment(moment:
|
|
136
|
+
def _is_insertable_moment(moment: Moment, single_qubit_gate_moments_only: bool) -> bool:
|
|
136
137
|
return not single_qubit_gate_moments_only or _is_single_qubit_gate_moment(moment)
|
|
137
138
|
|
|
138
139
|
|
|
139
140
|
def _merge_single_qubit_ops_to_phxz(
|
|
140
|
-
q: ops.Qid, operations:
|
|
141
|
+
q: ops.Qid, operations: tuple[ops.Operation, ...]
|
|
141
142
|
) -> ops.Operation:
|
|
142
143
|
"""Merges [op1, op2, ...] and returns an equivalent op"""
|
|
143
144
|
if len(operations) == 1:
|
|
@@ -148,9 +149,7 @@ def _merge_single_qubit_ops_to_phxz(
|
|
|
148
149
|
return gate.on(q)
|
|
149
150
|
|
|
150
151
|
|
|
151
|
-
def _try_merge_single_qubit_ops_of_two_moments(
|
|
152
|
-
m1: circuits.Moment, m2: circuits.Moment
|
|
153
|
-
) -> Tuple[circuits.Moment, ...]:
|
|
152
|
+
def _try_merge_single_qubit_ops_of_two_moments(m1: Moment, m2: Moment) -> tuple[Moment, ...]:
|
|
154
153
|
"""Merge single qubit ops of 2 moments if possible, returns 2 moments otherwise."""
|
|
155
154
|
for q in m1.qubits & m2.qubits:
|
|
156
155
|
op1 = m1.operation_at(q)
|
|
@@ -167,12 +166,10 @@ def _try_merge_single_qubit_ops_of_two_moments(
|
|
|
167
166
|
# ops_on_q may contain 1 op or 2 ops.
|
|
168
167
|
ops_on_q = [op for op in [m.operation_at(q) for m in [m1, m2]] if op is not None]
|
|
169
168
|
merged_ops.add(_merge_single_qubit_ops_to_phxz(q, tuple(ops_on_q)))
|
|
170
|
-
return (
|
|
169
|
+
return (Moment(merged_ops),)
|
|
171
170
|
|
|
172
171
|
|
|
173
|
-
def _calc_pulled_through(
|
|
174
|
-
moment: circuits.Moment, input_pauli_ops: ops.PauliString
|
|
175
|
-
) -> ops.PauliString:
|
|
172
|
+
def _calc_pulled_through(moment: Moment, input_pauli_ops: ops.PauliString) -> ops.PauliString:
|
|
176
173
|
"""Calculates the pulled_through such that circuit(input_pauli_ops, moment.clifford_ops) is
|
|
177
174
|
equivalent to circuit(moment.clifford_ops, pulled_through).
|
|
178
175
|
"""
|
|
@@ -182,7 +179,7 @@ def _calc_pulled_through(
|
|
|
182
179
|
return input_pauli_ops.after(clifford_ops_in_moment)
|
|
183
180
|
|
|
184
181
|
|
|
185
|
-
def _get_stop_qubits(moment:
|
|
182
|
+
def _get_stop_qubits(moment: Moment) -> set[ops.Qid]:
|
|
186
183
|
stop_pulling_through_qubits: set[ops.Qid] = set()
|
|
187
184
|
for op in moment:
|
|
188
185
|
if (not _is_clifford_op(op) and not _is_single_qubit_operation(op)) or not has_unitary(
|
|
@@ -204,20 +201,20 @@ def _need_merge_pulled_through(op_at_q: ops.Operation, is_at_last_busy_moment: b
|
|
|
204
201
|
|
|
205
202
|
@transformer_api.transformer
|
|
206
203
|
def add_dynamical_decoupling(
|
|
207
|
-
circuit:
|
|
204
|
+
circuit: cirq.AbstractCircuit,
|
|
208
205
|
*,
|
|
209
|
-
context:
|
|
210
|
-
schema:
|
|
206
|
+
context: cirq.TransformerContext | None = None,
|
|
207
|
+
schema: str | tuple[ops.Gate, ...] = 'DEFAULT',
|
|
211
208
|
single_qubit_gate_moments_only: bool = True,
|
|
212
|
-
) ->
|
|
209
|
+
) -> cirq.Circuit:
|
|
213
210
|
"""Adds dynamical decoupling gate operations to a given circuit.
|
|
214
|
-
This transformer might add new moments thus change structure of the original circuit.
|
|
211
|
+
This transformer might add new moments and thus change the structure of the original circuit.
|
|
215
212
|
|
|
216
213
|
Args:
|
|
217
214
|
circuit: Input circuit to transform.
|
|
218
215
|
context: `cirq.TransformerContext` storing common configurable options for transformers.
|
|
219
216
|
schema: Dynamical decoupling schema name or a dynamical decoupling sequence.
|
|
220
|
-
If a schema is specified, provided dynamical
|
|
217
|
+
If a schema is specified, the provided dynamical decoupling sequence will be used.
|
|
221
218
|
Otherwise, customized dynamical decoupling sequence will be applied.
|
|
222
219
|
single_qubit_gate_moments_only: If set True, dynamical decoupling operation will only be
|
|
223
220
|
added in single-qubit gate moments.
|
|
@@ -231,7 +228,7 @@ def add_dynamical_decoupling(
|
|
|
231
228
|
busy_moment_range_by_qubit = _calc_busy_moment_range_of_each_qubit(orig_circuit)
|
|
232
229
|
|
|
233
230
|
# Stores all the moments of the output circuit chronologically.
|
|
234
|
-
transformed_moments: list[
|
|
231
|
+
transformed_moments: list[Moment] = []
|
|
235
232
|
# A PauliString stores the result of 'pulling' Pauli gates past each operations
|
|
236
233
|
# right before the current moment.
|
|
237
234
|
pulled_through: ops.PauliString = ops.PauliString()
|
|
@@ -274,17 +271,27 @@ def add_dynamical_decoupling(
|
|
|
274
271
|
dd_iter_by_qubits[q] = cycle(base_dd_sequence)
|
|
275
272
|
# Need to insert a new moment before current moment
|
|
276
273
|
if new_moment_ops:
|
|
277
|
-
# Fill insertable idle moments in the new moment using dd sequence
|
|
278
|
-
for q in orig_circuit.all_qubits() - stop_pulling_through_qubits:
|
|
279
|
-
if busy_moment_range_by_qubit[q][0] < moment_id <= busy_moment_range_by_qubit[q][1]:
|
|
280
|
-
new_moment_ops.append(_update_pulled_through(q, next(dd_iter_by_qubits[q])))
|
|
281
274
|
moments_to_be_appended = _try_merge_single_qubit_ops_of_two_moments(
|
|
282
|
-
transformed_moments
|
|
275
|
+
transformed_moments[-1], Moment(new_moment_ops)
|
|
283
276
|
)
|
|
284
|
-
|
|
277
|
+
if len(moments_to_be_appended) == 1:
|
|
278
|
+
transformed_moments.pop()
|
|
279
|
+
transformed_moments.append(moments_to_be_appended[0])
|
|
280
|
+
else: # Fill insertable idle moments in the new moment using dd sequence
|
|
281
|
+
for q in orig_circuit.all_qubits() - stop_pulling_through_qubits:
|
|
282
|
+
if (
|
|
283
|
+
busy_moment_range_by_qubit[q][0]
|
|
284
|
+
< moment_id
|
|
285
|
+
<= busy_moment_range_by_qubit[q][1]
|
|
286
|
+
):
|
|
287
|
+
new_moment_ops.append(_update_pulled_through(q, next(dd_iter_by_qubits[q])))
|
|
288
|
+
moments_to_be_appended = _try_merge_single_qubit_ops_of_two_moments(
|
|
289
|
+
transformed_moments.pop(), Moment(new_moment_ops)
|
|
290
|
+
)
|
|
291
|
+
transformed_moments.extend(moments_to_be_appended)
|
|
285
292
|
|
|
286
293
|
# Step 2, calc updated_moment with insertions / merges.
|
|
287
|
-
updated_moment_ops: set[
|
|
294
|
+
updated_moment_ops: set[cirq.Operation] = set()
|
|
288
295
|
for q in orig_circuit.all_qubits():
|
|
289
296
|
op_at_q = moment.operation_at(q)
|
|
290
297
|
remaining_pulled_through_gate = pulled_through.get(q)
|
|
@@ -313,7 +320,7 @@ def add_dynamical_decoupling(
|
|
|
313
320
|
updated_moment_ops.add(updated_op)
|
|
314
321
|
|
|
315
322
|
if updated_moment_ops:
|
|
316
|
-
updated_moment =
|
|
323
|
+
updated_moment = Moment(updated_moment_ops)
|
|
317
324
|
transformed_moments.append(updated_moment)
|
|
318
325
|
|
|
319
326
|
# Step 3, update pulled through.
|
|
@@ -327,8 +334,8 @@ def add_dynamical_decoupling(
|
|
|
327
334
|
if ending_moment_ops:
|
|
328
335
|
transformed_moments.extend(
|
|
329
336
|
_try_merge_single_qubit_ops_of_two_moments(
|
|
330
|
-
transformed_moments.pop(),
|
|
337
|
+
transformed_moments.pop(), Moment(ending_moment_ops)
|
|
331
338
|
)
|
|
332
339
|
)
|
|
333
340
|
|
|
334
|
-
return
|
|
341
|
+
return Circuit.from_moments(*transformed_moments)
|