cirq-core 1.4.0.dev20240529225110__py3-none-any.whl → 1.5.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 +587 -569
- cirq/_compat.py +9 -0
- cirq/_compat_test.py +11 -9
- cirq/_import.py +7 -8
- cirq/_version.py +31 -1
- cirq/_version_test.py +1 -1
- cirq/circuits/__init__.py +15 -9
- cirq/circuits/_block_diagram_drawer.py +1 -2
- cirq/circuits/_block_diagram_drawer_test.py +3 -3
- cirq/circuits/_box_drawing_character_data.py +0 -1
- cirq/circuits/_box_drawing_character_data_test.py +2 -2
- cirq/circuits/_bucket_priority_queue.py +0 -1
- cirq/circuits/_bucket_priority_queue_test.py +1 -1
- cirq/circuits/circuit.py +336 -234
- cirq/circuits/circuit_operation.py +102 -52
- cirq/circuits/circuit_operation_test.py +85 -4
- cirq/circuits/circuit_test.py +101 -32
- cirq/circuits/frozen_circuit.py +36 -32
- cirq/circuits/insert_strategy.py +10 -0
- cirq/circuits/insert_strategy_test.py +20 -0
- cirq/circuits/moment.py +79 -80
- cirq/circuits/moment_test.py +105 -2
- cirq/circuits/optimization_pass.py +15 -15
- cirq/circuits/optimization_pass_test.py +8 -9
- cirq/circuits/qasm_output.py +64 -33
- cirq/circuits/qasm_output_test.py +63 -2
- cirq/circuits/text_diagram_drawer.py +26 -56
- cirq/circuits/text_diagram_drawer_test.py +5 -4
- cirq/contrib/__init__.py +2 -2
- cirq/contrib/acquaintance/__init__.py +44 -29
- cirq/contrib/acquaintance/bipartite.py +8 -7
- cirq/contrib/acquaintance/bipartite_test.py +11 -1
- cirq/contrib/acquaintance/devices.py +5 -4
- cirq/contrib/acquaintance/devices_test.py +5 -1
- cirq/contrib/acquaintance/executor.py +18 -21
- cirq/contrib/acquaintance/executor_test.py +3 -2
- cirq/contrib/acquaintance/gates.py +36 -27
- cirq/contrib/acquaintance/gates_test.py +1 -1
- cirq/contrib/acquaintance/inspection_utils.py +10 -9
- cirq/contrib/acquaintance/inspection_utils_test.py +6 -1
- cirq/contrib/acquaintance/mutation_utils.py +10 -10
- cirq/contrib/acquaintance/optimizers.py +7 -6
- cirq/contrib/acquaintance/optimizers_test.py +1 -1
- cirq/contrib/acquaintance/permutation.py +22 -21
- cirq/contrib/acquaintance/permutation_test.py +1 -1
- cirq/contrib/acquaintance/shift.py +8 -6
- cirq/contrib/acquaintance/shift_swap_network.py +6 -4
- cirq/contrib/acquaintance/strategies/__init__.py +9 -3
- cirq/contrib/acquaintance/strategies/complete.py +4 -3
- cirq/contrib/acquaintance/strategies/cubic.py +5 -3
- cirq/contrib/acquaintance/strategies/quartic_paired.py +8 -6
- cirq/contrib/acquaintance/topological_sort.py +4 -2
- cirq/contrib/bayesian_network/__init__.py +3 -1
- cirq/contrib/bayesian_network/bayesian_network_gate.py +5 -3
- cirq/contrib/circuitdag/__init__.py +1 -1
- cirq/contrib/circuitdag/circuit_dag.py +24 -24
- cirq/contrib/circuitdag/circuit_dag_test.py +1 -1
- cirq/contrib/custom_simulators/custom_state_simulator.py +10 -8
- cirq/contrib/custom_simulators/custom_state_simulator_test.py +15 -11
- cirq/contrib/graph_device/__init__.py +8 -8
- cirq/contrib/graph_device/graph_device.py +8 -8
- cirq/contrib/graph_device/graph_device_test.py +0 -1
- cirq/contrib/graph_device/hypergraph_test.py +1 -0
- cirq/contrib/json.py +1 -2
- cirq/contrib/json_test.py +2 -2
- cirq/contrib/noise_models/__init__.py +5 -6
- cirq/contrib/noise_models/noise_models.py +8 -6
- cirq/contrib/paulistring/__init__.py +22 -10
- cirq/contrib/paulistring/clifford_optimize.py +1 -1
- cirq/contrib/paulistring/clifford_optimize_test.py +0 -1
- cirq/contrib/paulistring/clifford_target_gateset.py +15 -12
- cirq/contrib/paulistring/optimize.py +2 -2
- cirq/contrib/paulistring/optimize_test.py +0 -1
- cirq/contrib/paulistring/pauli_string_dag_test.py +0 -1
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation.py +379 -0
- cirq/contrib/paulistring/pauli_string_measurement_with_readout_mitigation_test.py +523 -0
- cirq/contrib/paulistring/pauli_string_optimize.py +3 -1
- cirq/contrib/paulistring/pauli_string_optimize_test.py +1 -3
- cirq/contrib/paulistring/recombine.py +2 -2
- cirq/contrib/paulistring/recombine_test.py +2 -2
- cirq/contrib/paulistring/separate.py +3 -4
- cirq/contrib/qasm_import/__init__.py +2 -2
- cirq/contrib/qasm_import/_lexer.py +21 -26
- cirq/contrib/qasm_import/_lexer_test.py +90 -6
- cirq/contrib/qasm_import/_parser.py +238 -47
- cirq/contrib/qasm_import/_parser_test.py +514 -59
- cirq/contrib/qasm_import/qasm_test.py +1 -1
- cirq/contrib/qcircuit/__init__.py +6 -4
- cirq/contrib/qcircuit/qcircuit_diagram.py +5 -2
- cirq/contrib/qcircuit/qcircuit_pdf.py +1 -2
- cirq/{experiments/grid_parallel_two_qubit_xeb_test.py → contrib/qcircuit/qcircuit_pdf_test.py} +13 -12
- cirq/contrib/qcircuit/qcircuit_test.py +1 -1
- cirq/contrib/quantum_volume/__init__.py +7 -7
- cirq/contrib/quantum_volume/quantum_volume.py +6 -11
- cirq/contrib/quantum_volume/quantum_volume_test.py +3 -1
- cirq/contrib/quimb/__init__.py +16 -13
- cirq/contrib/quimb/density_matrix.py +1 -1
- cirq/contrib/quimb/mps_simulator.py +27 -28
- cirq/contrib/quimb/mps_simulator_test.py +5 -0
- cirq/contrib/quimb/state_vector.py +3 -10
- cirq/contrib/quirk/__init__.py +1 -1
- cirq/contrib/quirk/export_to_quirk.py +3 -3
- cirq/contrib/routing/__init__.py +12 -9
- cirq/contrib/routing/device.py +1 -1
- cirq/contrib/routing/device_test.py +1 -2
- cirq/contrib/routing/greedy.py +7 -5
- cirq/contrib/routing/greedy_test.py +5 -3
- cirq/contrib/routing/initialization.py +3 -1
- cirq/contrib/routing/initialization_test.py +1 -1
- cirq/contrib/routing/swap_network.py +6 -6
- cirq/contrib/routing/utils.py +6 -4
- cirq/contrib/routing/utils_test.py +1 -2
- cirq/{type_workarounds.py → contrib/shuffle_circuits/__init__.py} +5 -10
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking.py +250 -0
- cirq/contrib/shuffle_circuits/shuffle_circuits_with_readout_benchmarking_test.py +363 -0
- cirq/contrib/svg/__init__.py +1 -1
- cirq/contrib/svg/svg.py +12 -10
- cirq/contrib/svg/svg_test.py +3 -2
- cirq/devices/__init__.py +34 -25
- cirq/devices/device.py +16 -12
- cirq/devices/device_test.py +1 -0
- cirq/devices/grid_device_metadata.py +16 -12
- cirq/devices/grid_device_metadata_test.py +2 -1
- cirq/devices/grid_qubit.py +31 -26
- cirq/devices/grid_qubit_test.py +30 -1
- cirq/devices/insertion_noise_model.py +6 -6
- cirq/devices/insertion_noise_model_test.py +1 -1
- cirq/devices/line_qubit.py +28 -20
- cirq/devices/line_qubit_test.py +26 -0
- cirq/devices/named_topologies.py +12 -10
- cirq/devices/named_topologies_test.py +5 -4
- cirq/devices/noise_model.py +29 -33
- cirq/devices/noise_properties.py +2 -2
- cirq/devices/noise_properties_test.py +2 -2
- cirq/devices/noise_utils.py +3 -3
- cirq/devices/superconducting_qubits_noise_properties.py +2 -2
- cirq/devices/superconducting_qubits_noise_properties_test.py +3 -3
- cirq/devices/thermal_noise_model.py +2 -1
- cirq/devices/unconstrained_device.py +1 -1
- cirq/devices/unconstrained_device_test.py +6 -0
- cirq/experiments/__init__.py +51 -34
- cirq/experiments/qubit_characterizations.py +17 -15
- cirq/experiments/qubit_characterizations_test.py +4 -6
- cirq/experiments/random_quantum_circuit_generation.py +10 -9
- cirq/experiments/random_quantum_circuit_generation_test.py +21 -4
- cirq/experiments/readout_confusion_matrix.py +73 -8
- cirq/experiments/readout_confusion_matrix_test.py +104 -1
- cirq/experiments/single_qubit_readout_calibration.py +8 -6
- cirq/experiments/single_qubit_readout_calibration_test.py +1 -1
- cirq/experiments/t1_decay_experiment.py +4 -5
- cirq/experiments/t1_decay_experiment_test.py +1 -2
- cirq/experiments/t2_decay_experiment.py +0 -1
- cirq/experiments/t2_decay_experiment_test.py +1 -2
- cirq/experiments/two_qubit_xeb.py +157 -33
- cirq/experiments/two_qubit_xeb_test.py +38 -22
- cirq/experiments/xeb_fitting.py +99 -19
- cirq/experiments/xeb_fitting_test.py +64 -25
- cirq/experiments/xeb_sampling.py +14 -18
- cirq/experiments/xeb_simulation.py +4 -3
- cirq/experiments/xeb_simulation_test.py +20 -14
- cirq/experiments/z_phase_calibration.py +368 -0
- cirq/experiments/z_phase_calibration_test.py +241 -0
- cirq/interop/__init__.py +4 -1
- cirq/interop/quirk/__init__.py +7 -4
- cirq/interop/quirk/cells/__init__.py +17 -6
- cirq/interop/quirk/cells/arithmetic_cells.py +8 -8
- cirq/interop/quirk/cells/arithmetic_cells_test.py +1 -1
- cirq/interop/quirk/cells/cell.py +6 -6
- cirq/interop/quirk/cells/composite_cell.py +5 -5
- cirq/interop/quirk/cells/composite_cell_test.py +1 -1
- cirq/interop/quirk/cells/control_cells.py +1 -1
- cirq/interop/quirk/cells/frequency_space_cells.py +2 -2
- cirq/interop/quirk/cells/ignored_cells.py +1 -1
- cirq/interop/quirk/cells/input_cells.py +1 -1
- cirq/interop/quirk/cells/input_cells_test.py +1 -1
- cirq/interop/quirk/cells/input_rotation_cells.py +1 -1
- cirq/interop/quirk/cells/input_rotation_cells_test.py +1 -1
- cirq/interop/quirk/cells/measurement_cells.py +1 -1
- cirq/interop/quirk/cells/parse.py +8 -7
- cirq/interop/quirk/cells/parse_test.py +2 -2
- cirq/interop/quirk/cells/single_qubit_rotation_cells.py +1 -1
- cirq/interop/quirk/cells/swap_cell_test.py +1 -1
- cirq/interop/quirk/cells/unsupported_cells.py +1 -1
- cirq/interop/quirk/url_to_circuit.py +7 -7
- cirq/interop/quirk/url_to_circuit_test.py +1 -1
- cirq/ion/__init__.py +4 -2
- cirq/json_resolver_cache.py +15 -7
- cirq/linalg/__init__.py +62 -51
- cirq/linalg/combinators.py +4 -4
- cirq/linalg/combinators_test.py +4 -1
- cirq/linalg/decompositions.py +15 -40
- cirq/linalg/decompositions_test.py +16 -22
- cirq/linalg/diagonalize.py +1 -1
- cirq/linalg/diagonalize_test.py +1 -1
- cirq/linalg/operator_spaces.py +20 -4
- cirq/linalg/operator_spaces_test.py +15 -2
- cirq/linalg/predicates.py +3 -3
- cirq/linalg/predicates_test.py +1 -0
- cirq/linalg/tolerance.py +2 -2
- cirq/linalg/transformations.py +30 -12
- cirq/linalg/transformations_test.py +13 -0
- cirq/neutral_atoms/__init__.py +2 -2
- cirq/neutral_atoms/convert_to_neutral_atom_gates_test.py +0 -1
- cirq/ops/__init__.py +172 -132
- cirq/ops/arithmetic_operation.py +2 -2
- cirq/ops/arithmetic_operation_test.py +2 -2
- cirq/ops/boolean_hamiltonian.py +3 -2
- cirq/ops/classically_controlled_operation.py +39 -12
- cirq/ops/classically_controlled_operation_test.py +147 -1
- cirq/ops/clifford_gate.py +38 -36
- cirq/ops/clifford_gate_test.py +75 -1
- cirq/ops/common_channels.py +16 -45
- cirq/ops/common_channels_test.py +10 -0
- cirq/ops/common_gate_families.py +1 -1
- cirq/ops/common_gate_families_test.py +1 -0
- cirq/ops/common_gates.py +48 -49
- cirq/ops/common_gates_test.py +18 -2
- cirq/ops/control_values.py +3 -3
- cirq/ops/control_values_test.py +2 -1
- cirq/ops/controlled_gate.py +36 -23
- cirq/ops/controlled_gate_test.py +70 -3
- cirq/ops/controlled_operation.py +6 -5
- cirq/ops/controlled_operation_test.py +7 -3
- cirq/ops/dense_pauli_string.py +11 -11
- cirq/ops/diagonal_gate.py +2 -2
- cirq/ops/diagonal_gate_test.py +1 -0
- cirq/ops/eigen_gate.py +16 -36
- cirq/ops/eigen_gate_test.py +60 -10
- cirq/ops/fourier_transform.py +1 -3
- cirq/ops/fourier_transform_test.py +2 -1
- cirq/ops/fsim_gate.py +42 -3
- cirq/ops/fsim_gate_test.py +21 -0
- cirq/ops/gate_operation.py +8 -8
- cirq/ops/gate_operation_test.py +4 -2
- cirq/ops/gateset_test.py +11 -2
- cirq/ops/global_phase_op.py +8 -7
- cirq/ops/global_phase_op_test.py +1 -1
- cirq/ops/greedy_qubit_manager_test.py +5 -0
- cirq/ops/identity.py +14 -4
- cirq/ops/identity_test.py +24 -0
- cirq/ops/kraus_channel.py +1 -0
- cirq/ops/kraus_channel_test.py +3 -1
- cirq/ops/linear_combinations.py +27 -21
- cirq/ops/linear_combinations_test.py +23 -4
- cirq/ops/matrix_gates.py +24 -8
- cirq/ops/measure_util.py +2 -2
- cirq/ops/measurement_gate.py +7 -4
- cirq/ops/measurement_gate_test.py +2 -1
- cirq/ops/mixed_unitary_channel.py +1 -0
- cirq/ops/mixed_unitary_channel_test.py +3 -1
- cirq/ops/named_qubit.py +8 -1
- cirq/ops/op_tree.py +3 -30
- cirq/ops/op_tree_test.py +4 -0
- cirq/ops/parallel_gate.py +2 -3
- cirq/ops/parallel_gate_test.py +2 -1
- cirq/ops/parity_gates.py +7 -8
- cirq/ops/parity_gates_test.py +1 -0
- cirq/ops/pauli_gates.py +5 -11
- cirq/ops/pauli_gates_test.py +1 -0
- cirq/ops/pauli_interaction_gate.py +11 -5
- cirq/ops/pauli_interaction_gate_test.py +2 -3
- cirq/ops/pauli_measurement_gate.py +6 -5
- cirq/ops/pauli_measurement_gate_test.py +1 -0
- cirq/ops/pauli_string.py +115 -130
- cirq/ops/pauli_string_phasor.py +21 -20
- cirq/ops/pauli_string_phasor_test.py +13 -3
- cirq/ops/pauli_string_raw_types.py +1 -0
- cirq/ops/pauli_string_test.py +192 -55
- cirq/ops/pauli_sum_exponential.py +3 -4
- cirq/ops/pauli_sum_exponential_test.py +0 -1
- cirq/ops/permutation_gate.py +2 -2
- cirq/ops/permutation_gate_test.py +1 -1
- cirq/ops/phased_iswap_gate.py +6 -7
- cirq/ops/phased_iswap_gate_test.py +21 -5
- cirq/ops/phased_x_gate.py +11 -25
- cirq/ops/phased_x_gate_test.py +19 -3
- cirq/ops/phased_x_z_gate.py +12 -11
- cirq/ops/projector.py +4 -5
- cirq/ops/qubit_manager.py +2 -1
- cirq/ops/qubit_manager_test.py +2 -1
- cirq/ops/qubit_order.py +1 -1
- cirq/ops/random_gate_channel.py +1 -1
- cirq/ops/random_gate_channel_test.py +0 -6
- cirq/ops/raw_types.py +146 -50
- cirq/ops/raw_types_test.py +37 -3
- cirq/ops/state_preparation_channel.py +2 -2
- cirq/ops/state_preparation_channel_test.py +2 -1
- cirq/ops/swap_gates.py +9 -4
- cirq/ops/three_qubit_gates.py +8 -8
- cirq/ops/three_qubit_gates_test.py +1 -0
- cirq/ops/two_qubit_diagonal_gate.py +4 -3
- cirq/ops/uniform_superposition_gate.py +4 -4
- cirq/ops/uniform_superposition_gate_test.py +1 -0
- cirq/ops/wait_gate.py +6 -8
- cirq/protocols/__init__.py +135 -83
- cirq/protocols/act_on_protocol.py +1 -1
- cirq/protocols/act_on_protocol_test.py +1 -1
- cirq/protocols/apply_channel_protocol.py +3 -3
- cirq/protocols/apply_mixture_protocol.py +15 -9
- cirq/protocols/apply_mixture_protocol_test.py +11 -0
- cirq/protocols/apply_unitary_protocol.py +2 -2
- cirq/protocols/apply_unitary_protocol_test.py +2 -1
- cirq/protocols/approximate_equality_protocol.py +7 -8
- cirq/protocols/approximate_equality_protocol_test.py +3 -1
- cirq/protocols/circuit_diagram_info_protocol.py +8 -6
- cirq/protocols/circuit_diagram_info_protocol_test.py +5 -0
- cirq/protocols/commutes_protocol.py +6 -6
- cirq/protocols/control_key_protocol.py +1 -1
- cirq/protocols/decompose_protocol.py +4 -5
- cirq/protocols/decompose_protocol_test.py +2 -1
- cirq/protocols/equal_up_to_global_phase_protocol.py +3 -3
- cirq/protocols/equal_up_to_global_phase_protocol_test.py +7 -0
- cirq/protocols/has_stabilizer_effect_protocol.py +5 -5
- cirq/protocols/has_unitary_protocol.py +1 -1
- cirq/protocols/has_unitary_protocol_test.py +8 -7
- cirq/protocols/hash_from_pickle_test.py +120 -0
- cirq/protocols/inverse_protocol.py +1 -1
- cirq/protocols/json_serialization.py +14 -1
- cirq/protocols/json_serialization_test.py +28 -7
- cirq/protocols/json_test_data/BitMaskKeyCondition.json +86 -0
- cirq/protocols/json_test_data/BitMaskKeyCondition.repr +7 -0
- cirq/protocols/json_test_data/Concat.json +19 -0
- cirq/protocols/json_test_data/Concat.repr +1 -0
- cirq/protocols/json_test_data/README.md +4 -2
- cirq/protocols/json_test_data/SympyCondition.json +60 -15
- cirq/protocols/json_test_data/SympyCondition.repr +4 -1
- cirq/protocols/json_test_data/_InverseCompositeGate.json +10 -0
- cirq/protocols/json_test_data/_InverseCompositeGate.repr +1 -0
- cirq/protocols/json_test_data/__init__.py +1 -1
- cirq/protocols/json_test_data/sympy.And.json +13 -0
- cirq/protocols/json_test_data/sympy.And.repr +1 -0
- cirq/protocols/json_test_data/sympy.Indexed.json +18 -0
- cirq/protocols/json_test_data/sympy.Indexed.repr +1 -0
- cirq/protocols/json_test_data/sympy.IndexedBase.json +9 -0
- cirq/protocols/json_test_data/sympy.IndexedBase.repr +1 -0
- cirq/protocols/json_test_data/sympy.Not.json +9 -0
- cirq/protocols/json_test_data/sympy.Not.repr +1 -0
- cirq/protocols/json_test_data/sympy.Or.json +13 -0
- cirq/protocols/json_test_data/sympy.Or.repr +1 -0
- cirq/protocols/json_test_data/sympy.Xor.json +13 -0
- cirq/protocols/json_test_data/sympy.Xor.repr +1 -0
- cirq/protocols/kraus_protocol.py +8 -8
- cirq/protocols/kraus_protocol_test.py +0 -1
- cirq/protocols/measurement_key_protocol.py +1 -1
- cirq/protocols/measurement_key_protocol_test.py +7 -7
- cirq/protocols/mixture_protocol.py +6 -4
- cirq/protocols/mixture_protocol_test.py +21 -13
- cirq/protocols/pauli_expansion_protocol.py +1 -0
- cirq/protocols/pow_protocol.py +1 -1
- cirq/protocols/qasm.py +25 -6
- cirq/protocols/qasm_test.py +17 -0
- cirq/protocols/qid_shape_protocol.py +2 -2
- cirq/protocols/resolve_parameters.py +2 -3
- cirq/protocols/resolve_parameters_test.py +2 -1
- cirq/protocols/trace_distance_bound.py +1 -1
- cirq/protocols/trace_distance_bound_test.py +1 -0
- cirq/protocols/unitary_protocol.py +3 -3
- cirq/protocols/unitary_protocol_test.py +1 -1
- cirq/qis/__init__.py +48 -35
- cirq/qis/channels_test.py +0 -9
- cirq/qis/clifford_tableau.py +46 -26
- cirq/qis/clifford_tableau_test.py +2 -1
- cirq/qis/entropy.py +115 -0
- cirq/qis/entropy_test.py +43 -0
- cirq/qis/measures.py +5 -4
- cirq/qis/measures_test.py +7 -0
- cirq/qis/noise_utils_test.py +4 -4
- cirq/qis/quantum_state_representation.py +1 -1
- cirq/qis/states.py +7 -7
- cirq/sim/__init__.py +55 -37
- cirq/sim/classical_simulator.py +7 -6
- cirq/sim/classical_simulator_test.py +3 -1
- cirq/sim/clifford/__init__.py +17 -9
- cirq/sim/clifford/clifford_simulator.py +5 -4
- cirq/sim/clifford/clifford_simulator_test.py +32 -9
- cirq/sim/clifford/clifford_tableau_simulation_state.py +1 -1
- cirq/sim/clifford/stabilizer_simulation_state.py +1 -1
- cirq/sim/clifford/stabilizer_state_ch_form.py +4 -3
- cirq/sim/density_matrix_simulator.py +3 -2
- cirq/sim/density_matrix_simulator_test.py +12 -4
- cirq/sim/density_matrix_utils.py +1 -1
- cirq/sim/mux.py +2 -2
- cirq/sim/simulation_state.py +4 -5
- cirq/sim/simulation_state_base.py +2 -2
- cirq/sim/simulation_state_test.py +1 -1
- cirq/sim/simulation_utils.py +3 -1
- cirq/sim/simulation_utils_test.py +2 -3
- cirq/sim/simulator.py +7 -6
- cirq/sim/simulator_base.py +5 -5
- cirq/sim/simulator_test.py +14 -3
- cirq/sim/sparse_simulator.py +4 -3
- cirq/sim/sparse_simulator_test.py +17 -9
- cirq/sim/state_vector.py +2 -2
- cirq/sim/state_vector_simulation_state_test.py +1 -1
- cirq/sim/state_vector_simulator.py +4 -4
- cirq/sim/state_vector_test.py +27 -32
- cirq/study/__init__.py +27 -21
- cirq/study/flatten_expressions.py +5 -6
- cirq/study/flatten_expressions_test.py +1 -1
- cirq/study/resolver.py +14 -11
- cirq/study/resolver_test.py +10 -1
- cirq/study/result.py +3 -3
- cirq/study/sweepable.py +15 -9
- cirq/study/sweepable_test.py +27 -0
- cirq/study/sweeps.py +65 -10
- cirq/study/sweeps_test.py +123 -0
- cirq/testing/__init__.py +86 -57
- cirq/testing/_compat_test_data/module_a/__init__.py +2 -2
- cirq/testing/_compat_test_data/module_a/sub/subsub/__init__.py +1 -1
- cirq/testing/circuit_compare.py +3 -4
- cirq/testing/circuit_compare_test.py +7 -8
- cirq/testing/consistent_act_on.py +3 -3
- cirq/testing/consistent_channels_test.py +2 -1
- cirq/testing/consistent_controlled_gate_op.py +3 -2
- cirq/testing/consistent_controlled_gate_op_test.py +2 -3
- cirq/testing/consistent_decomposition.py +1 -1
- cirq/testing/consistent_decomposition_test.py +1 -2
- cirq/testing/consistent_pauli_expansion_test.py +1 -1
- cirq/testing/consistent_phase_by.py +1 -1
- cirq/testing/consistent_phase_by_test.py +1 -2
- cirq/testing/consistent_protocols.py +11 -11
- cirq/testing/consistent_protocols_test.py +4 -5
- cirq/testing/consistent_qasm.py +8 -12
- cirq/testing/consistent_qasm_test.py +1 -1
- cirq/testing/consistent_resolve_parameters.py +2 -1
- cirq/testing/consistent_specified_has_unitary_test.py +1 -1
- cirq/testing/consistent_unitary.py +3 -1
- cirq/testing/consistent_unitary_test.py +3 -3
- cirq/testing/devices.py +1 -1
- cirq/testing/devices_test.py +1 -0
- cirq/testing/equals_tester.py +2 -4
- cirq/testing/equals_tester_test.py +6 -5
- cirq/testing/equivalent_basis_map.py +1 -0
- cirq/testing/equivalent_basis_map_test.py +0 -1
- cirq/testing/gate_features_test.py +5 -0
- cirq/testing/json.py +4 -4
- cirq/testing/lin_alg_utils_test.py +1 -1
- cirq/testing/order_tester.py +1 -1
- cirq/testing/order_tester_test.py +1 -1
- cirq/testing/pytest_utils.py +57 -0
- cirq/testing/pytest_utils_test.py +35 -0
- cirq/testing/random_circuit.py +2 -2
- cirq/testing/random_circuit_test.py +2 -2
- cirq/testing/routing_devices_test.py +2 -1
- cirq/testing/sample_circuits.py +1 -1
- cirq/testing/sample_gates.py +5 -4
- cirq/testing/sample_gates_test.py +2 -2
- cirq/transformers/__init__.py +101 -82
- cirq/transformers/align.py +12 -1
- cirq/transformers/align_test.py +13 -0
- cirq/transformers/analytical_decompositions/__init__.py +27 -24
- cirq/transformers/analytical_decompositions/clifford_decomposition.py +2 -1
- cirq/transformers/analytical_decompositions/clifford_decomposition_test.py +1 -1
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition.py +1 -1
- cirq/transformers/analytical_decompositions/controlled_gate_decomposition_test.py +2 -0
- cirq/transformers/analytical_decompositions/cphase_to_fsim.py +1 -1
- cirq/transformers/analytical_decompositions/cphase_to_fsim_test.py +1 -1
- cirq/transformers/analytical_decompositions/pauli_string_decomposition.py +2 -2
- cirq/transformers/analytical_decompositions/pauli_string_decomposition_test.py +4 -4
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition.py +99 -24
- cirq/transformers/analytical_decompositions/quantum_shannon_decomposition_test.py +105 -14
- cirq/transformers/analytical_decompositions/single_qubit_decompositions.py +1 -1
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry.py +1 -1
- cirq/transformers/analytical_decompositions/single_to_two_qubit_isometry_test.py +1 -0
- cirq/transformers/analytical_decompositions/three_qubit_decomposition.py +3 -4
- cirq/transformers/analytical_decompositions/three_qubit_decomposition_test.py +1 -1
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation.py +2 -1
- cirq/transformers/analytical_decompositions/two_qubit_state_preparation_test.py +2 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_cz.py +5 -6
- cirq/transformers/analytical_decompositions/two_qubit_to_cz_test.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim.py +1 -1
- cirq/transformers/analytical_decompositions/two_qubit_to_fsim_test.py +1 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_ms.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap.py +2 -2
- cirq/transformers/analytical_decompositions/two_qubit_to_sqrt_iswap_test.py +2 -1
- cirq/transformers/drop_empty_moments.py +1 -0
- cirq/transformers/drop_negligible_operations.py +1 -0
- cirq/transformers/dynamical_decoupling.py +255 -43
- cirq/transformers/dynamical_decoupling_test.py +730 -17
- cirq/transformers/eject_phased_paulis.py +29 -15
- cirq/transformers/eject_phased_paulis_test.py +3 -8
- cirq/transformers/eject_z.py +3 -2
- cirq/transformers/eject_z_test.py +3 -3
- cirq/transformers/gauge_compiling/__init__.py +25 -9
- cirq/transformers/gauge_compiling/cphase_gauge.py +146 -0
- cirq/transformers/gauge_compiling/cphase_gauge_test.py +42 -0
- cirq/transformers/gauge_compiling/cz_gauge.py +4 -4
- cirq/transformers/gauge_compiling/gauge_compiling.py +245 -6
- cirq/transformers/gauge_compiling/gauge_compiling_test.py +107 -2
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils.py +39 -2
- cirq/transformers/gauge_compiling/gauge_compiling_test_utils_test.py +10 -1
- cirq/transformers/gauge_compiling/iswap_gauge.py +2 -2
- cirq/transformers/gauge_compiling/spin_inversion_gauge.py +2 -2
- cirq/transformers/gauge_compiling/sqrt_cz_gauge.py +23 -5
- cirq/transformers/gauge_compiling/sqrt_iswap_gauge.py +3 -2
- cirq/transformers/heuristic_decompositions/__init__.py +3 -3
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils.py +2 -1
- cirq/transformers/heuristic_decompositions/gate_tabulation_math_utils_test.py +1 -1
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation.py +4 -4
- cirq/transformers/heuristic_decompositions/two_qubit_gate_tabulation_test.py +4 -4
- cirq/transformers/insertion_sort.py +64 -0
- cirq/transformers/insertion_sort_test.py +34 -0
- cirq/transformers/measurement_transformers.py +14 -1
- cirq/transformers/measurement_transformers_test.py +35 -0
- cirq/transformers/merge_k_qubit_gates.py +2 -2
- cirq/transformers/merge_single_qubit_gates.py +1 -1
- cirq/transformers/merge_single_qubit_gates_test.py +1 -1
- cirq/transformers/noise_adding.py +115 -0
- cirq/transformers/noise_adding_test.py +54 -0
- cirq/transformers/optimize_for_target_gateset.py +1 -1
- cirq/transformers/optimize_for_target_gateset_test.py +3 -2
- cirq/transformers/qubit_management_transformers.py +1 -1
- cirq/transformers/randomized_measurements.py +171 -0
- cirq/transformers/randomized_measurements_test.py +68 -0
- cirq/transformers/routing/__init__.py +14 -5
- cirq/transformers/routing/initial_mapper.py +1 -1
- cirq/transformers/routing/initial_mapper_test.py +1 -0
- cirq/transformers/routing/line_initial_mapper.py +3 -2
- cirq/transformers/routing/mapping_manager.py +2 -2
- cirq/transformers/routing/mapping_manager_test.py +2 -2
- cirq/transformers/routing/route_circuit_cqc.py +3 -2
- cirq/transformers/routing/route_circuit_cqc_test.py +2 -1
- cirq/transformers/routing/visualize_routed_circuit.py +1 -0
- cirq/transformers/routing/visualize_routed_circuit_test.py +1 -0
- cirq/transformers/stratify.py +2 -2
- cirq/transformers/synchronize_terminal_measurements.py +2 -1
- cirq/transformers/target_gatesets/__init__.py +7 -5
- cirq/transformers/target_gatesets/compilation_target_gateset.py +16 -3
- cirq/transformers/target_gatesets/compilation_target_gateset_test.py +2 -0
- cirq/transformers/target_gatesets/cz_gateset.py +5 -1
- cirq/transformers/target_gatesets/cz_gateset_test.py +23 -2
- cirq/transformers/target_gatesets/sqrt_iswap_gateset.py +1 -1
- cirq/transformers/target_gatesets/sqrt_iswap_gateset_test.py +3 -2
- cirq/transformers/transformer_api.py +5 -4
- cirq/transformers/transformer_api_test.py +11 -3
- cirq/transformers/transformer_primitives.py +9 -31
- cirq/transformers/transformer_primitives_test.py +6 -5
- cirq/value/__init__.py +51 -30
- cirq/value/abc_alt.py +1 -2
- cirq/value/angle.py +2 -0
- cirq/value/classical_data.py +1 -0
- cirq/value/condition.py +149 -3
- cirq/value/condition_test.py +254 -0
- cirq/value/digits.py +1 -1
- cirq/value/duration.py +4 -4
- cirq/value/duration_test.py +2 -1
- cirq/value/linear_dict.py +85 -24
- cirq/value/linear_dict_test.py +94 -3
- cirq/value/measurement_key.py +9 -2
- cirq/value/periodic_value.py +2 -3
- cirq/value/periodic_value_test.py +5 -0
- cirq/value/probability.py +1 -0
- cirq/value/random_state.py +1 -1
- cirq/value/timestamp.py +2 -4
- cirq/value/timestamp_test.py +2 -1
- cirq/value/type_alias.py +2 -2
- cirq/value/value_equality_attr.py +14 -2
- cirq/value/value_equality_attr_test.py +1 -1
- cirq/vis/__init__.py +9 -6
- cirq/vis/density_matrix.py +1 -1
- cirq/vis/density_matrix_test.py +2 -5
- cirq/vis/heatmap.py +49 -12
- cirq/vis/heatmap_test.py +168 -4
- cirq/vis/histogram.py +1 -1
- cirq/vis/histogram_test.py +1 -2
- cirq/vis/state_histogram.py +7 -5
- cirq/vis/state_histogram_test.py +2 -2
- cirq/work/__init__.py +19 -13
- cirq/work/collector.py +2 -2
- cirq/work/observable_grouping.py +2 -2
- cirq/work/observable_measurement.py +3 -3
- cirq/work/observable_measurement_data.py +5 -2
- cirq/work/observable_measurement_test.py +8 -8
- cirq/work/observable_readout_calibration.py +2 -2
- cirq/work/observable_readout_calibration_test.py +2 -1
- cirq/work/observable_settings.py +8 -7
- cirq/work/observable_settings_test.py +3 -2
- cirq/work/pauli_sum_collector.py +1 -1
- cirq/work/sampler.py +8 -20
- cirq/work/sampler_test.py +4 -3
- cirq/work/zeros_sampler.py +1 -1
- cirq_core-1.5.0.dist-info/METADATA +125 -0
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/RECORD +586 -552
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/WHEEL +1 -1
- cirq/experiments/grid_parallel_two_qubit_xeb.py +0 -62
- cirq/protocols/json_test_data/GridParallelXEBMetadata.json +0 -119
- cirq/protocols/json_test_data/GridParallelXEBMetadata.repr +0 -1
- cirq_core-1.4.0.dev20240529225110.dist-info/METADATA +0 -50
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/LICENSE +0 -0
- {cirq_core-1.4.0.dev20240529225110.dist-info → cirq_core-1.5.0.dist-info}/top_level.txt +0 -0
cirq/ops/dense_pauli_string.py
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import abc
|
|
16
16
|
import numbers
|
|
17
|
+
from types import NotImplementedType
|
|
17
18
|
from typing import (
|
|
18
19
|
AbstractSet,
|
|
19
20
|
Any,
|
|
@@ -30,15 +31,14 @@ from typing import (
|
|
|
30
31
|
TYPE_CHECKING,
|
|
31
32
|
Union,
|
|
32
33
|
)
|
|
33
|
-
from typing_extensions import Self
|
|
34
34
|
|
|
35
35
|
import numpy as np
|
|
36
36
|
import sympy
|
|
37
|
+
from typing_extensions import Self
|
|
37
38
|
|
|
38
|
-
from cirq import
|
|
39
|
+
from cirq import linalg, protocols, value
|
|
39
40
|
from cirq._compat import proper_repr
|
|
40
|
-
from cirq.ops import
|
|
41
|
-
from cirq.type_workarounds import NotImplementedType
|
|
41
|
+
from cirq.ops import global_phase_op, identity, pauli_gates, pauli_string, raw_types
|
|
42
42
|
|
|
43
43
|
if TYPE_CHECKING:
|
|
44
44
|
import cirq
|
|
@@ -116,7 +116,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
|
|
|
116
116
|
return self._pauli_mask
|
|
117
117
|
|
|
118
118
|
@property
|
|
119
|
-
def coefficient(self) ->
|
|
119
|
+
def coefficient(self) -> 'cirq.TParamValComplex':
|
|
120
120
|
"""A complex coefficient or symbol."""
|
|
121
121
|
return self._coefficient
|
|
122
122
|
|
|
@@ -203,7 +203,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
|
|
|
203
203
|
def __pos__(self):
|
|
204
204
|
return self
|
|
205
205
|
|
|
206
|
-
def __pow__(self, power:
|
|
206
|
+
def __pow__(self, power: float) -> Union[NotImplementedType, Self]:
|
|
207
207
|
concrete_class = type(self)
|
|
208
208
|
if isinstance(power, int):
|
|
209
209
|
i_group = [1, +1j, -1, -1j]
|
|
@@ -359,7 +359,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
|
|
|
359
359
|
coef = '+'
|
|
360
360
|
elif self.coefficient == -1:
|
|
361
361
|
coef = '-'
|
|
362
|
-
elif isinstance(self.coefficient, (
|
|
362
|
+
elif isinstance(self.coefficient, (numbers.Complex, sympy.Symbol)):
|
|
363
363
|
coef = f'{self.coefficient}*'
|
|
364
364
|
else:
|
|
365
365
|
coef = f'({self.coefficient})*'
|
|
@@ -403,7 +403,7 @@ class BaseDensePauliString(raw_types.Gate, metaclass=abc.ABCMeta):
|
|
|
403
403
|
@abc.abstractmethod
|
|
404
404
|
def copy(
|
|
405
405
|
self,
|
|
406
|
-
coefficient: Optional[
|
|
406
|
+
coefficient: Optional['cirq.TParamValComplex'] = None,
|
|
407
407
|
pauli_mask: Union[None, str, Iterable[int], np.ndarray] = None,
|
|
408
408
|
) -> Self:
|
|
409
409
|
"""Returns a copy with possibly modified contents.
|
|
@@ -459,7 +459,7 @@ class DensePauliString(BaseDensePauliString):
|
|
|
459
459
|
|
|
460
460
|
def copy(
|
|
461
461
|
self,
|
|
462
|
-
coefficient: Optional[
|
|
462
|
+
coefficient: Optional['cirq.TParamValComplex'] = None,
|
|
463
463
|
pauli_mask: Union[None, str, Iterable[int], np.ndarray] = None,
|
|
464
464
|
) -> 'DensePauliString':
|
|
465
465
|
if pauli_mask is None and (coefficient is None or coefficient == self.coefficient):
|
|
@@ -559,7 +559,7 @@ class MutableDensePauliString(BaseDensePauliString):
|
|
|
559
559
|
|
|
560
560
|
def copy(
|
|
561
561
|
self,
|
|
562
|
-
coefficient: Optional[
|
|
562
|
+
coefficient: Optional['cirq.TParamValComplex'] = None,
|
|
563
563
|
pauli_mask: Union[None, str, Iterable[int], np.ndarray] = None,
|
|
564
564
|
) -> 'MutableDensePauliString':
|
|
565
565
|
return MutableDensePauliString(
|
|
@@ -627,7 +627,7 @@ def _attempt_value_to_pauli_index(v: 'cirq.Operation') -> Optional[Tuple[int, in
|
|
|
627
627
|
return None
|
|
628
628
|
|
|
629
629
|
if not isinstance(v.gate, pauli_gates.Pauli):
|
|
630
|
-
return None
|
|
630
|
+
return None # pragma: no cover
|
|
631
631
|
|
|
632
632
|
q = v.qubits[0]
|
|
633
633
|
from cirq import devices
|
cirq/ops/diagonal_gate.py
CHANGED
|
@@ -36,7 +36,7 @@ import sympy
|
|
|
36
36
|
|
|
37
37
|
from cirq import protocols, value
|
|
38
38
|
from cirq._compat import proper_repr
|
|
39
|
-
from cirq.ops import common_gates,
|
|
39
|
+
from cirq.ops import common_gates, global_phase_op, raw_types
|
|
40
40
|
|
|
41
41
|
if TYPE_CHECKING:
|
|
42
42
|
import cirq
|
|
@@ -166,7 +166,7 @@ class DiagonalGate(raw_types.Gate):
|
|
|
166
166
|
self, index: int, bit_flip: int, theta: 'cirq.TParamVal', qubits: Sequence['cirq.Qid']
|
|
167
167
|
) -> Iterator[Union['cirq.ZPowGate', 'cirq.CXPowGate']]:
|
|
168
168
|
if index == 0:
|
|
169
|
-
return
|
|
169
|
+
return
|
|
170
170
|
largest_digit = self._num_qubits_() - (len(bin(index)) - 2)
|
|
171
171
|
yield common_gates.rz(2 * theta)(qubits[largest_digit])
|
|
172
172
|
_flip_bit = self._num_qubits_() - bit_flip - 1
|
cirq/ops/diagonal_gate_test.py
CHANGED
cirq/ops/eigen_gate.py
CHANGED
|
@@ -15,6 +15,7 @@ import abc
|
|
|
15
15
|
import fractions
|
|
16
16
|
import math
|
|
17
17
|
import numbers
|
|
18
|
+
from types import NotImplementedType
|
|
18
19
|
from typing import (
|
|
19
20
|
AbstractSet,
|
|
20
21
|
Any,
|
|
@@ -32,10 +33,8 @@ from typing import (
|
|
|
32
33
|
import numpy as np
|
|
33
34
|
import sympy
|
|
34
35
|
|
|
35
|
-
from cirq import
|
|
36
|
-
from cirq.linalg import tolerance
|
|
36
|
+
from cirq import protocols, value
|
|
37
37
|
from cirq.ops import raw_types
|
|
38
|
-
from cirq.type_workarounds import NotImplementedType
|
|
39
38
|
|
|
40
39
|
if TYPE_CHECKING:
|
|
41
40
|
import cirq
|
|
@@ -122,7 +121,6 @@ class EigenGate(raw_types.Gate):
|
|
|
122
121
|
exponent = exponent.real
|
|
123
122
|
self._exponent = exponent
|
|
124
123
|
self._global_shift = global_shift
|
|
125
|
-
self._canonical_exponent_cached = None
|
|
126
124
|
|
|
127
125
|
@property
|
|
128
126
|
def exponent(self) -> value.TParamVal:
|
|
@@ -302,29 +300,22 @@ class EigenGate(raw_types.Gate):
|
|
|
302
300
|
def __pow__(self, exponent: Union[float, sympy.Symbol]) -> 'EigenGate':
|
|
303
301
|
new_exponent = protocols.mul(self._exponent, exponent, NotImplemented)
|
|
304
302
|
if new_exponent is NotImplemented:
|
|
305
|
-
return NotImplemented
|
|
303
|
+
return NotImplemented # pragma: no cover
|
|
306
304
|
return self._with_exponent(exponent=new_exponent)
|
|
307
305
|
|
|
308
|
-
@property
|
|
309
|
-
def _canonical_exponent(self):
|
|
310
|
-
if self._canonical_exponent_cached is None:
|
|
311
|
-
period = self._period()
|
|
312
|
-
if not period or protocols.is_parameterized(self._exponent):
|
|
313
|
-
self._canonical_exponent_cached = self._exponent
|
|
314
|
-
else:
|
|
315
|
-
self._canonical_exponent_cached = self._exponent % period
|
|
316
|
-
return self._canonical_exponent_cached
|
|
317
|
-
|
|
318
306
|
def _value_equality_values_(self):
|
|
319
|
-
|
|
307
|
+
"""The phases by which we multiply the eigenspaces.
|
|
320
308
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
309
|
+
The default implementation assumes that the eigenspaces are constant
|
|
310
|
+
for the class, and the eigenphases are the only distinguishing
|
|
311
|
+
characteristics. For gates whose eigenspaces can change, such as
|
|
312
|
+
`PhasedISwapPowGate`, this must be overridden to provide the additional
|
|
313
|
+
fields that affect the eigenspaces.
|
|
314
|
+
"""
|
|
315
|
+
symbolic = lambda x: isinstance(x, sympy.Expr) and x.free_symbols
|
|
316
|
+
f = lambda x: x if symbolic(x) else float(x)
|
|
317
|
+
shifts = (f(self._exponent) * f(self._global_shift + e) for e in self._eigen_shifts())
|
|
318
|
+
return tuple(s if symbolic(s) else value.PeriodicValue(f(s), 2) for s in shifts)
|
|
328
319
|
|
|
329
320
|
def _trace_distance_bound_(self) -> Optional[float]:
|
|
330
321
|
if protocols.is_parameterized(self._exponent):
|
|
@@ -355,7 +346,7 @@ class EigenGate(raw_types.Gate):
|
|
|
355
346
|
|
|
356
347
|
def _resolve_parameters_(self, resolver: 'cirq.ParamResolver', recursive: bool) -> 'EigenGate':
|
|
357
348
|
exponent = resolver.value_of(self._exponent, recursive)
|
|
358
|
-
if isinstance(exponent,
|
|
349
|
+
if isinstance(exponent, numbers.Complex):
|
|
359
350
|
if isinstance(exponent, numbers.Real):
|
|
360
351
|
exponent = float(exponent)
|
|
361
352
|
else:
|
|
@@ -374,20 +365,9 @@ class EigenGate(raw_types.Gate):
|
|
|
374
365
|
return False
|
|
375
366
|
self_without_phase = self._with_exponent(self.exponent)
|
|
376
367
|
self_without_phase._global_shift = 0
|
|
377
|
-
self_without_exp_or_phase = self_without_phase._with_exponent(0)
|
|
378
|
-
self_without_exp_or_phase._global_shift = 0
|
|
379
368
|
other_without_phase = other._with_exponent(other.exponent)
|
|
380
369
|
other_without_phase._global_shift = 0
|
|
381
|
-
|
|
382
|
-
other_without_exp_or_phase._global_shift = 0
|
|
383
|
-
if not protocols.approx_eq(
|
|
384
|
-
self_without_exp_or_phase, other_without_exp_or_phase, atol=atol
|
|
385
|
-
):
|
|
386
|
-
return False
|
|
387
|
-
|
|
388
|
-
period = self_without_phase._period()
|
|
389
|
-
exponents_diff = exponents[0] - exponents[1]
|
|
390
|
-
return tolerance.near_zero_mod(exponents_diff, period, atol=atol)
|
|
370
|
+
return protocols.approx_eq(self_without_phase, other_without_phase, atol=atol)
|
|
391
371
|
|
|
392
372
|
def _json_dict_(self) -> Dict[str, Any]:
|
|
393
373
|
return protocols.obj_to_dict_helper(self, ['exponent', 'global_shift'])
|
cirq/ops/eigen_gate_test.py
CHANGED
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
from typing import List, Tuple
|
|
16
|
-
import re
|
|
17
16
|
|
|
18
17
|
import numpy as np
|
|
19
18
|
import pytest
|
|
@@ -50,7 +49,7 @@ class CExpZinGate(cirq.EigenGate, cirq.testing.TwoQubitGate):
|
|
|
50
49
|
]
|
|
51
50
|
|
|
52
51
|
|
|
53
|
-
class ZGateDef(cirq.EigenGate, cirq.testing.
|
|
52
|
+
class ZGateDef(cirq.EigenGate, cirq.testing.SingleQubitGate):
|
|
54
53
|
@property
|
|
55
54
|
def exponent(self):
|
|
56
55
|
return self._exponent
|
|
@@ -97,7 +96,6 @@ def test_eq():
|
|
|
97
96
|
eq.make_equality_group(lambda: CExpZinGate(quarter_turns=0.1))
|
|
98
97
|
eq.add_equality_group(CExpZinGate(0), CExpZinGate(4), CExpZinGate(-4))
|
|
99
98
|
|
|
100
|
-
# Equates by canonicalized period.
|
|
101
99
|
eq.add_equality_group(CExpZinGate(1.5), CExpZinGate(41.5))
|
|
102
100
|
eq.add_equality_group(CExpZinGate(3.5), CExpZinGate(-0.5))
|
|
103
101
|
|
|
@@ -109,6 +107,64 @@ def test_eq():
|
|
|
109
107
|
eq.add_equality_group(ZGateDef(exponent=0.5, global_shift=0.5))
|
|
110
108
|
eq.add_equality_group(ZGateDef(exponent=1.0, global_shift=0.5))
|
|
111
109
|
|
|
110
|
+
# All variants of (0,0) == (0*a,0*a) == (0, 2) == (2, 2)
|
|
111
|
+
a, b = sympy.symbols('a, b')
|
|
112
|
+
eq.add_equality_group(
|
|
113
|
+
WeightedZPowGate(0),
|
|
114
|
+
WeightedZPowGate(0) ** 1.1,
|
|
115
|
+
WeightedZPowGate(0) ** a,
|
|
116
|
+
(WeightedZPowGate(0) ** a) ** 1.2,
|
|
117
|
+
WeightedZPowGate(0) ** (a + 1.3),
|
|
118
|
+
WeightedZPowGate(0) ** b,
|
|
119
|
+
WeightedZPowGate(1) ** 2,
|
|
120
|
+
WeightedZPowGate(0, global_shift=1) ** 2,
|
|
121
|
+
WeightedZPowGate(1, global_shift=1) ** 2,
|
|
122
|
+
WeightedZPowGate(2),
|
|
123
|
+
WeightedZPowGate(0, global_shift=2),
|
|
124
|
+
WeightedZPowGate(2, global_shift=2),
|
|
125
|
+
)
|
|
126
|
+
# WeightedZPowGate(2) is identity, but non-integer exponent would make it different, similar to
|
|
127
|
+
# how we treat (X**2)**0.5==X. So these are in their own equality group. (0, 2*a)
|
|
128
|
+
eq.add_equality_group(
|
|
129
|
+
WeightedZPowGate(2) ** a,
|
|
130
|
+
(WeightedZPowGate(1) ** 2) ** a,
|
|
131
|
+
(WeightedZPowGate(1) ** a) ** 2,
|
|
132
|
+
WeightedZPowGate(1) ** (a * 2),
|
|
133
|
+
WeightedZPowGate(1) ** (a + a),
|
|
134
|
+
)
|
|
135
|
+
# Similarly, these are identity without the exponent, but global_shift affects both phases
|
|
136
|
+
# instead of just the one, so will have a different effect from the above depending on the
|
|
137
|
+
# exponent. (2*a, 0)
|
|
138
|
+
eq.add_equality_group(
|
|
139
|
+
WeightedZPowGate(0, global_shift=2) ** a,
|
|
140
|
+
(WeightedZPowGate(0, global_shift=1) ** 2) ** a,
|
|
141
|
+
(WeightedZPowGate(0, global_shift=1) ** a) ** 2,
|
|
142
|
+
WeightedZPowGate(0, global_shift=1) ** (a * 2),
|
|
143
|
+
WeightedZPowGate(0, global_shift=1) ** (a + a),
|
|
144
|
+
)
|
|
145
|
+
# Symbolic exponents that cancel (0, 1) == (0, a/a)
|
|
146
|
+
eq.add_equality_group(
|
|
147
|
+
WeightedZPowGate(1),
|
|
148
|
+
WeightedZPowGate(a) ** (1 / a),
|
|
149
|
+
WeightedZPowGate(b) ** (1 / b),
|
|
150
|
+
WeightedZPowGate(1 / a) ** a,
|
|
151
|
+
WeightedZPowGate(1 / b) ** b,
|
|
152
|
+
)
|
|
153
|
+
# Symbol in one phase and constant off by period in another (0, a) == (2, a)
|
|
154
|
+
eq.add_equality_group(
|
|
155
|
+
WeightedZPowGate(a),
|
|
156
|
+
WeightedZPowGate(a - 2, global_shift=2),
|
|
157
|
+
WeightedZPowGate(1 - 2 / a, global_shift=2 / a) ** a,
|
|
158
|
+
)
|
|
159
|
+
# Different symbol, different equality group (0, b)
|
|
160
|
+
eq.add_equality_group(WeightedZPowGate(b))
|
|
161
|
+
# Various number types
|
|
162
|
+
eq.add_equality_group(
|
|
163
|
+
WeightedZPowGate(np.int64(3), global_shift=sympy.Number(5)) ** 7.0,
|
|
164
|
+
WeightedZPowGate(sympy.Number(3), global_shift=5.0) ** np.int64(7),
|
|
165
|
+
WeightedZPowGate(3.0, global_shift=np.int64(5)) ** sympy.Number(7),
|
|
166
|
+
)
|
|
167
|
+
|
|
112
168
|
|
|
113
169
|
def test_approx_eq():
|
|
114
170
|
assert cirq.approx_eq(CExpZinGate(1.5), CExpZinGate(1.5), atol=0.1)
|
|
@@ -118,8 +174,7 @@ def test_approx_eq():
|
|
|
118
174
|
assert cirq.approx_eq(ZGateDef(exponent=1.5), ZGateDef(exponent=1.5), atol=0.1)
|
|
119
175
|
assert not cirq.approx_eq(CExpZinGate(1.5), ZGateDef(exponent=1.5), atol=0.1)
|
|
120
176
|
with pytest.raises(
|
|
121
|
-
TypeError,
|
|
122
|
-
match=re.escape("unsupported operand type(s) for -: 'Symbol' and 'PeriodicValue'"),
|
|
177
|
+
TypeError, match="unsupported operand type\\(s\\) for -: '.*' and 'PeriodicValue'"
|
|
123
178
|
):
|
|
124
179
|
cirq.approx_eq(ZGateDef(exponent=1.5), ZGateDef(exponent=sympy.Symbol('a')), atol=0.1)
|
|
125
180
|
assert cirq.approx_eq(CExpZinGate(sympy.Symbol('a')), CExpZinGate(sympy.Symbol('a')), atol=0.1)
|
|
@@ -333,11 +388,6 @@ class WeightedZPowGate(cirq.EigenGate, cirq.testing.SingleQubitGate):
|
|
|
333
388
|
self.weight = weight
|
|
334
389
|
super().__init__(**kwargs)
|
|
335
390
|
|
|
336
|
-
def _value_equality_values_(self):
|
|
337
|
-
return self.weight, self._canonical_exponent, self._global_shift
|
|
338
|
-
|
|
339
|
-
_value_equality_approximate_values_ = _value_equality_values_
|
|
340
|
-
|
|
341
391
|
def _eigen_components(self) -> List[Tuple[float, np.ndarray]]:
|
|
342
392
|
return [(0, np.diag([1, 0])), (self.weight, np.diag([0, 1]))]
|
|
343
393
|
|
cirq/ops/fourier_transform.py
CHANGED
|
@@ -18,7 +18,7 @@ import numpy as np
|
|
|
18
18
|
import sympy
|
|
19
19
|
|
|
20
20
|
import cirq
|
|
21
|
-
from cirq import
|
|
21
|
+
from cirq import _compat, value
|
|
22
22
|
from cirq.ops import raw_types
|
|
23
23
|
|
|
24
24
|
|
|
@@ -170,8 +170,6 @@ class PhaseGradientGate(raw_types.Gate):
|
|
|
170
170
|
self, resolver: 'cirq.ParamResolver', recursive: bool
|
|
171
171
|
) -> 'PhaseGradientGate':
|
|
172
172
|
new_exponent = cirq.resolve_parameters(self.exponent, resolver, recursive)
|
|
173
|
-
if new_exponent is self.exponent:
|
|
174
|
-
return self
|
|
175
173
|
return PhaseGradientGate(num_qubits=self._num_qubits, exponent=new_exponent)
|
|
176
174
|
|
|
177
175
|
def __str__(self) -> str:
|
cirq/ops/fsim_gate.py
CHANGED
|
@@ -23,7 +23,7 @@ applies more generally to fermions, thus the name of the gate.
|
|
|
23
23
|
|
|
24
24
|
import cmath
|
|
25
25
|
import math
|
|
26
|
-
from typing import AbstractSet, Any, Dict, Optional, Tuple
|
|
26
|
+
from typing import AbstractSet, Any, Dict, Iterator, Optional, Tuple
|
|
27
27
|
|
|
28
28
|
import numpy as np
|
|
29
29
|
import sympy
|
|
@@ -187,7 +187,7 @@ class FSimGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
|
|
|
187
187
|
out[ii] *= cmath.exp(-1j * self.phi)
|
|
188
188
|
return out
|
|
189
189
|
|
|
190
|
-
def _decompose_(self, qubits) -> 'cirq.OP_TREE':
|
|
190
|
+
def _decompose_(self, qubits) -> Iterator['cirq.OP_TREE']:
|
|
191
191
|
a, b = qubits
|
|
192
192
|
xx = cirq.XXPowGate(exponent=self.theta / np.pi, global_shift=-0.5)
|
|
193
193
|
yy = cirq.YYPowGate(exponent=self.theta / np.pi, global_shift=-0.5)
|
|
@@ -347,6 +347,45 @@ class PhasedFSimGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
|
|
|
347
347
|
chi = (b0 - b1 - a0 + a1) / 2.0
|
|
348
348
|
return PhasedFSimGate(theta, zeta, chi, gamma, phi)
|
|
349
349
|
|
|
350
|
+
@staticmethod
|
|
351
|
+
def from_matrix(u: np.ndarray) -> Optional['PhasedFSimGate']:
|
|
352
|
+
"""Contruct a PhasedFSimGate from unitary.
|
|
353
|
+
|
|
354
|
+
Args:
|
|
355
|
+
u: A unitary matrix representing a PhasedFSimGate.
|
|
356
|
+
|
|
357
|
+
Returns:
|
|
358
|
+
- Either PhasedFSimGate with the given unitary or None if
|
|
359
|
+
the matrix is not unitary or if doesn't represent a PhasedFSimGate.
|
|
360
|
+
"""
|
|
361
|
+
|
|
362
|
+
gamma = np.angle(u[1, 1] * u[2, 2] - u[1, 2] * u[2, 1]) / -2
|
|
363
|
+
phi = -np.angle(u[3, 3]) - 2 * gamma
|
|
364
|
+
phased_cos_theta_2 = u[1, 1] * u[2, 2]
|
|
365
|
+
if phased_cos_theta_2 == 0:
|
|
366
|
+
# The zeta phase is multiplied with cos(theta),
|
|
367
|
+
# so if cos(theta) is zero then any value is possible.
|
|
368
|
+
zeta = 0
|
|
369
|
+
else:
|
|
370
|
+
zeta = np.angle(u[2, 2] / u[1, 1]) / 2
|
|
371
|
+
|
|
372
|
+
phased_sin_theta_2 = u[1, 2] * u[2, 1]
|
|
373
|
+
if phased_sin_theta_2 == 0:
|
|
374
|
+
# The chi phase is multiplied with sin(theta),
|
|
375
|
+
# so if sin(theta) is zero then any value is possible.
|
|
376
|
+
chi = 0
|
|
377
|
+
else:
|
|
378
|
+
chi = np.angle(u[1, 2] / u[2, 1]) / 2
|
|
379
|
+
|
|
380
|
+
theta = np.angle(
|
|
381
|
+
np.exp(1j * (gamma + zeta)) * u[1, 1] - np.exp(1j * (gamma - chi)) * u[1, 2]
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
gate = PhasedFSimGate(theta=theta, phi=phi, chi=chi, zeta=zeta, gamma=gamma)
|
|
385
|
+
if np.allclose(u, protocols.unitary(gate)):
|
|
386
|
+
return gate
|
|
387
|
+
return None
|
|
388
|
+
|
|
350
389
|
@property
|
|
351
390
|
def rz_angles_before(self) -> Tuple['cirq.TParamVal', 'cirq.TParamVal']:
|
|
352
391
|
"""Returns 2-tuple of phase angles applied to qubits before FSimGate."""
|
|
@@ -452,7 +491,7 @@ class PhasedFSimGate(gate_features.InterchangeableQubitsGate, raw_types.Gate):
|
|
|
452
491
|
out[ii] *= f * f
|
|
453
492
|
return out
|
|
454
493
|
|
|
455
|
-
def _decompose_(self, qubits) -> 'cirq.OP_TREE':
|
|
494
|
+
def _decompose_(self, qubits) -> Iterator['cirq.OP_TREE']:
|
|
456
495
|
"""Decomposes self into Z rotations and FSimGate.
|
|
457
496
|
|
|
458
497
|
Note that Z rotations returned by this method have unusual global phase
|
cirq/ops/fsim_gate_test.py
CHANGED
|
@@ -797,3 +797,24 @@ def test_phased_fsim_json_dict():
|
|
|
797
797
|
assert cirq.PhasedFSimGate(
|
|
798
798
|
theta=0.12, zeta=0.34, chi=0.56, gamma=0.78, phi=0.9
|
|
799
799
|
)._json_dict_() == {'theta': 0.12, 'zeta': 0.34, 'chi': 0.56, 'gamma': 0.78, 'phi': 0.9}
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
@pytest.mark.parametrize(
|
|
803
|
+
'gate',
|
|
804
|
+
[
|
|
805
|
+
cirq.CZ,
|
|
806
|
+
cirq.SQRT_ISWAP,
|
|
807
|
+
cirq.SQRT_ISWAP_INV,
|
|
808
|
+
cirq.ISWAP,
|
|
809
|
+
cirq.ISWAP_INV,
|
|
810
|
+
cirq.cphase(0.1),
|
|
811
|
+
cirq.CZ**0.2,
|
|
812
|
+
],
|
|
813
|
+
)
|
|
814
|
+
def test_phase_fsim_from_matrix(gate):
|
|
815
|
+
u = cirq.unitary(gate)
|
|
816
|
+
np.testing.assert_allclose(cirq.unitary(cirq.PhasedFSimGate.from_matrix(u)), u, atol=1e-8)
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
def test_phase_fsim_from_matrix_not_fsim_returns_none():
|
|
820
|
+
assert cirq.PhasedFSimGate.from_matrix(np.ones((4, 4))) is None
|
cirq/ops/gate_operation.py
CHANGED
|
@@ -16,29 +16,29 @@
|
|
|
16
16
|
|
|
17
17
|
import re
|
|
18
18
|
import warnings
|
|
19
|
+
from types import NotImplementedType
|
|
19
20
|
from typing import (
|
|
20
21
|
AbstractSet,
|
|
21
22
|
Any,
|
|
22
|
-
Mapping,
|
|
23
23
|
cast,
|
|
24
24
|
Collection,
|
|
25
25
|
Dict,
|
|
26
26
|
FrozenSet,
|
|
27
|
+
List,
|
|
28
|
+
Mapping,
|
|
27
29
|
Optional,
|
|
28
30
|
Sequence,
|
|
29
31
|
Tuple,
|
|
30
|
-
TypeVar,
|
|
31
32
|
TYPE_CHECKING,
|
|
33
|
+
TypeVar,
|
|
32
34
|
Union,
|
|
33
|
-
List,
|
|
34
35
|
)
|
|
35
|
-
from typing_extensions import Self
|
|
36
36
|
|
|
37
37
|
import numpy as np
|
|
38
|
+
from typing_extensions import Self
|
|
38
39
|
|
|
39
40
|
from cirq import ops, protocols, value
|
|
40
|
-
from cirq.ops import
|
|
41
|
-
from cirq.type_workarounds import NotImplementedType
|
|
41
|
+
from cirq.ops import control_values as cv, gate_features, raw_types
|
|
42
42
|
|
|
43
43
|
if TYPE_CHECKING:
|
|
44
44
|
import cirq
|
|
@@ -302,7 +302,7 @@ class GateOperation(raw_types.Operation):
|
|
|
302
302
|
def _decompose_into_clifford_(self):
|
|
303
303
|
sub = getattr(self.gate, '_decompose_into_clifford_with_qubits_', None)
|
|
304
304
|
if sub is None:
|
|
305
|
-
return NotImplemented
|
|
305
|
+
return NotImplemented # pragma: no cover
|
|
306
306
|
return sub(self.qubits)
|
|
307
307
|
|
|
308
308
|
def _trace_distance_bound_(self) -> float:
|
|
@@ -360,7 +360,7 @@ class GateOperation(raw_types.Operation):
|
|
|
360
360
|
return protocols.qasm(self.gate, args=args, qubits=self.qubits, default=None)
|
|
361
361
|
|
|
362
362
|
def _equal_up_to_global_phase_(
|
|
363
|
-
self, other: Any, atol:
|
|
363
|
+
self, other: Any, atol: float = 1e-8
|
|
364
364
|
) -> Union[NotImplementedType, bool]:
|
|
365
365
|
if not isinstance(other, type(self)):
|
|
366
366
|
return NotImplemented
|
cirq/ops/gate_operation_test.py
CHANGED
|
@@ -454,6 +454,7 @@ def test_is_parameterized():
|
|
|
454
454
|
return True
|
|
455
455
|
|
|
456
456
|
q = cirq.LineQubit(0)
|
|
457
|
+
assert No1().num_qubits() == 1
|
|
457
458
|
assert not cirq.is_parameterized(No1().on(q))
|
|
458
459
|
assert not cirq.is_parameterized(No2().on(q))
|
|
459
460
|
assert cirq.is_parameterized(Yes().on(q))
|
|
@@ -490,7 +491,9 @@ def test_gate_to_operation_to_gate_round_trips():
|
|
|
490
491
|
gate_subclasses = {
|
|
491
492
|
g
|
|
492
493
|
for g in all_subclasses(cirq.Gate)
|
|
493
|
-
if
|
|
494
|
+
if g.__module__.startswith("cirq.")
|
|
495
|
+
and "contrib" not in g.__module__
|
|
496
|
+
and "test" not in g.__module__
|
|
494
497
|
}
|
|
495
498
|
|
|
496
499
|
test_module_spec = cirq.testing.json.spec_for("cirq.protocols")
|
|
@@ -506,7 +509,6 @@ def test_gate_to_operation_to_gate_round_trips():
|
|
|
506
509
|
cirq.transformers.measurement_transformers._ConfusionChannel,
|
|
507
510
|
cirq.transformers.measurement_transformers._ModAdd,
|
|
508
511
|
cirq.transformers.routing.visualize_routed_circuit._SwapPrintGate,
|
|
509
|
-
cirq.ops.raw_types._InverseCompositeGate,
|
|
510
512
|
cirq.circuits.qasm_output.QasmTwoQubitGate,
|
|
511
513
|
cirq.ops.MSGate,
|
|
512
514
|
# Interop gates
|
cirq/ops/gateset_test.py
CHANGED
|
@@ -12,13 +12,15 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
from typing import Tuple, List, cast
|
|
16
15
|
import re
|
|
16
|
+
from typing import cast, List, Tuple
|
|
17
|
+
|
|
18
|
+
import numpy as np
|
|
17
19
|
import pytest
|
|
18
20
|
import sympy
|
|
21
|
+
|
|
19
22
|
import cirq
|
|
20
23
|
from cirq._compat import proper_repr
|
|
21
|
-
import numpy as np
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
class CustomXPowGate(cirq.EigenGate):
|
|
@@ -441,3 +443,10 @@ def test_gateset_contains_with_tags():
|
|
|
441
443
|
# Both tags to accept and tags to ignore
|
|
442
444
|
assert op in cirq.Gateset(gf_accept, gf_ignore)
|
|
443
445
|
assert op_with_tag in cirq.Gateset(gf_accept, gf_ignore)
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
def test_gateset_contains_op_with_no_gate():
|
|
449
|
+
gf = cirq.GateFamily(cirq.ZPowGate)
|
|
450
|
+
op = cirq.X(cirq.q(1)).with_classical_controls('a')
|
|
451
|
+
assert op.gate is None
|
|
452
|
+
assert op not in gf
|
cirq/ops/global_phase_op.py
CHANGED
|
@@ -13,22 +13,23 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
"""A no-qubit global phase operation."""
|
|
15
15
|
|
|
16
|
-
from
|
|
16
|
+
from types import NotImplementedType
|
|
17
|
+
from typing import AbstractSet, Any, cast, Collection, Dict, Optional, Sequence, Tuple, Union
|
|
17
18
|
|
|
18
19
|
import numpy as np
|
|
19
20
|
import sympy
|
|
20
21
|
|
|
21
22
|
import cirq
|
|
22
|
-
from cirq import
|
|
23
|
-
from cirq.
|
|
24
|
-
from cirq.
|
|
23
|
+
from cirq import protocols, value
|
|
24
|
+
from cirq._compat import proper_repr
|
|
25
|
+
from cirq.ops import control_values as cv, controlled_gate, raw_types
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
@value.value_equality(approximate=True)
|
|
28
29
|
class GlobalPhaseGate(raw_types.Gate):
|
|
29
30
|
def __init__(self, coefficient: 'cirq.TParamValComplex', atol: float = 1e-8) -> None:
|
|
30
31
|
if not isinstance(coefficient, sympy.Basic):
|
|
31
|
-
if abs(1 - abs(coefficient)) > atol:
|
|
32
|
+
if abs(1 - abs(coefficient)) > atol:
|
|
32
33
|
raise ValueError(f'Coefficient is not unitary: {coefficient!r}')
|
|
33
34
|
self._coefficient = coefficient
|
|
34
35
|
|
|
@@ -68,10 +69,10 @@ class GlobalPhaseGate(raw_types.Gate):
|
|
|
68
69
|
return str(self.coefficient)
|
|
69
70
|
|
|
70
71
|
def __repr__(self) -> str:
|
|
71
|
-
return f'cirq.GlobalPhaseGate({self.coefficient
|
|
72
|
+
return f'cirq.GlobalPhaseGate({proper_repr(self.coefficient)})'
|
|
72
73
|
|
|
73
74
|
def _op_repr_(self, qubits: Sequence['cirq.Qid']) -> str:
|
|
74
|
-
return f'cirq.global_phase_operation({self.coefficient
|
|
75
|
+
return f'cirq.global_phase_operation({proper_repr(self.coefficient)})'
|
|
75
76
|
|
|
76
77
|
def _json_dict_(self) -> Dict[str, Any]:
|
|
77
78
|
return protocols.obj_to_dict_helper(self, ['coefficient'])
|
cirq/ops/global_phase_op_test.py
CHANGED
|
@@ -90,6 +90,11 @@ ancilla_1: ───X───X───
|
|
|
90
90
|
)
|
|
91
91
|
|
|
92
92
|
|
|
93
|
+
def test_empty_qubits():
|
|
94
|
+
qm = cirq.GreedyQubitManager(prefix="anc")
|
|
95
|
+
assert qm.qalloc(0) == []
|
|
96
|
+
|
|
97
|
+
|
|
93
98
|
def test_greedy_qubit_manager_preserves_order():
|
|
94
99
|
qm = cirq.GreedyQubitManager(prefix="anc")
|
|
95
100
|
ancillae = [cirq.q(f"anc_{i}") for i in range(100)]
|