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,7 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
"""Utility methods for efficiently preparing two qubit states."""
|
|
16
16
|
|
|
17
|
-
from
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from typing import TYPE_CHECKING
|
|
18
20
|
|
|
19
21
|
import numpy as np
|
|
20
22
|
|
|
@@ -38,12 +40,8 @@ def _1q_matrices_to_ops(g0, g1, q0, q1, include_identity=False):
|
|
|
38
40
|
|
|
39
41
|
|
|
40
42
|
def prepare_two_qubit_state_using_sqrt_iswap(
|
|
41
|
-
q0:
|
|
42
|
-
|
|
43
|
-
state: 'cirq.STATE_VECTOR_LIKE',
|
|
44
|
-
*,
|
|
45
|
-
use_sqrt_iswap_inv: bool = True,
|
|
46
|
-
) -> List['cirq.Operation']:
|
|
43
|
+
q0: cirq.Qid, q1: cirq.Qid, state: cirq.STATE_VECTOR_LIKE, *, use_sqrt_iswap_inv: bool = True
|
|
44
|
+
) -> list[cirq.Operation]:
|
|
47
45
|
"""Prepares the given 2q state from |00> using at-most 1 √iSWAP gate + single qubit rotations.
|
|
48
46
|
|
|
49
47
|
Entangled states are prepared using exactly 1 √iSWAP gate while product states are prepared
|
|
@@ -77,8 +75,8 @@ def prepare_two_qubit_state_using_sqrt_iswap(
|
|
|
77
75
|
|
|
78
76
|
|
|
79
77
|
def prepare_two_qubit_state_using_cz(
|
|
80
|
-
q0:
|
|
81
|
-
) ->
|
|
78
|
+
q0: cirq.Qid, q1: cirq.Qid, state: cirq.STATE_VECTOR_LIKE
|
|
79
|
+
) -> list[cirq.Operation]:
|
|
82
80
|
"""Prepares the given 2q state from |00> using at-most 1 CZ gate + single qubit rotations.
|
|
83
81
|
|
|
84
82
|
Entangled states are prepared using exactly 1 CZ gate while product states are prepared
|
|
@@ -110,8 +108,8 @@ def prepare_two_qubit_state_using_cz(
|
|
|
110
108
|
|
|
111
109
|
|
|
112
110
|
def prepare_two_qubit_state_using_iswap(
|
|
113
|
-
q0:
|
|
114
|
-
) ->
|
|
111
|
+
q0: cirq.Qid, q1: cirq.Qid, state: cirq.STATE_VECTOR_LIKE, use_iswap_inv: bool = False
|
|
112
|
+
) -> list[cirq.Operation]:
|
|
115
113
|
"""Prepares the given 2q state from |00> using at-most 1 ISWAP gate + single qubit rotations.
|
|
116
114
|
|
|
117
115
|
Entangled states are prepared using exactly 1 ISWAP gate while product states are prepared
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
"""Utility methods for decomposing two-qubit unitaries into CZ gates."""
|
|
16
16
|
|
|
17
|
-
from
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from typing import cast, Iterable, Sequence, TYPE_CHECKING
|
|
18
20
|
|
|
19
21
|
import numpy as np
|
|
20
22
|
|
|
@@ -24,15 +26,14 @@ from cirq.linalg.decompositions import extract_right_diag, num_cnots_required
|
|
|
24
26
|
from cirq.transformers.analytical_decompositions import single_qubit_decompositions
|
|
25
27
|
from cirq.transformers.eject_phased_paulis import eject_phased_paulis
|
|
26
28
|
from cirq.transformers.eject_z import eject_z
|
|
27
|
-
from cirq.transformers.merge_single_qubit_gates import merge_single_qubit_gates_to_phased_x_and_z
|
|
28
29
|
|
|
29
30
|
if TYPE_CHECKING:
|
|
30
31
|
import cirq
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
def _remove_partial_czs_or_fail(
|
|
34
|
-
operations: Iterable[
|
|
35
|
-
) ->
|
|
35
|
+
operations: Iterable[cirq.Operation], atol: float
|
|
36
|
+
) -> list[cirq.Operation]:
|
|
36
37
|
result = []
|
|
37
38
|
for op in operations:
|
|
38
39
|
if isinstance(op.gate, ops.CZPowGate):
|
|
@@ -49,13 +50,13 @@ def _remove_partial_czs_or_fail(
|
|
|
49
50
|
|
|
50
51
|
|
|
51
52
|
def two_qubit_matrix_to_cz_operations(
|
|
52
|
-
q0:
|
|
53
|
-
q1:
|
|
53
|
+
q0: cirq.Qid,
|
|
54
|
+
q1: cirq.Qid,
|
|
54
55
|
mat: np.ndarray,
|
|
55
56
|
allow_partial_czs: bool,
|
|
56
57
|
atol: float = 1e-8,
|
|
57
58
|
clean_operations: bool = True,
|
|
58
|
-
) ->
|
|
59
|
+
) -> list[ops.Operation]:
|
|
59
60
|
"""Decomposes a two-qubit operation into Z/XY/CZ gates.
|
|
60
61
|
|
|
61
62
|
Args:
|
|
@@ -79,19 +80,19 @@ def two_qubit_matrix_to_cz_operations(
|
|
|
79
80
|
if clean_operations:
|
|
80
81
|
if not allow_partial_czs:
|
|
81
82
|
# CZ^t is not allowed for any $t$ except $t=1$.
|
|
82
|
-
return _remove_partial_czs_or_fail(cleanup_operations(operations), atol=atol)
|
|
83
|
-
return cleanup_operations(operations)
|
|
83
|
+
return _remove_partial_czs_or_fail(cleanup_operations(operations, atol=atol), atol=atol)
|
|
84
|
+
return cleanup_operations(operations, atol=atol)
|
|
84
85
|
return operations
|
|
85
86
|
|
|
86
87
|
|
|
87
88
|
def two_qubit_matrix_to_diagonal_and_cz_operations(
|
|
88
|
-
q0:
|
|
89
|
-
q1:
|
|
89
|
+
q0: cirq.Qid,
|
|
90
|
+
q1: cirq.Qid,
|
|
90
91
|
mat: np.ndarray,
|
|
91
92
|
allow_partial_czs: bool = False,
|
|
92
93
|
atol: float = 1e-8,
|
|
93
94
|
clean_operations: bool = True,
|
|
94
|
-
) ->
|
|
95
|
+
) -> tuple[np.ndarray, list[cirq.Operation]]:
|
|
95
96
|
"""Decomposes a 2-qubit unitary to a diagonal and the remaining operations.
|
|
96
97
|
|
|
97
98
|
For a 2-qubit unitary V, return ops, a list of operations and
|
|
@@ -136,7 +137,7 @@ def two_qubit_matrix_to_diagonal_and_cz_operations(
|
|
|
136
137
|
)
|
|
137
138
|
|
|
138
139
|
|
|
139
|
-
def _xx_interaction_via_full_czs(q0:
|
|
140
|
+
def _xx_interaction_via_full_czs(q0: cirq.Qid, q1: cirq.Qid, x: float):
|
|
140
141
|
a = x * -2 / np.pi
|
|
141
142
|
yield ops.H(q1)
|
|
142
143
|
yield ops.CZ(q0, q1)
|
|
@@ -145,7 +146,7 @@ def _xx_interaction_via_full_czs(q0: 'cirq.Qid', q1: 'cirq.Qid', x: float):
|
|
|
145
146
|
yield ops.H(q1)
|
|
146
147
|
|
|
147
148
|
|
|
148
|
-
def _xx_yy_interaction_via_full_czs(q0:
|
|
149
|
+
def _xx_yy_interaction_via_full_czs(q0: cirq.Qid, q1: cirq.Qid, x: float, y: float):
|
|
149
150
|
a = x * -2 / np.pi
|
|
150
151
|
b = y * -2 / np.pi
|
|
151
152
|
yield ops.X(q0) ** 0.5
|
|
@@ -160,9 +161,7 @@ def _xx_yy_interaction_via_full_czs(q0: 'cirq.Qid', q1: 'cirq.Qid', x: float, y:
|
|
|
160
161
|
yield ops.X(q0) ** -0.5
|
|
161
162
|
|
|
162
163
|
|
|
163
|
-
def _xx_yy_zz_interaction_via_full_czs(
|
|
164
|
-
q0: 'cirq.Qid', q1: 'cirq.Qid', x: float, y: float, z: float
|
|
165
|
-
):
|
|
164
|
+
def _xx_yy_zz_interaction_via_full_czs(q0: cirq.Qid, q1: cirq.Qid, x: float, y: float, z: float):
|
|
166
165
|
a = x * -2 / np.pi + 0.5
|
|
167
166
|
b = y * -2 / np.pi + 0.5
|
|
168
167
|
c = z * -2 / np.pi + 0.5
|
|
@@ -182,22 +181,87 @@ def _xx_yy_zz_interaction_via_full_czs(
|
|
|
182
181
|
yield ops.H(q1)
|
|
183
182
|
|
|
184
183
|
|
|
185
|
-
def cleanup_operations(operations: Sequence[ops.Operation]):
|
|
184
|
+
def cleanup_operations(operations: Sequence[ops.Operation], atol: float = 1e-8):
|
|
185
|
+
operations = _merge_single_qubit_gates(operations, atol=atol)
|
|
186
186
|
circuit = circuits.Circuit(operations)
|
|
187
|
-
circuit = merge_single_qubit_gates_to_phased_x_and_z(circuit)
|
|
188
187
|
circuit = eject_phased_paulis(circuit)
|
|
189
188
|
circuit = eject_z(circuit)
|
|
190
189
|
circuit = circuits.Circuit(circuit.all_operations(), strategy=circuits.InsertStrategy.EARLIEST)
|
|
191
190
|
return list(circuit.all_operations())
|
|
192
191
|
|
|
193
192
|
|
|
193
|
+
def _transform_single_qubit_operations_to_phased_x_and_z(
|
|
194
|
+
operations: Sequence[ops.Operation], atol: float
|
|
195
|
+
) -> Sequence[ops.Operation]:
|
|
196
|
+
"""Transforms operations on the same qubit to a PhasedXPowGate followed by a Z gate.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
operations: sequence of operations on the same qubit
|
|
200
|
+
atol: a limit on the amount of absolute error introduced by the
|
|
201
|
+
transformation.
|
|
202
|
+
Returns:
|
|
203
|
+
A PhasedXPowGate followed by a Z gate. If one the gates is not needed, it will be omitted.
|
|
204
|
+
"""
|
|
205
|
+
u = np.eye(2)
|
|
206
|
+
for op in operations:
|
|
207
|
+
u = protocols.unitary(op) @ u
|
|
208
|
+
return [
|
|
209
|
+
g(op.qubits[0])
|
|
210
|
+
for g in single_qubit_decompositions.single_qubit_matrix_to_phased_x_z(u, atol=atol)
|
|
211
|
+
]
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _merge_single_qubit_gates(
|
|
215
|
+
operations: Sequence[ops.Operation], atol: float
|
|
216
|
+
) -> Sequence[ops.Operation]:
|
|
217
|
+
"""Merge consecutive single qubit gates.
|
|
218
|
+
|
|
219
|
+
Traverses the sequence of operations maintaining a list of consecutive single qubit
|
|
220
|
+
operations for each qubit. When a 2-qubit gate is encountered, it transforms pending
|
|
221
|
+
operations to a PhasedXPowGate followed by a Z gate.
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
operations: sequence of operations
|
|
225
|
+
atol: a limit on the amount of absolute error introduced by the
|
|
226
|
+
transformation.
|
|
227
|
+
Returns:
|
|
228
|
+
new sequence of operations after merging gates
|
|
229
|
+
|
|
230
|
+
Raises:
|
|
231
|
+
ValueError: if one of the operations is not on 1 or 2 qubits
|
|
232
|
+
"""
|
|
233
|
+
merged_ops: list[ops.Operation] = []
|
|
234
|
+
pending_ops: dict[tuple[cirq.Qid, ...], list[ops.Operation]] = dict()
|
|
235
|
+
for op in operations:
|
|
236
|
+
if protocols.num_qubits(op) == 2:
|
|
237
|
+
for qubit_ops in pending_ops.values():
|
|
238
|
+
merged_ops.extend(
|
|
239
|
+
_transform_single_qubit_operations_to_phased_x_and_z(qubit_ops, atol=atol)
|
|
240
|
+
)
|
|
241
|
+
pending_ops.clear()
|
|
242
|
+
# Add the 2-qubit gate
|
|
243
|
+
merged_ops.append(op)
|
|
244
|
+
elif protocols.num_qubits(op) == 1:
|
|
245
|
+
if op.qubits not in pending_ops:
|
|
246
|
+
pending_ops[op.qubits] = []
|
|
247
|
+
pending_ops[op.qubits].append(op)
|
|
248
|
+
else:
|
|
249
|
+
raise ValueError(f'operation is on {protocols.num_qubits(op)} qubits, expected 1 or 2')
|
|
250
|
+
# Merge remaining pending operations
|
|
251
|
+
for qubit_ops in pending_ops.values():
|
|
252
|
+
merged_ops.extend(
|
|
253
|
+
_transform_single_qubit_operations_to_phased_x_and_z(qubit_ops, atol=atol)
|
|
254
|
+
)
|
|
255
|
+
return merged_ops
|
|
256
|
+
|
|
257
|
+
|
|
194
258
|
def _kak_decomposition_to_operations(
|
|
195
|
-
q0:
|
|
196
|
-
q1:
|
|
259
|
+
q0: cirq.Qid,
|
|
260
|
+
q1: cirq.Qid,
|
|
197
261
|
kak: linalg.KakDecomposition,
|
|
198
262
|
allow_partial_czs: bool,
|
|
199
263
|
atol: float = 1e-8,
|
|
200
|
-
) ->
|
|
264
|
+
) -> list[ops.Operation]:
|
|
201
265
|
"""Assumes that the decomposition is canonical."""
|
|
202
266
|
b0, b1 = kak.single_qubit_operations_before
|
|
203
267
|
pre = [_do_single_on(b0, q0, atol=atol), _do_single_on(b1, q1, atol=atol)]
|
|
@@ -232,7 +296,7 @@ def _is_trivial_angle(rad: float, atol: float) -> bool:
|
|
|
232
296
|
|
|
233
297
|
|
|
234
298
|
def _parity_interaction(
|
|
235
|
-
q0:
|
|
299
|
+
q0: cirq.Qid, q1: cirq.Qid, rads: float, atol: float, gate: ops.Gate | None = None
|
|
236
300
|
):
|
|
237
301
|
"""Yields a ZZ interaction framed by the given operation."""
|
|
238
302
|
if abs(rads) < atol:
|
|
@@ -255,15 +319,15 @@ def _parity_interaction(
|
|
|
255
319
|
yield g.on(q0), g.on(q1)
|
|
256
320
|
|
|
257
321
|
|
|
258
|
-
def _do_single_on(u: np.ndarray, q:
|
|
322
|
+
def _do_single_on(u: np.ndarray, q: cirq.Qid, atol: float = 1e-8):
|
|
259
323
|
for gate in single_qubit_decompositions.single_qubit_matrix_to_gates(u, atol):
|
|
260
324
|
yield gate(q)
|
|
261
325
|
|
|
262
326
|
|
|
263
327
|
def _non_local_part(
|
|
264
|
-
q0:
|
|
265
|
-
q1:
|
|
266
|
-
interaction_coefficients:
|
|
328
|
+
q0: cirq.Qid,
|
|
329
|
+
q1: cirq.Qid,
|
|
330
|
+
interaction_coefficients: tuple[float, float, float],
|
|
267
331
|
allow_partial_czs: bool,
|
|
268
332
|
atol: float = 1e-8,
|
|
269
333
|
):
|
|
@@ -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 cmath
|
|
16
18
|
import random
|
|
17
19
|
|
|
@@ -24,6 +26,7 @@ from cirq.testing import random_two_qubit_circuit_with_czs
|
|
|
24
26
|
from cirq.transformers.analytical_decompositions.two_qubit_to_cz import (
|
|
25
27
|
_is_trivial_angle,
|
|
26
28
|
_parity_interaction,
|
|
29
|
+
cleanup_operations,
|
|
27
30
|
two_qubit_matrix_to_diagonal_and_cz_operations,
|
|
28
31
|
)
|
|
29
32
|
|
|
@@ -52,7 +55,7 @@ from cirq.transformers.analytical_decompositions.two_qubit_to_cz import (
|
|
|
52
55
|
]
|
|
53
56
|
)(1e-8 * 2 / 3, 1e-8 * 4 / 3),
|
|
54
57
|
)
|
|
55
|
-
def test_is_trivial_angle(rad, expected):
|
|
58
|
+
def test_is_trivial_angle(rad, expected) -> None:
|
|
56
59
|
tolerance = 1e-8
|
|
57
60
|
out = _is_trivial_angle(rad, tolerance)
|
|
58
61
|
assert out == expected, f'rad = {rad}'
|
|
@@ -149,7 +152,7 @@ def assert_ops_implement_unitary(q0, q1, operations, intended_effect, atol=0.01)
|
|
|
149
152
|
)
|
|
150
153
|
def test_two_to_ops_equivalent_and_bounded_for_known_and_random(
|
|
151
154
|
max_partial_cz_depth, max_full_cz_depth, effect
|
|
152
|
-
):
|
|
155
|
+
) -> None:
|
|
153
156
|
q0 = cirq.NamedQubit('q0')
|
|
154
157
|
q1 = cirq.NamedQubit('q1')
|
|
155
158
|
|
|
@@ -163,7 +166,7 @@ def test_two_to_ops_equivalent_and_bounded_for_known_and_random(
|
|
|
163
166
|
assert_cz_depth_below(operations_with_full, max_full_cz_depth, True)
|
|
164
167
|
|
|
165
168
|
|
|
166
|
-
def test_trivial_parity_interaction_corner_case():
|
|
169
|
+
def test_trivial_parity_interaction_corner_case() -> None:
|
|
167
170
|
q0 = cirq.NamedQubit('q0')
|
|
168
171
|
q1 = cirq.NamedQubit('q1')
|
|
169
172
|
nearPi4 = np.pi / 4 * 0.99
|
|
@@ -172,7 +175,7 @@ def test_trivial_parity_interaction_corner_case():
|
|
|
172
175
|
assert len(circuit) == 2
|
|
173
176
|
|
|
174
177
|
|
|
175
|
-
def test_kak_decomposition_depth_full_cz():
|
|
178
|
+
def test_kak_decomposition_depth_full_cz() -> None:
|
|
176
179
|
a, b = cirq.LineQubit.range(2)
|
|
177
180
|
|
|
178
181
|
# Random.
|
|
@@ -210,7 +213,7 @@ def test_kak_decomposition_depth_full_cz():
|
|
|
210
213
|
assert len(c) <= 4
|
|
211
214
|
|
|
212
215
|
|
|
213
|
-
def test_kak_decomposition_depth_partial_cz():
|
|
216
|
+
def test_kak_decomposition_depth_partial_cz() -> None:
|
|
214
217
|
a, b = cirq.LineQubit.range(2)
|
|
215
218
|
|
|
216
219
|
# Random.
|
|
@@ -250,7 +253,7 @@ def test_kak_decomposition_depth_partial_cz():
|
|
|
250
253
|
np.diag(np.exp(1j * np.pi * np.random.random(4))),
|
|
251
254
|
],
|
|
252
255
|
)
|
|
253
|
-
def test_decompose_to_diagonal_and_circuit(v):
|
|
256
|
+
def test_decompose_to_diagonal_and_circuit(v) -> None:
|
|
254
257
|
b, c = cirq.LineQubit.range(2)
|
|
255
258
|
diagonal, ops = two_qubit_matrix_to_diagonal_and_cz_operations(b, c, v, atol=1e-8)
|
|
256
259
|
assert cirq.is_diagonal(diagonal)
|
|
@@ -259,7 +262,25 @@ def test_decompose_to_diagonal_and_circuit(v):
|
|
|
259
262
|
cirq.testing.assert_allclose_up_to_global_phase(circuit_unitary, v, atol=2e-6)
|
|
260
263
|
|
|
261
264
|
|
|
262
|
-
|
|
265
|
+
@pytest.mark.parametrize(
|
|
266
|
+
"mat, num_czs",
|
|
267
|
+
[
|
|
268
|
+
(cirq.unitary(random_two_qubit_circuit_with_czs(3)), 2),
|
|
269
|
+
(cirq.unitary(random_two_qubit_circuit_with_czs(2)), 2),
|
|
270
|
+
(cirq.unitary(random_two_qubit_circuit_with_czs(1)), 1),
|
|
271
|
+
(cirq.unitary(random_two_qubit_circuit_with_czs(0)), 0),
|
|
272
|
+
],
|
|
273
|
+
)
|
|
274
|
+
def test_decompose_to_diagonal_and_circuit_returns_circuit_with_expected_number_of_czs(
|
|
275
|
+
mat, num_czs
|
|
276
|
+
):
|
|
277
|
+
b, c = cirq.LineQubit.range(2)
|
|
278
|
+
_, ops = two_qubit_matrix_to_diagonal_and_cz_operations(b, c, mat, atol=1e-8)
|
|
279
|
+
circuit = cirq.Circuit(ops)
|
|
280
|
+
assert len(list(circuit.findall_operations_with_gate_type(cirq.CZPowGate))) == num_czs
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def test_remove_partial_czs_or_fail() -> None:
|
|
263
284
|
CZ = cirq.CZ(*cirq.LineQubit.range(2))
|
|
264
285
|
assert (
|
|
265
286
|
cirq.transformers.analytical_decompositions.two_qubit_to_cz._remove_partial_czs_or_fail(
|
|
@@ -274,3 +295,11 @@ def test_remove_partial_czs_or_fail():
|
|
|
274
295
|
_ = cirq.transformers.analytical_decompositions.two_qubit_to_cz._remove_partial_czs_or_fail(
|
|
275
296
|
[CZ**-0.5], atol=1e-9
|
|
276
297
|
)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
@pytest.mark.parametrize("gate", [cirq.CCZ, cirq.GlobalPhaseGate(1.0)])
|
|
301
|
+
def test_cleanup_operations_raises_if_op_not_on_1_or_2_qubits(gate: cirq.Gate) -> None:
|
|
302
|
+
qubits = cirq.LineQubit.range(gate.num_qubits())
|
|
303
|
+
op = gate.on(*qubits)
|
|
304
|
+
with pytest.raises(ValueError, match="expected 1 or 2"):
|
|
305
|
+
cleanup_operations([op], atol=1e-8)
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
"""Utility methods for decomposing two-qubit unitaries into FSim gates."""
|
|
16
16
|
|
|
17
|
-
from
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from typing import Iterable, Iterator, Sequence, TYPE_CHECKING
|
|
18
20
|
|
|
19
21
|
import numpy as np
|
|
20
22
|
|
|
@@ -25,11 +27,11 @@ if TYPE_CHECKING:
|
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
def decompose_two_qubit_interaction_into_four_fsim_gates(
|
|
28
|
-
interaction:
|
|
30
|
+
interaction: cirq.SupportsUnitary | np.ndarray,
|
|
29
31
|
*,
|
|
30
|
-
fsim_gate:
|
|
31
|
-
qubits:
|
|
32
|
-
) ->
|
|
32
|
+
fsim_gate: cirq.FSimGate | cirq.ISwapPowGate,
|
|
33
|
+
qubits: Sequence[cirq.Qid] | None = None,
|
|
34
|
+
) -> cirq.Circuit:
|
|
33
35
|
"""Decomposes operations into an FSimGate near theta=pi/2, phi=0.
|
|
34
36
|
|
|
35
37
|
This decomposition is guaranteed to use exactly four of the given FSim
|
|
@@ -98,7 +100,7 @@ def decompose_two_qubit_interaction_into_four_fsim_gates(
|
|
|
98
100
|
return result
|
|
99
101
|
|
|
100
102
|
|
|
101
|
-
def _sticky_0_to_1(v: float, *, atol: float) ->
|
|
103
|
+
def _sticky_0_to_1(v: float, *, atol: float) -> float | None:
|
|
102
104
|
if 0 <= v <= 1:
|
|
103
105
|
return v
|
|
104
106
|
if 1 < v <= 1 + atol:
|
|
@@ -110,12 +112,12 @@ def _sticky_0_to_1(v: float, *, atol: float) -> Optional[float]:
|
|
|
110
112
|
|
|
111
113
|
def _decompose_xx_yy_into_two_fsims_ignoring_single_qubit_ops(
|
|
112
114
|
*,
|
|
113
|
-
qubits: Sequence[
|
|
114
|
-
fsim_gate:
|
|
115
|
+
qubits: Sequence[cirq.Qid],
|
|
116
|
+
fsim_gate: cirq.FSimGate,
|
|
115
117
|
canonical_x_kak_coefficient: float,
|
|
116
118
|
canonical_y_kak_coefficient: float,
|
|
117
119
|
atol: float = 1e-8,
|
|
118
|
-
) ->
|
|
120
|
+
) -> list[cirq.Operation]:
|
|
119
121
|
x = canonical_x_kak_coefficient
|
|
120
122
|
y = canonical_y_kak_coefficient
|
|
121
123
|
assert 0 <= y <= x <= np.pi / 4
|
|
@@ -174,10 +176,10 @@ _B = _BGate()
|
|
|
174
176
|
|
|
175
177
|
|
|
176
178
|
def _decompose_two_qubit_interaction_into_two_b_gates(
|
|
177
|
-
interaction:
|
|
179
|
+
interaction: cirq.SupportsUnitary | np.ndarray | cirq.KakDecomposition,
|
|
178
180
|
*,
|
|
179
|
-
qubits: Sequence[
|
|
180
|
-
) ->
|
|
181
|
+
qubits: Sequence[cirq.Qid],
|
|
182
|
+
) -> list[cirq.Operation]:
|
|
181
183
|
kak = linalg.kak_decomposition(interaction)
|
|
182
184
|
|
|
183
185
|
result = _decompose_interaction_into_two_b_gates_ignoring_single_qubit_ops(
|
|
@@ -192,8 +194,8 @@ def _decompose_two_qubit_interaction_into_two_b_gates(
|
|
|
192
194
|
|
|
193
195
|
|
|
194
196
|
def _decompose_b_gate_into_two_fsims(
|
|
195
|
-
*, fsim_gate:
|
|
196
|
-
) ->
|
|
197
|
+
*, fsim_gate: cirq.FSimGate, qubits: Sequence[cirq.Qid]
|
|
198
|
+
) -> list[cirq.Operation]:
|
|
197
199
|
kak = linalg.kak_decomposition(_B)
|
|
198
200
|
|
|
199
201
|
result = _decompose_xx_yy_into_two_fsims_ignoring_single_qubit_ops(
|
|
@@ -211,8 +213,8 @@ def _decompose_b_gate_into_two_fsims(
|
|
|
211
213
|
|
|
212
214
|
|
|
213
215
|
def _decompose_interaction_into_two_b_gates_ignoring_single_qubit_ops(
|
|
214
|
-
qubits: Sequence[
|
|
215
|
-
) ->
|
|
216
|
+
qubits: Sequence[cirq.Qid], kak_interaction_coefficients: Iterable[float]
|
|
217
|
+
) -> list[cirq.Operation]:
|
|
216
218
|
"""Decompose using a minimal construction of two-qubit operations.
|
|
217
219
|
|
|
218
220
|
References:
|
|
@@ -236,11 +238,8 @@ def _decompose_interaction_into_two_b_gates_ignoring_single_qubit_ops(
|
|
|
236
238
|
|
|
237
239
|
|
|
238
240
|
def _fix_single_qubit_gates_around_kak_interaction(
|
|
239
|
-
*,
|
|
240
|
-
|
|
241
|
-
operations: List['cirq.Operation'],
|
|
242
|
-
qubits: Sequence['cirq.Qid'],
|
|
243
|
-
) -> Iterator['cirq.Operation']:
|
|
241
|
+
*, desired: cirq.KakDecomposition, operations: list[cirq.Operation], qubits: Sequence[cirq.Qid]
|
|
242
|
+
) -> Iterator[cirq.Operation]:
|
|
244
243
|
"""Adds single qubit operations to complete a desired interaction.
|
|
245
244
|
|
|
246
245
|
Args:
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import itertools
|
|
16
18
|
import random
|
|
17
19
|
from typing import Any
|
|
@@ -65,7 +67,7 @@ FEASIBLE_FSIM_GATES = [
|
|
|
65
67
|
|
|
66
68
|
|
|
67
69
|
@pytest.mark.parametrize('obj', UNITARY_OBJS)
|
|
68
|
-
def test_decompose_two_qubit_interaction_into_two_b_gates(obj: Any):
|
|
70
|
+
def test_decompose_two_qubit_interaction_into_two_b_gates(obj: Any) -> None:
|
|
69
71
|
circuit = cirq.Circuit(
|
|
70
72
|
_decompose_two_qubit_interaction_into_two_b_gates(obj, qubits=cirq.LineQubit.range(2))
|
|
71
73
|
)
|
|
@@ -75,7 +77,7 @@ def test_decompose_two_qubit_interaction_into_two_b_gates(obj: Any):
|
|
|
75
77
|
np.testing.assert_allclose(cirq.unitary(circuit), desired_unitary, atol=1e-6)
|
|
76
78
|
|
|
77
79
|
|
|
78
|
-
def test_decompose_xx_yy_into_two_fsims_ignoring_single_qubit_ops_fail():
|
|
80
|
+
def test_decompose_xx_yy_into_two_fsims_ignoring_single_qubit_ops_fail() -> None:
|
|
79
81
|
c = _decompose_xx_yy_into_two_fsims_ignoring_single_qubit_ops(
|
|
80
82
|
qubits=cirq.LineQubit.range(2),
|
|
81
83
|
fsim_gate=cirq.FSimGate(theta=np.pi / 2, phi=0),
|
|
@@ -98,7 +100,7 @@ def test_decompose_xx_yy_into_two_fsims_ignoring_single_qubit_ops_fail():
|
|
|
98
100
|
@pytest.mark.parametrize('obj,fsim_gate', itertools.product(UNITARY_OBJS, FEASIBLE_FSIM_GATES))
|
|
99
101
|
def test_decompose_two_qubit_interaction_into_four_fsim_gates_equivalence(
|
|
100
102
|
obj: Any, fsim_gate: cirq.FSimGate
|
|
101
|
-
):
|
|
103
|
+
) -> None:
|
|
102
104
|
qubits = obj.qubits if isinstance(obj, cirq.Operation) else cirq.LineQubit.range(2)
|
|
103
105
|
circuit = cirq.decompose_two_qubit_interaction_into_four_fsim_gates(obj, fsim_gate=fsim_gate)
|
|
104
106
|
desired_unitary = obj if isinstance(obj, np.ndarray) else cirq.unitary(obj)
|
|
@@ -108,7 +110,7 @@ def test_decompose_two_qubit_interaction_into_four_fsim_gates_equivalence(
|
|
|
108
110
|
assert cirq.approx_eq(circuit.unitary(qubit_order=qubits), desired_unitary, atol=1e-4)
|
|
109
111
|
|
|
110
112
|
|
|
111
|
-
def test_decompose_two_qubit_interaction_into_four_fsim_gates_validate():
|
|
113
|
+
def test_decompose_two_qubit_interaction_into_four_fsim_gates_validate() -> None:
|
|
112
114
|
iswap = cirq.FSimGate(theta=np.pi / 2, phi=0)
|
|
113
115
|
with pytest.raises(ValueError, match='fsim_gate.theta'):
|
|
114
116
|
cirq.decompose_two_qubit_interaction_into_four_fsim_gates(
|
|
@@ -127,7 +129,7 @@ def test_decompose_two_qubit_interaction_into_four_fsim_gates_validate():
|
|
|
127
129
|
cirq.decompose_two_qubit_interaction_into_four_fsim_gates(np.eye(4), fsim_gate=fsim)
|
|
128
130
|
|
|
129
131
|
|
|
130
|
-
def test_decompose_two_qubit_interaction_into_four_fsim_gates():
|
|
132
|
+
def test_decompose_two_qubit_interaction_into_four_fsim_gates() -> None:
|
|
131
133
|
iswap = cirq.FSimGate(theta=np.pi / 2, phi=0)
|
|
132
134
|
|
|
133
135
|
# Defaults to line qubits.
|
|
@@ -153,7 +155,7 @@ def test_decompose_two_qubit_interaction_into_four_fsim_gates():
|
|
|
153
155
|
assert set(c.all_qubits()) == set(cirq.LineQubit.range(10, 12))
|
|
154
156
|
|
|
155
157
|
|
|
156
|
-
def test_sticky_0_to_1():
|
|
158
|
+
def test_sticky_0_to_1() -> None:
|
|
157
159
|
assert _sticky_0_to_1(-1, atol=1e-8) is None
|
|
158
160
|
|
|
159
161
|
assert _sticky_0_to_1(-1e-6, atol=1e-8) is None
|
|
@@ -19,24 +19,22 @@ Gate compilation methods implemented here are following the paper below:
|
|
|
19
19
|
arXiv:1603.07678
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
|
-
from
|
|
22
|
+
from __future__ import annotations
|
|
23
23
|
|
|
24
|
-
import
|
|
24
|
+
from typing import cast, Iterable, TYPE_CHECKING
|
|
25
25
|
|
|
26
26
|
from cirq import linalg, ops, protocols
|
|
27
27
|
from cirq.transformers.analytical_decompositions import single_qubit_decompositions, two_qubit_to_cz
|
|
28
28
|
|
|
29
29
|
if TYPE_CHECKING:
|
|
30
|
+
import numpy as np
|
|
31
|
+
|
|
30
32
|
import cirq
|
|
31
33
|
|
|
32
34
|
|
|
33
35
|
def two_qubit_matrix_to_ion_operations(
|
|
34
|
-
q0:
|
|
35
|
-
|
|
36
|
-
mat: np.ndarray,
|
|
37
|
-
atol: float = 1e-8,
|
|
38
|
-
clean_operations: bool = True,
|
|
39
|
-
) -> List[ops.Operation]:
|
|
36
|
+
q0: cirq.Qid, q1: cirq.Qid, mat: np.ndarray, atol: float = 1e-8, clean_operations: bool = True
|
|
37
|
+
) -> list[ops.Operation]:
|
|
40
38
|
"""Decomposes a two-qubit operation into MS/single-qubit rotation gates.
|
|
41
39
|
|
|
42
40
|
Args:
|
|
@@ -56,8 +54,8 @@ def two_qubit_matrix_to_ion_operations(
|
|
|
56
54
|
|
|
57
55
|
|
|
58
56
|
def _kak_decomposition_to_operations(
|
|
59
|
-
q0:
|
|
60
|
-
) ->
|
|
57
|
+
q0: cirq.Qid, q1: cirq.Qid, kak: linalg.KakDecomposition, atol: float = 1e-8
|
|
58
|
+
) -> list[ops.Operation]:
|
|
61
59
|
"""Assumes that the decomposition is canonical."""
|
|
62
60
|
b0, b1 = kak.single_qubit_operations_before
|
|
63
61
|
pre = [_do_single_on(b0, q0, atol), _do_single_on(b1, q1, atol)]
|
|
@@ -74,13 +72,13 @@ def _kak_decomposition_to_operations(
|
|
|
74
72
|
)
|
|
75
73
|
|
|
76
74
|
|
|
77
|
-
def _do_single_on(u: np.ndarray, q:
|
|
75
|
+
def _do_single_on(u: np.ndarray, q: cirq.Qid, atol: float = 1e-8):
|
|
78
76
|
for gate in single_qubit_decompositions.single_qubit_matrix_to_gates(u, atol):
|
|
79
77
|
yield gate(q)
|
|
80
78
|
|
|
81
79
|
|
|
82
80
|
def _parity_interaction(
|
|
83
|
-
q0:
|
|
81
|
+
q0: cirq.Qid, q1: cirq.Qid, rads: float, atol: float, gate: ops.Gate | None = None
|
|
84
82
|
):
|
|
85
83
|
"""Yields an XX interaction framed by the given operation."""
|
|
86
84
|
|
|
@@ -98,9 +96,9 @@ def _parity_interaction(
|
|
|
98
96
|
|
|
99
97
|
|
|
100
98
|
def _non_local_part(
|
|
101
|
-
q0:
|
|
102
|
-
q1:
|
|
103
|
-
interaction_coefficients:
|
|
99
|
+
q0: cirq.Qid,
|
|
100
|
+
q1: cirq.Qid,
|
|
101
|
+
interaction_coefficients: tuple[float, float, float],
|
|
104
102
|
atol: float = 1e-8,
|
|
105
103
|
):
|
|
106
104
|
"""Yields non-local operation of KAK decomposition."""
|
|
@@ -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 random
|
|
16
18
|
|
|
17
19
|
import numpy as np
|
|
@@ -130,7 +132,7 @@ def assert_ms_depth_below(operations, threshold):
|
|
|
130
132
|
(2, _random_double_MS_effect()) for _ in range(10)
|
|
131
133
|
])
|
|
132
134
|
# yapf: enable
|
|
133
|
-
def test_two_to_ops(max_ms_depth: int, effect: np.ndarray):
|
|
135
|
+
def test_two_to_ops(max_ms_depth: int, effect: np.ndarray) -> None:
|
|
134
136
|
q0 = cirq.NamedQubit('q0')
|
|
135
137
|
q1 = cirq.NamedQubit('q1')
|
|
136
138
|
|