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
|
@@ -12,38 +12,39 @@
|
|
|
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 dataclasses
|
|
16
18
|
import functools
|
|
17
19
|
import itertools
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
cast,
|
|
21
|
-
Dict,
|
|
22
|
-
Iterator,
|
|
23
|
-
List,
|
|
24
|
-
Mapping,
|
|
25
|
-
Optional,
|
|
26
|
-
Sequence,
|
|
27
|
-
Tuple,
|
|
28
|
-
TYPE_CHECKING,
|
|
29
|
-
)
|
|
20
|
+
import uuid
|
|
21
|
+
from typing import Any, cast, Iterator, Mapping, Sequence, TYPE_CHECKING
|
|
30
22
|
|
|
23
|
+
import attrs
|
|
31
24
|
import numpy as np
|
|
32
25
|
from matplotlib import pyplot as plt
|
|
33
26
|
|
|
34
27
|
# this is for older systems with matplotlib <3.2 otherwise 3d projections fail
|
|
35
|
-
from mpl_toolkits import mplot3d
|
|
36
28
|
from scipy.optimize import curve_fit
|
|
37
29
|
|
|
38
30
|
import cirq.vis.heatmap as cirq_heatmap
|
|
39
31
|
import cirq.vis.histogram as cirq_histogram
|
|
40
32
|
from cirq import circuits, ops, protocols
|
|
33
|
+
from cirq._compat import deprecated
|
|
41
34
|
from cirq.devices import grid_qubit
|
|
42
35
|
|
|
43
36
|
if TYPE_CHECKING:
|
|
37
|
+
from mpl_toolkits import mplot3d
|
|
38
|
+
|
|
44
39
|
import cirq
|
|
45
40
|
|
|
46
41
|
|
|
42
|
+
def _canonize_clifford_sequences(
|
|
43
|
+
sequences: list[list[ops.SingleQubitCliffordGate]],
|
|
44
|
+
) -> list[list[ops.SingleQubitCliffordGate]]:
|
|
45
|
+
return [[_reduce_gate_seq(seq)] for seq in sequences]
|
|
46
|
+
|
|
47
|
+
|
|
47
48
|
@dataclasses.dataclass
|
|
48
49
|
class Cliffords:
|
|
49
50
|
"""The single-qubit Clifford group, decomposed into elementary gates.
|
|
@@ -62,11 +63,11 @@ class Cliffords:
|
|
|
62
63
|
s1_y
|
|
63
64
|
"""
|
|
64
65
|
|
|
65
|
-
c1_in_xy:
|
|
66
|
-
c1_in_xz:
|
|
67
|
-
s1:
|
|
68
|
-
s1_x:
|
|
69
|
-
s1_y:
|
|
66
|
+
c1_in_xy: list[list[ops.SingleQubitCliffordGate]]
|
|
67
|
+
c1_in_xz: list[list[ops.SingleQubitCliffordGate]]
|
|
68
|
+
s1: list[list[ops.SingleQubitCliffordGate]]
|
|
69
|
+
s1_x: list[list[ops.SingleQubitCliffordGate]]
|
|
70
|
+
s1_y: list[list[ops.SingleQubitCliffordGate]]
|
|
70
71
|
|
|
71
72
|
|
|
72
73
|
class RandomizedBenchMarkResult:
|
|
@@ -85,14 +86,14 @@ class RandomizedBenchMarkResult:
|
|
|
85
86
|
self._gnd_state_probs = ground_state_probabilities
|
|
86
87
|
|
|
87
88
|
@property
|
|
88
|
-
def data(self) -> Sequence[
|
|
89
|
+
def data(self) -> Sequence[tuple[int, float]]:
|
|
89
90
|
"""Returns a sequence of tuple pairs with the first item being a
|
|
90
91
|
number of Cliffords and the second item being the corresponding average
|
|
91
92
|
ground state probability.
|
|
92
93
|
"""
|
|
93
94
|
return [(num, prob) for num, prob in zip(self._num_cfds_seq, self._gnd_state_probs)]
|
|
94
95
|
|
|
95
|
-
def plot(self, ax:
|
|
96
|
+
def plot(self, ax: plt.Axes | None = None, **plot_kwargs: Any) -> plt.Axes:
|
|
96
97
|
"""Plots the average ground state probability vs the number of
|
|
97
98
|
Cliffords in the RB study.
|
|
98
99
|
|
|
@@ -135,14 +136,14 @@ class RandomizedBenchMarkResult:
|
|
|
135
136
|
p = opt_params[2]
|
|
136
137
|
return (1.0 - 1.0 / 4.0) * (1.0 - p)
|
|
137
138
|
|
|
138
|
-
def _fit_exponential(self) ->
|
|
139
|
+
def _fit_exponential(self) -> tuple[np.ndarray, np.ndarray]:
|
|
139
140
|
exp_fit = lambda x, A, B, p: A * p**x + B
|
|
140
141
|
return curve_fit(
|
|
141
142
|
f=exp_fit,
|
|
142
143
|
xdata=self._num_cfds_seq,
|
|
143
144
|
ydata=self._gnd_state_probs,
|
|
144
145
|
p0=[0.5, 0.5, 1.0 - 1e-3],
|
|
145
|
-
bounds=([0,
|
|
146
|
+
bounds=([0, -1, 0], [1, 1, 1]),
|
|
146
147
|
)
|
|
147
148
|
|
|
148
149
|
|
|
@@ -150,10 +151,10 @@ class RandomizedBenchMarkResult:
|
|
|
150
151
|
class ParallelRandomizedBenchmarkingResult:
|
|
151
152
|
"""Results from a parallel randomized benchmarking experiment."""
|
|
152
153
|
|
|
153
|
-
results_dictionary: Mapping[
|
|
154
|
+
results_dictionary: Mapping[cirq.Qid, RandomizedBenchMarkResult]
|
|
154
155
|
|
|
155
156
|
def plot_single_qubit(
|
|
156
|
-
self, qubit:
|
|
157
|
+
self, qubit: cirq.Qid, ax: plt.Axes | None = None, **plot_kwargs: Any
|
|
157
158
|
) -> plt.Axes:
|
|
158
159
|
"""Plot the raw data for the specified qubit.
|
|
159
160
|
|
|
@@ -168,7 +169,7 @@ class ParallelRandomizedBenchmarkingResult:
|
|
|
168
169
|
|
|
169
170
|
return self.results_dictionary[qubit].plot(ax, **plot_kwargs)
|
|
170
171
|
|
|
171
|
-
def pauli_error(self) -> Mapping[
|
|
172
|
+
def pauli_error(self) -> Mapping[cirq.Qid, float]:
|
|
172
173
|
"""Return a dictionary of Pauli errors.
|
|
173
174
|
Returns:
|
|
174
175
|
A dictionary containing the Pauli errors for all qubits.
|
|
@@ -180,7 +181,7 @@ class ParallelRandomizedBenchmarkingResult:
|
|
|
180
181
|
|
|
181
182
|
def plot_heatmap(
|
|
182
183
|
self,
|
|
183
|
-
ax:
|
|
184
|
+
ax: plt.Axes | None = None,
|
|
184
185
|
annotation_format: str = '0.1%',
|
|
185
186
|
title: str = 'Single-qubit Pauli error',
|
|
186
187
|
**plot_kwargs: Any,
|
|
@@ -213,16 +214,16 @@ class ParallelRandomizedBenchmarkingResult:
|
|
|
213
214
|
|
|
214
215
|
def plot_integrated_histogram(
|
|
215
216
|
self,
|
|
216
|
-
ax:
|
|
217
|
+
ax: plt.Axes | None = None,
|
|
217
218
|
cdf_on_x: bool = False,
|
|
218
219
|
axis_label: str = 'Pauli error',
|
|
219
220
|
semilog: bool = True,
|
|
220
221
|
median_line: bool = True,
|
|
221
|
-
median_label:
|
|
222
|
+
median_label: str | None = 'median',
|
|
222
223
|
mean_line: bool = False,
|
|
223
|
-
mean_label:
|
|
224
|
+
mean_label: str | None = 'mean',
|
|
224
225
|
show_zero: bool = False,
|
|
225
|
-
title:
|
|
226
|
+
title: str | None = None,
|
|
226
227
|
**kwargs,
|
|
227
228
|
) -> plt.Axes:
|
|
228
229
|
"""Plot the Pauli errors using cirq.integrated_histogram().
|
|
@@ -286,8 +287,8 @@ class TomographyResult:
|
|
|
286
287
|
return self._density_matrix
|
|
287
288
|
|
|
288
289
|
def plot(
|
|
289
|
-
self, axes:
|
|
290
|
-
) ->
|
|
290
|
+
self, axes: list[plt.Axes] | None = None, **plot_kwargs: Any
|
|
291
|
+
) -> list[plt.Axes]: # pragma: no cover
|
|
291
292
|
"""Plots the real and imaginary parts of the density matrix as two 3D bar plots.
|
|
292
293
|
|
|
293
294
|
Args:
|
|
@@ -341,9 +342,47 @@ class TomographyResult:
|
|
|
341
342
|
return axes
|
|
342
343
|
|
|
343
344
|
|
|
345
|
+
@attrs.frozen
|
|
346
|
+
class RBParameters:
|
|
347
|
+
r"""Parameters for running randomized benchmarking.
|
|
348
|
+
|
|
349
|
+
Arguments:
|
|
350
|
+
num_clifford_range: The different numbers of Cliffords in the RB study.
|
|
351
|
+
num_circuits: The number of random circuits generated for each
|
|
352
|
+
number of Cliffords.
|
|
353
|
+
repetitions: The number of repetitions of each circuit.
|
|
354
|
+
use_xy_basis: Determines if the Clifford gates are built with x and y
|
|
355
|
+
rotations (True) or x and z rotations (False).
|
|
356
|
+
strict_basis: whether to use only cliffords that can be represented by at
|
|
357
|
+
most 2 gates of the choses basis. For example,
|
|
358
|
+
if True and use_xy_basis is True, this excludes $I, Z, \sqrt(Z), \-sqrt(Z)^\dagger$.
|
|
359
|
+
if True and use_xy_basis is False, this excludes $I, Y, \sqrt(Y), -\sqrt(Y)^\dagger$.
|
|
360
|
+
"""
|
|
361
|
+
|
|
362
|
+
num_clifford_range: Sequence[int] = tuple(np.logspace(np.log10(5), 3, 5, dtype=int))
|
|
363
|
+
num_circuits: int = 10
|
|
364
|
+
repetitions: int = 600
|
|
365
|
+
use_xy_basis: bool = False
|
|
366
|
+
strict_basis: bool = True
|
|
367
|
+
|
|
368
|
+
def gateset(self) -> list[list[ops.SingleQubitCliffordGate]]:
|
|
369
|
+
clifford_group = _single_qubit_cliffords()
|
|
370
|
+
sequences = clifford_group.c1_in_xy if self.use_xy_basis else clifford_group.c1_in_xz
|
|
371
|
+
sequences = _canonize_clifford_sequences(sequences)
|
|
372
|
+
if self.strict_basis:
|
|
373
|
+
if self.use_xy_basis:
|
|
374
|
+
excluded_gates = ops.Gateset(ops.I, ops.Z, ops.Z**0.5, ops.Z**-0.5)
|
|
375
|
+
else:
|
|
376
|
+
excluded_gates = ops.Gateset(ops.I, ops.Y, ops.Y**0.5, ops.Y**-0.5)
|
|
377
|
+
|
|
378
|
+
sequences = [[g] for (g,) in sequences if g not in excluded_gates]
|
|
379
|
+
return sequences
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
@deprecated(deadline='v2.0', fix='please use single_qubit_rb instead')
|
|
344
383
|
def single_qubit_randomized_benchmarking(
|
|
345
|
-
sampler:
|
|
346
|
-
qubit:
|
|
384
|
+
sampler: cirq.Sampler,
|
|
385
|
+
qubit: cirq.Qid,
|
|
347
386
|
use_xy_basis: bool = True,
|
|
348
387
|
*,
|
|
349
388
|
num_clifford_range: Sequence[int] = tuple(np.logspace(np.log10(5), 3, 5, dtype=int)),
|
|
@@ -384,20 +423,23 @@ def single_qubit_randomized_benchmarking(
|
|
|
384
423
|
A RandomizedBenchMarkResult object that stores and plots the result.
|
|
385
424
|
"""
|
|
386
425
|
|
|
387
|
-
|
|
426
|
+
return single_qubit_rb(
|
|
388
427
|
sampler,
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
428
|
+
qubit,
|
|
429
|
+
RBParameters(
|
|
430
|
+
num_clifford_range=num_clifford_range,
|
|
431
|
+
num_circuits=num_circuits,
|
|
432
|
+
repetitions=repetitions,
|
|
433
|
+
use_xy_basis=use_xy_basis,
|
|
434
|
+
strict_basis=False,
|
|
435
|
+
),
|
|
394
436
|
)
|
|
395
|
-
return result.results_dictionary[qubit]
|
|
396
437
|
|
|
397
438
|
|
|
439
|
+
@deprecated(deadline='v2.0', fix='please use parallel_single_qubit_rb instead')
|
|
398
440
|
def parallel_single_qubit_randomized_benchmarking(
|
|
399
|
-
sampler:
|
|
400
|
-
qubits: Sequence[
|
|
441
|
+
sampler: cirq.Sampler,
|
|
442
|
+
qubits: Sequence[cirq.Qid],
|
|
401
443
|
use_xy_basis: bool = True,
|
|
402
444
|
*,
|
|
403
445
|
num_clifford_range: Sequence[int] = tuple(
|
|
@@ -405,7 +447,7 @@ def parallel_single_qubit_randomized_benchmarking(
|
|
|
405
447
|
),
|
|
406
448
|
num_circuits: int = 10,
|
|
407
449
|
repetitions: int = 1000,
|
|
408
|
-
) ->
|
|
450
|
+
) -> ParallelRandomizedBenchmarkingResult:
|
|
409
451
|
"""Clifford-based randomized benchmarking (RB) single qubits in parallel.
|
|
410
452
|
|
|
411
453
|
This is the same as `single_qubit_randomized_benchmarking` except on all
|
|
@@ -421,42 +463,97 @@ def parallel_single_qubit_randomized_benchmarking(
|
|
|
421
463
|
num_circuits: The number of random circuits generated for each
|
|
422
464
|
number of Cliffords.
|
|
423
465
|
repetitions: The number of repetitions of each circuit.
|
|
466
|
+
Returns:
|
|
467
|
+
A dictionary from qubits to RandomizedBenchMarkResult objects.
|
|
468
|
+
"""
|
|
469
|
+
return parallel_single_qubit_rb(
|
|
470
|
+
sampler,
|
|
471
|
+
qubits,
|
|
472
|
+
RBParameters(
|
|
473
|
+
num_clifford_range=num_clifford_range,
|
|
474
|
+
num_circuits=num_circuits,
|
|
475
|
+
repetitions=repetitions,
|
|
476
|
+
use_xy_basis=use_xy_basis,
|
|
477
|
+
strict_basis=False,
|
|
478
|
+
),
|
|
479
|
+
)
|
|
480
|
+
|
|
424
481
|
|
|
482
|
+
def single_qubit_rb(
|
|
483
|
+
sampler: cirq.Sampler,
|
|
484
|
+
qubit: cirq.Qid,
|
|
485
|
+
parameters: RBParameters = RBParameters(),
|
|
486
|
+
rng_or_seed: np.random.Generator | int | None = None,
|
|
487
|
+
) -> RandomizedBenchMarkResult:
|
|
488
|
+
"""Clifford-based randomized benchmarking (RB) on a single qubit.
|
|
489
|
+
|
|
490
|
+
Args:
|
|
491
|
+
sampler: The quantum engine or simulator to run the circuits.
|
|
492
|
+
qubit: The qubit(s) to benchmark.
|
|
493
|
+
parameters: The parameters of the experiment.
|
|
494
|
+
rng_or_seed: A np.random.Generator object or seed.
|
|
425
495
|
Returns:
|
|
426
496
|
A dictionary from qubits to RandomizedBenchMarkResult objects.
|
|
427
497
|
"""
|
|
498
|
+
return parallel_single_qubit_rb(sampler, [qubit], parameters, rng_or_seed).results_dictionary[
|
|
499
|
+
qubit
|
|
500
|
+
]
|
|
501
|
+
|
|
428
502
|
|
|
429
|
-
|
|
430
|
-
|
|
503
|
+
def parallel_single_qubit_rb(
|
|
504
|
+
sampler: cirq.Sampler,
|
|
505
|
+
qubits: Sequence[cirq.Qid],
|
|
506
|
+
parameters: RBParameters = RBParameters(),
|
|
507
|
+
rng_or_seed: np.random.Generator | int | None = None,
|
|
508
|
+
) -> ParallelRandomizedBenchmarkingResult:
|
|
509
|
+
"""Clifford-based randomized benchmarking (RB) single qubits in parallel.
|
|
510
|
+
|
|
511
|
+
Args:
|
|
512
|
+
sampler: The quantum engine or simulator to run the circuits.
|
|
513
|
+
qubits: The qubit(s) to benchmark.
|
|
514
|
+
parameters: The parameters of the experiment.
|
|
515
|
+
rng_or_seed: A np.random.Generator object or seed.
|
|
516
|
+
Returns:
|
|
517
|
+
A dictionary from qubits to RandomizedBenchMarkResult objects.
|
|
518
|
+
"""
|
|
519
|
+
|
|
520
|
+
rng_or_seed = (
|
|
521
|
+
rng_or_seed
|
|
522
|
+
if isinstance(rng_or_seed, np.random.Generator)
|
|
523
|
+
else np.random.default_rng(rng_or_seed)
|
|
524
|
+
)
|
|
525
|
+
|
|
526
|
+
c1 = parameters.gateset()
|
|
431
527
|
|
|
432
528
|
# create circuits
|
|
433
|
-
circuits_all:
|
|
434
|
-
for num_cliffords in num_clifford_range:
|
|
435
|
-
for _ in range(num_circuits):
|
|
436
|
-
circuits_all.append(_create_parallel_rb_circuit(qubits, num_cliffords, c1))
|
|
529
|
+
circuits_all: list[cirq.AbstractCircuit] = []
|
|
530
|
+
for num_cliffords in parameters.num_clifford_range:
|
|
531
|
+
for _ in range(parameters.num_circuits):
|
|
532
|
+
circuits_all.append(_create_parallel_rb_circuit(qubits, num_cliffords, c1, rng_or_seed))
|
|
437
533
|
|
|
438
534
|
# run circuits
|
|
439
|
-
results = sampler.run_batch(circuits_all, repetitions=repetitions)
|
|
535
|
+
results = sampler.run_batch(circuits_all, repetitions=parameters.repetitions)
|
|
440
536
|
gnd_probs: dict = {q: [] for q in qubits}
|
|
441
537
|
idx = 0
|
|
442
|
-
for num_cliffords in num_clifford_range:
|
|
443
|
-
excited_probs:
|
|
444
|
-
for _ in range(num_circuits):
|
|
538
|
+
for num_cliffords in parameters.num_clifford_range:
|
|
539
|
+
excited_probs: dict[cirq.Qid, list[float]] = {q: [] for q in qubits}
|
|
540
|
+
for _ in range(parameters.num_circuits):
|
|
445
541
|
result = results[idx][0]
|
|
446
542
|
for qubit in qubits:
|
|
447
543
|
excited_probs[qubit].append(np.mean(result.measurements[str(qubit)]))
|
|
448
544
|
idx += 1
|
|
449
545
|
for qubit in qubits:
|
|
450
546
|
gnd_probs[qubit].append(1.0 - np.mean(excited_probs[qubit]))
|
|
547
|
+
|
|
451
548
|
return ParallelRandomizedBenchmarkingResult(
|
|
452
|
-
{q: RandomizedBenchMarkResult(num_clifford_range, gnd_probs[q]) for q in qubits}
|
|
549
|
+
{q: RandomizedBenchMarkResult(parameters.num_clifford_range, gnd_probs[q]) for q in qubits}
|
|
453
550
|
)
|
|
454
551
|
|
|
455
552
|
|
|
456
553
|
def two_qubit_randomized_benchmarking(
|
|
457
|
-
sampler:
|
|
458
|
-
first_qubit:
|
|
459
|
-
second_qubit:
|
|
554
|
+
sampler: cirq.Sampler,
|
|
555
|
+
first_qubit: cirq.Qid,
|
|
556
|
+
second_qubit: cirq.Qid,
|
|
460
557
|
*,
|
|
461
558
|
num_clifford_range: Sequence[int] = range(5, 50, 5),
|
|
462
559
|
num_circuits: int = 20,
|
|
@@ -514,10 +611,7 @@ def two_qubit_randomized_benchmarking(
|
|
|
514
611
|
|
|
515
612
|
|
|
516
613
|
def single_qubit_state_tomography(
|
|
517
|
-
sampler:
|
|
518
|
-
qubit: 'cirq.Qid',
|
|
519
|
-
circuit: 'cirq.AbstractCircuit',
|
|
520
|
-
repetitions: int = 1000,
|
|
614
|
+
sampler: cirq.Sampler, qubit: cirq.Qid, circuit: cirq.AbstractCircuit, repetitions: int = 1000
|
|
521
615
|
) -> TomographyResult:
|
|
522
616
|
"""Single-qubit state tomography.
|
|
523
617
|
|
|
@@ -538,18 +632,24 @@ def single_qubit_state_tomography(
|
|
|
538
632
|
Returns:
|
|
539
633
|
A TomographyResult object that stores and plots the density matrix.
|
|
540
634
|
"""
|
|
541
|
-
|
|
635
|
+
keys = protocols.measurement_key_names(circuit)
|
|
636
|
+
tomo_key = "tomo_key"
|
|
637
|
+
while tomo_key in keys:
|
|
638
|
+
tomo_key = f"tomo_key{uuid.uuid4().hex}"
|
|
639
|
+
|
|
640
|
+
circuit_z = circuit + circuits.Circuit(ops.measure(qubit, key=tomo_key))
|
|
641
|
+
|
|
542
642
|
results = sampler.run(circuit_z, repetitions=repetitions)
|
|
543
|
-
rho_11 = np.mean(results.
|
|
643
|
+
rho_11 = np.mean(results.records[tomo_key][:, -1, :])
|
|
544
644
|
rho_00 = 1.0 - rho_11
|
|
545
645
|
|
|
546
|
-
circuit_x = circuits.Circuit(circuit, ops.X(qubit) ** 0.5, ops.measure(qubit, key=
|
|
646
|
+
circuit_x = circuits.Circuit(circuit, ops.X(qubit) ** 0.5, ops.measure(qubit, key=tomo_key))
|
|
547
647
|
results = sampler.run(circuit_x, repetitions=repetitions)
|
|
548
|
-
rho_01_im = np.mean(results.
|
|
648
|
+
rho_01_im = np.mean(results.records[tomo_key][:, -1, :]) - 0.5
|
|
549
649
|
|
|
550
|
-
circuit_y = circuits.Circuit(circuit, ops.Y(qubit) ** -0.5, ops.measure(qubit, key=
|
|
650
|
+
circuit_y = circuits.Circuit(circuit, ops.Y(qubit) ** -0.5, ops.measure(qubit, key=tomo_key))
|
|
551
651
|
results = sampler.run(circuit_y, repetitions=repetitions)
|
|
552
|
-
rho_01_re = 0.5 - np.mean(results.
|
|
652
|
+
rho_01_re = 0.5 - np.mean(results.records[tomo_key][:, -1, :])
|
|
553
653
|
|
|
554
654
|
rho_01 = rho_01_re + 1j * rho_01_im
|
|
555
655
|
rho_10 = np.conj(rho_01)
|
|
@@ -560,10 +660,10 @@ def single_qubit_state_tomography(
|
|
|
560
660
|
|
|
561
661
|
|
|
562
662
|
def two_qubit_state_tomography(
|
|
563
|
-
sampler:
|
|
564
|
-
first_qubit:
|
|
565
|
-
second_qubit:
|
|
566
|
-
circuit:
|
|
663
|
+
sampler: cirq.Sampler,
|
|
664
|
+
first_qubit: cirq.Qid,
|
|
665
|
+
second_qubit: cirq.Qid,
|
|
666
|
+
circuit: cirq.AbstractCircuit,
|
|
567
667
|
repetitions: int = 1000,
|
|
568
668
|
) -> TomographyResult:
|
|
569
669
|
r"""Two-qubit state tomography.
|
|
@@ -688,9 +788,14 @@ def two_qubit_state_tomography(
|
|
|
688
788
|
|
|
689
789
|
|
|
690
790
|
def _create_parallel_rb_circuit(
|
|
691
|
-
qubits: Sequence[
|
|
692
|
-
|
|
693
|
-
|
|
791
|
+
qubits: Sequence[cirq.Qid],
|
|
792
|
+
num_cliffords: int,
|
|
793
|
+
c1: list[list[ops.SingleQubitCliffordGate]],
|
|
794
|
+
rng: np.random.Generator | None = None,
|
|
795
|
+
) -> cirq.Circuit:
|
|
796
|
+
sequences_to_zip = [
|
|
797
|
+
_random_single_q_clifford(qubit, num_cliffords, c1, rng) for qubit in qubits
|
|
798
|
+
]
|
|
694
799
|
# Ensure each sequence has the same number of moments.
|
|
695
800
|
num_moments = max(len(sequence) for sequence in sequences_to_zip)
|
|
696
801
|
for q, sequence in zip(qubits, sequences_to_zip):
|
|
@@ -702,7 +807,7 @@ def _create_parallel_rb_circuit(
|
|
|
702
807
|
return circuits.Circuit.from_moments(*moments, ops.measure_each(*qubits))
|
|
703
808
|
|
|
704
809
|
|
|
705
|
-
def _indices_after_basis_rot(i: int, j: int) ->
|
|
810
|
+
def _indices_after_basis_rot(i: int, j: int) -> tuple[int, Sequence[int], Sequence[int]]:
|
|
706
811
|
mat_idx = 3 * (3 * i + j)
|
|
707
812
|
q_0_i = 3 - i
|
|
708
813
|
q_1_j = 3 - j
|
|
@@ -711,9 +816,7 @@ def _indices_after_basis_rot(i: int, j: int) -> Tuple[int, Sequence[int], Sequen
|
|
|
711
816
|
return mat_idx, indices, signs
|
|
712
817
|
|
|
713
818
|
|
|
714
|
-
def _two_qubit_clifford_matrices(
|
|
715
|
-
q_0: 'cirq.Qid', q_1: 'cirq.Qid', cliffords: Cliffords
|
|
716
|
-
) -> np.ndarray:
|
|
819
|
+
def _two_qubit_clifford_matrices(q_0: cirq.Qid, q_1: cirq.Qid, cliffords: Cliffords) -> np.ndarray:
|
|
717
820
|
mats = []
|
|
718
821
|
|
|
719
822
|
# Total number of different gates in the two-qubit Clifford group.
|
|
@@ -743,11 +846,14 @@ def _two_qubit_clifford_matrices(
|
|
|
743
846
|
|
|
744
847
|
|
|
745
848
|
def _random_single_q_clifford(
|
|
746
|
-
qubit:
|
|
747
|
-
|
|
748
|
-
|
|
849
|
+
qubit: cirq.Qid,
|
|
850
|
+
num_cfds: int,
|
|
851
|
+
cfds: Sequence[Sequence[cirq.ops.SingleQubitCliffordGate]],
|
|
852
|
+
rng: np.random.Generator | None = None,
|
|
853
|
+
) -> list[cirq.Operation]:
|
|
749
854
|
operations = [[gate.to_phased_xz_gate()(qubit) for gate in gates] for gates in cfds]
|
|
750
|
-
|
|
855
|
+
choice_fn = rng.choice if rng else np.random.choice
|
|
856
|
+
gate_ids = choice_fn(len(cfds), num_cfds).tolist()
|
|
751
857
|
adjoint = _reduce_gate_seq([gate for gate_id in gate_ids for gate in cfds[gate_id]]) ** -1
|
|
752
858
|
return [op for gate_id in gate_ids for op in operations[gate_id]] + [
|
|
753
859
|
adjoint.to_phased_xz_gate()(qubit)
|
|
@@ -755,10 +861,10 @@ def _random_single_q_clifford(
|
|
|
755
861
|
|
|
756
862
|
|
|
757
863
|
def _random_two_q_clifford(
|
|
758
|
-
q_0:
|
|
759
|
-
) ->
|
|
864
|
+
q_0: cirq.Qid, q_1: cirq.Qid, num_cfds: int, cfd_matrices: np.ndarray, cliffords: Cliffords
|
|
865
|
+
) -> cirq.Circuit:
|
|
760
866
|
clifford_group_size = 11520
|
|
761
|
-
idx_list =
|
|
867
|
+
idx_list = np.random.choice(clifford_group_size, num_cfds).tolist()
|
|
762
868
|
circuit = circuits.Circuit()
|
|
763
869
|
for idx in idx_list:
|
|
764
870
|
circuit.append(_two_qubit_clifford(q_0, q_1, idx, cliffords))
|
|
@@ -778,9 +884,9 @@ def _matrix_bar_plot(
|
|
|
778
884
|
mat: np.ndarray,
|
|
779
885
|
z_label: str,
|
|
780
886
|
ax: mplot3d.axes3d.Axes3D,
|
|
781
|
-
kets:
|
|
782
|
-
title:
|
|
783
|
-
ylim:
|
|
887
|
+
kets: Sequence[str] | None = None,
|
|
888
|
+
title: str | None = None,
|
|
889
|
+
ylim: tuple[int, int] = (-1, 1),
|
|
784
890
|
**bar3d_kwargs: Any,
|
|
785
891
|
) -> None: # pragma: no cover
|
|
786
892
|
num_rows, num_cols = mat.shape
|
|
@@ -819,8 +925,8 @@ def _reduce_gate_seq(
|
|
|
819
925
|
|
|
820
926
|
|
|
821
927
|
def _two_qubit_clifford(
|
|
822
|
-
q_0:
|
|
823
|
-
) -> Iterator[
|
|
928
|
+
q_0: cirq.Qid, q_1: cirq.Qid, idx: int, cliffords: Cliffords
|
|
929
|
+
) -> Iterator[cirq.OP_TREE]:
|
|
824
930
|
"""Generates a two-qubit Clifford gate.
|
|
825
931
|
|
|
826
932
|
An integer (idx) from 0 to 11519 is used to generate a two-qubit Clifford
|
|
@@ -875,8 +981,8 @@ def _split_two_q_clifford_idx(idx: int):
|
|
|
875
981
|
|
|
876
982
|
|
|
877
983
|
def _two_qubit_clifford_starters(
|
|
878
|
-
q_0:
|
|
879
|
-
) -> Iterator[
|
|
984
|
+
q_0: cirq.Qid, q_1: cirq.Qid, idx_0: int, idx_1: int, cliffords: Cliffords
|
|
985
|
+
) -> Iterator[cirq.OP_TREE]:
|
|
880
986
|
"""Fulfills part (a) for two-qubit Cliffords."""
|
|
881
987
|
c1 = cliffords.c1_in_xy
|
|
882
988
|
yield _single_qubit_gates(c1[idx_0], q_0)
|
|
@@ -884,8 +990,8 @@ def _two_qubit_clifford_starters(
|
|
|
884
990
|
|
|
885
991
|
|
|
886
992
|
def _two_qubit_clifford_mixers(
|
|
887
|
-
q_0:
|
|
888
|
-
) -> Iterator[
|
|
993
|
+
q_0: cirq.Qid, q_1: cirq.Qid, idx_2: int, cliffords: Cliffords
|
|
994
|
+
) -> Iterator[cirq.OP_TREE]:
|
|
889
995
|
"""Fulfills parts (b-d) for two-qubit Cliffords."""
|
|
890
996
|
s1 = cliffords.s1
|
|
891
997
|
s1_x = cliffords.s1_x
|
|
@@ -916,9 +1022,7 @@ def _two_qubit_clifford_mixers(
|
|
|
916
1022
|
yield _single_qubit_gates(s1_x[idx_4], q_1)
|
|
917
1023
|
|
|
918
1024
|
|
|
919
|
-
def _single_qubit_gates(
|
|
920
|
-
gate_seq: Sequence['cirq.Gate'], qubit: 'cirq.Qid'
|
|
921
|
-
) -> Iterator['cirq.OP_TREE']:
|
|
1025
|
+
def _single_qubit_gates(gate_seq: Sequence[cirq.Gate], qubit: cirq.Qid) -> Iterator[cirq.OP_TREE]:
|
|
922
1026
|
for gate in gate_seq:
|
|
923
1027
|
yield gate(qubit)
|
|
924
1028
|
|
|
@@ -931,8 +1035,8 @@ def _single_qubit_cliffords() -> Cliffords:
|
|
|
931
1035
|
ops.SingleQubitCliffordGate.Z,
|
|
932
1036
|
)
|
|
933
1037
|
|
|
934
|
-
c1_in_xy:
|
|
935
|
-
c1_in_xz:
|
|
1038
|
+
c1_in_xy: list[list[ops.SingleQubitCliffordGate]] = []
|
|
1039
|
+
c1_in_xz: list[list[ops.SingleQubitCliffordGate]] = []
|
|
936
1040
|
|
|
937
1041
|
for phi_0, phi_1 in itertools.product([1.0, 0.5, -0.5], [0.0, 0.5, -0.5]):
|
|
938
1042
|
c1_in_xy.append([X**phi_0, Y**phi_1])
|
|
@@ -955,9 +1059,9 @@ def _single_qubit_cliffords() -> Cliffords:
|
|
|
955
1059
|
for z0, x, z1 in phi_xz:
|
|
956
1060
|
c1_in_xz.append([Z**z0, X**x, Z**z1])
|
|
957
1061
|
|
|
958
|
-
s1:
|
|
959
|
-
s1_x:
|
|
960
|
-
s1_y:
|
|
1062
|
+
s1: list[list[ops.SingleQubitCliffordGate]] = [[X**0.0], [Y**0.5, X**0.5], [X**-0.5, Y**-0.5]]
|
|
1063
|
+
s1_x: list[list[ops.SingleQubitCliffordGate]] = [[X**0.5], [X**0.5, Y**0.5, X**0.5], [Y**-0.5]]
|
|
1064
|
+
s1_y: list[list[ops.SingleQubitCliffordGate]] = [
|
|
961
1065
|
[Y**0.5],
|
|
962
1066
|
[X**-0.5, Y**-0.5, X**0.5],
|
|
963
1067
|
[Y, X**0.5],
|
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import os
|
|
18
|
+
from unittest import mock
|
|
19
|
+
|
|
15
20
|
import matplotlib.pyplot as plt
|
|
16
21
|
import numpy as np
|
|
17
22
|
import pytest
|
|
@@ -102,6 +107,7 @@ def test_single_qubit_cliffords():
|
|
|
102
107
|
assert num_x <= 1
|
|
103
108
|
|
|
104
109
|
|
|
110
|
+
@mock.patch.dict(os.environ, clear='CIRQ_TESTING')
|
|
105
111
|
def test_single_qubit_randomized_benchmarking():
|
|
106
112
|
# Check that the ground state population at the end of the Clifford
|
|
107
113
|
# sequences is always unity.
|
|
@@ -114,7 +120,8 @@ def test_single_qubit_randomized_benchmarking():
|
|
|
114
120
|
assert np.isclose(results.pauli_error(), 0.0, atol=1e-7) # warning is expected
|
|
115
121
|
|
|
116
122
|
|
|
117
|
-
|
|
123
|
+
@mock.patch.dict(os.environ, clear='CIRQ_TESTING')
|
|
124
|
+
def test_parallel_single_qubit_parallel_single_qubit_randomized_benchmarking():
|
|
118
125
|
# Check that the ground state population at the end of the Clifford
|
|
119
126
|
# sequences is always unity.
|
|
120
127
|
simulator = sim.Simulator()
|
|
@@ -150,24 +157,34 @@ def test_two_qubit_randomized_benchmarking():
|
|
|
150
157
|
def test_single_qubit_state_tomography():
|
|
151
158
|
# Check that the density matrices of the output states of X/2, Y/2 and
|
|
152
159
|
# H + Y gates closely match the ideal cases.
|
|
160
|
+
# Checks that unique tomography keys are generated
|
|
153
161
|
simulator = sim.Simulator()
|
|
154
|
-
|
|
162
|
+
q_0 = GridQubit(0, 0)
|
|
163
|
+
q_1 = GridQubit(0, 1)
|
|
155
164
|
|
|
156
|
-
circuit_1 = circuits.Circuit(ops.X(
|
|
157
|
-
circuit_2 = circuits.Circuit(ops.Y(
|
|
158
|
-
circuit_3 = circuits.Circuit(ops.H(
|
|
165
|
+
circuit_1 = circuits.Circuit(ops.X(q_0) ** 0.5)
|
|
166
|
+
circuit_2 = circuits.Circuit(ops.Y(q_0) ** 0.5)
|
|
167
|
+
circuit_3 = circuits.Circuit(ops.H(q_0), ops.Y(q_0))
|
|
168
|
+
circuit_4 = circuits.Circuit(ops.H(q_0), ops.Y(q_0), cirq.measure(q_1, key='z'))
|
|
169
|
+
circuit_5 = circuits.Circuit(ops.H(q_0), ops.Y(q_0), cirq.measure(q_1, key='tomo_key'))
|
|
159
170
|
|
|
160
|
-
act_rho_1 = single_qubit_state_tomography(simulator,
|
|
161
|
-
act_rho_2 = single_qubit_state_tomography(simulator,
|
|
162
|
-
act_rho_3 = single_qubit_state_tomography(simulator,
|
|
171
|
+
act_rho_1 = single_qubit_state_tomography(simulator, q_0, circuit_1, 1000).data
|
|
172
|
+
act_rho_2 = single_qubit_state_tomography(simulator, q_0, circuit_2, 1000).data
|
|
173
|
+
act_rho_3 = single_qubit_state_tomography(simulator, q_0, circuit_3, 1000).data
|
|
174
|
+
act_rho_4 = single_qubit_state_tomography(simulator, q_0, circuit_4, 1000).data
|
|
175
|
+
act_rho_5 = single_qubit_state_tomography(simulator, q_0, circuit_5, 1000).data
|
|
163
176
|
|
|
164
177
|
tar_rho_1 = np.array([[0.5, 0.5j], [-0.5j, 0.5]])
|
|
165
178
|
tar_rho_2 = np.array([[0.5, 0.5], [0.5, 0.5]])
|
|
166
179
|
tar_rho_3 = np.array([[0.5, -0.5], [-0.5, 0.5]])
|
|
180
|
+
tar_rho_4 = np.array([[0.5, -0.5], [-0.5, 0.5]])
|
|
181
|
+
tar_rho_5 = np.array([[0.5, -0.5], [-0.5, 0.5]])
|
|
167
182
|
|
|
168
183
|
np.testing.assert_almost_equal(act_rho_1, tar_rho_1, decimal=1)
|
|
169
184
|
np.testing.assert_almost_equal(act_rho_2, tar_rho_2, decimal=1)
|
|
170
185
|
np.testing.assert_almost_equal(act_rho_3, tar_rho_3, decimal=1)
|
|
186
|
+
np.testing.assert_almost_equal(act_rho_4, tar_rho_4, decimal=1)
|
|
187
|
+
np.testing.assert_almost_equal(act_rho_5, tar_rho_5, decimal=1)
|
|
171
188
|
|
|
172
189
|
|
|
173
190
|
def test_two_qubit_state_tomography():
|
|
@@ -219,7 +236,7 @@ def test_tomography_plot_raises_for_incorrect_number_of_axes():
|
|
|
219
236
|
qubit = GridQubit(0, 0)
|
|
220
237
|
circuit = circuits.Circuit(ops.X(qubit) ** 0.5)
|
|
221
238
|
result = single_qubit_state_tomography(simulator, qubit, circuit, 1000)
|
|
222
|
-
with pytest.raises(TypeError): # ax is not a
|
|
239
|
+
with pytest.raises(TypeError): # ax is not a list[plt.Axes]
|
|
223
240
|
ax = plt.subplot()
|
|
224
241
|
result.plot(ax)
|
|
225
242
|
with pytest.raises(ValueError):
|
|
@@ -227,13 +244,24 @@ def test_tomography_plot_raises_for_incorrect_number_of_axes():
|
|
|
227
244
|
result.plot(axes)
|
|
228
245
|
|
|
229
246
|
|
|
230
|
-
|
|
247
|
+
@pytest.mark.parametrize('num_cliffords', range(5, 10))
|
|
248
|
+
@pytest.mark.parametrize('use_xy_basis', [False, True])
|
|
249
|
+
@pytest.mark.parametrize('strict_basis', [False, True])
|
|
250
|
+
def test_single_qubit_cliffords_gateset(num_cliffords, use_xy_basis, strict_basis):
|
|
231
251
|
qubits = [GridQubit(0, i) for i in range(4)]
|
|
232
|
-
|
|
252
|
+
c1_in_xy = cirq.experiments.qubit_characterizations.RBParameters(
|
|
253
|
+
use_xy_basis=use_xy_basis, strict_basis=strict_basis
|
|
254
|
+
).gateset()
|
|
255
|
+
if strict_basis:
|
|
256
|
+
assert len(c1_in_xy) == 20
|
|
257
|
+
else:
|
|
258
|
+
assert len(c1_in_xy) == 24
|
|
233
259
|
c = cirq.experiments.qubit_characterizations._create_parallel_rb_circuit(
|
|
234
|
-
qubits,
|
|
260
|
+
qubits, num_cliffords, c1_in_xy
|
|
235
261
|
)
|
|
236
262
|
device = cirq.testing.ValidatingTestDevice(
|
|
237
263
|
qubits=qubits, allowed_gates=(cirq.ops.PhasedXZGate, cirq.MeasurementGate)
|
|
238
264
|
)
|
|
239
265
|
device.validate_circuit(c)
|
|
266
|
+
|
|
267
|
+
assert len(c) == num_cliffords + 2
|