cirq-core 1.5.0.dev20250409222543__py3-none-any.whl → 1.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cirq-core might be problematic. Click here for more details.
- cirq/__init__.py +16 -17
- cirq/_compat.py +21 -20
- cirq/_compat_test.py +14 -34
- cirq/_doc.py +4 -2
- cirq/_import.py +8 -6
- cirq/_import_test.py +4 -2
- cirq/_version.py +6 -6
- cirq/_version_test.py +2 -2
- cirq/circuits/_block_diagram_drawer.py +11 -10
- cirq/circuits/_block_diagram_drawer_test.py +8 -6
- cirq/circuits/_box_drawing_character_data.py +8 -8
- cirq/circuits/_box_drawing_character_data_test.py +3 -1
- cirq/circuits/_bucket_priority_queue.py +9 -7
- cirq/circuits/_bucket_priority_queue_test.py +22 -20
- cirq/circuits/circuit.py +248 -172
- cirq/circuits/circuit_operation.py +73 -83
- cirq/circuits/circuit_operation_test.py +128 -90
- cirq/circuits/circuit_test.py +211 -151
- cirq/circuits/frozen_circuit.py +23 -60
- cirq/circuits/frozen_circuit_test.py +31 -8
- cirq/circuits/insert_strategy.py +7 -5
- cirq/circuits/insert_strategy_test.py +4 -2
- cirq/circuits/moment.py +88 -40
- cirq/circuits/moment_test.py +128 -51
- cirq/circuits/optimization_pass.py +5 -5
- cirq/circuits/optimization_pass_test.py +10 -10
- cirq/circuits/qasm_output.py +11 -11
- cirq/circuits/qasm_output_test.py +25 -22
- cirq/circuits/text_diagram_drawer.py +23 -38
- cirq/circuits/text_diagram_drawer_test.py +19 -17
- cirq/conftest.py +4 -3
- cirq/contrib/__init__.py +4 -4
- cirq/contrib/acquaintance/__init__.py +1 -1
- cirq/contrib/acquaintance/bipartite.py +5 -8
- cirq/contrib/acquaintance/bipartite_test.py +18 -13
- cirq/contrib/acquaintance/devices.py +2 -2
- cirq/contrib/acquaintance/devices_test.py +5 -3
- cirq/contrib/acquaintance/executor.py +5 -5
- cirq/contrib/acquaintance/executor_test.py +13 -9
- cirq/contrib/acquaintance/gates.py +18 -28
- cirq/contrib/acquaintance/gates_test.py +24 -20
- cirq/contrib/acquaintance/inspection_utils.py +8 -4
- cirq/contrib/acquaintance/inspection_utils_test.py +4 -2
- cirq/contrib/acquaintance/mutation_utils.py +4 -4
- cirq/contrib/acquaintance/mutation_utils_test.py +4 -2
- cirq/contrib/acquaintance/optimizers.py +4 -4
- cirq/contrib/acquaintance/optimizers_test.py +4 -1
- cirq/contrib/acquaintance/permutation.py +15 -27
- cirq/contrib/acquaintance/permutation_test.py +26 -17
- cirq/contrib/acquaintance/shift.py +4 -4
- cirq/contrib/acquaintance/shift_swap_network.py +4 -4
- cirq/contrib/acquaintance/shift_swap_network_test.py +9 -6
- cirq/contrib/acquaintance/shift_test.py +8 -6
- cirq/contrib/acquaintance/strategies/cubic.py +2 -2
- cirq/contrib/acquaintance/strategies/cubic_test.py +4 -2
- cirq/contrib/acquaintance/strategies/quartic_paired.py +6 -6
- cirq/contrib/acquaintance/strategies/quartic_paired_test.py +10 -6
- cirq/contrib/acquaintance/testing.py +2 -0
- cirq/contrib/acquaintance/topological_sort.py +2 -2
- cirq/contrib/acquaintance/topological_sort_test.py +3 -1
- cirq/contrib/bayesian_network/bayesian_network_gate.py +9 -10
- cirq/contrib/bayesian_network/bayesian_network_gate_test.py +14 -9
- cirq/contrib/circuitdag/circuit_dag.py +4 -4
- cirq/contrib/circuitdag/circuit_dag_test.py +17 -15
- cirq/contrib/custom_simulators/custom_state_simulator.py +5 -5
- cirq/contrib/custom_simulators/custom_state_simulator_test.py +22 -17
- cirq/contrib/graph_device/graph_device.py +12 -11
- cirq/contrib/graph_device/graph_device_test.py +18 -14
- cirq/contrib/graph_device/hypergraph.py +16 -14
- cirq/contrib/graph_device/hypergraph_test.py +13 -11
- cirq/contrib/graph_device/uniform_graph_device.py +6 -4
- cirq/contrib/graph_device/uniform_graph_device_test.py +11 -3
- cirq/contrib/hacks/disable_validation.py +6 -1
- cirq/contrib/hacks/disable_validation_test.py +3 -1
- cirq/contrib/json.py +31 -5
- cirq/contrib/json_test.py +6 -3
- cirq/contrib/json_test_data/DampedReadoutNoiseModel.json +12 -0
- cirq/contrib/json_test_data/DampedReadoutNoiseModel.repr +4 -0
- cirq/contrib/json_test_data/DepolarizingNoiseModel.json +12 -0
- cirq/contrib/json_test_data/DepolarizingNoiseModel.repr +4 -0
- cirq/contrib/json_test_data/DepolarizingWithDampedReadoutNoiseModel.json +6 -0
- cirq/contrib/json_test_data/DepolarizingWithDampedReadoutNoiseModel.repr +1 -0
- cirq/contrib/json_test_data/DepolarizingWithReadoutNoiseModel.json +5 -0
- cirq/contrib/json_test_data/DepolarizingWithReadoutNoiseModel.repr +1 -0
- cirq/contrib/json_test_data/ReadoutNoiseModel.json +12 -0
- cirq/contrib/json_test_data/ReadoutNoiseModel.repr +4 -0
- cirq/contrib/json_test_data/__init__.py +17 -0
- cirq/contrib/json_test_data/spec.py +32 -0
- cirq/contrib/noise_models/noise_models.py +119 -5
- cirq/contrib/noise_models/noise_models_test.py +37 -9
- cirq/contrib/paulistring/clifford_optimize.py +6 -4
- cirq/contrib/paulistring/clifford_optimize_test.py +6 -5
- cirq/contrib/paulistring/clifford_target_gateset.py +10 -10
- cirq/contrib/paulistring/clifford_target_gateset_test.py +13 -11
- cirq/contrib/paulistring/optimize.py +2 -0
- cirq/contrib/paulistring/optimize_test.py +4 -3
- cirq/contrib/paulistring/pauli_string_dag.py +2 -0
- cirq/contrib/paulistring/pauli_string_dag_test.py +3 -1
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +255 -120
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +398 -19
- cirq/contrib/paulistring/pauli_string_optimize.py +7 -1
- cirq/contrib/paulistring/pauli_string_optimize_test.py +5 -3
- cirq/contrib/paulistring/recombine.py +6 -4
- cirq/contrib/paulistring/recombine_test.py +3 -1
- cirq/contrib/paulistring/separate.py +9 -6
- cirq/contrib/paulistring/separate_test.py +3 -1
- cirq/contrib/qasm_import/_lexer.py +3 -2
- cirq/contrib/qasm_import/_lexer_test.py +49 -13
- cirq/contrib/qasm_import/_parser.py +547 -83
- cirq/contrib/qasm_import/_parser_test.py +988 -97
- cirq/contrib/qasm_import/exception.py +2 -0
- cirq/contrib/qasm_import/qasm.py +8 -2
- cirq/contrib/qasm_import/qasm_test.py +7 -4
- cirq/contrib/qcircuit/qcircuit_diagram_info.py +5 -5
- cirq/contrib/qcircuit/qcircuit_diagram_info_test.py +4 -1
- cirq/contrib/qcircuit/qcircuit_pdf.py +7 -3
- cirq/contrib/qcircuit/qcircuit_pdf_test.py +3 -1
- cirq/contrib/qcircuit/qcircuit_test.py +10 -8
- cirq/contrib/quantum_volume/quantum_volume.py +31 -27
- cirq/contrib/quantum_volume/quantum_volume_test.py +19 -16
- cirq/contrib/quimb/density_matrix.py +15 -14
- cirq/contrib/quimb/density_matrix_test.py +10 -7
- cirq/contrib/quimb/grid_circuits.py +5 -2
- cirq/contrib/quimb/grid_circuits_test.py +3 -0
- cirq/contrib/quimb/mps_simulator.py +20 -20
- cirq/contrib/quimb/mps_simulator_test.py +3 -0
- cirq/contrib/quimb/state_vector.py +12 -11
- cirq/contrib/quimb/state_vector_test.py +3 -0
- cirq/contrib/quirk/export_to_quirk.py +5 -3
- cirq/contrib/quirk/export_to_quirk_test.py +18 -16
- cirq/contrib/quirk/linearize_circuit.py +2 -0
- cirq/contrib/quirk/quirk_gate.py +18 -17
- cirq/contrib/routing/device.py +5 -3
- cirq/contrib/routing/device_test.py +2 -0
- cirq/contrib/routing/greedy.py +10 -21
- cirq/contrib/routing/greedy_test.py +4 -2
- cirq/contrib/routing/initialization.py +2 -2
- cirq/contrib/routing/initialization_test.py +5 -3
- cirq/contrib/routing/router.py +9 -5
- cirq/contrib/routing/router_test.py +2 -0
- cirq/contrib/routing/swap_network.py +3 -3
- cirq/contrib/routing/swap_network_test.py +3 -1
- cirq/contrib/routing/utils.py +2 -2
- cirq/contrib/routing/utils_test.py +3 -0
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +15 -9
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +3 -0
- cirq/contrib/svg/svg.py +3 -3
- cirq/contrib/svg/svg_test.py +8 -5
- cirq/devices/device.py +4 -4
- cirq/devices/device_test.py +7 -4
- cirq/devices/grid_device_metadata.py +10 -10
- cirq/devices/grid_device_metadata_test.py +3 -0
- cirq/devices/grid_qubit.py +29 -21
- cirq/devices/grid_qubit_test.py +3 -0
- cirq/devices/insertion_noise_model.py +7 -7
- cirq/devices/insertion_noise_model_test.py +7 -5
- cirq/devices/line_qubit.py +13 -13
- cirq/devices/line_qubit_test.py +2 -0
- cirq/devices/named_topologies.py +18 -29
- cirq/devices/named_topologies_test.py +13 -10
- cirq/devices/noise_model.py +3 -3
- cirq/devices/noise_model_test.py +19 -15
- cirq/devices/noise_properties.py +15 -6
- cirq/devices/noise_properties_test.py +34 -3
- cirq/devices/noise_utils.py +11 -9
- cirq/devices/noise_utils_test.py +2 -0
- cirq/devices/superconducting_qubits_noise_properties.py +23 -22
- cirq/devices/superconducting_qubits_noise_properties_test.py +6 -6
- cirq/devices/thermal_noise_model.py +107 -37
- cirq/devices/thermal_noise_model_test.py +21 -0
- cirq/devices/unconstrained_device.py +5 -3
- cirq/devices/unconstrained_device_test.py +2 -0
- cirq/experiments/__init__.py +4 -2
- cirq/experiments/benchmarking/__init__.py +17 -0
- cirq/experiments/benchmarking/parallel_xeb.py +677 -0
- cirq/experiments/benchmarking/parallel_xeb_test.py +447 -0
- cirq/experiments/fidelity_estimation.py +14 -8
- cirq/experiments/fidelity_estimation_test.py +3 -0
- cirq/experiments/n_qubit_tomography.py +17 -16
- cirq/experiments/n_qubit_tomography_test.py +8 -5
- cirq/experiments/purity_estimation.py +2 -0
- cirq/experiments/purity_estimation_test.py +2 -0
- cirq/experiments/qubit_characterizations.py +207 -103
- cirq/experiments/qubit_characterizations_test.py +40 -12
- cirq/experiments/random_quantum_circuit_generation.py +56 -70
- cirq/experiments/random_quantum_circuit_generation_test.py +11 -8
- cirq/experiments/readout_confusion_matrix.py +24 -22
- cirq/experiments/readout_confusion_matrix_test.py +2 -0
- cirq/experiments/single_qubit_readout_calibration.py +30 -15
- cirq/experiments/single_qubit_readout_calibration_test.py +5 -2
- cirq/experiments/t1_decay_experiment.py +9 -7
- cirq/experiments/t1_decay_experiment_test.py +13 -11
- cirq/experiments/t2_decay_experiment.py +16 -13
- cirq/experiments/t2_decay_experiment_test.py +2 -0
- cirq/experiments/two_qubit_xeb.py +64 -57
- cirq/experiments/two_qubit_xeb_test.py +10 -6
- cirq/experiments/xeb_fitting.py +39 -35
- cirq/experiments/xeb_sampling.py +37 -44
- cirq/experiments/xeb_sampling_test.py +3 -0
- cirq/experiments/xeb_simulation.py +14 -10
- cirq/experiments/xeb_simulation_test.py +5 -5
- cirq/experiments/z_phase_calibration.py +32 -29
- cirq/experiments/z_phase_calibration_test.py +3 -4
- cirq/interop/quirk/cells/__init__.py +1 -1
- cirq/interop/quirk/cells/all_cells.py +7 -2
- cirq/interop/quirk/cells/arithmetic_cells.py +29 -41
- cirq/interop/quirk/cells/arithmetic_cells_test.py +17 -14
- cirq/interop/quirk/cells/cell.py +19 -28
- cirq/interop/quirk/cells/cell_test.py +3 -0
- cirq/interop/quirk/cells/composite_cell.py +13 -28
- cirq/interop/quirk/cells/composite_cell_test.py +2 -0
- cirq/interop/quirk/cells/control_cells.py +15 -15
- cirq/interop/quirk/cells/control_cells_test.py +7 -5
- cirq/interop/quirk/cells/frequency_space_cells.py +4 -3
- cirq/interop/quirk/cells/frequency_space_cells_test.py +3 -1
- cirq/interop/quirk/cells/ignored_cells.py +3 -0
- cirq/interop/quirk/cells/ignored_cells_test.py +3 -1
- cirq/interop/quirk/cells/input_cells.py +7 -5
- cirq/interop/quirk/cells/input_cells_test.py +7 -5
- cirq/interop/quirk/cells/input_rotation_cells.py +15 -13
- cirq/interop/quirk/cells/input_rotation_cells_test.py +9 -7
- cirq/interop/quirk/cells/measurement_cells.py +5 -2
- cirq/interop/quirk/cells/measurement_cells_test.py +3 -1
- cirq/interop/quirk/cells/parse.py +22 -23
- cirq/interop/quirk/cells/parse_test.py +12 -10
- cirq/interop/quirk/cells/qubit_permutation_cells.py +5 -3
- cirq/interop/quirk/cells/qubit_permutation_cells_test.py +9 -7
- cirq/interop/quirk/cells/scalar_cells.py +4 -1
- cirq/interop/quirk/cells/scalar_cells_test.py +3 -1
- cirq/interop/quirk/cells/single_qubit_rotation_cells.py +5 -2
- cirq/interop/quirk/cells/single_qubit_rotation_cells_test.py +5 -3
- cirq/interop/quirk/cells/swap_cell.py +8 -6
- cirq/interop/quirk/cells/swap_cell_test.py +6 -4
- cirq/interop/quirk/cells/testing.py +6 -6
- cirq/interop/quirk/cells/testing_test.py +8 -6
- cirq/interop/quirk/cells/unsupported_cells.py +3 -0
- cirq/interop/quirk/cells/unsupported_cells_test.py +4 -2
- cirq/interop/quirk/url_to_circuit.py +23 -36
- cirq/interop/quirk/url_to_circuit_test.py +4 -1
- cirq/json_resolver_cache.py +14 -12
- cirq/linalg/__init__.py +4 -6
- cirq/linalg/combinators.py +7 -5
- cirq/linalg/combinators_test.py +10 -7
- cirq/linalg/decompositions.py +24 -35
- cirq/linalg/decompositions_test.py +3 -1
- cirq/linalg/diagonalize.py +6 -4
- cirq/linalg/diagonalize_test.py +15 -14
- cirq/linalg/operator_spaces.py +14 -14
- cirq/linalg/operator_spaces_test.py +13 -11
- cirq/linalg/predicates.py +18 -9
- cirq/linalg/predicates_test.py +5 -0
- cirq/linalg/tolerance.py +6 -3
- cirq/linalg/tolerance_test.py +6 -4
- cirq/linalg/transformations.py +23 -20
- cirq/linalg/transformations_test.py +73 -43
- cirq/neutral_atoms/convert_to_neutral_atom_gates.py +9 -3
- cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +3 -1
- cirq/neutral_atoms/neutral_atom_devices.py +2 -0
- cirq/ops/__init__.py +2 -0
- cirq/ops/arithmetic_operation.py +21 -21
- cirq/ops/arithmetic_operation_test.py +7 -8
- cirq/ops/boolean_hamiltonian.py +23 -22
- cirq/ops/boolean_hamiltonian_test.py +12 -9
- cirq/ops/classically_controlled_operation.py +31 -36
- cirq/ops/classically_controlled_operation_test.py +121 -117
- cirq/ops/clifford_gate.py +98 -81
- cirq/ops/clifford_gate_test.py +72 -57
- cirq/ops/common_channels.py +44 -44
- cirq/ops/common_channels_test.py +83 -81
- cirq/ops/common_gate_families.py +9 -7
- cirq/ops/common_gate_families_test.py +11 -7
- cirq/ops/common_gates.py +164 -183
- cirq/ops/common_gates_test.py +135 -95
- cirq/ops/control_values.py +23 -26
- cirq/ops/control_values_test.py +22 -20
- cirq/ops/controlled_gate.py +64 -112
- cirq/ops/controlled_gate_test.py +130 -35
- cirq/ops/controlled_operation.py +24 -35
- cirq/ops/controlled_operation_test.py +8 -6
- cirq/ops/dense_pauli_string.py +38 -49
- cirq/ops/dense_pauli_string_test.py +4 -2
- cirq/ops/diagonal_gate.py +18 -31
- cirq/ops/diagonal_gate_test.py +13 -13
- cirq/ops/eigen_gate.py +29 -29
- cirq/ops/eigen_gate_test.py +45 -28
- cirq/ops/fourier_transform.py +14 -20
- cirq/ops/fourier_transform_test.py +15 -12
- cirq/ops/fsim_gate.py +43 -42
- cirq/ops/fsim_gate_test.py +29 -29
- cirq/ops/gate_features.py +2 -0
- cirq/ops/gate_features_test.py +5 -3
- cirq/ops/gate_operation.py +43 -65
- cirq/ops/gate_operation_test.py +46 -42
- cirq/ops/gateset.py +28 -40
- cirq/ops/gateset_test.py +4 -2
- cirq/ops/global_phase_op.py +45 -20
- cirq/ops/global_phase_op_test.py +44 -20
- cirq/ops/greedy_qubit_manager.py +10 -8
- cirq/ops/greedy_qubit_manager_test.py +5 -3
- cirq/ops/identity.py +14 -12
- cirq/ops/identity_test.py +24 -20
- cirq/ops/kraus_channel.py +11 -8
- cirq/ops/kraus_channel_test.py +14 -11
- cirq/ops/linear_combinations.py +65 -77
- cirq/ops/linear_combinations_test.py +14 -9
- cirq/ops/matrix_gates.py +21 -18
- cirq/ops/matrix_gates_test.py +16 -0
- cirq/ops/measure_util.py +15 -20
- cirq/ops/measure_util_test.py +2 -0
- cirq/ops/measurement_gate.py +26 -37
- cirq/ops/measurement_gate_test.py +2 -0
- cirq/ops/mixed_unitary_channel.py +12 -9
- cirq/ops/mixed_unitary_channel_test.py +14 -11
- cirq/ops/named_qubit.py +16 -13
- cirq/ops/named_qubit_test.py +15 -13
- cirq/ops/op_tree.py +9 -7
- cirq/ops/op_tree_test.py +22 -19
- cirq/ops/parallel_gate.py +15 -17
- cirq/ops/parallel_gate_test.py +18 -16
- cirq/ops/parity_gates.py +23 -25
- cirq/ops/parity_gates_test.py +36 -32
- cirq/ops/pauli_gates.py +22 -21
- cirq/ops/pauli_gates_test.py +29 -20
- cirq/ops/pauli_interaction_gate.py +15 -19
- cirq/ops/pauli_interaction_gate_test.py +10 -8
- cirq/ops/pauli_measurement_gate.py +23 -35
- cirq/ops/pauli_measurement_gate_test.py +2 -0
- cirq/ops/pauli_string.py +92 -120
- cirq/ops/pauli_string_phasor.py +52 -45
- cirq/ops/pauli_string_phasor_test.py +4 -5
- cirq/ops/pauli_string_raw_types.py +9 -7
- cirq/ops/pauli_string_raw_types_test.py +2 -0
- cirq/ops/pauli_string_test.py +31 -154
- cirq/ops/pauli_sum_exponential.py +12 -12
- cirq/ops/pauli_sum_exponential_test.py +12 -10
- cirq/ops/permutation_gate.py +8 -6
- cirq/ops/permutation_gate_test.py +10 -8
- cirq/ops/phased_iswap_gate.py +16 -16
- cirq/ops/phased_iswap_gate_test.py +17 -15
- cirq/ops/phased_x_gate.py +16 -17
- cirq/ops/phased_x_gate_test.py +18 -16
- cirq/ops/phased_x_z_gate.py +24 -22
- cirq/ops/phased_x_z_gate_test.py +17 -11
- cirq/ops/projector.py +16 -11
- cirq/ops/projector_test.py +19 -16
- cirq/ops/qid_util.py +7 -5
- cirq/ops/qid_util_test.py +2 -0
- cirq/ops/qubit_manager.py +11 -9
- cirq/ops/qubit_manager_test.py +6 -4
- cirq/ops/qubit_order.py +11 -14
- cirq/ops/qubit_order_or_list.py +4 -2
- cirq/ops/qubit_order_test.py +12 -10
- cirq/ops/random_gate_channel.py +12 -10
- cirq/ops/random_gate_channel_test.py +14 -11
- cirq/ops/raw_types.py +109 -129
- cirq/ops/raw_types_test.py +63 -57
- cirq/ops/state_preparation_channel.py +7 -7
- cirq/ops/state_preparation_channel_test.py +11 -9
- cirq/ops/swap_gates.py +13 -15
- cirq/ops/swap_gates_test.py +19 -17
- cirq/ops/tags.py +5 -3
- cirq/ops/tags_test.py +4 -2
- cirq/ops/three_qubit_gates.py +43 -76
- cirq/ops/three_qubit_gates_test.py +19 -17
- cirq/ops/two_qubit_diagonal_gate.py +13 -13
- cirq/ops/two_qubit_diagonal_gate_test.py +10 -8
- cirq/ops/uniform_superposition_gate.py +5 -3
- cirq/ops/uniform_superposition_gate_test.py +5 -3
- cirq/ops/wait_gate.py +17 -14
- cirq/ops/wait_gate_test.py +9 -6
- cirq/protocols/__init__.py +0 -3
- cirq/protocols/act_on_protocol.py +8 -6
- cirq/protocols/act_on_protocol_test.py +15 -12
- cirq/protocols/apply_channel_protocol.py +10 -14
- cirq/protocols/apply_channel_protocol_test.py +2 -0
- cirq/protocols/apply_mixture_protocol.py +13 -42
- cirq/protocols/apply_mixture_protocol_test.py +7 -5
- cirq/protocols/apply_unitary_protocol.py +39 -34
- cirq/protocols/apply_unitary_protocol_test.py +4 -1
- cirq/protocols/approximate_equality_protocol.py +2 -0
- cirq/protocols/approximate_equality_protocol_test.py +2 -0
- cirq/protocols/circuit_diagram_info_protocol.py +58 -42
- cirq/protocols/circuit_diagram_info_protocol_test.py +70 -12
- cirq/protocols/commutes_protocol.py +8 -7
- cirq/protocols/commutes_protocol_test.py +2 -0
- cirq/protocols/control_key_protocol.py +6 -4
- cirq/protocols/control_key_protocol_test.py +3 -1
- cirq/protocols/decompose_protocol.py +49 -48
- cirq/protocols/decompose_protocol_test.py +27 -16
- cirq/protocols/equal_up_to_global_phase_protocol.py +2 -0
- cirq/protocols/equal_up_to_global_phase_protocol_test.py +9 -6
- cirq/protocols/has_stabilizer_effect_protocol.py +7 -5
- cirq/protocols/has_stabilizer_effect_protocol_test.py +7 -5
- cirq/protocols/has_unitary_protocol.py +10 -6
- cirq/protocols/has_unitary_protocol_test.py +13 -8
- cirq/protocols/hash_from_pickle_test.py +2 -11
- cirq/protocols/inverse_protocol.py +13 -16
- cirq/protocols/inverse_protocol_test.py +5 -3
- cirq/protocols/json_serialization.py +35 -54
- cirq/protocols/json_serialization_test.py +14 -21
- cirq/protocols/json_test_data/CXSWAP.json +46 -0
- cirq/protocols/json_test_data/CXSWAP.repr +13 -0
- cirq/protocols/json_test_data/CZSWAP.json +46 -0
- cirq/protocols/json_test_data/CZSWAP.repr +13 -0
- cirq/protocols/json_test_data/CircuitOperation.json +6 -3
- cirq/protocols/json_test_data/CircuitOperation.repr_inward +4 -2
- cirq/protocols/json_test_data/Moment.json +24 -1
- cirq/protocols/json_test_data/Moment.repr +6 -1
- cirq/protocols/json_test_data/ThermalNoiseModel.json +32 -0
- cirq/protocols/json_test_data/ThermalNoiseModel.repr +1 -0
- cirq/protocols/json_test_data/spec.py +6 -2
- cirq/protocols/kraus_protocol.py +47 -7
- cirq/protocols/kraus_protocol_test.py +86 -12
- cirq/protocols/measurement_key_protocol.py +15 -16
- cirq/protocols/measurement_key_protocol_test.py +13 -11
- cirq/protocols/mixture_protocol.py +7 -5
- cirq/protocols/mixture_protocol_test.py +4 -2
- cirq/protocols/mul_protocol.py +2 -3
- cirq/protocols/mul_protocol_test.py +2 -0
- cirq/protocols/pauli_expansion_protocol.py +6 -3
- cirq/protocols/pauli_expansion_protocol_test.py +5 -3
- cirq/protocols/phase_protocol.py +2 -0
- cirq/protocols/phase_protocol_test.py +3 -1
- cirq/protocols/pow_protocol.py +11 -16
- cirq/protocols/pow_protocol_test.py +2 -0
- cirq/protocols/qasm.py +14 -20
- cirq/protocols/qasm_test.py +6 -3
- cirq/protocols/qid_shape_protocol.py +8 -8
- cirq/protocols/qid_shape_protocol_test.py +3 -1
- cirq/protocols/resolve_parameters.py +5 -3
- cirq/protocols/resolve_parameters_test.py +8 -7
- cirq/protocols/trace_distance_bound.py +6 -4
- cirq/protocols/trace_distance_bound_test.py +3 -1
- cirq/protocols/unitary_protocol.py +17 -7
- cirq/protocols/unitary_protocol_test.py +12 -2
- cirq/qis/channels.py +6 -2
- cirq/qis/channels_test.py +20 -16
- cirq/qis/clifford_tableau.py +21 -19
- cirq/qis/clifford_tableau_test.py +2 -2
- cirq/qis/entropy.py +14 -3
- cirq/qis/entropy_test.py +3 -1
- cirq/qis/measures.py +13 -13
- cirq/qis/measures_test.py +20 -14
- cirq/qis/noise_utils.py +2 -0
- cirq/qis/noise_utils_test.py +9 -7
- cirq/qis/quantum_state_representation.py +7 -8
- cirq/qis/states.py +58 -56
- cirq/qis/states_test.py +2 -0
- cirq/sim/classical_simulator.py +23 -22
- cirq/sim/classical_simulator_test.py +2 -0
- cirq/sim/clifford/clifford_simulator.py +23 -21
- cirq/sim/clifford/clifford_simulator_test.py +7 -4
- cirq/sim/clifford/clifford_tableau_simulation_state.py +10 -7
- cirq/sim/clifford/clifford_tableau_simulation_state_test.py +5 -5
- cirq/sim/clifford/stabilizer_ch_form_simulation_state.py +8 -6
- cirq/sim/clifford/stabilizer_ch_form_simulation_state_test.py +8 -6
- cirq/sim/clifford/stabilizer_sampler.py +9 -7
- cirq/sim/clifford/stabilizer_sampler_test.py +4 -2
- cirq/sim/clifford/stabilizer_simulation_state.py +14 -13
- cirq/sim/clifford/stabilizer_simulation_state_test.py +6 -4
- cirq/sim/clifford/stabilizer_state_ch_form.py +13 -11
- cirq/sim/clifford/stabilizer_state_ch_form_test.py +4 -2
- cirq/sim/density_matrix_simulation_state.py +26 -27
- cirq/sim/density_matrix_simulation_state_test.py +10 -8
- cirq/sim/density_matrix_simulator.py +30 -28
- cirq/sim/density_matrix_simulator_test.py +48 -48
- cirq/sim/density_matrix_utils.py +13 -11
- cirq/sim/density_matrix_utils_test.py +38 -36
- cirq/sim/mux.py +33 -31
- cirq/sim/mux_test.py +3 -0
- cirq/sim/simulation_product_state.py +15 -15
- cirq/sim/simulation_product_state_test.py +29 -26
- cirq/sim/simulation_state.py +29 -38
- cirq/sim/simulation_state_base.py +21 -32
- cirq/sim/simulation_state_test.py +15 -13
- cirq/sim/simulation_utils.py +5 -2
- cirq/sim/simulation_utils_test.py +5 -2
- cirq/sim/simulator.py +90 -106
- cirq/sim/simulator_base.py +33 -45
- cirq/sim/simulator_base_test.py +20 -15
- cirq/sim/simulator_test.py +23 -14
- cirq/sim/sparse_simulator.py +19 -17
- cirq/sim/sparse_simulator_test.py +41 -40
- cirq/sim/state_vector.py +15 -12
- cirq/sim/state_vector_simulation_state.py +31 -31
- cirq/sim/state_vector_simulation_state_test.py +16 -14
- cirq/sim/state_vector_simulator.py +17 -14
- cirq/sim/state_vector_simulator_test.py +2 -0
- cirq/sim/state_vector_test.py +6 -3
- cirq/study/flatten_expressions.py +16 -15
- cirq/study/flatten_expressions_test.py +13 -11
- cirq/study/resolver.py +18 -17
- cirq/study/resolver_test.py +22 -20
- cirq/study/result.py +17 -27
- cirq/study/result_test.py +2 -0
- cirq/study/sweepable.py +12 -10
- cirq/study/sweepable_test.py +3 -0
- cirq/study/sweeps.py +42 -61
- cirq/study/sweeps_test.py +33 -0
- cirq/testing/__init__.py +7 -11
- cirq/testing/_compat_test_data/module_a/__init__.py +1 -0
- cirq/testing/_compat_test_data/module_a/module_b/__init__.py +1 -0
- cirq/testing/_compat_test_data/module_a/sub/__init__.py +1 -0
- cirq/testing/circuit_compare.py +8 -17
- cirq/testing/circuit_compare_test.py +2 -0
- cirq/testing/consistent_act_on.py +13 -11
- cirq/testing/consistent_act_on_test.py +5 -3
- cirq/testing/consistent_channels.py +2 -0
- cirq/testing/consistent_channels_test.py +10 -8
- cirq/testing/consistent_controlled_gate_op.py +5 -5
- cirq/testing/consistent_controlled_gate_op_test.py +18 -18
- cirq/testing/consistent_decomposition.py +2 -2
- cirq/testing/consistent_decomposition_test.py +4 -2
- cirq/testing/consistent_pauli_expansion.py +2 -0
- cirq/testing/consistent_pauli_expansion_test.py +3 -1
- cirq/testing/consistent_phase_by.py +2 -0
- cirq/testing/consistent_phase_by_test.py +3 -1
- cirq/testing/consistent_protocols.py +14 -20
- cirq/testing/consistent_protocols_test.py +13 -11
- cirq/testing/consistent_qasm.py +6 -4
- cirq/testing/consistent_qasm_test.py +7 -7
- cirq/testing/consistent_resolve_parameters.py +2 -0
- cirq/testing/consistent_specified_has_unitary.py +2 -2
- cirq/testing/consistent_specified_has_unitary_test.py +6 -4
- cirq/testing/consistent_unitary.py +1 -0
- cirq/testing/consistent_unitary_test.py +4 -2
- cirq/testing/deprecation.py +5 -2
- cirq/testing/deprecation_test.py +5 -2
- cirq/testing/devices.py +7 -4
- cirq/testing/devices_test.py +7 -4
- cirq/testing/equals_tester.py +4 -2
- cirq/testing/equals_tester_test.py +21 -17
- cirq/testing/equivalent_basis_map.py +6 -4
- cirq/testing/equivalent_basis_map_test.py +6 -4
- cirq/testing/equivalent_repr_eval.py +6 -4
- cirq/testing/equivalent_repr_eval_test.py +5 -3
- cirq/testing/gate_features.py +2 -0
- cirq/testing/gate_features_test.py +7 -5
- cirq/testing/json.py +19 -15
- cirq/testing/json_test.py +5 -3
- cirq/testing/lin_alg_utils.py +10 -11
- cirq/testing/lin_alg_utils_test.py +14 -12
- cirq/testing/logs.py +7 -6
- cirq/testing/logs_test.py +9 -7
- cirq/testing/no_identifier_qubit.py +4 -2
- cirq/testing/no_identifier_qubit_test.py +5 -3
- cirq/testing/op_tree.py +2 -0
- cirq/testing/op_tree_test.py +4 -1
- cirq/testing/order_tester.py +2 -0
- cirq/testing/order_tester_test.py +8 -6
- cirq/testing/pytest_utils.py +2 -0
- cirq/testing/pytest_utils_test.py +4 -2
- cirq/testing/random_circuit.py +21 -20
- cirq/testing/random_circuit_test.py +12 -9
- cirq/testing/repr_pretty_tester.py +1 -0
- cirq/testing/repr_pretty_tester_test.py +5 -3
- cirq/testing/routing_devices.py +4 -1
- cirq/testing/routing_devices_test.py +9 -6
- cirq/testing/sample_circuits.py +4 -1
- cirq/testing/sample_circuits_test.py +3 -1
- cirq/testing/sample_gates.py +3 -0
- cirq/testing/sample_gates_test.py +5 -2
- cirq/transformers/__init__.py +11 -4
- cirq/transformers/align.py +9 -7
- cirq/transformers/align_test.py +2 -0
- cirq/transformers/analytical_decompositions/__init__.py +3 -6
- cirq/transformers/analytical_decompositions/clifford_decomposition.py +18 -16
- cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +2 -0
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +19 -16
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
- cirq/transformers/analytical_decompositions/cphase_to_fsim.py +11 -9
- cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +5 -3
- cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +5 -3
- cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +5 -3
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +141 -44
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +35 -1
- cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +8 -7
- cirq/transformers/analytical_decompositions/single_qubit_decompositions_test.py +2 -0
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +7 -4
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +3 -0
- cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +11 -19
- cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +8 -33
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +9 -11
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -0
- cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +91 -27
- cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +36 -7
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +20 -21
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +8 -6
- cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +13 -15
- cirq/transformers/analytical_decompositions/two_qubit_to_ms_test.py +3 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +39 -41
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -0
- cirq/transformers/drop_empty_moments.py +5 -3
- cirq/transformers/drop_empty_moments_test.py +4 -2
- cirq/transformers/drop_negligible_operations.py +7 -5
- cirq/transformers/drop_negligible_operations_test.py +2 -0
- cirq/transformers/dynamical_decoupling.py +49 -42
- cirq/transformers/dynamical_decoupling_test.py +223 -205
- cirq/transformers/eject_phased_paulis.py +28 -26
- cirq/transformers/eject_phased_paulis_test.py +12 -9
- cirq/transformers/eject_z.py +12 -12
- cirq/transformers/eject_z_test.py +2 -2
- cirq/transformers/expand_composite.py +6 -4
- cirq/transformers/expand_composite_test.py +3 -1
- cirq/transformers/gauge_compiling/__init__.py +3 -1
- cirq/transformers/gauge_compiling/cphase_gauge.py +2 -0
- cirq/transformers/gauge_compiling/cphase_gauge_test.py +2 -0
- cirq/transformers/gauge_compiling/cz_gauge.py +2 -0
- cirq/transformers/gauge_compiling/cz_gauge_test.py +1 -0
- cirq/transformers/gauge_compiling/gauge_compiling.py +45 -41
- cirq/transformers/gauge_compiling/gauge_compiling_test.py +2 -0
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +1 -0
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +5 -1
- cirq/transformers/gauge_compiling/iswap_gauge.py +2 -0
- cirq/transformers/gauge_compiling/iswap_gauge_test.py +1 -0
- cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -0
- cirq/transformers/gauge_compiling/spin_inversion_gauge_test.py +2 -0
- cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +7 -6
- cirq/transformers/gauge_compiling/sqrt_cz_gauge_test.py +2 -0
- cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +2 -0
- cirq/transformers/gauge_compiling/sqrt_iswap_gauge_test.py +2 -0
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +6 -3
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +3 -0
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +12 -9
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +9 -7
- cirq/transformers/insertion_sort.py +8 -6
- cirq/transformers/insertion_sort_test.py +3 -1
- cirq/transformers/measurement_transformers.py +29 -29
- cirq/transformers/measurement_transformers_test.py +2 -0
- cirq/transformers/merge_k_qubit_gates.py +12 -10
- cirq/transformers/merge_k_qubit_gates_test.py +18 -18
- cirq/transformers/merge_single_qubit_gates.py +197 -20
- cirq/transformers/merge_single_qubit_gates_test.py +177 -5
- cirq/transformers/noise_adding.py +5 -3
- cirq/transformers/noise_adding_test.py +2 -0
- cirq/transformers/optimize_for_target_gateset.py +19 -17
- cirq/transformers/optimize_for_target_gateset_test.py +11 -8
- cirq/transformers/qubit_management_transformers.py +13 -11
- cirq/transformers/qubit_management_transformers_test.py +5 -3
- cirq/transformers/randomized_measurements.py +16 -14
- cirq/transformers/randomized_measurements_test.py +10 -4
- cirq/transformers/routing/initial_mapper.py +6 -4
- cirq/transformers/routing/initial_mapper_test.py +2 -0
- cirq/transformers/routing/line_initial_mapper.py +16 -14
- cirq/transformers/routing/line_initial_mapper_test.py +9 -7
- cirq/transformers/routing/mapping_manager.py +10 -10
- cirq/transformers/routing/mapping_manager_test.py +2 -0
- cirq/transformers/routing/route_circuit_cqc.py +33 -31
- cirq/transformers/routing/route_circuit_cqc_test.py +15 -13
- cirq/transformers/routing/visualize_routed_circuit.py +8 -7
- cirq/transformers/routing/visualize_routed_circuit_test.py +4 -2
- cirq/transformers/stratify.py +17 -15
- cirq/transformers/stratify_test.py +3 -0
- cirq/transformers/symbolize.py +103 -0
- cirq/transformers/symbolize_test.py +62 -0
- cirq/transformers/synchronize_terminal_measurements.py +10 -10
- cirq/transformers/synchronize_terminal_measurements_test.py +12 -10
- cirq/transformers/tag_transformers.py +97 -0
- cirq/transformers/tag_transformers_test.py +103 -0
- cirq/transformers/target_gatesets/compilation_target_gateset.py +21 -19
- cirq/transformers/target_gatesets/compilation_target_gateset_test.py +20 -16
- cirq/transformers/target_gatesets/cz_gateset.py +7 -5
- cirq/transformers/target_gatesets/cz_gateset_test.py +21 -19
- cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +9 -7
- cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +25 -25
- cirq/transformers/transformer_api.py +34 -47
- cirq/transformers/transformer_api_test.py +9 -8
- cirq/transformers/transformer_primitives.py +39 -49
- cirq/transformers/transformer_primitives_test.py +10 -17
- cirq/value/abc_alt.py +6 -4
- cirq/value/abc_alt_test.py +5 -3
- cirq/value/angle.py +11 -12
- cirq/value/angle_test.py +5 -3
- cirq/value/classical_data.py +27 -27
- cirq/value/classical_data_test.py +11 -8
- cirq/value/condition.py +26 -24
- cirq/value/condition_test.py +2 -0
- cirq/value/digits.py +14 -11
- cirq/value/digits_test.py +2 -0
- cirq/value/duration.py +23 -20
- cirq/value/duration_test.py +2 -0
- cirq/value/linear_dict.py +25 -30
- cirq/value/linear_dict_test.py +10 -8
- cirq/value/measurement_key.py +12 -12
- cirq/value/measurement_key_test.py +2 -0
- cirq/value/periodic_value.py +4 -4
- cirq/value/periodic_value_test.py +11 -7
- cirq/value/probability.py +3 -1
- cirq/value/probability_test.py +4 -2
- cirq/value/product_state.py +15 -13
- cirq/value/product_state_test.py +4 -1
- cirq/value/random_state.py +2 -0
- cirq/value/random_state_test.py +5 -3
- cirq/value/timestamp.py +11 -7
- cirq/value/timestamp_test.py +14 -12
- cirq/value/type_alias.py +4 -4
- cirq/value/value_equality_attr.py +8 -9
- cirq/value/value_equality_attr_test.py +14 -11
- cirq/vis/density_matrix.py +3 -3
- cirq/vis/density_matrix_test.py +20 -17
- cirq/vis/heatmap.py +24 -37
- cirq/vis/heatmap_test.py +3 -0
- cirq/vis/histogram.py +9 -6
- cirq/vis/histogram_test.py +5 -2
- cirq/vis/state_histogram.py +10 -8
- cirq/vis/state_histogram_test.py +7 -5
- cirq/vis/vis_utils.py +4 -1
- cirq/vis/vis_utils_test.py +4 -1
- cirq/work/collector.py +12 -18
- cirq/work/collector_test.py +15 -10
- cirq/work/observable_grouping.py +6 -7
- cirq/work/observable_grouping_test.py +10 -9
- cirq/work/observable_measurement.py +47 -45
- cirq/work/observable_measurement_data.py +22 -17
- cirq/work/observable_measurement_data_test.py +4 -1
- cirq/work/observable_measurement_test.py +48 -29
- cirq/work/observable_readout_calibration.py +5 -2
- cirq/work/observable_readout_calibration_test.py +5 -2
- cirq/work/observable_settings.py +13 -22
- cirq/work/observable_settings_test.py +9 -7
- cirq/work/pauli_sum_collector.py +12 -10
- cirq/work/pauli_sum_collector_test.py +9 -9
- cirq/work/sampler.py +42 -43
- cirq/work/sampler_test.py +31 -24
- cirq/work/zeros_sampler.py +6 -4
- cirq/work/zeros_sampler_test.py +7 -5
- {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/METADATA +7 -8
- cirq_core-1.6.0.dist-info/RECORD +1241 -0
- {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/WHEEL +1 -1
- cirq_core-1.5.0.dev20250409222543.dist-info/RECORD +0 -1216
- {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/licenses/LICENSE +0 -0
- {cirq_core-1.5.0.dev20250409222543.dist-info → cirq_core-1.6.0.dist-info}/top_level.txt +0 -0
cirq/devices/grid_qubit.py
CHANGED
|
@@ -17,7 +17,7 @@ from __future__ import annotations
|
|
|
17
17
|
import abc
|
|
18
18
|
import functools
|
|
19
19
|
import weakref
|
|
20
|
-
from typing import Any,
|
|
20
|
+
from typing import Any, Iterable, TYPE_CHECKING
|
|
21
21
|
|
|
22
22
|
import numpy as np
|
|
23
23
|
from typing_extensions import Self
|
|
@@ -35,7 +35,7 @@ class _BaseGridQid(ops.Qid):
|
|
|
35
35
|
_row: int
|
|
36
36
|
_col: int
|
|
37
37
|
_dimension: int
|
|
38
|
-
_comp_key:
|
|
38
|
+
_comp_key: tuple[int, int] | None = None
|
|
39
39
|
_hash: int
|
|
40
40
|
|
|
41
41
|
def __hash__(self) -> int:
|
|
@@ -116,8 +116,16 @@ class _BaseGridQid(ops.Qid):
|
|
|
116
116
|
and abs(self._row - other._row) + abs(self._col - other._col) == 1
|
|
117
117
|
)
|
|
118
118
|
|
|
119
|
-
def neighbors(self, qids:
|
|
120
|
-
"""Returns qubits that are potential neighbors to this GridQid
|
|
119
|
+
def neighbors(self, qids: Iterable[ops.Qid] | None = None) -> set[_BaseGridQid]:
|
|
120
|
+
"""Returns qubits that are potential neighbors to this GridQid.
|
|
121
|
+
|
|
122
|
+
Note that this returns _potential_ neighbors. That is, if no arguments
|
|
123
|
+
are given, this returns the qubits above, below, to the right and left of
|
|
124
|
+
the Qid in the grid. It does not take into account any hardware device
|
|
125
|
+
layout.
|
|
126
|
+
|
|
127
|
+
If you want to take into account the device layout, you must pass in the
|
|
128
|
+
device's qubit set as the `qids` parameter.
|
|
121
129
|
|
|
122
130
|
Args:
|
|
123
131
|
qids: optional Iterable of qubits to constrain neighbors to.
|
|
@@ -135,7 +143,7 @@ class _BaseGridQid(ops.Qid):
|
|
|
135
143
|
def __complex__(self) -> complex:
|
|
136
144
|
return self._col + 1j * self._row
|
|
137
145
|
|
|
138
|
-
def __add__(self, other:
|
|
146
|
+
def __add__(self, other: tuple[int, int] | Self) -> Self:
|
|
139
147
|
if isinstance(other, _BaseGridQid):
|
|
140
148
|
if self.dimension != other.dimension:
|
|
141
149
|
raise TypeError(
|
|
@@ -154,7 +162,7 @@ class _BaseGridQid(ops.Qid):
|
|
|
154
162
|
)
|
|
155
163
|
return self._with_row_col(row=self._row + other[0], col=self._col + other[1])
|
|
156
164
|
|
|
157
|
-
def __sub__(self, other:
|
|
165
|
+
def __sub__(self, other: tuple[int, int] | Self) -> Self:
|
|
158
166
|
if isinstance(other, _BaseGridQid):
|
|
159
167
|
if self.dimension != other.dimension:
|
|
160
168
|
raise TypeError(
|
|
@@ -173,10 +181,10 @@ class _BaseGridQid(ops.Qid):
|
|
|
173
181
|
)
|
|
174
182
|
return self._with_row_col(row=self._row - other[0], col=self._col - other[1])
|
|
175
183
|
|
|
176
|
-
def __radd__(self, other:
|
|
184
|
+
def __radd__(self, other: tuple[int, int]) -> Self:
|
|
177
185
|
return self + other
|
|
178
186
|
|
|
179
|
-
def __rsub__(self, other:
|
|
187
|
+
def __rsub__(self, other: tuple[int, int]) -> Self:
|
|
180
188
|
return -self + other
|
|
181
189
|
|
|
182
190
|
def __neg__(self) -> Self:
|
|
@@ -204,7 +212,7 @@ class GridQid(_BaseGridQid):
|
|
|
204
212
|
|
|
205
213
|
# Cache of existing GridQid instances, returned by __new__ if available.
|
|
206
214
|
# Holds weak references so instances can still be garbage collected.
|
|
207
|
-
_cache = weakref.WeakValueDictionary[
|
|
215
|
+
_cache = weakref.WeakValueDictionary[tuple[int, int, int], 'cirq.GridQid']()
|
|
208
216
|
|
|
209
217
|
def __new__(cls, row: int, col: int, *, dimension: int) -> cirq.GridQid:
|
|
210
218
|
"""Creates a grid qid at the given row, col coordinate
|
|
@@ -233,14 +241,14 @@ class GridQid(_BaseGridQid):
|
|
|
233
241
|
return (self._row, self._col), {"dimension": self._dimension}
|
|
234
242
|
|
|
235
243
|
# avoid pickling the _hash value, attributes are already stored with __getnewargs_ex__
|
|
236
|
-
def __getstate__(self) ->
|
|
244
|
+
def __getstate__(self) -> dict[str, Any]:
|
|
237
245
|
return {}
|
|
238
246
|
|
|
239
247
|
def _with_row_col(self, row: int, col: int) -> GridQid:
|
|
240
248
|
return GridQid(row, col, dimension=self._dimension)
|
|
241
249
|
|
|
242
250
|
@staticmethod
|
|
243
|
-
def square(diameter: int, top: int = 0, left: int = 0, *, dimension: int) ->
|
|
251
|
+
def square(diameter: int, top: int = 0, left: int = 0, *, dimension: int) -> list[GridQid]:
|
|
244
252
|
"""Returns a square of GridQid.
|
|
245
253
|
|
|
246
254
|
Args:
|
|
@@ -256,7 +264,7 @@ class GridQid(_BaseGridQid):
|
|
|
256
264
|
return GridQid.rect(diameter, diameter, top=top, left=left, dimension=dimension)
|
|
257
265
|
|
|
258
266
|
@staticmethod
|
|
259
|
-
def rect(rows: int, cols: int, top: int = 0, left: int = 0, *, dimension: int) ->
|
|
267
|
+
def rect(rows: int, cols: int, top: int = 0, left: int = 0, *, dimension: int) -> list[GridQid]:
|
|
260
268
|
"""Returns a rectangle of GridQid.
|
|
261
269
|
|
|
262
270
|
Args:
|
|
@@ -277,7 +285,7 @@ class GridQid(_BaseGridQid):
|
|
|
277
285
|
]
|
|
278
286
|
|
|
279
287
|
@staticmethod
|
|
280
|
-
def from_diagram(diagram: str, dimension: int) ->
|
|
288
|
+
def from_diagram(diagram: str, dimension: int) -> list[GridQid]:
|
|
281
289
|
"""Parse ASCII art device layout into a device.
|
|
282
290
|
|
|
283
291
|
As an example, the below diagram will create a list of GridQid in a
|
|
@@ -342,7 +350,7 @@ class GridQid(_BaseGridQid):
|
|
|
342
350
|
wire_symbols=(f"({self._row}, {self._col}) (d={self._dimension})",)
|
|
343
351
|
)
|
|
344
352
|
|
|
345
|
-
def _json_dict_(self) ->
|
|
353
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
346
354
|
return protocols.obj_to_dict_helper(self, ['row', 'col', 'dimension'])
|
|
347
355
|
|
|
348
356
|
|
|
@@ -367,7 +375,7 @@ class GridQubit(_BaseGridQid):
|
|
|
367
375
|
|
|
368
376
|
# Cache of existing GridQubit instances, returned by __new__ if available.
|
|
369
377
|
# Holds weak references so instances can still be garbage collected.
|
|
370
|
-
_cache = weakref.WeakValueDictionary[
|
|
378
|
+
_cache = weakref.WeakValueDictionary[tuple[int, int], 'cirq.GridQubit']()
|
|
371
379
|
|
|
372
380
|
def __new__(cls, row: int, col: int) -> cirq.GridQubit:
|
|
373
381
|
"""Creates a grid qubit at the given row, col coordinate
|
|
@@ -391,14 +399,14 @@ class GridQubit(_BaseGridQid):
|
|
|
391
399
|
return (self._row, self._col)
|
|
392
400
|
|
|
393
401
|
# avoid pickling the _hash value, attributes are already stored with __getnewargs__
|
|
394
|
-
def __getstate__(self) ->
|
|
402
|
+
def __getstate__(self) -> dict[str, Any]:
|
|
395
403
|
return {}
|
|
396
404
|
|
|
397
405
|
def _with_row_col(self, row: int, col: int) -> GridQubit:
|
|
398
406
|
return GridQubit(row, col)
|
|
399
407
|
|
|
400
408
|
@staticmethod
|
|
401
|
-
def square(diameter: int, top: int = 0, left: int = 0) ->
|
|
409
|
+
def square(diameter: int, top: int = 0, left: int = 0) -> list[GridQubit]:
|
|
402
410
|
"""Returns a square of GridQubits.
|
|
403
411
|
|
|
404
412
|
Args:
|
|
@@ -412,7 +420,7 @@ class GridQubit(_BaseGridQid):
|
|
|
412
420
|
return GridQubit.rect(diameter, diameter, top=top, left=left)
|
|
413
421
|
|
|
414
422
|
@staticmethod
|
|
415
|
-
def rect(rows: int, cols: int, top: int = 0, left: int = 0) ->
|
|
423
|
+
def rect(rows: int, cols: int, top: int = 0, left: int = 0) -> list[GridQubit]:
|
|
416
424
|
"""Returns a rectangle of GridQubits.
|
|
417
425
|
|
|
418
426
|
Args:
|
|
@@ -431,7 +439,7 @@ class GridQubit(_BaseGridQid):
|
|
|
431
439
|
]
|
|
432
440
|
|
|
433
441
|
@staticmethod
|
|
434
|
-
def from_diagram(diagram: str) ->
|
|
442
|
+
def from_diagram(diagram: str) -> list[GridQubit]:
|
|
435
443
|
"""Parse ASCII art into device layout info.
|
|
436
444
|
|
|
437
445
|
As an example, the below diagram will create a list of
|
|
@@ -491,11 +499,11 @@ class GridQubit(_BaseGridQid):
|
|
|
491
499
|
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
492
500
|
return protocols.CircuitDiagramInfo(wire_symbols=(f"({self._row}, {self._col})",))
|
|
493
501
|
|
|
494
|
-
def _json_dict_(self) ->
|
|
502
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
495
503
|
return protocols.obj_to_dict_helper(self, ['row', 'col'])
|
|
496
504
|
|
|
497
505
|
|
|
498
|
-
def _ascii_diagram_to_coords(diagram: str) ->
|
|
506
|
+
def _ascii_diagram_to_coords(diagram: str) -> list[tuple[int, int]]:
|
|
499
507
|
"""Parse ASCII art device layout into info about qids coordinates
|
|
500
508
|
|
|
501
509
|
Args:
|
cirq/devices/grid_qubit_test.py
CHANGED
|
@@ -11,8 +11,11 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
"""Tests for grid_qubit."""
|
|
15
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
16
19
|
import pickle
|
|
17
20
|
|
|
18
21
|
import numpy as np
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
import dataclasses
|
|
18
|
-
from typing import Any,
|
|
18
|
+
from typing import Any, Mapping, Sequence, TYPE_CHECKING
|
|
19
19
|
|
|
20
20
|
from cirq import devices
|
|
21
21
|
from cirq.devices import noise_utils
|
|
@@ -44,21 +44,21 @@ class InsertionNoiseModel(devices.NoiseModel):
|
|
|
44
44
|
with PHYSICAL_GATE_TAG.
|
|
45
45
|
"""
|
|
46
46
|
|
|
47
|
-
ops_added:
|
|
47
|
+
ops_added: Mapping[noise_utils.OpIdentifier, cirq.Operation] = dataclasses.field(
|
|
48
48
|
default_factory=dict
|
|
49
49
|
)
|
|
50
50
|
prepend: bool = False
|
|
51
51
|
require_physical_tag: bool = True
|
|
52
52
|
|
|
53
53
|
def noisy_moment(self, moment: cirq.Moment, system_qubits: Sequence[cirq.Qid]) -> cirq.OP_TREE:
|
|
54
|
-
noise_ops:
|
|
54
|
+
noise_ops: list[cirq.Operation] = []
|
|
55
55
|
candidate_ops = [
|
|
56
56
|
op
|
|
57
57
|
for op in moment
|
|
58
58
|
if (not self.require_physical_tag) or noise_utils.PHYSICAL_GATE_TAG in op.tags
|
|
59
59
|
]
|
|
60
60
|
for op in candidate_ops:
|
|
61
|
-
match_id:
|
|
61
|
+
match_id: noise_utils.OpIdentifier | None = None
|
|
62
62
|
candidate_ids = [op_id for op_id in self.ops_added if op in op_id]
|
|
63
63
|
for op_id in candidate_ids:
|
|
64
64
|
if match_id is None or op_id.is_proper_subtype_of(match_id):
|
|
@@ -78,11 +78,11 @@ class InsertionNoiseModel(devices.NoiseModel):
|
|
|
78
78
|
def __repr__(self) -> str:
|
|
79
79
|
return (
|
|
80
80
|
f'cirq.devices.InsertionNoiseModel(ops_added={self.ops_added},'
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
f' prepend={self.prepend},'
|
|
82
|
+
f' require_physical_tag={self.require_physical_tag})'
|
|
83
83
|
)
|
|
84
84
|
|
|
85
|
-
def _json_dict_(self) ->
|
|
85
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
86
86
|
return {
|
|
87
87
|
'ops_added': list(self.ops_added.items()),
|
|
88
88
|
'prepend': self.prepend,
|
|
@@ -12,12 +12,14 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
15
17
|
import cirq
|
|
16
18
|
from cirq.devices.insertion_noise_model import InsertionNoiseModel
|
|
17
19
|
from cirq.devices.noise_utils import OpIdentifier, PHYSICAL_GATE_TAG
|
|
18
20
|
|
|
19
21
|
|
|
20
|
-
def test_insertion_noise():
|
|
22
|
+
def test_insertion_noise() -> None:
|
|
21
23
|
q0, q1 = cirq.LineQubit.range(2)
|
|
22
24
|
op_id0 = OpIdentifier(cirq.XPowGate, q0)
|
|
23
25
|
op_id1 = OpIdentifier(cirq.ZPowGate, q1)
|
|
@@ -50,7 +52,7 @@ def test_insertion_noise():
|
|
|
50
52
|
cirq.testing.assert_equivalent_repr(model)
|
|
51
53
|
|
|
52
54
|
|
|
53
|
-
def test_colliding_noise_qubits():
|
|
55
|
+
def test_colliding_noise_qubits() -> None:
|
|
54
56
|
# Check that noise affecting other qubits doesn't cause issues.
|
|
55
57
|
q0, q1, q2, q3 = cirq.LineQubit.range(4)
|
|
56
58
|
op_id0 = OpIdentifier(cirq.CZPowGate)
|
|
@@ -66,7 +68,7 @@ def test_colliding_noise_qubits():
|
|
|
66
68
|
cirq.testing.assert_equivalent_repr(model)
|
|
67
69
|
|
|
68
70
|
|
|
69
|
-
def test_prepend():
|
|
71
|
+
def test_prepend() -> None:
|
|
70
72
|
q0, q1 = cirq.LineQubit.range(2)
|
|
71
73
|
op_id0 = OpIdentifier(cirq.XPowGate, q0)
|
|
72
74
|
op_id1 = OpIdentifier(cirq.ZPowGate, q1)
|
|
@@ -81,7 +83,7 @@ def test_prepend():
|
|
|
81
83
|
]
|
|
82
84
|
|
|
83
85
|
|
|
84
|
-
def test_require_physical_tag():
|
|
86
|
+
def test_require_physical_tag() -> None:
|
|
85
87
|
q0, q1 = cirq.LineQubit.range(2)
|
|
86
88
|
op_id0 = OpIdentifier(cirq.XPowGate, q0)
|
|
87
89
|
op_id1 = OpIdentifier(cirq.ZPowGate, q1)
|
|
@@ -95,7 +97,7 @@ def test_require_physical_tag():
|
|
|
95
97
|
]
|
|
96
98
|
|
|
97
99
|
|
|
98
|
-
def test_supertype_matching():
|
|
100
|
+
def test_supertype_matching() -> None:
|
|
99
101
|
# Demonstrate that the model applies the closest matching type
|
|
100
102
|
# if multiple types match a given gate.
|
|
101
103
|
q0 = cirq.LineQubit(0)
|
cirq/devices/line_qubit.py
CHANGED
|
@@ -17,7 +17,7 @@ from __future__ import annotations
|
|
|
17
17
|
import abc
|
|
18
18
|
import functools
|
|
19
19
|
import weakref
|
|
20
|
-
from typing import Any,
|
|
20
|
+
from typing import Any, Iterable, Sequence, TYPE_CHECKING
|
|
21
21
|
|
|
22
22
|
from typing_extensions import Self
|
|
23
23
|
|
|
@@ -108,7 +108,7 @@ class _BaseLineQid(ops.Qid):
|
|
|
108
108
|
"""
|
|
109
109
|
return isinstance(other, _BaseLineQid) and abs(self._x - other._x) == 1
|
|
110
110
|
|
|
111
|
-
def neighbors(self, qids:
|
|
111
|
+
def neighbors(self, qids: Iterable[ops.Qid] | None = None) -> set[_BaseLineQid]:
|
|
112
112
|
"""Returns qubits that are potential neighbors to this LineQubit
|
|
113
113
|
|
|
114
114
|
Args:
|
|
@@ -120,7 +120,7 @@ class _BaseLineQid(ops.Qid):
|
|
|
120
120
|
def _with_x(self, x: int) -> Self:
|
|
121
121
|
"""Returns a qubit with the same type but a different value of `x`."""
|
|
122
122
|
|
|
123
|
-
def __add__(self, other:
|
|
123
|
+
def __add__(self, other: int | Self) -> Self:
|
|
124
124
|
if isinstance(other, _BaseLineQid):
|
|
125
125
|
if self._dimension != other._dimension:
|
|
126
126
|
raise TypeError(
|
|
@@ -132,7 +132,7 @@ class _BaseLineQid(ops.Qid):
|
|
|
132
132
|
raise TypeError(f"Can only add ints and {type(self).__name__}. Instead was {other}")
|
|
133
133
|
return self._with_x(self._x + other)
|
|
134
134
|
|
|
135
|
-
def __sub__(self, other:
|
|
135
|
+
def __sub__(self, other: int | Self) -> Self:
|
|
136
136
|
if isinstance(other, _BaseLineQid):
|
|
137
137
|
if self._dimension != other._dimension:
|
|
138
138
|
raise TypeError(
|
|
@@ -184,7 +184,7 @@ class LineQid(_BaseLineQid):
|
|
|
184
184
|
|
|
185
185
|
# Cache of existing LineQid instances, returned by __new__ if available.
|
|
186
186
|
# Holds weak references so instances can still be garbage collected.
|
|
187
|
-
_cache = weakref.WeakValueDictionary[
|
|
187
|
+
_cache = weakref.WeakValueDictionary[tuple[int, int], 'cirq.LineQid']()
|
|
188
188
|
|
|
189
189
|
def __new__(cls, x: int, dimension: int) -> cirq.LineQid:
|
|
190
190
|
"""Initializes a line qid at the given x coordinate.
|
|
@@ -211,14 +211,14 @@ class LineQid(_BaseLineQid):
|
|
|
211
211
|
return (self._x, self._dimension)
|
|
212
212
|
|
|
213
213
|
# avoid pickling the _hash value, attributes are already stored with __getnewargs__
|
|
214
|
-
def __getstate__(self) ->
|
|
214
|
+
def __getstate__(self) -> dict[str, Any]:
|
|
215
215
|
return {}
|
|
216
216
|
|
|
217
217
|
def _with_x(self, x: int) -> LineQid:
|
|
218
218
|
return LineQid(x, dimension=self._dimension)
|
|
219
219
|
|
|
220
220
|
@staticmethod
|
|
221
|
-
def range(*range_args, dimension: int) ->
|
|
221
|
+
def range(*range_args, dimension: int) -> list[LineQid]:
|
|
222
222
|
"""Returns a range of line qids.
|
|
223
223
|
|
|
224
224
|
Args:
|
|
@@ -232,7 +232,7 @@ class LineQid(_BaseLineQid):
|
|
|
232
232
|
return [LineQid(i, dimension=dimension) for i in range(*range_args)]
|
|
233
233
|
|
|
234
234
|
@staticmethod
|
|
235
|
-
def for_qid_shape(qid_shape: Sequence[int], start: int = 0, step: int = 1) ->
|
|
235
|
+
def for_qid_shape(qid_shape: Sequence[int], start: int = 0, step: int = 1) -> list[LineQid]:
|
|
236
236
|
"""Returns a range of line qids for each entry in `qid_shape` with
|
|
237
237
|
matching dimension.
|
|
238
238
|
|
|
@@ -246,7 +246,7 @@ class LineQid(_BaseLineQid):
|
|
|
246
246
|
]
|
|
247
247
|
|
|
248
248
|
@staticmethod
|
|
249
|
-
def for_gate(val: Any, start: int = 0, step: int = 1) ->
|
|
249
|
+
def for_gate(val: Any, start: int = 0, step: int = 1) -> list[LineQid]:
|
|
250
250
|
"""Returns a range of line qids with the same qid shape as the gate.
|
|
251
251
|
|
|
252
252
|
Args:
|
|
@@ -269,7 +269,7 @@ class LineQid(_BaseLineQid):
|
|
|
269
269
|
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
270
270
|
return protocols.CircuitDiagramInfo(wire_symbols=(f"{self._x} (d={self._dimension})",))
|
|
271
271
|
|
|
272
|
-
def _json_dict_(self) ->
|
|
272
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
273
273
|
return protocols.obj_to_dict_helper(self, ['x', 'dimension'])
|
|
274
274
|
|
|
275
275
|
|
|
@@ -315,14 +315,14 @@ class LineQubit(_BaseLineQid):
|
|
|
315
315
|
return (self._x,)
|
|
316
316
|
|
|
317
317
|
# avoid pickling the _hash value, attributes are already stored with __getnewargs__
|
|
318
|
-
def __getstate__(self) ->
|
|
318
|
+
def __getstate__(self) -> dict[str, Any]:
|
|
319
319
|
return {}
|
|
320
320
|
|
|
321
321
|
def _with_x(self, x: int) -> LineQubit:
|
|
322
322
|
return LineQubit(x)
|
|
323
323
|
|
|
324
324
|
@staticmethod
|
|
325
|
-
def range(*range_args) ->
|
|
325
|
+
def range(*range_args) -> list[LineQubit]:
|
|
326
326
|
"""Returns a range of line qubits.
|
|
327
327
|
|
|
328
328
|
Args:
|
|
@@ -342,5 +342,5 @@ class LineQubit(_BaseLineQid):
|
|
|
342
342
|
def _circuit_diagram_info_(self, args: cirq.CircuitDiagramInfoArgs) -> cirq.CircuitDiagramInfo:
|
|
343
343
|
return protocols.CircuitDiagramInfo(wire_symbols=(f"{self._x}",))
|
|
344
344
|
|
|
345
|
-
def _json_dict_(self) ->
|
|
345
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
346
346
|
return protocols.obj_to_dict_helper(self, ['x'])
|
cirq/devices/line_qubit_test.py
CHANGED
cirq/devices/named_topologies.py
CHANGED
|
@@ -17,18 +17,7 @@ from __future__ import annotations
|
|
|
17
17
|
import abc
|
|
18
18
|
import warnings
|
|
19
19
|
from dataclasses import dataclass
|
|
20
|
-
from typing import
|
|
21
|
-
Any,
|
|
22
|
-
Callable,
|
|
23
|
-
Dict,
|
|
24
|
-
Iterable,
|
|
25
|
-
List,
|
|
26
|
-
Optional,
|
|
27
|
-
Sequence,
|
|
28
|
-
Tuple,
|
|
29
|
-
TYPE_CHECKING,
|
|
30
|
-
Union,
|
|
31
|
-
)
|
|
20
|
+
from typing import Any, Callable, Iterable, Sequence, TYPE_CHECKING, Union
|
|
32
21
|
|
|
33
22
|
import networkx as nx
|
|
34
23
|
from matplotlib import pyplot as plt
|
|
@@ -59,12 +48,12 @@ class NamedTopology(metaclass=abc.ABCMeta):
|
|
|
59
48
|
"""A networkx graph representation of the topology."""
|
|
60
49
|
|
|
61
50
|
|
|
62
|
-
_GRIDLIKE_NODE = Union['cirq.GridQubit',
|
|
51
|
+
_GRIDLIKE_NODE = Union['cirq.GridQubit', tuple[int, int]]
|
|
63
52
|
|
|
64
53
|
|
|
65
54
|
def _node_and_coordinates(
|
|
66
55
|
nodes: Iterable[_GRIDLIKE_NODE],
|
|
67
|
-
) -> Iterable[
|
|
56
|
+
) -> Iterable[tuple[_GRIDLIKE_NODE, tuple[int, int]]]:
|
|
68
57
|
"""Yield tuples whose first element is the input node and the second is guaranteed to be a tuple
|
|
69
58
|
of two integers. The input node can be a tuple of ints or a GridQubit."""
|
|
70
59
|
for node in nodes:
|
|
@@ -76,8 +65,8 @@ def _node_and_coordinates(
|
|
|
76
65
|
|
|
77
66
|
|
|
78
67
|
def draw_gridlike(
|
|
79
|
-
graph: nx.Graph, ax:
|
|
80
|
-
) ->
|
|
68
|
+
graph: nx.Graph, ax: plt.Axes | None = None, tilted: bool = True, **kwargs
|
|
69
|
+
) -> dict[Any, tuple[int, int]]:
|
|
81
70
|
"""Draw a grid-like graph using Matplotlib.
|
|
82
71
|
|
|
83
72
|
This wraps nx.draw_networkx to produce a matplotlib drawing of the graph. Nodes
|
|
@@ -129,11 +118,11 @@ class LineTopology(NamedTopology):
|
|
|
129
118
|
)
|
|
130
119
|
object.__setattr__(self, 'graph', graph)
|
|
131
120
|
|
|
132
|
-
def nodes_as_linequbits(self) ->
|
|
121
|
+
def nodes_as_linequbits(self) -> list[cirq.LineQubit]:
|
|
133
122
|
"""Get the graph nodes as cirq.LineQubit"""
|
|
134
123
|
return [LineQubit(x) for x in sorted(self.graph.nodes)]
|
|
135
124
|
|
|
136
|
-
def draw(self, ax=None, tilted: bool = True, **kwargs) ->
|
|
125
|
+
def draw(self, ax=None, tilted: bool = True, **kwargs) -> dict[Any, tuple[int, int]]:
|
|
137
126
|
"""Draw this graph using Matplotlib.
|
|
138
127
|
|
|
139
128
|
Args:
|
|
@@ -144,7 +133,7 @@ class LineTopology(NamedTopology):
|
|
|
144
133
|
g2 = nx.relabel_nodes(self.graph, {n: (n, 1) for n in self.graph.nodes})
|
|
145
134
|
return draw_gridlike(g2, ax=ax, tilted=tilted, **kwargs)
|
|
146
135
|
|
|
147
|
-
def nodes_to_linequbits(self, offset: int = 0) ->
|
|
136
|
+
def nodes_to_linequbits(self, offset: int = 0) -> dict[int, cirq.LineQubit]:
|
|
148
137
|
"""Return a mapping from graph nodes to `cirq.LineQubit`
|
|
149
138
|
|
|
150
139
|
Args:
|
|
@@ -152,7 +141,7 @@ class LineTopology(NamedTopology):
|
|
|
152
141
|
"""
|
|
153
142
|
return dict(enumerate(LineQubit.range(offset, offset + self.n_nodes)))
|
|
154
143
|
|
|
155
|
-
def _json_dict_(self) ->
|
|
144
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
156
145
|
return dataclass_json_dict(self)
|
|
157
146
|
|
|
158
147
|
def __repr__(self) -> str:
|
|
@@ -242,11 +231,11 @@ class TiltedSquareLattice(NamedTopology):
|
|
|
242
231
|
"""
|
|
243
232
|
return draw_gridlike(self.graph, ax=ax, tilted=tilted, **kwargs)
|
|
244
233
|
|
|
245
|
-
def nodes_as_gridqubits(self) ->
|
|
234
|
+
def nodes_as_gridqubits(self) -> list[cirq.GridQubit]:
|
|
246
235
|
"""Get the graph nodes as cirq.GridQubit"""
|
|
247
236
|
return [GridQubit(r, c) for r, c in sorted(self.graph.nodes)]
|
|
248
237
|
|
|
249
|
-
def nodes_to_gridqubits(self, offset=(0, 0)) ->
|
|
238
|
+
def nodes_to_gridqubits(self, offset=(0, 0)) -> dict[tuple[int, int], cirq.GridQubit]:
|
|
250
239
|
"""Return a mapping from graph nodes to `cirq.GridQubit`
|
|
251
240
|
|
|
252
241
|
Args:
|
|
@@ -255,7 +244,7 @@ class TiltedSquareLattice(NamedTopology):
|
|
|
255
244
|
"""
|
|
256
245
|
return {(r, c): GridQubit(r, c) + offset for r, c in self.graph.nodes}
|
|
257
246
|
|
|
258
|
-
def _json_dict_(self) ->
|
|
247
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
259
248
|
return dataclass_json_dict(self)
|
|
260
249
|
|
|
261
250
|
def __repr__(self) -> str:
|
|
@@ -264,7 +253,7 @@ class TiltedSquareLattice(NamedTopology):
|
|
|
264
253
|
|
|
265
254
|
def get_placements(
|
|
266
255
|
big_graph: nx.Graph, small_graph: nx.Graph, max_placements=100_000
|
|
267
|
-
) ->
|
|
256
|
+
) -> list[dict]:
|
|
268
257
|
"""Get 'placements' mapping small_graph nodes onto those of `big_graph`.
|
|
269
258
|
|
|
270
259
|
This function considers monomorphisms with a restriction: we restrict only to unique set
|
|
@@ -311,7 +300,7 @@ def get_placements(
|
|
|
311
300
|
|
|
312
301
|
|
|
313
302
|
def _is_valid_placement_helper(
|
|
314
|
-
big_graph: nx.Graph, small_mapped: nx.Graph, small_to_big_mapping:
|
|
303
|
+
big_graph: nx.Graph, small_mapped: nx.Graph, small_to_big_mapping: dict
|
|
315
304
|
):
|
|
316
305
|
"""Helper function for `is_valid_placement` that assumes the mapping of `small_graph` has
|
|
317
306
|
already occurred.
|
|
@@ -322,7 +311,7 @@ def _is_valid_placement_helper(
|
|
|
322
311
|
return (subgraph.nodes == small_mapped.nodes) and (subgraph.edges == small_mapped.edges)
|
|
323
312
|
|
|
324
313
|
|
|
325
|
-
def is_valid_placement(big_graph: nx.Graph, small_graph: nx.Graph, small_to_big_mapping:
|
|
314
|
+
def is_valid_placement(big_graph: nx.Graph, small_graph: nx.Graph, small_to_big_mapping: dict):
|
|
326
315
|
"""Return whether the given placement is a valid placement of small_graph onto big_graph.
|
|
327
316
|
|
|
328
317
|
This is done by making sure all the nodes and edges on the mapped version of `small_graph`
|
|
@@ -344,11 +333,11 @@ def is_valid_placement(big_graph: nx.Graph, small_graph: nx.Graph, small_to_big_
|
|
|
344
333
|
def draw_placements(
|
|
345
334
|
big_graph: nx.Graph,
|
|
346
335
|
small_graph: nx.Graph,
|
|
347
|
-
small_to_big_mappings: Sequence[
|
|
336
|
+
small_to_big_mappings: Sequence[dict],
|
|
348
337
|
max_plots: int = 20,
|
|
349
|
-
axes:
|
|
338
|
+
axes: Sequence[plt.Axes] | None = None,
|
|
350
339
|
tilted: bool = True,
|
|
351
|
-
bad_placement_callback:
|
|
340
|
+
bad_placement_callback: Callable[[plt.Axes, int], None] | None = None,
|
|
352
341
|
):
|
|
353
342
|
"""Draw a visualization of placements from small_graph onto big_graph using Matplotlib.
|
|
354
343
|
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
14
17
|
import itertools
|
|
15
18
|
from unittest.mock import MagicMock
|
|
16
19
|
|
|
@@ -29,7 +32,7 @@ from cirq import (
|
|
|
29
32
|
|
|
30
33
|
|
|
31
34
|
@pytest.mark.parametrize('width, height', list(itertools.product([1, 2, 3, 24], repeat=2)))
|
|
32
|
-
def test_tilted_square_lattice(width, height):
|
|
35
|
+
def test_tilted_square_lattice(width, height) -> None:
|
|
33
36
|
topo = TiltedSquareLattice(width, height)
|
|
34
37
|
assert topo.graph.number_of_edges() == width * height
|
|
35
38
|
assert all(1 <= topo.graph.degree[node] <= 4 for node in topo.graph.nodes)
|
|
@@ -41,14 +44,14 @@ def test_tilted_square_lattice(width, height):
|
|
|
41
44
|
cirq.testing.assert_equivalent_repr(topo)
|
|
42
45
|
|
|
43
46
|
|
|
44
|
-
def test_bad_tilted_square_lattice():
|
|
47
|
+
def test_bad_tilted_square_lattice() -> None:
|
|
45
48
|
with pytest.raises(ValueError):
|
|
46
49
|
_ = TiltedSquareLattice(0, 3)
|
|
47
50
|
with pytest.raises(ValueError):
|
|
48
51
|
_ = TiltedSquareLattice(3, 0)
|
|
49
52
|
|
|
50
53
|
|
|
51
|
-
def test_tilted_square_methods():
|
|
54
|
+
def test_tilted_square_methods() -> None:
|
|
52
55
|
topo = TiltedSquareLattice(5, 5)
|
|
53
56
|
ax = MagicMock()
|
|
54
57
|
topo.draw(ax=ax)
|
|
@@ -63,13 +66,13 @@ def test_tilted_square_methods():
|
|
|
63
66
|
)
|
|
64
67
|
|
|
65
68
|
|
|
66
|
-
def test_tilted_square_lattice_n_nodes():
|
|
69
|
+
def test_tilted_square_lattice_n_nodes() -> None:
|
|
67
70
|
for width, height in itertools.product(list(range(1, 4 + 1)), repeat=2):
|
|
68
71
|
topo = TiltedSquareLattice(width, height)
|
|
69
72
|
assert topo.n_nodes == topo.graph.number_of_nodes()
|
|
70
73
|
|
|
71
74
|
|
|
72
|
-
def test_line_topology():
|
|
75
|
+
def test_line_topology() -> None:
|
|
73
76
|
n = 10
|
|
74
77
|
topo = LineTopology(n)
|
|
75
78
|
assert topo.n_nodes == n
|
|
@@ -94,13 +97,13 @@ def test_line_topology():
|
|
|
94
97
|
cirq.testing.assert_equivalent_repr(topo)
|
|
95
98
|
|
|
96
99
|
|
|
97
|
-
def test_line_topology_nodes_as_qubits():
|
|
100
|
+
def test_line_topology_nodes_as_qubits() -> None:
|
|
98
101
|
for n in range(2, 10, 2):
|
|
99
102
|
assert LineTopology(n).nodes_as_linequbits() == cirq.LineQubit.range(n)
|
|
100
103
|
|
|
101
104
|
|
|
102
105
|
@pytest.mark.parametrize('tilted', [True, False])
|
|
103
|
-
def test_draw_gridlike(tilted):
|
|
106
|
+
def test_draw_gridlike(tilted) -> None:
|
|
104
107
|
graph = nx.grid_2d_graph(3, 3)
|
|
105
108
|
ax = MagicMock()
|
|
106
109
|
pos = draw_gridlike(graph, tilted=tilted, ax=ax)
|
|
@@ -111,7 +114,7 @@ def test_draw_gridlike(tilted):
|
|
|
111
114
|
|
|
112
115
|
|
|
113
116
|
@pytest.mark.parametrize('tilted', [True, False])
|
|
114
|
-
def test_draw_gridlike_qubits(tilted):
|
|
117
|
+
def test_draw_gridlike_qubits(tilted) -> None:
|
|
115
118
|
graph = nx.grid_2d_graph(3, 3)
|
|
116
119
|
graph = nx.relabel_nodes(graph, {(r, c): cirq.GridQubit(r, c) for r, c in sorted(graph.nodes)})
|
|
117
120
|
ax = MagicMock()
|
|
@@ -122,7 +125,7 @@ def test_draw_gridlike_qubits(tilted):
|
|
|
122
125
|
assert 0 <= q.col < 3
|
|
123
126
|
|
|
124
127
|
|
|
125
|
-
def test_get_placements():
|
|
128
|
+
def test_get_placements() -> None:
|
|
126
129
|
topo = TiltedSquareLattice(4, 2)
|
|
127
130
|
syc23 = TiltedSquareLattice(8, 4).graph
|
|
128
131
|
placements = get_placements(syc23, topo.graph)
|
|
@@ -134,7 +137,7 @@ def test_get_placements():
|
|
|
134
137
|
ax.scatter.assert_called()
|
|
135
138
|
|
|
136
139
|
|
|
137
|
-
def test_is_valid_placement():
|
|
140
|
+
def test_is_valid_placement() -> None:
|
|
138
141
|
topo = TiltedSquareLattice(4, 2)
|
|
139
142
|
syc23 = TiltedSquareLattice(8, 4).graph
|
|
140
143
|
placements = get_placements(syc23, topo.graph)
|
cirq/devices/noise_model.py
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import Any, Callable,
|
|
17
|
+
from typing import Any, Callable, Iterable, Sequence, TYPE_CHECKING, Union
|
|
18
18
|
|
|
19
19
|
from cirq import ops, protocols, value
|
|
20
20
|
from cirq._doc import document
|
|
@@ -196,7 +196,7 @@ class _NoNoiseModel(NoiseModel):
|
|
|
196
196
|
def __repr__(self) -> str:
|
|
197
197
|
return 'cirq.NO_NOISE'
|
|
198
198
|
|
|
199
|
-
def _json_dict_(self) ->
|
|
199
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
200
200
|
return protocols.obj_to_dict_helper(self, [])
|
|
201
201
|
|
|
202
202
|
def _has_unitary_(self) -> bool:
|
|
@@ -247,7 +247,7 @@ class ConstantQubitNoiseModel(NoiseModel):
|
|
|
247
247
|
]
|
|
248
248
|
return output[::-1] if self._prepend else output
|
|
249
249
|
|
|
250
|
-
def _json_dict_(self) ->
|
|
250
|
+
def _json_dict_(self) -> dict[str, Any]:
|
|
251
251
|
return protocols.obj_to_dict_helper(self, ['qubit_noise_gate'])
|
|
252
252
|
|
|
253
253
|
def _has_unitary_(self) -> bool:
|